Add setting to change "midnight" of day
This commit is contained in:
		
							parent
							
								
									1e2afe481c
								
							
						
					
					
						commit
						4f48b04acc
					
				
					 6 changed files with 37 additions and 23 deletions
				
			
		| 
						 | 
					@ -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"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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)),
 | 
				
			||||||
	);
 | 
						);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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()
 | 
				
			||||||
	);
 | 
						);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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(),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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??;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue