Skip to main content

signalk/
electrical.rs

1use std::collections::HashMap;
2
3use serde::{Deserialize, Serialize};
4
5use crate::definitions::{V1CommonValueFields, V1NumberValue, V2NumberValue};
6use crate::{helper_functions, SignalKGetError};
7
8#[derive(Serialize, Deserialize, PartialEq, Debug, Default, Clone)]
9pub struct V1Electrical {
10    pub batteries: Option<HashMap<String, V1Battery>>,
11    pub inverters: Option<HashMap<String, V1Inverter>>,
12    pub chargers: Option<HashMap<String, V1Charger>>,
13    pub alternators: Option<HashMap<String, V1Alternator>>,
14    pub solar: Option<HashMap<String, V1Solar>>,
15    pub ac: Option<HashMap<String, V1ACBus>>,
16}
17
18impl V1Electrical {
19    pub fn builder() -> V1ElectricalBuilder {
20        V1ElectricalBuilder::default()
21    }
22
23    pub fn update(&mut self, path: &mut Vec<&str>, value: &serde_json::value::Value) {
24        match path[0] {
25            "batteries" => {
26                if self.batteries.is_none() {
27                    self.batteries = Some(HashMap::new());
28                }
29                if let Some(ref mut batteries) = self.batteries {
30                    let id = path[1].to_string();
31                    if !batteries.contains_key(&id) {
32                        batteries.insert(
33                            id.clone(),
34                            V1Battery::builder()
35                                .identity(V1ElectricalIdentity::builder().name(id.clone()).build())
36                                .build(),
37                        );
38                    }
39                    let mut t = batteries.get_mut(&id);
40                    if let Some(ref mut battery) = t {
41                        path.remove(0); // Remove batteries
42                        path.remove(0); // and the index of the bank
43                        battery.update(path, value);
44                    }
45                }
46            }
47
48            &_ => {
49                log::warn!(
50                    "V1Electrical: Unknown value to update: {:?}::{:?}",
51                    path,
52                    value
53                );
54            }
55        }
56    }
57
58    pub fn get_f64_for_path(&self, path: &mut Vec<&str>) -> Result<f64, SignalKGetError> {
59        match path[0] {
60            "batteries" => {
61                log::debug!("batteries path: {:?}", path);
62                if let Some(ref batteries) = self.batteries {
63                    if let Some(battery) = batteries.get(path[1]) {
64                        path.remove(0); // Remove both batteries
65                        path.remove(0); // Remove name instance
66                        battery.get_f64_for_path(path)
67                    } else {
68                        Err(SignalKGetError::NoSuchPath)
69                    }
70                } else {
71                    Err(SignalKGetError::ValueNotSet)
72                }
73            }
74            &_ => {
75                log::info!("path: {:?}", path);
76                Err(SignalKGetError::NoSuchPath)
77            }
78        }
79    }
80}
81
82#[derive(Default)]
83pub struct V1ElectricalBuilder {
84    batteries: Option<HashMap<String, V1Battery>>,
85    inverters: Option<HashMap<String, V1Inverter>>,
86    chargers: Option<HashMap<String, V1Charger>>,
87    alternators: Option<HashMap<String, V1Alternator>>,
88    solar: Option<HashMap<String, V1Solar>>,
89    ac: Option<HashMap<String, V1ACBus>>,
90}
91
92impl V1ElectricalBuilder {
93    pub fn add_battery(mut self, key: String, value: V1Battery) -> V1ElectricalBuilder {
94        if self.batteries.is_none() {
95            self.batteries = Some(HashMap::new());
96        }
97        if let Some(ref mut x) = self.batteries {
98            x.insert(key, value);
99        }
100        self
101    }
102    pub fn add_inverter(mut self, key: String, value: V1Inverter) -> V1ElectricalBuilder {
103        if self.inverters.is_none() {
104            self.inverters = Some(HashMap::new());
105        }
106        if let Some(ref mut x) = self.inverters {
107            x.insert(key, value);
108        }
109        self
110    }
111    pub fn add_charger(mut self, key: String, value: V1Charger) -> V1ElectricalBuilder {
112        if self.chargers.is_none() {
113            self.chargers = Some(HashMap::new());
114        }
115        if let Some(ref mut x) = self.chargers {
116            x.insert(key, value);
117        }
118        self
119    }
120    pub fn add_alternator(mut self, key: String, value: V1Alternator) -> V1ElectricalBuilder {
121        if self.alternators.is_none() {
122            self.alternators = Some(HashMap::new());
123        }
124        if let Some(ref mut x) = self.alternators {
125            x.insert(key, value);
126        }
127        self
128    }
129    pub fn add_solar(mut self, key: String, value: V1Solar) -> V1ElectricalBuilder {
130        if self.solar.is_none() {
131            self.solar = Some(HashMap::new());
132        }
133        if let Some(ref mut x) = self.solar {
134            x.insert(key, value);
135        }
136        self
137    }
138    pub fn add_ac(mut self, key: String, value: V1ACBus) -> V1ElectricalBuilder {
139        if self.ac.is_none() {
140            self.ac = Some(HashMap::new());
141        }
142        if let Some(ref mut x) = self.ac {
143            x.insert(key, value);
144        }
145        self
146    }
147
148    pub fn build(self) -> V1Electrical {
149        V1Electrical {
150            batteries: self.batteries,
151            inverters: self.inverters,
152            chargers: self.chargers,
153            alternators: self.alternators,
154            solar: self.solar,
155            ac: self.ac,
156        }
157    }
158}
159
160#[derive(Serialize, Deserialize, PartialEq, Debug, Default, Clone)]
161#[serde(rename_all = "camelCase")]
162pub struct V1ElectricalIdentity {
163    pub name: Option<String>,
164    pub location: Option<String>,
165    pub date_installed: Option<String>,
166    pub manufacturer: Option<V1ElectricalManufacturer>,
167}
168
169impl V1ElectricalIdentity {
170    pub fn builder() -> V1ElectricalIdentityBuilder {
171        V1ElectricalIdentityBuilder::default()
172    }
173}
174
175#[derive(Default)]
176pub struct V1ElectricalIdentityBuilder {
177    name: Option<String>,
178    location: Option<String>,
179    date_installed: Option<String>,
180    manufacturer: Option<V1ElectricalManufacturer>,
181}
182
183impl V1ElectricalIdentityBuilder {
184    pub fn name(mut self, value: String) -> V1ElectricalIdentityBuilder {
185        self.name = Some(value);
186        self
187    }
188    pub fn location(mut self, value: String) -> V1ElectricalIdentityBuilder {
189        self.location = Some(value);
190        self
191    }
192    pub fn date_installed(mut self, value: String) -> V1ElectricalIdentityBuilder {
193        self.date_installed = Some(value);
194        self
195    }
196    pub fn manufacturer(mut self, value: V1ElectricalManufacturer) -> V1ElectricalIdentityBuilder {
197        self.manufacturer = Some(value);
198        self
199    }
200    pub fn build(self) -> V1ElectricalIdentity {
201        V1ElectricalIdentity {
202            name: self.name,
203            location: self.location,
204            date_installed: self.date_installed,
205            manufacturer: self.manufacturer,
206        }
207    }
208}
209
210#[derive(Serialize, Deserialize, PartialEq, Debug, Default, Clone)]
211pub struct V1ElectricalManufacturer {
212    pub name: Option<String>,
213    pub model: Option<String>,
214    #[serde(rename = "URL")]
215    pub url: Option<String>,
216}
217
218impl V1ElectricalManufacturer {
219    pub fn builder() -> V1ElectricalManufacturerBuilder {
220        V1ElectricalManufacturerBuilder::default()
221    }
222}
223
224#[derive(Default)]
225pub struct V1ElectricalManufacturerBuilder {
226    name: Option<String>,
227    model: Option<String>,
228    url: Option<String>,
229}
230
231impl V1ElectricalManufacturerBuilder {
232    pub fn name(mut self, value: String) -> V1ElectricalManufacturerBuilder {
233        self.name = Some(value);
234        self
235    }
236    pub fn model(mut self, value: String) -> V1ElectricalManufacturerBuilder {
237        self.model = Some(value);
238        self
239    }
240    pub fn url(mut self, value: String) -> V1ElectricalManufacturerBuilder {
241        self.url = Some(value);
242        self
243    }
244    pub fn build(self) -> V1ElectricalManufacturer {
245        V1ElectricalManufacturer {
246            name: self.name,
247            model: self.model,
248            url: self.url,
249        }
250    }
251}
252
253#[derive(Serialize, Deserialize, PartialEq, Debug, Default, Clone)]
254#[serde(rename_all = "camelCase")]
255pub struct V1ElectricalDCQualities {
256    pub associated_bus: Option<String>,
257    pub voltage: Option<V1ElectricalDCVoltageValue>,
258    pub current: Option<V1ElectricalDCCurrentValue>,
259    pub temperature: Option<V1ElectricalDCTemperatureValue>,
260}
261
262impl V1ElectricalDCQualities {
263    pub fn builder() -> V1ElectricalDCQualitiesBuilder {
264        V1ElectricalDCQualitiesBuilder::default()
265    }
266}
267
268#[derive(Default)]
269pub struct V1ElectricalDCQualitiesBuilder {
270    associated_bus: Option<String>,
271    voltage: Option<V1ElectricalDCVoltageValue>,
272    current: Option<V1ElectricalDCCurrentValue>,
273    temperature: Option<V1ElectricalDCTemperatureValue>,
274}
275
276impl V1ElectricalDCQualitiesBuilder {
277    pub fn associated_bus(mut self, value: String) -> V1ElectricalDCQualitiesBuilder {
278        self.associated_bus = Some(value);
279        self
280    }
281    pub fn voltage(mut self, value: V1ElectricalDCVoltageValue) -> V1ElectricalDCQualitiesBuilder {
282        self.voltage = Some(value);
283        self
284    }
285    pub fn current(mut self, value: V1ElectricalDCCurrentValue) -> V1ElectricalDCQualitiesBuilder {
286        self.current = Some(value);
287        self
288    }
289    pub fn temperature(
290        mut self,
291        value: V1ElectricalDCTemperatureValue,
292    ) -> V1ElectricalDCQualitiesBuilder {
293        self.temperature = Some(value);
294        self
295    }
296    pub fn build(self) -> V1ElectricalDCQualities {
297        V1ElectricalDCQualities {
298            associated_bus: self.associated_bus,
299            voltage: self.voltage,
300            current: self.current,
301            temperature: self.temperature,
302        }
303    }
304}
305
306#[derive(Serialize, Deserialize, PartialEq, Debug, Default, Clone)]
307#[serde(rename_all = "camelCase")]
308pub struct V1ElectricalDCVoltageValue {
309    #[serde(flatten)]
310    pub value: Option<V1NumberValue>,
311    pub ripple: Option<V1NumberValue>,
312    pub meta: Option<V1ElectricalDCVoltageMeta>,
313}
314
315impl V1ElectricalDCVoltageValue {
316    pub fn builder() -> V1ElectricalDCVoltageValueBuilder {
317        V1ElectricalDCVoltageValueBuilder::default()
318    }
319}
320
321#[derive(Default)]
322pub struct V1ElectricalDCVoltageValueBuilder {
323    value: Option<V1NumberValue>,
324    ripple: Option<V1NumberValue>,
325    meta: Option<V1ElectricalDCVoltageMeta>,
326}
327
328impl V1ElectricalDCVoltageValueBuilder {
329    pub fn value(mut self, value: V1NumberValue) -> V1ElectricalDCVoltageValueBuilder {
330        self.value = Some(value);
331        self
332    }
333    pub fn ripple(mut self, value: V1NumberValue) -> V1ElectricalDCVoltageValueBuilder {
334        self.ripple = Some(value);
335        self
336    }
337    pub fn meta(mut self, value: V1ElectricalDCVoltageMeta) -> V1ElectricalDCVoltageValueBuilder {
338        self.meta = Some(value);
339        self
340    }
341    pub fn build(self) -> V1ElectricalDCVoltageValue {
342        V1ElectricalDCVoltageValue {
343            value: self.value,
344            ripple: self.ripple,
345            meta: self.meta,
346        }
347    }
348}
349
350#[derive(Serialize, Deserialize, PartialEq, Debug, Default, Clone)]
351#[serde(rename_all = "camelCase")]
352pub struct V1ElectricalDCVoltageMeta {
353    pub nominal: Option<f64>,
354    pub warn_upper: Option<f64>,
355    pub warn_lower: Option<f64>,
356    pub fault_upper: Option<f64>,
357    pub fault_lower: Option<f64>,
358}
359
360impl V1ElectricalDCVoltageMeta {
361    pub fn builder() -> V1ElectricalDCVoltageMetaBuilder {
362        V1ElectricalDCVoltageMetaBuilder::default()
363    }
364}
365
366#[derive(Default)]
367pub struct V1ElectricalDCVoltageMetaBuilder {
368    nominal: Option<f64>,
369    warn_upper: Option<f64>,
370    warn_lower: Option<f64>,
371    fault_upper: Option<f64>,
372    fault_lower: Option<f64>,
373}
374
375impl V1ElectricalDCVoltageMetaBuilder {
376    pub fn nominal(mut self, value: f64) -> V1ElectricalDCVoltageMetaBuilder {
377        self.nominal = Some(value);
378        self
379    }
380    pub fn warn_upper(mut self, value: f64) -> V1ElectricalDCVoltageMetaBuilder {
381        self.warn_upper = Some(value);
382        self
383    }
384    pub fn warn_lower(mut self, value: f64) -> V1ElectricalDCVoltageMetaBuilder {
385        self.warn_lower = Some(value);
386        self
387    }
388    pub fn fault_upper(mut self, value: f64) -> V1ElectricalDCVoltageMetaBuilder {
389        self.fault_upper = Some(value);
390        self
391    }
392    pub fn fault_lower(mut self, value: f64) -> V1ElectricalDCVoltageMetaBuilder {
393        self.fault_lower = Some(value);
394        self
395    }
396    pub fn build(self) -> V1ElectricalDCVoltageMeta {
397        V1ElectricalDCVoltageMeta {
398            nominal: self.nominal,
399            warn_upper: self.warn_upper,
400            warn_lower: self.warn_lower,
401            fault_upper: self.fault_upper,
402            fault_lower: self.fault_lower,
403        }
404    }
405}
406
407#[derive(Serialize, Deserialize, PartialEq, Debug, Default, Clone)]
408#[serde(rename_all = "camelCase")]
409pub struct V1ElectricalDCCurrentValue {
410    #[serde(flatten)]
411    pub value: Option<V1NumberValue>,
412    pub meta: Option<V1ElectricalDCCurrentMeta>,
413}
414
415impl V1ElectricalDCCurrentValue {
416    pub fn builder() -> V1ElectricalDCCurrentValueBuilder {
417        V1ElectricalDCCurrentValueBuilder::default()
418    }
419}
420
421#[derive(Default)]
422pub struct V1ElectricalDCCurrentValueBuilder {
423    value: Option<V1NumberValue>,
424    meta: Option<V1ElectricalDCCurrentMeta>,
425}
426
427impl V1ElectricalDCCurrentValueBuilder {
428    pub fn value(mut self, value: V1NumberValue) -> V1ElectricalDCCurrentValueBuilder {
429        self.value = Some(value);
430        self
431    }
432    pub fn meta(mut self, value: V1ElectricalDCCurrentMeta) -> V1ElectricalDCCurrentValueBuilder {
433        self.meta = Some(value);
434        self
435    }
436    pub fn build(self) -> V1ElectricalDCCurrentValue {
437        V1ElectricalDCCurrentValue {
438            value: self.value,
439            meta: self.meta,
440        }
441    }
442}
443
444#[derive(Serialize, Deserialize, PartialEq, Debug, Default, Clone)]
445#[serde(rename_all = "camelCase")]
446pub struct V1ElectricalDCCurrentMeta {
447    #[serde(flatten)]
448    pub warn_upper: Option<f64>,
449    pub warn_lower: Option<f64>,
450    pub fault_upper: Option<f64>,
451    pub fault_lower: Option<f64>,
452}
453
454impl V1ElectricalDCCurrentMeta {
455    pub fn new(
456        warn_upper: Option<f64>,
457        warn_lower: Option<f64>,
458        fault_upper: Option<f64>,
459        fault_lower: Option<f64>,
460    ) -> Self {
461        Self {
462            warn_upper,
463            warn_lower,
464            fault_upper,
465            fault_lower,
466        }
467    }
468}
469
470#[derive(Serialize, Deserialize, PartialEq, Debug, Default, Clone)]
471#[serde(rename_all = "camelCase")]
472pub struct V1ElectricalDCTemperatureValue {
473    #[serde(flatten)]
474    pub value: Option<V1NumberValue>,
475    pub warn_upper: Option<f64>,
476    pub warn_lower: Option<f64>,
477    pub fault_upper: Option<f64>,
478    pub fault_lower: Option<f64>,
479}
480
481impl V1ElectricalDCTemperatureValue {
482    pub fn new(
483        value: Option<V1NumberValue>,
484        warn_upper: Option<f64>,
485        warn_lower: Option<f64>,
486        fault_upper: Option<f64>,
487        fault_lower: Option<f64>,
488    ) -> Self {
489        Self {
490            value,
491            warn_upper,
492            warn_lower,
493            fault_upper,
494            fault_lower,
495        }
496    }
497}
498
499#[derive(Serialize, Deserialize, PartialEq, Debug, Default, Clone)]
500#[serde(rename_all = "camelCase")]
501pub struct V1ElectricalACQualities {
502    pub associated_bus: Option<String>,
503    pub line_neutral_voltage: Option<V1NumberValue>,
504    pub line_line_voltage: Option<V1NumberValue>,
505    pub current: Option<V1NumberValue>,
506    pub frequency: Option<V1NumberValue>,
507    pub reactive_power: Option<V1NumberValue>,
508    pub power_factor: Option<V1NumberValue>,
509    pub power_factor_lagging: Option<String>,
510    pub real_power: Option<V1NumberValue>,
511    pub apparent_power: Option<V1NumberValue>,
512}
513
514impl V1ElectricalACQualities {
515    pub fn builder() -> V1ElectricalACQualitiesBuilder {
516        V1ElectricalACQualitiesBuilder::default()
517    }
518}
519
520#[derive(Default)]
521pub struct V1ElectricalACQualitiesBuilder {
522    associated_bus: Option<String>,
523    line_neutral_voltage: Option<V1NumberValue>,
524    line_line_voltage: Option<V1NumberValue>,
525    current: Option<V1NumberValue>,
526    frequency: Option<V1NumberValue>,
527    reactive_power: Option<V1NumberValue>,
528    power_factor: Option<V1NumberValue>,
529    power_factor_lagging: Option<String>,
530    real_power: Option<V1NumberValue>,
531    apparent_power: Option<V1NumberValue>,
532}
533
534impl V1ElectricalACQualitiesBuilder {
535    pub fn associated_bus(mut self, value: String) -> V1ElectricalACQualitiesBuilder {
536        self.associated_bus = Some(value);
537        self
538    }
539    pub fn line_neutral_voltage(mut self, value: V1NumberValue) -> V1ElectricalACQualitiesBuilder {
540        self.line_neutral_voltage = Some(value);
541        self
542    }
543    pub fn line_line_voltage(mut self, value: V1NumberValue) -> V1ElectricalACQualitiesBuilder {
544        self.line_line_voltage = Some(value);
545        self
546    }
547    pub fn current(mut self, value: V1NumberValue) -> V1ElectricalACQualitiesBuilder {
548        self.current = Some(value);
549        self
550    }
551    pub fn frequency(mut self, value: V1NumberValue) -> V1ElectricalACQualitiesBuilder {
552        self.frequency = Some(value);
553        self
554    }
555    pub fn reactive_power(mut self, value: V1NumberValue) -> V1ElectricalACQualitiesBuilder {
556        self.reactive_power = Some(value);
557        self
558    }
559    pub fn power_factor(mut self, value: V1NumberValue) -> V1ElectricalACQualitiesBuilder {
560        self.power_factor = Some(value);
561        self
562    }
563    pub fn power_factor_lagging(mut self, value: String) -> V1ElectricalACQualitiesBuilder {
564        self.power_factor_lagging = Some(value);
565        self
566    }
567    pub fn real_power(mut self, value: V1NumberValue) -> V1ElectricalACQualitiesBuilder {
568        self.real_power = Some(value);
569        self
570    }
571    pub fn apparent_power(mut self, value: V1NumberValue) -> V1ElectricalACQualitiesBuilder {
572        self.apparent_power = Some(value);
573        self
574    }
575    pub fn build(self) -> V1ElectricalACQualities {
576        V1ElectricalACQualities {
577            associated_bus: self.associated_bus,
578            line_neutral_voltage: self.line_neutral_voltage,
579            line_line_voltage: self.line_line_voltage,
580            current: self.current,
581            frequency: self.frequency,
582            reactive_power: self.reactive_power,
583            power_factor: self.power_factor,
584            power_factor_lagging: self.power_factor_lagging,
585            real_power: self.real_power,
586            apparent_power: self.apparent_power,
587        }
588    }
589}
590
591#[derive(Serialize, Deserialize, PartialEq, Debug, Default, Clone)]
592#[serde(rename_all = "camelCase")]
593pub struct V1BatteryTemperature {
594    #[serde(flatten)]
595    pub value: Option<V1NumberValue>,
596
597    pub limit_discharge_lower: Option<f64>,
598    pub limit_discharge_upper: Option<f64>,
599    pub limit_recharge_lower: Option<f64>,
600    pub limit_recharge_upper: Option<f64>,
601}
602
603impl V1BatteryTemperature {
604    pub fn new(
605        value: Option<V1NumberValue>,
606        limit_discharge_lower: Option<f64>,
607        limit_discharge_upper: Option<f64>,
608        limit_recharge_lower: Option<f64>,
609        limit_recharge_upper: Option<f64>,
610    ) -> Self {
611        Self {
612            value,
613            limit_discharge_lower,
614            limit_discharge_upper,
615            limit_recharge_lower,
616            limit_recharge_upper,
617        }
618    }
619}
620
621#[derive(Serialize, Deserialize, PartialEq, Debug, Default, Clone)]
622#[serde(rename_all = "camelCase")]
623pub struct V1BatteryCapacity {
624    pub nominal: Option<V2NumberValue>,
625    pub actual: Option<V2NumberValue>,
626    pub remaining: Option<V2NumberValue>,
627    pub discharge_limit: Option<V2NumberValue>,
628    pub state_of_charge: Option<V2NumberValue>,
629    pub state_of_health: Option<V2NumberValue>,
630    pub discharge_since_full: Option<V2NumberValue>,
631    pub time_remaining: Option<V2NumberValue>,
632}
633
634impl V1BatteryCapacity {
635    pub fn builder() -> V1BatteryCapacityBuilder {
636        V1BatteryCapacityBuilder::default()
637    }
638    pub fn update(&mut self, path: &mut Vec<&str>, value: &serde_json::value::Value) {
639        match path[0] {
640            "nominal" => self.nominal = V2NumberValue::from_value(value),
641            "actual" => self.actual = V2NumberValue::from_value(value),
642            "remaining" => self.remaining = V2NumberValue::from_value(value),
643            "dischargeLimit" => self.discharge_limit = V2NumberValue::from_value(value),
644            "stateOfCharge" => self.state_of_charge = V2NumberValue::from_value(value),
645            "stateOfHealth" => self.state_of_health = V2NumberValue::from_value(value),
646            "dischargeSinceFull" => self.discharge_since_full = V2NumberValue::from_value(value),
647            "timeRemaining" => self.time_remaining = V2NumberValue::from_value(value),
648            &_ => {
649                log::warn!(
650                    "V1BatteryCapacity: Unknown value to update: {:?}::{:?}",
651                    path,
652                    value
653                );
654            }
655        }
656    }
657}
658
659#[derive(Default)]
660pub struct V1BatteryCapacityBuilder {
661    nominal: Option<V2NumberValue>,
662    actual: Option<V2NumberValue>,
663    remaining: Option<V2NumberValue>,
664    discharge_limit: Option<V2NumberValue>,
665    state_of_charge: Option<V2NumberValue>,
666    state_of_health: Option<V2NumberValue>,
667    discharge_since_full: Option<V2NumberValue>,
668    time_remaining: Option<V2NumberValue>,
669}
670
671impl V1BatteryCapacityBuilder {
672    pub fn nominal(mut self, value: i64) -> V1BatteryCapacityBuilder {
673        self.nominal = Some(V2NumberValue::Int(value));
674        self
675    }
676    pub fn actual(mut self, value: i64) -> V1BatteryCapacityBuilder {
677        self.actual = Some(V2NumberValue::Int(value));
678        self
679    }
680    pub fn remaining(mut self, value: i64) -> V1BatteryCapacityBuilder {
681        self.remaining = Some(V2NumberValue::Int(value));
682        self
683    }
684    pub fn discharge_limit(mut self, value: i64) -> V1BatteryCapacityBuilder {
685        self.discharge_limit = Some(V2NumberValue::Int(value));
686        self
687    }
688    pub fn state_of_charge(mut self, value: i64) -> V1BatteryCapacityBuilder {
689        self.state_of_charge = Some(V2NumberValue::Int(value));
690        self
691    }
692    pub fn state_of_health(mut self, value: i64) -> V1BatteryCapacityBuilder {
693        self.state_of_health = Some(V2NumberValue::Int(value));
694        self
695    }
696    pub fn discharge_since_full(mut self, value: i64) -> V1BatteryCapacityBuilder {
697        self.discharge_since_full = Some(V2NumberValue::Int(value));
698        self
699    }
700    pub fn time_remaining(mut self, value: i64) -> V1BatteryCapacityBuilder {
701        self.time_remaining = Some(V2NumberValue::Int(value));
702        self
703    }
704    pub fn build(self) -> V1BatteryCapacity {
705        V1BatteryCapacity {
706            nominal: self.nominal,
707            actual: self.actual,
708            remaining: self.remaining,
709            discharge_limit: self.discharge_limit,
710            state_of_charge: self.state_of_charge,
711            state_of_health: self.state_of_health,
712            discharge_since_full: self.discharge_since_full,
713            time_remaining: self.time_remaining,
714        }
715    }
716}
717
718#[derive(Serialize, Deserialize, PartialEq, Debug, Default, Clone)]
719#[serde(rename_all = "camelCase")]
720pub struct V1Battery {
721    #[serde(flatten)]
722    pub identity: Option<V1ElectricalIdentity>,
723    #[serde(flatten)]
724    pub dc_qualities: Option<V1ElectricalDCQualities>,
725    pub chemistry: Option<String>,
726    pub temperature: Option<V1BatteryTemperature>,
727    pub capacity: Option<V1BatteryCapacity>,
728    pub lifetime_discharge: Option<V1NumberValue>,
729    pub lifetime_recharge: Option<V1NumberValue>,
730}
731
732impl V1Battery {
733    pub fn builder() -> V1BatteryBuilder {
734        V1BatteryBuilder::default()
735    }
736    pub fn update(&mut self, path: &mut Vec<&str>, value: &serde_json::value::Value) {
737        match path[0] {
738            // V1ElectricalIdentity
739            // name
740            // location
741            // dateInstalled
742            // manufacturer
743            // V1ElectricalDCQualities
744            // associated_bus
745            "voltage" => {
746                if self.dc_qualities.is_none() {
747                    self.dc_qualities = Some(V1ElectricalDCQualities::default());
748                }
749                if let Some(ref mut dc) = self.dc_qualities {
750                    let val = V1NumberValue::builder().json_value(value).build();
751                    dc.voltage = Some(V1ElectricalDCVoltageValue::builder().value(val).build());
752                }
753            }
754            "current" => {
755                if self.dc_qualities.is_none() {
756                    self.dc_qualities = Some(V1ElectricalDCQualities::default());
757                }
758                if let Some(ref mut dc) = self.dc_qualities {
759                    let val = V1NumberValue::builder().json_value(value).build();
760                    dc.current = Some(V1ElectricalDCCurrentValue::builder().value(val).build());
761                }
762            }
763            "temperature" => {
764                if self.temperature.is_none() {
765                    self.temperature = Some(V1BatteryTemperature::default());
766                }
767                if let Some(ref mut temperature) = self.temperature {
768                    let val = V1NumberValue::builder().json_value(value).build();
769                    temperature.value = Some(val);
770                }
771            }
772            "capacity" => {
773                if self.capacity.is_none() {
774                    self.capacity = Some(V1BatteryCapacity::default());
775                }
776                if let Some(ref mut capacity) = self.capacity {
777                    path.remove(0);
778                    capacity.update(path, value);
779                }
780            }
781            &_ => {
782                log::warn!(
783                    "V1Battery: {:?}--Unknown value to update: {:?}::{:?}",
784                    self,
785                    path,
786                    value
787                );
788            }
789        }
790    }
791
792    pub fn get_f64_for_path(&self, path: &mut Vec<&str>) -> Result<f64, SignalKGetError> {
793        log::info!("V1Batterypath: {:?}", path);
794        match path[0] {
795            "voltage" => {
796                if let Some(ref dc) = self.dc_qualities {
797                    if let Some(ref voltage) = dc.voltage {
798                        helper_functions::get_f64_value(&voltage.value)
799                    } else {
800                        Err(SignalKGetError::ValueNotSet)
801                    }
802                } else {
803                    Err(SignalKGetError::ValueNotSet)
804                }
805            }
806            &_ => Err(SignalKGetError::TBD),
807        }
808    }
809}
810
811#[derive(Default)]
812pub struct V1BatteryBuilder {
813    identity: Option<V1ElectricalIdentity>,
814    dc_qualities: Option<V1ElectricalDCQualities>,
815    chemistry: Option<String>,
816    temperature: Option<V1BatteryTemperature>,
817    capacity: Option<V1BatteryCapacity>,
818    lifetime_discharge: Option<V1NumberValue>,
819    lifetime_recharge: Option<V1NumberValue>,
820}
821
822impl V1BatteryBuilder {
823    pub fn identity(mut self, value: V1ElectricalIdentity) -> V1BatteryBuilder {
824        self.identity = Some(value);
825        self
826    }
827    pub fn dc_qualities(mut self, value: V1ElectricalDCQualities) -> V1BatteryBuilder {
828        self.dc_qualities = Some(value);
829        self
830    }
831    pub fn chemistry(mut self, value: String) -> V1BatteryBuilder {
832        self.chemistry = Some(value);
833        self
834    }
835    pub fn temperature(mut self, value: V1BatteryTemperature) -> V1BatteryBuilder {
836        self.temperature = Some(value);
837        self
838    }
839    pub fn capacity(mut self, value: V1BatteryCapacity) -> V1BatteryBuilder {
840        self.capacity = Some(value);
841        self
842    }
843    pub fn lifetime_discharge(mut self, value: f64) -> V1BatteryBuilder {
844        self.lifetime_discharge = Some(V1NumberValue::builder().value(value).build());
845        self
846    }
847    pub fn lifetime_recharge(mut self, value: f64) -> V1BatteryBuilder {
848        self.lifetime_recharge = Some(V1NumberValue::builder().value(value).build());
849        self
850    }
851    pub fn build(self) -> V1Battery {
852        V1Battery {
853            identity: self.identity,
854            dc_qualities: self.dc_qualities,
855            chemistry: self.chemistry,
856            temperature: self.temperature,
857            capacity: self.capacity,
858            lifetime_discharge: self.lifetime_discharge,
859            lifetime_recharge: self.lifetime_recharge,
860        }
861    }
862}
863
864#[derive(Serialize, Deserialize, PartialEq, Debug, Default, Clone)]
865pub struct V1ElectricalInverterMode {
866    #[serde(flatten)]
867    pub common: Option<V1CommonValueFields>,
868    pub value: Option<String>,
869}
870
871impl V1ElectricalInverterMode {
872    pub fn new(common: Option<V1CommonValueFields>, value: Option<String>) -> Self {
873        Self { common, value }
874    }
875}
876
877#[derive(Serialize, Deserialize, PartialEq, Debug, Default, Clone)]
878pub struct V1ElectricalChargerQualities {
879    #[serde(flatten)]
880    pub common: Option<V1CommonValueFields>,
881    pub value: Option<String>,
882}
883
884#[derive(Serialize, Deserialize, PartialEq, Debug, Default, Clone)]
885#[serde(rename_all = "camelCase")]
886pub struct V1Inverter {
887    #[serde(flatten)]
888    pub identity: Option<V1ElectricalIdentity>,
889    pub dc: Option<V1ElectricalDCQualities>,
890    pub ac: Option<V1ElectricalACQualities>,
891    pub inverter_mode: Option<V1ElectricalInverterMode>,
892}
893
894impl V1Inverter {
895    pub fn new(
896        identity: Option<V1ElectricalIdentity>,
897        dc: Option<V1ElectricalDCQualities>,
898        ac: Option<V1ElectricalACQualities>,
899        inverter_mode: Option<V1ElectricalInverterMode>,
900    ) -> Self {
901        Self {
902            identity,
903            dc,
904            ac,
905            inverter_mode,
906        }
907    }
908}
909
910#[derive(Serialize, Deserialize, PartialEq, Debug, Default, Clone)]
911pub struct V1Charger {
912    #[serde(flatten)]
913    pub identity: Option<V1ElectricalIdentity>,
914    #[serde(flatten)]
915    pub dc: Option<V1ElectricalDCQualities>,
916    #[serde(flatten)]
917    pub charger: Option<V1ElectricalChargerQualities>,
918}
919
920impl V1Charger {
921    pub fn new(
922        identity: Option<V1ElectricalIdentity>,
923        dc: Option<V1ElectricalDCQualities>,
924        charger: Option<V1ElectricalChargerQualities>,
925    ) -> Self {
926        Self {
927            identity,
928            dc,
929            charger,
930        }
931    }
932}
933
934#[derive(Serialize, Deserialize, PartialEq, Debug, Default, Clone)]
935#[serde(rename_all = "camelCase")]
936pub struct V1Alternator {
937    #[serde(flatten)]
938    pub identity: Option<V1ElectricalIdentity>,
939    #[serde(flatten)]
940    pub dc: Option<V1ElectricalDCQualities>,
941    #[serde(flatten)]
942    pub charger: Option<V1ElectricalChargerQualities>,
943    pub revolutions: Option<f64>,
944    pub pulley_ratio: Option<f64>,
945    pub field_drive: Option<f64>,
946    pub regulator_temperature: Option<f64>,
947}
948
949impl V1Alternator {
950    pub fn builder() -> V1AlternatorBuilder {
951        V1AlternatorBuilder::default()
952    }
953}
954
955#[derive(Default)]
956pub struct V1AlternatorBuilder {
957    identity: Option<V1ElectricalIdentity>,
958    dc: Option<V1ElectricalDCQualities>,
959    charger: Option<V1ElectricalChargerQualities>,
960    revolutions: Option<f64>,
961    pulley_ratio: Option<f64>,
962    field_drive: Option<f64>,
963    regulator_temperature: Option<f64>,
964}
965
966impl V1AlternatorBuilder {
967    pub fn identity(mut self, value: V1ElectricalIdentity) -> V1AlternatorBuilder {
968        self.identity = Some(value);
969        self
970    }
971    pub fn dc(mut self, value: V1ElectricalDCQualities) -> V1AlternatorBuilder {
972        self.dc = Some(value);
973        self
974    }
975    pub fn charger(mut self, value: V1ElectricalChargerQualities) -> V1AlternatorBuilder {
976        self.charger = Some(value);
977        self
978    }
979    pub fn revolutions(mut self, value: f64) -> V1AlternatorBuilder {
980        self.revolutions = Some(value);
981        self
982    }
983    pub fn pulley_ratio(mut self, value: f64) -> V1AlternatorBuilder {
984        self.pulley_ratio = Some(value);
985        self
986    }
987    pub fn field_drive(mut self, value: f64) -> V1AlternatorBuilder {
988        self.field_drive = Some(value);
989        self
990    }
991    pub fn regulator_temperature(mut self, value: f64) -> V1AlternatorBuilder {
992        self.regulator_temperature = Some(value);
993        self
994    }
995    pub fn build(self) -> V1Alternator {
996        V1Alternator {
997            identity: self.identity,
998            dc: self.dc,
999            charger: self.charger,
1000            revolutions: self.revolutions,
1001            pulley_ratio: self.pulley_ratio,
1002            field_drive: self.field_drive,
1003            regulator_temperature: self.regulator_temperature,
1004        }
1005    }
1006}
1007
1008#[derive(Serialize, Deserialize, PartialEq, Debug, Default, Clone)]
1009pub struct V1SolarLoad {
1010    #[serde(flatten)]
1011    pub common: Option<V1CommonValueFields>,
1012    pub value: Option<String>,
1013}
1014
1015impl V1SolarLoad {
1016    pub fn new(common: Option<V1CommonValueFields>, value: Option<String>) -> Self {
1017        Self { common, value }
1018    }
1019}
1020
1021#[derive(Serialize, Deserialize, PartialEq, Debug, Default, Clone)]
1022#[serde(rename_all = "camelCase")]
1023pub struct V1Solar {
1024    #[serde(flatten)]
1025    pub identity: Option<V1ElectricalIdentity>,
1026    #[serde(flatten)]
1027    pub dc: Option<V1ElectricalDCQualities>,
1028    #[serde(flatten)]
1029    pub charger: Option<V1ElectricalChargerQualities>,
1030    pub value: Option<String>,
1031    pub panel_voltage: Option<V1NumberValue>,
1032    pub panel_current: Option<V1NumberValue>,
1033    pub panel_temperature: Option<V1NumberValue>,
1034    pub load: Option<V1SolarLoad>,
1035    pub load_current: Option<V1NumberValue>,
1036}
1037
1038impl V1Solar {
1039    pub fn builder() -> V1SolarBuilder {
1040        V1SolarBuilder::default()
1041    }
1042}
1043
1044#[derive(Default)]
1045pub struct V1SolarBuilder {
1046    identity: Option<V1ElectricalIdentity>,
1047    dc: Option<V1ElectricalDCQualities>,
1048    charger: Option<V1ElectricalChargerQualities>,
1049    value: Option<String>,
1050    panel_voltage: Option<V1NumberValue>,
1051    panel_current: Option<V1NumberValue>,
1052    panel_temperature: Option<V1NumberValue>,
1053    load: Option<V1SolarLoad>,
1054    load_current: Option<V1NumberValue>,
1055}
1056
1057impl V1SolarBuilder {
1058    pub fn identity(mut self, value: V1ElectricalIdentity) -> V1SolarBuilder {
1059        self.identity = Some(value);
1060        self
1061    }
1062    pub fn dc(mut self, value: V1ElectricalDCQualities) -> V1SolarBuilder {
1063        self.dc = Some(value);
1064        self
1065    }
1066    pub fn charger(mut self, value: V1ElectricalChargerQualities) -> V1SolarBuilder {
1067        self.charger = Some(value);
1068        self
1069    }
1070    pub fn value(mut self, value: String) -> V1SolarBuilder {
1071        self.value = Some(value);
1072        self
1073    }
1074    pub fn panel_voltage(mut self, value: f64) -> V1SolarBuilder {
1075        self.panel_voltage = Some(V1NumberValue::builder().value(value).build());
1076        self
1077    }
1078    pub fn panel_current(mut self, value: f64) -> V1SolarBuilder {
1079        self.panel_current = Some(V1NumberValue::builder().value(value).build());
1080        self
1081    }
1082    pub fn panel_temperature(mut self, value: f64) -> V1SolarBuilder {
1083        self.panel_temperature = Some(V1NumberValue::builder().value(value).build());
1084        self
1085    }
1086    pub fn load(mut self, value: V1SolarLoad) -> V1SolarBuilder {
1087        self.load = Some(value);
1088        self
1089    }
1090    pub fn load_current(mut self, value: f64) -> V1SolarBuilder {
1091        self.load_current = Some(V1NumberValue::builder().value(value).build());
1092        self
1093    }
1094    pub fn build(self) -> V1Solar {
1095        V1Solar {
1096            identity: self.identity,
1097            dc: self.dc,
1098            charger: self.charger,
1099            value: self.value,
1100            panel_voltage: self.panel_voltage,
1101            panel_current: self.panel_current,
1102            panel_temperature: self.panel_temperature,
1103            load: self.load,
1104            load_current: self.load_current,
1105        }
1106    }
1107}
1108
1109#[derive(Serialize, Deserialize, PartialEq, Debug, Default, Clone)]
1110#[serde(rename_all = "camelCase")]
1111pub struct V1ACBus {
1112    #[serde(flatten)]
1113    pub identity: Option<V1ElectricalIdentity>,
1114    pub phase: HashMap<String, V1ElectricalACQualities>,
1115}
1116
1117impl V1ACBus {
1118    pub fn builder() -> V1ACBusBuilder {
1119        V1ACBusBuilder::default()
1120    }
1121}
1122
1123#[derive(Default)]
1124pub struct V1ACBusBuilder {
1125    identity: Option<V1ElectricalIdentity>,
1126    phase: HashMap<String, V1ElectricalACQualities>,
1127}
1128
1129impl V1ACBusBuilder {
1130    pub fn identity(mut self, value: V1ElectricalIdentity) -> V1ACBusBuilder {
1131        self.identity = Some(value);
1132        self
1133    }
1134    pub fn add_phase(mut self, key: String, value: V1ElectricalACQualities) -> V1ACBusBuilder {
1135        self.phase.insert(key, value);
1136        self
1137    }
1138    pub fn build(self) -> V1ACBus {
1139        V1ACBus {
1140            identity: self.identity,
1141            phase: self.phase,
1142        }
1143    }
1144}