Skip to main content

sunspec/models/
model102.rs

1//! Inverter (Split-Phase)
2/// Type alias for [`InverterSplitPhase`].
3pub type Model102 = InverterSplitPhase;
4/// Inverter (Split-Phase)
5///
6/// Include this model for split phase inverter monitoring
7#[derive(Debug)]
8#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
9pub struct InverterSplitPhase {
10    /// Amps
11    ///
12    /// AC Current
13    ///
14    /// Detail: Sum of active phases
15    pub a: u16,
16    /// Amps PhaseA
17    ///
18    /// Phase A Current
19    ///
20    /// Detail: Connected Phase
21    pub aph_a: u16,
22    /// Amps PhaseB
23    ///
24    /// Phase B Current
25    ///
26    /// Detail: Connected Phase
27    pub aph_b: u16,
28    /// Amps PhaseC
29    ///
30    /// Phase C Current
31    pub aph_c: Option<u16>,
32    #[allow(missing_docs)]
33    pub a_sf: i16,
34    /// Phase Voltage AB
35    ///
36    /// Phase Voltage AB
37    pub pp_vph_ab: Option<u16>,
38    /// Phase Voltage BC
39    ///
40    /// Phase Voltage BC
41    pub pp_vph_bc: Option<u16>,
42    /// Phase Voltage CA
43    ///
44    /// Phase Voltage CA
45    pub pp_vph_ca: Option<u16>,
46    /// Phase Voltage AN
47    ///
48    /// Phase Voltage AN
49    pub ph_vph_a: u16,
50    /// Phase Voltage BN
51    ///
52    /// Phase Voltage BN
53    pub ph_vph_b: u16,
54    /// Phase Voltage CN
55    ///
56    /// Phase Voltage CN
57    pub ph_vph_c: Option<u16>,
58    #[allow(missing_docs)]
59    pub v_sf: i16,
60    /// Watts
61    ///
62    /// AC Power
63    pub w: i16,
64    #[allow(missing_docs)]
65    pub w_sf: i16,
66    /// Hz
67    ///
68    /// Line Frequency
69    pub hz: u16,
70    #[allow(missing_docs)]
71    pub hz_sf: i16,
72    /// VA
73    ///
74    /// AC Apparent Power
75    pub va: Option<i16>,
76    #[allow(missing_docs)]
77    pub va_sf: Option<i16>,
78    /// VAr
79    ///
80    /// AC Reactive Power
81    pub v_ar: Option<i16>,
82    #[allow(missing_docs)]
83    pub v_ar_sf: Option<i16>,
84    /// PF
85    ///
86    /// AC Power Factor
87    pub pf: Option<i16>,
88    #[allow(missing_docs)]
89    pub pf_sf: Option<i16>,
90    /// WattHours
91    ///
92    /// AC Energy
93    pub wh: u32,
94    #[allow(missing_docs)]
95    pub wh_sf: i16,
96    /// DC Amps
97    ///
98    /// DC Current
99    pub dca: Option<u16>,
100    #[allow(missing_docs)]
101    pub dca_sf: Option<i16>,
102    /// DC Voltage
103    ///
104    /// DC Voltage
105    pub dcv: Option<u16>,
106    #[allow(missing_docs)]
107    pub dcv_sf: Option<i16>,
108    /// DC Watts
109    ///
110    /// DC Power
111    pub dcw: Option<i16>,
112    #[allow(missing_docs)]
113    pub dcw_sf: Option<i16>,
114    /// Cabinet Temperature
115    ///
116    /// Cabinet Temperature
117    pub tmp_cab: i16,
118    /// Heat Sink Temperature
119    ///
120    /// Heat Sink Temperature
121    pub tmp_snk: Option<i16>,
122    /// Transformer Temperature
123    ///
124    /// Transformer Temperature
125    pub tmp_trns: Option<i16>,
126    /// Other Temperature
127    ///
128    /// Other Temperature
129    pub tmp_ot: Option<i16>,
130    #[allow(missing_docs)]
131    pub tmp_sf: i16,
132    /// Operating State
133    ///
134    /// Enumerated value.  Operating state
135    pub st: St,
136    /// Vendor Operating State
137    ///
138    /// Vendor specific operating state code
139    pub st_vnd: Option<u16>,
140    /// Event1
141    ///
142    /// Bitmask value. Event fields
143    pub evt1: Evt1,
144    /// Event Bitfield 2
145    ///
146    /// Reserved for future use
147    pub evt2: Evt2,
148    /// Vendor Event Bitfield 1
149    ///
150    /// Vendor defined events
151    pub evt_vnd1: Option<EvtVnd1>,
152    /// Vendor Event Bitfield 2
153    ///
154    /// Vendor defined events
155    pub evt_vnd2: Option<EvtVnd2>,
156    /// Vendor Event Bitfield 3
157    ///
158    /// Vendor defined events
159    pub evt_vnd3: Option<EvtVnd3>,
160    /// Vendor Event Bitfield 4
161    ///
162    /// Vendor defined events
163    pub evt_vnd4: Option<EvtVnd4>,
164}
165#[allow(missing_docs)]
166impl InverterSplitPhase {
167    pub const A: crate::Point<Self, u16> = crate::Point::new(0, 1, false);
168    pub const APH_A: crate::Point<Self, u16> = crate::Point::new(1, 1, false);
169    pub const APH_B: crate::Point<Self, u16> = crate::Point::new(2, 1, false);
170    pub const APH_C: crate::Point<Self, Option<u16>> = crate::Point::new(3, 1, false);
171    pub const A_SF: crate::Point<Self, i16> = crate::Point::new(4, 1, false);
172    pub const PP_VPH_AB: crate::Point<Self, Option<u16>> = crate::Point::new(5, 1, false);
173    pub const PP_VPH_BC: crate::Point<Self, Option<u16>> = crate::Point::new(6, 1, false);
174    pub const PP_VPH_CA: crate::Point<Self, Option<u16>> = crate::Point::new(7, 1, false);
175    pub const PH_VPH_A: crate::Point<Self, u16> = crate::Point::new(8, 1, false);
176    pub const PH_VPH_B: crate::Point<Self, u16> = crate::Point::new(9, 1, false);
177    pub const PH_VPH_C: crate::Point<Self, Option<u16>> = crate::Point::new(10, 1, false);
178    pub const V_SF: crate::Point<Self, i16> = crate::Point::new(11, 1, false);
179    pub const W: crate::Point<Self, i16> = crate::Point::new(12, 1, false);
180    pub const W_SF: crate::Point<Self, i16> = crate::Point::new(13, 1, false);
181    pub const HZ: crate::Point<Self, u16> = crate::Point::new(14, 1, false);
182    pub const HZ_SF: crate::Point<Self, i16> = crate::Point::new(15, 1, false);
183    pub const VA: crate::Point<Self, Option<i16>> = crate::Point::new(16, 1, false);
184    pub const VA_SF: crate::Point<Self, Option<i16>> = crate::Point::new(17, 1, false);
185    pub const V_AR: crate::Point<Self, Option<i16>> = crate::Point::new(18, 1, false);
186    pub const V_AR_SF: crate::Point<Self, Option<i16>> = crate::Point::new(19, 1, false);
187    pub const PF: crate::Point<Self, Option<i16>> = crate::Point::new(20, 1, false);
188    pub const PF_SF: crate::Point<Self, Option<i16>> = crate::Point::new(21, 1, false);
189    pub const WH: crate::Point<Self, u32> = crate::Point::new(22, 2, false);
190    pub const WH_SF: crate::Point<Self, i16> = crate::Point::new(24, 1, false);
191    pub const DCA: crate::Point<Self, Option<u16>> = crate::Point::new(25, 1, false);
192    pub const DCA_SF: crate::Point<Self, Option<i16>> = crate::Point::new(26, 1, false);
193    pub const DCV: crate::Point<Self, Option<u16>> = crate::Point::new(27, 1, false);
194    pub const DCV_SF: crate::Point<Self, Option<i16>> = crate::Point::new(28, 1, false);
195    pub const DCW: crate::Point<Self, Option<i16>> = crate::Point::new(29, 1, false);
196    pub const DCW_SF: crate::Point<Self, Option<i16>> = crate::Point::new(30, 1, false);
197    pub const TMP_CAB: crate::Point<Self, i16> = crate::Point::new(31, 1, false);
198    pub const TMP_SNK: crate::Point<Self, Option<i16>> = crate::Point::new(32, 1, false);
199    pub const TMP_TRNS: crate::Point<Self, Option<i16>> = crate::Point::new(33, 1, false);
200    pub const TMP_OT: crate::Point<Self, Option<i16>> = crate::Point::new(34, 1, false);
201    pub const TMP_SF: crate::Point<Self, i16> = crate::Point::new(35, 1, false);
202    pub const ST: crate::Point<Self, St> = crate::Point::new(36, 1, false);
203    pub const ST_VND: crate::Point<Self, Option<u16>> = crate::Point::new(37, 1, false);
204    pub const EVT1: crate::Point<Self, Evt1> = crate::Point::new(38, 2, false);
205    pub const EVT2: crate::Point<Self, Evt2> = crate::Point::new(40, 2, false);
206    pub const EVT_VND1: crate::Point<Self, Option<EvtVnd1>> = crate::Point::new(42, 2, false);
207    pub const EVT_VND2: crate::Point<Self, Option<EvtVnd2>> = crate::Point::new(44, 2, false);
208    pub const EVT_VND3: crate::Point<Self, Option<EvtVnd3>> = crate::Point::new(46, 2, false);
209    pub const EVT_VND4: crate::Point<Self, Option<EvtVnd4>> = crate::Point::new(48, 2, false);
210}
211impl crate::Group for InverterSplitPhase {
212    const LEN: u16 = 50;
213}
214impl InverterSplitPhase {
215    fn parse_group(data: &[u16]) -> Result<(&[u16], Self), crate::DecodeError> {
216        let nested_data = data
217            .get(usize::from(<Self as crate::Group>::LEN)..)
218            .unwrap_or(&[]);
219        Ok((
220            nested_data,
221            Self {
222                a: Self::A.from_data(data)?,
223                aph_a: Self::APH_A.from_data(data)?,
224                aph_b: Self::APH_B.from_data(data)?,
225                aph_c: Self::APH_C.from_data(data)?,
226                a_sf: Self::A_SF.from_data(data)?,
227                pp_vph_ab: Self::PP_VPH_AB.from_data(data)?,
228                pp_vph_bc: Self::PP_VPH_BC.from_data(data)?,
229                pp_vph_ca: Self::PP_VPH_CA.from_data(data)?,
230                ph_vph_a: Self::PH_VPH_A.from_data(data)?,
231                ph_vph_b: Self::PH_VPH_B.from_data(data)?,
232                ph_vph_c: Self::PH_VPH_C.from_data(data)?,
233                v_sf: Self::V_SF.from_data(data)?,
234                w: Self::W.from_data(data)?,
235                w_sf: Self::W_SF.from_data(data)?,
236                hz: Self::HZ.from_data(data)?,
237                hz_sf: Self::HZ_SF.from_data(data)?,
238                va: Self::VA.from_data(data)?,
239                va_sf: Self::VA_SF.from_data(data)?,
240                v_ar: Self::V_AR.from_data(data)?,
241                v_ar_sf: Self::V_AR_SF.from_data(data)?,
242                pf: Self::PF.from_data(data)?,
243                pf_sf: Self::PF_SF.from_data(data)?,
244                wh: Self::WH.from_data(data)?,
245                wh_sf: Self::WH_SF.from_data(data)?,
246                dca: Self::DCA.from_data(data)?,
247                dca_sf: Self::DCA_SF.from_data(data)?,
248                dcv: Self::DCV.from_data(data)?,
249                dcv_sf: Self::DCV_SF.from_data(data)?,
250                dcw: Self::DCW.from_data(data)?,
251                dcw_sf: Self::DCW_SF.from_data(data)?,
252                tmp_cab: Self::TMP_CAB.from_data(data)?,
253                tmp_snk: Self::TMP_SNK.from_data(data)?,
254                tmp_trns: Self::TMP_TRNS.from_data(data)?,
255                tmp_ot: Self::TMP_OT.from_data(data)?,
256                tmp_sf: Self::TMP_SF.from_data(data)?,
257                st: Self::ST.from_data(data)?,
258                st_vnd: Self::ST_VND.from_data(data)?,
259                evt1: Self::EVT1.from_data(data)?,
260                evt2: Self::EVT2.from_data(data)?,
261                evt_vnd1: Self::EVT_VND1.from_data(data)?,
262                evt_vnd2: Self::EVT_VND2.from_data(data)?,
263                evt_vnd3: Self::EVT_VND3.from_data(data)?,
264                evt_vnd4: Self::EVT_VND4.from_data(data)?,
265            },
266        ))
267    }
268}
269/// Operating State
270///
271/// Enumerated value.  Operating state
272#[derive(Copy, Clone, Debug, Eq, PartialEq)]
273#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
274pub enum St {
275    #[allow(missing_docs)]
276    Off,
277    #[allow(missing_docs)]
278    Sleeping,
279    #[allow(missing_docs)]
280    Starting,
281    #[allow(missing_docs)]
282    Mppt,
283    #[allow(missing_docs)]
284    Throttled,
285    #[allow(missing_docs)]
286    ShuttingDown,
287    #[allow(missing_docs)]
288    Fault,
289    #[allow(missing_docs)]
290    Standby,
291    /// Raw enum value not defined by the SunSpec model.
292    Invalid(u16),
293}
294impl crate::EnumValue for St {
295    type Repr = u16;
296    const INVALID: Self::Repr = 65535;
297    fn from_repr(value: Self::Repr) -> Self {
298        match value {
299            1 => Self::Off,
300            2 => Self::Sleeping,
301            3 => Self::Starting,
302            4 => Self::Mppt,
303            5 => Self::Throttled,
304            6 => Self::ShuttingDown,
305            7 => Self::Fault,
306            8 => Self::Standby,
307            value => Self::Invalid(value),
308        }
309    }
310    fn to_repr(self) -> Self::Repr {
311        match self {
312            Self::Off => 1,
313            Self::Sleeping => 2,
314            Self::Starting => 3,
315            Self::Mppt => 4,
316            Self::Throttled => 5,
317            Self::ShuttingDown => 6,
318            Self::Fault => 7,
319            Self::Standby => 8,
320            Self::Invalid(value) => value,
321        }
322    }
323}
324impl crate::FixedSize for St {
325    const SIZE: u16 = 1u16;
326    const INVALID: Self = Self::Invalid(65535);
327    fn is_invalid(&self) -> bool {
328        matches!(self, Self::Invalid(_))
329    }
330}
331bitflags::bitflags! {
332    #[doc = " Event1"] #[doc = " "] #[doc = " Bitmask value. Event fields"]
333    #[derive(Copy, Clone, Debug, Eq, PartialEq)] #[cfg_attr(feature = "serde",
334    derive(::serde::Serialize, ::serde::Deserialize))] pub struct Evt1 : u32 {
335    #[allow(missing_docs)] const GroundFault = 1; #[allow(missing_docs)] const DcOverVolt
336    = 2; #[allow(missing_docs)] const AcDisconnect = 4; #[allow(missing_docs)] const
337    DcDisconnect = 8; #[allow(missing_docs)] const GridDisconnect = 16;
338    #[allow(missing_docs)] const CabinetOpen = 32; #[allow(missing_docs)] const
339    ManualShutdown = 64; #[allow(missing_docs)] const OverTemp = 128;
340    #[allow(missing_docs)] const OverFrequency = 256; #[allow(missing_docs)] const
341    UnderFrequency = 512; #[allow(missing_docs)] const AcOverVolt = 1024;
342    #[allow(missing_docs)] const AcUnderVolt = 2048; #[allow(missing_docs)] const
343    BlownStringFuse = 4096; #[allow(missing_docs)] const UnderTemp = 8192;
344    #[allow(missing_docs)] const MemoryLoss = 16384; #[allow(missing_docs)] const
345    HwTestFailure = 32768; }
346}
347impl crate::Value for Evt1 {
348    fn decode(data: &[u16]) -> Result<Self, crate::DecodeError> {
349        let value = u32::decode(data)?;
350        Ok(Self::from_bits_retain(value))
351    }
352    fn encode(self) -> Box<[u16]> {
353        self.bits().encode()
354    }
355}
356impl crate::FixedSize for Evt1 {
357    const SIZE: u16 = 2u16;
358    const INVALID: Self = Self::from_bits_retain(4294967295u32);
359    fn is_invalid(&self) -> bool {
360        self.bits() == 4294967295u32
361    }
362}
363bitflags::bitflags! {
364    #[doc = " Event Bitfield 2"] #[doc = " "] #[doc = " Reserved for future use"]
365    #[derive(Copy, Clone, Debug, Eq, PartialEq)] #[cfg_attr(feature = "serde",
366    derive(::serde::Serialize, ::serde::Deserialize))] pub struct Evt2 : u32 {}
367}
368impl crate::Value for Evt2 {
369    fn decode(data: &[u16]) -> Result<Self, crate::DecodeError> {
370        let value = u32::decode(data)?;
371        Ok(Self::from_bits_retain(value))
372    }
373    fn encode(self) -> Box<[u16]> {
374        self.bits().encode()
375    }
376}
377impl crate::FixedSize for Evt2 {
378    const SIZE: u16 = 2u16;
379    const INVALID: Self = Self::from_bits_retain(4294967295u32);
380    fn is_invalid(&self) -> bool {
381        self.bits() == 4294967295u32
382    }
383}
384bitflags::bitflags! {
385    #[doc = " Vendor Event Bitfield 1"] #[doc = " "] #[doc = " Vendor defined events"]
386    #[derive(Copy, Clone, Debug, Eq, PartialEq)] #[cfg_attr(feature = "serde",
387    derive(::serde::Serialize, ::serde::Deserialize))] pub struct EvtVnd1 : u32 {}
388}
389impl crate::Value for EvtVnd1 {
390    fn decode(data: &[u16]) -> Result<Self, crate::DecodeError> {
391        let value = u32::decode(data)?;
392        Ok(Self::from_bits_retain(value))
393    }
394    fn encode(self) -> Box<[u16]> {
395        self.bits().encode()
396    }
397}
398impl crate::FixedSize for EvtVnd1 {
399    const SIZE: u16 = 2u16;
400    const INVALID: Self = Self::from_bits_retain(4294967295u32);
401    fn is_invalid(&self) -> bool {
402        self.bits() == 4294967295u32
403    }
404}
405bitflags::bitflags! {
406    #[doc = " Vendor Event Bitfield 2"] #[doc = " "] #[doc = " Vendor defined events"]
407    #[derive(Copy, Clone, Debug, Eq, PartialEq)] #[cfg_attr(feature = "serde",
408    derive(::serde::Serialize, ::serde::Deserialize))] pub struct EvtVnd2 : u32 {}
409}
410impl crate::Value for EvtVnd2 {
411    fn decode(data: &[u16]) -> Result<Self, crate::DecodeError> {
412        let value = u32::decode(data)?;
413        Ok(Self::from_bits_retain(value))
414    }
415    fn encode(self) -> Box<[u16]> {
416        self.bits().encode()
417    }
418}
419impl crate::FixedSize for EvtVnd2 {
420    const SIZE: u16 = 2u16;
421    const INVALID: Self = Self::from_bits_retain(4294967295u32);
422    fn is_invalid(&self) -> bool {
423        self.bits() == 4294967295u32
424    }
425}
426bitflags::bitflags! {
427    #[doc = " Vendor Event Bitfield 3"] #[doc = " "] #[doc = " Vendor defined events"]
428    #[derive(Copy, Clone, Debug, Eq, PartialEq)] #[cfg_attr(feature = "serde",
429    derive(::serde::Serialize, ::serde::Deserialize))] pub struct EvtVnd3 : u32 {}
430}
431impl crate::Value for EvtVnd3 {
432    fn decode(data: &[u16]) -> Result<Self, crate::DecodeError> {
433        let value = u32::decode(data)?;
434        Ok(Self::from_bits_retain(value))
435    }
436    fn encode(self) -> Box<[u16]> {
437        self.bits().encode()
438    }
439}
440impl crate::FixedSize for EvtVnd3 {
441    const SIZE: u16 = 2u16;
442    const INVALID: Self = Self::from_bits_retain(4294967295u32);
443    fn is_invalid(&self) -> bool {
444        self.bits() == 4294967295u32
445    }
446}
447bitflags::bitflags! {
448    #[doc = " Vendor Event Bitfield 4"] #[doc = " "] #[doc = " Vendor defined events"]
449    #[derive(Copy, Clone, Debug, Eq, PartialEq)] #[cfg_attr(feature = "serde",
450    derive(::serde::Serialize, ::serde::Deserialize))] pub struct EvtVnd4 : u32 {}
451}
452impl crate::Value for EvtVnd4 {
453    fn decode(data: &[u16]) -> Result<Self, crate::DecodeError> {
454        let value = u32::decode(data)?;
455        Ok(Self::from_bits_retain(value))
456    }
457    fn encode(self) -> Box<[u16]> {
458        self.bits().encode()
459    }
460}
461impl crate::FixedSize for EvtVnd4 {
462    const SIZE: u16 = 2u16;
463    const INVALID: Self = Self::from_bits_retain(4294967295u32);
464    fn is_invalid(&self) -> bool {
465        self.bits() == 4294967295u32
466    }
467}
468impl crate::Model for InverterSplitPhase {
469    const ID: u16 = 102;
470    fn addr(models: &crate::Models) -> crate::ModelAddr<Self> {
471        models.m102
472    }
473    fn parse(data: &[u16]) -> Result<Self, crate::ParseError<Self>> {
474        let (_, model) = Self::parse_group(data)?;
475        Ok(model)
476    }
477}