From 4f48b04acc0b341eeafa0ceed5397497056ba198 Mon Sep 17 00:00:00 2001 From: Tobias Reisinger Date: Thu, 30 May 2024 02:37:40 +0200 Subject: [PATCH] Add setting to change "midnight" of day --- controller.pkl | 2 +- src/app_state.rs | 5 ++--- src/main.rs | 6 +++--- src/relay_loop.rs | 41 +++++++++++++++++++++++++++-------------- src/settings.rs | 3 +++ src/ws/handlers.rs | 3 +-- 6 files changed, 37 insertions(+), 23 deletions(-) diff --git a/controller.pkl b/controller.pkl index 98dfdb2..3685ba0 100644 --- a/controller.pkl +++ b/controller.pkl @@ -1,4 +1,4 @@ -amends "package://emgauwa.app/pkl/emgauwa@0.1.1#/controller.pkl" +amends "package://emgauwa.app/pkl/emgauwa@0.2.0#/controller.pkl" logging { level = "DEBUG" diff --git a/src/app_state.rs b/src/app_state.rs index d53de02..cfe8d62 100644 --- a/src/app_state.rs +++ b/src/app_state.rs @@ -6,7 +6,7 @@ use emgauwa_common::constants; use emgauwa_common::db::DbSchedule; use emgauwa_common::errors::EmgauwaError; use emgauwa_common::models::Controller; -use emgauwa_common::types::{RelayStates, Weekday}; +use emgauwa_common::types::{EmgauwaNow, RelayStates}; use futures::executor::block_on; use sqlx::{Pool, Sqlite}; use tokio::sync::Notify; @@ -36,7 +36,6 @@ pub struct RelayPulse { pub struct RelayOverrideSchedule { pub relay_number: i64, pub schedule: Option, - pub weekday: Weekday, } #[derive(Message)] @@ -177,7 +176,7 @@ impl Handler for AppState { fn handle(&mut self, msg: RelayOverrideSchedule, _ctx: &mut Self::Context) -> Self::Result { let relay_num = msg.relay_number; let schedule = msg.schedule; - let weekday = msg.weekday; + let weekday = EmgauwaNow::now(&self.settings.midnight).weekday; let relay = self .this diff --git a/src/main.rs b/src/main.rs index 0da73b5..c3be8a6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -97,7 +97,7 @@ async fn main() -> Result<(), std::io::Error> { let mut this = Controller::from_db_model(&mut conn, db_controller).map_err(EmgauwaError::from)?; - let now = EmgauwaNow::now(); + let now = EmgauwaNow::now(&settings.midnight); let initial_states: Vec = this .relays .iter_mut() @@ -115,12 +115,12 @@ async fn main() -> Result<(), std::io::Error> { settings.server.host, settings.server.port ); - let app_state = app_state::AppState::new(pool.clone(), this, settings, drivers).start(); + let app_state = app_state::AppState::new(pool.clone(), this, settings.clone(), drivers).start(); log::info!("Starting main loops"); let _ = tokio::join!( - tokio::spawn(run_relays_loop(app_state.clone())), + tokio::spawn(run_relays_loop(app_state.clone(), settings.clone())), tokio::spawn(run_ws_loop(pool.clone(), app_state.clone(), url)), ); diff --git a/src/relay_loop.rs b/src/relay_loop.rs index 366a3de..6196501 100644 --- a/src/relay_loop.rs +++ b/src/relay_loop.rs @@ -1,11 +1,11 @@ use std::time::Duration; use actix::Addr; -use chrono::Timelike; +use chrono::{Timelike, Weekday}; use emgauwa_common::constants::RELAYS_RETRY_TIMEOUT; use emgauwa_common::errors::EmgauwaError; use emgauwa_common::models::Controller; -use emgauwa_common::types::{EmgauwaNow, Weekday}; +use emgauwa_common::types::EmgauwaNow; use emgauwa_common::utils::printable_relay_states; use futures::pin_mut; use tokio::time; @@ -13,11 +13,12 @@ use tokio::time::timeout; use crate::app_state::AppState; use crate::app_state; +use crate::settings::Settings; -pub async fn run_relays_loop(app_state: Addr) { +pub async fn run_relays_loop(app_state: Addr, settings: Settings) { log::debug!("Spawned relays loop"); loop { - let run_result = run_relays(&app_state).await; + let run_result = run_relays(&app_state, &settings).await; if let Err(err) = run_result { log::error!("Error running relays: {}", err); } @@ -25,18 +26,21 @@ pub async fn run_relays_loop(app_state: Addr) { } } -async fn run_relays(app_state: &Addr) -> Result<(), EmgauwaError> { +async fn run_relays(app_state: &Addr, settings: &Settings) -> Result<(), EmgauwaError> { let notifier = &*app_state .send(app_state::GetControllerNotifier {}) .await?; - let mut last_weekday = emgauwa_common::utils::get_weekday(); + let mut last_weekday = EmgauwaNow::now(&settings.midnight).weekday; let mut this = AppState::get_this(app_state).await?; let mut duration_override = None; + let now = EmgauwaNow::now(&settings.midnight); + calc_relay_states(&mut this, app_state, &now).await?; + loop { - let now = EmgauwaNow::now(); + let now = EmgauwaNow::now(&settings.midnight); let notifier_future = notifier.notified(); pin_mut!(notifier_future); @@ -47,7 +51,7 @@ async fn run_relays(app_state: &Addr) -> Result<(), EmgauwaError> { .await .is_ok(); - let now = EmgauwaNow::now(); + let now = EmgauwaNow::now(&settings.midnight); check_weekday(app_state, &mut last_weekday, &mut changed, &now).await?; @@ -57,8 +61,9 @@ async fn run_relays(app_state: &Addr) -> Result<(), EmgauwaError> { } log::debug!( - "Relay loop at {}: {}", + "Relay loop at {} on {}: {}", now.time, + now.weekday.to_string(), printable_relay_states(&this.get_relay_states()) ); @@ -117,15 +122,23 @@ fn get_next_duration( return *duration; } - let next_timestamp = this + let next_time = this .check_next_time(now) - .map_or(86400, |t| t.num_seconds_from_midnight()); + .unwrap_or(now.midnight); - let duration_to_next = Duration::from_secs((next_timestamp - now.time_in_s()) as u64); + // 86400 is the number of seconds in a day + // If the next timestamp is before the current time, we need to wait until the next day + let mut seconds_to_next = (86400 + next_time.num_seconds_from_midnight() - now.num_seconds_from_midnight()) % 86400; + if seconds_to_next == 0 { + seconds_to_next = 86400; + } + + + let duration_to_next = Duration::from_secs(seconds_to_next as u64); log::debug!( - "Next timestamp: {}; Waiting for {}s", - next_timestamp, + "Next time: {}; Waiting for {}s", + next_time, duration_to_next.as_secs() ); diff --git a/src/settings.rs b/src/settings.rs index f4f83fd..b812ab0 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -1,3 +1,4 @@ +use chrono::NaiveTime; use emgauwa_common::errors::EmgauwaError; use emgauwa_common::settings; use rppal_pfd::PiFaceDigital; @@ -27,6 +28,7 @@ pub struct Settings { pub logging: settings::Logging, pub name: String, + pub midnight: NaiveTime, pub relays: Vec, } @@ -39,6 +41,7 @@ impl Default for Settings { logging: settings::Logging::default(), name: String::from("Emgauwa Controller"), + midnight: NaiveTime::default(), relays: Vec::new(), } } diff --git a/src/ws/handlers.rs b/src/ws/handlers.rs index 97caded..bc38744 100644 --- a/src/ws/handlers.rs +++ b/src/ws/handlers.rs @@ -156,8 +156,7 @@ async fn handle_relays( app_state .send(app_state::RelayOverrideSchedule { relay_number: relay.r.number, - schedule: relay.override_schedule.clone(), - weekday: relay.override_schedule_weekday, + schedule: relay.override_schedule.clone() }) .await??;