use emgauwa_common::errors::EmgauwaError; use emgauwa_common::{drivers, settings}; use rppal_pfd::PiFaceDigital; use serde_derive::Deserialize; use crate::driver::Driver; #[derive(Clone, Debug, Deserialize)] #[serde(default)] #[allow(unused)] pub struct Relay { pub driver: Driver, pub name: String, pub number: i64, pub pin: u8, pub inverted: bool, pub pulse: Option<u64>, } #[derive(Clone, Debug, Deserialize)] #[serde(default)] #[allow(unused)] pub struct Settings { pub server: settings::Server, pub database: String, pub permissions: settings::Permissions, pub logging: settings::Logging, pub name: String, pub relays: Vec<Relay>, } impl Default for Settings { fn default() -> Self { Settings { server: settings::Server::default(), database: String::from("sqlite://emgauwa-controller.sqlite"), permissions: settings::Permissions::default(), logging: settings::Logging::default(), name: String::from("Emgauwa Controller"), relays: Vec::new(), } } } impl Default for Relay { fn default() -> Self { Relay { driver: Driver::Gpio, number: None, name: String::from("Relay"), pin: 0, inverted: false, pulse: None, } } } pub fn init() -> Result<Settings, EmgauwaError> { settings::load("controller", "CONTROLLER") } impl Settings { pub fn get_relay(&self, number: i64) -> Option<&Relay> { self.relays.iter().find(|r| r.number == number) } pub fn relays_make_drivers( &self, pfd: &mut Option<PiFaceDigital>, ) -> Result<Vec<Box<dyn drivers::RelayDriver>>, EmgauwaError> { let mut drivers = Vec::new(); for relay in &self.relays { drivers.push(relay.make_driver(pfd)?); } Ok(drivers) } } impl Relay { pub fn make_driver( &self, pfd: &mut Option<PiFaceDigital>, ) -> Result<Box<dyn drivers::RelayDriver>, EmgauwaError> { let driver: Box<dyn drivers::RelayDriver> = match self.driver { Driver::Null => Box::new(drivers::NullDriver::new(self.pin)), Driver::Gpio => Box::new(drivers::GpioDriver::new(self.pin, self.inverted)?), Driver::PiFace => { if pfd.is_none() { *pfd = Some(drivers::PiFaceDriver::init_piface()?); } Box::new(drivers::PiFaceDriver::new(self.pin, pfd)?) } }; Ok(driver) } }