Files
zjk e0488d513b 协议:按0824协议更新复合管控通信解析 + 新增燃料电池监控网页
- pmSysvariable/ccuUdpMsg: 域起始符改为0x40 0x40,域标识符重编号0x0001~0x0004,
  ccuState/ccuColCmd/ccuSetParmCmd 按新协议字段布局与字节序重写(状态248B/操控45B/参数28B)
- systemData/httpserver: 新增FC单片电压、甲醇制氢装置、DC/DC、尾气装置、一体化罐、
  供氢供氧流量、应急上浮等字段解析与WebSocket JSON推送
- 新增 /fcs 燃料电池监控页(fuelcell.h):实时数据显示 + 操控指令交互按钮,
  过滤日志推送消息避免界面闪烁
- SQLite/LowerCommManager/测试:更新建表列、解析打印与单元/集成测试适配新协议
2026-08-26 20:56:39 +08:00

202 lines
7.6 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//=======================================================================
// SystemDataTest: SystemData 的故障检测逻辑(断路器映射、绝缘、电源失电、
// 漏水、DCDC、继电器位提取、缩放、故障码集合、漏水位)。
// 不改动生产代码;仅链接现有 systemData.h + SQLite + MOOS。
//=======================================================================
#include <gtest/gtest.h>
#include "MOOS/libMOOS/Utils/MOOSUtilityFunctions.h" // MOOSTime (updateCommonStatus)
#include "systemData.h"
#include "faultCode.h"
TEST(SystemDataTest, BreakerMapping)
{
SystemData sd;
unsigned char status = 0;
// 0x55 = 闭合(1),无故障码
sd.updateBreakerFault(status, 0x55, 99);
EXPECT_EQ(status, 1u);
EXPECT_EQ(sd.disSysFaultCode.count(99), 0u);
// 0xAA = 断开(0),无故障码
sd.updateBreakerFault(status, 0xAA, 99);
EXPECT_EQ(status, 0u);
EXPECT_EQ(sd.disSysFaultCode.count(99), 0u);
// 0x5A = 故障脱扣(2),插入故障码
sd.updateBreakerFault(status, 0x5A, 99);
EXPECT_EQ(status, 2u);
EXPECT_EQ(sd.disSysFaultCode.count(99), 1u);
// 再次正常后擦除
sd.updateBreakerFault(status, 0x55, 99);
EXPECT_EQ(sd.disSysFaultCode.count(99), 0u);
}
TEST(SystemDataTest, HighVolBusFaultDetection)
{
SystemData sd;
disHighVolBusState s{};
// 全 0xAA(断开,正常)
s.fuelCellCircuitBreaker = 0xAA;
s.powerLithiumBatteryCircuitBreaker = 0xAA;
s.propulsionMotorCircuitBreaker = 0xAA;
s.lithiumBatteryGroupInstrumentCircuitBreaker = 0xAA;
s.dcDc5ModuleCircuitBreaker = 0xAA;
s.bowHighVoltageDistributionBoxCircuitBreaker = 0xAA;
s.sternFTDevice45CircuitBreaker = 0xAA;
s.sternRudderSwitch1CircuitBreaker = 0xAA;
s.sternRudderSwitch2CircuitBreaker = 0xAA;
s.powerBusInsulationStatus = 0x55;
s.aBusInsulationStatus = 0x55;
s.meterPowerLossSignal = 0x55;
s.emergencyPowerLossSignal = 0x55;
sd.updateSystemData(s);
EXPECT_EQ(sd.power_bus_status.fuelCellCircuitBreaker, 0u);
EXPECT_EQ(sd.disSysFaultCode.count(1), 0u);
// 燃料电断路器故障脱扣
s.fuelCellCircuitBreaker = 0x5A;
sd.updateSystemData(s);
EXPECT_EQ(sd.power_bus_status.fuelCellCircuitBreaker, 2u);
EXPECT_EQ(sd.disSysFaultCode.count(1), 1u);
// 动力锂电池闭合 + A汇流排/动力母排绝缘低 → 34/35
s.fuelCellCircuitBreaker = 0xAA;
s.powerLithiumBatteryCircuitBreaker = 0x55;
s.powerBusInsulationStatus = 0xAA;
s.aBusInsulationStatus = 0xAA;
sd.updateSystemData(s);
EXPECT_EQ(sd.disSysFaultCode.count(34), 1u);
EXPECT_EQ(sd.disSysFaultCode.count(35), 1u);
EXPECT_EQ(sd.power_bus_status.powerBusInsulationStatus, 1u);
EXPECT_EQ(sd.power_bus_status.aBusInsulationStatus, 1u);
// 电源失电 → 36/37
s.meterPowerLossSignal = 0xAA;
s.emergencyPowerLossSignal = 0xAA;
sd.updateSystemData(s);
EXPECT_EQ(sd.disSysFaultCode.count(36), 1u);
EXPECT_EQ(sd.disSysFaultCode.count(37), 1u);
// 全部恢复正常后故障码擦除
s.powerLithiumBatteryCircuitBreaker = 0xAA;
s.powerBusInsulationStatus = 0x55;
s.aBusInsulationStatus = 0x55;
s.meterPowerLossSignal = 0x55;
s.emergencyPowerLossSignal = 0x55;
sd.updateSystemData(s);
EXPECT_EQ(sd.disSysFaultCode.count(34), 0u);
EXPECT_EQ(sd.disSysFaultCode.count(35), 0u);
EXPECT_EQ(sd.disSysFaultCode.count(36), 0u);
EXPECT_EQ(sd.disSysFaultCode.count(37), 0u);
}
TEST(SystemDataTest, HighAVolBusFaultDetection)
{
SystemData sd;
disHighAVolBusState s{};
s.actuatorCircuitBreaker = 0x5A; // 启闭机构断路器脱扣 → 14
s.xczCircuitBreaker = 0x55;
s.instrumentPowerFailureSignal = 0x55;
s.emergencyPowerFailureSignal = 0x55;
s.waterIngressionAlarm = 0x55;
sd.updateSystemData(s);
EXPECT_EQ(sd.power_a_bus_status.actuatorCircuitBreaker, 2u);
EXPECT_EQ(sd.disSysFaultCode.count(14), 1u);
s.actuatorCircuitBreaker = 0xAA;
s.instrumentPowerFailureSignal = 0xAA; // 失电 → 38
s.emergencyPowerFailureSignal = 0xAA; // 失电 → 39
s.waterIngressionAlarm = 0xAA; // 浸水 → leakStatus[BOW_HIGH_VOLTAGE]
sd.updateSystemData(s);
EXPECT_EQ(sd.disSysFaultCode.count(14), 0u);
EXPECT_EQ(sd.disSysFaultCode.count(38), 1u);
EXPECT_EQ(sd.disSysFaultCode.count(39), 1u);
EXPECT_TRUE(sd.leakStatus[SystemData::LEAKAGE_BOW_HIGH_VOLTAGE]);
}
TEST(SystemDataTest, LowMainBusFaultDetection)
{
SystemData sd;
disLowMainBusState s{};
s.lithiumBatteryGroupInstrumentCircuitBreaker = 0x5A; // 19
s.unit4InstrumentDC48VCircuitBreaker = 0x5A; // 21
s.instrumentPowerFailureSignal = 0xAA; // 41
s.emergencyPowerFailureSignal = 0xAA; // 42
s.instrumentBusbarInsulationLow = 0xAA; // 43
sd.updateSystemData(s);
EXPECT_EQ(sd.disSysFaultCode.count(19), 1u);
EXPECT_EQ(sd.disSysFaultCode.count(21), 1u);
EXPECT_EQ(sd.disSysFaultCode.count(41), 1u);
EXPECT_EQ(sd.disSysFaultCode.count(42), 1u);
EXPECT_EQ(sd.disSysFaultCode.count(43), 1u);
}
TEST(SystemDataTest, LowBusFaultDetection)
{
SystemData sd;
disLowBusState s{};
s.unit1CircuitBreaker = 0x5A; // 26
s.emergencyLithiumBatteryGroup1CircuitBreaker = 0x5A; // 33
s.powerFailureSignal = 0xAA; // 44
s.emergencyPowerFailureSignal = 0xAA; // 45
s.waterIngressionAlarm = 0xAA; // leakage BOW_LOW_VOLTAGE
sd.updateSystemData(s);
EXPECT_EQ(sd.disSysFaultCode.count(26), 1u);
EXPECT_EQ(sd.disSysFaultCode.count(33), 1u);
EXPECT_EQ(sd.disSysFaultCode.count(44), 1u);
EXPECT_EQ(sd.disSysFaultCode.count(45), 1u);
EXPECT_TRUE(sd.leakStatus[SystemData::LEAKAGE_BOW_LOW_VOLTAGE]);
}
TEST(SystemDataTest, CcuStateScalingAndRelayBits)
{
SystemData sd;
ccuState c{};
c.ins_soc = 60;
c.dyn_soc = 80;
c.ins_relay_status1 = 0x12; // 高4位=1(充电), 低4位=2(正极)
c.ins_relay_status2 = 0x34;
c.ins_voltage_link = 4800; // ×0.1 = 480.0
sd.updateSystemData(c);
EXPECT_EQ(sd.ins_soc, 60);
EXPECT_EQ(sd.dyn_soc, 80);
EXPECT_EQ(sd.ins_pos_relay_status, 2u); // 低4位
EXPECT_EQ(sd.ins_charge_relay_status, 1u); // 高4位
EXPECT_EQ(sd.ins_precharge_relay_status, 4u); // 低4位 of status2
EXPECT_EQ(sd.ins_neg_relay_status, 3u); // 高4位 of status2
EXPECT_NEAR(sd.ins_voltage_link, 480.0, 0.01);
EXPECT_EQ(sd.water_leak_status_from_insbat, 0u);
EXPECT_EQ(sd.dcdc_status_from_insbat, 0u);
EXPECT_FALSE(sd.leakStatus[SystemData::LEAKAGE_LI_BATTERY]);
}
TEST(SystemDataTest, FaultCodeSetAndLevel)
{
SystemData sd;
EXPECT_EQ(sd.getFaultCodeLevel(), 0u);
sd.insertFaultCode(0x1102); // 0x11>>... level = (0x1102>>8)&0xF = 1
EXPECT_EQ(sd.getFaultCodeLevel(), 1u);
sd.insertFaultCode(0x4402); // level = (0x4402>>8)&0xF = 4
EXPECT_EQ(sd.getFaultCodeLevel(), 4u);
sd.eraseFaultCode(0x4402);
EXPECT_EQ(sd.getFaultCodeLevel(), 1u);
auto codes = sd.getFaultCode();
EXPECT_EQ(codes.count(0x1102), 1u);
}
TEST(SystemDataTest, LeakageCodeGeneration)
{
SystemData sd;
EXPECT_EQ(sd.generateLeakageCode(), 0u);
sd.leakStatus[SystemData::LEAKAGE_BOW_EMERGENCY] = true; // 0x01
sd.leakStatus[SystemData::LEAKAGE_FUEL_CELL] = true; // 0x08
sd.leakStatus[SystemData::LEAKAGE_LI_BATTERY] = true; // 0x10
EXPECT_EQ(sd.generateLeakageCode(), 0x19u);
}
TEST(SystemDataTest, CommonStatusTimeout)
{
SystemData sd;
sd.updateCommonStatus(30.0);
// 新建 SystemData 的 lastUpdateTime=0,与当前 MOOSTime 之差远大于 30s
EXPECT_TRUE(sd.device_common_status.ccu_status.isTimeout);
}