Add drivers for gpio and piface
This commit is contained in:
parent
61a3c6093b
commit
4ed1cd3182
14 changed files with 259 additions and 17 deletions
emgauwa-controller
|
@ -26,3 +26,7 @@ sqlx = { version = "0.7", features = ["sqlite", "runtime-tokio", "macros", "chro
|
|||
|
||||
futures = "0.3"
|
||||
futures-channel = "0.3"
|
||||
|
||||
rppal = "0.17"
|
||||
rppal-pfd = "0.0.5"
|
||||
rppal-mcp23s17 = "0.0.3"
|
||||
|
|
|
@ -3,6 +3,7 @@ use std::time::{Duration, Instant};
|
|||
|
||||
use actix::{Actor, Context, Handler, Message};
|
||||
use emgauwa_lib::constants;
|
||||
use emgauwa_lib::drivers::RelayDriver;
|
||||
use emgauwa_lib::errors::EmgauwaError;
|
||||
use emgauwa_lib::models::Controller;
|
||||
use emgauwa_lib::types::RelayStates;
|
||||
|
@ -45,16 +46,23 @@ pub struct AppState {
|
|||
pub pool: Pool<Sqlite>,
|
||||
pub this: Controller,
|
||||
pub settings: Settings,
|
||||
pub drivers: Vec<Box<dyn RelayDriver>>,
|
||||
pub controller_notifier: Arc<Notify>,
|
||||
pub relay_notifier: Arc<Notify>,
|
||||
}
|
||||
|
||||
impl AppState {
|
||||
pub fn new(pool: Pool<Sqlite>, this: Controller, settings: Settings) -> AppState {
|
||||
pub fn new(
|
||||
pool: Pool<Sqlite>,
|
||||
this: Controller,
|
||||
settings: Settings,
|
||||
drivers: Vec<Box<dyn RelayDriver>>,
|
||||
) -> AppState {
|
||||
AppState {
|
||||
pool,
|
||||
this,
|
||||
settings,
|
||||
drivers,
|
||||
controller_notifier: Arc::new(Notify::new()),
|
||||
relay_notifier: Arc::new(Notify::new()),
|
||||
}
|
||||
|
@ -93,6 +101,14 @@ impl Handler<UpdateRelayStates> for AppState {
|
|||
|
||||
fn handle(&mut self, msg: UpdateRelayStates, _ctx: &mut Self::Context) -> Self::Result {
|
||||
self.this.apply_relay_states(&msg.relay_states);
|
||||
self.drivers
|
||||
.iter_mut()
|
||||
.zip(msg.relay_states.iter())
|
||||
.for_each(|(driver, state)| {
|
||||
if let Err(e) = driver.set(state.unwrap_or(false)) {
|
||||
log::error!("Error setting relay: {}", e);
|
||||
}
|
||||
});
|
||||
|
||||
self.notify_relay_change();
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ use emgauwa_lib::errors::EmgauwaError;
|
|||
use emgauwa_lib::models::{Controller, FromDbModel};
|
||||
use emgauwa_lib::types::ControllerUid;
|
||||
use emgauwa_lib::utils::{drop_privileges, init_logging};
|
||||
use rppal_pfd::PiFaceDigital;
|
||||
use sqlx::pool::PoolConnection;
|
||||
use sqlx::Sqlite;
|
||||
|
||||
|
@ -64,6 +65,9 @@ async fn main() -> Result<(), std::io::Error> {
|
|||
|
||||
init_logging(&settings.logging.level)?;
|
||||
|
||||
let mut pfd: Option<PiFaceDigital> = None;
|
||||
let drivers = settings.relays_make_drivers(&mut pfd)?;
|
||||
|
||||
let pool = db::init(&settings.database)
|
||||
.await
|
||||
.map_err(EmgauwaError::from)?;
|
||||
|
@ -109,7 +113,7 @@ async fn main() -> Result<(), std::io::Error> {
|
|||
settings.server.host, settings.server.port
|
||||
);
|
||||
|
||||
let app_state = app_state::AppState::new(pool.clone(), this, settings).start();
|
||||
let app_state = app_state::AppState::new(pool.clone(), this, settings, drivers).start();
|
||||
|
||||
let _ = tokio::join!(
|
||||
tokio::spawn(run_relays_loop(app_state.clone())),
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use emgauwa_lib::drivers::{GpioDriver, PifaceDriver, RelayDriver};
|
||||
use emgauwa_lib::errors::EmgauwaError;
|
||||
use emgauwa_lib::settings;
|
||||
use rppal_pfd::PiFaceDigital;
|
||||
use serde_derive::Deserialize;
|
||||
|
||||
use crate::driver::Driver;
|
||||
|
@ -72,4 +74,33 @@ impl Settings {
|
|||
pub fn get_relay(&self, number: i64) -> Option<&Relay> {
|
||||
self.relays.iter().find(|r| r.number == Some(number))
|
||||
}
|
||||
|
||||
pub fn relays_make_drivers(
|
||||
&self,
|
||||
pfd: &mut Option<PiFaceDigital>,
|
||||
) -> Result<Vec<Box<dyn 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 RelayDriver>, EmgauwaError> {
|
||||
let driver: Box<dyn RelayDriver> = match self.driver {
|
||||
Driver::Gpio => Box::new(GpioDriver::new(self.pin, self.inverted)?),
|
||||
Driver::Piface => {
|
||||
if pfd.is_none() {
|
||||
*pfd = Some(PifaceDriver::init_piface()?);
|
||||
}
|
||||
Box::new(PifaceDriver::new(self.pin, pfd)?)
|
||||
}
|
||||
};
|
||||
Ok(driver)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue