10constexpr unsigned int NUMBER_OF_CELLS = 4;
11constexpr unsigned int MANUFACTURE_NAME_LENGTH = 21;
12constexpr unsigned int DEVICE_NAME_LENGTH = 21;
13constexpr unsigned int DEVICE_CHEMISTRY = 5;
15constexpr unsigned int ESC_SERIAL_LENGTH = 20;
16constexpr unsigned int ESC_UID_LENGTH = 16;
17constexpr unsigned int COMMIT_ID_LENGTH = 7;
19enum class EscHwVersion : uint8_t { ipeaka = 0, speedy_bee = 1 };
22typedef struct __attribute__((__packed__)) {
24 int16_t cell_max_voltages[NUMBER_OF_CELLS];
26 int16_t cell_min_voltages[NUMBER_OF_CELLS];
28 int16_t max_delta_cell_voltage;
30 int16_t max_charge_current;
32 int16_t max_discharge_current;
34 int16_t max_avg_discharge_current;
36 int16_t max_avg_discharge_power;
38 int8_t max_cell_temperature;
40 int8_t min_cell_temperature;
43 int8_t max_delta_cell_temperature;
45 int8_t max_temperature_internal_sensor;
47 int8_t min_temperature_internal_sensor;
49 int8_t max_temperature_fet;
50} TBatteryLifetimesRaw;
52typedef struct __attribute__((__packed__)) {
54 uint16_t cov_events_count;
56 uint16_t cov_last_event;
58 uint16_t cuv_events_count;
60 uint16_t cuv_last_event;
62 uint16_t ocd1_events_count;
64 uint16_t ocd1_last_event;
66 uint16_t ocd2_events_count;
68 uint16_t ocd2_last_event;
70 uint16_t occ1_events_count;
72 uint16_t occ1_last_event;
74 uint16_t occ2_events_count;
76 uint16_t occ2_last_event;
78 uint16_t aold_events_count;
80 uint16_t aold_last_event;
82 uint16_t ascd_events_count;
84 uint16_t ascd_last_event;
86 uint16_t ascc_events_count;
88 uint16_t ascc_last_event;
90 uint16_t otc_events_count;
92 uint16_t otc_last_event;
94 uint16_t otd_events_count;
96 uint16_t otd_last_event;
98 uint16_t otf_events_count;
100 uint16_t otf_last_event;
101} TBatterySafetyEventsRaw;
103typedef struct __attribute__((__packed__)) {
105 uint16_t charge_termination_events_count;
107 uint16_t charge_termination_last_event;
108} TBatteryChargingEventsRaw;
110typedef struct __attribute__((__packed__)) {
111 uint16_t temperature;
114 int32_t average_current;
116 uint8_t state_of_charge_rel;
117 uint16_t remaining_capacity;
118 uint16_t full_charge_capacity;
119 uint16_t run_time_to_empty;
120 uint16_t avg_time_to_empty;
121 uint16_t avg_time_to_full;
122 uint16_t at_rate_time_to_full;
123 uint16_t at_rate_time_to_empty;
125 uint16_t charging_current;
126 uint16_t charging_voltage;
128 uint16_t battery_status;
130 uint16_t cell_voltage[NUMBER_OF_CELLS];
131 int16_t cell_temperature[NUMBER_OF_CELLS];
134typedef struct __attribute__((__packed__)) {
137 uint16_t cycle_count;
138 uint16_t design_capacity;
139 uint16_t manufacture_date;
140 uint16_t serial_number;
141 char manufacture_name[MANUFACTURE_NAME_LENGTH];
142 char device_name[DEVICE_NAME_LENGTH];
143 char device_chemistry[DEVICE_CHEMISTRY];
144 TBatteryLifetimesRaw lifetimes;
145 TBatterySafetyEventsRaw safety_events;
146 TBatteryChargingEventsRaw charging_events;
149typedef struct __attribute__((__packed__)) {
150 EscHwVersion hw_version;
151 char serial_number[ESC_SERIAL_LENGTH];
152 char uid[ESC_UID_LENGTH];
153 uint8_t serial_number_read_status;
154 uint8_t uid_read_status;
155 uint8_t hw_version_read_status;
158typedef struct __attribute__((__packed__)) {
159 uint8_t transfer_status;
160} TEscSetSerialReplyRaw;
162typedef struct __attribute__((__packed__)) {
166 char commit_id[COMMIT_ID_LENGTH];
169typedef struct __attribute__((__packed__)) {
170 uint8_t humidity_low_byte;
171 uint8_t humidity_high_byte;
172 uint8_t temperature_low_byte;
173 uint8_t temperature_high_byte;
179 float cell_max_voltages[NUMBER_OF_CELLS];
181 float cell_min_voltages[NUMBER_OF_CELLS];
183 float max_delta_cell_voltage;
185 float max_charge_current;
187 float max_discharge_current;
189 float max_avg_discharge_current;
191 float max_avg_discharge_power;
193 float max_cell_temperature;
195 float min_cell_temperature;
198 float max_delta_cell_temperature;
200 float max_temperature_internal_sensor;
202 float min_temperature_internal_sensor;
204 float max_temperature_fet;
209 uint16_t cov_events_count;
211 uint16_t cov_last_event;
213 uint16_t cuv_events_count;
215 uint16_t cuv_last_event;
217 uint16_t ocd1_events_count;
219 uint16_t ocd1_last_event;
221 uint16_t ocd2_events_count;
223 uint16_t ocd2_last_event;
225 uint16_t occ1_events_count;
227 uint16_t occ1_last_event;
229 uint16_t occ2_events_count;
231 uint16_t occ2_last_event;
233 uint16_t aold_events_count;
235 uint16_t aold_last_event;
237 uint16_t ascd_events_count;
239 uint16_t ascd_last_event;
241 uint16_t ascc_events_count;
243 uint16_t ascc_last_event;
245 uint16_t otc_events_count;
247 uint16_t otc_last_event;
249 uint16_t otd_events_count;
251 uint16_t otd_last_event;
253 uint16_t otf_events_count;
255 uint16_t otf_last_event;
260 uint16_t charge_termination_events_count;
262 uint16_t charge_termination_last_event;
269 float average_current;
271 float state_of_charge_rel;
272 float state_of_charge_calculated;
273 float remaining_capacity;
274 float full_charge_capacity;
275 uint32_t run_time_to_empty;
276 uint32_t avg_time_to_empty;
277 uint32_t avg_time_to_full;
279 float charging_current;
280 float charging_voltage;
282 uint16_t battery_status;
284 float cell_voltage[NUMBER_OF_CELLS];
285 float cell_temperature[NUMBER_OF_CELLS];
291 uint16_t cycle_count;
292 float design_capacity;
294 uint16_t serial_number;
295 std::string manufacture_name;
296 std::string device_name;
297 std::string device_chemistry;
304 char uid[ESC_UID_LENGTH];
307enum class PMUI2CStatusCode {
319 EscHwVersion hw_version;
320 std::string serial_number;
322 PMUI2CStatusCode serial_number_read_status;
323 PMUI2CStatusCode uid_read_status;
324 PMUI2CStatusCode hw_version_read_status;
328 PMUI2CStatusCode transfer_status;
332 uint8_t ver_major = 0;
333 uint8_t ver_minor = 0;
334 uint16_t ver_patch = 0;
335 std::string commit_id =
"Unknown";
343enum class PMUErrorCode {
345 WrongProtocolVersion,
356 PMUErrorCode errorcode;
361inline std::ostream& operator<<(std::ostream& os,
362 blunux::pmu::EscHwVersion version) {
364 case blunux::pmu::EscHwVersion::ipeaka:
365 return os <<
"iPeaka";
366 case blunux::pmu::EscHwVersion::speedy_bee:
367 return os <<
"SpeedyBee";
369 return os << static_cast<int>(version);
373struct fmt::formatter<blunux::pmu::EscHwVersion> : formatter<string_view> {
375 template <
typename FormatContext>
377 auto format(blunux::pmu::EscHwVersion version, FormatContext& ctx)
const {
378 std::stringstream ss;
380 return formatter<string_view>::format(ss.str(), ctx);
385struct fmt::formatter<blunux::pmu::EscUid> : formatter<string_view> {
387 template <
typename FormatContext>
390 std::stringstream ss;
391 ss << std::hex << std::setfill(
'0');
392 for (
unsigned int i = 0; i < blunux::pmu::ESC_UID_LENGTH; i++) {
393 ss << std::setw(2) << std::hex << static_cast<int>(uid.uid[i]);
394 if (i == 3 || i == 5 || i == 7 || i == 9) {
398 return formatter<string_view>::format(ss.str(), ctx);
403 return os << fmt::format(
"{}", data);
406inline std::ostream& operator<<(std::ostream& os,
408 return os << fmt::format(
"{}.{}.{} {}", version.ver_major, version.ver_minor,
409 version.ver_patch, version.commit_id);
413struct fmt::formatter<blunux::pmu::TVersionInfo> : formatter<string_view> {
415 template <
typename FormatContext>
418 std::stringstream ss;
420 return formatter<string_view>::format(ss.str(), ctx);
425struct fmt::formatter<blunux::pmu::PMUErrorCode> {
426 template <
typename ParseContext>
428 constexpr auto parse(ParseContext& ctx) {
431 template <
typename FormatContext>
432 auto format(blunux::pmu::PMUErrorCode
const& error,
433 FormatContext& ctx)
const {
435 case blunux::pmu::PMUErrorCode::NoMagicByte:
436 return fmt::format_to(ctx.out(),
"NoMagicByte");
437 case blunux::pmu::PMUErrorCode::WrongProtocolVersion:
438 return fmt::format_to(ctx.out(),
"WrongProtocolVersion");
439 case blunux::pmu::PMUErrorCode::UnknownPacketType:
440 return fmt::format_to(ctx.out(),
"UnknownPacketType");
441 case blunux::pmu::PMUErrorCode::CRCError:
442 return fmt::format_to(ctx.out(),
"CRCError");
443 case blunux::pmu::PMUErrorCode::NoAck:
444 return fmt::format_to(ctx.out(),
"NoAck");
445 case blunux::pmu::PMUErrorCode::NoVersion:
446 return fmt::format_to(ctx.out(),
"NoVersion");
447 case blunux::pmu::PMUErrorCode::NoEscInfo:
448 return fmt::format_to(ctx.out(),
"NoEscInfo");
449 case blunux::pmu::PMUErrorCode::NoEscSetSerialReply:
450 return fmt::format_to(ctx.out(),
"NoEscSetSerialReply");
451 case blunux::pmu::PMUErrorCode::NoBatteryInfo:
452 return fmt::format_to(ctx.out(),
"NoBatteryInfo");
454 return fmt::format_to(ctx.out(),
"");
458inline std::ostream& operator<<(std::ostream& os,
459 blunux::pmu::PMUErrorCode data) {
460 return os << fmt::format(
"{}", data);
464struct fmt::formatter<blunux::pmu::PMUI2CStatusCode> {
465 template <
typename ParseContext>
467 constexpr auto parse(ParseContext& ctx) {
470 template <
typename FormatContext>
471 auto format(blunux::pmu::PMUI2CStatusCode
const& status,
472 FormatContext& ctx)
const {
474 case blunux::pmu::PMUI2CStatusCode::Ok:
475 return fmt::format_to(ctx.out(),
"Ok");
476 case blunux::pmu::PMUI2CStatusCode::Busy:
477 return fmt::format_to(ctx.out(),
"Busy");
478 case blunux::pmu::PMUI2CStatusCode::Idle:
479 return fmt::format_to(ctx.out(),
"Idle");
480 case blunux::pmu::PMUI2CStatusCode::Nak:
481 return fmt::format_to(ctx.out(),
"Nak");
482 case blunux::pmu::PMUI2CStatusCode::ArbitrationLost:
483 return fmt::format_to(ctx.out(),
"ArbitrationLost");
484 case blunux::pmu::PMUI2CStatusCode::Timeout:
485 return fmt::format_to(ctx.out(),
"Timeout");
486 case blunux::pmu::PMUI2CStatusCode::AddressNak:
487 return fmt::format_to(ctx.out(),
"AddressNak");
488 case blunux::pmu::PMUI2CStatusCode::UnknownError:
489 return fmt::format_to(ctx.out(),
"UnknownError");
491 return fmt::format_to(ctx.out(),
"");
495inline std::ostream& operator<<(std::ostream& os,
496 blunux::pmu::PMUI2CStatusCode data) {
497 return os << fmt::format(
"{}", data);
501struct fmt::formatter<blunux::pmu::TPMUError> {
502 template <
typename ParseContext>
504 constexpr auto parse(ParseContext& ctx) {
508 template <
typename FormatContext>
511 return fmt::format_to(ctx.out(),
"{}", error.errorcode);
516 return os << fmt::format(
"{}", data);
519inline std::ostream& operator<<(std::ostream& os,
521 return os << fmt::format(
522 "HW version: {}\nHW version transfer status: {}\nSerial: "
523 "{}\nSerial transfer status: {}\nUID: {}\nUID transfer status: {}",
524 esc_info.hw_version, esc_info.hw_version_read_status,
525 esc_info.serial_number, esc_info.serial_number_read_status,
526 esc_info.uid, esc_info.uid_read_status);
530struct fmt::formatter<blunux::pmu::TEscInfo> : formatter<string_view> {
532 template <
typename FormatContext>
535 std::stringstream ss;
537 return formatter<string_view>::format(ss.str(), ctx);
542struct fmt::formatter<blunux::pmu::TBatteryInfo> : formatter<string_view> {
544 template <
typename FormatContext>
547 FormatContext& ctx)
const {
548 std::stringstream ss;
549 ss <<
"Max Error: " <<
static_cast<int>(battery_info.max_error) <<
" %\n"
550 <<
"Absolute SOC: " <<
static_cast<int>(battery_info.abs_soc * 100)
552 <<
"Cycle Count: " << battery_info.cycle_count <<
"\n"
553 <<
"Design Capacity: " << battery_info.design_capacity <<
" Ah\n"
554 <<
"Manufacture Date: " << battery_info.manufacture_date.tm_year <<
"-"
555 << battery_info.manufacture_date.tm_mon <<
"-"
556 << battery_info.manufacture_date.tm_mday <<
"\n"
557 <<
"Serial Number: " << battery_info.serial_number <<
"\n"
558 <<
"Manufacture Name: " << battery_info.manufacture_name <<
"\n"
559 <<
"Device Name: " << battery_info.device_name <<
"\n"
560 <<
"Device Chemistry: " << battery_info.device_chemistry <<
"\n"
562 <<
"Max Cell Voltage: [";
563 for (uint8_t i = 0; i < blunux::pmu::NUMBER_OF_CELLS; i++) {
564 ss << battery_info.lifetimes.cell_max_voltages[i];
565 if (i < blunux::pmu::NUMBER_OF_CELLS - 1) {
569 ss <<
"] (mV)\nMin Cell Voltage: [";
570 for (uint8_t i = 0; i < blunux::pmu::NUMBER_OF_CELLS; i++) {
571 ss << battery_info.lifetimes.cell_min_voltages[i];
572 if (i < blunux::pmu::NUMBER_OF_CELLS - 1) {
579 ss <<
"Max Delta Cell Voltage: "
580 << battery_info.lifetimes.max_delta_cell_voltage <<
" mV\n"
581 <<
"Max Charge Current: " << battery_info.lifetimes.max_charge_current
583 <<
"Max Discharge Current: "
584 << battery_info.lifetimes.max_discharge_current <<
" mA\n"
585 <<
"Max Avg Discharge Current: "
586 << battery_info.lifetimes.max_avg_discharge_current <<
" mA\n"
587 <<
"Max Avg Discharge Power: "
588 << battery_info.lifetimes.max_avg_discharge_power <<
" cW\n"
589 <<
"Max Cell Temperature: "
590 <<
static_cast<int>(battery_info.lifetimes.max_cell_temperature)
592 <<
"Min Cell Temperature: "
593 <<
static_cast<int>(battery_info.lifetimes.min_cell_temperature)
595 <<
"Max Delta Cell Temperature: "
596 <<
static_cast<int>(battery_info.lifetimes.max_delta_cell_temperature)
598 <<
"Max Temperature Internal Sensor: "
600 battery_info.lifetimes.max_temperature_internal_sensor)
602 <<
"Min Temperature Internal Sensor: "
604 battery_info.lifetimes.min_temperature_internal_sensor)
606 <<
"Max Temperature FET: "
607 <<
static_cast<int>(battery_info.lifetimes.max_temperature_fet)
609 <<
"Number of COV events: "
610 << battery_info.safety_events.cov_events_count
611 <<
", last occurred cycle " << battery_info.safety_events.cov_last_event
613 <<
"Number of CUV events: "
614 << battery_info.safety_events.cuv_events_count
615 <<
", last occurred cycle " << battery_info.safety_events.cuv_last_event
617 <<
"Number of OCD1 events: "
618 << battery_info.safety_events.ocd1_events_count
619 <<
", last occurred cycle " << battery_info.safety_events.ocd1_last_event
621 <<
"Number of OCD2 events: "
622 << battery_info.safety_events.ocd2_events_count
623 <<
", last occurred cycle " << battery_info.safety_events.ocd2_last_event
625 <<
"Number of OCC1 events: "
626 << battery_info.safety_events.occ1_events_count
627 <<
", last occurred cycle " << battery_info.safety_events.occ1_last_event
629 <<
"Number of OCC2 events: "
630 << battery_info.safety_events.occ2_events_count
631 <<
", last occurred cycle " << battery_info.safety_events.occ2_last_event
633 <<
"Number of AOLD events: "
634 << battery_info.safety_events.aold_events_count
635 <<
", last occurred cycle " << battery_info.safety_events.aold_last_event
637 <<
"Number of ASCD events: "
638 << battery_info.safety_events.ascd_events_count
639 <<
", last occurred cycle " << battery_info.safety_events.ascd_last_event
641 <<
"Number of ASCC events: "
642 << battery_info.safety_events.ascc_events_count
643 <<
", last occurred cycle " << battery_info.safety_events.ascc_last_event
645 <<
"Number of OTC events: "
646 << battery_info.safety_events.otc_events_count
647 <<
", last occurred cycle " << battery_info.safety_events.otc_last_event
649 <<
"Number of OTD events: "
650 << battery_info.safety_events.otd_events_count
651 <<
", last occurred cycle " << battery_info.safety_events.otd_last_event
653 <<
"Number of OTF events: "
654 << battery_info.safety_events.otf_events_count
655 <<
", last occurred cycle " << battery_info.safety_events.otf_last_event
657 <<
"Number of Charge Termination events: "
658 << battery_info.charging_events.charge_termination_events_count
659 <<
", last occurred cycle "
660 << battery_info.charging_events.charge_termination_last_event;
662 return formatter<string_view>::format(ss.str(), ctx);
666inline std::ostream& operator<<(std::ostream& os,
668 return os << fmt::format(
"{}", battery_info);
Definition message_types.hpp:303
Definition message_types.hpp:258
Definition message_types.hpp:288
Definition message_types.hpp:177
Definition message_types.hpp:207
Definition message_types.hpp:265
Definition message_types.hpp:318
Definition message_types.hpp:327
Definition message_types.hpp:355
Definition message_types.hpp:338
Definition message_types.hpp:331