From ca6988b01f9ae19e6d92e40d018cf79ed89ebaf2 Mon Sep 17 00:00:00 2001
From: Tobias Reisinger <tobias@msrg.cc>
Date: Fri, 10 May 2024 16:47:28 +0200
Subject: [PATCH] Improve relay initialization

---
 Cargo.lock      |  1 -
 src/main.rs     | 11 ++++++++---
 src/settings.rs | 16 +++++++++++-----
 3 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index e313d9a..637c455 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -704,7 +704,6 @@ dependencies = [
 [[package]]
 name = "emgauwa-common"
 version = "0.5.0"
-source = "git+https://git.serguzim.me/emgauwa/common.git#b14049b3f6e8aa6a748e4d185bd52ca3f7a38f38"
 dependencies = [
  "actix",
  "actix-web",
diff --git a/src/main.rs b/src/main.rs
index b49a92b..4d07668 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -64,9 +64,6 @@ 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)?;
@@ -105,6 +102,12 @@ async fn main() -> Result<(), std::io::Error> {
 
 	let this = Controller::from_db_model(&mut conn, db_controller).map_err(EmgauwaError::from)?;
 
+	let now = chrono::Local::now().time();
+	let initial_states: Vec<bool> = this.relays.iter().map(|r| r.active_schedule.is_on(&now)).collect();
+
+	let mut pfd: Option<PiFaceDigital> = None;
+	let drivers = settings.relays_make_drivers(&mut pfd, initial_states)?;
+
 	let url = format!(
 		"ws://{}:{}/api/v1/ws/controllers",
 		settings.server.host, settings.server.port
@@ -112,6 +115,8 @@ async fn main() -> Result<(), std::io::Error> {
 
 	let app_state = app_state::AppState::new(pool.clone(), this, settings, drivers).start();
 
+	log::info!("Starting main loops");
+
 	let _ = tokio::join!(
 		tokio::spawn(run_relays_loop(app_state.clone())),
 		tokio::spawn(run_ws_loop(pool.clone(), app_state.clone(), url)),
diff --git a/src/settings.rs b/src/settings.rs
index 445f531..a5fd5bf 100644
--- a/src/settings.rs
+++ b/src/settings.rs
@@ -68,11 +68,15 @@ impl Settings {
 	pub fn relays_make_drivers(
 		&self,
 		pfd: &mut Option<PiFaceDigital>,
-	) -> Result<Vec<Box<dyn drivers::RelayDriver>>, EmgauwaError> {
+		initial_states: Vec<bool>,
+    ) -> Result<Vec<Box<dyn drivers::RelayDriver>>, EmgauwaError> {
 		let mut drivers = Vec::new();
-		for relay in &self.relays {
-			drivers.push(relay.make_driver(pfd)?);
-		}
+		let result: Result<(), EmgauwaError> = self.relays.iter().zip(initial_states.into_iter()).try_for_each(|(relay, state)| {
+			let driver = relay.make_driver(pfd, state)?;
+			drivers.push(driver);
+			Ok(())
+		});
+		result?;
 		Ok(drivers)
 	}
 }
@@ -81,8 +85,9 @@ impl Relay {
 	pub fn make_driver(
 		&self,
 		pfd: &mut Option<PiFaceDigital>,
+		state: bool,
 	) -> Result<Box<dyn drivers::RelayDriver>, EmgauwaError> {
-		let driver: Box<dyn drivers::RelayDriver> = match self.driver {
+		let mut driver: Box<dyn drivers::RelayDriver> = match self.driver {
 			drivers::Driver::Null => Box::new(drivers::NullDriver::new(self.pin)),
 			drivers::Driver::Gpio => Box::new(drivers::GpioDriver::new(self.pin, self.inverted)?),
 			drivers::Driver::PiFace => {
@@ -92,6 +97,7 @@ impl Relay {
 				Box::new(drivers::PiFaceDriver::new(self.pin, pfd)?)
 			}
 		};
+		driver.set(state)?;
 		Ok(driver)
 	}
 }