1use chrono::{DateTime, Utc, serde::ts_seconds};
8use serde::{Deserialize, Serialize};
9
10#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
11pub struct Production {
12 pub production: Vec<Device>,
13 pub consumption: Vec<Device>,
14 pub storage: Vec<Device>,
15}
16
17#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
18#[serde(rename_all = "camelCase")]
19pub struct Device {
20 #[serde(rename = "type")]
22 pub type_: DeviceType,
23 pub active_count: u32,
25 pub measurement_type: Option<MeasurementType>,
26 #[serde(with = "ts_seconds")]
28 pub reading_time: DateTime<Utc>,
29 pub w_now: f64,
31 pub wh_now: Option<f64>,
32 pub state: Option<AcBatteryState>,
33 pub lines: Option<Vec<Line>>,
34 #[serde(flatten)]
35 pub details: Option<Details>,
36}
37
38#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
39#[serde(rename_all = "camelCase")]
40pub struct Line {
41 pub w_now: f64,
43 #[serde(flatten)]
44 pub details: Details,
45}
46
47#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
48#[serde(rename_all = "camelCase")]
49pub struct Details {
50 pub wh_lifetime: f64,
52 pub varh_lead_lifetime: f64,
54 pub varh_lag_lifetime: f64,
56 pub vah_lifetime: f64,
58 pub rms_current: f64,
60 pub rms_voltage: f64,
62 pub react_pwr: f64,
63 pub apprnt_pwr: f64,
64 pub pwr_factor: f64,
65 pub wh_today: f64,
66 pub wh_last_seven_days: f64,
67 pub vah_today: f64,
68 pub varh_lead_today: f64,
69 pub varh_lag_today: f64,
70}
71
72#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
73#[serde(rename_all = "lowercase")]
74pub enum DeviceType {
75 Inverters,
77 Eim,
79 Acb,
81 Rgms,
83 Pmus,
85}
86
87#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
88#[serde(rename_all = "kebab-case")]
89pub enum MeasurementType {
90 Production,
92 NetConsumption,
94 TotalConsumption,
96}
97
98#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
99#[serde(rename_all = "lowercase")]
100pub enum AcBatteryState {
101 Charging,
102 Discharging,
103 Full,
104 Idle,
105}
106
107#[cfg(test)]
108mod tests {
109 use super::*;
110
111 #[test]
112 fn parse_example() {
113 assert_eq!(
114 serde_json::from_str::<Production>(
115 r#"{
116 "production": [
117 {
118 "type": "inverters",
119 "activeCount": 10,
120 "readingTime": 1672574917,
121 "wNow": 225,
122 "whLifetime": 22444
123 },
124 {
125 "type": "eim",
126 "activeCount": 0,
127 "measurementType": "production",
128 "readingTime": 1672575063,
129 "wNow": 63.302,
130 "whLifetime": 1513.493,
131 "varhLeadLifetime": 0.024,
132 "varhLagLifetime": 16902.01,
133 "vahLifetime": 23774.477,
134 "rmsCurrent": 2.154,
135 "rmsVoltage": 240.087,
136 "reactPwr": 453.423,
137 "apprntPwr": 517.896,
138 "pwrFactor": 0.13,
139 "whToday": 2.0,
140 "whLastSevenDays": 1520.0,
141 "vahToday": 5106.0,
142 "varhLeadToday": 0.0,
143 "varhLagToday": 3865.0
144 }
145 ],
146 "consumption": [
147 {
148 "type": "eim",
149 "activeCount": 0,
150 "measurementType": "total-consumption",
151 "readingTime": 1672575063,
152 "wNow": 61.709,
153 "whLifetime": 1371.426,
154 "varhLeadLifetime": 0.205,
155 "varhLagLifetime": 16918.508,
156 "vahLifetime": 2593.65,
157 "rmsCurrent": 1.792,
158 "rmsVoltage": 243.568,
159 "reactPwr": -452.024,
160 "apprntPwr": 436.397,
161 "pwrFactor": 0.14,
162 "whToday": 0.0,
163 "whLastSevenDays": 1465.0,
164 "vahToday": 695.65,
165 "varhLeadToday": 0.205,
166 "varhLagToday": 3875.508
167 },
168 {
169 "type": "eim",
170 "activeCount": 0,
171 "measurementType": "net-consumption",
172 "readingTime": 1672575063,
173 "wNow": -1.592,
174 "whLifetime": 0.001,
175 "varhLeadLifetime": 0.181,
176 "varhLagLifetime": 16.498,
177 "vahLifetime": 2593.65,
178 "rmsCurrent": 0.363,
179 "rmsVoltage": 247.049,
180 "reactPwr": 1.398,
181 "apprntPwr": 61.047,
182 "pwrFactor": 0.0,
183 "whToday": 0,
184 "whLastSevenDays": 0,
185 "vahToday": 0,
186 "varhLeadToday": 0,
187 "varhLagToday": 0
188 }
189 ],
190 "storage": [
191 {
192 "type": "acb",
193 "activeCount": 0,
194 "readingTime": 0,
195 "wNow": 0,
196 "whNow": 0,
197 "state": "idle"
198 }
199 ]
200}
201 "#,
202 )
203 .unwrap(),
204 Production {
205 production: vec![
206 Device {
207 type_: DeviceType::Inverters,
208 active_count: 10,
209 measurement_type: None,
210 reading_time: "2023-01-01T12:08:37Z".parse().unwrap(),
211 w_now: 225.0,
212 wh_now: None,
213 state: None,
214 lines: None,
215 details: None,
216 },
217 Device {
218 type_: DeviceType::Eim,
219 active_count: 0,
220 measurement_type: Some(MeasurementType::Production),
221 reading_time: "2023-01-01T12:11:03Z".parse().unwrap(),
222 w_now: 63.302,
223 wh_now: None,
224 state: None,
225 lines: None,
226 details: Some(Details {
227 wh_lifetime: 1513.493,
228 varh_lead_lifetime: 0.024,
229 varh_lag_lifetime: 16902.01,
230 vah_lifetime: 23774.477,
231 rms_current: 2.154,
232 rms_voltage: 240.087,
233 react_pwr: 453.423,
234 apprnt_pwr: 517.896,
235 pwr_factor: 0.13,
236 wh_today: 2.0,
237 wh_last_seven_days: 1520.0,
238 vah_today: 5106.0,
239 varh_lead_today: 0.0,
240 varh_lag_today: 3865.0
241 })
242 }
243 ],
244 consumption: vec![
245 Device {
246 type_: DeviceType::Eim,
247 active_count: 0,
248 measurement_type: Some(MeasurementType::TotalConsumption),
249 reading_time: "2023-01-01T12:11:03Z".parse().unwrap(),
250 w_now: 61.709,
251 wh_now: None,
252 state: None,
253 lines: None,
254 details: Some(Details {
255 wh_lifetime: 1371.426,
256 varh_lead_lifetime: 0.205,
257 varh_lag_lifetime: 16918.508,
258 vah_lifetime: 2593.65,
259 rms_current: 1.792,
260 rms_voltage: 243.568,
261 react_pwr: -452.024,
262 apprnt_pwr: 436.397,
263 pwr_factor: 0.14,
264 wh_today: 0.0,
265 wh_last_seven_days: 1465.0,
266 vah_today: 695.65,
267 varh_lead_today: 0.205,
268 varh_lag_today: 3875.508
269 })
270 },
271 Device {
272 type_: DeviceType::Eim,
273 active_count: 0,
274 measurement_type: Some(MeasurementType::NetConsumption),
275 reading_time: "2023-01-01T12:11:03Z".parse().unwrap(),
276 w_now: -1.592,
277 wh_now: None,
278 state: None,
279 lines: None,
280 details: Some(Details {
281 wh_lifetime: 0.001,
282 varh_lead_lifetime: 0.181,
283 varh_lag_lifetime: 16.498,
284 vah_lifetime: 2593.65,
285 rms_current: 0.363,
286 rms_voltage: 247.049,
287 react_pwr: 1.398,
288 apprnt_pwr: 61.047,
289 pwr_factor: 0.0,
290 wh_today: 0.0,
291 wh_last_seven_days: 0.0,
292 vah_today: 0.0,
293 varh_lead_today: 0.0,
294 varh_lag_today: 0.0
295 })
296 }
297 ],
298 storage: vec![Device {
299 type_: DeviceType::Acb,
300 active_count: 0,
301 measurement_type: None,
302 reading_time: DateTime::from_timestamp_millis(0).unwrap(),
303 w_now: 0.0,
304 wh_now: Some(0.0),
305 state: Some(AcBatteryState::Idle),
306 details: None,
307 lines: None,
308 }],
309 }
310 );
311 }
312}