Compare commits
No commits in common. "929985c64af0a69db30c89e3c03d22294fc0935c" and "f26e66d68796bcd3e391a36100c12c3bb9fa210a" have entirely different histories.
929985c64a
...
f26e66d687
12 changed files with 35 additions and 124 deletions
BIN
Cargo.lock
generated
BIN
Cargo.lock
generated
Binary file not shown.
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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>>,
|
||||
}
|
||||
|
|
|
@ -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 => "?",
|
||||
|
|
Loading…
Reference in a new issue