2019-01-20 12:02:39 +00:00
|
|
|
use crate::light::{Status, Update, Value, BRIGHTNESS, HUE, KELVIN, POWER, SATURATION};
|
|
|
|
use log::warn;
|
2019-01-16 21:46:12 +00:00
|
|
|
use rumqtt;
|
|
|
|
use rumqtt::{MqttClient, QoS};
|
|
|
|
|
|
|
|
pub struct MqttUpdates {
|
|
|
|
client: MqttClient,
|
|
|
|
updates: crossbeam_channel::Receiver<Status>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl MqttUpdates {
|
|
|
|
pub fn new(client: MqttClient, updates: crossbeam_channel::Receiver<Status>) -> Self {
|
|
|
|
MqttUpdates { client, updates }
|
|
|
|
}
|
2019-02-09 17:32:23 +00:00
|
|
|
pub fn add_light(&mut self, id: &str, lightname: &str) -> Result<(), rumqtt::ClientError> {
|
|
|
|
info!("Add light: {}", lightname);
|
2019-01-16 21:46:12 +00:00
|
|
|
self.client.publish(
|
2019-02-09 19:02:14 +00:00
|
|
|
format!("/{}/lights", crate::MQTT_ID),
|
2019-01-16 21:46:12 +00:00
|
|
|
QoS::AtLeastOnce,
|
|
|
|
false,
|
2019-02-09 17:32:23 +00:00
|
|
|
format!("{}:{}", id, lightname),
|
2019-01-16 21:46:12 +00:00
|
|
|
)?;
|
2019-02-09 19:02:14 +00:00
|
|
|
let base_url = format!("/{}/lights/{}/", crate::MQTT_ID, lightname);
|
2019-01-16 21:46:12 +00:00
|
|
|
self.client.publish(
|
2019-01-20 09:02:44 +00:00
|
|
|
base_url.clone() + "status/connected",
|
2019-01-16 21:46:12 +00:00
|
|
|
QoS::AtLeastOnce,
|
2019-01-20 09:02:44 +00:00
|
|
|
true,
|
2019-01-16 21:46:12 +00:00
|
|
|
"true",
|
|
|
|
)?;
|
2019-01-20 09:02:44 +00:00
|
|
|
self.client
|
|
|
|
.subscribe(base_url.clone() + "command/" + POWER, QoS::AtLeastOnce)?;
|
|
|
|
self.client
|
|
|
|
.subscribe(base_url.clone() + "command/" + BRIGHTNESS, QoS::AtLeastOnce)?;
|
2019-01-20 12:02:39 +00:00
|
|
|
self.client
|
|
|
|
.subscribe(base_url.clone() + "command/" + HUE, QoS::AtLeastOnce)?;
|
|
|
|
self.client
|
|
|
|
.subscribe(base_url.clone() + "command/" + SATURATION, QoS::AtLeastOnce)?;
|
|
|
|
self.client
|
|
|
|
.subscribe(base_url.clone() + "command/" + KELVIN, QoS::AtLeastOnce)?;
|
2019-01-16 21:46:12 +00:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn listen(&mut self) {
|
|
|
|
while let Ok(status) = self.updates.recv() {
|
|
|
|
match status {
|
2019-01-20 09:02:44 +00:00
|
|
|
Status::New(light) => {
|
2019-01-20 12:02:39 +00:00
|
|
|
if let Err(err) = self.add_light(&light.id, &light.label) {
|
|
|
|
warn!("{}", err);
|
|
|
|
continue;
|
|
|
|
}
|
2019-01-20 09:02:44 +00:00
|
|
|
self.handle_update(Update::new(&light.label, Value::Power(light.power)));
|
|
|
|
self.handle_update(Update::new(
|
|
|
|
&light.label,
|
|
|
|
Value::Brightness(light.brightness),
|
|
|
|
));
|
2019-01-20 12:02:39 +00:00
|
|
|
self.handle_update(Update::new(&light.label, Value::Hue(light.color.hue)));
|
|
|
|
self.handle_update(Update::new(
|
|
|
|
&light.label,
|
|
|
|
Value::Saturation(light.color.saturation),
|
|
|
|
));
|
|
|
|
self.handle_update(Update::new(
|
|
|
|
&light.label,
|
|
|
|
Value::Kelvin(light.color.kelvin),
|
|
|
|
));
|
2019-01-16 21:46:12 +00:00
|
|
|
}
|
2019-01-20 12:02:39 +00:00
|
|
|
Status::Remove(_name) => {
|
|
|
|
if let Err(err) = self.client.publish(
|
2019-02-09 19:02:14 +00:00
|
|
|
format!("/{}/lights/{}/status/connected", crate::MQTT_ID, _name),
|
2019-01-20 09:02:44 +00:00
|
|
|
QoS::AtLeastOnce,
|
|
|
|
true,
|
|
|
|
"false",
|
2019-01-20 12:02:39 +00:00
|
|
|
) {
|
|
|
|
warn!("{}", err);
|
|
|
|
}
|
|
|
|
}
|
2019-01-20 09:02:44 +00:00
|
|
|
Status::Update(update) => self.handle_update(update),
|
2019-01-16 21:46:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-01-20 09:02:44 +00:00
|
|
|
|
|
|
|
fn handle_update(&mut self, update: Update) {
|
|
|
|
let (detail, value) = update.status.unravel();
|
2019-01-20 12:02:39 +00:00
|
|
|
if let Err(err) = self.client.publish(
|
2019-02-09 17:32:23 +00:00
|
|
|
format!(
|
2019-02-09 19:02:14 +00:00
|
|
|
"/{}/lights/{}/status/{}",
|
2019-02-09 17:32:23 +00:00
|
|
|
crate::MQTT_ID,
|
|
|
|
update.lightname,
|
|
|
|
detail
|
|
|
|
),
|
2019-01-20 12:02:39 +00:00
|
|
|
QoS::AtLeastOnce,
|
|
|
|
true,
|
|
|
|
value,
|
|
|
|
) {
|
|
|
|
warn!("{}", err);
|
|
|
|
}
|
2019-01-20 09:02:44 +00:00
|
|
|
}
|
2019-01-16 21:46:12 +00:00
|
|
|
}
|