Implement temperature push

This commit is contained in:
hodasemi 2023-10-23 10:32:52 +02:00
parent 0650270b22
commit 184011c232
5 changed files with 54 additions and 12 deletions

View file

@ -67,6 +67,32 @@ pub struct ActionSet {
}
impl ActionSet {
pub fn push_device(&self) -> Option<String> {
self.iter()
.find(|action| action.action_type == ActionType::Push)
.map(|action| action.device_id.clone())
}
pub fn receive_device(&self) -> Option<String> {
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);
}

View file

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

View file

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

View file

@ -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<Arc<Mutex<DataBase>>>,
scheduler: Data<Scheduler>,
) -> 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)?;

View file

@ -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<f32>,
req: HttpRequest,
db: Data<Arc<Mutex<DataBase>>>,
scheduler: Data<Scheduler>,
) -> Result<impl Responder, Error> {
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<f32>,
req: HttpRequest,
db: Data<Arc<Mutex<DataBase>>>,
scheduler: Data<Scheduler>,
) -> Result<impl Responder, Error> {
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))?;
}