#ifndef PCCU_PM_PROTOCOL_H #define PCCU_PM_PROTOCOL_H #include #include #include "Message.h" namespace ccu { //============================================================================ // PM 协议(复合管控器 <-> 控制主机 pPowerManger) // 依据:docs/控制主机与复合管控器通信协议 - 0824.xlsx // // 帧格式统一:0x40 0x40 + 域标识符(2B) + 域字节数(2B) + 数据域 + uint32 校验和 // 校验和为从域起始符到校验和之前所有数据的字节和。 // // 四条消息(均带 uint32 校验和): // 0x0001 操控指令域 (控制主机->复合管控器)payload 35B,总长 45B // 0x0002 参数设定指令域 (控制主机->复合管控器)payload 18B,总长 28B // 0x0003 参数设定反馈域 (复合管控器->控制主机)payload 2B,总长 12B // 0x0004 状态报文域 (复合管控器->控制主机)payload 238B,总长 248B //============================================================================ //-------------------------------------------------------------------------- // 0x0001 操控指令域 // payload 35 字节,对应文档字节 7~41 //-------------------------------------------------------------------------- struct PmControlValue { // 系统时间 uint16_t year = 0; uint8_t month = 0; uint8_t day = 0; uint8_t hour = 0; uint8_t minute = 0; uint8_t second = 0; uint8_t millisecond10 = 0; // 10毫秒 // 指令 uint8_t mode = 0; // 模式设定 00~03 uint8_t cmd = 0; // 操控指令 00~0B uint8_t outputPower = 0; // 输出功率指令 0~250,0.1kW int16_t pitch = 0; // 纵倾姿态数据1 int16,分辨率0.1°(字节18,19) int16_t roll = 0; // 横倾姿态数据1 int16,分辨率0.1°(字节20,21) uint8_t emergencyAllow = 0; // 应急允许 uint16_t depth = 0; // 潜深深度 m uint8_t supplyCmd = 0; // 补给/排放指令 uint8_t reservedCmd5 = 0; // 预留指令5 uint8_t reservedCmd6 = 0; // 预留指令6 uint8_t insBatCmd = 0; // 仪表锂电池启停指令 00/10/20 uint8_t dynBatCmd = 0; // 动力锂电池启停指令 00/10/20 uint16_t dynBatPower = 0; // 动力锂电池功率配置值 kW uint8_t heartbeat = 0; // 通信心跳,每次+1 uint8_t hostState = 0; // 主机状态 运行AAH/关机FFH/故障其他 uint32_t reserved1 = 0; // 预留 uint32_t reserved2 = 0; // 预留 }; //-------------------------------------------------------------------------- // 0x0002 参数设定指令域 // payload 18 字节,对应文档字节 7~24 //-------------------------------------------------------------------------- struct PmParamSetValue { uint8_t insSocHold1 = 0; // 仪表电池充电一级功率SOC门限 uint8_t insSocHold2 = 0; // 仪表电池充电二级功率SOC门限 uint8_t insSocHold3 = 0; // 仪表电池充电三级功率SOC门限 uint8_t insOutputPower = 0; // 仪表锂电池输出功率 % uint8_t insReserved = 0; // 预留 uint8_t dynSocHold1 = 0; // 动力电池充电一级功率SOC门限 uint8_t dynSocHold2 = 0; // 动力电池充电二级功率SOC门限 uint8_t dynSocHold3 = 0; // 动力电池充电三级功率SOC门限 uint8_t dynOutputPower = 0; // 动力电池输出功率 % uint8_t dynReserved = 0; // 预留 uint32_t reserved1 = 0; // 预留 uint32_t reserved2 = 0; // 预留 }; //-------------------------------------------------------------------------- // 0x0003 参数设定反馈域 // payload 2 字节,对应文档字节 7~8 //-------------------------------------------------------------------------- struct PmParamSetFbValue { uint8_t flag = 0; // 设定标志:00H无效 / 10H成功 / 20H失败 uint8_t failCode = 0; // 设定失败原因 }; //-------------------------------------------------------------------------- // 0x0004 状态报文域 // payload 238 字节,对应文档字节 7~244 //-------------------------------------------------------------------------- struct PmStatusValue { uint8_t fc_mode = 0; // 燃料电池系统运行模式 uint8_t fc_status = 0; // 燃料电池系统运行状态 uint16_t fault_level_1 = 0; // 一级故障码 uint16_t fault_level_2 = 0; // 二级故障码 uint16_t fault_level_3 = 0; // 三级故障码 uint16_t fault_level_4 = 0; // 四级故障码 uint16_t total_generation_time = 0; // 累积发电时间 0.1h uint8_t fc_fault_level = 0; // 系统故障等级 00~04 uint16_t output_power_limit = 0; // 系统输出功率限定功率 W uint16_t generation_power = 0; // 系统发电功率 0.01kW uint8_t hydrogen_capacity = 0; // 储氢剩余容量 % uint8_t liquid_oxygen_capacity = 0; // 液氧剩余容量 % uint8_t fc1_min_cell_voltage = 0; // I#FC最低单片电压 10mV uint8_t fc1_min_cell_pos = 0; // I#FC最低单片电压位置 uint8_t fc1_avg_cell_voltage = 0; // I#FC平均单片电压 uint8_t fc2_min_cell_voltage = 0; // 2#FC最低单片电压 uint8_t fc2_min_cell_pos = 0; // 2#FC最低单片电压位置 uint8_t fc2_avg_cell_voltage = 0; // 2#FC平均单片电压 uint16_t palladium_temp = 0; // 甲醇制氢装置钯膜最高温度 0.1℃ uint16_t buffer_tank_pressure = 0; // 缓冲罐压力 0.1kPa uint16_t flue_total_emission = 0; // 烟气累计排放量 0.1kg uint16_t flue_pressure = 0; // 烟气压力 0.001MPa uint16_t reactor_pressure = 0; // 反应器压力 0.001MPa uint16_t electric_valve_open = 0; // 电动阀开度 0.1% uint16_t main_pipe_pressure = 0; // 主水路盘管侧压力 0.01kPa uint16_t aux_pipe_pressure = 0; // 辅水路盘管侧压力 0.01kPa uint16_t dcdc1_in_voltage = 0; // DC/DC通道1输入电压 0.1V uint16_t dcdc1_in_current = 0; // DC/DC通道1输入电流 0.1A uint16_t dcdc2_in_voltage = 0; // DC/DC通道2输入电压 0.1V uint16_t dcdc2_in_current = 0; // DC/DC通道2输入电流 0.1A uint16_t dcdc_out_voltage = 0; // DC/DC输出电压 0.1V uint16_t dcdc_out_current = 0; // DC/DC输出电流 0.1A uint8_t dcdc_ctrl_voltage = 0; // DC/DC控制电源电压 0.25V uint8_t dcdc_aux_voltage = 0; // DC/DC辅电输出电压 0.125V uint16_t methanol_total_use = 0; // 甲醇累计使用量 0.1kg uint16_t methanol_feed = 0; // 甲醇溶液进料量 1mL/min uint16_t oxygen_side_water_level = 0; // 氧侧生成水箱液位 0.01mm uint16_t hydrogen_side_water_level = 0; // 氢侧生成水箱液位 uint16_t ballast_water_level = 0; // 配重水箱液位 uint16_t exhaust_inlet_pressure = 0; // 尾气装置进气压力 0.01MPa uint16_t exhaust_outlet_pressure = 0; // 尾气装置排气压力 0.01MPa uint16_t exhaust_run_freq = 0; // 尾气装置运行频率 0.01Hz uint16_t exhaust_inlet_temp = 0; // 尾气装置进气温度 0.01℃ uint16_t exhaust_outlet_temp = 0; // 尾气装置排气温度 0.01℃ uint16_t exhaust_water_in_pressure = 0; // 尾气装置进水压力 0.01kPa uint16_t exhaust_water_out_pressure = 0; // 尾气装置排水压力 0.01kPa uint16_t tank_lo2_pressure = 0; // 一体化罐装置液氧罐压力 0.01MPa uint16_t tank_co2_pressure = 0; // 一体化罐装置二氧化碳压力 0.01MPa uint16_t tank_lo2_level = 0; // 一体化罐装置液氧罐液位 0.01mm uint16_t alloy_h2_flow = 0; // 合金供氢流量 0.01L/min uint16_t fc_h2_flow = 0; // FC供氢流量 0.01L/min uint16_t fc_o2_flow = 0; // FC供氧流量 0.01L/min uint16_t emergency_float_depth = 0; // 应急上浮深度 1m uint16_t emergency_float_time = 0; // 应急上浮时间 1min uint16_t cabin_pressure1 = 0; // 舱室压力1 0.01kPa uint16_t cabin_pressure2 = 0; // 舱室压力2 uint16_t cabin_temp1 = 0; // 舱室温度1 0.01℃ uint16_t cabin_temp2 = 0; // 舱室温度2 uint16_t cabin_humidity1 = 0; // 舱室湿度1 0.01%RH uint16_t cabin_humidity2 = 0; // 舱室湿度2 uint16_t h2_concentration1 = 0; // 舱室H2浓度1 0.01%LEL uint16_t h2_concentration2 = 0; // 舱室H2浓度2 uint16_t h2_concentration3 = 0; // 舱室H2浓度3 uint16_t o2_concentration1 = 0; // 舱室O2浓度1 0.01%Vol uint16_t o2_concentration2 = 0; // 舱室O2浓度2 uint16_t ch3oh_concentration1 = 0; // 舱室甲醇浓度1 0.01%LEL uint16_t ch3oh_concentration2 = 0; // 舱室甲醇浓度2 uint8_t flame_detector1 = 0; // 火焰探测器1状态 uint8_t flame_detector2 = 0; // 火焰探测器2状态 uint16_t pmReserved1 = 0; // 预留 uint16_t pmReserved2 = 0; // 预留 uint16_t emergency_battery1_voltage = 0; // 应急电池1总电压 uint16_t emergency_battery1_current = 0; // 应急电池1总电流 uint16_t emergency_battery1_max_temp = 0; // 应急电池1最高温度 uint16_t emergency_battery1_fault_word = 0;// 应急电池1故障字 uint16_t emergency_battery2_voltage = 0; // 应急电池2总电压 uint16_t emergency_battery2_current = 0; // 应急电池2总电流 uint16_t emergency_battery2_max_temp = 0; // 应急电池2最高温度 uint16_t emergency_battery2_fault_word = 0;// 应急电池2故障字 uint16_t ins_cabin_ox_concentration = 0; // 仪表舱内氧气浓度 % uint16_t ins_cabin_temperature = 0; // 仪表舱内温度 ℃ uint16_t ins_cabin_humidity = 0; // 仪表舱内湿度 %RH uint16_t ins_cabin_pressure = 0; // 仪表舱内大气压 kPa uint16_t dyn_cabin_ox_concentration = 0; // 动力舱内氧气浓度 % uint16_t dyn_cabin_temperature = 0; // 动力舱内温度 ℃ uint16_t dyn_cabin_humidity = 0; // 动力舱内湿度 %RH uint16_t dyn_cabin_pressure = 0; // 动力舱内大气压 kPa uint8_t pmReserved3 = 0; // 预留 uint8_t dyn_alarm_flag[6] = {0}; // 动力锂电池报警标识字1~6 uint8_t ins_alarm_flag[6] = {0}; // 仪表锂电池报警标识字1~6 uint8_t ins_relay_status1 = 0; // 仪表电池正极+充电继电器状态 uint8_t ins_relay_status2 = 0; // 仪表电池预充+负极继电器状态 uint8_t dyn_relay_status1 = 0; // 动力电池正极+充电继电器状态 uint8_t dyn_relay_status2 = 0; // 动力电池预充+负极继电器状态 uint16_t ins_max_discharge_power = 0; // 仪表电池允许最高放电功率 0.05kW uint16_t dyn_max_discharge_power = 0; // 动力电池允许最高放电功率 0.05kW uint8_t ins_soc = 0; // 仪表锂电池SOC % uint8_t dyn_soc = 0; // 动力锂电池SOC % uint16_t ins_total_energy = 0; // 仪表锂电池总能量 0.1kWh uint16_t dyn_total_energy = 0; // 动力锂电池总电量 0.1kWh uint16_t ins_power_input = 0; // 仪表电池当前接入功率 kW uint16_t dyn_power_input = 0; // 动力电池当前接入功率 kW uint8_t ins_charge_status = 0; // 仪表电池充电状态 uint8_t dyn_charge_status = 0; // 动力电池充电状态 uint16_t ins_voltage_link = 0; // 仪表电池电压LINK端 0.01V uint16_t ins_voltage_pack = 0; // 仪表电池电压PACK端 0.01V uint16_t ins_current = 0; // 仪表电池放电电流 0.05A uint16_t ins_resistance_pos = 0; // 仪表电池正端绝缘电阻 kΩ uint16_t ins_resistance_neg = 0; // 仪表电池负端绝缘电阻 kΩ uint16_t dyn_voltage_link = 0; // 动力电池电压LINK端 0.01V uint16_t dyn_voltage_pack = 0; // 动力电池电压PACK端 0.01V uint16_t dyn_current = 0; // 动力电池放电电流 0.05A uint16_t dyn_resistance_pos = 0; // 动力电池正端绝缘电阻 kΩ uint16_t dyn_resistance_neg = 0; // 动力电池负端绝缘电阻 kΩ uint8_t ins_emergency_status = 0; // 仪表电池紧急状态 uint8_t dyn_emergency_status = 0; // 动力电池紧急状态 uint8_t ins_soc_threshold1 = 0; // 仪表电池充电一级功率SOC门限当前值 uint8_t ins_soc_threshold2 = 0; // 仪表电池充电二级 uint8_t ins_soc_threshold3 = 0; // 仪表电池充电三级 uint8_t ins_power_limit1 = 0; // 仪表通路FC输出功率一级限制当前值 uint8_t ins_power_limit2 = 0; // 仪表通路FC输出功率二级限制当前值 uint8_t dyn_soc_threshold1 = 0; // 动力电池充电一级功率SOC门限当前值 uint8_t dyn_soc_threshold2 = 0; // 动力电池充电二级 uint8_t dyn_soc_threshold3 = 0; // 动力电池充电三级 uint8_t dyn_power_limit1 = 0; // 动力通路FC输出功率一级限制当前值 uint8_t dyn_power_limit2 = 0; // 动力通路FC输出功率二级限制当前值 uint32_t device_online_flag1 = 0; // 设备在线状态标志字1 uint32_t device_online_flag2 = 0; // 设备在线状态标志字2 uint32_t pmReserved4 = 0; // 预留 uint8_t heartbeat = 0; // 通信心跳,每次+1 uint8_t emergency_cmd = 0; // 应急指令 }; //-------------------------------------------------------------------------- // 消息类 //-------------------------------------------------------------------------- class PmControlMessage : public Message { public: uint16_t id() const override { return 0x0001; } const char* name() const override { return "pm_control"; } const ChecksumPolicy& checksum() const override { return m_checksum; } size_t payloadLength() const override { return 35; } std::vector encode(const void* obj) const override; bool decode(const std::vector& frame, void* obj) const override; std::vector encode(const PmControlValue& v) const { return encode(&v); } bool decode(const std::vector& frame, PmControlValue& v) const { return decode(frame, static_cast(&v)); } private: ChecksumPolicy m_checksum{ChecksumType::Sum32}; }; class PmParamSetMessage : public Message { public: uint16_t id() const override { return 0x0002; } const char* name() const override { return "pm_param_set"; } const ChecksumPolicy& checksum() const override { return m_checksum; } size_t payloadLength() const override { return 18; } std::vector encode(const void* obj) const override; bool decode(const std::vector& frame, void* obj) const override; std::vector encode(const PmParamSetValue& v) const { return encode(&v); } bool decode(const std::vector& frame, PmParamSetValue& v) const { return decode(frame, static_cast(&v)); } private: ChecksumPolicy m_checksum{ChecksumType::Sum32}; }; class PmParamSetFbMessage : public Message { public: uint16_t id() const override { return 0x0003; } const char* name() const override { return "pm_param_set_fb"; } const ChecksumPolicy& checksum() const override { return m_checksum; } size_t payloadLength() const override { return 2; } std::vector encode(const void* obj) const override; bool decode(const std::vector& frame, void* obj) const override; std::vector encode(const PmParamSetFbValue& v) const { return encode(&v); } bool decode(const std::vector& frame, PmParamSetFbValue& v) const { return decode(frame, static_cast(&v)); } private: ChecksumPolicy m_checksum{ChecksumType::Sum32}; }; class PmStatusMessage : public Message { public: uint16_t id() const override { return 0x0004; } const char* name() const override { return "pm_status"; } const ChecksumPolicy& checksum() const override { return m_checksum; } size_t payloadLength() const override { return 238; } std::vector encode(const void* obj) const override; bool decode(const std::vector& frame, void* obj) const override; std::vector encode(const PmStatusValue& v) const { return encode(&v); } bool decode(const std::vector& frame, PmStatusValue& v) const { return decode(frame, static_cast(&v)); } private: ChecksumPolicy m_checksum{ChecksumType::Sum32}; }; // 注册 PM 消息到给定注册表 void registerPmMessages(class MessageRegistry& reg); } // namespace ccu #endif // PCCU_PM_PROTOCOL_H