107 lines
2.5 KiB
Rust
107 lines
2.5 KiB
Rust
use std::time::Instant;
|
|
|
|
use chrono::NaiveTime;
|
|
use futures::executor::block_on;
|
|
use serde_derive::{Deserialize, Serialize};
|
|
use sqlx::pool::PoolConnection;
|
|
use sqlx::Sqlite;
|
|
|
|
use crate::db::{DbController, DbJunctionRelaySchedule, DbRelay, DbSchedule};
|
|
use crate::errors::DatabaseError;
|
|
use crate::models::FromDbModel;
|
|
use crate::types::ControllerUid;
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct Relay {
|
|
#[serde(flatten)]
|
|
pub r: DbRelay,
|
|
pub controller: DbController,
|
|
pub controller_id: ControllerUid,
|
|
pub schedules: Vec<DbSchedule>,
|
|
pub active_schedule: DbSchedule,
|
|
pub is_on: Option<bool>,
|
|
pub tags: Vec<String>,
|
|
|
|
// for internal use only.
|
|
#[serde(skip)]
|
|
pub pulsing: Option<Instant>,
|
|
}
|
|
|
|
|
|
impl FromDbModel for Relay {
|
|
type DbModel = DbRelay;
|
|
type DbModelCache = DbController;
|
|
|
|
fn from_db_model(
|
|
conn: &mut PoolConnection<Sqlite>,
|
|
db_model: Self::DbModel,
|
|
) -> Result<Self, DatabaseError> {
|
|
let cache = block_on(db_model.get_controller(conn))?;
|
|
Self::from_db_model_cache(conn, db_model, cache)
|
|
}
|
|
|
|
fn from_db_model_cache(
|
|
conn: &mut PoolConnection<Sqlite>,
|
|
db_model: Self::DbModel,
|
|
cache: Self::DbModelCache,
|
|
) -> Result<Self, DatabaseError> {
|
|
let tags = block_on(db_model.get_tags(conn))?;
|
|
let controller_id = cache.uid.clone();
|
|
|
|
let schedules = block_on(DbJunctionRelaySchedule::get_schedules(conn, &db_model))?;
|
|
let active_schedule = block_on(db_model.get_active_schedule(conn))?;
|
|
|
|
let is_on = None;
|
|
|
|
Ok(Relay {
|
|
r: db_model,
|
|
controller: cache,
|
|
controller_id,
|
|
schedules,
|
|
active_schedule,
|
|
is_on,
|
|
tags,
|
|
pulsing: None,
|
|
})
|
|
}
|
|
}
|
|
|
|
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(())
|
|
}
|
|
|
|
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(())
|
|
}
|
|
|
|
pub fn is_on(&self, now: &NaiveTime) -> bool {
|
|
self.active_schedule.is_on(now)
|
|
}
|
|
|
|
pub fn get_next_time(&self, now: &NaiveTime) -> Option<NaiveTime> {
|
|
self.active_schedule.get_next_time(now)
|
|
}
|
|
|
|
pub fn check_pulsing(&mut self, now: &Instant) -> Option<Instant> {
|
|
match self.pulsing {
|
|
Some(dur_instant) => {
|
|
if dur_instant.lt(now) {
|
|
self.pulsing = None;
|
|
None
|
|
} else {
|
|
Some(dur_instant)
|
|
}
|
|
}
|
|
None => None,
|
|
}
|
|
}
|
|
}
|