#include "PmProtocol.h" #include "FieldCodec.h" #include "Frame.h" #include "MessageRegistry.h" namespace ccu { void registerPmMessages(MessageRegistry& reg) { reg.registerMessage(std::unique_ptr(new PmControlMessage())); reg.registerMessage(std::unique_ptr(new PmParamSetMessage())); reg.registerMessage(std::unique_ptr(new PmParamSetFbMessage())); reg.registerMessage(std::unique_ptr(new PmStatusMessage())); } //============================================================================ // 0x0001 操控指令域编解码 // 数据域 35 字节,偏移 0~34(对应文档字节 7~41) //============================================================================ namespace { enum : size_t { PO_YEAR = 0, // u16 PO_MONTH = 2, PO_DAY = 3, PO_HOUR = 4, PO_MINUTE = 5, PO_SECOND = 6, PO_MS10 = 7, PO_MODE = 8, PO_CMD = 9, PO_OUTPOWER = 10, PO_PITCH = 11, // 纵倾姿态数据1 int16 (字节18-19) PO_ROLL = 13, // 横倾姿态数据1 int16 (字节20-21) PO_EMER_ALLOW = 15, PO_DEPTH = 16, // u16 PO_SUPPLY_CMD = 18, PO_RESV_CMD5 = 19, PO_RESV_CMD6 = 20, PO_INS_BAT_CMD = 21, PO_DYN_BAT_CMD = 22, PO_DYN_BAT_PWR = 23, // u16 PO_HEARTBEAT = 25, PO_HOST_STATE = 26, PO_RESV1 = 27, // u32 PO_RESV2 = 31, // u32 }; } std::vector PmControlMessage::encode(const void* obj) const { const PmControlValue* v = static_cast(obj); std::vector p(payloadLength(), 0); FieldCodec::putU16(p, PO_YEAR, v->year); FieldCodec::putU8(p, PO_MONTH, v->month); FieldCodec::putU8(p, PO_DAY, v->day); FieldCodec::putU8(p, PO_HOUR, v->hour); FieldCodec::putU8(p, PO_MINUTE, v->minute); FieldCodec::putU8(p, PO_SECOND, v->second); FieldCodec::putU8(p, PO_MS10, v->millisecond10); FieldCodec::putU8(p, PO_MODE, v->mode); FieldCodec::putU8(p, PO_CMD, v->cmd); FieldCodec::putU8(p, PO_OUTPOWER, v->outputPower); FieldCodec::putU16(p, PO_PITCH, static_cast(v->pitch)); // 姿态数据1,数据2字节预留 FieldCodec::putU16(p, PO_ROLL, static_cast(v->roll)); FieldCodec::putU8(p, PO_EMER_ALLOW, v->emergencyAllow); FieldCodec::putU16(p, PO_DEPTH, v->depth); FieldCodec::putU8(p, PO_SUPPLY_CMD, v->supplyCmd); FieldCodec::putU8(p, PO_RESV_CMD5, v->reservedCmd5); FieldCodec::putU8(p, PO_RESV_CMD6, v->reservedCmd6); FieldCodec::putU8(p, PO_INS_BAT_CMD, v->insBatCmd); FieldCodec::putU8(p, PO_DYN_BAT_CMD, v->dynBatCmd); FieldCodec::putU16(p, PO_DYN_BAT_PWR, v->dynBatPower); FieldCodec::putU8(p, PO_HEARTBEAT, v->heartbeat); FieldCodec::putU8(p, PO_HOST_STATE, v->hostState); FieldCodec::putU32(p, PO_RESV1, v->reserved1); FieldCodec::putU32(p, PO_RESV2, v->reserved2); return Frame::build(id(), p, checksum()); } bool PmControlMessage::decode(const std::vector& frame, void* obj) const { if (!validateFrame(frame, id(), checksum(), totalLength())) return false; PmControlValue* v = static_cast(obj); size_t o = FRAME_HEADER_LEN; v->year = FieldCodec::getU16(frame, o + PO_YEAR); v->month = FieldCodec::getU8(frame, o + PO_MONTH); v->day = FieldCodec::getU8(frame, o + PO_DAY); v->hour = FieldCodec::getU8(frame, o + PO_HOUR); v->minute = FieldCodec::getU8(frame, o + PO_MINUTE); v->second = FieldCodec::getU8(frame, o + PO_SECOND); v->millisecond10 = FieldCodec::getU8(frame, o + PO_MS10); v->mode = FieldCodec::getU8(frame, o + PO_MODE); v->cmd = FieldCodec::getU8(frame, o + PO_CMD); v->outputPower = FieldCodec::getU8(frame, o + PO_OUTPOWER); v->pitch = static_cast(FieldCodec::getU16(frame, o + PO_PITCH)); v->roll = static_cast(FieldCodec::getU16(frame, o + PO_ROLL)); v->emergencyAllow= FieldCodec::getU8(frame, o + PO_EMER_ALLOW); v->depth = FieldCodec::getU16(frame, o + PO_DEPTH); v->supplyCmd = FieldCodec::getU8(frame, o + PO_SUPPLY_CMD); v->reservedCmd5 = FieldCodec::getU8(frame, o + PO_RESV_CMD5); v->reservedCmd6 = FieldCodec::getU8(frame, o + PO_RESV_CMD6); v->insBatCmd = FieldCodec::getU8(frame, o + PO_INS_BAT_CMD); v->dynBatCmd = FieldCodec::getU8(frame, o + PO_DYN_BAT_CMD); v->dynBatPower = FieldCodec::getU16(frame, o + PO_DYN_BAT_PWR); v->heartbeat = FieldCodec::getU8(frame, o + PO_HEARTBEAT); v->hostState = FieldCodec::getU8(frame, o + PO_HOST_STATE); v->reserved1 = FieldCodec::getU32(frame, o + PO_RESV1); v->reserved2 = FieldCodec::getU32(frame, o + PO_RESV2); return true; } //============================================================================ // 0x0002 参数设定指令域 // 数据域 18 字节,偏移 0~17 //============================================================================ namespace { enum : size_t { PP_INS_H1 = 0, PP_INS_H2 = 1, PP_INS_H3 = 2, PP_INS_PWR = 3, PP_INS_RESV = 4, PP_DYN_H1 = 5, PP_DYN_H2 = 6, PP_DYN_H3 = 7, PP_DYN_PWR = 8, PP_DYN_RESV = 9, PP_RESV1 = 10, // u32 PP_RESV2 = 14, // u32 }; } std::vector PmParamSetMessage::encode(const void* obj) const { const PmParamSetValue* v = static_cast(obj); std::vector p(payloadLength(), 0); FieldCodec::putU8(p, PP_INS_H1, v->insSocHold1); FieldCodec::putU8(p, PP_INS_H2, v->insSocHold2); FieldCodec::putU8(p, PP_INS_H3, v->insSocHold3); FieldCodec::putU8(p, PP_INS_PWR, v->insOutputPower); FieldCodec::putU8(p, PP_INS_RESV, v->insReserved); FieldCodec::putU8(p, PP_DYN_H1, v->dynSocHold1); FieldCodec::putU8(p, PP_DYN_H2, v->dynSocHold2); FieldCodec::putU8(p, PP_DYN_H3, v->dynSocHold3); FieldCodec::putU8(p, PP_DYN_PWR, v->dynOutputPower); FieldCodec::putU8(p, PP_DYN_RESV, v->dynReserved); FieldCodec::putU32(p, PP_RESV1, v->reserved1); FieldCodec::putU32(p, PP_RESV2, v->reserved2); return Frame::build(id(), p, checksum()); } bool PmParamSetMessage::decode(const std::vector& frame, void* obj) const { if (!validateFrame(frame, id(), checksum(), totalLength())) return false; PmParamSetValue* v = static_cast(obj); size_t o = FRAME_HEADER_LEN; v->insSocHold1 = FieldCodec::getU8(frame, o + PP_INS_H1); v->insSocHold2 = FieldCodec::getU8(frame, o + PP_INS_H2); v->insSocHold3 = FieldCodec::getU8(frame, o + PP_INS_H3); v->insOutputPower = FieldCodec::getU8(frame, o + PP_INS_PWR); v->insReserved = FieldCodec::getU8(frame, o + PP_INS_RESV); v->dynSocHold1 = FieldCodec::getU8(frame, o + PP_DYN_H1); v->dynSocHold2 = FieldCodec::getU8(frame, o + PP_DYN_H2); v->dynSocHold3 = FieldCodec::getU8(frame, o + PP_DYN_H3); v->dynOutputPower = FieldCodec::getU8(frame, o + PP_DYN_PWR); v->dynReserved = FieldCodec::getU8(frame, o + PP_DYN_RESV); v->reserved1 = FieldCodec::getU32(frame, o + PP_RESV1); v->reserved2 = FieldCodec::getU32(frame, o + PP_RESV2); return true; } //============================================================================ // 0x0003 参数设定反馈域 // 数据域 2 字节 //============================================================================ std::vector PmParamSetFbMessage::encode(const void* obj) const { const PmParamSetFbValue* v = static_cast(obj); std::vector p(payloadLength(), 0); FieldCodec::putU8(p, 0, v->flag); FieldCodec::putU8(p, 1, v->failCode); return Frame::build(id(), p, checksum()); } bool PmParamSetFbMessage::decode(const std::vector& frame, void* obj) const { if (!validateFrame(frame, id(), checksum(), totalLength())) return false; PmParamSetFbValue* v = static_cast(obj); size_t o = FRAME_HEADER_LEN; v->flag = FieldCodec::getU8(frame, o + 0); v->failCode = FieldCodec::getU8(frame, o + 1); return true; } //============================================================================ // 0x0004 状态报文域 // 数据域 238 字节,偏移 0~237(对应文档字节 7~244) //============================================================================ namespace { enum : size_t { PS_MODE = 0, PS_STATUS = 1, PS_FL1 = 2, // u16 PS_FL2 = 4, PS_FL3 = 6, PS_FL4 = 8, PS_GEN_TIME = 10, // u16 PS_FAULT_LEVEL = 12, PS_OUT_POWER_LIMIT = 13, // u16 PS_GEN_POWER = 15, // u16 PS_H2_CAP = 17, PS_LO2_CAP = 18, PS_FC1_MIN_V = 19, PS_FC1_MIN_POS = 20, PS_FC1_AVG_V = 21, PS_FC2_MIN_V = 22, PS_FC2_MIN_POS = 23, PS_FC2_AVG_V = 24, PS_PALLADIUM = 25, // u16 PS_BUFFER_PRES = 27, PS_FLUE_TOTAL = 29, PS_FLUE_PRES = 31, PS_REACTOR_PRES = 33, PS_EVALVE_OPEN = 35, PS_MAIN_PIPE_PRES = 37, PS_AUX_PIPE_PRES = 39, PS_DCDC1_IN_V = 41, PS_DCDC1_IN_I = 43, PS_DCDC2_IN_V = 45, PS_DCDC2_IN_I = 47, PS_DCDC_OUT_V = 49, PS_DCDC_OUT_I = 51, PS_DCDC_CTRL_V = 53, PS_DCDC_AUX_V = 54, PS_METHANOL_TOTAL = 55, // u16 PS_METHANOL_FEED = 57, PS_O2_WATER = 59, PS_H2_WATER = 61, PS_BALLAST_WATER = 63, PS_EXH_IN_PRES = 65, PS_EXH_OUT_PRES = 67, PS_EXH_FREQ = 69, PS_EXH_IN_TEMP = 71, PS_EXH_OUT_TEMP = 73, PS_EXH_WIN_PRES = 75, PS_EXH_WOUT_PRES = 77, PS_TANK_LO2_PRES = 79, PS_TANK_CO2_PRES = 81, PS_TANK_LO2_LEVEL = 83, PS_ALLOY_H2_FLOW = 85, PS_FC_H2_FLOW = 87, PS_FC_O2_FLOW = 89, PS_EMER_DEPTH = 91, // u16 PS_EMER_TIME = 93, PS_CABIN_P1 = 95, PS_CABIN_P2 = 97, PS_CABIN_T1 = 99, PS_CABIN_T2 = 101, PS_CABIN_H1 = 103, PS_CABIN_H2 = 105, PS_H2_C1 = 107, PS_H2_C2 = 109, PS_H2_C3 = 111, PS_O2_C1 = 113, PS_O2_C2 = 115, PS_CH3OH_C1 = 117, PS_CH3OH_C2 = 119, PS_FLAME1 = 121, PS_FLAME2 = 122, PS_RESV1 = 123, // u16 PS_RESV2 = 125, // u16 PS_EB1_VOLTAGE = 127, // u16 PS_EB1_CURRENT = 129, PS_EB1_MAX_TEMP = 131, PS_EB1_FAULT = 133, PS_EB2_VOLTAGE = 135, PS_EB2_CURRENT = 137, PS_EB2_MAX_TEMP = 139, PS_EB2_FAULT = 141, PS_INS_CABIN_OX = 143, // u16 PS_INS_CABIN_TEMP = 145, PS_INS_CABIN_HUM = 147, PS_INS_CABIN_PRES = 149, PS_DYN_CABIN_OX = 151, PS_DYN_CABIN_TEMP = 153, PS_DYN_CABIN_HUM = 155, PS_DYN_CABIN_PRES = 157, PS_RESV3 = 159, // u8 PS_DYN_ALARM = 160, // u8 * 6 PS_INS_ALARM = 166, // u8 * 6 PS_INS_RELAY1 = 172, PS_INS_RELAY2 = 173, PS_DYN_RELAY1 = 174, PS_DYN_RELAY2 = 175, PS_INS_MAX_PWR = 176, // u16 PS_DYN_MAX_PWR = 178, // u16 PS_INS_SOC = 180, PS_DYN_SOC = 181, PS_INS_TOTAL_ENERGY= 182, // u16 PS_DYN_TOTAL_ENERGY= 184, // u16 PS_INS_PWR_IN = 186, // u16 PS_DYN_PWR_IN = 188, // u16 PS_INS_CHARGE_ST = 190, PS_DYN_CHARGE_ST = 191, PS_INS_V_LINK = 192, // u16 PS_INS_V_PACK = 194, // u16 PS_INS_CURRENT = 196, // u16 PS_INS_RES_POS = 198, // u16 PS_INS_RES_NEG = 200, // u16 PS_DYN_V_LINK = 202, // u16 PS_DYN_V_PACK = 204, // u16 PS_DYN_CURRENT = 206, // u16 PS_DYN_RES_POS = 208, // u16 PS_DYN_RES_NEG = 210, // u16 PS_INS_EMERGENCY = 212, PS_DYN_EMERGENCY = 213, PS_INS_SOC_H1 = 214, PS_INS_SOC_H2 = 215, PS_INS_SOC_H3 = 216, PS_INS_PWR_L1 = 217, PS_INS_PWR_L2 = 218, PS_DYN_SOC_H1 = 219, PS_DYN_SOC_H2 = 220, PS_DYN_SOC_H3 = 221, PS_DYN_PWR_L1 = 222, PS_DYN_PWR_L2 = 223, PS_ONLINE_FLAG1 = 224, // u32 PS_ONLINE_FLAG2 = 228, // u32 PS_RESV4 = 232, // u32 PS_HEARTBEAT = 236, PS_EMERGENCY_CMD = 237, }; inline void getU8Arr(const std::vector& f, size_t off, uint8_t* dst, size_t n) { for (size_t i = 0; i < n; ++i) dst[i] = f[off + i]; } inline void putU8Arr(std::vector& p, size_t off, const uint8_t* src, size_t n) { for (size_t i = 0; i < n; ++i) p[off + i] = src[i]; } } std::vector PmStatusMessage::encode(const void* obj) const { const PmStatusValue* v = static_cast(obj); std::vector p(payloadLength(), 0); FieldCodec::putU8(p, PS_MODE, v->fc_mode); FieldCodec::putU8(p, PS_STATUS, v->fc_status); FieldCodec::putU16(p, PS_FL1, v->fault_level_1); FieldCodec::putU16(p, PS_FL2, v->fault_level_2); FieldCodec::putU16(p, PS_FL3, v->fault_level_3); FieldCodec::putU16(p, PS_FL4, v->fault_level_4); FieldCodec::putU16(p, PS_GEN_TIME, v->total_generation_time); FieldCodec::putU8(p, PS_FAULT_LEVEL, v->fc_fault_level); FieldCodec::putU16(p, PS_OUT_POWER_LIMIT, v->output_power_limit); FieldCodec::putU16(p, PS_GEN_POWER, v->generation_power); FieldCodec::putU8(p, PS_H2_CAP, v->hydrogen_capacity); FieldCodec::putU8(p, PS_LO2_CAP, v->liquid_oxygen_capacity); FieldCodec::putU8(p, PS_FC1_MIN_V, v->fc1_min_cell_voltage); FieldCodec::putU8(p, PS_FC1_MIN_POS, v->fc1_min_cell_pos); FieldCodec::putU8(p, PS_FC1_AVG_V, v->fc1_avg_cell_voltage); FieldCodec::putU8(p, PS_FC2_MIN_V, v->fc2_min_cell_voltage); FieldCodec::putU8(p, PS_FC2_MIN_POS, v->fc2_min_cell_pos); FieldCodec::putU8(p, PS_FC2_AVG_V, v->fc2_avg_cell_voltage); FieldCodec::putU16(p, PS_PALLADIUM, v->palladium_temp); FieldCodec::putU16(p, PS_BUFFER_PRES, v->buffer_tank_pressure); FieldCodec::putU16(p, PS_FLUE_TOTAL, v->flue_total_emission); FieldCodec::putU16(p, PS_FLUE_PRES, v->flue_pressure); FieldCodec::putU16(p, PS_REACTOR_PRES, v->reactor_pressure); FieldCodec::putU16(p, PS_EVALVE_OPEN, v->electric_valve_open); FieldCodec::putU16(p, PS_MAIN_PIPE_PRES, v->main_pipe_pressure); FieldCodec::putU16(p, PS_AUX_PIPE_PRES, v->aux_pipe_pressure); FieldCodec::putU16(p, PS_DCDC1_IN_V, v->dcdc1_in_voltage); FieldCodec::putU16(p, PS_DCDC1_IN_I, v->dcdc1_in_current); FieldCodec::putU16(p, PS_DCDC2_IN_V, v->dcdc2_in_voltage); FieldCodec::putU16(p, PS_DCDC2_IN_I, v->dcdc2_in_current); FieldCodec::putU16(p, PS_DCDC_OUT_V, v->dcdc_out_voltage); FieldCodec::putU16(p, PS_DCDC_OUT_I, v->dcdc_out_current); FieldCodec::putU8(p, PS_DCDC_CTRL_V, v->dcdc_ctrl_voltage); FieldCodec::putU8(p, PS_DCDC_AUX_V, v->dcdc_aux_voltage); FieldCodec::putU16(p, PS_METHANOL_TOTAL, v->methanol_total_use); FieldCodec::putU16(p, PS_METHANOL_FEED, v->methanol_feed); FieldCodec::putU16(p, PS_O2_WATER, v->oxygen_side_water_level); FieldCodec::putU16(p, PS_H2_WATER, v->hydrogen_side_water_level); FieldCodec::putU16(p, PS_BALLAST_WATER, v->ballast_water_level); FieldCodec::putU16(p, PS_EXH_IN_PRES, v->exhaust_inlet_pressure); FieldCodec::putU16(p, PS_EXH_OUT_PRES, v->exhaust_outlet_pressure); FieldCodec::putU16(p, PS_EXH_FREQ, v->exhaust_run_freq); FieldCodec::putU16(p, PS_EXH_IN_TEMP, v->exhaust_inlet_temp); FieldCodec::putU16(p, PS_EXH_OUT_TEMP, v->exhaust_outlet_temp); FieldCodec::putU16(p, PS_EXH_WIN_PRES, v->exhaust_water_in_pressure); FieldCodec::putU16(p, PS_EXH_WOUT_PRES, v->exhaust_water_out_pressure); FieldCodec::putU16(p, PS_TANK_LO2_PRES, v->tank_lo2_pressure); FieldCodec::putU16(p, PS_TANK_CO2_PRES, v->tank_co2_pressure); FieldCodec::putU16(p, PS_TANK_LO2_LEVEL, v->tank_lo2_level); FieldCodec::putU16(p, PS_ALLOY_H2_FLOW, v->alloy_h2_flow); FieldCodec::putU16(p, PS_FC_H2_FLOW, v->fc_h2_flow); FieldCodec::putU16(p, PS_FC_O2_FLOW, v->fc_o2_flow); FieldCodec::putU16(p, PS_EMER_DEPTH, v->emergency_float_depth); FieldCodec::putU16(p, PS_EMER_TIME, v->emergency_float_time); FieldCodec::putU16(p, PS_CABIN_P1, v->cabin_pressure1); FieldCodec::putU16(p, PS_CABIN_P2, v->cabin_pressure2); FieldCodec::putU16(p, PS_CABIN_T1, v->cabin_temp1); FieldCodec::putU16(p, PS_CABIN_T2, v->cabin_temp2); FieldCodec::putU16(p, PS_CABIN_H1, v->cabin_humidity1); FieldCodec::putU16(p, PS_CABIN_H2, v->cabin_humidity2); FieldCodec::putU16(p, PS_H2_C1, v->h2_concentration1); FieldCodec::putU16(p, PS_H2_C2, v->h2_concentration2); FieldCodec::putU16(p, PS_H2_C3, v->h2_concentration3); FieldCodec::putU16(p, PS_O2_C1, v->o2_concentration1); FieldCodec::putU16(p, PS_O2_C2, v->o2_concentration2); FieldCodec::putU16(p, PS_CH3OH_C1, v->ch3oh_concentration1); FieldCodec::putU16(p, PS_CH3OH_C2, v->ch3oh_concentration2); FieldCodec::putU8(p, PS_FLAME1, v->flame_detector1); FieldCodec::putU8(p, PS_FLAME2, v->flame_detector2); FieldCodec::putU16(p, PS_RESV1, v->pmReserved1); FieldCodec::putU16(p, PS_RESV2, v->pmReserved2); FieldCodec::putU16(p, PS_EB1_VOLTAGE, v->emergency_battery1_voltage); FieldCodec::putU16(p, PS_EB1_CURRENT, v->emergency_battery1_current); FieldCodec::putU16(p, PS_EB1_MAX_TEMP, v->emergency_battery1_max_temp); FieldCodec::putU16(p, PS_EB1_FAULT, v->emergency_battery1_fault_word); FieldCodec::putU16(p, PS_EB2_VOLTAGE, v->emergency_battery2_voltage); FieldCodec::putU16(p, PS_EB2_CURRENT, v->emergency_battery2_current); FieldCodec::putU16(p, PS_EB2_MAX_TEMP, v->emergency_battery2_max_temp); FieldCodec::putU16(p, PS_EB2_FAULT, v->emergency_battery2_fault_word); FieldCodec::putU16(p, PS_INS_CABIN_OX, v->ins_cabin_ox_concentration); FieldCodec::putU16(p, PS_INS_CABIN_TEMP, v->ins_cabin_temperature); FieldCodec::putU16(p, PS_INS_CABIN_HUM, v->ins_cabin_humidity); FieldCodec::putU16(p, PS_INS_CABIN_PRES, v->ins_cabin_pressure); FieldCodec::putU16(p, PS_DYN_CABIN_OX, v->dyn_cabin_ox_concentration); FieldCodec::putU16(p, PS_DYN_CABIN_TEMP, v->dyn_cabin_temperature); FieldCodec::putU16(p, PS_DYN_CABIN_HUM, v->dyn_cabin_humidity); FieldCodec::putU16(p, PS_DYN_CABIN_PRES, v->dyn_cabin_pressure); FieldCodec::putU8(p, PS_RESV3, v->pmReserved3); putU8Arr(p, PS_DYN_ALARM, v->dyn_alarm_flag, 6); putU8Arr(p, PS_INS_ALARM, v->ins_alarm_flag, 6); FieldCodec::putU8(p, PS_INS_RELAY1, v->ins_relay_status1); FieldCodec::putU8(p, PS_INS_RELAY2, v->ins_relay_status2); FieldCodec::putU8(p, PS_DYN_RELAY1, v->dyn_relay_status1); FieldCodec::putU8(p, PS_DYN_RELAY2, v->dyn_relay_status2); FieldCodec::putU16(p, PS_INS_MAX_PWR, v->ins_max_discharge_power); FieldCodec::putU16(p, PS_DYN_MAX_PWR, v->dyn_max_discharge_power); FieldCodec::putU8(p, PS_INS_SOC, v->ins_soc); FieldCodec::putU8(p, PS_DYN_SOC, v->dyn_soc); FieldCodec::putU16(p, PS_INS_TOTAL_ENERGY, v->ins_total_energy); FieldCodec::putU16(p, PS_DYN_TOTAL_ENERGY, v->dyn_total_energy); FieldCodec::putU16(p, PS_INS_PWR_IN, v->ins_power_input); FieldCodec::putU16(p, PS_DYN_PWR_IN, v->dyn_power_input); FieldCodec::putU8(p, PS_INS_CHARGE_ST, v->ins_charge_status); FieldCodec::putU8(p, PS_DYN_CHARGE_ST, v->dyn_charge_status); FieldCodec::putU16(p, PS_INS_V_LINK, v->ins_voltage_link); FieldCodec::putU16(p, PS_INS_V_PACK, v->ins_voltage_pack); FieldCodec::putU16(p, PS_INS_CURRENT, v->ins_current); FieldCodec::putU16(p, PS_INS_RES_POS, v->ins_resistance_pos); FieldCodec::putU16(p, PS_INS_RES_NEG, v->ins_resistance_neg); FieldCodec::putU16(p, PS_DYN_V_LINK, v->dyn_voltage_link); FieldCodec::putU16(p, PS_DYN_V_PACK, v->dyn_voltage_pack); FieldCodec::putU16(p, PS_DYN_CURRENT, v->dyn_current); FieldCodec::putU16(p, PS_DYN_RES_POS, v->dyn_resistance_pos); FieldCodec::putU16(p, PS_DYN_RES_NEG, v->dyn_resistance_neg); FieldCodec::putU8(p, PS_INS_EMERGENCY, v->ins_emergency_status); FieldCodec::putU8(p, PS_DYN_EMERGENCY, v->dyn_emergency_status); FieldCodec::putU8(p, PS_INS_SOC_H1, v->ins_soc_threshold1); FieldCodec::putU8(p, PS_INS_SOC_H2, v->ins_soc_threshold2); FieldCodec::putU8(p, PS_INS_SOC_H3, v->ins_soc_threshold3); FieldCodec::putU8(p, PS_INS_PWR_L1, v->ins_power_limit1); FieldCodec::putU8(p, PS_INS_PWR_L2, v->ins_power_limit2); FieldCodec::putU8(p, PS_DYN_SOC_H1, v->dyn_soc_threshold1); FieldCodec::putU8(p, PS_DYN_SOC_H2, v->dyn_soc_threshold2); FieldCodec::putU8(p, PS_DYN_SOC_H3, v->dyn_soc_threshold3); FieldCodec::putU8(p, PS_DYN_PWR_L1, v->dyn_power_limit1); FieldCodec::putU8(p, PS_DYN_PWR_L2, v->dyn_power_limit2); FieldCodec::putU32(p, PS_ONLINE_FLAG1, v->device_online_flag1); FieldCodec::putU32(p, PS_ONLINE_FLAG2, v->device_online_flag2); FieldCodec::putU32(p, PS_RESV4, v->pmReserved4); FieldCodec::putU8(p, PS_HEARTBEAT, v->heartbeat); FieldCodec::putU8(p, PS_EMERGENCY_CMD, v->emergency_cmd); return Frame::build(id(), p, checksum()); } bool PmStatusMessage::decode(const std::vector& frame, void* obj) const { if (!validateFrame(frame, id(), checksum(), totalLength())) return false; PmStatusValue* v = static_cast(obj); size_t o = FRAME_HEADER_LEN; v->fc_mode = FieldCodec::getU8(frame, o + PS_MODE); v->fc_status = FieldCodec::getU8(frame, o + PS_STATUS); v->fault_level_1 = FieldCodec::getU16(frame, o + PS_FL1); v->fault_level_2 = FieldCodec::getU16(frame, o + PS_FL2); v->fault_level_3 = FieldCodec::getU16(frame, o + PS_FL3); v->fault_level_4 = FieldCodec::getU16(frame, o + PS_FL4); v->total_generation_time = FieldCodec::getU16(frame, o + PS_GEN_TIME); v->fc_fault_level = FieldCodec::getU8(frame, o + PS_FAULT_LEVEL); v->output_power_limit = FieldCodec::getU16(frame, o + PS_OUT_POWER_LIMIT); v->generation_power = FieldCodec::getU16(frame, o + PS_GEN_POWER); v->hydrogen_capacity = FieldCodec::getU8(frame, o + PS_H2_CAP); v->liquid_oxygen_capacity = FieldCodec::getU8(frame, o + PS_LO2_CAP); v->fc1_min_cell_voltage = FieldCodec::getU8(frame, o + PS_FC1_MIN_V); v->fc1_min_cell_pos = FieldCodec::getU8(frame, o + PS_FC1_MIN_POS); v->fc1_avg_cell_voltage = FieldCodec::getU8(frame, o + PS_FC1_AVG_V); v->fc2_min_cell_voltage = FieldCodec::getU8(frame, o + PS_FC2_MIN_V); v->fc2_min_cell_pos = FieldCodec::getU8(frame, o + PS_FC2_MIN_POS); v->fc2_avg_cell_voltage = FieldCodec::getU8(frame, o + PS_FC2_AVG_V); v->palladium_temp = FieldCodec::getU16(frame, o + PS_PALLADIUM); v->buffer_tank_pressure = FieldCodec::getU16(frame, o + PS_BUFFER_PRES); v->flue_total_emission = FieldCodec::getU16(frame, o + PS_FLUE_TOTAL); v->flue_pressure = FieldCodec::getU16(frame, o + PS_FLUE_PRES); v->reactor_pressure = FieldCodec::getU16(frame, o + PS_REACTOR_PRES); v->electric_valve_open = FieldCodec::getU16(frame, o + PS_EVALVE_OPEN); v->main_pipe_pressure = FieldCodec::getU16(frame, o + PS_MAIN_PIPE_PRES); v->aux_pipe_pressure = FieldCodec::getU16(frame, o + PS_AUX_PIPE_PRES); v->dcdc1_in_voltage = FieldCodec::getU16(frame, o + PS_DCDC1_IN_V); v->dcdc1_in_current = FieldCodec::getU16(frame, o + PS_DCDC1_IN_I); v->dcdc2_in_voltage = FieldCodec::getU16(frame, o + PS_DCDC2_IN_V); v->dcdc2_in_current = FieldCodec::getU16(frame, o + PS_DCDC2_IN_I); v->dcdc_out_voltage = FieldCodec::getU16(frame, o + PS_DCDC_OUT_V); v->dcdc_out_current = FieldCodec::getU16(frame, o + PS_DCDC_OUT_I); v->dcdc_ctrl_voltage = FieldCodec::getU8(frame, o + PS_DCDC_CTRL_V); v->dcdc_aux_voltage = FieldCodec::getU8(frame, o + PS_DCDC_AUX_V); v->methanol_total_use = FieldCodec::getU16(frame, o + PS_METHANOL_TOTAL); v->methanol_feed = FieldCodec::getU16(frame, o + PS_METHANOL_FEED); v->oxygen_side_water_level = FieldCodec::getU16(frame, o + PS_O2_WATER); v->hydrogen_side_water_level = FieldCodec::getU16(frame, o + PS_H2_WATER); v->ballast_water_level = FieldCodec::getU16(frame, o + PS_BALLAST_WATER); v->exhaust_inlet_pressure = FieldCodec::getU16(frame, o + PS_EXH_IN_PRES); v->exhaust_outlet_pressure = FieldCodec::getU16(frame, o + PS_EXH_OUT_PRES); v->exhaust_run_freq = FieldCodec::getU16(frame, o + PS_EXH_FREQ); v->exhaust_inlet_temp = FieldCodec::getU16(frame, o + PS_EXH_IN_TEMP); v->exhaust_outlet_temp = FieldCodec::getU16(frame, o + PS_EXH_OUT_TEMP); v->exhaust_water_in_pressure = FieldCodec::getU16(frame, o + PS_EXH_WIN_PRES); v->exhaust_water_out_pressure = FieldCodec::getU16(frame, o + PS_EXH_WOUT_PRES); v->tank_lo2_pressure = FieldCodec::getU16(frame, o + PS_TANK_LO2_PRES); v->tank_co2_pressure = FieldCodec::getU16(frame, o + PS_TANK_CO2_PRES); v->tank_lo2_level = FieldCodec::getU16(frame, o + PS_TANK_LO2_LEVEL); v->alloy_h2_flow = FieldCodec::getU16(frame, o + PS_ALLOY_H2_FLOW); v->fc_h2_flow = FieldCodec::getU16(frame, o + PS_FC_H2_FLOW); v->fc_o2_flow = FieldCodec::getU16(frame, o + PS_FC_O2_FLOW); v->emergency_float_depth = FieldCodec::getU16(frame, o + PS_EMER_DEPTH); v->emergency_float_time = FieldCodec::getU16(frame, o + PS_EMER_TIME); v->cabin_pressure1 = FieldCodec::getU16(frame, o + PS_CABIN_P1); v->cabin_pressure2 = FieldCodec::getU16(frame, o + PS_CABIN_P2); v->cabin_temp1 = FieldCodec::getU16(frame, o + PS_CABIN_T1); v->cabin_temp2 = FieldCodec::getU16(frame, o + PS_CABIN_T2); v->cabin_humidity1 = FieldCodec::getU16(frame, o + PS_CABIN_H1); v->cabin_humidity2 = FieldCodec::getU16(frame, o + PS_CABIN_H2); v->h2_concentration1 = FieldCodec::getU16(frame, o + PS_H2_C1); v->h2_concentration2 = FieldCodec::getU16(frame, o + PS_H2_C2); v->h2_concentration3 = FieldCodec::getU16(frame, o + PS_H2_C3); v->o2_concentration1 = FieldCodec::getU16(frame, o + PS_O2_C1); v->o2_concentration2 = FieldCodec::getU16(frame, o + PS_O2_C2); v->ch3oh_concentration1 = FieldCodec::getU16(frame, o + PS_CH3OH_C1); v->ch3oh_concentration2 = FieldCodec::getU16(frame, o + PS_CH3OH_C2); v->flame_detector1 = FieldCodec::getU8(frame, o + PS_FLAME1); v->flame_detector2 = FieldCodec::getU8(frame, o + PS_FLAME2); v->pmReserved1 = FieldCodec::getU16(frame, o + PS_RESV1); v->pmReserved2 = FieldCodec::getU16(frame, o + PS_RESV2); v->emergency_battery1_voltage = FieldCodec::getU16(frame, o + PS_EB1_VOLTAGE); v->emergency_battery1_current = FieldCodec::getU16(frame, o + PS_EB1_CURRENT); v->emergency_battery1_max_temp = FieldCodec::getU16(frame, o + PS_EB1_MAX_TEMP); v->emergency_battery1_fault_word = FieldCodec::getU16(frame, o + PS_EB1_FAULT); v->emergency_battery2_voltage = FieldCodec::getU16(frame, o + PS_EB2_VOLTAGE); v->emergency_battery2_current = FieldCodec::getU16(frame, o + PS_EB2_CURRENT); v->emergency_battery2_max_temp = FieldCodec::getU16(frame, o + PS_EB2_MAX_TEMP); v->emergency_battery2_fault_word = FieldCodec::getU16(frame, o + PS_EB2_FAULT); v->ins_cabin_ox_concentration = FieldCodec::getU16(frame, o + PS_INS_CABIN_OX); v->ins_cabin_temperature = FieldCodec::getU16(frame, o + PS_INS_CABIN_TEMP); v->ins_cabin_humidity = FieldCodec::getU16(frame, o + PS_INS_CABIN_HUM); v->ins_cabin_pressure = FieldCodec::getU16(frame, o + PS_INS_CABIN_PRES); v->dyn_cabin_ox_concentration = FieldCodec::getU16(frame, o + PS_DYN_CABIN_OX); v->dyn_cabin_temperature = FieldCodec::getU16(frame, o + PS_DYN_CABIN_TEMP); v->dyn_cabin_humidity = FieldCodec::getU16(frame, o + PS_DYN_CABIN_HUM); v->dyn_cabin_pressure = FieldCodec::getU16(frame, o + PS_DYN_CABIN_PRES); v->pmReserved3 = FieldCodec::getU8(frame, o + PS_RESV3); getU8Arr(frame, o + PS_DYN_ALARM, v->dyn_alarm_flag, 6); getU8Arr(frame, o + PS_INS_ALARM, v->ins_alarm_flag, 6); v->ins_relay_status1 = FieldCodec::getU8(frame, o + PS_INS_RELAY1); v->ins_relay_status2 = FieldCodec::getU8(frame, o + PS_INS_RELAY2); v->dyn_relay_status1 = FieldCodec::getU8(frame, o + PS_DYN_RELAY1); v->dyn_relay_status2 = FieldCodec::getU8(frame, o + PS_DYN_RELAY2); v->ins_max_discharge_power = FieldCodec::getU16(frame, o + PS_INS_MAX_PWR); v->dyn_max_discharge_power = FieldCodec::getU16(frame, o + PS_DYN_MAX_PWR); v->ins_soc = FieldCodec::getU8(frame, o + PS_INS_SOC); v->dyn_soc = FieldCodec::getU8(frame, o + PS_DYN_SOC); v->ins_total_energy = FieldCodec::getU16(frame, o + PS_INS_TOTAL_ENERGY); v->dyn_total_energy = FieldCodec::getU16(frame, o + PS_DYN_TOTAL_ENERGY); v->ins_power_input = FieldCodec::getU16(frame, o + PS_INS_PWR_IN); v->dyn_power_input = FieldCodec::getU16(frame, o + PS_DYN_PWR_IN); v->ins_charge_status = FieldCodec::getU8(frame, o + PS_INS_CHARGE_ST); v->dyn_charge_status = FieldCodec::getU8(frame, o + PS_DYN_CHARGE_ST); v->ins_voltage_link = FieldCodec::getU16(frame, o + PS_INS_V_LINK); v->ins_voltage_pack = FieldCodec::getU16(frame, o + PS_INS_V_PACK); v->ins_current = FieldCodec::getU16(frame, o + PS_INS_CURRENT); v->ins_resistance_pos = FieldCodec::getU16(frame, o + PS_INS_RES_POS); v->ins_resistance_neg = FieldCodec::getU16(frame, o + PS_INS_RES_NEG); v->dyn_voltage_link = FieldCodec::getU16(frame, o + PS_DYN_V_LINK); v->dyn_voltage_pack = FieldCodec::getU16(frame, o + PS_DYN_V_PACK); v->dyn_current = FieldCodec::getU16(frame, o + PS_DYN_CURRENT); v->dyn_resistance_pos = FieldCodec::getU16(frame, o + PS_DYN_RES_POS); v->dyn_resistance_neg = FieldCodec::getU16(frame, o + PS_DYN_RES_NEG); v->ins_emergency_status = FieldCodec::getU8(frame, o + PS_INS_EMERGENCY); v->dyn_emergency_status = FieldCodec::getU8(frame, o + PS_DYN_EMERGENCY); v->ins_soc_threshold1 = FieldCodec::getU8(frame, o + PS_INS_SOC_H1); v->ins_soc_threshold2 = FieldCodec::getU8(frame, o + PS_INS_SOC_H2); v->ins_soc_threshold3 = FieldCodec::getU8(frame, o + PS_INS_SOC_H3); v->ins_power_limit1 = FieldCodec::getU8(frame, o + PS_INS_PWR_L1); v->ins_power_limit2 = FieldCodec::getU8(frame, o + PS_INS_PWR_L2); v->dyn_soc_threshold1 = FieldCodec::getU8(frame, o + PS_DYN_SOC_H1); v->dyn_soc_threshold2 = FieldCodec::getU8(frame, o + PS_DYN_SOC_H2); v->dyn_soc_threshold3 = FieldCodec::getU8(frame, o + PS_DYN_SOC_H3); v->dyn_power_limit1 = FieldCodec::getU8(frame, o + PS_DYN_PWR_L1); v->dyn_power_limit2 = FieldCodec::getU8(frame, o + PS_DYN_PWR_L2); v->device_online_flag1 = FieldCodec::getU32(frame, o + PS_ONLINE_FLAG1); v->device_online_flag2 = FieldCodec::getU32(frame, o + PS_ONLINE_FLAG2); v->pmReserved4 = FieldCodec::getU32(frame, o + PS_RESV4); v->heartbeat = FieldCodec::getU8(frame, o + PS_HEARTBEAT); v->emergency_cmd = FieldCodec::getU8(frame, o + PS_EMERGENCY_CMD); return true; } } // namespace ccu