Skip to main content

sunspec/models/
model141.rs

1//! LFRTC
2/// Type alias for [`Lfrtc`].
3pub type Model141 = Lfrtc;
4/// LFRTC
5///
6/// LFRT must remain connected
7///
8/// Detail: Ref 4: 11
9#[derive(Debug)]
10#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
11pub struct Lfrtc {
12    /// ActCrv
13    ///
14    /// Index of active curve. 0=no active curve.
15    pub act_crv: u16,
16    /// ModEna
17    ///
18    /// LHzRT control mode. Enable active curve.  Bitfield value.
19    pub mod_ena: ModEna,
20    /// WinTms
21    ///
22    /// Time window for LFRT change.
23    ///
24    /// Detail: Setting is ignored for LFRT controls.
25    pub win_tms: Option<u16>,
26    /// RvrtTms
27    ///
28    /// Timeout period for LFRT curve selection.
29    ///
30    /// Detail: Setting is ignored for LFRT controls.
31    pub rvrt_tms: Option<u16>,
32    /// RmpTms
33    ///
34    /// Ramp time for moving from current mode to new mode.
35    ///
36    /// Detail: Setting is ignored for LFRT controls.
37    pub rmp_tms: Option<u16>,
38    /// NCrv
39    ///
40    /// Number of curves supported (recommend 4).
41    pub n_crv: u16,
42    /// NPt
43    ///
44    /// Number of curve points supported (maximum of 20).
45    pub n_pt: u16,
46    /// Tms_SF
47    ///
48    /// Scale factor for duration.
49    pub tms_sf: i16,
50    /// Hz_SF
51    ///
52    /// Scale factor for frequency.
53    pub hz_sf: i16,
54    #[allow(missing_docs)]
55    pub curve: Vec<Curve>,
56}
57#[allow(missing_docs)]
58impl Lfrtc {
59    pub const ACT_CRV: crate::Point<Self, u16> = crate::Point::new(0, 1, true);
60    pub const MOD_ENA: crate::Point<Self, ModEna> = crate::Point::new(1, 1, true);
61    pub const WIN_TMS: crate::Point<Self, Option<u16>> = crate::Point::new(2, 1, true);
62    pub const RVRT_TMS: crate::Point<Self, Option<u16>> = crate::Point::new(3, 1, true);
63    pub const RMP_TMS: crate::Point<Self, Option<u16>> = crate::Point::new(4, 1, true);
64    pub const N_CRV: crate::Point<Self, u16> = crate::Point::new(5, 1, false);
65    pub const N_PT: crate::Point<Self, u16> = crate::Point::new(6, 1, false);
66    pub const TMS_SF: crate::Point<Self, i16> = crate::Point::new(7, 1, false);
67    pub const HZ_SF: crate::Point<Self, i16> = crate::Point::new(8, 1, false);
68}
69impl crate::Group for Lfrtc {
70    const LEN: u16 = 10;
71}
72impl Lfrtc {
73    fn parse_group(data: &[u16]) -> Result<(&[u16], Self), crate::DecodeError> {
74        let nested_data = data
75            .get(usize::from(<Self as crate::Group>::LEN)..)
76            .unwrap_or(&[]);
77        let (nested_data, curve) = Curve::parse_multiple(nested_data)?;
78        Ok((
79            nested_data,
80            Self {
81                act_crv: Self::ACT_CRV.from_data(data)?,
82                mod_ena: Self::MOD_ENA.from_data(data)?,
83                win_tms: Self::WIN_TMS.from_data(data)?,
84                rvrt_tms: Self::RVRT_TMS.from_data(data)?,
85                rmp_tms: Self::RMP_TMS.from_data(data)?,
86                n_crv: Self::N_CRV.from_data(data)?,
87                n_pt: Self::N_PT.from_data(data)?,
88                tms_sf: Self::TMS_SF.from_data(data)?,
89                hz_sf: Self::HZ_SF.from_data(data)?,
90                curve,
91            },
92        ))
93    }
94}
95bitflags::bitflags! {
96    #[doc = " ModEna"] #[doc = " "] #[doc =
97    " LHzRT control mode. Enable active curve.  Bitfield value."] #[derive(Copy, Clone,
98    Debug, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(::serde::Serialize,
99    ::serde::Deserialize))] pub struct ModEna : u16 { #[allow(missing_docs)] const
100    Enabled = 1; }
101}
102impl crate::Value for ModEna {
103    fn decode(data: &[u16]) -> Result<Self, crate::DecodeError> {
104        let value = u16::decode(data)?;
105        Ok(Self::from_bits_retain(value))
106    }
107    fn encode(self) -> Box<[u16]> {
108        self.bits().encode()
109    }
110}
111impl crate::FixedSize for ModEna {
112    const SIZE: u16 = 1u16;
113    const INVALID: Self = Self::from_bits_retain(65535u16);
114    fn is_invalid(&self) -> bool {
115        self.bits() == 65535u16
116    }
117}
118#[allow(missing_docs)]
119#[derive(Debug)]
120#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
121pub struct Curve {
122    /// ActPt
123    ///
124    /// Number of active points in array.
125    pub act_pt: u16,
126    /// Tms1
127    ///
128    /// Point 1 must remain connected duration.
129    pub tms1: u16,
130    /// Hz1
131    ///
132    /// Point 1 must remain connected frequency.
133    pub hz1: u16,
134    /// Tms2
135    ///
136    /// Point 2 must remain connected duration.
137    pub tms2: Option<u16>,
138    /// Hz2
139    ///
140    /// Point 2 must remain connected frequency.
141    pub hz2: Option<u16>,
142    /// Tms3
143    ///
144    /// Point 3 must remain connected duration.
145    pub tms3: Option<u16>,
146    /// Hz3
147    ///
148    /// Point 3 must remain connected frequency.
149    pub hz3: Option<u16>,
150    /// Tms4
151    ///
152    /// Point 4 must remain connected duration.
153    pub tms4: Option<u16>,
154    /// Hz4
155    ///
156    /// Point 4 must remain connected frequency.
157    pub hz4: Option<u16>,
158    /// Tms5
159    ///
160    /// Point 5 must remain connected duration.
161    pub tms5: Option<u16>,
162    /// Hz5
163    ///
164    /// Point 5 must remain connected frequency.
165    pub hz5: Option<u16>,
166    /// Tms6
167    ///
168    /// Point 6 must remain connected duration.
169    pub tms6: Option<u16>,
170    /// Hz6
171    ///
172    /// Point 6 must remain connected frequency.
173    pub hz6: Option<u16>,
174    /// Tms7
175    ///
176    /// Point 7 must remain connected duration.
177    pub tms7: Option<u16>,
178    /// Hz7
179    ///
180    /// Point 7 must remain connected frequency.
181    pub hz7: Option<u16>,
182    /// Tms8
183    ///
184    /// Point 8 must remain connected duration.
185    pub tms8: Option<u16>,
186    /// Hz8
187    ///
188    /// Point 8 must remain connected frequency.
189    pub hz8: Option<u16>,
190    /// Tms9
191    ///
192    /// Point 9 must remain connected duration.
193    pub tms9: Option<u16>,
194    /// Hz9
195    ///
196    /// Point 9 must remain connected frequency.
197    pub hz9: Option<u16>,
198    /// Tms10
199    ///
200    /// Point 10 must remain connected duration.
201    pub tms10: Option<u16>,
202    /// Hz10
203    ///
204    /// Point 10 must remain connected frequency.
205    pub hz10: Option<u16>,
206    /// Tms11
207    ///
208    /// Point 11 must remain connected duration.
209    pub tms11: Option<u16>,
210    /// Hz11
211    ///
212    /// Point 11 must remain connected frequency.
213    pub hz11: Option<u16>,
214    /// Tms12
215    ///
216    /// Point 12 must remain connected duration.
217    pub tms12: Option<u16>,
218    /// Hz12
219    ///
220    /// Point 12 must remain connected frequency.
221    pub hz12: Option<u16>,
222    /// Tms13
223    ///
224    /// Point 13 must remain connected duration.
225    pub tms13: Option<u16>,
226    /// Hz13
227    ///
228    /// Point 13 must remain connected frequency.
229    pub hz13: Option<u16>,
230    /// Tms14
231    ///
232    /// Point 14 must remain connected duration.
233    pub tms14: Option<u16>,
234    /// Hz14
235    ///
236    /// Point 14 must remain connected frequency.
237    pub hz14: Option<u16>,
238    /// Tms15
239    ///
240    /// Point 15 must remain connected duration.
241    pub tms15: Option<u16>,
242    /// Hz15
243    ///
244    /// Point 15 must remain connected frequency.
245    pub hz15: Option<u16>,
246    /// Tms16
247    ///
248    /// Point 16 must remain connected duration.
249    pub tms16: Option<u16>,
250    /// Hz16
251    ///
252    /// Point 16 must remain connected frequency.
253    pub hz16: Option<u16>,
254    /// Tms17
255    ///
256    /// Point 17 must remain connected duration.
257    pub tms17: Option<u16>,
258    /// Hz17
259    ///
260    /// Point 17 must remain connected frequency.
261    pub hz17: Option<u16>,
262    /// Tms18
263    ///
264    /// Point 18 must remain connected duration.
265    pub tms18: Option<u16>,
266    /// Hz18
267    ///
268    /// Point 18 must remain connected frequency.
269    pub hz18: Option<u16>,
270    /// Tms19
271    ///
272    /// Point 19 must remain connected duration.
273    pub tms19: Option<u16>,
274    /// Hz19
275    ///
276    /// Point 19 must remain connected frequency.
277    pub hz19: Option<u16>,
278    /// Tms20
279    ///
280    /// Point 20 must remain connected duration.
281    pub tms20: Option<u16>,
282    /// Hz20
283    ///
284    /// Point 20 must remain connected frequency.
285    pub hz20: Option<u16>,
286    /// CrvNam
287    ///
288    /// Optional description for curve.
289    pub crv_nam: Option<String>,
290    /// ReadOnly
291    ///
292    /// Enumerated value indicates if curve is read-only or can be modified.
293    pub read_only: CurveReadOnly,
294}
295#[allow(missing_docs)]
296impl Curve {
297    pub const ACT_PT: crate::Point<Self, u16> = crate::Point::new(0, 1, true);
298    pub const TMS1: crate::Point<Self, u16> = crate::Point::new(1, 1, true);
299    pub const HZ1: crate::Point<Self, u16> = crate::Point::new(2, 1, true);
300    pub const TMS2: crate::Point<Self, Option<u16>> = crate::Point::new(3, 1, true);
301    pub const HZ2: crate::Point<Self, Option<u16>> = crate::Point::new(4, 1, true);
302    pub const TMS3: crate::Point<Self, Option<u16>> = crate::Point::new(5, 1, true);
303    pub const HZ3: crate::Point<Self, Option<u16>> = crate::Point::new(6, 1, true);
304    pub const TMS4: crate::Point<Self, Option<u16>> = crate::Point::new(7, 1, true);
305    pub const HZ4: crate::Point<Self, Option<u16>> = crate::Point::new(8, 1, true);
306    pub const TMS5: crate::Point<Self, Option<u16>> = crate::Point::new(9, 1, true);
307    pub const HZ5: crate::Point<Self, Option<u16>> = crate::Point::new(10, 1, true);
308    pub const TMS6: crate::Point<Self, Option<u16>> = crate::Point::new(11, 1, true);
309    pub const HZ6: crate::Point<Self, Option<u16>> = crate::Point::new(12, 1, true);
310    pub const TMS7: crate::Point<Self, Option<u16>> = crate::Point::new(13, 1, true);
311    pub const HZ7: crate::Point<Self, Option<u16>> = crate::Point::new(14, 1, true);
312    pub const TMS8: crate::Point<Self, Option<u16>> = crate::Point::new(15, 1, true);
313    pub const HZ8: crate::Point<Self, Option<u16>> = crate::Point::new(16, 1, true);
314    pub const TMS9: crate::Point<Self, Option<u16>> = crate::Point::new(17, 1, true);
315    pub const HZ9: crate::Point<Self, Option<u16>> = crate::Point::new(18, 1, true);
316    pub const TMS10: crate::Point<Self, Option<u16>> = crate::Point::new(19, 1, true);
317    pub const HZ10: crate::Point<Self, Option<u16>> = crate::Point::new(20, 1, true);
318    pub const TMS11: crate::Point<Self, Option<u16>> = crate::Point::new(21, 1, true);
319    pub const HZ11: crate::Point<Self, Option<u16>> = crate::Point::new(22, 1, true);
320    pub const TMS12: crate::Point<Self, Option<u16>> = crate::Point::new(23, 1, true);
321    pub const HZ12: crate::Point<Self, Option<u16>> = crate::Point::new(24, 1, true);
322    pub const TMS13: crate::Point<Self, Option<u16>> = crate::Point::new(25, 1, true);
323    pub const HZ13: crate::Point<Self, Option<u16>> = crate::Point::new(26, 1, true);
324    pub const TMS14: crate::Point<Self, Option<u16>> = crate::Point::new(27, 1, true);
325    pub const HZ14: crate::Point<Self, Option<u16>> = crate::Point::new(28, 1, true);
326    pub const TMS15: crate::Point<Self, Option<u16>> = crate::Point::new(29, 1, true);
327    pub const HZ15: crate::Point<Self, Option<u16>> = crate::Point::new(30, 1, true);
328    pub const TMS16: crate::Point<Self, Option<u16>> = crate::Point::new(31, 1, true);
329    pub const HZ16: crate::Point<Self, Option<u16>> = crate::Point::new(32, 1, true);
330    pub const TMS17: crate::Point<Self, Option<u16>> = crate::Point::new(33, 1, true);
331    pub const HZ17: crate::Point<Self, Option<u16>> = crate::Point::new(34, 1, true);
332    pub const TMS18: crate::Point<Self, Option<u16>> = crate::Point::new(35, 1, true);
333    pub const HZ18: crate::Point<Self, Option<u16>> = crate::Point::new(36, 1, true);
334    pub const TMS19: crate::Point<Self, Option<u16>> = crate::Point::new(37, 1, true);
335    pub const HZ19: crate::Point<Self, Option<u16>> = crate::Point::new(38, 1, true);
336    pub const TMS20: crate::Point<Self, Option<u16>> = crate::Point::new(39, 1, true);
337    pub const HZ20: crate::Point<Self, Option<u16>> = crate::Point::new(40, 1, true);
338    pub const CRV_NAM: crate::Point<Self, Option<String>> = crate::Point::new(41, 8, true);
339    pub const READ_ONLY: crate::Point<Self, CurveReadOnly> = crate::Point::new(49, 1, false);
340}
341impl crate::Group for Curve {
342    const LEN: u16 = 50;
343}
344impl Curve {
345    fn parse_group(data: &[u16]) -> Result<(&[u16], Self), crate::DecodeError> {
346        let nested_data = data
347            .get(usize::from(<Self as crate::Group>::LEN)..)
348            .unwrap_or(&[]);
349        Ok((
350            nested_data,
351            Self {
352                act_pt: Self::ACT_PT.from_data(data)?,
353                tms1: Self::TMS1.from_data(data)?,
354                hz1: Self::HZ1.from_data(data)?,
355                tms2: Self::TMS2.from_data(data)?,
356                hz2: Self::HZ2.from_data(data)?,
357                tms3: Self::TMS3.from_data(data)?,
358                hz3: Self::HZ3.from_data(data)?,
359                tms4: Self::TMS4.from_data(data)?,
360                hz4: Self::HZ4.from_data(data)?,
361                tms5: Self::TMS5.from_data(data)?,
362                hz5: Self::HZ5.from_data(data)?,
363                tms6: Self::TMS6.from_data(data)?,
364                hz6: Self::HZ6.from_data(data)?,
365                tms7: Self::TMS7.from_data(data)?,
366                hz7: Self::HZ7.from_data(data)?,
367                tms8: Self::TMS8.from_data(data)?,
368                hz8: Self::HZ8.from_data(data)?,
369                tms9: Self::TMS9.from_data(data)?,
370                hz9: Self::HZ9.from_data(data)?,
371                tms10: Self::TMS10.from_data(data)?,
372                hz10: Self::HZ10.from_data(data)?,
373                tms11: Self::TMS11.from_data(data)?,
374                hz11: Self::HZ11.from_data(data)?,
375                tms12: Self::TMS12.from_data(data)?,
376                hz12: Self::HZ12.from_data(data)?,
377                tms13: Self::TMS13.from_data(data)?,
378                hz13: Self::HZ13.from_data(data)?,
379                tms14: Self::TMS14.from_data(data)?,
380                hz14: Self::HZ14.from_data(data)?,
381                tms15: Self::TMS15.from_data(data)?,
382                hz15: Self::HZ15.from_data(data)?,
383                tms16: Self::TMS16.from_data(data)?,
384                hz16: Self::HZ16.from_data(data)?,
385                tms17: Self::TMS17.from_data(data)?,
386                hz17: Self::HZ17.from_data(data)?,
387                tms18: Self::TMS18.from_data(data)?,
388                hz18: Self::HZ18.from_data(data)?,
389                tms19: Self::TMS19.from_data(data)?,
390                hz19: Self::HZ19.from_data(data)?,
391                tms20: Self::TMS20.from_data(data)?,
392                hz20: Self::HZ20.from_data(data)?,
393                crv_nam: Self::CRV_NAM.from_data(data)?,
394                read_only: Self::READ_ONLY.from_data(data)?,
395            },
396        ))
397    }
398    fn parse_multiple(data: &[u16]) -> Result<(&[u16], Vec<Self>), crate::DecodeError> {
399        let group_len = usize::from(<Curve as crate::Group>::LEN);
400        if group_len == 0 {
401            return Ok((data, Vec::new()));
402        }
403        if data.len() % group_len != 0 {
404            return Err(crate::DecodeError::OutOfBounds);
405        }
406        let group_count = data.len() / group_len;
407        let (data, groups) =
408            (0..group_count).try_fold((data, Vec::new()), |(data, mut groups), _| {
409                let (data, group) = Curve::parse_group(data)?;
410                groups.push(group);
411                Ok::<_, crate::DecodeError>((data, groups))
412            })?;
413        Ok((data, groups))
414    }
415}
416/// ReadOnly
417///
418/// Enumerated value indicates if curve is read-only or can be modified.
419#[derive(Copy, Clone, Debug, Eq, PartialEq)]
420#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
421pub enum CurveReadOnly {
422    #[allow(missing_docs)]
423    Readwrite,
424    #[allow(missing_docs)]
425    Readonly,
426    /// Raw enum value not defined by the SunSpec model.
427    Invalid(u16),
428}
429impl crate::EnumValue for CurveReadOnly {
430    type Repr = u16;
431    const INVALID: Self::Repr = 65535;
432    fn from_repr(value: Self::Repr) -> Self {
433        match value {
434            0 => Self::Readwrite,
435            1 => Self::Readonly,
436            value => Self::Invalid(value),
437        }
438    }
439    fn to_repr(self) -> Self::Repr {
440        match self {
441            Self::Readwrite => 0,
442            Self::Readonly => 1,
443            Self::Invalid(value) => value,
444        }
445    }
446}
447impl crate::FixedSize for CurveReadOnly {
448    const SIZE: u16 = 1u16;
449    const INVALID: Self = Self::Invalid(65535);
450    fn is_invalid(&self) -> bool {
451        matches!(self, Self::Invalid(_))
452    }
453}
454impl crate::Model for Lfrtc {
455    const ID: u16 = 141;
456    fn addr(models: &crate::Models) -> crate::ModelAddr<Self> {
457        models.m141
458    }
459    fn parse(data: &[u16]) -> Result<Self, crate::ParseError<Self>> {
460        let (_, model) = Self::parse_group(data)?;
461        Ok(model)
462    }
463}