From 55617dbd7c3705260a5e683089f9ad94bc5cab07 Mon Sep 17 00:00:00 2001 From: Tobias Reisinger Date: Thu, 25 Apr 2024 14:10:32 +0200 Subject: [PATCH] Add handler for relay states --- emgauwa-controller/src/app_state.rs | 17 ++++++----------- emgauwa-controller/src/relay_loop.rs | 5 +++-- emgauwa-controller/src/utils.rs | 7 ++++--- emgauwa-controller/src/ws/mod.rs | 7 +++---- .../src/handlers/v1/ws/controllers/handlers.rs | 17 +++++++++++++++++ .../src/handlers/v1/ws/controllers/mod.rs | 3 +++ emgauwa-lib/src/models/controller.rs | 14 ++++++++++++++ emgauwa-lib/src/types/mod.rs | 3 +++ 8 files changed, 53 insertions(+), 20 deletions(-) diff --git a/emgauwa-controller/src/app_state.rs b/emgauwa-controller/src/app_state.rs index e67eabd..a1d31e9 100644 --- a/emgauwa-controller/src/app_state.rs +++ b/emgauwa-controller/src/app_state.rs @@ -3,6 +3,7 @@ use std::sync::Arc; use actix::{Actor, Context, Handler, Message}; use emgauwa_lib::errors::EmgauwaError; use emgauwa_lib::models::Controller; +use emgauwa_lib::types::RelayStates; use futures::executor::block_on; use sqlx::{Pool, Sqlite}; use tokio::sync::Notify; @@ -13,8 +14,8 @@ pub struct Reload {} #[derive(Message)] #[rtype(result = "()")] -pub struct UpdateRelaysOn { - pub relays_are_on: Vec>, +pub struct UpdateRelayStates { + pub relay_states: RelayStates, } #[derive(Message)] @@ -74,17 +75,11 @@ impl Handler for AppState { } } -impl Handler for AppState { +impl Handler for AppState { type Result = (); - fn handle(&mut self, msg: UpdateRelaysOn, _ctx: &mut Self::Context) -> Self::Result { - self.this - .relays - .iter_mut() - .zip(msg.relays_are_on.iter()) - .for_each(|(relay, is_on)| { - relay.is_on = *is_on; - }); + fn handle(&mut self, msg: UpdateRelayStates, _ctx: &mut Self::Context) -> Self::Result { + self.this.apply_relay_states(&msg.relay_states); self.notify_relay_change(); } diff --git a/emgauwa-controller/src/relay_loop.rs b/emgauwa-controller/src/relay_loop.rs index 38fbbb2..f1902fa 100644 --- a/emgauwa-controller/src/relay_loop.rs +++ b/emgauwa-controller/src/relay_loop.rs @@ -5,6 +5,7 @@ use chrono::Local; use emgauwa_lib::constants::RELAYS_RETRY_TIMEOUT; use emgauwa_lib::errors::EmgauwaError; use emgauwa_lib::models::Controller; +use emgauwa_lib::types::RelayStates; use futures::pin_mut; use tokio::time; use tokio::time::timeout; @@ -30,7 +31,7 @@ async fn run_relays(app_state: &Addr) -> Result<(), EmgauwaError> { let mut last_weekday = emgauwa_lib::utils::get_weekday(); let mut this = utils::app_state_get_this(app_state).await?; - let mut relay_states: Vec> = Vec::new(); + let mut relay_states: RelayStates = Vec::new(); init_relay_states(&mut relay_states, &this); loop { @@ -80,7 +81,7 @@ async fn run_relays(app_state: &Addr) -> Result<(), EmgauwaError> { } } -fn init_relay_states(relay_states: &mut Vec>, this: &Controller) { +fn init_relay_states(relay_states: &mut RelayStates, this: &Controller) { relay_states.clear(); for _ in 0..this.c.relay_count { relay_states.push(None); diff --git a/emgauwa-controller/src/utils.rs b/emgauwa-controller/src/utils.rs index 1404f72..c88f340 100644 --- a/emgauwa-controller/src/utils.rs +++ b/emgauwa-controller/src/utils.rs @@ -3,6 +3,7 @@ use std::sync::Arc; use actix::Addr; use emgauwa_lib::errors::EmgauwaError; use emgauwa_lib::models::Controller; +use emgauwa_lib::types::RelayStates; use tokio::sync::Notify; use crate::app_state; @@ -42,11 +43,11 @@ pub async fn app_state_reload(app_state: &Addr) -> Result<(), EmgauwaE pub async fn app_state_update_relays_on( app_state: &Addr, - relay_states: Vec>, + relay_states: RelayStates, ) -> Result<(), EmgauwaError> { app_state - .send(app_state::UpdateRelaysOn { - relays_are_on: relay_states, + .send(app_state::UpdateRelayStates { + relay_states: relay_states, }) .await .map_err(EmgauwaError::from) diff --git a/emgauwa-controller/src/ws/mod.rs b/emgauwa-controller/src/ws/mod.rs index 1799f63..b0a8a98 100644 --- a/emgauwa-controller/src/ws/mod.rs +++ b/emgauwa-controller/src/ws/mod.rs @@ -78,7 +78,9 @@ async fn read_app_state( loop { notifier.notified().await; log::debug!("Relay change detected"); - let ws_action = ControllerWsAction::Register(app_state_get_this(&app_state).await?); + let this = app_state_get_this(&app_state).await?; + let relay_states = this.get_relay_states(); + let ws_action = ControllerWsAction::RelayStates((this.c.uid, relay_states)); let ws_action_json = serde_json::to_string(&ws_action)?; tx.unbounded_send(Message::text(ws_action_json)) @@ -122,9 +124,6 @@ async fn handle_message( log::error!("Error deserializing action: {:?}", e); } }, - Message::Ping(_) => { - log::debug!("Received ping"); - } _ => {} } } diff --git a/emgauwa-core/src/handlers/v1/ws/controllers/handlers.rs b/emgauwa-core/src/handlers/v1/ws/controllers/handlers.rs index 5f7aa37..abdbbe2 100644 --- a/emgauwa-core/src/handlers/v1/ws/controllers/handlers.rs +++ b/emgauwa-core/src/handlers/v1/ws/controllers/handlers.rs @@ -1,7 +1,10 @@ +use std::hash::{Hash, Hasher}; + use actix::{Actor, AsyncContext}; use emgauwa_lib::db::{DbController, DbJunctionRelaySchedule, DbRelay, DbSchedule}; use emgauwa_lib::errors::{DatabaseError, EmgauwaError}; use emgauwa_lib::models::{Controller, FromDbModel}; +use emgauwa_lib::types::{ControllerUid, RelayStates}; use futures::executor::block_on; use sqlx::pool::PoolConnection; use sqlx::Sqlite; @@ -81,4 +84,18 @@ impl ControllerWs { log::debug!("Done registering controller"); Ok(()) } + + pub fn handle_relay_states( + &mut self, + ctx: &mut ::Context, + controller_uid: ControllerUid, + relay_states: RelayStates, + ) -> Result<(), EmgauwaError> { + log::debug!( + "Received relay states: {:?} for {}", + relay_states, + controller_uid + ); + Ok(()) + } } diff --git a/emgauwa-core/src/handlers/v1/ws/controllers/mod.rs b/emgauwa-core/src/handlers/v1/ws/controllers/mod.rs index a205b78..58d8ab6 100644 --- a/emgauwa-core/src/handlers/v1/ws/controllers/mod.rs +++ b/emgauwa-core/src/handlers/v1/ws/controllers/mod.rs @@ -54,6 +54,9 @@ impl ControllerWs { ) { let action_res = match action { ControllerWsAction::Register(controller) => self.handle_register(conn, ctx, controller), + ControllerWsAction::RelayStates((controller_uid, relay_states)) => { + self.handle_relay_states(ctx, controller_uid, relay_states) + } _ => Ok(()), }; if let Err(e) = action_res { diff --git a/emgauwa-lib/src/models/controller.rs b/emgauwa-lib/src/models/controller.rs index 36148ee..40e7bdc 100644 --- a/emgauwa-lib/src/models/controller.rs +++ b/emgauwa-lib/src/models/controller.rs @@ -7,6 +7,7 @@ use sqlx::Sqlite; use crate::db::DbController; use crate::errors::{DatabaseError, EmgauwaError}; use crate::models::{convert_db_list_cache, FromDbModel, Relay}; +use crate::types::RelayStates; #[derive(Serialize, Deserialize, Debug, Clone, MessageResponse)] pub struct Controller { @@ -48,4 +49,17 @@ impl Controller { } Ok(()) } + + pub fn apply_relay_states(&mut self, relay_states: &RelayStates) { + self.relays + .iter_mut() + .zip(relay_states.iter()) + .for_each(|(relay, is_on)| { + relay.is_on = *is_on; + }); + } + + pub fn get_relay_states(&self) -> RelayStates { + self.relays.iter().map(|r| r.is_on).collect() + } } diff --git a/emgauwa-lib/src/types/mod.rs b/emgauwa-lib/src/types/mod.rs index dcf88d1..f131e16 100644 --- a/emgauwa-lib/src/types/mod.rs +++ b/emgauwa-lib/src/types/mod.rs @@ -14,6 +14,8 @@ use crate::models::{Controller, Relay}; pub type Weekday = i64; +pub type RelayStates = Vec>; + #[derive(Debug, Serialize, Deserialize, Message)] #[rtype(result = "Result<(), EmgauwaError>")] pub enum ControllerWsAction { @@ -22,4 +24,5 @@ pub enum ControllerWsAction { Schedules(Vec), Relays(Vec), Controller(Controller), + RelayStates((ControllerUid, RelayStates)), }