diff --git a/Cargo.lock b/Cargo.lock index 1bee2db..18d357b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -55,7 +55,7 @@ dependencies = [ "actix-service", "actix-utils", "ahash", - "base64 0.21.7", + "base64", "bitflags 2.5.0", "brotli", "bytes", @@ -355,12 +355,6 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - [[package]] name = "base64ct" version = "1.6.0" @@ -632,41 +626,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "darling" -version = "0.20.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.20.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 2.0.60", -] - -[[package]] -name = "darling_macro" -version = "0.20.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" -dependencies = [ - "darling_core", - "quote", - "syn 2.0.60", -] - [[package]] name = "der" version = "0.7.9" @@ -685,7 +644,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", - "serde", ] [[package]] @@ -753,7 +711,6 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "serde_with", "simple_logger", "sqlx", "uuid", @@ -988,19 +945,13 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 2.2.6", + "indexmap", "slab", "tokio", "tokio-util", "tracing", ] -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - [[package]] name = "hashbrown" version = "0.13.2" @@ -1114,12 +1065,6 @@ dependencies = [ "cc", ] -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - [[package]] name = "idna" version = "0.5.0" @@ -1130,17 +1075,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", -] - [[package]] name = "indexmap" version = "2.2.6" @@ -1149,7 +1083,6 @@ checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", "hashbrown 0.14.5", - "serde", ] [[package]] @@ -1672,7 +1605,7 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" dependencies = [ - "base64 0.21.7", + "base64", "bitflags 2.5.0", "serde", "serde_derive", @@ -1806,36 +1739,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_with" -version = "3.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad483d2ab0149d5a5ebcd9972a3852711e0153d863bf5a5d0391d28883c4a20" -dependencies = [ - "base64 0.22.1", - "chrono", - "hex", - "indexmap 1.9.3", - "indexmap 2.2.6", - "serde", - "serde_derive", - "serde_json", - "serde_with_macros", - "time", -] - -[[package]] -name = "serde_with_macros" -version = "3.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65569b702f41443e8bc8bbb1c5779bd0450bbe723b56198980e80ec45780bce2" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn 2.0.60", -] - [[package]] name = "sha1" version = "0.10.6" @@ -1984,7 +1887,7 @@ dependencies = [ "futures-util", "hashlink", "hex", - "indexmap 2.2.6", + "indexmap", "log", "memchr", "once_cell", @@ -2047,7 +1950,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ed31390216d20e538e447a7a9b959e06ed9fc51c37b514b46eb758016ecd418" dependencies = [ "atoi", - "base64 0.21.7", + "base64", "bitflags 2.5.0", "byteorder", "bytes", @@ -2089,7 +1992,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c824eb80b894f926f89a0b9da0c7f435d27cdd35b8c655b114e58223918577e" dependencies = [ "atoi", - "base64 0.21.7", + "base64", "bitflags 2.5.0", "byteorder", "crc", @@ -2154,12 +2057,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - [[package]] name = "subtle" version = "2.5.0" @@ -2345,7 +2242,7 @@ version = "0.22.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3328d4f68a705b2a4498da1d580585d39a6510f98318a2cec3018a7ec61ddef" dependencies = [ - "indexmap 2.2.6", + "indexmap", "serde", "serde_spanned", "toml_datetime", diff --git a/Cargo.toml b/Cargo.toml index 464e9b2..30ed02a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,6 @@ actix-web-actors = "4.2" serde = "1.0" serde_json = "1.0" serde_derive = "1.0" -serde_with = "3.8" simple_logger = "5.0" log = "0.4" diff --git a/src/db/model_utils.rs b/src/db/model_utils.rs index db845bc..e178d8e 100644 --- a/src/db/model_utils.rs +++ b/src/db/model_utils.rs @@ -1,10 +1,10 @@ use chrono::{NaiveTime, Timelike}; use serde::{Deserialize, Serialize}; +use sqlx::{Decode, Encode, Sqlite, Type}; use sqlx::database::HasArguments; use sqlx::encode::IsNull; use sqlx::error::BoxDynError; use sqlx::sqlite::{SqliteTypeInfo, SqliteValueRef}; -use sqlx::{Decode, Encode, Sqlite, Type}; use crate::db::DbPeriods; @@ -67,12 +67,12 @@ impl Period { let start_before_end = self.start.lt(&self.end); match (start_after_now, end_after_now, start_before_end) { - (false, false, true) => false, // both before now; start before end means "normal" period before now - (false, false, false) => true, // both before now; end before start means "inversed" period around now - (true, false, _) => false, // only start after now - (false, true, _) => true, // only end after now - (true, true, true) => false, // both after now but start first - (true, true, false) => true, // both after now but end first + (false, false, true) => false, // both before now; start before end means "normal" period before now + (false, false, false) => true, // both before now; end before start means "inversed" period around now + (true, false, _) => false, // only start after now + (false, true, _) => true, // only end after now + (true, true, true) => false, // both after now but start first + (true, true, false) => true, // both after now but end first } } diff --git a/src/errors/emgauwa_error.rs b/src/errors/emgauwa_error.rs index a833c78..f37c38e 100644 --- a/src/errors/emgauwa_error.rs +++ b/src/errors/emgauwa_error.rs @@ -47,9 +47,7 @@ impl From<&EmgauwaError> for String { EmgauwaError::Database(err) => String::from(err), EmgauwaError::Uid(_) => String::from("the uid is in a bad format"), EmgauwaError::Internal(_) => String::from("internal error"), - EmgauwaError::Connection(uid) => { - format!("unable to connect to controller with uid: {}", uid) - } + EmgauwaError::Connection(uid) => format!("unable to connect to controller with uid: {}", uid), EmgauwaError::Other(err) => format!("other error: {}", err), EmgauwaError::Hardware(err) => format!("hardware error: {}", err), } diff --git a/src/models/controller.rs b/src/models/controller.rs index e1a272b..96d7b00 100644 --- a/src/models/controller.rs +++ b/src/models/controller.rs @@ -10,7 +10,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::{EmgauwaNow, RelayState, RelayStates}; +use crate::types::RelayStates; #[derive(Serialize, Deserialize, Debug, Clone, MessageResponse)] pub struct Controller { @@ -57,20 +57,19 @@ impl Controller { self.relays .iter_mut() .zip(relay_states.iter()) - .for_each(|(relay, state)| relay.apply_state(state)); + .for_each(|(relay, is_on)| { + relay.is_on = *is_on; + }); } pub fn get_relay_states(&self) -> RelayStates { - self.relays.iter().map(RelayState::from).collect() + self.relays.iter().map(|r| r.is_on).collect() } - pub fn check_next_time(&mut self, now: &EmgauwaNow) -> Option<NaiveTime> { + pub fn get_next_time(&self, now: &NaiveTime) -> Option<NaiveTime> { self.relays - .iter_mut() - .filter_map(|r| { - r.reload_active_schedule(now.weekday); - r.active_schedule.get_next_time(&now.time) - }) + .iter() + .filter_map(|r| r.active_schedule.get_next_time(now)) .min() } @@ -81,8 +80,6 @@ impl Controller { .find(|r| r.r.number == relay_num) .ok_or(EmgauwaError::Other(String::from("Relay not found")))?; - log::debug!("Pulsing relay {} until {:?}", relay_num, until); - relay.pulsing = Some(until); Ok(()) } diff --git a/src/models/macro_action.rs b/src/models/macro_action.rs index 786bf81..a36a45a 100644 --- a/src/models/macro_action.rs +++ b/src/models/macro_action.rs @@ -3,13 +3,13 @@ use serde_derive::{Deserialize, Serialize}; use sqlx::pool::PoolConnection; use sqlx::Sqlite; -use crate::db::{DbJunctionRelaySchedule, DbMacroAction, DbSchedule}; +use crate::db::{DbJunctionRelaySchedule, DbMacroAction}; use crate::errors::{DatabaseError, EmgauwaError}; -use crate::models::{FromDbModel, Relay}; +use crate::models::{FromDbModel, Relay, Schedule}; #[derive(Serialize, Deserialize, Debug, Clone)] pub struct MacroAction { - pub schedule: DbSchedule, + pub schedule: Schedule, pub relay: Relay, pub weekday: i64, } @@ -30,7 +30,8 @@ impl FromDbModel for MacroAction { db_model: Self::DbModel, _cache: Self::DbModelCache, ) -> Result<Self, DatabaseError> { - let schedule = block_on(db_model.get_schedule(conn))?; + let schedule_db = block_on(db_model.get_schedule(conn))?; + let schedule = Schedule::from_db_model(conn, schedule_db)?; let relay_db = block_on(db_model.get_relay(conn))?; let relay = Relay::from_db_model(conn, relay_db)?; @@ -47,7 +48,7 @@ impl FromDbModel for MacroAction { impl MacroAction { pub async fn execute(&self, conn: &mut PoolConnection<Sqlite>) -> Result<(), EmgauwaError> { - DbJunctionRelaySchedule::set_schedule(conn, &self.relay.r, &self.schedule, self.weekday) + DbJunctionRelaySchedule::set_schedule(conn, &self.relay.r, &self.schedule.s, self.weekday) .await?; Ok(()) } diff --git a/src/models/relay.rs b/src/models/relay.rs index 51289ca..e6ecd0f 100644 --- a/src/models/relay.rs +++ b/src/models/relay.rs @@ -9,8 +9,7 @@ use sqlx::Sqlite; use crate::db::{DbController, DbJunctionRelaySchedule, DbRelay, DbSchedule}; use crate::errors::DatabaseError; use crate::models::FromDbModel; -use crate::types::{EmgauwaUid, RelayState, Weekday}; -use crate::utils; +use crate::types::EmgauwaUid; #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Relay { @@ -20,18 +19,12 @@ pub struct Relay { pub controller_id: EmgauwaUid, pub schedules: Vec<DbSchedule>, pub active_schedule: DbSchedule, - pub override_schedule: Option<DbSchedule>, pub is_on: Option<bool>, pub tags: Vec<String>, // for internal use only. #[serde(skip)] pub pulsing: Option<Instant>, - #[serde( - skip, - default = "utils::get_weekday", - )] - pub override_schedule_weekday: Weekday, } impl FromDbModel for Relay { @@ -65,11 +58,9 @@ impl FromDbModel for Relay { controller_id, schedules, active_schedule, - override_schedule: None, is_on, tags, pulsing: None, - override_schedule_weekday: Weekday::default(), }) } } @@ -78,9 +69,16 @@ impl Relay { pub fn reload(&mut self, conn: &mut PoolConnection<Sqlite>) -> Result<(), DatabaseError> { self.r = block_on(self.r.reload(conn))?; self.schedules = block_on(DbJunctionRelaySchedule::get_schedules(conn, &self.r))?; + self.reload_active_schedule(conn)?; - self.reload_active_schedule(utils::get_weekday()); + Ok(()) + } + pub fn reload_active_schedule( + &mut self, + conn: &mut PoolConnection<Sqlite>, + ) -> Result<(), DatabaseError> { + self.active_schedule = block_on(self.r.get_active_schedule(conn))?; Ok(()) } @@ -105,31 +103,4 @@ impl Relay { None => None, } } - - pub fn reload_active_schedule(&mut self, weekday: Weekday) { - if let Some(schedule) = &self.override_schedule { - if self.override_schedule_weekday == weekday { - self.active_schedule = schedule.clone(); - return; - } - if self.override_schedule_weekday != weekday { - self.override_schedule = None; - } - } - - self.active_schedule = self.schedules.get(weekday as usize).unwrap().clone() - } - - pub fn apply_state(&mut self, state: &RelayState) { - self.active_schedule = state.active_schedule.clone(); - self.override_schedule.clone_from(&state.override_schedule); - self.is_on = state.is_on; - } - - pub fn find_and_apply_state(&mut self, stated_relays: &[Relay]) { - if let Some(stated_relay) = stated_relays.iter().find(|r| r.r.id == self.r.id) { - self.apply_state(&stated_relay.into()); - } - } - } diff --git a/src/types/emgauwa_now.rs b/src/types/emgauwa_now.rs deleted file mode 100644 index 40f4907..0000000 --- a/src/types/emgauwa_now.rs +++ /dev/null @@ -1,26 +0,0 @@ -use std::time::Instant; - -use chrono::{Local, NaiveTime, Timelike}; - -use crate::types::Weekday; -use crate::utils; - -pub struct EmgauwaNow { - pub time: NaiveTime, - pub instant: Instant, - pub weekday: Weekday, -} - -impl EmgauwaNow { - pub fn now() -> EmgauwaNow { - EmgauwaNow { - time: Local::now().time(), - instant: Instant::now(), - weekday: utils::get_weekday(), - } - } - - pub fn time_in_s(&self) -> u32 { - self.time.num_seconds_from_midnight() - } -} diff --git a/src/types/mod.rs b/src/types/mod.rs index 44d116c..dbbfb77 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -1,13 +1,9 @@ -mod emgauwa_now; mod emgauwa_uid; mod request; mod schedule_uid; -mod relay_state; use actix::Message; -pub use emgauwa_now::EmgauwaNow; pub use emgauwa_uid::EmgauwaUid; -pub use relay_state::{RelayState, RelayStates}; pub use request::*; pub use schedule_uid::ScheduleUid; use serde_derive::{Deserialize, Serialize}; @@ -18,6 +14,8 @@ use crate::models::{Controller, Relay}; pub type Weekday = i64; +pub type RelayStates = Vec<Option<bool>>; + #[derive(Debug, Serialize, Deserialize, Message)] #[rtype(result = "Result<(), EmgauwaError>")] pub enum ControllerWsAction { diff --git a/src/types/relay_state.rs b/src/types/relay_state.rs deleted file mode 100644 index f4a2e3a..0000000 --- a/src/types/relay_state.rs +++ /dev/null @@ -1,22 +0,0 @@ -use serde_derive::{Deserialize, Serialize}; -use crate::db::DbSchedule; -use crate::models::Relay; - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct RelayState { - pub active_schedule: DbSchedule, - pub override_schedule: Option<DbSchedule>, - pub is_on: Option<bool> -} - -pub type RelayStates = Vec<RelayState>; - -impl From<&Relay> for RelayState { - fn from(relay: &Relay) -> Self { - RelayState { - active_schedule: relay.active_schedule.clone(), - override_schedule: relay.override_schedule.clone(), - is_on: relay.is_on - } - } -} \ No newline at end of file diff --git a/src/types/request.rs b/src/types/request.rs index d452b31..4956733 100644 --- a/src/types/request.rs +++ b/src/types/request.rs @@ -23,12 +23,7 @@ pub struct RequestScheduleUpdate { #[derive(Debug, Serialize, Deserialize)] pub struct RequestRelayUpdate { pub name: Option<String>, - #[serde( - default, // <- important for deserialization - skip_serializing_if = "Option::is_none", // <- important for serialization - with = "::serde_with::rust::double_option", - )] - pub override_schedule: Option<Option<RequestScheduleId>>, + pub active_schedule: Option<RequestScheduleId>, pub schedules: Option<Vec<RequestScheduleId>>, pub tags: Option<Vec<String>>, } diff --git a/src/utils.rs b/src/utils.rs index 3b20d9a..e9ee62e 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -103,7 +103,7 @@ pub fn get_weekday() -> Weekday { pub fn printable_relay_states(relay_states: &RelayStates) -> String { let mut relay_debug = String::new(); relay_states.iter().for_each(|state| { - relay_debug.push_str(match state.is_on { + relay_debug.push_str(match state { Some(true) => "+", Some(false) => "-", None => "?",