86 lines
2.1 KiB
Rust
86 lines
2.1 KiB
Rust
use std::time::Instant;
|
|
|
|
use actix::MessageResponse;
|
|
use chrono::NaiveTime;
|
|
use futures::executor::block_on;
|
|
use serde_derive::{Deserialize, Serialize};
|
|
use sqlx::pool::PoolConnection;
|
|
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;
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, MessageResponse)]
|
|
pub struct Controller {
|
|
#[serde(flatten)]
|
|
pub c: DbController,
|
|
pub relays: Vec<Relay>,
|
|
}
|
|
|
|
impl FromDbModel for Controller {
|
|
type DbModel = DbController;
|
|
type DbModelCache = Vec<Relay>;
|
|
|
|
fn from_db_model(
|
|
conn: &mut PoolConnection<Sqlite>,
|
|
db_model: Self::DbModel,
|
|
) -> Result<Self, DatabaseError> {
|
|
let relays_db = block_on(db_model.get_relays(conn))?;
|
|
let cache = convert_db_list_cache(conn, relays_db, db_model.clone())?;
|
|
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> {
|
|
Ok(Controller {
|
|
c: db_model,
|
|
relays: cache,
|
|
})
|
|
}
|
|
}
|
|
|
|
impl Controller {
|
|
pub fn reload(&mut self, conn: &mut PoolConnection<Sqlite>) -> Result<(), EmgauwaError> {
|
|
self.c = block_on(self.c.reload(conn))?;
|
|
for relay in &mut self.relays {
|
|
relay.reload(conn)?;
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
pub fn apply_relay_states(&mut self, relay_states: &RelayStates) {
|
|
self.relays
|
|
.iter_mut()
|
|
.zip(relay_states.iter())
|
|
.for_each(|(relay, is_on)| {
|
|
relay.is_on = *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))
|
|
.min()
|
|
}
|
|
|
|
pub fn relay_pulse(&mut self, relay_num: i64, until: Instant) -> Result<(), EmgauwaError> {
|
|
let relay = self
|
|
.relays
|
|
.iter_mut()
|
|
.find(|r| r.r.number == relay_num)
|
|
.ok_or(EmgauwaError::Other(String::from("Relay not found")))?;
|
|
|
|
relay.pulsing = Some(until);
|
|
Ok(())
|
|
}
|
|
}
|