Skip to main content

sunspec/models/
model160.rs

1//! Multiple MPPT Inverter Extension Model
2/// Type alias for [`Mppt`].
3pub type Model160 = Mppt;
4/// Multiple MPPT Inverter Extension Model
5#[derive(Debug)]
6#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
7pub struct Mppt {
8    /// Current Scale Factor
9    pub dca_sf: Option<i16>,
10    /// Voltage Scale Factor
11    pub dcv_sf: Option<i16>,
12    /// Power Scale Factor
13    pub dcw_sf: Option<i16>,
14    /// Energy Scale Factor
15    pub dcwh_sf: Option<i16>,
16    /// Global Events
17    pub evt: Option<Evt>,
18    /// Number of Modules
19    pub n: Option<u16>,
20    /// Timestamp Period
21    pub tms_per: Option<u16>,
22    #[allow(missing_docs)]
23    pub module: Vec<Module>,
24}
25#[allow(missing_docs)]
26impl Mppt {
27    pub const DCA_SF: crate::Point<Self, Option<i16>> = crate::Point::new(0, 1, false);
28    pub const DCV_SF: crate::Point<Self, Option<i16>> = crate::Point::new(1, 1, false);
29    pub const DCW_SF: crate::Point<Self, Option<i16>> = crate::Point::new(2, 1, false);
30    pub const DCWH_SF: crate::Point<Self, Option<i16>> = crate::Point::new(3, 1, false);
31    pub const EVT: crate::Point<Self, Option<Evt>> = crate::Point::new(4, 2, false);
32    pub const N: crate::Point<Self, Option<u16>> = crate::Point::new(6, 1, false);
33    pub const TMS_PER: crate::Point<Self, Option<u16>> = crate::Point::new(7, 1, false);
34}
35impl crate::Group for Mppt {
36    const LEN: u16 = 8;
37}
38impl Mppt {
39    fn parse_group(data: &[u16]) -> Result<(&[u16], Self), crate::DecodeError> {
40        let nested_data = data
41            .get(usize::from(<Self as crate::Group>::LEN)..)
42            .unwrap_or(&[]);
43        let (nested_data, module) = Module::parse_multiple(nested_data)?;
44        Ok((
45            nested_data,
46            Self {
47                dca_sf: Self::DCA_SF.from_data(data)?,
48                dcv_sf: Self::DCV_SF.from_data(data)?,
49                dcw_sf: Self::DCW_SF.from_data(data)?,
50                dcwh_sf: Self::DCWH_SF.from_data(data)?,
51                evt: Self::EVT.from_data(data)?,
52                n: Self::N.from_data(data)?,
53                tms_per: Self::TMS_PER.from_data(data)?,
54                module,
55            },
56        ))
57    }
58}
59bitflags::bitflags! {
60    #[doc = " Global Events"] #[derive(Copy, Clone, Debug, Eq, PartialEq)]
61    #[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))] pub
62    struct Evt : u32 { #[allow(missing_docs)] const GroundFault = 1;
63    #[allow(missing_docs)] const InputOverVoltage = 2; #[allow(missing_docs)] const
64    Reserved2 = 4; #[allow(missing_docs)] const DcDisconnect = 8; #[allow(missing_docs)]
65    const Reserved4 = 16; #[allow(missing_docs)] const CabinetOpen = 32;
66    #[allow(missing_docs)] const ManualShutdown = 64; #[allow(missing_docs)] const
67    OverTemp = 128; #[allow(missing_docs)] const Reserved8 = 256; #[allow(missing_docs)]
68    const Reserved9 = 512; #[allow(missing_docs)] const Reserved10 = 1024;
69    #[allow(missing_docs)] const Reserved11 = 2048; #[allow(missing_docs)] const
70    BlownFuse = 4096; #[allow(missing_docs)] const UnderTemp = 8192;
71    #[allow(missing_docs)] const MemoryLoss = 16384; #[allow(missing_docs)] const
72    ArcDetection = 32768; #[allow(missing_docs)] const Reserved16 = 65536;
73    #[allow(missing_docs)] const Reserved17 = 131072; #[allow(missing_docs)] const
74    Reserved18 = 262144; #[allow(missing_docs)] const Reserved19 = 524288;
75    #[allow(missing_docs)] const TestFailed = 1048576; #[allow(missing_docs)] const
76    InputUnderVoltage = 2097152; #[allow(missing_docs)] const InputOverCurrent = 4194304;
77    }
78}
79impl crate::Value for Evt {
80    fn decode(data: &[u16]) -> Result<Self, crate::DecodeError> {
81        let value = u32::decode(data)?;
82        Ok(Self::from_bits_retain(value))
83    }
84    fn encode(self) -> Box<[u16]> {
85        self.bits().encode()
86    }
87}
88impl crate::FixedSize for Evt {
89    const SIZE: u16 = 2u16;
90    const INVALID: Self = Self::from_bits_retain(4294967295u32);
91    fn is_invalid(&self) -> bool {
92        self.bits() == 4294967295u32
93    }
94}
95#[allow(missing_docs)]
96#[derive(Debug)]
97#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
98pub struct Module {
99    /// Input ID
100    pub id: Option<u16>,
101    /// Input ID String
102    pub id_str: Option<String>,
103    /// DC Current
104    pub dca: Option<u16>,
105    /// DC Voltage
106    pub dcv: Option<u16>,
107    /// DC Power
108    pub dcw: Option<u16>,
109    /// Lifetime Energy
110    pub dcwh: Option<u32>,
111    /// Timestamp
112    pub tms: Option<u32>,
113    /// Temperature
114    pub tmp: Option<i16>,
115    /// Operating State
116    pub dc_st: Option<ModuleDcSt>,
117    /// Module Events
118    pub dc_evt: Option<ModuleDcEvt>,
119}
120#[allow(missing_docs)]
121impl Module {
122    pub const ID: crate::Point<Self, Option<u16>> = crate::Point::new(0, 1, false);
123    pub const ID_STR: crate::Point<Self, Option<String>> = crate::Point::new(1, 8, false);
124    pub const DCA: crate::Point<Self, Option<u16>> = crate::Point::new(9, 1, false);
125    pub const DCV: crate::Point<Self, Option<u16>> = crate::Point::new(10, 1, false);
126    pub const DCW: crate::Point<Self, Option<u16>> = crate::Point::new(11, 1, false);
127    pub const DCWH: crate::Point<Self, Option<u32>> = crate::Point::new(12, 2, false);
128    pub const TMS: crate::Point<Self, Option<u32>> = crate::Point::new(14, 2, false);
129    pub const TMP: crate::Point<Self, Option<i16>> = crate::Point::new(16, 1, false);
130    pub const DC_ST: crate::Point<Self, Option<ModuleDcSt>> = crate::Point::new(17, 1, false);
131    pub const DC_EVT: crate::Point<Self, Option<ModuleDcEvt>> = crate::Point::new(18, 2, false);
132}
133impl crate::Group for Module {
134    const LEN: u16 = 20;
135}
136impl Module {
137    fn parse_group(data: &[u16]) -> Result<(&[u16], Self), crate::DecodeError> {
138        let nested_data = data
139            .get(usize::from(<Self as crate::Group>::LEN)..)
140            .unwrap_or(&[]);
141        Ok((
142            nested_data,
143            Self {
144                id: Self::ID.from_data(data)?,
145                id_str: Self::ID_STR.from_data(data)?,
146                dca: Self::DCA.from_data(data)?,
147                dcv: Self::DCV.from_data(data)?,
148                dcw: Self::DCW.from_data(data)?,
149                dcwh: Self::DCWH.from_data(data)?,
150                tms: Self::TMS.from_data(data)?,
151                tmp: Self::TMP.from_data(data)?,
152                dc_st: Self::DC_ST.from_data(data)?,
153                dc_evt: Self::DC_EVT.from_data(data)?,
154            },
155        ))
156    }
157    fn parse_multiple(data: &[u16]) -> Result<(&[u16], Vec<Self>), crate::DecodeError> {
158        let group_len = usize::from(<Module as crate::Group>::LEN);
159        if group_len == 0 {
160            return Ok((data, Vec::new()));
161        }
162        if data.len() % group_len != 0 {
163            return Err(crate::DecodeError::OutOfBounds);
164        }
165        let group_count = data.len() / group_len;
166        let (data, groups) =
167            (0..group_count).try_fold((data, Vec::new()), |(data, mut groups), _| {
168                let (data, group) = Module::parse_group(data)?;
169                groups.push(group);
170                Ok::<_, crate::DecodeError>((data, groups))
171            })?;
172        Ok((data, groups))
173    }
174}
175/// Operating State
176#[derive(Copy, Clone, Debug, Eq, PartialEq)]
177#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
178pub enum ModuleDcSt {
179    #[allow(missing_docs)]
180    Off,
181    #[allow(missing_docs)]
182    Sleeping,
183    #[allow(missing_docs)]
184    Starting,
185    #[allow(missing_docs)]
186    Mppt,
187    #[allow(missing_docs)]
188    Throttled,
189    #[allow(missing_docs)]
190    ShuttingDown,
191    #[allow(missing_docs)]
192    Fault,
193    #[allow(missing_docs)]
194    Standby,
195    #[allow(missing_docs)]
196    Test,
197    #[allow(missing_docs)]
198    Reserved10,
199    /// Raw enum value not defined by the SunSpec model.
200    Invalid(u16),
201}
202impl crate::EnumValue for ModuleDcSt {
203    type Repr = u16;
204    const INVALID: Self::Repr = 65535;
205    fn from_repr(value: Self::Repr) -> Self {
206        match value {
207            1 => Self::Off,
208            2 => Self::Sleeping,
209            3 => Self::Starting,
210            4 => Self::Mppt,
211            5 => Self::Throttled,
212            6 => Self::ShuttingDown,
213            7 => Self::Fault,
214            8 => Self::Standby,
215            9 => Self::Test,
216            10 => Self::Reserved10,
217            value => Self::Invalid(value),
218        }
219    }
220    fn to_repr(self) -> Self::Repr {
221        match self {
222            Self::Off => 1,
223            Self::Sleeping => 2,
224            Self::Starting => 3,
225            Self::Mppt => 4,
226            Self::Throttled => 5,
227            Self::ShuttingDown => 6,
228            Self::Fault => 7,
229            Self::Standby => 8,
230            Self::Test => 9,
231            Self::Reserved10 => 10,
232            Self::Invalid(value) => value,
233        }
234    }
235}
236impl crate::FixedSize for ModuleDcSt {
237    const SIZE: u16 = 1u16;
238    const INVALID: Self = Self::Invalid(65535);
239    fn is_invalid(&self) -> bool {
240        matches!(self, Self::Invalid(_))
241    }
242}
243bitflags::bitflags! {
244    #[doc = " Module Events"] #[derive(Copy, Clone, Debug, Eq, PartialEq)]
245    #[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))] pub
246    struct ModuleDcEvt : u32 { #[allow(missing_docs)] const GroundFault = 1;
247    #[allow(missing_docs)] const InputOverVoltage = 2; #[allow(missing_docs)] const
248    Reserved2 = 4; #[allow(missing_docs)] const DcDisconnect = 8; #[allow(missing_docs)]
249    const Reserved4 = 16; #[allow(missing_docs)] const CabinetOpen = 32;
250    #[allow(missing_docs)] const ManualShutdown = 64; #[allow(missing_docs)] const
251    OverTemp = 128; #[allow(missing_docs)] const Reserved8 = 256; #[allow(missing_docs)]
252    const Reserved9 = 512; #[allow(missing_docs)] const Reserved10 = 1024;
253    #[allow(missing_docs)] const Reserved11 = 2048; #[allow(missing_docs)] const
254    BlownFuse = 4096; #[allow(missing_docs)] const UnderTemp = 8192;
255    #[allow(missing_docs)] const MemoryLoss = 16384; #[allow(missing_docs)] const
256    ArcDetection = 32768; #[allow(missing_docs)] const Reserved16 = 65536;
257    #[allow(missing_docs)] const Reserved17 = 131072; #[allow(missing_docs)] const
258    Reserved18 = 262144; #[allow(missing_docs)] const Reserved19 = 524288;
259    #[allow(missing_docs)] const TestFailed = 1048576; #[allow(missing_docs)] const
260    InputUnderVoltage = 2097152; #[allow(missing_docs)] const InputOverCurrent = 4194304;
261    }
262}
263impl crate::Value for ModuleDcEvt {
264    fn decode(data: &[u16]) -> Result<Self, crate::DecodeError> {
265        let value = u32::decode(data)?;
266        Ok(Self::from_bits_retain(value))
267    }
268    fn encode(self) -> Box<[u16]> {
269        self.bits().encode()
270    }
271}
272impl crate::FixedSize for ModuleDcEvt {
273    const SIZE: u16 = 2u16;
274    const INVALID: Self = Self::from_bits_retain(4294967295u32);
275    fn is_invalid(&self) -> bool {
276        self.bits() == 4294967295u32
277    }
278}
279impl crate::Model for Mppt {
280    const ID: u16 = 160;
281    fn addr(models: &crate::Models) -> crate::ModelAddr<Self> {
282        models.m160
283    }
284    fn parse(data: &[u16]) -> Result<Self, crate::ParseError<Self>> {
285        let (_, model) = Self::parse_group(data)?;
286        Ok(model)
287    }
288}