From c726ddefc1b215e74423195683297438b7856cdf Mon Sep 17 00:00:00 2001 From: hodasemi Date: Tue, 19 Sep 2023 11:18:22 +0200 Subject: [PATCH] Implement main functionality --- src/db.rs | 55 ++++++++++++++++++++++++++++++++++++++++++++++---- src/devices.rs | 5 +++-- src/main.rs | 13 ++++++------ src/tasmota.rs | 20 +++++++++++++----- 4 files changed, 75 insertions(+), 18 deletions(-) diff --git a/src/db.rs b/src/db.rs index dae71c1..f49a954 100644 --- a/src/db.rs +++ b/src/db.rs @@ -1,7 +1,7 @@ use std::path::Path; use anyhow::Result; -use rusqlite::Connection; +use rusqlite::{Connection, ToSql}; pub struct DataBase { sql: Connection, @@ -19,10 +19,57 @@ impl DataBase { } fn generate_tables(&self) -> Result<()> { - todo!() + self.sql.execute( + "CREATE TABLE IF NOT EXISTS data ( + id INTEGER PRIMARY KEY, + device TEXT NOT NULL, + time BIGINT NOT NULL, + watts REAL NOT NULL + )", + [], + )?; + + Ok(()) } - pub async fn write(&self, device_name: &str, time: u64, watts: f32) -> Result<()> { - todo!() + pub fn write(&self, device_name: &str, time: u64, watts: f32) -> Result<()> { + let params: &[&dyn ToSql] = &[&device_name, &time, &watts]; + + self.sql.execute( + "INSERT INTO data (device, time, watts) + VALUES (?1, ?2, ?3)", + params, + )?; + + Ok(()) + } +} + +#[cfg(test)] +mod test { + use std::fs; + + use anyhow::Result; + + use super::DataBase; + + #[tokio::test] + async fn test_connection() -> Result<()> { + DataBase::new("connection_test.db").await?; + + fs::remove_file("connection_test.db")?; + + Ok(()) + } + + #[tokio::test] + async fn test_write() -> Result<()> { + let db = DataBase::new("write_test.db").await?; + + db.write("test", 0, 5.5)?; + + fs::remove_file("write_test.db")?; + + Ok(()) } } diff --git a/src/devices.rs b/src/devices.rs index 84a868a..cad79a1 100644 --- a/src/devices.rs +++ b/src/devices.rs @@ -14,8 +14,9 @@ impl Devices { Ok(from_str(&fs::read_to_string(file)?)?) } + #[allow(unused)] pub fn save(&self, file: &str) -> Result<()> { - fs::write("devices.conf", to_string_pretty(self)?)?; + fs::write(file, to_string_pretty(self)?)?; Ok(()) } @@ -32,6 +33,6 @@ mod test { plugs: vec!["Dev1".to_string(), "Dev2".to_string()], }; - devices.save("devices.conf") + devices.save("test_devices.conf") } } diff --git a/src/main.rs b/src/main.rs index 6ff87c8..4490395 100644 --- a/src/main.rs +++ b/src/main.rs @@ -35,13 +35,12 @@ async fn main() -> Result<()> { loop { try_join_all(tasmota_plugs.iter().map(|plug| async { - let usage = plug.read_power_usage().await?; - - shared_db - .lock() - .unwrap() - .write(plug.name(), since_epoch()?, usage) - .await?; + if let Ok(usage) = plug.read_power_usage().await { + shared_db + .lock() + .unwrap() + .write(plug.name(), since_epoch()?, usage)?; + } Ok::<(), anyhow::Error>(()) })) diff --git a/src/tasmota.rs b/src/tasmota.rs index f0d9460..a09094b 100644 --- a/src/tasmota.rs +++ b/src/tasmota.rs @@ -38,22 +38,32 @@ impl Tasmota { } pub async fn turn_on_led(&self) -> Result<()> { - todo!("LedPower=1") + self.post("LedPower=1").await?; + + Ok(()) } pub async fn turn_off_led(&self) -> Result<()> { - todo!("LedPower=2") + self.post("LedPower=2").await?; + + Ok(()) } pub async fn switch_on(&self) -> Result<()> { - todo!("Power0=1") + self.post("Power0=1").await?; + + Ok(()) } pub async fn switch_off(&self) -> Result<()> { - todo!("Power0=0") + self.post("Power0=0").await?; + + Ok(()) } pub async fn read_power_usage(&self) -> Result { - todo!("Status=8") + let res = self.get("Status=8").await?; + + Ok(res.parse()?) } }