Skip to main content

sunspec/models/
model129.rs

1//! LVRTD
2/// Type alias for [`Lvrt`].
3pub type Model129 = Lvrt;
4/// LVRTD
5///
6/// LVRT Must Disconnect
7///
8/// Detail: Ref 4: 11
9#[derive(Debug)]
10#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
11pub struct Lvrt {
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 curve: Vec<Curve>,
56}
57#[allow(missing_docs)]
58impl Lvrt {
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 V_SF: crate::Point<Self, i16> = crate::Point::new(8, 1, false);
68}
69impl crate::Group for Lvrt {
70    const LEN: u16 = 10;
71}
72impl Lvrt {
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                v_sf: Self::V_SF.from_data(data)?,
90                curve,
91            },
92        ))
93    }
94}
95bitflags::bitflags! {
96    #[doc = " ModEna"] #[doc = " "] #[doc =
97    " LVRT 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 disconnect duration.
129    pub tms1: u16,
130    /// V1
131    ///
132    /// Point 1 must disconnect voltage.
133    pub v1: u16,
134    /// Tms2
135    ///
136    /// Point 2 must disconnect duration.
137    pub tms2: Option<u16>,
138    /// V2
139    ///
140    /// Point 2 must disconnect voltage.
141    pub v2: Option<u16>,
142    /// Tms3
143    ///
144    /// Point 3 must disconnect duration.
145    pub tms3: Option<u16>,
146    /// V3
147    ///
148    /// Point 3 must disconnect voltage.
149    pub v3: Option<u16>,
150    /// Tms4
151    ///
152    /// Point 4 must disconnect duration.
153    pub tms4: Option<u16>,
154    /// V4
155    ///
156    /// Point 4 must disconnect voltage.
157    pub v4: Option<u16>,
158    /// Tms5
159    ///
160    /// Point 5 must disconnect duration.
161    pub tms5: Option<u16>,
162    /// V5
163    ///
164    /// Point 5 must disconnect voltage.
165    pub v5: Option<u16>,
166    /// Tms6
167    ///
168    /// Point 6 must disconnect duration.
169    pub tms6: Option<u16>,
170    /// V6
171    ///
172    /// Point 6 must disconnect voltage.
173    pub v6: Option<u16>,
174    /// Tms7
175    ///
176    /// Point 7 must disconnect duration.
177    pub tms7: Option<u16>,
178    /// V7
179    ///
180    /// Point 7 must disconnect voltage.
181    pub v7: Option<u16>,
182    /// Tms8
183    ///
184    /// Point 8 must disconnect duration.
185    pub tms8: Option<u16>,
186    /// V8
187    ///
188    /// Point 8 must disconnect voltage.
189    pub v8: Option<u16>,
190    /// Tms9
191    ///
192    /// Point 9 must disconnect duration.
193    pub tms9: Option<u16>,
194    /// V9
195    ///
196    /// Point 9 must disconnect voltage.
197    pub v9: Option<u16>,
198    /// Tms10
199    ///
200    /// Point 10 must disconnect duration.
201    pub tms10: Option<u16>,
202    /// V10
203    ///
204    /// Point 10 must disconnect voltage.
205    pub v10: Option<u16>,
206    /// Tms11
207    ///
208    /// Point 11 must disconnect duration.
209    pub tms11: Option<u16>,
210    /// V11
211    ///
212    /// Point 11 must disconnect voltage.
213    pub v11: Option<u16>,
214    /// Tms12
215    ///
216    /// Point 12 must disconnect duration.
217    pub tms12: Option<u16>,
218    /// V12
219    ///
220    /// Point 12 must disconnect voltage.
221    pub v12: Option<u16>,
222    /// Tms13
223    ///
224    /// Point 13 must disconnect duration.
225    pub tms13: Option<u16>,
226    /// V13
227    ///
228    /// Point 13 must disconnect voltage.
229    pub v13: Option<u16>,
230    /// Tms14
231    ///
232    /// Point 14 must disconnect duration.
233    pub tms14: Option<u16>,
234    /// V14
235    ///
236    /// Point 14 must disconnect voltage.
237    pub v14: Option<u16>,
238    /// Tms15
239    ///
240    /// Point 15 must disconnect duration.
241    pub tms15: Option<u16>,
242    /// V15
243    ///
244    /// Point 15 must disconnect voltage.
245    pub v15: Option<u16>,
246    /// Tms16
247    ///
248    /// Point 16 must disconnect duration.
249    pub tms16: Option<u16>,
250    /// V16
251    ///
252    /// Point 16 must disconnect voltage.
253    pub v16: Option<u16>,
254    /// Tms17
255    ///
256    /// Point 17 must disconnect duration.
257    pub tms17: Option<u16>,
258    /// V17
259    ///
260    /// Point 17 must disconnect voltage.
261    pub v17: Option<u16>,
262    /// Tms18
263    ///
264    /// Point 18 must disconnect duration.
265    pub tms18: Option<u16>,
266    /// V18
267    ///
268    /// Point 18 must disconnect voltage.
269    pub v18: Option<u16>,
270    /// Tms19
271    ///
272    /// Point 19 must disconnect duration.
273    pub tms19: Option<u16>,
274    /// V19
275    ///
276    /// Point 19 must disconnect voltage.
277    pub v19: Option<u16>,
278    /// Tms20
279    ///
280    /// Point 20 must disconnect duration.
281    pub tms20: Option<u16>,
282    /// V20
283    ///
284    /// Point 20 must disconnect voltage.
285    pub v20: 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 V1: 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 V2: 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 V3: 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 V4: 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 V5: 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 V6: 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 V7: 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 V8: 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 V9: 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 V10: 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 V11: 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 V12: 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 V13: 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 V14: 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 V15: 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 V16: 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 V17: 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 V18: 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 V19: 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 V20: 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                v1: Self::V1.from_data(data)?,
355                tms2: Self::TMS2.from_data(data)?,
356                v2: Self::V2.from_data(data)?,
357                tms3: Self::TMS3.from_data(data)?,
358                v3: Self::V3.from_data(data)?,
359                tms4: Self::TMS4.from_data(data)?,
360                v4: Self::V4.from_data(data)?,
361                tms5: Self::TMS5.from_data(data)?,
362                v5: Self::V5.from_data(data)?,
363                tms6: Self::TMS6.from_data(data)?,
364                v6: Self::V6.from_data(data)?,
365                tms7: Self::TMS7.from_data(data)?,
366                v7: Self::V7.from_data(data)?,
367                tms8: Self::TMS8.from_data(data)?,
368                v8: Self::V8.from_data(data)?,
369                tms9: Self::TMS9.from_data(data)?,
370                v9: Self::V9.from_data(data)?,
371                tms10: Self::TMS10.from_data(data)?,
372                v10: Self::V10.from_data(data)?,
373                tms11: Self::TMS11.from_data(data)?,
374                v11: Self::V11.from_data(data)?,
375                tms12: Self::TMS12.from_data(data)?,
376                v12: Self::V12.from_data(data)?,
377                tms13: Self::TMS13.from_data(data)?,
378                v13: Self::V13.from_data(data)?,
379                tms14: Self::TMS14.from_data(data)?,
380                v14: Self::V14.from_data(data)?,
381                tms15: Self::TMS15.from_data(data)?,
382                v15: Self::V15.from_data(data)?,
383                tms16: Self::TMS16.from_data(data)?,
384                v16: Self::V16.from_data(data)?,
385                tms17: Self::TMS17.from_data(data)?,
386                v17: Self::V17.from_data(data)?,
387                tms18: Self::TMS18.from_data(data)?,
388                v18: Self::V18.from_data(data)?,
389                tms19: Self::TMS19.from_data(data)?,
390                v19: Self::V19.from_data(data)?,
391                tms20: Self::TMS20.from_data(data)?,
392                v20: Self::V20.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 Lvrt {
455    const ID: u16 = 129;
456    fn addr(models: &crate::Models) -> crate::ModelAddr<Self> {
457        models.m129
458    }
459    fn parse(data: &[u16]) -> Result<Self, crate::ParseError<Self>> {
460        let (_, model) = Self::parse_group(data)?;
461        Ok(model)
462    }
463}