From f88c7a569504309ac3c336b2cb4b68a422c6f216 Mon Sep 17 00:00:00 2001 From: Dreaded_X Date: Thu, 5 Jan 2023 03:01:21 +0100 Subject: [PATCH] Added hue_bridge to bridge across the presence and darkness events --- config/zeus.dev.toml | 5 +++ src/config.rs | 14 +++++++++ src/hue_bridge.rs | 74 ++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 1 + src/main.rs | 8 +++-- 5 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 src/hue_bridge.rs diff --git a/config/zeus.dev.toml b/config/zeus.dev.toml index 01044a1..fded465 100644 --- a/config/zeus.dev.toml +++ b/config/zeus.dev.toml @@ -9,6 +9,11 @@ username="Dreaded_X" [presence] topic = "automation_dev/presence" +[hue_bridge] +ip = "10.0.0.146" +login = "yPZs07rEirWOKkDhAO6ggCMT9T4Xb-FJYnqnTOLF" +flags = { presence = 41, darkness = 43 } + [light_sensor] topic = "zigbee2mqtt_dev/living/light" min = 23_000 diff --git a/src/config.rs b/src/config.rs index 76399ff..ee32f85 100644 --- a/src/config.rs +++ b/src/config.rs @@ -16,6 +16,7 @@ pub struct Config { pub ntfy: NtfyConfig, pub presence: MqttDeviceConfig, pub light_sensor: LightSensorConfig, + pub hue_bridge: HueBridgeConfig, #[serde(default)] pub devices: HashMap } @@ -64,6 +65,19 @@ pub struct LightSensorConfig { pub max: isize, } +#[derive(Debug, Deserialize)] +pub struct Flags { + pub presence: isize, + pub darkness: isize, +} + +#[derive(Debug, Deserialize)] +pub struct HueBridgeConfig { + pub ip: Ipv4Addr, + pub login: String, + pub flags: Flags, +} + #[derive(Debug, Deserialize)] pub struct InfoConfig { pub name: String, diff --git a/src/hue_bridge.rs b/src/hue_bridge.rs new file mode 100644 index 0000000..29452f9 --- /dev/null +++ b/src/hue_bridge.rs @@ -0,0 +1,74 @@ +use std::net::SocketAddr; + +use pollster::FutureExt; +use serde::Serialize; +use tracing::{warn, error, trace}; + +use crate::{config::{HueBridgeConfig, Flags}, presence::OnPresence, light_sensor::OnDarkness}; + +pub enum Flag { + Presence, + Darkness, +} + +pub struct HueBridge { + addr: SocketAddr, + login: String, + flags: Flags, +} + +#[derive(Debug, Serialize)] +struct FlagMessage { + flag: bool +} + +impl HueBridge { + pub fn new(config: HueBridgeConfig) -> Self { + Self { + addr: (config.ip, 80).into(), + login: config.login, + flags: config.flags, + } + } + + pub fn set_flag(&self, flag: Flag, value: bool) { + let flag = match flag { + Flag::Presence => self.flags.presence, + Flag::Darkness => self.flags.darkness, + }; + + let url = format!("http://{}/api/{}/sensors/{flag}/state", self.addr, self.login); + let json = serde_json::to_string(&FlagMessage{ flag: value }).unwrap(); + let client = reqwest::Client::new(); + let res = client.put(url) + .body(json) + .send() + .block_on(); + + match res { + Ok(res) => { + let status = res.status(); + if !status.is_success() { + warn!(flag, "Status code is not success: {status}"); + } + }, + Err(err) => { + error!(flag, "Error: {err}"); + } + } + } +} + +impl OnPresence for HueBridge { + fn on_presence(&mut self, presence: bool) { + trace!("Bridging presence to hue"); + self.set_flag(Flag::Presence, presence); + } +} + +impl OnDarkness for HueBridge { + fn on_darkness(&mut self, dark: bool) { + trace!("Bridging darkness to hue"); + self.set_flag(Flag::Darkness, dark); + } +} diff --git a/src/lib.rs b/src/lib.rs index 8007f50..4138364 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,3 +5,4 @@ pub mod config; pub mod presence; pub mod ntfy; pub mod light_sensor; +pub mod hue_bridge; diff --git a/src/main.rs b/src/main.rs index c20b6d7..9161426 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,12 +3,12 @@ use std::{time::Duration, sync::{Arc, RwLock}, process, net::SocketAddr}; use axum::{Router, Json, routing::post, http::StatusCode}; -use automation::{config::Config, presence::Presence, ntfy::Ntfy, light_sensor::{self, LightSensor}}; +use automation::{config::Config, presence::Presence, ntfy::Ntfy, light_sensor::{self, LightSensor}, hue_bridge::HueBridge}; use dotenv::dotenv; use rumqttc::{MqttOptions, Transport, AsyncClient}; use tracing::{error, info, metadata::LevelFilter}; -use automation::{devices::{Devices}, mqtt::Mqtt}; +use automation::{devices::Devices, mqtt::Mqtt}; use google_home::{GoogleHome, Request}; use tracing_subscriber::EnvFilter; @@ -54,12 +54,16 @@ async fn main() { let ntfy = Arc::new(RwLock::new(Ntfy::new(config.ntfy))); presence.add_listener(Arc::downgrade(&ntfy)); + let hue_bridge = Arc::new(RwLock::new(HueBridge::new(config.hue_bridge))); + presence.add_listener(Arc::downgrade(&hue_bridge)); + // Register presence as mqtt listener let presence = Arc::new(RwLock::new(presence)); mqtt.add_listener(Arc::downgrade(&presence)); let mut light_sensor = LightSensor::new(config.light_sensor, client.clone()); light_sensor.add_listener(Arc::downgrade(&devices)); + light_sensor.add_listener(Arc::downgrade(&hue_bridge)); let light_sensor = Arc::new(RwLock::new(light_sensor)); mqtt.add_listener(Arc::downgrade(&light_sensor));