From 184011c232d4fd13e6ea9a18e3c6ac3c1f2d971c Mon Sep 17 00:00:00 2001 From: hodasemi Date: Mon, 23 Oct 2023 10:32:52 +0200 Subject: [PATCH] Implement temperature push --- src/action.rs | 26 ++++++++++++++++++++++++++ src/main.rs | 4 +--- src/task_scheduler.rs | 7 ------- src/temperature.rs | 24 ++++++++++++++++++++++-- src/web_server.rs | 5 +++++ 5 files changed, 54 insertions(+), 12 deletions(-) diff --git a/src/action.rs b/src/action.rs index f1e000e..b6b1583 100644 --- a/src/action.rs +++ b/src/action.rs @@ -67,6 +67,32 @@ pub struct ActionSet { } impl ActionSet { + pub fn push_device(&self) -> Option { + self.iter() + .find(|action| action.action_type == ActionType::Push) + .map(|action| action.device_id.clone()) + } + + pub fn receive_device(&self) -> Option { + self.iter() + .find(|action| action.action_type == ActionType::Receive) + .map(|action| action.device_id.clone()) + } + + pub fn begins_with_device(&self, device_name: &str) -> bool { + match self.actions.get(0) { + Some(action) => action.device_id == device_name, + None => false, + } + } + + pub fn parameter(&self, parameter: &str) -> bool { + match self.actions.get(0) { + Some(action) => action.parameter == parameter, + None => false, + } + } + pub fn chain(&mut self, action: Action) { self.actions.push(action); } diff --git a/src/main.rs b/src/main.rs index 33502c5..37aa32f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,6 @@ use std::{ fs, - pin::pin, sync::{Arc, Mutex}, - thread, time::{Duration, SystemTime, UNIX_EPOCH}, }; @@ -23,7 +21,7 @@ use actix_cors::Cors; use actix_web::{web::Data, App, HttpServer}; use anyhow::Result; use devices::Devices; -use futures::{future::try_join_all, try_join, Future}; +use futures::{try_join, Future}; use midea_helper::MideaDishwasher; use task_scheduler::{Scheduler, Task}; use tasmota::Tasmota; diff --git a/src/task_scheduler.rs b/src/task_scheduler.rs index 28b4bc0..8836e5b 100644 --- a/src/task_scheduler.rs +++ b/src/task_scheduler.rs @@ -67,13 +67,6 @@ impl Task { fn execution_time(&self) -> SystemTime { self.creation_time + self.time } - - fn reschedule(&self) -> bool { - match self.callback { - Callback::Looping(_) => true, - Callback::Once(_) => false, - } - } } #[derive(Default, Clone)] diff --git a/src/temperature.rs b/src/temperature.rs index 1e8cc3d..70dd576 100644 --- a/src/temperature.rs +++ b/src/temperature.rs @@ -1,6 +1,7 @@ use std::{ net::IpAddr, sync::{Arc, Mutex}, + time::Duration, }; use actix_web::web::Data; @@ -8,7 +9,11 @@ use anyhow::{bail, Result}; use dns_lookup::{lookup_addr, lookup_host}; use reqwest::Client; -use crate::{db::DataBase, since_epoch}; +use crate::{ + db::DataBase, + since_epoch, + task_scheduler::{Scheduler, Task}, +}; pub struct Thermostat { device: String, @@ -54,6 +59,7 @@ impl Thermometer { change: ThermometerChange, ip: IpAddr, db: Data>>, + scheduler: Data, ) -> Result<()> { let db_lock = db.lock().unwrap(); let device_id = lookup_addr(&ip)?.trim_end_matches(".fritz.box").to_string(); @@ -63,7 +69,21 @@ impl Thermometer { ThermometerChange::Temperature(temp) => { db_lock.write(&device_id, since_epoch()?, "temperature", temp)?; - // maybe push to thermostate + for action_set in db_lock.action_sets(&device_id)? { + if let Some(push_device) = action_set.push_device() { + if action_set.parameter("temperature") && push_device == device_id { + if let Some(receive_device) = action_set.receive_device() { + scheduler.add_task(Task::one_shot( + Duration::from_secs(0), + Box::pin(async move { + let _ = Thermostat::new(receive_device) + .set_temperature(temp); + }), + )); + } + } + } + } } ThermometerChange::Humidity(humid) => { db_lock.write(&device_id, since_epoch()?, "humidity", humid)?; diff --git a/src/web_server.rs b/src/web_server.rs index 74ce049..f672553 100644 --- a/src/web_server.rs +++ b/src/web_server.rs @@ -9,6 +9,7 @@ use serde_json::to_string; use crate::{ db::DataBase, + task_scheduler::Scheduler, tasmota::Tasmota, temperature::{Thermometer, ThermometerChange}, }; @@ -235,12 +236,14 @@ async fn push_temperature( param: Path, req: HttpRequest, db: Data>>, + scheduler: Data, ) -> Result { if let Some(val) = req.peer_addr() { Thermometer::push_change( ThermometerChange::Temperature(param.into_inner()), val.ip(), db, + scheduler, ) .map_err(|err| MyError::from(err))?; } @@ -253,12 +256,14 @@ async fn push_humidity( param: Path, req: HttpRequest, db: Data>>, + scheduler: Data, ) -> Result { if let Some(val) = req.peer_addr() { Thermometer::push_change( ThermometerChange::Humidity(param.into_inner()), val.ip(), db, + scheduler, ) .map_err(|err| MyError::from(err))?; }