diff --git a/src/monitor.rs b/src/monitor.rs index 068bdc3..dec5afd 100644 --- a/src/monitor.rs +++ b/src/monitor.rs @@ -1,4 +1,4 @@ -use crate::tasmota::{PowerStatusData, StatusResponse}; +use crate::tasmota::{PowerStatusData, StatusResponse, TasmotaInterface, TasmotaInterfaceConfig}; use reqwest::Client; use serde::Deserialize; use std::fs; @@ -16,20 +16,24 @@ pub enum Error { JsonParseError(#[from] serde_json::Error), } +pub trait Monitoring { + async fn get_power(&self) -> Result; +} + #[derive(Deserialize)] pub struct MonitorConfig { - target: Vec, + targets: Vec, } impl MonitorConfig { fn print(&self) { - for t in &self.target { - println!("* {}", t); + for t in &self.targets { + t.print(); } } } pub struct Monitor { - config: MonitorConfig, + targets: Vec, client: Client, } @@ -37,26 +41,28 @@ impl Monitor { pub fn new_from_file(config_file: &str) -> Result { let config_str = fs::read_to_string(config_file)?; let config: MonitorConfig = toml::from_str(&config_str)?; - // config.print(); + config.print(); + Ok(Self { - config, + targets: Monitor::load_targets(&config.targets), client: Client::new(), }) } - pub async fn get_power(&self) -> Result<(), Error> { - let ip = &self.config.target[0]; - let res = self - .client - .get(format!("http://{ip}/cm?cmnd=Status%208")) - .send() - .await? - .text() - .await?; + pub fn load_targets(targets: &Vec) -> Vec { + let mut v = Vec::new(); + for target in targets { + v.push(TasmotaInterface::new(target.clone())); + } + v + } - // println!("body = {res:?}"); - let data: StatusResponse = serde_json::from_str(&res)?; - println!("POWER: {}W", data.status.energy.power); + pub async fn get_power(&self) -> Result<(), Error> { + for target in &self.targets { + if let Ok(res) = target.get_power().await { + println!("POWER: {}W", res); + } + } Ok(()) } } diff --git a/src/tasmota.rs b/src/tasmota.rs index 6cd1f7b..dcc010b 100644 --- a/src/tasmota.rs +++ b/src/tasmota.rs @@ -1,5 +1,9 @@ +use reqwest::Client; use serde::Deserialize; +use crate::monitor::Error; +use crate::monitor::Monitoring; + #[derive(Deserialize)] pub struct EnergyData { #[serde(rename = "Power")] @@ -19,3 +23,44 @@ pub struct StatusResponse { #[serde(rename = "StatusSNS")] pub status: PowerStatusData, } + +#[derive(Deserialize, Clone)] +pub struct TasmotaInterfaceConfig { + target: String, +} + +impl TasmotaInterfaceConfig { + pub fn print(&self) { + println!("* {}", self.target); + } +} + +pub struct TasmotaInterface { + config: TasmotaInterfaceConfig, + client: Client, +} + +impl TasmotaInterface { + pub fn new(config: TasmotaInterfaceConfig) -> Self { + Self { + config, + client: Client::new(), + } + } +} + +// Monitoring +impl Monitoring for TasmotaInterface { + async fn get_power(&self) -> Result { + let res = self + .client + .get(format!("http://{}/cm?cmnd=Status%208", &self.config.target)) + .send() + .await? + .text() + .await?; + + let data: StatusResponse = serde_json::from_str(&res)?; + Ok(data.status.energy.power) + } +}