diff --git a/Cargo.lock b/Cargo.lock index acf7184..352765d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -176,6 +176,7 @@ version = "0.1.0" dependencies = [ "reqwest", "serde", + "serde_json", "strum_macros", "time", ] diff --git a/Cargo.toml b/Cargo.toml index c66572a..3afa102 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,3 +10,4 @@ serde = { version = "1.0", features = ["derive"]} reqwest = { version = "0.11", features = ["blocking", "json"]} strum_macros = { version = "0.26.1"} time = { version = "0.3.32", features = ["serde", "serde-well-known"]} +serde_json = "1.0.113" diff --git a/src/fronious.rs b/src/fronious.rs index e12030c..677037c 100644 --- a/src/fronious.rs +++ b/src/fronious.rs @@ -1,4 +1,4 @@ -use serde::{Deserialize, Serialize}; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; use std::net::IpAddr; #[derive(Debug)] @@ -91,14 +91,6 @@ pub fn get_api_version(ip: IpAddr) -> Result for DeviceId { @@ -119,46 +111,41 @@ impl From for u8 { } } -#[derive(strum_macros::Display)] -pub enum DataCollection { - CumulationInverterData, - CommonInverterData, - ThreePInverterData, - MinMaxInverterData, +pub trait DataCollection: DeserializeOwned { + /// Returns the value of the `DataCollection` GET parameter for this collection. + fn param_value() -> &'static str; } #[derive(Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct CumulationInverterData { - pac: T, - day_energy: T, - year_energy: T, - total_energy: T, - device_status: Option>, +#[serde(rename_all = "SCREAMING_SNAKE_CASE")] +pub struct CumulationInverterData { + pac: UnitAndValue, + day_energy: UnitAndValue, + year_energy: UnitAndValue, + total_energy: UnitAndValue, + #[serde(rename = "DeviceStatus")] + device_status: Option>, } -pub fn get_inverter_realtime_data( - ip: IpAddr, - scope: Scope, -) -> Result> { - let mut params: Vec<(&str, String)> = vec![]; - - match scope { - Scope::System => { - params.push(("Scope", "System".to_owned())); - } - Scope::Device { - device_id, - data_collection, - } => { - params.push(("Scope", "Device".to_owned())); - params.push(("DeviceId", (u8::from(device_id)).to_string())); - params.push(("DataCollection", data_collection.to_string())); - } +impl DataCollection for CumulationInverterData { + fn param_value() -> &'static str { + "CumulationInverterData" } +} + +pub fn get_inverter_realtime_data_device( + ip: IpAddr, + device_id: DeviceId, +) -> Result>, Box> { + let device_id = u8::from(device_id).to_string(); + let params = [ + ("Scope", "Device"), + ("DeviceId", &device_id), + ("DataCollection", C::param_value()), + ]; let mut url = reqwest::Url::parse_with_params( - &format!("http://placeholder.local/solar_api/v1/GetInverterRealtimeData.cgi"), + "http://placeholder.local/solar_api/v1/GetInverterRealtimeData.cgi", ¶ms, )?; let _ = url.set_ip_host(ip);