1pub type Model804 = LithiumIonString;
4struct Counts {
5 n_mod: u16,
6}
7#[derive(Debug)]
9#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
10pub struct LithiumIonString {
11 pub idx: u16,
17 pub n_mod: u16,
21 pub st: St,
25 pub con_fail: Option<ConFail>,
27 pub n_cell_bal: Option<u16>,
31 pub soc: u16,
37 pub do_d: Option<u16>,
43 pub n_cyc: Option<u32>,
47 pub soh: Option<u16>,
53 pub a: i16,
59 pub v: Option<u16>,
65 pub cell_v_max: u16,
71 pub cell_v_max_mod: Option<u16>,
75 pub cell_v_min: u16,
81 pub cell_v_min_mod: Option<u16>,
85 pub cell_v_avg: u16,
91 pub mod_tmp_max: i16,
97 pub mod_tmp_max_mod: u16,
101 pub mod_tmp_min: i16,
107 pub mod_tmp_min_mod: u16,
111 pub mod_tmp_avg: i16,
117 pub con_st: Option<ConSt>,
121 pub evt1: Evt1,
125 pub evt2: Option<Evt2>,
131 pub evt_vnd1: Option<EvtVnd1>,
135 pub evt_vnd2: Option<EvtVnd2>,
139 pub set_ena: Option<u16>,
143 pub set_con: Option<SetCon>,
149 pub soc_sf: i16,
151 pub soh_sf: Option<i16>,
153 pub do_d_sf: Option<i16>,
155 pub a_sf: i16,
157 pub v_sf: Option<i16>,
159 pub cell_v_sf: i16,
161 pub mod_tmp_sf: i16,
163 #[allow(missing_docs)]
164 pub lithium_ion_string_module: Vec<LithiumIonStringModule>,
165}
166#[allow(missing_docs)]
167impl LithiumIonString {
168 pub const IDX: crate::Point<Self, u16> = crate::Point::new(0, 1, false);
169 pub const N_MOD: crate::Point<Self, u16> = crate::Point::new(1, 1, false);
170 pub const ST: crate::Point<Self, St> = crate::Point::new(2, 2, false);
171 pub const CON_FAIL: crate::Point<Self, Option<ConFail>> = crate::Point::new(4, 1, false);
172 pub const N_CELL_BAL: crate::Point<Self, Option<u16>> = crate::Point::new(5, 1, false);
173 pub const SOC: crate::Point<Self, u16> = crate::Point::new(6, 1, false);
174 pub const DO_D: crate::Point<Self, Option<u16>> = crate::Point::new(7, 1, false);
175 pub const N_CYC: crate::Point<Self, Option<u32>> = crate::Point::new(8, 2, false);
176 pub const SOH: crate::Point<Self, Option<u16>> = crate::Point::new(10, 1, false);
177 pub const A: crate::Point<Self, i16> = crate::Point::new(11, 1, false);
178 pub const V: crate::Point<Self, Option<u16>> = crate::Point::new(12, 1, false);
179 pub const CELL_V_MAX: crate::Point<Self, u16> = crate::Point::new(13, 1, false);
180 pub const CELL_V_MAX_MOD: crate::Point<Self, Option<u16>> = crate::Point::new(14, 1, false);
181 pub const CELL_V_MIN: crate::Point<Self, u16> = crate::Point::new(15, 1, false);
182 pub const CELL_V_MIN_MOD: crate::Point<Self, Option<u16>> = crate::Point::new(16, 1, false);
183 pub const CELL_V_AVG: crate::Point<Self, u16> = crate::Point::new(17, 1, false);
184 pub const MOD_TMP_MAX: crate::Point<Self, i16> = crate::Point::new(18, 1, false);
185 pub const MOD_TMP_MAX_MOD: crate::Point<Self, u16> = crate::Point::new(19, 1, false);
186 pub const MOD_TMP_MIN: crate::Point<Self, i16> = crate::Point::new(20, 1, false);
187 pub const MOD_TMP_MIN_MOD: crate::Point<Self, u16> = crate::Point::new(21, 1, false);
188 pub const MOD_TMP_AVG: crate::Point<Self, i16> = crate::Point::new(22, 1, false);
189 pub const CON_ST: crate::Point<Self, Option<ConSt>> = crate::Point::new(24, 2, false);
190 pub const EVT1: crate::Point<Self, Evt1> = crate::Point::new(26, 2, false);
191 pub const EVT2: crate::Point<Self, Option<Evt2>> = crate::Point::new(28, 2, false);
192 pub const EVT_VND1: crate::Point<Self, Option<EvtVnd1>> = crate::Point::new(30, 2, false);
193 pub const EVT_VND2: crate::Point<Self, Option<EvtVnd2>> = crate::Point::new(32, 2, false);
194 pub const SET_ENA: crate::Point<Self, Option<u16>> = crate::Point::new(34, 1, true);
195 pub const SET_CON: crate::Point<Self, Option<SetCon>> = crate::Point::new(35, 1, true);
196 pub const SOC_SF: crate::Point<Self, i16> = crate::Point::new(36, 1, false);
197 pub const SOH_SF: crate::Point<Self, Option<i16>> = crate::Point::new(37, 1, false);
198 pub const DO_D_SF: crate::Point<Self, Option<i16>> = crate::Point::new(38, 1, false);
199 pub const A_SF: crate::Point<Self, i16> = crate::Point::new(39, 1, false);
200 pub const V_SF: crate::Point<Self, Option<i16>> = crate::Point::new(40, 1, false);
201 pub const CELL_V_SF: crate::Point<Self, i16> = crate::Point::new(41, 1, false);
202 pub const MOD_TMP_SF: crate::Point<Self, i16> = crate::Point::new(42, 1, false);
203}
204impl crate::Group for LithiumIonString {
205 const LEN: u16 = 46;
206}
207impl LithiumIonString {
208 fn parse_group(data: &[u16]) -> Result<(&[u16], Self), crate::DecodeError> {
209 let nested_data = data
210 .get(usize::from(<Self as crate::Group>::LEN)..)
211 .unwrap_or(&[]);
212 let counts = Counts {
213 n_mod: Self::N_MOD.from_data(data)?,
214 };
215 let (nested_data, lithium_ion_string_module) =
216 LithiumIonStringModule::parse_multiple(nested_data, &counts)?;
217 Ok((
218 nested_data,
219 Self {
220 idx: Self::IDX.from_data(data)?,
221 n_mod: Self::N_MOD.from_data(data)?,
222 st: Self::ST.from_data(data)?,
223 con_fail: Self::CON_FAIL.from_data(data)?,
224 n_cell_bal: Self::N_CELL_BAL.from_data(data)?,
225 soc: Self::SOC.from_data(data)?,
226 do_d: Self::DO_D.from_data(data)?,
227 n_cyc: Self::N_CYC.from_data(data)?,
228 soh: Self::SOH.from_data(data)?,
229 a: Self::A.from_data(data)?,
230 v: Self::V.from_data(data)?,
231 cell_v_max: Self::CELL_V_MAX.from_data(data)?,
232 cell_v_max_mod: Self::CELL_V_MAX_MOD.from_data(data)?,
233 cell_v_min: Self::CELL_V_MIN.from_data(data)?,
234 cell_v_min_mod: Self::CELL_V_MIN_MOD.from_data(data)?,
235 cell_v_avg: Self::CELL_V_AVG.from_data(data)?,
236 mod_tmp_max: Self::MOD_TMP_MAX.from_data(data)?,
237 mod_tmp_max_mod: Self::MOD_TMP_MAX_MOD.from_data(data)?,
238 mod_tmp_min: Self::MOD_TMP_MIN.from_data(data)?,
239 mod_tmp_min_mod: Self::MOD_TMP_MIN_MOD.from_data(data)?,
240 mod_tmp_avg: Self::MOD_TMP_AVG.from_data(data)?,
241 con_st: Self::CON_ST.from_data(data)?,
242 evt1: Self::EVT1.from_data(data)?,
243 evt2: Self::EVT2.from_data(data)?,
244 evt_vnd1: Self::EVT_VND1.from_data(data)?,
245 evt_vnd2: Self::EVT_VND2.from_data(data)?,
246 set_ena: Self::SET_ENA.from_data(data)?,
247 set_con: Self::SET_CON.from_data(data)?,
248 soc_sf: Self::SOC_SF.from_data(data)?,
249 soh_sf: Self::SOH_SF.from_data(data)?,
250 do_d_sf: Self::DO_D_SF.from_data(data)?,
251 a_sf: Self::A_SF.from_data(data)?,
252 v_sf: Self::V_SF.from_data(data)?,
253 cell_v_sf: Self::CELL_V_SF.from_data(data)?,
254 mod_tmp_sf: Self::MOD_TMP_SF.from_data(data)?,
255 lithium_ion_string_module,
256 },
257 ))
258 }
259}
260bitflags::bitflags! {
261 #[doc = " String Status"] #[doc = " "] #[doc = " Current status of the string."]
262 #[derive(Copy, Clone, Debug, Eq, PartialEq)] #[cfg_attr(feature = "serde",
263 derive(::serde::Serialize, ::serde::Deserialize))] pub struct St : u32 {
264 #[allow(missing_docs)] const StringEnabled = 1; #[doc =
265 " Detail: If string has multiple contactors, indicates that all contactors are closed."]
266 const ContactorStatus = 2; }
267}
268impl crate::Value for St {
269 fn decode(data: &[u16]) -> Result<Self, crate::DecodeError> {
270 let value = u32::decode(data)?;
271 Ok(Self::from_bits_retain(value))
272 }
273 fn encode(self) -> Box<[u16]> {
274 self.bits().encode()
275 }
276}
277impl crate::FixedSize for St {
278 const SIZE: u16 = 2u16;
279 const INVALID: Self = Self::from_bits_retain(4294967295u32);
280 fn is_invalid(&self) -> bool {
281 self.bits() == 4294967295u32
282 }
283}
284#[derive(Copy, Clone, Debug, Eq, PartialEq)]
286#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
287pub enum ConFail {
288 #[allow(missing_docs)]
289 NoFailure,
290 #[allow(missing_docs)]
291 ButtonPushed,
292 #[allow(missing_docs)]
293 StrGroundFault,
294 #[allow(missing_docs)]
295 OutsideVoltageRange,
296 #[allow(missing_docs)]
297 StringNotEnabled,
298 #[allow(missing_docs)]
299 FuseOpen,
300 #[allow(missing_docs)]
301 ContactorFailure,
302 #[allow(missing_docs)]
303 PrechargeFailure,
304 StringFault,
306 Invalid(u16),
308}
309impl crate::EnumValue for ConFail {
310 type Repr = u16;
311 const INVALID: Self::Repr = 65535;
312 fn from_repr(value: Self::Repr) -> Self {
313 match value {
314 0 => Self::NoFailure,
315 1 => Self::ButtonPushed,
316 2 => Self::StrGroundFault,
317 3 => Self::OutsideVoltageRange,
318 4 => Self::StringNotEnabled,
319 5 => Self::FuseOpen,
320 6 => Self::ContactorFailure,
321 7 => Self::PrechargeFailure,
322 8 => Self::StringFault,
323 value => Self::Invalid(value),
324 }
325 }
326 fn to_repr(self) -> Self::Repr {
327 match self {
328 Self::NoFailure => 0,
329 Self::ButtonPushed => 1,
330 Self::StrGroundFault => 2,
331 Self::OutsideVoltageRange => 3,
332 Self::StringNotEnabled => 4,
333 Self::FuseOpen => 5,
334 Self::ContactorFailure => 6,
335 Self::PrechargeFailure => 7,
336 Self::StringFault => 8,
337 Self::Invalid(value) => value,
338 }
339 }
340}
341impl crate::FixedSize for ConFail {
342 const SIZE: u16 = 1u16;
343 const INVALID: Self = Self::Invalid(65535);
344 fn is_invalid(&self) -> bool {
345 matches!(self, Self::Invalid(_))
346 }
347}
348bitflags::bitflags! {
349 #[doc = " Contactor Status"] #[doc = " "] #[doc =
350 " Status of the contactor(s) for the string."] #[derive(Copy, Clone, Debug, Eq,
351 PartialEq)] #[cfg_attr(feature = "serde", derive(::serde::Serialize,
352 ::serde::Deserialize))] pub struct ConSt : u32 { #[allow(missing_docs)] const
353 Contactor0 = 1; #[allow(missing_docs)] const Contactor1 = 2; #[allow(missing_docs)]
354 const Contactor2 = 4; #[allow(missing_docs)] const Contactor3 = 8;
355 #[allow(missing_docs)] const Contactor4 = 16; #[allow(missing_docs)] const Contactor5
356 = 32; #[allow(missing_docs)] const Contactor6 = 64; #[allow(missing_docs)] const
357 Contactor7 = 128; #[allow(missing_docs)] const Contactor8 = 256;
358 #[allow(missing_docs)] const Contactor9 = 512; #[allow(missing_docs)] const
359 Contactor10 = 1024; #[allow(missing_docs)] const Contactor11 = 2048;
360 #[allow(missing_docs)] const Contactor12 = 4096; #[allow(missing_docs)] const
361 Contactor13 = 8192; #[allow(missing_docs)] const Contactor14 = 16384;
362 #[allow(missing_docs)] const Contactor15 = 32768; #[allow(missing_docs)] const
363 Contactor16 = 65536; #[allow(missing_docs)] const Contactor17 = 131072;
364 #[allow(missing_docs)] const Contactor18 = 262144; #[allow(missing_docs)] const
365 Contactor19 = 524288; #[allow(missing_docs)] const Contactor20 = 1048576;
366 #[allow(missing_docs)] const Contactor21 = 2097152; #[allow(missing_docs)] const
367 Contactor22 = 4194304; #[allow(missing_docs)] const Contactor23 = 8388608;
368 #[allow(missing_docs)] const Contactor24 = 16777216; #[allow(missing_docs)] const
369 Contactor25 = 33554432; #[allow(missing_docs)] const Contactor26 = 67108864;
370 #[allow(missing_docs)] const Contactor27 = 134217728; #[allow(missing_docs)] const
371 Contactor28 = 268435456; #[allow(missing_docs)] const Contactor29 = 536870912;
372 #[allow(missing_docs)] const Contactor30 = 1073741824; }
373}
374impl crate::Value for ConSt {
375 fn decode(data: &[u16]) -> Result<Self, crate::DecodeError> {
376 let value = u32::decode(data)?;
377 Ok(Self::from_bits_retain(value))
378 }
379 fn encode(self) -> Box<[u16]> {
380 self.bits().encode()
381 }
382}
383impl crate::FixedSize for ConSt {
384 const SIZE: u16 = 2u16;
385 const INVALID: Self = Self::from_bits_retain(4294967295u32);
386 fn is_invalid(&self) -> bool {
387 self.bits() == 4294967295u32
388 }
389}
390bitflags::bitflags! {
391 #[doc = " String Event 1"] #[doc = " "] #[doc =
392 " Alarms, warnings and status values. Bit flags."] #[derive(Copy, Clone, Debug, Eq,
393 PartialEq)] #[cfg_attr(feature = "serde", derive(::serde::Serialize,
394 ::serde::Deserialize))] pub struct Evt1 : u32 { #[allow(missing_docs)] const
395 CommunicationError = 1; #[allow(missing_docs)] const OverTempAlarm = 2;
396 #[allow(missing_docs)] const OverTempWarning = 4; #[allow(missing_docs)] const
397 UnderTempAlarm = 8; #[allow(missing_docs)] const UnderTempWarning = 16; #[doc =
398 " Detail: See AChaMax in model S 802."] const OverChargeCurrentAlarm = 32; #[doc =
399 " Detail: See AChaMax in model S 802."] const OverChargeCurrentWarning = 64; #[doc =
400 " Detail: See ADisChaMax in model S 802."] const OverDischargeCurrentAlarm = 128;
401 #[doc = " Detail: See ADisChaMax in model S 802."] const OverDischargeCurrentWarning
402 = 256; #[allow(missing_docs)] const OverVoltAlarm = 512; #[allow(missing_docs)] const
403 OverVoltWarning = 1024; #[allow(missing_docs)] const UnderVoltAlarm = 2048;
404 #[allow(missing_docs)] const UnderVoltWarning = 4096; #[allow(missing_docs)] const
405 UnderSocMinAlarm = 8192; #[allow(missing_docs)] const UnderSocMinWarning = 16384;
406 #[allow(missing_docs)] const OverSocMaxAlarm = 32768; #[allow(missing_docs)] const
407 OverSocMaxWarning = 65536; #[allow(missing_docs)] const VoltageImbalanceWarning =
408 131072; #[allow(missing_docs)] const TemperatureImbalanceAlarm = 262144;
409 #[allow(missing_docs)] const TemperatureImbalanceWarning = 524288;
410 #[allow(missing_docs)] const ContactorError = 1048576; #[allow(missing_docs)] const
411 FanError = 2097152; #[allow(missing_docs)] const GroundFault = 4194304;
412 #[allow(missing_docs)] const OpenDoorError = 8388608; #[doc =
413 " Detail: Do not implement."] const Reserved1 = 16777216; #[doc =
414 " Detail: See EvtVnd1 and EvtVnd2 for more information."] const OtherAlarm =
415 33554432; #[doc = " Detail: See EvtVnd1 and EvtVnd2 for more information."] const
416 OtherWarning = 67108864; #[doc = " Detail: Do not implement."] const Reserved2 =
417 134217728; #[allow(missing_docs)] const ConfigurationAlarm = 268435456;
418 #[allow(missing_docs)] const ConfigurationWarning = 536870912; }
419}
420impl crate::Value for Evt1 {
421 fn decode(data: &[u16]) -> Result<Self, crate::DecodeError> {
422 let value = u32::decode(data)?;
423 Ok(Self::from_bits_retain(value))
424 }
425 fn encode(self) -> Box<[u16]> {
426 self.bits().encode()
427 }
428}
429impl crate::FixedSize for Evt1 {
430 const SIZE: u16 = 2u16;
431 const INVALID: Self = Self::from_bits_retain(4294967295u32);
432 fn is_invalid(&self) -> bool {
433 self.bits() == 4294967295u32
434 }
435}
436bitflags::bitflags! {
437 #[doc = " String Event 2"] #[doc = " "] #[doc =
438 " Alarms, warnings and status values. Bit flags."] #[doc = " "] #[doc =
439 " Detail: Reserved for future use."] #[derive(Copy, Clone, Debug, Eq, PartialEq)]
440 #[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))] pub
441 struct Evt2 : u32 {}
442}
443impl crate::Value for Evt2 {
444 fn decode(data: &[u16]) -> Result<Self, crate::DecodeError> {
445 let value = u32::decode(data)?;
446 Ok(Self::from_bits_retain(value))
447 }
448 fn encode(self) -> Box<[u16]> {
449 self.bits().encode()
450 }
451}
452impl crate::FixedSize for Evt2 {
453 const SIZE: u16 = 2u16;
454 const INVALID: Self = Self::from_bits_retain(4294967295u32);
455 fn is_invalid(&self) -> bool {
456 self.bits() == 4294967295u32
457 }
458}
459bitflags::bitflags! {
460 #[doc = " Vendor Event Bitfield 1"] #[doc = " "] #[doc = " Vendor defined events."]
461 #[derive(Copy, Clone, Debug, Eq, PartialEq)] #[cfg_attr(feature = "serde",
462 derive(::serde::Serialize, ::serde::Deserialize))] pub struct EvtVnd1 : u32 {}
463}
464impl crate::Value for EvtVnd1 {
465 fn decode(data: &[u16]) -> Result<Self, crate::DecodeError> {
466 let value = u32::decode(data)?;
467 Ok(Self::from_bits_retain(value))
468 }
469 fn encode(self) -> Box<[u16]> {
470 self.bits().encode()
471 }
472}
473impl crate::FixedSize for EvtVnd1 {
474 const SIZE: u16 = 2u16;
475 const INVALID: Self = Self::from_bits_retain(4294967295u32);
476 fn is_invalid(&self) -> bool {
477 self.bits() == 4294967295u32
478 }
479}
480bitflags::bitflags! {
481 #[doc = " Vendor Event Bitfield 2"] #[doc = " "] #[doc = " Vendor defined events."]
482 #[derive(Copy, Clone, Debug, Eq, PartialEq)] #[cfg_attr(feature = "serde",
483 derive(::serde::Serialize, ::serde::Deserialize))] pub struct EvtVnd2 : u32 {}
484}
485impl crate::Value for EvtVnd2 {
486 fn decode(data: &[u16]) -> Result<Self, crate::DecodeError> {
487 let value = u32::decode(data)?;
488 Ok(Self::from_bits_retain(value))
489 }
490 fn encode(self) -> Box<[u16]> {
491 self.bits().encode()
492 }
493}
494impl crate::FixedSize for EvtVnd2 {
495 const SIZE: u16 = 2u16;
496 const INVALID: Self = Self::from_bits_retain(4294967295u32);
497 fn is_invalid(&self) -> bool {
498 self.bits() == 4294967295u32
499 }
500}
501#[derive(Copy, Clone, Debug, Eq, PartialEq)]
507#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
508pub enum SetCon {
509 #[allow(missing_docs)]
510 ConnectString,
511 #[allow(missing_docs)]
512 DisconnectString,
513 Invalid(u16),
515}
516impl crate::EnumValue for SetCon {
517 type Repr = u16;
518 const INVALID: Self::Repr = 65535;
519 fn from_repr(value: Self::Repr) -> Self {
520 match value {
521 1 => Self::ConnectString,
522 2 => Self::DisconnectString,
523 value => Self::Invalid(value),
524 }
525 }
526 fn to_repr(self) -> Self::Repr {
527 match self {
528 Self::ConnectString => 1,
529 Self::DisconnectString => 2,
530 Self::Invalid(value) => value,
531 }
532 }
533}
534impl crate::FixedSize for SetCon {
535 const SIZE: u16 = 1u16;
536 const INVALID: Self = Self::Invalid(65535);
537 fn is_invalid(&self) -> bool {
538 matches!(self, Self::Invalid(_))
539 }
540}
541#[allow(missing_docs)]
542#[derive(Debug)]
543#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
544pub struct LithiumIonStringModule {
545 pub mod_n_cell: u16,
549 pub mod_soc: Option<u16>,
553 pub mod_soh: Option<u16>,
557 pub mod_cell_v_max: u16,
561 pub mod_cell_v_max_cell: Option<u16>,
565 pub mod_cell_v_min: u16,
569 pub mod_cell_v_min_cell: Option<u16>,
573 pub mod_cell_v_avg: u16,
577 pub mod_cell_tmp_max: i16,
581 pub mod_cell_tmp_max_cell: Option<u16>,
585 pub mod_cell_tmp_min: i16,
589 pub mod_cell_tmp_min_cell: Option<u16>,
593 pub mod_cell_tmp_avg: i16,
597}
598#[allow(missing_docs)]
599impl LithiumIonStringModule {
600 pub const MOD_N_CELL: crate::Point<Self, u16> = crate::Point::new(0, 1, false);
601 pub const MOD_SOC: crate::Point<Self, Option<u16>> = crate::Point::new(1, 1, false);
602 pub const MOD_SOH: crate::Point<Self, Option<u16>> = crate::Point::new(2, 1, false);
603 pub const MOD_CELL_V_MAX: crate::Point<Self, u16> = crate::Point::new(3, 1, false);
604 pub const MOD_CELL_V_MAX_CELL: crate::Point<Self, Option<u16>> = crate::Point::new(4, 1, false);
605 pub const MOD_CELL_V_MIN: crate::Point<Self, u16> = crate::Point::new(5, 1, false);
606 pub const MOD_CELL_V_MIN_CELL: crate::Point<Self, Option<u16>> = crate::Point::new(6, 1, false);
607 pub const MOD_CELL_V_AVG: crate::Point<Self, u16> = crate::Point::new(7, 1, false);
608 pub const MOD_CELL_TMP_MAX: crate::Point<Self, i16> = crate::Point::new(8, 1, false);
609 pub const MOD_CELL_TMP_MAX_CELL: crate::Point<Self, Option<u16>> =
610 crate::Point::new(9, 1, false);
611 pub const MOD_CELL_TMP_MIN: crate::Point<Self, i16> = crate::Point::new(10, 1, false);
612 pub const MOD_CELL_TMP_MIN_CELL: crate::Point<Self, Option<u16>> =
613 crate::Point::new(11, 1, false);
614 pub const MOD_CELL_TMP_AVG: crate::Point<Self, i16> = crate::Point::new(12, 1, false);
615}
616impl crate::Group for LithiumIonStringModule {
617 const LEN: u16 = 16;
618}
619impl LithiumIonStringModule {
620 fn parse_group(data: &[u16]) -> Result<(&[u16], Self), crate::DecodeError> {
621 let nested_data = data
622 .get(usize::from(<Self as crate::Group>::LEN)..)
623 .unwrap_or(&[]);
624 Ok((
625 nested_data,
626 Self {
627 mod_n_cell: Self::MOD_N_CELL.from_data(data)?,
628 mod_soc: Self::MOD_SOC.from_data(data)?,
629 mod_soh: Self::MOD_SOH.from_data(data)?,
630 mod_cell_v_max: Self::MOD_CELL_V_MAX.from_data(data)?,
631 mod_cell_v_max_cell: Self::MOD_CELL_V_MAX_CELL.from_data(data)?,
632 mod_cell_v_min: Self::MOD_CELL_V_MIN.from_data(data)?,
633 mod_cell_v_min_cell: Self::MOD_CELL_V_MIN_CELL.from_data(data)?,
634 mod_cell_v_avg: Self::MOD_CELL_V_AVG.from_data(data)?,
635 mod_cell_tmp_max: Self::MOD_CELL_TMP_MAX.from_data(data)?,
636 mod_cell_tmp_max_cell: Self::MOD_CELL_TMP_MAX_CELL.from_data(data)?,
637 mod_cell_tmp_min: Self::MOD_CELL_TMP_MIN.from_data(data)?,
638 mod_cell_tmp_min_cell: Self::MOD_CELL_TMP_MIN_CELL.from_data(data)?,
639 mod_cell_tmp_avg: Self::MOD_CELL_TMP_AVG.from_data(data)?,
640 },
641 ))
642 }
643 fn parse_multiple<'a>(
644 data: &'a [u16],
645 counts: &Counts,
646 ) -> Result<(&'a [u16], Vec<Self>), crate::DecodeError> {
647 let (data, groups) =
648 (0..counts.n_mod).try_fold((data, Vec::new()), |(data, mut groups), _| {
649 let (data, group) = LithiumIonStringModule::parse_group(data)?;
650 groups.push(group);
651 Ok::<_, crate::DecodeError>((data, groups))
652 })?;
653 Ok((data, groups))
654 }
655}
656impl crate::Model for LithiumIonString {
657 const ID: u16 = 804;
658 fn addr(models: &crate::Models) -> crate::ModelAddr<Self> {
659 models.m804
660 }
661 fn parse(data: &[u16]) -> Result<Self, crate::ParseError<Self>> {
662 let (_, model) = Self::parse_group(data)?;
663 Ok(model)
664 }
665}