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