Implement 'set_color' for corsair lighting pro
[temp2RGB.git] / src / corsair_lighting_pro.rs
index 48bef11..7ccb373 100644 (file)
@@ -20,14 +20,19 @@ const CORSAIR_LIGHTING_NODE_PORT_STATE_SOFTWARE: u8 = 0x02; // Direct software c
 
 const CORSAIR_LIGHTING_NODE_MODE_STATIC: u8 = 0x04; // Static mode
 
+const CORSAIR_LIGHTING_NODE_DIRECT_CHANNEL_RED: u8 = 0x00;
+const CORSAIR_LIGHTING_NODE_DIRECT_CHANNEL_GREEN: u8 = 0x01;
+const CORSAIR_LIGHTING_NODE_DIRECT_CHANNEL_BLUE: u8 = 0x02;
+
 const CHANNEL_COUNT: u8 = 2;
+const NB_LEDS: u8 = 20;
 
 pub struct Device {
     device: hidapi::HidDevice,
 }
 
 impl Device {
-    pub fn new(api: &hidapi::HidApi) -> Self {
+    pub fn new(api: &hidapi::HidApi, initial_color: &RGB) -> Self {
         let device = Device {
             device: api
                 .open(CORSAIR_VID, CORSAIR_LIGHTING_NODE_PRO_PID)
@@ -38,26 +43,13 @@ impl Device {
             device.send_reset(channel_id);
             device.send_begin(channel_id);
             device.send_port_state(channel_id, CORSAIR_LIGHTING_NODE_PORT_STATE_HARDWARE);
-            device.send_effect_config(
-                channel_id,
-                &RGB {
-                    red: 0x00,
-                    green: 0x00,
-                    blue: 0x00,
-                },
-            );
+            device.send_effect_config(channel_id, initial_color);
             device.send_commit(channel_id);
         }
 
         device
     }
 
-    pub fn set_color(&self, color: &RGB) {
-        for channel_id in 0..CHANNEL_COUNT {
-            self.send_effect_config(channel_id, color);
-        }
-    }
-
     fn send_reset(&self, channel_id: u8) {
         let mut buffer = [0u8; 65];
         buffer[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_RESET;
@@ -68,6 +60,7 @@ impl Device {
 
         let n_read = self.device.read(&mut buffer[0..16]).unwrap();
         assert_eq!(n_read, 16);
+        assert_eq!(buffer[0], 0);
     }
 
     fn send_begin(&self, channel_id: u8) {
@@ -80,6 +73,7 @@ impl Device {
 
         let n_read = self.device.read(&mut buffer[0..16]).unwrap();
         assert_eq!(n_read, 16);
+        assert_eq!(buffer[0], 0);
     }
 
     fn send_port_state(&self, channel_id: u8, state: u8) {
@@ -93,14 +87,17 @@ impl Device {
 
         let n_read = self.device.read(&mut buffer[0..16]).unwrap();
         assert_eq!(n_read, 16);
+        assert_eq!(buffer[0], 0);
     }
 
     fn send_effect_config(&self, channel_id: u8, color: &RGB) {
+        println!("{color:?}");
+
         let mut buffer = [0u8; 65];
         buffer[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_EFFECT_CONFIG;
         buffer[0x02] = channel_id;
         buffer[0x03] = 0x00; // count.
-        buffer[0x04] = 0x1E; // led type.
+        buffer[0x04] = NB_LEDS; // led type. (number of leds!?).
         buffer[0x05] = CORSAIR_LIGHTING_NODE_MODE_STATIC; // mode: static.
         buffer[0x06] = 0x00; // speed.
         buffer[0x07] = 0x00; // direction.
@@ -119,6 +116,7 @@ impl Device {
 
         let n_read = self.device.read(&mut buffer[0..16]).unwrap();
         assert_eq!(n_read, 16);
+        assert_eq!(buffer[0], 0);
     }
 
     fn send_commit(&self, channel_id: u8) {
@@ -131,5 +129,45 @@ impl Device {
 
         let n_read = self.device.read(&mut buffer[0..16]).unwrap();
         assert_eq!(n_read, 16);
+        assert_eq!(buffer[0], 0);
+    }
+
+    pub fn set_color(&self, color: &RGB) {
+        // println!("set_color: {color:?}");
+        for channel_id in 0..CHANNEL_COUNT {
+            self.send_port_state(channel_id, CORSAIR_LIGHTING_NODE_PORT_STATE_SOFTWARE);
+
+            let mut buffer = [0u8; 65];
+
+            for color_channel in [
+                CORSAIR_LIGHTING_NODE_DIRECT_CHANNEL_RED,
+                CORSAIR_LIGHTING_NODE_DIRECT_CHANNEL_GREEN,
+                CORSAIR_LIGHTING_NODE_DIRECT_CHANNEL_BLUE,
+            ] {
+                buffer[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_DIRECT;
+                buffer[0x02] = channel_id;
+                buffer[0x04] = NB_LEDS; // Number of color;
+                buffer[0x05] = color_channel;
+
+                let color_component =  match color_channel {
+                    0 => color.red,
+                    1 => color.green,
+                    _ => color.blue,
+                };
+
+                for n in 0..NB_LEDS {
+                    buffer[0x06 + n as usize] = color_component;
+                }
+
+                let n_write = self.device.write(&buffer).unwrap();
+                assert_eq!(n_write, 65);
+
+                let n_read = self.device.read(&mut buffer[0..16]).unwrap();
+                assert_eq!(n_read, 16);
+                assert_eq!(buffer[0], 0);
+            }
+
+            self.send_commit(channel_id);
+        }
     }
 }