magichue_rs/
lib.rs

1use std::net::TcpStream;
2use std::io::{self, Write};
3
4
5fn gen_rgb(r: u8, g: u8, b: u8, brightness: u8) -> (u8, u8, u8) {
6    let scale = brightness as f32 / 255.0;
7    (
8        (r as f32 * scale) as u8,
9        (g as f32 * scale) as u8,
10        (b as f32 * scale) as u8,
11    )
12}
13
14fn on() -> Vec<u8> {
15    vec![0x71, 0x23, 0x0F, 0xA4]
16}
17
18fn off() -> Vec<u8> {
19    vec![0x71, 0x24, 0x0F, 0xA4]
20}
21
22fn mk_rgb(r: u8, g: u8, b: u8, brightness: u8) -> Vec<u8> {
23    let (r_scaled, g_scaled, b_scaled) = gen_rgb(r, g, b, brightness);
24    vec![0x31, r_scaled, g_scaled, b_scaled, 0, 0, 0xF0, 0x0F, 0x2F]
25}
26
27fn mk_ww(brightness: u8) -> Vec<u8> {
28    vec![0x31, 0x00, 0x00, 0x00, brightness, 0x00, 0x0F, 0x0F, 0x4E]
29}
30
31fn mk_cw(brightness: u8) -> Vec<u8> {
32    vec![0x31, 0x00, 0x00, 0x00, 0x00, brightness, 0x0F, 0x0F, 0x4E]
33}
34
35pub struct MagicBulb {
36    ip: String,
37    stream: Option<std::net::TcpStream>,
38}
39
40impl MagicBulb {
41    pub fn new(ip: &str) -> Self {
42        MagicBulb {
43            ip: ip.to_string() + ":5577",
44            stream: None,
45        }
46    }
47
48    pub fn connect(&mut self) -> io::Result<()> {
49        let stream = TcpStream::connect(&self.ip)?; 
50        self.stream = Some(stream);                   
51        Ok(())
52    }
53
54    fn send(&mut self, data: &[u8]) -> io::Result<()> {
55        if let Some(ref mut stream) = self.stream {
56            stream.write_all(data)?;
57            Ok(())
58        } else {
59            Err(io::Error::new(io::ErrorKind::NotConnected, "No connection"))
60        }
61    }
62
63    pub fn turn_on(&mut self) -> io::Result<()> {
64        self.send(&on())
65    }
66
67    pub fn turn_off(&mut self) -> io::Result<()> {
68        self.send(&off())
69    }
70
71    pub fn set_rgb(&mut self, r: u8, g: u8, b: u8, brightness: u8) -> io::Result<()> {
72        self.send(&mk_rgb(r, g, b, brightness))
73    }
74
75    pub fn set_ww(&mut self, brightness: u8) -> io::Result<()> {
76        self.send(&mk_ww(brightness))
77    }
78
79    pub fn set_cw(&mut self, brightness: u8) -> io::Result<()> {
80        self.send(&mk_cw(brightness))
81    }
82}
83