diff --git a/config/config.toml b/config/config.toml index ab2d600..d887300 100644 --- a/config/config.toml +++ b/config/config.toml @@ -100,6 +100,7 @@ login = "${HUE_TOKEN}" group_id = 81 scene_id = "3qWKxGVadXFFG4o" timer_id = 1 +remotes = [{ topic = "zigbee2mqtt/hallway/remote" }] [device.hallway_frontdoor] type = "ContactSensor" diff --git a/config/zeus.dev.toml b/config/zeus.dev.toml index b805138..e8aa283 100644 --- a/config/zeus.dev.toml +++ b/config/zeus.dev.toml @@ -102,6 +102,7 @@ login = "${HUE_TOKEN}" group_id = 81 scene_id = "3qWKxGVadXFFG4o" timer_id = 1 +remotes = [{ topic = "zigbee2mqtt/hallway/remote" }] [device.hallway_frontdoor] type = "ContactSensor" diff --git a/src/devices/hue_light.rs b/src/devices/hue_light.rs index d83daa2..8f5ab31 100644 --- a/src/devices/hue_light.rs +++ b/src/devices/hue_light.rs @@ -6,12 +6,16 @@ use std::{ use anyhow::{anyhow, Context, Result}; use async_trait::async_trait; use google_home::{errors::ErrorCode, traits::OnOff}; +use rumqttc::Publish; use serde::Deserialize; -use tracing::{error, warn}; +use tracing::{debug, error, warn}; use crate::{ + config::MqttDeviceConfig, device_manager::{ConfigExternal, DeviceConfig}, error::DeviceConfigError, + event::OnMqtt, + messages::{RemoteAction, RemoteMessage}, traits::Timeout, }; @@ -24,6 +28,8 @@ pub struct HueGroupConfig { pub group_id: isize, pub timer_id: isize, pub scene_id: String, + #[serde(default)] + pub remotes: Vec, } #[async_trait] @@ -40,6 +46,7 @@ impl DeviceConfig for HueGroupConfig { group_id: self.group_id, scene_id: self.scene_id, timer_id: self.timer_id, + remotes: self.remotes, }; Ok(Box::new(device)) @@ -48,12 +55,13 @@ impl DeviceConfig for HueGroupConfig { #[derive(Debug)] struct HueGroup { - pub identifier: String, - pub addr: SocketAddr, - pub login: String, - pub group_id: isize, - pub timer_id: isize, - pub scene_id: String, + identifier: String, + addr: SocketAddr, + login: String, + group_id: isize, + timer_id: isize, + scene_id: String, + remotes: Vec, } // Couple of helper function to get the correct urls @@ -81,6 +89,36 @@ impl Device for HueGroup { } } +#[async_trait] +impl OnMqtt for HueGroup { + fn topics(&self) -> Vec<&str> { + self.remotes + .iter() + .map(|mqtt| mqtt.topic.as_str()) + .collect() + } + + async fn on_mqtt(&mut self, message: Publish) { + let action = match RemoteMessage::try_from(message) { + Ok(message) => message.action(), + Err(err) => { + error!(id = self.identifier, "Failed to parse message: {err}"); + return; + } + }; + + debug!("Action: {action:#?}"); + + match action { + RemoteAction::On | RemoteAction::BrightnessMoveUp => self.set_on(true).await.unwrap(), + RemoteAction::Off | RemoteAction::BrightnessMoveDown => { + self.set_on(false).await.unwrap() + } + RemoteAction::BrightnessStop => { /* Ignore this action */ } + }; + } +} + #[async_trait] impl OnOff for HueGroup { async fn set_on(&mut self, on: bool) -> Result<(), ErrorCode> { @@ -90,7 +128,7 @@ impl OnOff for HueGroup { let message = if on { message::Action::scene(self.scene_id.clone()) } else { - message::Action::on(true) + message::Action::on(false) }; let res = reqwest::Client::new()