diff --git a/Cargo.lock b/Cargo.lock index 08e0c85..13199b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -47,7 +47,7 @@ dependencies = [ [[package]] name = "autocfg" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -55,7 +55,7 @@ name = "backtrace" version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.47 (registry+https://github.com/rust-lang/crates.io-index)", @@ -221,10 +221,10 @@ name = "derive_more" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.25 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.25 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -266,9 +266,9 @@ name = "failure_derive" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.25 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.25 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -433,9 +433,9 @@ dependencies = [ "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.36 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -483,8 +483,8 @@ dependencies = [ "lifxi 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rumqtt 0.30.0 (git+https://github.com/AtherEnergy/rumqtt)", - "serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -493,8 +493,8 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "reqwest 0.9.8 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -771,7 +771,7 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "0.4.24" +version = "0.4.25" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -787,7 +787,7 @@ name = "quote" version = "0.6.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.25 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -807,7 +807,7 @@ name = "rand" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.47 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -824,7 +824,7 @@ name = "rand_chacha" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -953,8 +953,8 @@ dependencies = [ "mime 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", "mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.36 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -992,8 +992,8 @@ dependencies = [ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "mqtt311 0.2.0 (git+https://github.com/tekjar/mqtt311)", "pretty_env_logger 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1098,27 +1098,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.84" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_derive" -version = "1.0.84" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.25 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.25 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_json" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1128,7 +1128,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1167,10 +1167,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "syn" -version = "0.15.25" +version = "0.15.26" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.25 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1180,9 +1180,9 @@ name = "synstructure" version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.25 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.25 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1494,7 +1494,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1598,7 +1598,7 @@ dependencies = [ "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71" "checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" -"checksum autocfg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4e5f34df7a019573fb8bdc7e24a2bfebe51a2a1d6bfdbaeccedb3c41fc574727" +"checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799" "checksum backtrace 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)" = "b5b493b66e03090ebc4343eb02f94ff944e0cbc9ac6571491d170ba026741eb5" "checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6" "checksum base64 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "621fc7ecb8008f86d7fb9b95356cd692ce9514b80a86d85b397f32a22da7b9e2" @@ -1678,7 +1678,7 @@ dependencies = [ "checksum phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0" "checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" "checksum pretty_env_logger 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ed8d1e63042e889b85228620629b51c011d380eed2c7e0015f8a644def280c28" -"checksum proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)" = "77619697826f31a02ae974457af0b29b723e5619e113e9397b8b82c6bd253f09" +"checksum proc-macro2 0.4.25 (registry+https://github.com/rust-lang/crates.io-index)" = "d3797b7142c9aa74954e351fc089bbee7958cebbff6bf2815e7ffff0b19f547d" "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" "checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c" "checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" @@ -1712,9 +1712,9 @@ dependencies = [ "checksum security-framework-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "40d95f3d7da09612affe897f320d78264f0d2320f3e8eea27d12bd1bd94445e2" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)" = "0e732ed5a5592c17d961555e3b552985baf98d50ce418b7b655f31f6ba7eb1b7" -"checksum serde_derive 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d6115a3ca25c224e409185325afc16a0d5aaaabc15c42b09587d6f1ba39a5b" -"checksum serde_json 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)" = "dfb1277d4d0563e4593e0b8b5d23d744d277b55d2bc0bf1c38d0d8a6589d38aa" +"checksum serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)" = "534b8b91a95e0f71bca3ed5824752d558da048d4248c91af873b63bd60519752" +"checksum serde_derive 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)" = "a915306b0f1ac5607797697148c223bedeaa36bcc2e28a01441cd638cc6567b4" +"checksum serde_json 1.0.36 (registry+https://github.com/rust-lang/crates.io-index)" = "574378d957d6dcdf1bbb5d562a15cbd5e644159432f84634b94e485267abbcc7" "checksum serde_urlencoded 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d48f9f99cd749a2de71d29da5f948de7f2764cc5a9d7f3c97e3514d4ee6eabf2" "checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" @@ -1722,7 +1722,7 @@ dependencies = [ "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" "checksum string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b639411d0b9c738748b5397d5ceba08e648f4f1992231aa859af1a017f31f60b" "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" -"checksum syn 0.15.25 (registry+https://github.com/rust-lang/crates.io-index)" = "71b7693d9626935a362a3d1d4e59380800a919ebfa478d77a4f49e2a6d2c3ad5" +"checksum syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)" = "f92e629aa1d9c827b2bb8297046c1ccffc57c99b947a680d3ccff1f136a3bee9" "checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" "checksum tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "7e91405c14320e5c79b3d148e1c86f40749a36e490642202a31689cb1a3452b2" "checksum termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f" diff --git a/Cargo.toml b/Cargo.toml index 613413e..9f0a557 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,11 +5,11 @@ authors = ["Lara "] edition = "2018" [dependencies] -rumqtt = { git = "https://github.com/AtherEnergy/rumqtt" } -lifxi = "0.1" clap = "2" +crossbeam-channel = "0.3" +lazy_static = "1" +lifxi = "0.1" +regex = "1" +rumqtt = { git = "https://github.com/AtherEnergy/rumqtt" } serde = "1" serde_derive = "1" -regex = "1" -lazy_static = "1" -crossbeam-channel = "0.3" diff --git a/src/lifx.rs b/src/lifx.rs index 99bf5bd..c1b5eff 100644 --- a/src/lifx.rs +++ b/src/lifx.rs @@ -1,10 +1,13 @@ -use crate::light::{Command, Light, Status}; +use crate::light::{Command, Light, Status, Update, Value}; +use crossbeam_channel::RecvTimeoutError; use lifxi::http::prelude::*; +use std::time::Duration; pub struct Lifx { client: Client, updates: crossbeam_channel::Sender, commands: crossbeam_channel::Receiver, + lights: Vec, } impl Lifx { @@ -17,10 +20,11 @@ impl Lifx { client: Client::new(secret), updates, commands, + lights: vec![], } } - pub fn find_lights(&self) -> Vec { + pub fn get_lights(&self) -> Vec { self.client .select(Selector::All) .list() @@ -30,6 +34,68 @@ impl Lifx { .unwrap() } + pub fn listen(&mut self) { + loop { + match self.commands.recv_timeout(Duration::from_secs(1)) { + Ok(command) => self.handle_command(command), + Err(RecvTimeoutError::Disconnected) => return, + Err(RecvTimeoutError::Timeout) => {} + } + + self.update_lights(); + } + } + + fn update_lights(&mut self) { + let new_lights = self.get_lights(); + + // find changes + for new_light in &new_lights { + if let Some(old_light) = self.lights.iter().find(|x| new_light.id == x.id) { + self.find_diffs(old_light, new_light); + } else { + self.updates.send(Status::New(new_light.clone())).unwrap(); + } + } + + // find removed lamps + self.lights + .iter() + .filter(|o| new_lights.iter().find(|n| n.id == o.id).is_none()) + .for_each(|l| { + self.updates.send(Status::Remove(l.label.clone())).unwrap(); + }); + + self.lights = new_lights; + } + + fn find_diffs(&self, old_light: &Light, new_light: &Light) { + if old_light.power != new_light.power { + self.updates + .send(Status::Update(Update::new( + &new_light.label, + Value::Power(new_light.power.clone()), + ))) + .unwrap(); + } + + if (old_light.brightness - new_light.brightness).abs() < 0.01 { + self.updates + .send(Status::Update(Update::new( + &new_light.label, + Value::Brightness(new_light.brightness), + ))) + .unwrap(); + } + } + + fn handle_command(&self, command: Command) { + match command.command { + Value::Power(val) => self.set_power(command.lampname, val == "on").unwrap(), + Value::Brightness(val) => self.set_brightness(command.lampname, val).unwrap(), + }; + } + fn set_power(&self, id: String, state: bool) -> Result<(), lifxi::http::Error> { self.client .select(Selector::Id(id)) diff --git a/src/light.rs b/src/light.rs index 18af289..38a30fa 100644 --- a/src/light.rs +++ b/src/light.rs @@ -1,11 +1,11 @@ -#[derive(Deserialize, Debug)] +#[derive(Deserialize, Debug, Clone)] pub struct Color { pub hue: f32, pub saturation: f32, pub kelvin: f32, } -#[derive(Deserialize, Debug)] +#[derive(Deserialize, Debug, Clone)] pub struct Light { pub id: String, pub label: String, @@ -15,8 +15,8 @@ pub struct Light { pub brightness: f32, } -const POWER: &str = "power"; -const BRIGHTNESS: &str = "brightness"; +pub const POWER: &str = "power"; +pub const BRIGHTNESS: &str = "brightness"; pub enum Value { Power(String), @@ -27,30 +27,24 @@ impl Value { pub fn new(label: &str, value: Vec) -> Self { match label { POWER => Value::Power(String::from_utf8(value).unwrap()), - BRIGHTNESS => Value::Brightness(Self::vec_to_f32(value)), + BRIGHTNESS => Value::Brightness(vec_to_f32(value)), _ => unimplemented!(), } } - fn vec_to_f32(vec: Vec) -> f32 { - assert!(vec.len() == 4); - let mut value_u32: u32 = 0; - for val in vec.clone() { - value_u32 = value_u32 << 8; - value_u32 = value_u32 | val as u32; - } - println!("{:?} -> {}", vec, value_u32); - f32::from_bits(value_u32) - } - pub fn unravel(self) -> (&'static str, Vec) { match self { Value::Power(val) => (POWER, val.into_bytes()), - Value::Brightness(val) => (BRIGHTNESS, Vec::new()), + Value::Brightness(val) => (BRIGHTNESS, (val as u32).to_ne_bytes().to_vec()), } } } +fn vec_to_f32(value: Vec) -> f32 { + assert!(value.len() == 4); + u32::from_ne_bytes([value[0], value[1], value[2], value[3]]) as f32 +} + pub struct Command { pub lampname: String, pub command: Value, @@ -61,6 +55,15 @@ pub struct Update { pub status: Value, } +impl Update { + pub fn new(lampname: &str, status: Value) -> Self { + Update { + lampname: lampname.to_owned(), + status, + } + } +} + pub enum Status { Update(Update), New(Light), diff --git a/src/main.rs b/src/main.rs index 5f60c6d..56d9fb0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,7 +19,7 @@ use std::thread; pub const MQTT_ID: &str = "lifx-mqtt-bridge"; fn main() { - let matches = App::new("lifx-mqtt-bridge") + let matches = App::new(MQTT_ID) .version("0.1") .about("Lifx Mqtt Bridge") .author("BuntpfotenkÃĪtzchen") @@ -38,9 +38,9 @@ fn main() { .default_value("1883"), ) .arg( - Arg::with_name("lifx_secret") + Arg::with_name("lifx-secret") .short("s") - .long("lifx_secret") + .long("lifx-secret") .required(true) .takes_value(true), ) @@ -48,22 +48,22 @@ fn main() { let host = matches.value_of("host").unwrap(); let port: u16 = matches.value_of("port").unwrap().parse().unwrap(); - let lifx_secret = matches.value_of("lifx_secret").unwrap(); + let lifx_secret = matches.value_of("lifx-secret").unwrap(); println!("Connecting to {}:{}", host, port); let (s_commands, r_commands) = unbounded(); let (s_updates, r_updates) = unbounded(); - let (mqtt_commands, mut mqtt_updates) = match mqtt::mqtt_connect(host, port, s_commands, r_updates) - { - Ok(mqtt) => mqtt, - Err(err) => panic!("Error connecting: {}", err), - }; + let (mqtt_commands, mut mqtt_updates) = + match mqtt::mqtt_connect(host, port, s_commands, r_updates) { + Ok(mqtt) => mqtt, + Err(err) => panic!("Error connecting: {}", err), + }; - let lifx_client = lifx::Lifx::new(lifx_secret, s_updates, r_commands); + let mut lifx_client = lifx::Lifx::new(lifx_secret, s_updates, r_commands); thread::spawn(move || mqtt_commands.listen()); thread::spawn(move || mqtt_updates.listen()); - loop {} + lifx_client.listen(); } diff --git a/src/mqtt_updates.rs b/src/mqtt_updates.rs index 7f7e77d..06b377b 100644 --- a/src/mqtt_updates.rs +++ b/src/mqtt_updates.rs @@ -1,4 +1,4 @@ -use crate::light::Status; +use crate::light::{Status, Update, Value, BRIGHTNESS, POWER}; use rumqtt; use rumqtt::{MqttClient, QoS}; @@ -18,40 +18,54 @@ impl MqttUpdates { false, format!("{}:{}", id, lampname), )?; + let base_url = format!("{}/{}/", crate::MQTT_ID, lampname); self.client.publish( - format!("{}/{}/status/connected", crate::MQTT_ID, lampname), + base_url.clone() + "status/connected", QoS::AtLeastOnce, - false, + true, "true", )?; - self.client.subscribe( - format!("{}/{}/command/power", crate::MQTT_ID, lampname), - QoS::AtLeastOnce, - )?; - self.client.subscribe( - format!("{}/{}/command/brightness", crate::MQTT_ID, lampname), - QoS::AtLeastOnce, - )?; + self.client + .subscribe(base_url.clone() + "command/" + POWER, QoS::AtLeastOnce)?; + self.client + .subscribe(base_url.clone() + "command/" + BRIGHTNESS, QoS::AtLeastOnce)?; Ok(()) } pub fn listen(&mut self) { while let Ok(status) = self.updates.recv() { match status { - Status::New(light) => self.add_light(&light.id, &light.label).unwrap(), - Status::Remove(_name) => unimplemented!(), - Status::Update(update) => { - let (detail, value) = update.status.unravel(); - self.client - .publish( - format!("{}/{}/status/{}", crate::MQTT_ID, update.lampname, detail), - QoS::AtLeastOnce, - true, - value, - ) - .unwrap(); + Status::New(light) => { + self.add_light(&light.id, &light.label).unwrap(); + self.handle_update(Update::new(&light.label, Value::Power(light.power))); + self.handle_update(Update::new( + &light.label, + Value::Brightness(light.brightness), + )); } + Status::Remove(_name) => self + .client + .publish( + format!("{}/{}/status/connected", crate::MQTT_ID, _name), + QoS::AtLeastOnce, + true, + "false", + ) + .unwrap(), + Status::Update(update) => self.handle_update(update), } } } + + fn handle_update(&mut self, update: Update) { + let (detail, value) = update.status.unravel(); + self.client + .publish( + format!("{}/{}/status/{}", crate::MQTT_ID, update.lampname, detail), + QoS::AtLeastOnce, + true, + value, + ) + .unwrap(); + } }