sunspec 0.8.0

SunSpec 1.1 compliant library with tokio support
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
//! DER Capacity
/// DER Capacity
///
/// DER capacity model.
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
pub struct Model702 {
    /// Active Power Max Rating
    ///
    /// Maximum active power rating at unity power factor in watts.
    ///
    /// Comments: Nameplate Ratings - Specifies capacity ratings
    pub w_max_rtg: Option<u16>,
    /// Active Power (Over-Excited) Rating
    ///
    /// Active power rating at specified over-excited power factor in watts.
    pub w_ovr_ext_rtg: Option<u16>,
    /// Specified Over-Excited PF
    ///
    /// Specified over-excited power factor.
    pub w_ovr_ext_rtg_pf: Option<u16>,
    /// Active Power (Under-Excited) Rating
    ///
    /// Active power rating at specified under-excited power factor in watts.
    pub w_und_ext_rtg: Option<u16>,
    /// Specified Under-Excited PF
    ///
    /// Specified under-excited power factor.
    pub w_und_ext_rtg_pf: Option<u16>,
    /// Apparent Power Max Rating
    ///
    /// Maximum apparent power rating in voltamperes.
    pub va_max_rtg: Option<u16>,
    /// Reactive Power Injected Rating
    ///
    /// Maximum injected reactive power rating in vars.
    pub var_max_inj_rtg: Option<u16>,
    /// Reactive Power Absorbed Rating
    ///
    /// Maximum absorbed reactive power rating in vars.
    pub var_max_abs_rtg: Option<u16>,
    /// Charge Rate Max Rating
    ///
    /// Maximum active power charge rate in watts.
    pub w_cha_rte_max_rtg: Option<u16>,
    /// Discharge Rate Max Rating
    ///
    /// Maximum active power discharge rate in watts.
    pub w_dis_cha_rte_max_rtg: Option<u16>,
    /// Charge Rate Max VA Rating
    ///
    /// Maximum apparent power charge rate in voltamperes.
    pub va_cha_rte_max_rtg: Option<u16>,
    /// Discharge Rate Max VA Rating
    ///
    /// Maximum apparent power discharge rate in voltamperes.
    pub va_dis_cha_rte_max_rtg: Option<u16>,
    /// AC Voltage Nominal Rating
    ///
    /// AC voltage nominal rating.
    ///
    /// Detail: Voltages are LN for single phase DER (e.g. 120 V nominal), LL for split phase DER (e.g. 240 V nominal), and LL for three phase DER (e.g., 480 V nominal).
    pub v_nom_rtg: Option<u16>,
    /// AC Voltage Max Rating
    ///
    /// AC voltage maximum rating.
    ///
    /// Detail: Voltages are LN for single phase DER (e.g. 120 V nominal), LL for split phase DER (e.g. 240 V nominal), and LL for three phase DER (e.g., 480 V nominal).
    pub v_max_rtg: Option<u16>,
    /// AC Voltage Min Rating
    ///
    /// AC voltage minimum rating.
    ///
    /// Detail: Voltages are LN for single phase DER (e.g. 120 V nominal), LL for split phase DER (e.g. 240 V nominal), and LL for three phase DER (e.g., 480 V nominal).
    pub v_min_rtg: Option<u16>,
    /// AC Current Max Rating
    ///
    /// AC current maximum rating in amps.
    pub a_max_rtg: Option<u16>,
    /// PF Over-Excited Rating (Unused)
    ///
    /// Unused. Please use WOvrExtRtgPF.
    ///
    /// Detail: This point is duplicative of WOvrExtRtgPF.
    pub pf_ovr_ext_rtg: Option<u16>,
    /// PF Under-Excited Rating (Unused)
    ///
    /// Unused. Please use WUndExtRtgPF.
    ///
    /// Detail: This point is duplicative of WUndExtRtgPF.
    pub pf_und_ext_rtg: Option<u16>,
    /// Reactive Susceptance
    ///
    /// Reactive susceptance that remains connected to the Area EPS in the cease to energize and trip state.
    pub react_suscept_rtg: Option<u16>,
    /// Normal Operating Category
    ///
    /// Normal operating performance category as specified in IEEE 1547-2018.
    pub nor_op_cat_rtg: Option<NorOpCatRtg>,
    /// Abnormal Operating Category
    ///
    /// Abnormal operating performance category as specified in IEEE 1547-2018.
    pub abn_op_cat_rtg: Option<AbnOpCatRtg>,
    /// Supported Control Modes
    ///
    /// Supported control mode functions.
    pub ctrl_modes: Option<CtrlModes>,
    /// Intentional Island Categories
    ///
    /// Intentional island categories.
    pub int_island_cat_rtg: Option<IntIslandCatRtg>,
    /// Active Power Max Setting
    ///
    /// Maximum active power setting used to adjust maximum active power setting.
    ///
    /// Comments: Settings - Used to adjust nameplate ratings
    pub w_max: Option<u16>,
    /// Active Power (Over-Excited) Setting
    ///
    /// Active power setting at specified over-excited power factor in watts.
    pub w_max_ovr_ext: Option<u16>,
    /// Specified Over-Excited PF
    ///
    /// Specified over-excited power factor.
    pub w_ovr_ext_pf: Option<u16>,
    /// Active Power (Under-Excited) Setting
    ///
    /// Active power setting at specified under-excited power factor in watts.
    pub w_max_und_ext: Option<u16>,
    /// Specified Under-Excited PF
    ///
    /// Specified under-excited power factor.
    pub w_und_ext_pf: Option<u16>,
    /// Apparent Power Max Setting
    ///
    /// Maximum apparent power setting used to adjust maximum apparent power rating.
    pub va_max: Option<u16>,
    /// Reactive Power Injected Setting
    ///
    /// Maximum injected reactive power setting used to adjust maximum injected reactive power rating.
    pub var_max_inj: Option<u16>,
    /// Reactive Power Absorbed Setting
    ///
    /// Maximum absorbed reactive power setting used to adjust maximum absorbed reactive power rating.
    pub var_max_abs: Option<u16>,
    /// Charge Rate Max Setting
    ///
    /// Maximum active power charge rate setting used to adjust maximum active power charge rate rating.
    pub w_cha_rte_max: Option<u16>,
    /// Discharge Rate Max Setting
    ///
    /// Maximum active power discharge rate setting used to adjust maximum active power discharge rate rating.
    pub w_dis_cha_rte_max: Option<u16>,
    /// Charge Rate Max VA Setting
    ///
    /// Maximum apparent power charge rate setting used to adjust maximum apparent power charge rate rating.
    pub va_cha_rte_max: Option<u16>,
    /// Discharge Rate Max VA Setting
    ///
    /// Maximum apparent power discharge rate setting used to adjust maximum apparent power discharge rate rating.
    pub va_dis_cha_rte_max: Option<u16>,
    /// Nominal AC Voltage Setting
    ///
    /// Nominal AC voltage setting.
    ///
    /// Detail: Voltages are LN for single phase DER (e.g. 120 V nominal), LL for split phase DER (e.g. 240 V nominal), and LL for three phase DER (e.g., 480 V nominal).
    pub v_nom: Option<u16>,
    /// AC Voltage Max Setting
    ///
    /// AC voltage maximum setting used to adjust AC voltage maximum rating.
    ///
    /// Detail: Voltages are LN for single phase DER (e.g. 120 V nominal), LL for split phase DER (e.g. 240 V nominal), and LL for three phase DER (e.g., 480 V nominal).
    pub v_max: Option<u16>,
    /// AC Voltage Min Setting
    ///
    /// AC voltage minimum setting used to adjust AC voltage minimum rating.
    ///
    /// Detail: Voltages are LN for single phase DER (e.g. 120 V nominal), LL for split phase DER (e.g. 240 V nominal), and LL for three phase DER (e.g., 480 V nominal).
    pub v_min: Option<u16>,
    /// AC Current Max Setting
    ///
    /// Maximum AC current setting used to adjust maximum AC current rating.
    pub a_max: Option<u16>,
    /// PF Over-Excited Setting (Unused)
    ///
    /// Unused. Please use WOvrExtPF.
    ///
    /// Detail: This point is duplicative of WOvrExtPF.
    pub pf_ovr_ext: Option<u16>,
    /// PF Under-Excited Setting (Unused)
    ///
    /// Unused. Please use WUndExtPF.
    ///
    /// Detail: This point is duplicative of WUndExtPF.
    pub pf_und_ext: Option<u16>,
    /// Intentional Island Categories
    ///
    /// Intentional island categories.
    pub int_island_cat: Option<IntIslandCat>,
    /// Active Power Scale Factor
    ///
    /// Active power scale factor.
    ///
    /// Comments: Scale Factors
    pub w_sf: Option<i16>,
    /// Power Factor Scale Factor
    ///
    /// Power factor scale factor.
    pub pf_sf: Option<i16>,
    /// Apparent Power Scale Factor
    ///
    /// Apparent power scale factor.
    pub va_sf: Option<i16>,
    /// Reactive Power Scale Factor
    ///
    /// Reactive power scale factor.
    pub var_sf: Option<i16>,
    /// Voltage Scale Factor
    ///
    /// Voltage scale factor.
    pub v_sf: Option<i16>,
    /// Current Scale Factor
    ///
    /// Current scale factor.
    pub a_sf: Option<i16>,
    /// Susceptance Scale Factor
    ///
    /// Susceptance scale factor.
    pub s_sf: Option<i16>,
}
#[allow(missing_docs)]
impl Model702 {
    pub const W_MAX_RTG: crate::Point<Self, Option<u16>> = crate::Point::new(0, 1, false);
    pub const W_OVR_EXT_RTG: crate::Point<Self, Option<u16>> = crate::Point::new(1, 1, false);
    pub const W_OVR_EXT_RTG_PF: crate::Point<Self, Option<u16>> = crate::Point::new(2, 1, false);
    pub const W_UND_EXT_RTG: crate::Point<Self, Option<u16>> = crate::Point::new(3, 1, false);
    pub const W_UND_EXT_RTG_PF: crate::Point<Self, Option<u16>> = crate::Point::new(4, 1, false);
    pub const VA_MAX_RTG: crate::Point<Self, Option<u16>> = crate::Point::new(5, 1, false);
    pub const VAR_MAX_INJ_RTG: crate::Point<Self, Option<u16>> = crate::Point::new(6, 1, false);
    pub const VAR_MAX_ABS_RTG: crate::Point<Self, Option<u16>> = crate::Point::new(7, 1, false);
    pub const W_CHA_RTE_MAX_RTG: crate::Point<Self, Option<u16>> = crate::Point::new(8, 1, false);
    pub const W_DIS_CHA_RTE_MAX_RTG: crate::Point<Self, Option<u16>> =
        crate::Point::new(9, 1, false);
    pub const VA_CHA_RTE_MAX_RTG: crate::Point<Self, Option<u16>> = crate::Point::new(10, 1, false);
    pub const VA_DIS_CHA_RTE_MAX_RTG: crate::Point<Self, Option<u16>> =
        crate::Point::new(11, 1, false);
    pub const V_NOM_RTG: crate::Point<Self, Option<u16>> = crate::Point::new(12, 1, false);
    pub const V_MAX_RTG: crate::Point<Self, Option<u16>> = crate::Point::new(13, 1, false);
    pub const V_MIN_RTG: crate::Point<Self, Option<u16>> = crate::Point::new(14, 1, false);
    pub const A_MAX_RTG: crate::Point<Self, Option<u16>> = crate::Point::new(15, 1, false);
    pub const PF_OVR_EXT_RTG: crate::Point<Self, Option<u16>> = crate::Point::new(16, 1, false);
    pub const PF_UND_EXT_RTG: crate::Point<Self, Option<u16>> = crate::Point::new(17, 1, false);
    pub const REACT_SUSCEPT_RTG: crate::Point<Self, Option<u16>> = crate::Point::new(18, 1, false);
    pub const NOR_OP_CAT_RTG: crate::Point<Self, Option<NorOpCatRtg>> =
        crate::Point::new(19, 1, false);
    pub const ABN_OP_CAT_RTG: crate::Point<Self, Option<AbnOpCatRtg>> =
        crate::Point::new(20, 1, false);
    pub const CTRL_MODES: crate::Point<Self, Option<CtrlModes>> = crate::Point::new(21, 2, false);
    pub const INT_ISLAND_CAT_RTG: crate::Point<Self, Option<IntIslandCatRtg>> =
        crate::Point::new(23, 1, false);
    pub const W_MAX: crate::Point<Self, Option<u16>> = crate::Point::new(24, 1, true);
    pub const W_MAX_OVR_EXT: crate::Point<Self, Option<u16>> = crate::Point::new(25, 1, true);
    pub const W_OVR_EXT_PF: crate::Point<Self, Option<u16>> = crate::Point::new(26, 1, true);
    pub const W_MAX_UND_EXT: crate::Point<Self, Option<u16>> = crate::Point::new(27, 1, true);
    pub const W_UND_EXT_PF: crate::Point<Self, Option<u16>> = crate::Point::new(28, 1, true);
    pub const VA_MAX: crate::Point<Self, Option<u16>> = crate::Point::new(29, 1, true);
    pub const VAR_MAX_INJ: crate::Point<Self, Option<u16>> = crate::Point::new(30, 1, true);
    pub const VAR_MAX_ABS: crate::Point<Self, Option<u16>> = crate::Point::new(31, 1, true);
    pub const W_CHA_RTE_MAX: crate::Point<Self, Option<u16>> = crate::Point::new(32, 1, true);
    pub const W_DIS_CHA_RTE_MAX: crate::Point<Self, Option<u16>> = crate::Point::new(33, 1, true);
    pub const VA_CHA_RTE_MAX: crate::Point<Self, Option<u16>> = crate::Point::new(34, 1, true);
    pub const VA_DIS_CHA_RTE_MAX: crate::Point<Self, Option<u16>> = crate::Point::new(35, 1, true);
    pub const V_NOM: crate::Point<Self, Option<u16>> = crate::Point::new(36, 1, true);
    pub const V_MAX: crate::Point<Self, Option<u16>> = crate::Point::new(37, 1, true);
    pub const V_MIN: crate::Point<Self, Option<u16>> = crate::Point::new(38, 1, true);
    pub const A_MAX: crate::Point<Self, Option<u16>> = crate::Point::new(39, 1, true);
    pub const PF_OVR_EXT: crate::Point<Self, Option<u16>> = crate::Point::new(40, 1, true);
    pub const PF_UND_EXT: crate::Point<Self, Option<u16>> = crate::Point::new(41, 1, true);
    pub const INT_ISLAND_CAT: crate::Point<Self, Option<IntIslandCat>> =
        crate::Point::new(42, 1, true);
    pub const W_SF: crate::Point<Self, Option<i16>> = crate::Point::new(43, 1, false);
    pub const PF_SF: crate::Point<Self, Option<i16>> = crate::Point::new(44, 1, false);
    pub const VA_SF: crate::Point<Self, Option<i16>> = crate::Point::new(45, 1, false);
    pub const VAR_SF: crate::Point<Self, Option<i16>> = crate::Point::new(46, 1, false);
    pub const V_SF: crate::Point<Self, Option<i16>> = crate::Point::new(47, 1, false);
    pub const A_SF: crate::Point<Self, Option<i16>> = crate::Point::new(48, 1, false);
    pub const S_SF: crate::Point<Self, Option<i16>> = crate::Point::new(49, 1, false);
}
impl crate::Model for Model702 {
    const ID: u16 = 702;
    fn from_data(data: &[u16]) -> Result<Self, crate::DecodeError> {
        Ok(Self {
            w_max_rtg: Self::W_MAX_RTG.from_data(data)?,
            w_ovr_ext_rtg: Self::W_OVR_EXT_RTG.from_data(data)?,
            w_ovr_ext_rtg_pf: Self::W_OVR_EXT_RTG_PF.from_data(data)?,
            w_und_ext_rtg: Self::W_UND_EXT_RTG.from_data(data)?,
            w_und_ext_rtg_pf: Self::W_UND_EXT_RTG_PF.from_data(data)?,
            va_max_rtg: Self::VA_MAX_RTG.from_data(data)?,
            var_max_inj_rtg: Self::VAR_MAX_INJ_RTG.from_data(data)?,
            var_max_abs_rtg: Self::VAR_MAX_ABS_RTG.from_data(data)?,
            w_cha_rte_max_rtg: Self::W_CHA_RTE_MAX_RTG.from_data(data)?,
            w_dis_cha_rte_max_rtg: Self::W_DIS_CHA_RTE_MAX_RTG.from_data(data)?,
            va_cha_rte_max_rtg: Self::VA_CHA_RTE_MAX_RTG.from_data(data)?,
            va_dis_cha_rte_max_rtg: Self::VA_DIS_CHA_RTE_MAX_RTG.from_data(data)?,
            v_nom_rtg: Self::V_NOM_RTG.from_data(data)?,
            v_max_rtg: Self::V_MAX_RTG.from_data(data)?,
            v_min_rtg: Self::V_MIN_RTG.from_data(data)?,
            a_max_rtg: Self::A_MAX_RTG.from_data(data)?,
            pf_ovr_ext_rtg: Self::PF_OVR_EXT_RTG.from_data(data)?,
            pf_und_ext_rtg: Self::PF_UND_EXT_RTG.from_data(data)?,
            react_suscept_rtg: Self::REACT_SUSCEPT_RTG.from_data(data)?,
            nor_op_cat_rtg: Self::NOR_OP_CAT_RTG.from_data(data)?,
            abn_op_cat_rtg: Self::ABN_OP_CAT_RTG.from_data(data)?,
            ctrl_modes: Self::CTRL_MODES.from_data(data)?,
            int_island_cat_rtg: Self::INT_ISLAND_CAT_RTG.from_data(data)?,
            w_max: Self::W_MAX.from_data(data)?,
            w_max_ovr_ext: Self::W_MAX_OVR_EXT.from_data(data)?,
            w_ovr_ext_pf: Self::W_OVR_EXT_PF.from_data(data)?,
            w_max_und_ext: Self::W_MAX_UND_EXT.from_data(data)?,
            w_und_ext_pf: Self::W_UND_EXT_PF.from_data(data)?,
            va_max: Self::VA_MAX.from_data(data)?,
            var_max_inj: Self::VAR_MAX_INJ.from_data(data)?,
            var_max_abs: Self::VAR_MAX_ABS.from_data(data)?,
            w_cha_rte_max: Self::W_CHA_RTE_MAX.from_data(data)?,
            w_dis_cha_rte_max: Self::W_DIS_CHA_RTE_MAX.from_data(data)?,
            va_cha_rte_max: Self::VA_CHA_RTE_MAX.from_data(data)?,
            va_dis_cha_rte_max: Self::VA_DIS_CHA_RTE_MAX.from_data(data)?,
            v_nom: Self::V_NOM.from_data(data)?,
            v_max: Self::V_MAX.from_data(data)?,
            v_min: Self::V_MIN.from_data(data)?,
            a_max: Self::A_MAX.from_data(data)?,
            pf_ovr_ext: Self::PF_OVR_EXT.from_data(data)?,
            pf_und_ext: Self::PF_UND_EXT.from_data(data)?,
            int_island_cat: Self::INT_ISLAND_CAT.from_data(data)?,
            w_sf: Self::W_SF.from_data(data)?,
            pf_sf: Self::PF_SF.from_data(data)?,
            va_sf: Self::VA_SF.from_data(data)?,
            var_sf: Self::VAR_SF.from_data(data)?,
            v_sf: Self::V_SF.from_data(data)?,
            a_sf: Self::A_SF.from_data(data)?,
            s_sf: Self::S_SF.from_data(data)?,
        })
    }
    fn addr(models: &crate::Models) -> crate::ModelAddr<Self> {
        models.m702
    }
}
/// Normal Operating Category
///
/// Normal operating performance category as specified in IEEE 1547-2018.
#[derive(Copy, Clone, Debug, Eq, PartialEq, strum::FromRepr)]
#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
#[repr(u16)]
pub enum NorOpCatRtg {
    /// Category A
    CatA = 0,
    /// Category B
    CatB = 1,
}
impl crate::Value for NorOpCatRtg {
    fn decode(data: &[u16]) -> Result<Self, crate::DecodeError> {
        let value = u16::decode(data)?;
        Self::from_repr(value).ok_or(crate::DecodeError::InvalidEnumValue)
    }
    fn encode(self) -> Box<[u16]> {
        (self as u16).encode()
    }
}
impl crate::Value for Option<NorOpCatRtg> {
    fn decode(data: &[u16]) -> Result<Self, crate::DecodeError> {
        let value = u16::decode(data)?;
        if value != 65535 {
            Ok(Some(
                NorOpCatRtg::from_repr(value).ok_or(crate::DecodeError::InvalidEnumValue)?,
            ))
        } else {
            Ok(None)
        }
    }
    fn encode(self) -> Box<[u16]> {
        if let Some(value) = self {
            value.encode()
        } else {
            65535.encode()
        }
    }
}
/// Abnormal Operating Category
///
/// Abnormal operating performance category as specified in IEEE 1547-2018.
#[derive(Copy, Clone, Debug, Eq, PartialEq, strum::FromRepr)]
#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
#[repr(u16)]
pub enum AbnOpCatRtg {
    /// Category I
    Cat1 = 0,
    /// Category II
    Cat2 = 1,
    /// Category III
    Cat3 = 2,
}
impl crate::Value for AbnOpCatRtg {
    fn decode(data: &[u16]) -> Result<Self, crate::DecodeError> {
        let value = u16::decode(data)?;
        Self::from_repr(value).ok_or(crate::DecodeError::InvalidEnumValue)
    }
    fn encode(self) -> Box<[u16]> {
        (self as u16).encode()
    }
}
impl crate::Value for Option<AbnOpCatRtg> {
    fn decode(data: &[u16]) -> Result<Self, crate::DecodeError> {
        let value = u16::decode(data)?;
        if value != 65535 {
            Ok(Some(
                AbnOpCatRtg::from_repr(value).ok_or(crate::DecodeError::InvalidEnumValue)?,
            ))
        } else {
            Ok(None)
        }
    }
    fn encode(self) -> Box<[u16]> {
        if let Some(value) = self {
            value.encode()
        } else {
            65535.encode()
        }
    }
}
bitflags::bitflags! {
    #[doc = " Supported Control Modes"] #[doc = " "] #[doc =
    " Supported control mode functions."] #[derive(Copy, Clone, Debug, Eq, PartialEq)]
    #[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))] pub
    struct CtrlModes : u32 { #[doc = " Limit Maximum Active Power"] const MaxW = 1; #[doc
    = " Fixed Active Power"] const FixedW = 2; #[doc = " Fixed Reactive Power"] const
    FixedVar = 4; #[doc = " Fixed Power Factor"] const FixedPf = 8; #[doc =
    " Volt-Var Function"] const VoltVar = 16; #[doc = " Freq-Watt Function"] const
    FreqWatt = 32; #[doc = " Dynamic Reactive Current Function"] const DynReactCurr = 64;
    #[doc = " Low-Voltage Trip"] const LvTrip = 128; #[doc = " High-Voltage Trip"] const
    HvTrip = 256; #[doc = " Watt-Var Function"] const WattVar = 512; #[doc =
    " Volt-Watt Function"] const VoltWatt = 1024; #[doc = " Scheduling"] const Scheduled
    = 2048; #[doc = " Low-Frequency Trip"] const LfTrip = 4096; #[doc =
    " High-Frequency Trip"] const HfTrip = 8192; }
}
impl crate::Value for CtrlModes {
    fn decode(data: &[u16]) -> Result<Self, crate::DecodeError> {
        let value = u32::decode(data)?;
        Ok(Self::from_bits_retain(value))
    }
    fn encode(self) -> Box<[u16]> {
        self.bits().encode()
    }
}
impl crate::Value for Option<CtrlModes> {
    fn decode(data: &[u16]) -> Result<Self, crate::DecodeError> {
        let value = u32::decode(data)?;
        if value != 4294967295u32 {
            Ok(Some(CtrlModes::from_bits_retain(value)))
        } else {
            Ok(None)
        }
    }
    fn encode(self) -> Box<[u16]> {
        if let Some(value) = self {
            value.encode()
        } else {
            4294967295u32.encode()
        }
    }
}
bitflags::bitflags! {
    #[doc = " Intentional Island Categories"] #[doc = " "] #[doc =
    " Intentional island categories."] #[derive(Copy, Clone, Debug, Eq, PartialEq)]
    #[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))] pub
    struct IntIslandCatRtg : u16 { #[doc = " Uncategorized"] const Uncategorized = 1;
    #[doc = " Intentional Island-Capable"] const IntIslCapable = 2; #[doc =
    " Black Start-Capable"] const BlackStartCapable = 4; #[doc = " Isochronous-Capable"]
    const IsochCapable = 8; }
}
impl crate::Value for IntIslandCatRtg {
    fn decode(data: &[u16]) -> Result<Self, crate::DecodeError> {
        let value = u16::decode(data)?;
        Ok(Self::from_bits_retain(value))
    }
    fn encode(self) -> Box<[u16]> {
        self.bits().encode()
    }
}
impl crate::Value for Option<IntIslandCatRtg> {
    fn decode(data: &[u16]) -> Result<Self, crate::DecodeError> {
        let value = u16::decode(data)?;
        if value != 65535u16 {
            Ok(Some(IntIslandCatRtg::from_bits_retain(value)))
        } else {
            Ok(None)
        }
    }
    fn encode(self) -> Box<[u16]> {
        if let Some(value) = self {
            value.encode()
        } else {
            65535u16.encode()
        }
    }
}
bitflags::bitflags! {
    #[doc = " Intentional Island Categories"] #[doc = " "] #[doc =
    " Intentional island categories."] #[derive(Copy, Clone, Debug, Eq, PartialEq)]
    #[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))] pub
    struct IntIslandCat : u16 { #[doc = " Uncategorized"] const Uncategorized = 1; #[doc
    = " Intentional Island-Capable"] const IntIslCapable = 2; #[doc =
    " Black Start-Capable"] const BlackStartCapable = 4; #[doc = " Isochronous-Capable"]
    const IsochCapable = 8; }
}
impl crate::Value for IntIslandCat {
    fn decode(data: &[u16]) -> Result<Self, crate::DecodeError> {
        let value = u16::decode(data)?;
        Ok(Self::from_bits_retain(value))
    }
    fn encode(self) -> Box<[u16]> {
        self.bits().encode()
    }
}
impl crate::Value for Option<IntIslandCat> {
    fn decode(data: &[u16]) -> Result<Self, crate::DecodeError> {
        let value = u16::decode(data)?;
        if value != 65535u16 {
            Ok(Some(IntIslandCat::from_bits_retain(value)))
        } else {
            Ok(None)
        }
    }
    fn encode(self) -> Box<[u16]> {
        if let Some(value) = self {
            value.encode()
        } else {
            65535u16.encode()
        }
    }
}