You can now add remotes to HueGroups

This commit is contained in:
Dreaded_X 2023-08-24 01:49:55 +02:00
parent 5d6faddce1
commit 1ba20c3390
Signed by: Dreaded_X
GPG Key ID: FA5F485356B0D2D4
3 changed files with 48 additions and 8 deletions

View File

@ -100,6 +100,7 @@ login = "${HUE_TOKEN}"
group_id = 81 group_id = 81
scene_id = "3qWKxGVadXFFG4o" scene_id = "3qWKxGVadXFFG4o"
timer_id = 1 timer_id = 1
remotes = [{ topic = "zigbee2mqtt/hallway/remote" }]
[device.hallway_frontdoor] [device.hallway_frontdoor]
type = "ContactSensor" type = "ContactSensor"

View File

@ -102,6 +102,7 @@ login = "${HUE_TOKEN}"
group_id = 81 group_id = 81
scene_id = "3qWKxGVadXFFG4o" scene_id = "3qWKxGVadXFFG4o"
timer_id = 1 timer_id = 1
remotes = [{ topic = "zigbee2mqtt/hallway/remote" }]
[device.hallway_frontdoor] [device.hallway_frontdoor]
type = "ContactSensor" type = "ContactSensor"

View File

@ -6,12 +6,16 @@ use std::{
use anyhow::{anyhow, Context, Result}; use anyhow::{anyhow, Context, Result};
use async_trait::async_trait; use async_trait::async_trait;
use google_home::{errors::ErrorCode, traits::OnOff}; use google_home::{errors::ErrorCode, traits::OnOff};
use rumqttc::Publish;
use serde::Deserialize; use serde::Deserialize;
use tracing::{error, warn}; use tracing::{debug, error, warn};
use crate::{ use crate::{
config::MqttDeviceConfig,
device_manager::{ConfigExternal, DeviceConfig}, device_manager::{ConfigExternal, DeviceConfig},
error::DeviceConfigError, error::DeviceConfigError,
event::OnMqtt,
messages::{RemoteAction, RemoteMessage},
traits::Timeout, traits::Timeout,
}; };
@ -24,6 +28,8 @@ pub struct HueGroupConfig {
pub group_id: isize, pub group_id: isize,
pub timer_id: isize, pub timer_id: isize,
pub scene_id: String, pub scene_id: String,
#[serde(default)]
pub remotes: Vec<MqttDeviceConfig>,
} }
#[async_trait] #[async_trait]
@ -40,6 +46,7 @@ impl DeviceConfig for HueGroupConfig {
group_id: self.group_id, group_id: self.group_id,
scene_id: self.scene_id, scene_id: self.scene_id,
timer_id: self.timer_id, timer_id: self.timer_id,
remotes: self.remotes,
}; };
Ok(Box::new(device)) Ok(Box::new(device))
@ -48,12 +55,13 @@ impl DeviceConfig for HueGroupConfig {
#[derive(Debug)] #[derive(Debug)]
struct HueGroup { struct HueGroup {
pub identifier: String, identifier: String,
pub addr: SocketAddr, addr: SocketAddr,
pub login: String, login: String,
pub group_id: isize, group_id: isize,
pub timer_id: isize, timer_id: isize,
pub scene_id: String, scene_id: String,
remotes: Vec<MqttDeviceConfig>,
} }
// Couple of helper function to get the correct urls // 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] #[async_trait]
impl OnOff for HueGroup { impl OnOff for HueGroup {
async fn set_on(&mut self, on: bool) -> Result<(), ErrorCode> { async fn set_on(&mut self, on: bool) -> Result<(), ErrorCode> {
@ -90,7 +128,7 @@ impl OnOff for HueGroup {
let message = if on { let message = if on {
message::Action::scene(self.scene_id.clone()) message::Action::scene(self.scene_id.clone())
} else { } else {
message::Action::on(true) message::Action::on(false)
}; };
let res = reqwest::Client::new() let res = reqwest::Client::new()