Use type-based data collections
This commit is contained in:
parent
97f7a5f1e2
commit
15d9d21c9b
3 changed files with 31 additions and 41 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -176,6 +176,7 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"strum_macros",
|
||||
"time",
|
||||
]
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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<ApiVersion, Box<dyn std::error::Err
|
|||
Ok(reqwest::blocking::Client::new().get(url).send()?.json()?)
|
||||
}
|
||||
|
||||
pub enum Scope {
|
||||
System,
|
||||
Device {
|
||||
device_id: DeviceId,
|
||||
data_collection: DataCollection,
|
||||
},
|
||||
}
|
||||
|
||||
pub struct DeviceId(u8);
|
||||
|
||||
impl TryFrom<u8> for DeviceId {
|
||||
|
@ -119,46 +111,42 @@ impl From<DeviceId> 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<T> {
|
||||
pac: T,
|
||||
day_energy: T,
|
||||
year_energy: T,
|
||||
total_energy: T,
|
||||
device_status: Option<std::collections::HashMap<String, String>>,
|
||||
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
||||
pub struct CumulationInverterData {
|
||||
pac: UnitAndValue<u64>,
|
||||
day_energy: UnitAndValue<f64>,
|
||||
year_energy: UnitAndValue<f64>,
|
||||
total_energy: UnitAndValue<f64>,
|
||||
#[serde(rename = "DeviceStatus")]
|
||||
device_status: Option<HashMap<String, serde_json::Value>>,
|
||||
}
|
||||
|
||||
pub fn get_inverter_realtime_data(
|
||||
ip: IpAddr,
|
||||
scope: Scope,
|
||||
) -> Result<FroniousResponse, Box<dyn std::error::Error>> {
|
||||
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<C: DataCollection>(
|
||||
ip: IpAddr,
|
||||
device_id: DeviceId,
|
||||
) -> Result<FroniousResponse<CommonResponseBody<CumulationInverterData>>, Box<dyn std::error::Error>>
|
||||
{
|
||||
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);
|
||||
|
|
Loading…
Reference in a new issue