Skip to main content

sunspec/models/
model709.rs

1//! DER Trip LF
2/// Type alias for [`DerTripLf`].
3pub type Model709 = DerTripLf;
4struct Counts {
5    n_pt: u16,
6    n_crv_set: u16,
7}
8/// DER Trip LF
9///
10/// DER low frequency trip model.
11#[derive(Debug)]
12#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
13pub struct DerTripLf {
14    /// DER Trip LF Module Enable
15    ///
16    /// DER low frequency trip control enable.
17    pub ena: Ena,
18    /// Adopt Curve Request
19    ///
20    /// Index of curve points to adopt. First curve index is 1.
21    pub adpt_crv_req: u16,
22    /// Adopt Curve Result
23    ///
24    /// Result of last adopt curve operation.
25    pub adpt_crv_rslt: AdptCrvRslt,
26    /// Number Of Points
27    ///
28    /// Number of curve points supported.
29    pub n_pt: u16,
30    /// Stored Curve Count
31    ///
32    /// Number of stored curves supported.
33    pub n_crv_set: u16,
34    /// Frequency Scale Factor
35    ///
36    /// Scale factor for curve frequency points.
37    pub hz_sf: i16,
38    /// Time Point Scale Factor
39    ///
40    /// Scale factor for curve time points.
41    pub tms_sf: i16,
42    /// Stored Curves
43    ///
44    /// Stored curve sets.
45    ///
46    /// Comments: Stored curve sets - Number of curve sets contained in NCrvSet - The first set is read-only and indicates the current settings.
47    pub crv: Vec<Crv>,
48}
49#[allow(missing_docs)]
50impl DerTripLf {
51    pub const ENA: crate::Point<Self, Ena> = crate::Point::new(0, 1, true);
52    pub const ADPT_CRV_REQ: crate::Point<Self, u16> = crate::Point::new(1, 1, true);
53    pub const ADPT_CRV_RSLT: crate::Point<Self, AdptCrvRslt> = crate::Point::new(2, 1, false);
54    pub const N_PT: crate::Point<Self, u16> = crate::Point::new(3, 1, false);
55    pub const N_CRV_SET: crate::Point<Self, u16> = crate::Point::new(4, 1, false);
56    pub const HZ_SF: crate::Point<Self, i16> = crate::Point::new(5, 1, false);
57    pub const TMS_SF: crate::Point<Self, i16> = crate::Point::new(6, 1, false);
58}
59impl crate::Group for DerTripLf {
60    const LEN: u16 = 7;
61}
62impl DerTripLf {
63    fn parse_group(data: &[u16]) -> Result<(&[u16], Self), crate::DecodeError> {
64        let nested_data = data
65            .get(usize::from(<Self as crate::Group>::LEN)..)
66            .unwrap_or(&[]);
67        let counts = Counts {
68            n_pt: Self::N_PT.from_data(data)?,
69            n_crv_set: Self::N_CRV_SET.from_data(data)?,
70        };
71        let (nested_data, crv) = Crv::parse_multiple(nested_data, &counts)?;
72        Ok((
73            nested_data,
74            Self {
75                ena: Self::ENA.from_data(data)?,
76                adpt_crv_req: Self::ADPT_CRV_REQ.from_data(data)?,
77                adpt_crv_rslt: Self::ADPT_CRV_RSLT.from_data(data)?,
78                n_pt: Self::N_PT.from_data(data)?,
79                n_crv_set: Self::N_CRV_SET.from_data(data)?,
80                hz_sf: Self::HZ_SF.from_data(data)?,
81                tms_sf: Self::TMS_SF.from_data(data)?,
82                crv,
83            },
84        ))
85    }
86}
87/// DER Trip LF Module Enable
88///
89/// DER low frequency trip control enable.
90#[derive(Copy, Clone, Debug, Eq, PartialEq)]
91#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
92pub enum Ena {
93    /// Disabled
94    ///
95    /// Function is disabled.
96    Disabled,
97    /// Enabled
98    ///
99    /// Function is enabled.
100    Enabled,
101    /// Raw enum value not defined by the SunSpec model.
102    Invalid(u16),
103}
104impl crate::EnumValue for Ena {
105    type Repr = u16;
106    const INVALID: Self::Repr = 65535;
107    fn from_repr(value: Self::Repr) -> Self {
108        match value {
109            0 => Self::Disabled,
110            1 => Self::Enabled,
111            value => Self::Invalid(value),
112        }
113    }
114    fn to_repr(self) -> Self::Repr {
115        match self {
116            Self::Disabled => 0,
117            Self::Enabled => 1,
118            Self::Invalid(value) => value,
119        }
120    }
121}
122impl crate::FixedSize for Ena {
123    const SIZE: u16 = 1u16;
124    const INVALID: Self = Self::Invalid(65535);
125    fn is_invalid(&self) -> bool {
126        matches!(self, Self::Invalid(_))
127    }
128}
129/// Adopt Curve Result
130///
131/// Result of last adopt curve operation.
132#[derive(Copy, Clone, Debug, Eq, PartialEq)]
133#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
134pub enum AdptCrvRslt {
135    /// Update In Progress
136    ///
137    /// Curve update in progress.
138    InProgress,
139    /// Update Complete
140    ///
141    /// Curve update completed successfully.
142    Completed,
143    /// Update Failed
144    ///
145    /// Curve update failed.
146    Failed,
147    /// Raw enum value not defined by the SunSpec model.
148    Invalid(u16),
149}
150impl crate::EnumValue for AdptCrvRslt {
151    type Repr = u16;
152    const INVALID: Self::Repr = 65535;
153    fn from_repr(value: Self::Repr) -> Self {
154        match value {
155            0 => Self::InProgress,
156            1 => Self::Completed,
157            2 => Self::Failed,
158            value => Self::Invalid(value),
159        }
160    }
161    fn to_repr(self) -> Self::Repr {
162        match self {
163            Self::InProgress => 0,
164            Self::Completed => 1,
165            Self::Failed => 2,
166            Self::Invalid(value) => value,
167        }
168    }
169}
170impl crate::FixedSize for AdptCrvRslt {
171    const SIZE: u16 = 1u16;
172    const INVALID: Self = Self::Invalid(65535);
173    fn is_invalid(&self) -> bool {
174        matches!(self, Self::Invalid(_))
175    }
176}
177/// Stored Curves
178///
179/// Stored curve sets.
180///
181/// Comments: Stored curve sets - Number of curve sets contained in NCrvSet - The first set is read-only and indicates the current settings.
182#[derive(Debug)]
183#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
184pub struct Crv {
185    /// Curve Access
186    ///
187    /// Curve read-write access.
188    pub read_only: CrvReadOnly,
189    /// Must Trip Curve
190    ///
191    /// Stored must trip curve.
192    ///
193    /// Comments: Stored curve set containing a Must Trip, May Trip, and Momentary Cessation Curve - Number of curve points contained in NPt
194    pub must_trip: MustTrip,
195    /// May Trip Curve
196    ///
197    /// Stored may trip curve.
198    pub may_trip: MayTrip,
199    /// Momentary Cessation Curve
200    ///
201    /// Stored momentary cessation curve.
202    pub mom_cess: MomCess,
203}
204#[allow(missing_docs)]
205impl Crv {
206    pub const READ_ONLY: crate::Point<Self, CrvReadOnly> = crate::Point::new(0, 1, false);
207}
208impl crate::Group for Crv {
209    const LEN: u16 = 1;
210}
211impl Crv {
212    fn parse_group<'a>(
213        data: &'a [u16],
214        counts: &Counts,
215    ) -> Result<(&'a [u16], Self), crate::DecodeError> {
216        let nested_data = data
217            .get(usize::from(<Self as crate::Group>::LEN)..)
218            .unwrap_or(&[]);
219        let (nested_data, must_trip) = MustTrip::parse_group(nested_data, counts)?;
220        let (nested_data, may_trip) = MayTrip::parse_group(nested_data, counts)?;
221        let (nested_data, mom_cess) = MomCess::parse_group(nested_data, counts)?;
222        Ok((
223            nested_data,
224            Self {
225                read_only: Self::READ_ONLY.from_data(data)?,
226                must_trip,
227                may_trip,
228                mom_cess,
229            },
230        ))
231    }
232    fn parse_multiple<'a>(
233        data: &'a [u16],
234        counts: &Counts,
235    ) -> Result<(&'a [u16], Vec<Self>), crate::DecodeError> {
236        let (data, groups) =
237            (0..counts.n_crv_set).try_fold((data, Vec::new()), |(data, mut groups), _| {
238                let (data, group) = Crv::parse_group(data, counts)?;
239                groups.push(group);
240                Ok::<_, crate::DecodeError>((data, groups))
241            })?;
242        Ok((data, groups))
243    }
244}
245/// Curve Access
246///
247/// Curve read-write access.
248#[derive(Copy, Clone, Debug, Eq, PartialEq)]
249#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
250pub enum CrvReadOnly {
251    /// Read-Write Access
252    ///
253    /// Curve has read-write access.
254    Rw,
255    /// Read-Only Access
256    ///
257    /// Curve has read-only access.
258    R,
259    /// Raw enum value not defined by the SunSpec model.
260    Invalid(u16),
261}
262impl crate::EnumValue for CrvReadOnly {
263    type Repr = u16;
264    const INVALID: Self::Repr = 65535;
265    fn from_repr(value: Self::Repr) -> Self {
266        match value {
267            0 => Self::Rw,
268            1 => Self::R,
269            value => Self::Invalid(value),
270        }
271    }
272    fn to_repr(self) -> Self::Repr {
273        match self {
274            Self::Rw => 0,
275            Self::R => 1,
276            Self::Invalid(value) => value,
277        }
278    }
279}
280impl crate::FixedSize for CrvReadOnly {
281    const SIZE: u16 = 1u16;
282    const INVALID: Self = Self::Invalid(65535);
283    fn is_invalid(&self) -> bool {
284        matches!(self, Self::Invalid(_))
285    }
286}
287/// Must Trip Curve
288///
289/// Stored must trip curve.
290///
291/// Comments: Stored curve set containing a Must Trip, May Trip, and Momentary Cessation Curve - Number of curve points contained in NPt
292#[derive(Debug)]
293#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
294pub struct MustTrip {
295    /// Number Of Active Points
296    ///
297    /// Number of active points in must trip curve.
298    pub act_pt: Option<u16>,
299    /// Must Trip Curve Points
300    ///
301    /// Must trip curve points.
302    pub pt: Vec<Pt>,
303}
304#[allow(missing_docs)]
305impl MustTrip {
306    pub const ACT_PT: crate::Point<Self, Option<u16>> = crate::Point::new(0, 1, true);
307}
308impl crate::Group for MustTrip {
309    const LEN: u16 = 1;
310}
311impl MustTrip {
312    fn parse_group<'a>(
313        data: &'a [u16],
314        counts: &Counts,
315    ) -> Result<(&'a [u16], Self), crate::DecodeError> {
316        let nested_data = data
317            .get(usize::from(<Self as crate::Group>::LEN)..)
318            .unwrap_or(&[]);
319        let (nested_data, pt) = Pt::parse_multiple(nested_data, counts)?;
320        Ok((
321            nested_data,
322            Self {
323                act_pt: Self::ACT_PT.from_data(data)?,
324                pt,
325            },
326        ))
327    }
328}
329/// Must Trip Curve Points
330///
331/// Must trip curve points.
332#[derive(Debug)]
333#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
334pub struct Pt {
335    /// Frequency Point
336    ///
337    /// Curve frequency point.
338    ///
339    /// Detail: Internal curve conformance checks should be conducted when AdptCrvReq is set to 1, not on point writes.
340    pub hz: Option<u32>,
341    /// Time Point
342    ///
343    /// Curve time point in seconds.
344    ///
345    /// Detail: Internal curve conformance checks should be conducted when AdptCrvReq is set to 1, not on point writes.
346    pub tms: Option<u32>,
347}
348#[allow(missing_docs)]
349impl Pt {
350    pub const HZ: crate::Point<Self, Option<u32>> = crate::Point::new(0, 2, true);
351    pub const TMS: crate::Point<Self, Option<u32>> = crate::Point::new(2, 2, true);
352}
353impl crate::Group for Pt {
354    const LEN: u16 = 4;
355}
356impl Pt {
357    fn parse_group(data: &[u16]) -> Result<(&[u16], Self), crate::DecodeError> {
358        let nested_data = data
359            .get(usize::from(<Self as crate::Group>::LEN)..)
360            .unwrap_or(&[]);
361        Ok((
362            nested_data,
363            Self {
364                hz: Self::HZ.from_data(data)?,
365                tms: Self::TMS.from_data(data)?,
366            },
367        ))
368    }
369    fn parse_multiple<'a>(
370        data: &'a [u16],
371        counts: &Counts,
372    ) -> Result<(&'a [u16], Vec<Self>), crate::DecodeError> {
373        let (data, groups) =
374            (0..counts.n_pt).try_fold((data, Vec::new()), |(data, mut groups), _| {
375                let (data, group) = Pt::parse_group(data)?;
376                groups.push(group);
377                Ok::<_, crate::DecodeError>((data, groups))
378            })?;
379        Ok((data, groups))
380    }
381}
382/// May Trip Curve
383///
384/// Stored may trip curve.
385#[derive(Debug)]
386#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
387pub struct MayTrip {
388    /// Number Of Active Points
389    ///
390    /// Number of active points in may trip curve.
391    pub act_pt: Option<u16>,
392    /// May Trip Curve Points
393    ///
394    /// May trip curve points.
395    pub pt: Vec<Pt>,
396}
397#[allow(missing_docs)]
398impl MayTrip {
399    pub const ACT_PT: crate::Point<Self, Option<u16>> = crate::Point::new(0, 1, true);
400}
401impl crate::Group for MayTrip {
402    const LEN: u16 = 1;
403}
404impl MayTrip {
405    fn parse_group<'a>(
406        data: &'a [u16],
407        counts: &Counts,
408    ) -> Result<(&'a [u16], Self), crate::DecodeError> {
409        let nested_data = data
410            .get(usize::from(<Self as crate::Group>::LEN)..)
411            .unwrap_or(&[]);
412        let (nested_data, pt) = Pt::parse_multiple(nested_data, counts)?;
413        Ok((
414            nested_data,
415            Self {
416                act_pt: Self::ACT_PT.from_data(data)?,
417                pt,
418            },
419        ))
420    }
421}
422/// Momentary Cessation Curve
423///
424/// Stored momentary cessation curve.
425#[derive(Debug)]
426#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
427pub struct MomCess {
428    /// Number Of Active Points
429    ///
430    /// Number of active points in the momentary cessation curve.
431    pub act_pt: Option<u16>,
432    /// Mom Cessation Curve Points
433    ///
434    /// Momentary cessation curve points.
435    pub pt: Vec<Pt>,
436}
437#[allow(missing_docs)]
438impl MomCess {
439    pub const ACT_PT: crate::Point<Self, Option<u16>> = crate::Point::new(0, 1, true);
440}
441impl crate::Group for MomCess {
442    const LEN: u16 = 1;
443}
444impl MomCess {
445    fn parse_group<'a>(
446        data: &'a [u16],
447        counts: &Counts,
448    ) -> Result<(&'a [u16], Self), crate::DecodeError> {
449        let nested_data = data
450            .get(usize::from(<Self as crate::Group>::LEN)..)
451            .unwrap_or(&[]);
452        let (nested_data, pt) = Pt::parse_multiple(nested_data, counts)?;
453        Ok((
454            nested_data,
455            Self {
456                act_pt: Self::ACT_PT.from_data(data)?,
457                pt,
458            },
459        ))
460    }
461}
462impl crate::Model for DerTripLf {
463    const ID: u16 = 709;
464    fn addr(models: &crate::Models) -> crate::ModelAddr<Self> {
465        models.m709
466    }
467    fn parse(data: &[u16]) -> Result<Self, crate::ParseError<Self>> {
468        let (_, model) = Self::parse_group(data)?;
469        Ok(model)
470    }
471}