Add setting to change "midnight" of day

This commit is contained in:
Tobias Reisinger 2024-05-30 02:37:40 +02:00
parent 1e2afe481c
commit 4f48b04acc
Signed by: serguzim
GPG key ID: 13AD60C237A28DFE
6 changed files with 37 additions and 23 deletions

View file

@ -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 { logging {
level = "DEBUG" level = "DEBUG"

View file

@ -6,7 +6,7 @@ use emgauwa_common::constants;
use emgauwa_common::db::DbSchedule; use emgauwa_common::db::DbSchedule;
use emgauwa_common::errors::EmgauwaError; use emgauwa_common::errors::EmgauwaError;
use emgauwa_common::models::Controller; use emgauwa_common::models::Controller;
use emgauwa_common::types::{RelayStates, Weekday}; use emgauwa_common::types::{EmgauwaNow, RelayStates};
use futures::executor::block_on; use futures::executor::block_on;
use sqlx::{Pool, Sqlite}; use sqlx::{Pool, Sqlite};
use tokio::sync::Notify; use tokio::sync::Notify;
@ -36,7 +36,6 @@ pub struct RelayPulse {
pub struct RelayOverrideSchedule { pub struct RelayOverrideSchedule {
pub relay_number: i64, pub relay_number: i64,
pub schedule: Option<DbSchedule>, pub schedule: Option<DbSchedule>,
pub weekday: Weekday,
} }
#[derive(Message)] #[derive(Message)]
@ -177,7 +176,7 @@ impl Handler<RelayOverrideSchedule> for AppState {
fn handle(&mut self, msg: RelayOverrideSchedule, _ctx: &mut Self::Context) -> Self::Result { fn handle(&mut self, msg: RelayOverrideSchedule, _ctx: &mut Self::Context) -> Self::Result {
let relay_num = msg.relay_number; let relay_num = msg.relay_number;
let schedule = msg.schedule; let schedule = msg.schedule;
let weekday = msg.weekday; let weekday = EmgauwaNow::now(&self.settings.midnight).weekday;
let relay = self let relay = self
.this .this

View file

@ -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 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<bool> = this let initial_states: Vec<bool> = this
.relays .relays
.iter_mut() .iter_mut()
@ -115,12 +115,12 @@ async fn main() -> Result<(), std::io::Error> {
settings.server.host, settings.server.port 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"); log::info!("Starting main loops");
let _ = tokio::join!( 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)), tokio::spawn(run_ws_loop(pool.clone(), app_state.clone(), url)),
); );

View file

@ -1,11 +1,11 @@
use std::time::Duration; use std::time::Duration;
use actix::Addr; use actix::Addr;
use chrono::Timelike; use chrono::{Timelike, Weekday};
use emgauwa_common::constants::RELAYS_RETRY_TIMEOUT; use emgauwa_common::constants::RELAYS_RETRY_TIMEOUT;
use emgauwa_common::errors::EmgauwaError; use emgauwa_common::errors::EmgauwaError;
use emgauwa_common::models::Controller; use emgauwa_common::models::Controller;
use emgauwa_common::types::{EmgauwaNow, Weekday}; use emgauwa_common::types::EmgauwaNow;
use emgauwa_common::utils::printable_relay_states; use emgauwa_common::utils::printable_relay_states;
use futures::pin_mut; use futures::pin_mut;
use tokio::time; use tokio::time;
@ -13,11 +13,12 @@ use tokio::time::timeout;
use crate::app_state::AppState; use crate::app_state::AppState;
use crate::app_state; use crate::app_state;
use crate::settings::Settings;
pub async fn run_relays_loop(app_state: Addr<AppState>) { pub async fn run_relays_loop(app_state: Addr<AppState>, settings: Settings) {
log::debug!("Spawned relays loop"); log::debug!("Spawned relays loop");
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 { if let Err(err) = run_result {
log::error!("Error running relays: {}", err); log::error!("Error running relays: {}", err);
} }
@ -25,18 +26,21 @@ pub async fn run_relays_loop(app_state: Addr<AppState>) {
} }
} }
async fn run_relays(app_state: &Addr<AppState>) -> Result<(), EmgauwaError> { async fn run_relays(app_state: &Addr<AppState>, settings: &Settings) -> Result<(), EmgauwaError> {
let notifier = &*app_state let notifier = &*app_state
.send(app_state::GetControllerNotifier {}) .send(app_state::GetControllerNotifier {})
.await?; .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 this = AppState::get_this(app_state).await?;
let mut duration_override = None; let mut duration_override = None;
let now = EmgauwaNow::now(&settings.midnight);
calc_relay_states(&mut this, app_state, &now).await?;
loop { loop {
let now = EmgauwaNow::now(); let now = EmgauwaNow::now(&settings.midnight);
let notifier_future = notifier.notified(); let notifier_future = notifier.notified();
pin_mut!(notifier_future); pin_mut!(notifier_future);
@ -47,7 +51,7 @@ async fn run_relays(app_state: &Addr<AppState>) -> Result<(), EmgauwaError> {
.await .await
.is_ok(); .is_ok();
let now = EmgauwaNow::now(); let now = EmgauwaNow::now(&settings.midnight);
check_weekday(app_state, &mut last_weekday, &mut changed, &now).await?; check_weekday(app_state, &mut last_weekday, &mut changed, &now).await?;
@ -57,8 +61,9 @@ async fn run_relays(app_state: &Addr<AppState>) -> Result<(), EmgauwaError> {
} }
log::debug!( log::debug!(
"Relay loop at {}: {}", "Relay loop at {} on {}: {}",
now.time, now.time,
now.weekday.to_string(),
printable_relay_states(&this.get_relay_states()) printable_relay_states(&this.get_relay_states())
); );
@ -117,15 +122,23 @@ fn get_next_duration(
return *duration; return *duration;
} }
let next_timestamp = this let next_time = this
.check_next_time(now) .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!( log::debug!(
"Next timestamp: {}; Waiting for {}s", "Next time: {}; Waiting for {}s",
next_timestamp, next_time,
duration_to_next.as_secs() duration_to_next.as_secs()
); );

View file

@ -1,3 +1,4 @@
use chrono::NaiveTime;
use emgauwa_common::errors::EmgauwaError; use emgauwa_common::errors::EmgauwaError;
use emgauwa_common::settings; use emgauwa_common::settings;
use rppal_pfd::PiFaceDigital; use rppal_pfd::PiFaceDigital;
@ -27,6 +28,7 @@ pub struct Settings {
pub logging: settings::Logging, pub logging: settings::Logging,
pub name: String, pub name: String,
pub midnight: NaiveTime,
pub relays: Vec<Relay>, pub relays: Vec<Relay>,
} }
@ -39,6 +41,7 @@ impl Default for Settings {
logging: settings::Logging::default(), logging: settings::Logging::default(),
name: String::from("Emgauwa Controller"), name: String::from("Emgauwa Controller"),
midnight: NaiveTime::default(),
relays: Vec::new(), relays: Vec::new(),
} }
} }

View file

@ -156,8 +156,7 @@ async fn handle_relays(
app_state app_state
.send(app_state::RelayOverrideSchedule { .send(app_state::RelayOverrideSchedule {
relay_number: relay.r.number, relay_number: relay.r.number,
schedule: relay.override_schedule.clone(), schedule: relay.override_schedule.clone()
weekday: relay.override_schedule_weekday,
}) })
.await??; .await??;