From 9326b66007f61cb3c92cf3774f2c6a8d238a3b7d Mon Sep 17 00:00:00 2001 From: Tobias Reisinger <tobias@msrg.cc> Date: Mon, 13 May 2024 19:17:35 +0200 Subject: [PATCH 1/3] Simplify schedule in macro action --- src/models/macro_action.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/models/macro_action.rs b/src/models/macro_action.rs index a36a45a..786bf81 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}; +use crate::db::{DbJunctionRelaySchedule, DbMacroAction, DbSchedule}; use crate::errors::{DatabaseError, EmgauwaError}; -use crate::models::{FromDbModel, Relay, Schedule}; +use crate::models::{FromDbModel, Relay}; #[derive(Serialize, Deserialize, Debug, Clone)] pub struct MacroAction { - pub schedule: Schedule, + pub schedule: DbSchedule, pub relay: Relay, pub weekday: i64, } @@ -30,8 +30,7 @@ impl FromDbModel for MacroAction { db_model: Self::DbModel, _cache: Self::DbModelCache, ) -> Result<Self, DatabaseError> { - let schedule_db = block_on(db_model.get_schedule(conn))?; - let schedule = Schedule::from_db_model(conn, schedule_db)?; + let schedule = block_on(db_model.get_schedule(conn))?; let relay_db = block_on(db_model.get_relay(conn))?; let relay = Relay::from_db_model(conn, relay_db)?; @@ -48,7 +47,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.s, self.weekday) + DbJunctionRelaySchedule::set_schedule(conn, &self.relay.r, &self.schedule, self.weekday) .await?; Ok(()) } From 473832f58a258e404d7bba0ca20a3ff58e6ba11c Mon Sep 17 00:00:00 2001 From: Tobias Reisinger <tobias@msrg.cc> Date: Sun, 26 May 2024 22:48:22 +0200 Subject: [PATCH 2/3] Rename active_schedule to override_schedule and add EmgauwaNow --- Cargo.lock | 117 +++++++++++++++++++++++++++++++++--- Cargo.toml | 1 + src/db/model_utils.rs | 14 ++--- src/errors/emgauwa_error.rs | 4 +- src/models/controller.rs | 26 +++++--- src/models/relay.rs | 46 +++++++++++--- src/types/emgauwa_now.rs | 26 ++++++++ src/types/mod.rs | 10 ++- src/types/request.rs | 7 ++- src/utils.rs | 2 +- 10 files changed, 218 insertions(+), 35 deletions(-) create mode 100644 src/types/emgauwa_now.rs diff --git a/Cargo.lock b/Cargo.lock index 18d357b..1bee2db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -55,7 +55,7 @@ dependencies = [ "actix-service", "actix-utils", "ahash", - "base64", + "base64 0.21.7", "bitflags 2.5.0", "brotli", "bytes", @@ -355,6 +355,12 @@ 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" @@ -626,6 +632,41 @@ 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" @@ -644,6 +685,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", + "serde", ] [[package]] @@ -711,6 +753,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", + "serde_with", "simple_logger", "sqlx", "uuid", @@ -945,13 +988,19 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap", + "indexmap 2.2.6", "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" @@ -1065,6 +1114,12 @@ 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" @@ -1075,6 +1130,17 @@ 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" @@ -1083,6 +1149,7 @@ checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", "hashbrown 0.14.5", + "serde", ] [[package]] @@ -1605,7 +1672,7 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" dependencies = [ - "base64", + "base64 0.21.7", "bitflags 2.5.0", "serde", "serde_derive", @@ -1739,6 +1806,36 @@ 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" @@ -1887,7 +1984,7 @@ dependencies = [ "futures-util", "hashlink", "hex", - "indexmap", + "indexmap 2.2.6", "log", "memchr", "once_cell", @@ -1950,7 +2047,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ed31390216d20e538e447a7a9b959e06ed9fc51c37b514b46eb758016ecd418" dependencies = [ "atoi", - "base64", + "base64 0.21.7", "bitflags 2.5.0", "byteorder", "bytes", @@ -1992,7 +2089,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c824eb80b894f926f89a0b9da0c7f435d27cdd35b8c655b114e58223918577e" dependencies = [ "atoi", - "base64", + "base64 0.21.7", "bitflags 2.5.0", "byteorder", "crc", @@ -2057,6 +2154,12 @@ 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" @@ -2242,7 +2345,7 @@ version = "0.22.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3328d4f68a705b2a4498da1d580585d39a6510f98318a2cec3018a7ec61ddef" dependencies = [ - "indexmap", + "indexmap 2.2.6", "serde", "serde_spanned", "toml_datetime", diff --git a/Cargo.toml b/Cargo.toml index 30ed02a..464e9b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ 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 e178d8e..db845bc 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 f37c38e..a833c78 100644 --- a/src/errors/emgauwa_error.rs +++ b/src/errors/emgauwa_error.rs @@ -47,7 +47,9 @@ 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 96d7b00..ebc556a 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::RelayStates; +use crate::types::{EmgauwaNow, RelayState, RelayStates}; #[derive(Serialize, Deserialize, Debug, Clone, MessageResponse)] pub struct Controller { @@ -57,19 +57,29 @@ impl Controller { self.relays .iter_mut() .zip(relay_states.iter()) - .for_each(|(relay, is_on)| { - relay.is_on = *is_on; + .for_each(|(relay, state)| { + relay.active_schedule = state.active_schedule.clone(); + relay.is_on = state.is_on; }); } pub fn get_relay_states(&self) -> RelayStates { - self.relays.iter().map(|r| r.is_on).collect() - } - - pub fn get_next_time(&self, now: &NaiveTime) -> Option<NaiveTime> { self.relays .iter() - .filter_map(|r| r.active_schedule.get_next_time(now)) + .map(|r| RelayState { + active_schedule: r.active_schedule.clone(), + is_on: r.is_on, + }) + .collect() + } + + pub fn check_next_time(&mut self, now: &EmgauwaNow) -> Option<NaiveTime> { + self.relays + .iter_mut() + .filter_map(|r| { + r.reload_active_schedule(now.weekday); + r.active_schedule.get_next_time(&now.time) + }) .min() } diff --git a/src/models/relay.rs b/src/models/relay.rs index e6ecd0f..f44b290 100644 --- a/src/models/relay.rs +++ b/src/models/relay.rs @@ -9,7 +9,8 @@ use sqlx::Sqlite; use crate::db::{DbController, DbJunctionRelaySchedule, DbRelay, DbSchedule}; use crate::errors::DatabaseError; use crate::models::FromDbModel; -use crate::types::EmgauwaUid; +use crate::types::{EmgauwaUid, Weekday}; +use crate::utils; #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Relay { @@ -19,12 +20,23 @@ pub struct Relay { pub controller_id: EmgauwaUid, pub schedules: Vec<DbSchedule>, pub active_schedule: DbSchedule, + #[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<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 { @@ -58,9 +70,11 @@ impl FromDbModel for Relay { controller_id, schedules, active_schedule, + override_schedule: None, is_on, tags, pulsing: None, + override_schedule_weekday: Weekday::default(), }) } } @@ -69,16 +83,9 @@ 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)?; - Ok(()) - } + self.reload_active_schedule(utils::get_weekday()); - 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(()) } @@ -103,4 +110,25 @@ impl Relay { None => None, } } + + pub fn reload_active_schedule(&mut self, weekday: Weekday) { + if let Some((Some(schedule), schedule_weekday)) = self.unwrap_override_schedule() { + if schedule_weekday == weekday { + self.active_schedule = schedule.clone(); + return; + } + if schedule_weekday != weekday { + self.override_schedule = None; + } + } + + self.active_schedule = self.schedules.get(weekday as usize).unwrap().clone() + } + + pub fn unwrap_override_schedule(&self) -> Option<(&Option<DbSchedule>, Weekday)> { + if let Some(schedule) = &self.override_schedule { + return Some((schedule, self.override_schedule_weekday)); + } + None + } } diff --git a/src/types/emgauwa_now.rs b/src/types/emgauwa_now.rs new file mode 100644 index 0000000..40f4907 --- /dev/null +++ b/src/types/emgauwa_now.rs @@ -0,0 +1,26 @@ +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 dbbfb77..24f3c78 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -1,8 +1,10 @@ +mod emgauwa_now; mod emgauwa_uid; mod request; mod schedule_uid; use actix::Message; +pub use emgauwa_now::EmgauwaNow; pub use emgauwa_uid::EmgauwaUid; pub use request::*; pub use schedule_uid::ScheduleUid; @@ -14,7 +16,13 @@ use crate::models::{Controller, Relay}; pub type Weekday = i64; -pub type RelayStates = Vec<Option<bool>>; +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct RelayState { + pub active_schedule: DbSchedule, + pub is_on: Option<bool> +} + +pub type RelayStates = Vec<RelayState>; #[derive(Debug, Serialize, Deserialize, Message)] #[rtype(result = "Result<(), EmgauwaError>")] diff --git a/src/types/request.rs b/src/types/request.rs index 4956733..d452b31 100644 --- a/src/types/request.rs +++ b/src/types/request.rs @@ -23,7 +23,12 @@ pub struct RequestScheduleUpdate { #[derive(Debug, Serialize, Deserialize)] pub struct RequestRelayUpdate { pub name: Option<String>, - pub active_schedule: Option<RequestScheduleId>, + #[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 schedules: Option<Vec<RequestScheduleId>>, pub tags: Option<Vec<String>>, } diff --git a/src/utils.rs b/src/utils.rs index e9ee62e..3b20d9a 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 { + relay_debug.push_str(match state.is_on { Some(true) => "+", Some(false) => "-", None => "?", From 929985c64af0a69db30c89e3c03d22294fc0935c Mon Sep 17 00:00:00 2001 From: Tobias Reisinger <tobias@msrg.cc> Date: Tue, 28 May 2024 21:17:21 +0200 Subject: [PATCH 3/3] Improve handling of override_schedule --- src/models/controller.rs | 15 ++++----------- src/models/relay.rs | 31 ++++++++++++++++--------------- src/types/mod.rs | 10 ++-------- src/types/relay_state.rs | 22 ++++++++++++++++++++++ 4 files changed, 44 insertions(+), 34 deletions(-) create mode 100644 src/types/relay_state.rs diff --git a/src/models/controller.rs b/src/models/controller.rs index ebc556a..e1a272b 100644 --- a/src/models/controller.rs +++ b/src/models/controller.rs @@ -57,20 +57,11 @@ impl Controller { self.relays .iter_mut() .zip(relay_states.iter()) - .for_each(|(relay, state)| { - relay.active_schedule = state.active_schedule.clone(); - relay.is_on = state.is_on; - }); + .for_each(|(relay, state)| relay.apply_state(state)); } pub fn get_relay_states(&self) -> RelayStates { - self.relays - .iter() - .map(|r| RelayState { - active_schedule: r.active_schedule.clone(), - is_on: r.is_on, - }) - .collect() + self.relays.iter().map(RelayState::from).collect() } pub fn check_next_time(&mut self, now: &EmgauwaNow) -> Option<NaiveTime> { @@ -90,6 +81,8 @@ 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/relay.rs b/src/models/relay.rs index f44b290..51289ca 100644 --- a/src/models/relay.rs +++ b/src/models/relay.rs @@ -9,7 +9,7 @@ use sqlx::Sqlite; use crate::db::{DbController, DbJunctionRelaySchedule, DbRelay, DbSchedule}; use crate::errors::DatabaseError; use crate::models::FromDbModel; -use crate::types::{EmgauwaUid, Weekday}; +use crate::types::{EmgauwaUid, RelayState, Weekday}; use crate::utils; #[derive(Serialize, Deserialize, Debug, Clone)] @@ -20,12 +20,7 @@ pub struct Relay { pub controller_id: EmgauwaUid, pub schedules: Vec<DbSchedule>, pub active_schedule: DbSchedule, - #[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<DbSchedule>>, + pub override_schedule: Option<DbSchedule>, pub is_on: Option<bool>, pub tags: Vec<String>, @@ -112,12 +107,12 @@ impl Relay { } pub fn reload_active_schedule(&mut self, weekday: Weekday) { - if let Some((Some(schedule), schedule_weekday)) = self.unwrap_override_schedule() { - if schedule_weekday == weekday { + if let Some(schedule) = &self.override_schedule { + if self.override_schedule_weekday == weekday { self.active_schedule = schedule.clone(); return; } - if schedule_weekday != weekday { + if self.override_schedule_weekday != weekday { self.override_schedule = None; } } @@ -125,10 +120,16 @@ impl Relay { self.active_schedule = self.schedules.get(weekday as usize).unwrap().clone() } - pub fn unwrap_override_schedule(&self) -> Option<(&Option<DbSchedule>, Weekday)> { - if let Some(schedule) = &self.override_schedule { - return Some((schedule, self.override_schedule_weekday)); - } - None + 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/mod.rs b/src/types/mod.rs index 24f3c78..44d116c 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -2,10 +2,12 @@ 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}; @@ -16,14 +18,6 @@ use crate::models::{Controller, Relay}; pub type Weekday = i64; -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct RelayState { - pub active_schedule: DbSchedule, - pub is_on: Option<bool> -} - -pub type RelayStates = Vec<RelayState>; - #[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 new file mode 100644 index 0000000..f4a2e3a --- /dev/null +++ b/src/types/relay_state.rs @@ -0,0 +1,22 @@ +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