Skip to main content

sunspec/models/
model139.rs

1//! LVRTX
2/// Type alias for [`Lvrtx`].
3pub type Model139 = Lvrtx;
4/// LVRTX
5///
6/// LVRT extended curve
7///
8/// Detail: Ref 4: 11
9#[derive(Debug)]
10#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
11pub struct Lvrtx {
12    /// ActCrv
13    ///
14    /// Index of active curve. 0=no active curve.
15    pub act_crv: u16,
16    /// ModEna
17    ///
18    /// LVRT control mode. Enable active curve.  Bitfield value.
19    pub mod_ena: ModEna,
20    /// WinTms
21    ///
22    /// Time window for LVRT change.
23    ///
24    /// Detail: Setting is ignored for LVRT controls.
25    pub win_tms: Option<u16>,
26    /// RvrtTms
27    ///
28    /// Timeout period for LVRT curve selection.
29    ///
30    /// Detail: Setting is ignored for LVRT 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 LVRT 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    /// V_SF
51    ///
52    /// Scale factor for percent VRef.
53    pub v_sf: i16,
54    #[allow(missing_docs)]
55    pub crv_type: CrvType,
56    #[allow(missing_docs)]
57    pub curve: Vec<Curve>,
58}
59#[allow(missing_docs)]
60impl Lvrtx {
61    pub const ACT_CRV: crate::Point<Self, u16> = crate::Point::new(0, 1, true);
62    pub const MOD_ENA: crate::Point<Self, ModEna> = crate::Point::new(1, 1, true);
63    pub const WIN_TMS: crate::Point<Self, Option<u16>> = crate::Point::new(2, 1, true);
64    pub const RVRT_TMS: crate::Point<Self, Option<u16>> = crate::Point::new(3, 1, true);
65    pub const RMP_TMS: crate::Point<Self, Option<u16>> = crate::Point::new(4, 1, true);
66    pub const N_CRV: crate::Point<Self, u16> = crate::Point::new(5, 1, false);
67    pub const N_PT: crate::Point<Self, u16> = crate::Point::new(6, 1, false);
68    pub const TMS_SF: crate::Point<Self, i16> = crate::Point::new(7, 1, false);
69    pub const V_SF: crate::Point<Self, i16> = crate::Point::new(8, 1, false);
70    pub const CRV_TYPE: crate::Point<Self, CrvType> = crate::Point::new(9, 1, false);
71}
72impl crate::Group for Lvrtx {
73    const LEN: u16 = 10;
74}
75impl Lvrtx {
76    fn parse_group(data: &[u16]) -> Result<(&[u16], Self), crate::DecodeError> {
77        let nested_data = data
78            .get(usize::from(<Self as crate::Group>::LEN)..)
79            .unwrap_or(&[]);
80        let (nested_data, curve) = Curve::parse_multiple(nested_data)?;
81        Ok((
82            nested_data,
83            Self {
84                act_crv: Self::ACT_CRV.from_data(data)?,
85                mod_ena: Self::MOD_ENA.from_data(data)?,
86                win_tms: Self::WIN_TMS.from_data(data)?,
87                rvrt_tms: Self::RVRT_TMS.from_data(data)?,
88                rmp_tms: Self::RMP_TMS.from_data(data)?,
89                n_crv: Self::N_CRV.from_data(data)?,
90                n_pt: Self::N_PT.from_data(data)?,
91                tms_sf: Self::TMS_SF.from_data(data)?,
92                v_sf: Self::V_SF.from_data(data)?,
93                crv_type: Self::CRV_TYPE.from_data(data)?,
94                curve,
95            },
96        ))
97    }
98}
99bitflags::bitflags! {
100    #[doc = " ModEna"] #[doc = " "] #[doc =
101    " LVRT control mode. Enable active curve.  Bitfield value."] #[derive(Copy, Clone,
102    Debug, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(::serde::Serialize,
103    ::serde::Deserialize))] pub struct ModEna : u16 { #[allow(missing_docs)] const
104    Enabled = 1; }
105}
106impl crate::Value for ModEna {
107    fn decode(data: &[u16]) -> Result<Self, crate::DecodeError> {
108        let value = u16::decode(data)?;
109        Ok(Self::from_bits_retain(value))
110    }
111    fn encode(self) -> Box<[u16]> {
112        self.bits().encode()
113    }
114}
115impl crate::FixedSize for ModEna {
116    const SIZE: u16 = 1u16;
117    const INVALID: Self = Self::from_bits_retain(65535u16);
118    fn is_invalid(&self) -> bool {
119        self.bits() == 65535u16
120    }
121}
122#[allow(missing_docs)]
123#[derive(Copy, Clone, Debug, Eq, PartialEq)]
124#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
125pub enum CrvType {
126    #[allow(missing_docs)]
127    CeaseToEnergize,
128    /// Raw enum value not defined by the SunSpec model.
129    Invalid(u16),
130}
131impl crate::EnumValue for CrvType {
132    type Repr = u16;
133    const INVALID: Self::Repr = 65535;
134    fn from_repr(value: Self::Repr) -> Self {
135        match value {
136            1 => Self::CeaseToEnergize,
137            value => Self::Invalid(value),
138        }
139    }
140    fn to_repr(self) -> Self::Repr {
141        match self {
142            Self::CeaseToEnergize => 1,
143            Self::Invalid(value) => value,
144        }
145    }
146}
147impl crate::FixedSize for CrvType {
148    const SIZE: u16 = 1u16;
149    const INVALID: Self = Self::Invalid(65535);
150    fn is_invalid(&self) -> bool {
151        matches!(self, Self::Invalid(_))
152    }
153}
154#[allow(missing_docs)]
155#[derive(Debug)]
156#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
157pub struct Curve {
158    /// ActPt
159    ///
160    /// Number of active points in array.
161    pub act_pt: u16,
162    /// Tms1
163    ///
164    /// Point 1 duration.
165    pub tms1: u16,
166    /// V1
167    ///
168    /// Point 1 voltage.
169    pub v1: u16,
170    /// Tms2
171    ///
172    /// Point 2 duration.
173    pub tms2: Option<u16>,
174    /// V2
175    ///
176    /// Point 2 voltage.
177    pub v2: Option<u16>,
178    /// Tms3
179    ///
180    /// Point 3 duration.
181    pub tms3: Option<u16>,
182    /// V3
183    ///
184    /// Point 3 voltage.
185    pub v3: Option<u16>,
186    /// Tms4
187    ///
188    /// Point 4 duration.
189    pub tms4: Option<u16>,
190    /// V4
191    ///
192    /// Point 4 voltage.
193    pub v4: Option<u16>,
194    /// Tms5
195    ///
196    /// Point 5 duration.
197    pub tms5: Option<u16>,
198    /// V5
199    ///
200    /// Point 5 voltage.
201    pub v5: Option<u16>,
202    /// Tms6
203    ///
204    /// Point 6 duration.
205    pub tms6: Option<u16>,
206    /// V6
207    ///
208    /// Point 6 voltage.
209    pub v6: Option<u16>,
210    /// Tms7
211    ///
212    /// Point 7 duration.
213    pub tms7: Option<u16>,
214    /// V7
215    ///
216    /// Point 7 voltage.
217    pub v7: Option<u16>,
218    /// Tms8
219    ///
220    /// Point 8 duration.
221    pub tms8: Option<u16>,
222    /// V8
223    ///
224    /// Point 8 voltage.
225    pub v8: Option<u16>,
226    /// Tms9
227    ///
228    /// Point 9 duration.
229    pub tms9: Option<u16>,
230    /// V9
231    ///
232    /// Point 9 voltage.
233    pub v9: Option<u16>,
234    /// Tms10
235    ///
236    /// Point 10 duration.
237    pub tms10: Option<u16>,
238    /// V10
239    ///
240    /// Point 10 voltage.
241    pub v10: Option<u16>,
242    /// Tms11
243    ///
244    /// Point 11 duration.
245    pub tms11: Option<u16>,
246    /// V11
247    ///
248    /// Point 11 voltage.
249    pub v11: Option<u16>,
250    /// Tms12
251    ///
252    /// Point 12 duration.
253    pub tms12: Option<u16>,
254    /// V12
255    ///
256    /// Point 12 voltage.
257    pub v12: Option<u16>,
258    /// Tms13
259    ///
260    /// Point 13 duration.
261    pub tms13: Option<u16>,
262    /// V13
263    ///
264    /// Point 13 voltage.
265    pub v13: Option<u16>,
266    /// Tms14
267    ///
268    /// Point 14 duration.
269    pub tms14: Option<u16>,
270    /// V14
271    ///
272    /// Point 14 voltage.
273    pub v14: Option<u16>,
274    /// Tms15
275    ///
276    /// Point 15 duration.
277    pub tms15: Option<u16>,
278    /// V15
279    ///
280    /// Point 15 voltage.
281    pub v15: Option<u16>,
282    /// Tms16
283    ///
284    /// Point 16 duration.
285    pub tms16: Option<u16>,
286    /// V16
287    ///
288    /// Point 16 voltage.
289    pub v16: Option<u16>,
290    /// Tms17
291    ///
292    /// Point 17 duration.
293    pub tms17: Option<u16>,
294    /// V17
295    ///
296    /// Point 17 voltage.
297    pub v17: Option<u16>,
298    /// Tms18
299    ///
300    /// Point 18 duration.
301    pub tms18: Option<u16>,
302    /// V18
303    ///
304    /// Point 18 voltage.
305    pub v18: Option<u16>,
306    /// Tms19
307    ///
308    /// Point 19 duration.
309    pub tms19: Option<u16>,
310    /// V19
311    ///
312    /// Point 19 voltage.
313    pub v19: Option<u16>,
314    /// Tms20
315    ///
316    /// Point 20 duration.
317    pub tms20: Option<u16>,
318    /// V20
319    ///
320    /// Point 20 voltage.
321    pub v20: Option<u16>,
322    /// CrvNam
323    ///
324    /// Optional description for curve.
325    pub crv_nam: Option<String>,
326    /// ReadOnly
327    ///
328    /// Enumerated value indicates if curve is read-only or can be modified.
329    pub read_only: CurveReadOnly,
330}
331#[allow(missing_docs)]
332impl Curve {
333    pub const ACT_PT: crate::Point<Self, u16> = crate::Point::new(0, 1, true);
334    pub const TMS1: crate::Point<Self, u16> = crate::Point::new(1, 1, true);
335    pub const V1: crate::Point<Self, u16> = crate::Point::new(2, 1, true);
336    pub const TMS2: crate::Point<Self, Option<u16>> = crate::Point::new(3, 1, true);
337    pub const V2: crate::Point<Self, Option<u16>> = crate::Point::new(4, 1, true);
338    pub const TMS3: crate::Point<Self, Option<u16>> = crate::Point::new(5, 1, true);
339    pub const V3: crate::Point<Self, Option<u16>> = crate::Point::new(6, 1, true);
340    pub const TMS4: crate::Point<Self, Option<u16>> = crate::Point::new(7, 1, true);
341    pub const V4: crate::Point<Self, Option<u16>> = crate::Point::new(8, 1, true);
342    pub const TMS5: crate::Point<Self, Option<u16>> = crate::Point::new(9, 1, true);
343    pub const V5: crate::Point<Self, Option<u16>> = crate::Point::new(10, 1, true);
344    pub const TMS6: crate::Point<Self, Option<u16>> = crate::Point::new(11, 1, true);
345    pub const V6: crate::Point<Self, Option<u16>> = crate::Point::new(12, 1, true);
346    pub const TMS7: crate::Point<Self, Option<u16>> = crate::Point::new(13, 1, true);
347    pub const V7: crate::Point<Self, Option<u16>> = crate::Point::new(14, 1, true);
348    pub const TMS8: crate::Point<Self, Option<u16>> = crate::Point::new(15, 1, true);
349    pub const V8: crate::Point<Self, Option<u16>> = crate::Point::new(16, 1, true);
350    pub const TMS9: crate::Point<Self, Option<u16>> = crate::Point::new(17, 1, true);
351    pub const V9: crate::Point<Self, Option<u16>> = crate::Point::new(18, 1, true);
352    pub const TMS10: crate::Point<Self, Option<u16>> = crate::Point::new(19, 1, true);
353    pub const V10: crate::Point<Self, Option<u16>> = crate::Point::new(20, 1, true);
354    pub const TMS11: crate::Point<Self, Option<u16>> = crate::Point::new(21, 1, true);
355    pub const V11: crate::Point<Self, Option<u16>> = crate::Point::new(22, 1, true);
356    pub const TMS12: crate::Point<Self, Option<u16>> = crate::Point::new(23, 1, true);
357    pub const V12: crate::Point<Self, Option<u16>> = crate::Point::new(24, 1, true);
358    pub const TMS13: crate::Point<Self, Option<u16>> = crate::Point::new(25, 1, true);
359    pub const V13: crate::Point<Self, Option<u16>> = crate::Point::new(26, 1, true);
360    pub const TMS14: crate::Point<Self, Option<u16>> = crate::Point::new(27, 1, true);
361    pub const V14: crate::Point<Self, Option<u16>> = crate::Point::new(28, 1, true);
362    pub const TMS15: crate::Point<Self, Option<u16>> = crate::Point::new(29, 1, true);
363    pub const V15: crate::Point<Self, Option<u16>> = crate::Point::new(30, 1, true);
364    pub const TMS16: crate::Point<Self, Option<u16>> = crate::Point::new(31, 1, true);
365    pub const V16: crate::Point<Self, Option<u16>> = crate::Point::new(32, 1, true);
366    pub const TMS17: crate::Point<Self, Option<u16>> = crate::Point::new(33, 1, true);
367    pub const V17: crate::Point<Self, Option<u16>> = crate::Point::new(34, 1, true);
368    pub const TMS18: crate::Point<Self, Option<u16>> = crate::Point::new(35, 1, true);
369    pub const V18: crate::Point<Self, Option<u16>> = crate::Point::new(36, 1, true);
370    pub const TMS19: crate::Point<Self, Option<u16>> = crate::Point::new(37, 1, true);
371    pub const V19: crate::Point<Self, Option<u16>> = crate::Point::new(38, 1, true);
372    pub const TMS20: crate::Point<Self, Option<u16>> = crate::Point::new(39, 1, true);
373    pub const V20: crate::Point<Self, Option<u16>> = crate::Point::new(40, 1, true);
374    pub const CRV_NAM: crate::Point<Self, Option<String>> = crate::Point::new(41, 8, true);
375    pub const READ_ONLY: crate::Point<Self, CurveReadOnly> = crate::Point::new(49, 1, false);
376}
377impl crate::Group for Curve {
378    const LEN: u16 = 50;
379}
380impl Curve {
381    fn parse_group(data: &[u16]) -> Result<(&[u16], Self), crate::DecodeError> {
382        let nested_data = data
383            .get(usize::from(<Self as crate::Group>::LEN)..)
384            .unwrap_or(&[]);
385        Ok((
386            nested_data,
387            Self {
388                act_pt: Self::ACT_PT.from_data(data)?,
389                tms1: Self::TMS1.from_data(data)?,
390                v1: Self::V1.from_data(data)?,
391                tms2: Self::TMS2.from_data(data)?,
392                v2: Self::V2.from_data(data)?,
393                tms3: Self::TMS3.from_data(data)?,
394                v3: Self::V3.from_data(data)?,
395                tms4: Self::TMS4.from_data(data)?,
396                v4: Self::V4.from_data(data)?,
397                tms5: Self::TMS5.from_data(data)?,
398                v5: Self::V5.from_data(data)?,
399                tms6: Self::TMS6.from_data(data)?,
400                v6: Self::V6.from_data(data)?,
401                tms7: Self::TMS7.from_data(data)?,
402                v7: Self::V7.from_data(data)?,
403                tms8: Self::TMS8.from_data(data)?,
404                v8: Self::V8.from_data(data)?,
405                tms9: Self::TMS9.from_data(data)?,
406                v9: Self::V9.from_data(data)?,
407                tms10: Self::TMS10.from_data(data)?,
408                v10: Self::V10.from_data(data)?,
409                tms11: Self::TMS11.from_data(data)?,
410                v11: Self::V11.from_data(data)?,
411                tms12: Self::TMS12.from_data(data)?,
412                v12: Self::V12.from_data(data)?,
413                tms13: Self::TMS13.from_data(data)?,
414                v13: Self::V13.from_data(data)?,
415                tms14: Self::TMS14.from_data(data)?,
416                v14: Self::V14.from_data(data)?,
417                tms15: Self::TMS15.from_data(data)?,
418                v15: Self::V15.from_data(data)?,
419                tms16: Self::TMS16.from_data(data)?,
420                v16: Self::V16.from_data(data)?,
421                tms17: Self::TMS17.from_data(data)?,
422                v17: Self::V17.from_data(data)?,
423                tms18: Self::TMS18.from_data(data)?,
424                v18: Self::V18.from_data(data)?,
425                tms19: Self::TMS19.from_data(data)?,
426                v19: Self::V19.from_data(data)?,
427                tms20: Self::TMS20.from_data(data)?,
428                v20: Self::V20.from_data(data)?,
429                crv_nam: Self::CRV_NAM.from_data(data)?,
430                read_only: Self::READ_ONLY.from_data(data)?,
431            },
432        ))
433    }
434    fn parse_multiple(data: &[u16]) -> Result<(&[u16], Vec<Self>), crate::DecodeError> {
435        let group_len = usize::from(<Curve as crate::Group>::LEN);
436        if group_len == 0 {
437            return Ok((data, Vec::new()));
438        }
439        if data.len() % group_len != 0 {
440            return Err(crate::DecodeError::OutOfBounds);
441        }
442        let group_count = data.len() / group_len;
443        let (data, groups) =
444            (0..group_count).try_fold((data, Vec::new()), |(data, mut groups), _| {
445                let (data, group) = Curve::parse_group(data)?;
446                groups.push(group);
447                Ok::<_, crate::DecodeError>((data, groups))
448            })?;
449        Ok((data, groups))
450    }
451}
452/// ReadOnly
453///
454/// Enumerated value indicates if curve is read-only or can be modified.
455#[derive(Copy, Clone, Debug, Eq, PartialEq)]
456#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
457pub enum CurveReadOnly {
458    #[allow(missing_docs)]
459    Readwrite,
460    #[allow(missing_docs)]
461    Readonly,
462    /// Raw enum value not defined by the SunSpec model.
463    Invalid(u16),
464}
465impl crate::EnumValue for CurveReadOnly {
466    type Repr = u16;
467    const INVALID: Self::Repr = 65535;
468    fn from_repr(value: Self::Repr) -> Self {
469        match value {
470            0 => Self::Readwrite,
471            1 => Self::Readonly,
472            value => Self::Invalid(value),
473        }
474    }
475    fn to_repr(self) -> Self::Repr {
476        match self {
477            Self::Readwrite => 0,
478            Self::Readonly => 1,
479            Self::Invalid(value) => value,
480        }
481    }
482}
483impl crate::FixedSize for CurveReadOnly {
484    const SIZE: u16 = 1u16;
485    const INVALID: Self = Self::Invalid(65535);
486    fn is_invalid(&self) -> bool {
487        matches!(self, Self::Invalid(_))
488    }
489}
490impl crate::Model for Lvrtx {
491    const ID: u16 = 139;
492    fn addr(models: &crate::Models) -> crate::ModelAddr<Self> {
493        models.m139
494    }
495    fn parse(data: &[u16]) -> Result<Self, crate::ParseError<Self>> {
496        let (_, model) = Self::parse_group(data)?;
497        Ok(model)
498    }
499}