Added hue_bridge to bridge across the presence and darkness events

This commit is contained in:
Dreaded_X 2023-01-05 03:01:21 +01:00
parent 69abaf98d7
commit f88c7a5695
Signed by: Dreaded_X
GPG Key ID: 76BDEC4E165D8AD9
5 changed files with 100 additions and 2 deletions

View File

@ -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

View File

@ -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<String, Device>
}
@ -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,

74
src/hue_bridge.rs Normal file
View File

@ -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);
}
}

View File

@ -5,3 +5,4 @@ pub mod config;
pub mod presence;
pub mod ntfy;
pub mod light_sensor;
pub mod hue_bridge;

View File

@ -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));