use actix::{Actor, AsyncContext}; use emgauwa_common::db::{DbController, DbJunctionRelaySchedule, DbRelay, DbSchedule}; use emgauwa_common::errors::{DatabaseError, EmgauwaError}; use emgauwa_common::models::{Controller, FromDbModel}; use emgauwa_common::types::{ControllerWsAction, EmgauwaUid, RelayStates}; use emgauwa_common::utils; use futures::executor::block_on; use sqlx::pool::PoolConnection; use sqlx::Sqlite; use crate::app_state::{Action, ConnectController, UpdateRelayStates}; use crate::handlers::v1::ws::controllers::ControllersWs; impl ControllersWs { pub fn handle_register( &mut self, conn: &mut PoolConnection<Sqlite>, ctx: &mut <ControllersWs as Actor>::Context, controller: Controller, ) -> Result<(), EmgauwaError> { log::info!( "Registering controller: {} ({})", controller.c.name, controller.c.uid ); let c = &controller.c; let controller_db = block_on(DbController::get_by_uid_or_create( conn, &c.uid, &c.name, c.relay_count, ))?; block_on(controller_db.update_active(conn, true))?; // update only the relay count block_on(controller_db.update(conn, &controller_db.name, c.relay_count))?; for relay in &controller.relays { log::debug!( "Registering relay: {} ({})", relay.r.name, match relay.is_on { Some(true) => "+", Some(false) => "-", None => "?", } ); let (new_relay, created) = block_on(DbRelay::get_by_controller_and_num_or_create( conn, &controller_db, relay.r.number, &relay.r.name, ))?; if created { let mut relay_schedules = Vec::new(); for schedule in &relay.schedules { let (new_schedule, _) = block_on(DbSchedule::get_by_uid_or_create( conn, schedule.uid.clone(), &schedule.name, &schedule.periods, ))?; relay_schedules.push(new_schedule); } block_on(DbJunctionRelaySchedule::set_schedules( conn, &new_relay, relay_schedules.iter().collect(), ))?; } } let controller_uid = &controller.c.uid; let controller_db = block_on(DbController::get_by_uid(conn, controller_uid))? .ok_or(DatabaseError::InsertGetError)?; let controller = Controller::from_db_model(conn, controller_db)?; let addr = ctx.address(); self.controller_uid = Some(controller_uid.clone()); block_on(self.app_state.send(ConnectController { address: addr.recipient(), controller: controller.clone(), }))??; block_on(self.app_state.send(Action { controller_uid: controller_uid.clone(), action: ControllerWsAction::Controller(controller.clone()), }))??; block_on(self.app_state.send(Action { controller_uid: controller_uid.clone(), action: ControllerWsAction::Relays(controller.relays), }))??; log::debug!("Done registering controller"); Ok(()) } pub fn handle_relay_states( &mut self, controller_uid: EmgauwaUid, relay_states: RelayStates, ) -> Result<(), EmgauwaError> { log::debug!( "Received relay states: {} for {}", utils::printable_relay_states(&relay_states), controller_uid ); block_on(self.app_state.send(UpdateRelayStates { controller_uid, relay_states, }))?; Ok(()) } }