use crate::light::{Status, Update, Value, BRIGHTNESS, POWER}; use rumqtt; use rumqtt::{MqttClient, QoS}; pub struct MqttUpdates { client: MqttClient, updates: crossbeam_channel::Receiver, } impl MqttUpdates { pub fn new(client: MqttClient, updates: crossbeam_channel::Receiver) -> Self { MqttUpdates { client, updates } } pub fn add_light(&mut self, id: &str, lampname: &str) -> Result<(), rumqtt::ClientError> { self.client.publish( format!("{}/lights", crate::MQTT_ID), QoS::AtLeastOnce, false, format!("{}:{}", id, lampname), )?; let base_url = format!("{}/{}/", crate::MQTT_ID, lampname); self.client.publish( base_url.clone() + "status/connected", QoS::AtLeastOnce, true, "true", )?; 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(); 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(); } }