增加了xc声纳的上电
This commit is contained in:
Vendored
+2
-1
@@ -86,7 +86,8 @@
|
||||
"stack": "cpp",
|
||||
"cstdbool": "cpp",
|
||||
"version": "cpp",
|
||||
"unordered_set": "cpp"
|
||||
"unordered_set": "cpp",
|
||||
"ranges": "cpp"
|
||||
},
|
||||
"C_Cpp.errorSquiggles": "disabled",
|
||||
"marscode.chatLanguage": "cn",
|
||||
|
||||
+1
-1
@@ -103,4 +103,4 @@ ENDIF( ${WIN32} )
|
||||
# Add Subdirectories
|
||||
#=======================================================================
|
||||
ADD_SUBDIRECTORY( src )
|
||||
# ADD_SUBDIRECTORY( test )
|
||||
ADD_SUBDIRECTORY( test )
|
||||
|
||||
@@ -4,4 +4,6 @@ ProcessConfig = pPowerManger
|
||||
{
|
||||
AppTick = 4
|
||||
CommsTick = 4
|
||||
log_level = INFO
|
||||
log_file = ./logfile.log
|
||||
}
|
||||
@@ -1,47 +1 @@
|
||||
{
|
||||
"HVABFTDev123Cur_uint16": 0,
|
||||
"HVABactCur_uint16": 0,
|
||||
"HVABbowRudCur_uint16": 0,
|
||||
"HVABbusBCur_uint16": 0,
|
||||
"HVABbusBVol_uint16": 0,
|
||||
"HVABmastSteGeaCur_uint16": 0,
|
||||
"HVABopenWaterCur_uint16": 0,
|
||||
"HVABxczCur_uint16": 0,
|
||||
"HVBBCCUCur_uint16": 0,
|
||||
"HVBBFCSSecurSysCur_uint16": 0,
|
||||
"HVBBbatInsCur_uint16": 0,
|
||||
"HVBBbowLowVolDisBoxCur_uint16": 0,
|
||||
"HVBBdcC1InsCur_uint16": 0,
|
||||
"HVBBemer2BusVol_uint16": 0,
|
||||
"HVBBemerBatCur_uint16": 0,
|
||||
"HVBBinsBusVol_uint16": 0,
|
||||
"HVBBplcCur_uint16": 0,
|
||||
"HVBBreservedCur1_uint16": 0,
|
||||
"HVBBreservedCur2_uint16": 0,
|
||||
"HVBBunit4Cur_uint16": 0,
|
||||
"HVBFTDev45Cur_uint16": 0,
|
||||
"HVBbatGroupCur_uint16": 0,
|
||||
"HVBbowHVolDisBoxCur_uint16": 0,
|
||||
"HVBbusACur_uint16": 0,
|
||||
"HVBbusAVol_uint16": 0,
|
||||
"HVBdcDc5Cur_uint16": 0,
|
||||
"HVBfbCur_uint16": 0,
|
||||
"HVBmotorCur_uint16": 0,
|
||||
"HVBpowerBusCur_uint16": 0,
|
||||
"HVBpowerBusVol_uint16": 0,
|
||||
"HVBreservedCur1_uint16": 0,
|
||||
"HVBreservedCur2_uint16": 0,
|
||||
"HVBreservedCur3_uint16": 0,
|
||||
"HVBsternRud1Cur_uint16": 0,
|
||||
"HVBsternRud2Cur_uint16": 0,
|
||||
"HVBtyzCur_uint16": 0,
|
||||
"LVBBbowPZDevCur_uint16": 0,
|
||||
"LVBBemerBatCur_uint16": 0,
|
||||
"LVBBemerBusVol_uint16": 0,
|
||||
"LVBBinsBusCur_uint16": 0,
|
||||
"LVBBunit1Cur_uint16": 0,
|
||||
"LVBBunit2Cur_uint16": 0,
|
||||
"LVBBunit3Cur_uint16": 0,
|
||||
"LVBBunit5Cur_uint16": 0,
|
||||
"LVBinsBusVol_uint16": 0
|
||||
}
|
||||
{"uPower_currentState_st":{"HVABFTDev123Cur_uint16":0,"HVABactCur_uint16":0,"HVABbowRudCur_uint16":0,"HVABbusBCur_uint16":0,"HVABbusBVol_uint16":0,"HVABmastSteGeaCur_uint16":0,"HVABopenWaterCur_uint16":0,"HVABxczCur_uint16":0,"HVBBCCUCur_uint16":0,"HVBBFCSSecurSysCur_uint16":0,"HVBBbatInsCur_uint16":0,"HVBBbowLowVolDisBoxCur_uint16":0,"HVBBdcC1InsCur_uint16":0,"HVBBemer2BusVol_uint16":0,"HVBBemerBatCur_uint16":0,"HVBBinsBusVol_uint16":0,"HVBBplcCur_uint16":0,"HVBBreservedCur1_uint16":0,"HVBBreservedCur2_uint16":0,"HVBBunit4Cur_uint16":0,"HVBFTDev45Cur_uint16":0,"HVBbatGroupCur_uint16":0,"HVBbowHVolDisBoxCur_uint16":0,"HVBbusACur_uint16":0,"HVBbusAVol_uint16":0,"HVBdcDc5Cur_uint16":0,"HVBfbCur_uint16":0,"HVBmotorCur_uint16":0,"HVBpowerBusCur_uint16":0,"HVBpowerBusVol_uint16":0,"HVBreservedCur1_uint16":0,"HVBreservedCur2_uint16":0,"HVBreservedCur3_uint16":0,"HVBsternRud1Cur_uint16":0,"HVBsternRud2Cur_uint16":0,"HVBtyzCur_uint16":0,"LVBBbowPZDevCur_uint16":0,"LVBBemerBatCur_uint16":0,"LVBBemerBusVol_uint16":0,"LVBBinsBusCur_uint16":0,"LVBBunit1Cur_uint16":0,"LVBBunit2Cur_uint16":0,"LVBBunit3Cur_uint16":0,"LVBBunit5Cur_uint16":0,"LVBinsBusVol_uint16":0}}
|
||||
|
||||
@@ -1,10 +1 @@
|
||||
{
|
||||
"HVolABusBreaker_unit16": 0,
|
||||
"HVolBBusBreaker_unit16": 0,
|
||||
"HVolBusBreaker_uint16": 0,
|
||||
"LVolBusBreaker_uint16": 0,
|
||||
"faultCode_array":
|
||||
[
|
||||
0
|
||||
]
|
||||
}
|
||||
{"uPower_disSysState_st":{"HVolABusBreaker_uint16":0,"HVolBBusBreaker_uint16":0,"HVolBusBreaker_uint16":0,"LVolBusBreaker_uint16":0,"faultCode_array":[1,2,3,4,5,6,7,8,9,13,14,15,16,17,18,19,20,21,22,25,26,27,28,29,33,34,35,36,37,38,39,40,41,42,44,45]}}
|
||||
|
||||
@@ -1,65 +1,65 @@
|
||||
{"uPower_equState_fb":{
|
||||
"DVL_uni8" : 0,
|
||||
"USBL_uni8" : 0,
|
||||
"bowCover1_uni8" : 0,
|
||||
"bowCover2_uni8" : 0,
|
||||
"bowCover3_uni8" : 0,
|
||||
"bowCover4_uni8" : 0,
|
||||
"bowCover5_uni8" : 0,
|
||||
"bowCover6_uni8" : 0,
|
||||
"bowRudderDeploy_uni8" : 0,
|
||||
"bowRudderServo1_uni8" : 0,
|
||||
"bowRudderServo2_uni8" : 0,
|
||||
"bowThrow_uni8" : 0,
|
||||
"bowWaterInet1_uni8" : 0,
|
||||
"bowWaterInet2_uni8" : 0,
|
||||
"bowWaterInet3_uni8" : 0,
|
||||
"bowWaterInet4_uni8" : 0,
|
||||
"bowWaterInet5_uni8" : 0,
|
||||
"bowWaterInet6_uni8" : 0,
|
||||
"bowWaterInet7_uni8" : 0,
|
||||
"bowWaterInet8_uni8" : 0,
|
||||
"buoyage_uni8" : 0,
|
||||
"buoyancyAdjust1_uni8" : 0,
|
||||
"buoyancyAdjust2_uni8" : 0,
|
||||
"buoyancyAdjust3_uni8" : 0,
|
||||
"buoyancyAdjust4_uni8" : 0,
|
||||
"buoyancyAdjust5_uni8" : 0,
|
||||
"commMast_uni8" : 0,
|
||||
"ctd1_uni8" : 0,
|
||||
"ctd2_uni8" : 0,
|
||||
"depth1_uni8" : 0,
|
||||
"depth2_uni8" : 0,
|
||||
"depth3_uni8" : 0,
|
||||
"electSensor_uni8" : 0,
|
||||
"forwardSonar_uni8" : 0,
|
||||
"inputWaterSensor1_uni8" : 0,
|
||||
"inputWaterSensor2_uni8" : 0,
|
||||
"inputWaterSensor3_uni8" : 0,
|
||||
"ins_uni8" : 0,
|
||||
"launchControler_uni8" : 0,
|
||||
"lowFreqSonar_uni8" : 0,
|
||||
"mastLiftingServo_uni8" : 0,
|
||||
"ntp_uni8" : 0,
|
||||
"overDeep1_uni8" : 0,
|
||||
"overDeep2_uni8" : 0,
|
||||
"photoSensor_uni8" : 0,
|
||||
"sideSonar_uni8" : 0,
|
||||
"singleBeamSonar1_uni8" : 0,
|
||||
"singleBeamSonar2_uni8" : 0,
|
||||
"singleBeamSonar3_uni8" : 0,
|
||||
"singleBeamSonar4_uni8" : 0,
|
||||
"singleBeamSonar5_uni8" : 0,
|
||||
"singleBeamSonar6_uni8" : 0,
|
||||
"singleBeamSonar7_uni8" : 0,
|
||||
"singleBeamSonar8_uni8" : 0,
|
||||
"soundVeloc_uni8" : 0,
|
||||
"sternRudderServo1_uni8" : 0,
|
||||
"sternRudderServo2_uni8" : 0,
|
||||
"sternRudderServo3_uni8" : 0,
|
||||
"sternRudderServo4_uni8" : 0,
|
||||
"sternThrow_uni8" : 0,
|
||||
"thruster_uni8" : 0,
|
||||
"waterInject_uni8" : 0
|
||||
"DVL_uint8" : 0,
|
||||
"USBL_uint8" : 0,
|
||||
"bowCover1_uint8" : 0,
|
||||
"bowCover2_uint8" : 0,
|
||||
"bowCover3_uint8" : 0,
|
||||
"bowCover4_uint8" : 0,
|
||||
"bowCover5_uint8" : 0,
|
||||
"bowCover6_uint8" : 0,
|
||||
"bowRudderDeploy_uint8" : 0,
|
||||
"bowRudderServo1_uint8" : 0,
|
||||
"bowRudderServo2_uint8" : 0,
|
||||
"bowThrow_uint8" : 0,
|
||||
"bowWaterInet1_uint8" : 0,
|
||||
"bowWaterInet2_uint8" : 0,
|
||||
"bowWaterInet3_uint8" : 0,
|
||||
"bowWaterInet4_uint8" : 0,
|
||||
"bowWaterInet5_uint8" : 0,
|
||||
"bowWaterInet6_uint8" : 0,
|
||||
"bowWaterInet7_uint8" : 0,
|
||||
"bowWaterInet8_uint8" : 0,
|
||||
"buoyage_uint8" : 0,
|
||||
"buoyancyAdjust1_uint8" : 0,
|
||||
"buoyancyAdjust2_uint8" : 0,
|
||||
"buoyancyAdjust3_uint8" : 0,
|
||||
"buoyancyAdjust4_uint8" : 0,
|
||||
"buoyancyAdjust5_uint8" : 0,
|
||||
"commDev_uint8" : 0,
|
||||
"ctd1_uint8" : 0,
|
||||
"ctd2_uint8" : 0,
|
||||
"depth1_uint8" : 0,
|
||||
"depth2_uint8" : 0,
|
||||
"depth3_uint8" : 0,
|
||||
"electSensor_uint8" : 0,
|
||||
"forwardSonar_uint8" : 0,
|
||||
"inputWaterSensor1_uint8" : 0,
|
||||
"inputWaterSensor2_uint8" : 0,
|
||||
"inputWaterSensor3_uint8" : 0,
|
||||
"ins_uint8" : 1,
|
||||
"launchControler_uint8" : 0,
|
||||
"lowFreqSonar_uint8" : 0,
|
||||
"mastLiftingServo_uint8" : 0,
|
||||
"ntp_uint8" : 1,
|
||||
"overDeep1_uint8" : 0,
|
||||
"overDeep2_uint8" : 0,
|
||||
"photoSensor_uint8" : 0,
|
||||
"sideSonar_uint8" : 0,
|
||||
"singleBeamSonar1_uint8" : 0,
|
||||
"singleBeamSonar2_uint8" : 0,
|
||||
"singleBeamSonar3_uint8" : 0,
|
||||
"singleBeamSonar4_uint8" : 0,
|
||||
"singleBeamSonar5_uint8" : 0,
|
||||
"singleBeamSonar6_uint8" : 0,
|
||||
"singleBeamSonar7_uint8" : 0,
|
||||
"singleBeamSonar8_uint8" : 0,
|
||||
"soundVeloc_uint8" : 0,
|
||||
"sternRudderServo1_uint8" : 0,
|
||||
"sternRudderServo2_uint8" : 0,
|
||||
"sternRudderServo3_uint8" : 0,
|
||||
"sternRudderServo4_uint8" : 0,
|
||||
"sternThrow_uint8" : 0,
|
||||
"thruster_uint8" : 0,
|
||||
"waterInject_uint8" : 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
null
|
||||
{"uPower_fcsState_st":{"backpressure1_fp32":0.0,"backpressure2_fp32":0.0,"ch4oConcent1_fp32":0.0,"ch4oConcent2_fp32":0.0,"ch4o_fp32":0.0,"excTemp_fp32":0.0,"faultCode1_uint16":0,"faultCode2_uint16":0,"faultCode3_uint16":0,"faultCode4_uint16":0,"fcCommState_uint8":0,"fcuCurIns_fp32":0.0,"fcuCurPower_fp32":0.0,"fcuCur_fp32":0.0,"fcuFaultLeve_uint8":0,"fcuOutIns_fp32":0.0,"fcuOutPower_fp32":0.0,"fcuState_uint8":0,"fcuVolIns_fp32":0.0,"fcuVolPower_fp32":0.0,"fcuVol_fp32":0.0,"flameDet_uint8":0,"h2Concent1_fp32":0.0,"h2Concent2_fp32":0.0,"o2Concent1_fp32":0.0,"o2Concent2_fp32":0.0,"o2Level_fp32":0.0,"o2_fp32":0.0,"powLimit_fp32":0.0,"powerGen_fp32":0.0}}
|
||||
|
||||
@@ -1 +1 @@
|
||||
null
|
||||
{"uPower_liBatState_st":{"insBatCurElect_uint16":0.0,"insBatLimit_uint16":0.0,"insBatSoc_uint8":0,"insBatTotalElect_uint16":0.0,"insChargeState_uint8":0,"insCommState_uint8":0,"insCurSocHold1_uint8":0,"insCurSocHold2_uint8":0,"insCurSocHold3_uint8":0,"insCurrent_uint16":0.0,"insFaultCode_uint8":0,"insLinkVol_uint16":0.0,"insNegRelayState_uint8":0,"insNegRes_uint16":0.0,"insPackVol_uint16":0.0,"insPosRelayState_uint8":0,"insPosRes_uint16":0.0,"powBatCurElect_uint16":0,"powBatSoc_uint8":0,"powBatTotalElect_uint16":0.0,"powChargeState_uint8":0,"powCommState_uint8":0,"powCurSocHold1_uint8":0,"powCurSocHold2_uint8":0,"powCurSocHold3_uint8":0,"powCurToInsLimit1_uint8":0.0,"powCurToInsLimit2_uint8":0.0,"powCur_uint16":0.0,"powFaultCode_uint8":0,"powLinkVol_uint16":0.0,"powNegRelayState_uint8":0,"powNegRes_uint16":0.0,"powPosRelayState_uint8":0,"powPosRes_uint16":0.0,"powerBatLimit_uint16":0,"powerPackVol_uint16":0.0}}
|
||||
|
||||
@@ -1,65 +1 @@
|
||||
{"uPower_secdistState_cmd":{
|
||||
"DVL_uni8" : 0,
|
||||
"USBL_uni8" : 0,
|
||||
"bowCover1_uni8" : 0,
|
||||
"bowCover2_uni8" : 0,
|
||||
"bowCover3_uni8" : 0,
|
||||
"bowCover4_uni8" : 0,
|
||||
"bowCover5_uni8" : 0,
|
||||
"bowCover6_uni8" : 0,
|
||||
"bowRudderDeploy_uni8" : 0,
|
||||
"bowRudderServo1_uni8" : 0,
|
||||
"bowRudderServo2_uni8" : 0,
|
||||
"bowThrow_uni8" : 0,
|
||||
"bowWaterInet1_uni8" : 0,
|
||||
"bowWaterInet2_uni8" : 0,
|
||||
"bowWaterInet3_uni8" : 0,
|
||||
"bowWaterInet4_uni8" : 0,
|
||||
"bowWaterInet5_uni8" : 0,
|
||||
"bowWaterInet6_uni8" : 0,
|
||||
"bowWaterInet7_uni8" : 0,
|
||||
"bowWaterInet8_uni8" : 0,
|
||||
"buoyage_uni8" : 0,
|
||||
"buoyancyAdjust1_uni8" : 0,
|
||||
"buoyancyAdjust2_uni8" : 0,
|
||||
"buoyancyAdjust3_uni8" : 0,
|
||||
"buoyancyAdjust4_uni8" : 0,
|
||||
"buoyancyAdjust5_uni8" : 0,
|
||||
"commMast_uni8" : 1,
|
||||
"ctd1_uni8" : 1,
|
||||
"ctd2_uni8" : 1,
|
||||
"depth1_uni8" : 1,
|
||||
"depth2_uni8" : 1,
|
||||
"depth3_uni8" : 1,
|
||||
"electSensor_uni8" : 0,
|
||||
"forwardSonar_uni8" : 0,
|
||||
"inputWaterSensor1_uni8" : 1,
|
||||
"inputWaterSensor2_uni8" : 1,
|
||||
"inputWaterSensor3_uni8" : 1,
|
||||
"ins_uni8" : 1,
|
||||
"launchControler_uni8" : 0,
|
||||
"lowFreqSonar_uni8" : 0,
|
||||
"mastLiftingServo_uni8" : 0,
|
||||
"ntp_uni8" : 1,
|
||||
"overDeep1_uni8" : 1,
|
||||
"overDeep2_uni8" : 1,
|
||||
"photoSensor_uni8" : 0,
|
||||
"sideSonar_uni8" : 0,
|
||||
"singleBeamSonar1_uni8" : 0,
|
||||
"singleBeamSonar2_uni8" : 1,
|
||||
"singleBeamSonar3_uni8" : 0,
|
||||
"singleBeamSonar4_uni8" : 0,
|
||||
"singleBeamSonar5_uni8" : 0,
|
||||
"singleBeamSonar6_uni8" : 0,
|
||||
"singleBeamSonar7_uni8" : 0,
|
||||
"singleBeamSonar8_uni8" : 0,
|
||||
"soundVeloc_uni8" : 1,
|
||||
"sternRudderServo1_uni8" : 0,
|
||||
"sternRudderServo2_uni8" : 0,
|
||||
"sternRudderServo3_uni8" : 0,
|
||||
"sternRudderServo4_uni8" : 0,
|
||||
"sternThrow_uni8" : 0,
|
||||
"thruster_uni8" : 0,
|
||||
"waterInject_uni8" : 0
|
||||
}
|
||||
}
|
||||
{"uPower_secdistState_cmd":{"ADCP_uint8":2,"DVL_uint8":2,"USBL_uint8":2,"bowCover1_uint8":2,"bowCover2_uint8":2,"bowCover3_uint8":2,"bowCover4_uint8":2,"bowCover5_uint8":2,"bowCover6_uint8":2,"bowRudderDeploy_uint8":2,"bowRudderServo_uint8":2,"bowThrow_uint8":2,"bowWaterInet1_uint8":2,"bowWaterInet2_uint8":2,"bowWaterInet3_uint8":2,"bowWaterInet4_uint8":2,"bowWaterInet5_uint8":2,"bowWaterInet6_uint8":2,"bowWaterInet7_uint8":2,"bowWaterInet8_uint8":2,"buoyage_uint8":2,"buoyancyAdjust1_uint8":2,"buoyancyAdjust2_uint8":2,"buoyancyAdjust3_uint8":2,"buoyancyAdjust4_uint8":2,"buoyancyAdjust5_uint8":2,"commDevStern_uint8":2,"commDev_uint8":1,"ctd1_uint8":1,"ctd2_uint8":1,"depth1_uint8":1,"depth2_uint8":1,"depth3_uint8":1,"dragSonar_uint8":2,"electSensor_uint8":2,"forwardSonar_uint8":2,"haulingMachine_uint8":2,"inOutLetWater1_uint8":1,"inOutLetWater2_uint8":1,"inOutLetWater3_uint8":1,"launchControler_uint8":2,"lowFreqSonar_uint8":2,"mainINS_uint8":1,"mastLiftingServo_uint8":2,"photoSensor_uint8":2,"secINS_uint8":1,"sideSonar_uint8":2,"singleBeamSonar1_uint8":2,"singleBeamSonar2_uint8":2,"singleBeamSonar3_uint8":2,"singleBeamSonar4_uint8":2,"singleBeamSonar5_uint8":2,"singleBeamSonar6_uint8":2,"singleBeamSonar7_uint8":2,"singleBeamSonar8_uint8":2,"soundVeloc_uint8":1,"sternRudderServo1_uint8":2,"sternRudderServo2_uint8":2,"sternRudderServo3_uint8":2,"sternRudderServo4_uint8":2,"sternThrow_uint8":2,"thruster_uint8":2,"waterInject_uint8":2}}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"state_uint8" : 1
|
||||
"state_uint8" : 12
|
||||
}
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
scp root@192.168.0.223:/root/work/moos_ws/moos-ivp-extend/missions/union_test/power_data.db ./data/power_data.db
|
||||
scp root@192.168.0.223:/root/work/moos_ws/moos-ivp-extend/missions/union_test/pPowerManger.log ./data/pPowerManger.log
|
||||
@@ -63,6 +63,7 @@ SET(SRC
|
||||
LowerCommManager.cpp
|
||||
UpperCommManager.cpp
|
||||
# loguru.cpp
|
||||
upmsg/upmsg_definitions.cpp
|
||||
)
|
||||
|
||||
ADD_EXECUTABLE(pPowerManger ${SRC})
|
||||
|
||||
@@ -77,17 +77,37 @@ bool LowerCommManager::initUdpComm(){
|
||||
}
|
||||
void LowerCommManager::processPeriodicTasks() {
|
||||
sendCcuCommand(m_pm->m_CcuColCmd);
|
||||
// cout << "send ccu command" << endl;
|
||||
m_pm->m_db->insertData(m_pm->m_CcuColCmd);
|
||||
//延时5ms
|
||||
usleep(5000);
|
||||
// sendDisSysCommand(m_pm->m_targetDisBreakerState);
|
||||
// if(m_pm->m_systemData->device_common_status.dis_hv_c1.isTimeout)
|
||||
// {
|
||||
|
||||
// }
|
||||
if(m_pm->m_systemData->device_common_status.dis_hv_c1.isTimeout )
|
||||
{
|
||||
disHighVolBusCmd clr1{};
|
||||
m_udpComm->sendDisSysCmd(clr1);
|
||||
MOOSPause(200);
|
||||
}
|
||||
if(m_pm->m_systemData->device_common_status.dis_lv_c1.isTimeout )
|
||||
{
|
||||
disHighBVolBusCmd clr3{};
|
||||
m_udpComm->sendDisSysCmd(clr3);
|
||||
MOOSPause(200);
|
||||
}
|
||||
m_udpComm->clearMsgQueue();
|
||||
}
|
||||
|
||||
void LowerCommManager::operate_hold()
|
||||
{
|
||||
disHighVolBusCmd clr1{};
|
||||
disHighAVolBusCmd clr2{};
|
||||
disHighBVolBusCmd clr3{};
|
||||
disLowBusCmd clr4{};
|
||||
m_udpComm->sendDisSysCmd(clr1);
|
||||
MOOSPause(200);
|
||||
m_udpComm->sendDisSysCmd(clr2);
|
||||
MOOSPause(200);
|
||||
m_udpComm->sendDisSysCmd(clr3);
|
||||
MOOSPause(200);
|
||||
m_udpComm->sendDisSysCmd(clr4);
|
||||
}
|
||||
bool LowerCommManager::sendCcuCommand(const ccuColCmd cmd){
|
||||
// m_pm->m_db->insertCcuSysCmd(cmd);
|
||||
if(!m_udpComm->sendCcuColCmd(cmd))
|
||||
|
||||
@@ -80,6 +80,9 @@ public:
|
||||
bool operate_LVA_reservedCircuit1_Breaker(char opt);
|
||||
bool operate_LVA_reservedCircuit2_Breaker(char opt);
|
||||
bool operate_LVA_mergencyLithiumBatteryGroup1Circuit_Breaker(char opt);
|
||||
|
||||
//保持指令
|
||||
void operate_hold();
|
||||
//================================复合管控器操作函数====================================
|
||||
// 发送CCU控制命令
|
||||
bool sendCcuCommand(const ccuColCmd cmd);
|
||||
|
||||
@@ -21,6 +21,12 @@ bool _FsmCB(void * pParam)
|
||||
return pMe->FsmLoop();
|
||||
}
|
||||
|
||||
bool _CommCB(void * pParam)
|
||||
{
|
||||
PowerManger* pMe = (PowerManger* )pParam;
|
||||
return pMe->commLoop();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Constructor()
|
||||
|
||||
@@ -78,6 +84,7 @@ PowerManger::PowerManger()
|
||||
|
||||
PowerManger::~PowerManger()
|
||||
{
|
||||
m_commThread.Stop();
|
||||
delete m_db;
|
||||
delete m_lowerCommManager;
|
||||
delete m_upperCommManager;
|
||||
@@ -154,12 +161,12 @@ bool PowerManger::Iterate()
|
||||
// 更新系统数据
|
||||
m_systemData->updateCommonStatus();
|
||||
// m_CcuColCmd.heartbeat
|
||||
if (m_ticker++ % 5 == 0)
|
||||
{
|
||||
m_CcuColCmd.heartbeat++;
|
||||
m_lowerCommManager->processPeriodicTasks();
|
||||
m_upperCommManager->processPeriodicTasks();
|
||||
}
|
||||
// if (m_ticker++ % 5 == 0)
|
||||
// {
|
||||
// m_CcuColCmd.heartbeat++;
|
||||
// m_lowerCommManager->processPeriodicTasks();
|
||||
// m_upperCommManager->processPeriodicTasks();
|
||||
// }
|
||||
return(true);
|
||||
}
|
||||
|
||||
@@ -203,6 +210,10 @@ bool PowerManger::OnStartUp()
|
||||
PowerManagerFsm::start();
|
||||
InitEvent initEvent;
|
||||
PowerManagerFsm::dispatch(initEvent);
|
||||
|
||||
//初始化通信线程
|
||||
m_commThread.Initialise(_CommCB,this);
|
||||
m_commThread.Start();
|
||||
return(true);
|
||||
}
|
||||
|
||||
@@ -224,6 +235,9 @@ void PowerManger::registerVariables()
|
||||
Register(DB_TO_PM_SETPMSYS,0);
|
||||
Register(DB_TO_PM_SETDEVSWITCH,0);
|
||||
Register(DB_TO_PM_TASKSTOP,0);
|
||||
|
||||
Register(uDetect_xcVoltage_cmd::key,0);
|
||||
Register(uDetect_zdpVoltage_cmd::key,0);
|
||||
}
|
||||
|
||||
|
||||
@@ -249,20 +263,6 @@ bool PowerManger::buildReport()
|
||||
|
||||
bool PowerManger::FsmLoop()
|
||||
{
|
||||
//状态机循环
|
||||
// while (!m_FsmThread.IsQuitRequested())
|
||||
// {
|
||||
// // // 检查故障并触发事件
|
||||
// // if(int error = checkError()) {
|
||||
// // m_fsm.triggerFaultEvent(error);
|
||||
// // } else {
|
||||
// // // 自动状态转换由状态机内部处理
|
||||
// // MOOSPause(1000);
|
||||
// // }
|
||||
|
||||
// //延时1s
|
||||
// usleep(1000000);
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -278,7 +278,6 @@ int PowerManger::checkError()
|
||||
// m_pmCurrentState.ccustate.fcuGZ_3L != 0 ||
|
||||
// m_pmCurrentState.ccustate.insEmergencyStatusWord != 0)
|
||||
return 0;
|
||||
//2.检查断路器状态
|
||||
}
|
||||
|
||||
void PowerManger::printState(const std::string& stateName, const std::string& desp){
|
||||
@@ -360,6 +359,19 @@ unsigned char PowerManger::getFaultLevel()
|
||||
return maxLevel;
|
||||
}
|
||||
|
||||
bool PowerManger::commLoop()
|
||||
{
|
||||
while(!m_commThread.IsQuitRequested())
|
||||
{
|
||||
m_CcuColCmd.heartbeat++;
|
||||
m_lowerCommManager->processPeriodicTasks();
|
||||
m_upperCommManager->processPeriodicTasks();
|
||||
// 延时1秒
|
||||
usleep(1000000);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void PowerManger::injectFault(unsigned type,unsigned int faultCode){
|
||||
LOG_F(INFO, "注入故障: %d %d", type, faultCode);
|
||||
TestEvent testEvent("故障注入测试",type,faultCode);
|
||||
|
||||
@@ -124,7 +124,7 @@ class PowerManger : public AppCastingMOOSApp
|
||||
void initControlCmd();
|
||||
|
||||
public:
|
||||
// CMOOSThread m_FsmThread;
|
||||
CMOOSThread m_commThread;
|
||||
LowerCommManager* m_lowerCommManager;
|
||||
UpperCommManager* m_upperCommManager;
|
||||
|
||||
@@ -136,6 +136,7 @@ class PowerManger : public AppCastingMOOSApp
|
||||
bool FSM_RUN_IS_OK = true;
|
||||
|
||||
//==================================================================================
|
||||
bool commLoop();
|
||||
int checkError();
|
||||
|
||||
bool sendNotification(const std::string& key, const std::string& value) {
|
||||
|
||||
@@ -153,6 +153,28 @@ bool UpperCommManager::processUpperMsg(const string& key, const string& strJson)
|
||||
LOG_F(WARNING, "task stop error:%s", strJson.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if(key == uDetect_xcVoltage_cmd::key)
|
||||
{
|
||||
uDetect_xcVoltage_cmd xcCmd;
|
||||
xcCmd.fromJsonString(strJson);
|
||||
SideSonarCmd sideSonarCmd;
|
||||
sideSonarCmd.xcHighVoltageAdd = xcCmd.xcHighVoltageAdd_int32;
|
||||
sideSonarCmd.xcLowVoltageAdd = xcCmd.xcLowVoltageAdd_int32;
|
||||
PowerManagerFsm::dispatch(sideSonarCmd);
|
||||
return true;
|
||||
}
|
||||
else if(key == uDetect_zdpVoltage_cmd::key)
|
||||
{
|
||||
uDetect_zdpVoltage_cmd zdpCmd;
|
||||
zdpCmd.fromJsonString(strJson);
|
||||
|
||||
DevCmdExt devCmdExt;
|
||||
devCmdExt.id = DeviceId::lowFreqSonar;
|
||||
devCmdExt.cmd = zdpCmd.zdpVoltageAdd_int32;
|
||||
PowerManagerFsm::dispatch(devCmdExt);
|
||||
LOG_F(INFO, "set dev switch success");
|
||||
return true;
|
||||
};
|
||||
LOG_F(WARNING, "Unknown key: %s", key.c_str());
|
||||
return false;
|
||||
|
||||
@@ -25,7 +25,8 @@
|
||||
#include "upmsg/uExternComm_setPowerSystem.h"
|
||||
#include "upmsg/uPower_equState.h"
|
||||
#include "upmsg/uPower_sysState.h"
|
||||
|
||||
#include "upmsg/uDetect_zdpVoltage_cmd.h"
|
||||
#include "upmsg/uDetect_xcVoltage_cmd.h"
|
||||
#define _DEBUG
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -5,5 +5,6 @@ void InitState::entry() {
|
||||
PowerManagerFsm::entry();
|
||||
LOG_F(INFO, "进入初始化状态");
|
||||
pm->initControlCmd();
|
||||
pm->m_lowerCommManager->operate_hold();
|
||||
transit<StandbyState>();
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
#include "PowerManagerFsm.hpp"
|
||||
|
||||
void Lifting::entry() {
|
||||
PowerManagerFsm::entry();
|
||||
pm->workCondition = WorkCondition::CHANING;
|
||||
//1. 关闭所有水声设备
|
||||
LOG_F(INFO,"前视声纳关机指令");
|
||||
pm->sendNotification("uExternComm_frontSonarControl_cmd","0");
|
||||
MOOSPause(10000);
|
||||
for(auto iter : underWterDevices)
|
||||
{
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, static_cast<DeviceId::Type>(iter), 0);
|
||||
}
|
||||
//2. 关闭动力电设备
|
||||
//2.1 断开所有艏部高压断路器
|
||||
pm->m_lowerCommManager->operate_HVA_actuatorCircuit_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_lowerCommManager->operate_HVA_bowFTDevice123Circuit_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_lowerCommManager->operate_HVA_bowRudderControlBoxCircuit_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_lowerCommManager->operate_HVA_mastSteeringGearControlBoxCircuit_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_lowerCommManager->operate_HVA_openWaterCoverStartCylinderCircuit_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_lowerCommManager->operate_HVA_xczCircuit_Breaker(0);
|
||||
MOOSPause(3);
|
||||
//2.2 断开所有艉部高压设备断路器
|
||||
pm->m_lowerCommManager->operate_HV_propulsionMotor_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_lowerCommManager->operate_HV_sternFt45_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_lowerCommManager->operate_HV_sternRudder1_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_lowerCommManager->operate_HV_sternRudder2_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_lowerCommManager->operate_HV_fbReserved_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_lowerCommManager->operate_HV_tyzReserved_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_lowerCommManager->operate_HV_reserved_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_lowerCommManager->operate_HV_dcDc5_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_lowerCommManager->operate_HV_coolingSystem_Breaker(0);
|
||||
MOOSPause(3);
|
||||
|
||||
//2.5 断开动力电断路器
|
||||
pm->m_lowerCommManager->operate_HV_bowHighVoltageBox_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_lowerCommManager->operate_HV_dcDc5_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_lowerCommManager->operate_HV_coolingSystem_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_lowerCommManager->operate_HV_dcDc5Module_Breaker(0);
|
||||
MOOSPause(3);
|
||||
pm->m_lowerCommManager->operate_HV_powerLithiumBattery_Breaker(0);
|
||||
//3. 关闭燃料电池
|
||||
//4. 关闭动力锂电池
|
||||
MOOSPause(3);
|
||||
{
|
||||
int count=0;
|
||||
while (!(pm->m_systemData->dyn_pos_relay_status == 0x02 && pm->m_systemData->dyn_neg_relay_status == 0x02))
|
||||
{
|
||||
LOG_F(INFO,"动力锂电池下电中...");
|
||||
MOOSPause(3);
|
||||
if(count>10)
|
||||
{
|
||||
LOG_F(INFO, "动力锂电池无下电反馈");
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
}
|
||||
LOG_F(INFO, "动力锂电池已下电");
|
||||
pm->workCondition = WorkCondition::LIFT_MODE;
|
||||
LOG_F(INFO, "WorkCondition %d", pm->workCondition);
|
||||
}
|
||||
|
||||
void Lifting::react(MasterCommandEvent const &) {
|
||||
PowerManagerFsm::handelPowerCmd();
|
||||
PowerManagerFsm::handleModCmd();
|
||||
PowerManagerFsm::handleWorkCmd();
|
||||
}
|
||||
|
||||
void Lifting::react(DevCmdExt const &e)
|
||||
{
|
||||
LOG_F(INFO, "DevCmdExt 执行");
|
||||
PowerManagerFsm::react(e);
|
||||
}
|
||||
@@ -718,6 +718,30 @@ void PowerManagerFsm::handleFBSystemCmd(int id, int cmd)
|
||||
}
|
||||
}
|
||||
|
||||
void PowerManagerFsm::react(SideSonarCmd const &e)
|
||||
{
|
||||
LOG_F(INFO, "处理探测模块舷侧声纳指令");
|
||||
if(e.xcHighVoltageAdd == 1)
|
||||
{
|
||||
pm->m_lowerCommManager->operate_HVA_xczCircuit_Breaker(1);
|
||||
pm->m_upperCommManager->processPeriodicTasks();
|
||||
}
|
||||
else if(e.xcHighVoltageAdd == 2)
|
||||
{
|
||||
pm->m_lowerCommManager->operate_HVA_xczCircuit_Breaker(0);
|
||||
pm->m_upperCommManager->processPeriodicTasks();
|
||||
}
|
||||
|
||||
if(e.xcLowVoltageAdd == 1)
|
||||
{
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::sideSonar, (unsigned char)1);
|
||||
}
|
||||
else if(e.xcLowVoltageAdd == 2)
|
||||
{
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::sideSonar, (unsigned char)0);
|
||||
}
|
||||
}
|
||||
|
||||
void PowerManagerFsm::handleSideSonarCmd(int id, int cmd)
|
||||
{
|
||||
if(id == DeviceId::sideSonar)
|
||||
@@ -2516,6 +2540,7 @@ void PowerManagerFsm::react(FaultEvent const &e)
|
||||
sensorSystemFault(e);
|
||||
}
|
||||
|
||||
|
||||
void PowerManagerFsm::handelPowerCmd(){
|
||||
switch (pm->m_msCmd.powerCMD)
|
||||
{
|
||||
@@ -2765,6 +2790,8 @@ void PowerManagerFsm::handleWorkCmd(){
|
||||
LOG_F(INFO, "收到上位机控制指令:DJ模式");
|
||||
transit<DJMode>();
|
||||
break;
|
||||
case 12:
|
||||
LOG_F(INFO, "收到上位机控制指令:起吊准备");
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -44,6 +44,12 @@ struct DevCmdExt : tinyfsm::Event {
|
||||
DevCmdExt() : id(0), cmd(0) {};
|
||||
DevCmdExt(int id, int cmd) : id(id), cmd(cmd) {};
|
||||
};
|
||||
struct SideSonarCmd : tinyfsm::Event {
|
||||
int xcLowVoltageAdd;
|
||||
int xcHighVoltageAdd;
|
||||
SideSonarCmd() : xcLowVoltageAdd(0),xcHighVoltageAdd(0) {};
|
||||
SideSonarCmd(int xcLowVoltageAdd,int xcHighVoltageAdd) : xcLowVoltageAdd(xcLowVoltageAdd),xcHighVoltageAdd(xcHighVoltageAdd) {};
|
||||
};
|
||||
//==================测试事件================================
|
||||
struct TestEvent : tinyfsm::Event {
|
||||
std::string eventName;
|
||||
@@ -94,6 +100,8 @@ public:
|
||||
virtual void react(FaultEvent const &e);
|
||||
virtual void react(TaskStopEvent const &e);
|
||||
virtual void react(CycleTriggeredEvent const &e);
|
||||
virtual void react(SideSonarCmd const &e);
|
||||
|
||||
|
||||
//测试事件
|
||||
virtual void react(TestEvent const &);
|
||||
@@ -282,5 +290,10 @@ public:
|
||||
void react(MasterCommandEvent const &) override;
|
||||
};
|
||||
|
||||
class Lifting : public PowerManagerFsm {
|
||||
public:
|
||||
void entry() override;
|
||||
void react(MasterCommandEvent const &) override;
|
||||
};
|
||||
|
||||
#endif // POWER_MANAGER_FSM_HPP
|
||||
@@ -17,14 +17,14 @@ void ShoreBasedReady::entry() {
|
||||
pm->m_CcuColCmd.powerBatCmd = BatteryCommand::Start;
|
||||
//1.2 闭合动力电断路器
|
||||
pm->m_lowerCommManager->operate_HV_powerLithiumBattery_Breaker(1);
|
||||
MOOSPause(3);
|
||||
MOOSPause(100);
|
||||
pm->m_lowerCommManager->operate_HV_dcDc5Module_Breaker(1);
|
||||
MOOSPause(3);
|
||||
MOOSPause(100);
|
||||
pm->m_lowerCommManager->operate_HV_dcDc5_Breaker(1);
|
||||
pm->m_lowerCommManager->operate_HV_coolingSystem_Breaker(1);
|
||||
MOOSPause(10);
|
||||
MOOSPause(100);
|
||||
pm->m_lowerCommManager->operate_HV_bowHighVoltageBox_Breaker(1);
|
||||
MOOSPause(3);
|
||||
MOOSPause(100);
|
||||
//2. 启动动力电设备
|
||||
unsigned char cmd = 1;
|
||||
//2.0 艉舵
|
||||
@@ -44,7 +44,7 @@ void ShoreBasedReady::entry() {
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowCover5, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowCover6, (unsigned char)cmd);
|
||||
pm->m_upperCommManager->processPeriodicTasks();
|
||||
MOOSPause(3);
|
||||
MOOSPause(100);
|
||||
pm->m_lowerCommManager->operate_HVA_actuatorCircuit_Breaker(1);
|
||||
//2.2 敞水电缸
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet1, (unsigned char)cmd);
|
||||
@@ -56,36 +56,36 @@ void ShoreBasedReady::entry() {
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet7, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowWaterInet8, (unsigned char)cmd);
|
||||
pm->m_upperCommManager->processPeriodicTasks();
|
||||
MOOSPause(3);
|
||||
MOOSPause(100);
|
||||
pm->m_lowerCommManager->operate_HVA_openWaterCoverStartCylinderCircuit_Breaker(1);
|
||||
//2.3 艏舵
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowRudderDeploy, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::bowRudderServo1, (unsigned char)cmd);
|
||||
pm->m_upperCommManager->processPeriodicTasks();
|
||||
MOOSPause(3);
|
||||
MOOSPause(100);
|
||||
pm->m_lowerCommManager->operate_HVA_bowRudderControlBoxCircuit_Breaker(1);
|
||||
//2.4 桅杆舵机
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::mastLiftingServo, (unsigned char)cmd);
|
||||
pm->m_upperCommManager->processPeriodicTasks();
|
||||
MOOSPause(3);
|
||||
MOOSPause(100);
|
||||
pm->m_lowerCommManager->operate_HVA_mastSteeringGearControlBoxCircuit_Breaker(1);
|
||||
//2.5 艏部浮调机构
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::buoyancyAdjust1, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::buoyancyAdjust2, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::buoyancyAdjust3, (unsigned char)cmd);
|
||||
pm->m_upperCommManager->processPeriodicTasks();
|
||||
MOOSPause(3);
|
||||
MOOSPause(100);
|
||||
pm->m_lowerCommManager->operate_HVA_bowFTDevice123Circuit_Breaker(1);
|
||||
//2.6 艉部浮调机构
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::buoyancyAdjust4, (unsigned char)cmd);
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::buoyancyAdjust5, (unsigned char)cmd);
|
||||
pm->m_upperCommManager->processPeriodicTasks();
|
||||
MOOSPause(3);
|
||||
MOOSPause(100);
|
||||
pm->m_lowerCommManager->operate_HV_sternFt45_Breaker(1);
|
||||
//2.7 推进电机
|
||||
pm->m_driver.setDeviceState(pm->m_subDisSysCmd, DeviceId::thruster, (unsigned char)cmd);
|
||||
pm->m_upperCommManager->processPeriodicTasks();
|
||||
MOOSPause(3);
|
||||
MOOSPause(100);
|
||||
pm->m_lowerCommManager->operate_HV_propulsionMotor_Breaker(1);
|
||||
pm->workCondition = WorkCondition::SHORE_BASED_READY;
|
||||
LOG_F(INFO, "进入岸基备航状态");
|
||||
|
||||
@@ -5,6 +5,7 @@ void StandbyState::entry() {
|
||||
PowerManagerFsm::entry();
|
||||
pm->workCondition = WorkCondition::STANDBY;
|
||||
pm->m_driver.getSTANDBYTable(&pm->m_subDisSysCmd);
|
||||
pm->m_lowerCommManager->operate_hold();
|
||||
LOG_F(INFO, "WorkCondition %d", pm->workCondition);
|
||||
}
|
||||
void StandbyState::react(StandbyEvent const &) {
|
||||
|
||||
@@ -891,6 +891,44 @@ const std::string DATA_HTML = R"(
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="collapsible">应急电池信息</button>
|
||||
<div class="content">
|
||||
<div class="system-data-grid">
|
||||
<div class="data-item">
|
||||
<span class="data-label">应急电池1总电压:</span>
|
||||
<span class="data-value" id="emergency-battery1-voltage">正在加载...</span>
|
||||
</div>
|
||||
<div class="data-item">
|
||||
<span class="data-label">应急电池1总电流:</span>
|
||||
<span class="data-value" id="emergency-battery1-current">正在加载...</span>
|
||||
</div>
|
||||
<div class="data-item">
|
||||
<span class="data-label">应急电池1最高温度:</span>
|
||||
<span class="data-value" id="emergency-battery1-max-temp">正在加载...</span>
|
||||
</div>
|
||||
<div class="data-item">
|
||||
<span class="data-label">应急电池1故障字:</span>
|
||||
<span class="data-value" id="emergency-battery1-fault-word">正在加载...</span>
|
||||
</div>
|
||||
<div class="data-item">
|
||||
<span class="data-label">应急电池2总电压:</span>
|
||||
<span class="data-value" id="emergency-battery2-voltage">正在加载...</span>
|
||||
</div>
|
||||
<div class="data-item">
|
||||
<span class="data-label">应急电池2总电流:</span>
|
||||
<span class="data-value" id="emergency-battery2-current">正在加载...</span>
|
||||
</div>
|
||||
<div class="data-item">
|
||||
<span class="data-label">应急电池2最高温度:</span>
|
||||
<span class="data-value" id="emergency-battery2-max-temp">正在加载...</span>
|
||||
</div>
|
||||
<div class="data-item">
|
||||
<span class="data-label">应急电池2故障字:</span>
|
||||
<span class="data-value" id="emergency-battery2-fault-word">正在加载...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="collapsible">其他系统参数</button>
|
||||
<div class="content">
|
||||
<div class="system-data-grid">
|
||||
@@ -1682,6 +1720,40 @@ if (data.power_a_bus_status) {
|
||||
if (data.timestamp !== undefined) {
|
||||
document.getElementById('timestamp').textContent = new Date(data.timestamp).toLocaleString();
|
||||
}
|
||||
|
||||
// 应急电池数据
|
||||
if (data.emergency_battery1 && data.emergency_battery1.voltage !== undefined) {
|
||||
document.getElementById('emergency-battery1-voltage').textContent =
|
||||
data.emergency_battery1.voltage.toFixed(2) + ' V';
|
||||
}
|
||||
if (data.emergency_battery1 && data.emergency_battery1.current !== undefined) {
|
||||
document.getElementById('emergency-battery1-current').textContent =
|
||||
data.emergency_battery1.current.toFixed(2) + ' A';
|
||||
}
|
||||
if (data.emergency_battery1 && data.emergency_battery1.max_temp !== undefined) {
|
||||
document.getElementById('emergency-battery1-max-temp').textContent =
|
||||
data.emergency_battery1.max_temp.toFixed(1) + ' °C';
|
||||
}
|
||||
if (data.emergency_battery1 && data.emergency_battery1.fault_word !== undefined) {
|
||||
document.getElementById('emergency-battery1-fault-word').textContent =
|
||||
'0x' + data.emergency_battery1.fault_word.toString(16).toUpperCase();
|
||||
}
|
||||
if (data.emergency_battery2 && data.emergency_battery2.voltage !== undefined) {
|
||||
document.getElementById('emergency-battery2-voltage').textContent =
|
||||
data.emergency_battery2.voltage.toFixed(2) + ' V';
|
||||
}
|
||||
if (data.emergency_battery2 && data.emergency_battery2.current !== undefined) {
|
||||
document.getElementById('emergency-battery2-current').textContent =
|
||||
data.emergency_battery2.current.toFixed(2) + ' A';
|
||||
}
|
||||
if (data.emergency_battery2 && data.emergency_battery2.max_temp !== undefined) {
|
||||
document.getElementById('emergency-battery2-max-temp').textContent =
|
||||
data.emergency_battery2.max_temp.toFixed(1) + ' °C';
|
||||
}
|
||||
if (data.emergency_battery2 && data.emergency_battery2.fault_word !== undefined) {
|
||||
document.getElementById('emergency-battery2-fault-word').textContent =
|
||||
'0x' + data.emergency_battery2.fault_word.toString(16).toUpperCase();
|
||||
}
|
||||
}
|
||||
|
||||
// 充放电状态文本转换
|
||||
|
||||
@@ -579,6 +579,30 @@ void HttpServer::pushSystemData() {
|
||||
j["power_bus_status"]["reservedCurrent3"] = Json::Value(m_systemData->power_bus_status.reservedCurrent3); // 预留电流3
|
||||
j["power_bus_status"]["coolWaterPressure"] = Json::Value(m_systemData->power_bus_status.coolWaterPressure); // 冷却水压力
|
||||
|
||||
|
||||
//应急电池信息
|
||||
j["emergency_battery1"]["voltage"] = Json::Value(m_systemData->emergency_battery1_voltage); // 应急电池1总电压 [V]
|
||||
j["emergency_battery1"]["current"] = Json::Value(m_systemData->emergency_battery1_current); // 应急电池1总电流 [A]
|
||||
j["emergency_battery1"]["max_temp"] = Json::Value(m_systemData->emergency_battery1_max_temp); // 应急电池1最高温度 [°C]
|
||||
j["emergency_battery1"]["fault_word"] = Json::Value(m_systemData->emergency_battery1_fault_word); // 应急电池1故障字
|
||||
|
||||
j["emergency_battery2"]["voltage"] = Json::Value(m_systemData->emergency_battery2_voltage); // 应急电池2总电压 [V]
|
||||
j["emergency_battery2"]["current"] = Json::Value(m_systemData->emergency_battery2_current); // 应急电池2总电流 [A]
|
||||
j["emergency_battery2"]["max_temp"] = Json::Value(m_systemData->emergency_battery2_max_temp); // 应急电池2最高温度 [°C]
|
||||
j["emergency_battery2"]["fault_word"] = Json::Value(m_systemData->emergency_battery2_fault_word); // 应急电池2故障字
|
||||
|
||||
|
||||
//应急电池
|
||||
// emergency_battery1_voltage = data.emergency_battery1_voltage * 0.1;
|
||||
// emergency_battery1_current = data.emergency_battery1_current * 0.05;
|
||||
// emergency_battery1_max_temp = data.emergency_battery1_max_temp * 0.1;
|
||||
// emergency_battery1_fault_word = data.emergency_battery1_fault_word;
|
||||
// emergency_battery2_voltage = data.emergency_battery2_voltage * 0.1;
|
||||
// emergency_battery2_current = data.emergency_battery2_current * 0.05;
|
||||
// emergency_battery2_max_temp = data.emergency_battery2_max_temp * 0.1;
|
||||
// emergency_battery2_fault_word = data.emergency_battery2_fault_word;
|
||||
|
||||
|
||||
// union {
|
||||
// unsigned char lowFaultWord;
|
||||
// struct {
|
||||
|
||||
@@ -540,6 +540,11 @@ body {
|
||||
animation: alarm-pulse 2s infinite ease-in-out;
|
||||
}
|
||||
|
||||
.emergency-battery-card {
|
||||
|
||||
/* 移除特殊宽度限制,使用标准电池卡片样式 */
|
||||
}
|
||||
|
||||
@keyframes alarm-pulse {
|
||||
0% {
|
||||
border-color: #f87171; /* light red */
|
||||
@@ -774,6 +779,26 @@ body {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="battery-card emergency-battery-card">
|
||||
<h3>应急电池1状态</h3>
|
||||
<div class="battery-data">
|
||||
<div class="data-row"><span>总电压:</span><span id="emergency-battery1-voltage">-</span>V</div>
|
||||
<div class="data-row"><span>总电流:</span><span id="emergency-battery1-current">-</span>A</div>
|
||||
<div class="data-row"><span>最高温度:</span><span id="emergency-battery1-max-temp">-</span>°C</div>
|
||||
<div class="data-row"><span>故障字:</span><span id="emergency-battery1-fault-word">-</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="battery-card emergency-battery-card">
|
||||
<h3>应急电池2状态</h3>
|
||||
<div class="battery-data">
|
||||
<div class="data-row"><span>总电压:</span><span id="emergency-battery2-voltage">-</span>V</div>
|
||||
<div class="data-row"><span>总电流:</span><span id="emergency-battery2-current">-</span>A</div>
|
||||
<div class="data-row"><span>最高温度:</span><span id="emergency-battery2-max-temp">-</span>°C</div>
|
||||
<div class="data-row"><span>故障字:</span><span id="emergency-battery2-fault-word">-</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel-title">电池报警状态</div>
|
||||
<div class="battery-cards">
|
||||
@@ -1094,6 +1119,20 @@ body {
|
||||
updateWithDebounce('h2-concentration1', data.h2_concentration1, 0);
|
||||
updateWithDebounce('h2-concentration2', data.h2_concentration2, 0);
|
||||
|
||||
// 更新应急电池数据
|
||||
if (data.emergency_battery1) {
|
||||
updateWithDebounce('emergency-battery1-voltage', data.emergency_battery1.voltage, 2);
|
||||
updateWithDebounce('emergency-battery1-current', data.emergency_battery1.current, 2);
|
||||
updateWithDebounce('emergency-battery1-max-temp', data.emergency_battery1.max_temp, 1);
|
||||
updateStatusWithDebounce('emergency-battery1-fault-word', data.emergency_battery1.fault_word, getFaultWordText);
|
||||
}
|
||||
if (data.emergency_battery2) {
|
||||
updateWithDebounce('emergency-battery2-voltage', data.emergency_battery2.voltage, 2);
|
||||
updateWithDebounce('emergency-battery2-current', data.emergency_battery2.current, 2);
|
||||
updateWithDebounce('emergency-battery2-max-temp', data.emergency_battery2.max_temp, 1);
|
||||
updateStatusWithDebounce('emergency-battery2-fault-word', data.emergency_battery2.fault_word, getFaultWordText);
|
||||
}
|
||||
|
||||
// 更新电池报警状态
|
||||
updateWithDebounce('dyn-alarm-flag1', data.dyn_alarm_flag1, 0);
|
||||
updateWithDebounce('dyn-alarm-flag2', data.dyn_alarm_flag2, 0);
|
||||
@@ -1516,6 +1555,11 @@ body {
|
||||
return commands[cmd] || '未知指令';
|
||||
}
|
||||
|
||||
function getFaultWordText(faultWord) {
|
||||
if (faultWord === undefined || faultWord === null) return '-';
|
||||
return '0x' + faultWord.toString(16).toUpperCase().padStart(4, '0');
|
||||
}
|
||||
|
||||
function updateCcuControlData(data) {
|
||||
if (data.ccuColCmd) {
|
||||
const ccuData = data.ccuColCmd;
|
||||
@@ -1812,4 +1856,4 @@ body {
|
||||
</html>
|
||||
)";
|
||||
|
||||
#endif // HTTP_SERVER_INDEX_H
|
||||
#endif // HTTP_SERVER_INDEX_H
|
||||
@@ -4,4 +4,6 @@ ProcessConfig = pPowerManger
|
||||
{
|
||||
AppTick = 4
|
||||
CommsTick = 4
|
||||
log_level = INFO
|
||||
log_file = /path/to/your/logfile.log
|
||||
}
|
||||
@@ -51,7 +51,16 @@ typedef struct ccuState
|
||||
uint16_t ch3oh_concentration1; // 舱室甲醇气体浓度1,单位:0.01% LEL
|
||||
uint16_t ch3oh_concentration2; // 舱室甲醇气体浓度2,单位:0.01% LEL
|
||||
|
||||
uint16_t reserved1[10]; // 保留字段,地址范围35~52,共18个uint16_t,协议预留
|
||||
uint16_t reserved1[2]; // 保留字段前2个元素
|
||||
uint16_t emergency_battery1_voltage; // 应急电池1总电压 [V]
|
||||
uint16_t emergency_battery1_current; // 应急电池1总电流 [A]
|
||||
uint16_t emergency_battery1_max_temp; // 应急电池1最高温度 [°C]
|
||||
uint16_t emergency_battery1_fault_word; // 应急电池1故障字
|
||||
uint16_t emergency_battery2_voltage; // 应急电池2总电压 [V]
|
||||
uint16_t emergency_battery2_current; // 应急电池2总电流 [A]
|
||||
uint16_t emergency_battery2_max_temp; // 应急电池2最高温度 [°C]
|
||||
uint16_t emergency_battery2_fault_word; // 应急电池2故障字
|
||||
|
||||
uint16_t cabin_ox_concentration; // 仪表舱内氧气浓度 [%]
|
||||
uint16_t cabin_temperature; // 仪表舱内温度 [°C]
|
||||
uint16_t cabin_humidity; // 仪表舱内湿度 [%RH]
|
||||
@@ -632,7 +641,7 @@ namespace WorkCondition {
|
||||
UNDERWATER_RECON = 9, // 水下侦查
|
||||
SURFACE_RECON = 10, // 水面侦查
|
||||
DJ_MODE = 11, // DJ模式
|
||||
DEBUG_MODE = 12 // 调试模式
|
||||
LIFT_MODE = 12 // 调试模式
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -3,13 +3,17 @@
|
||||
#include <iostream>
|
||||
#include "../logc/loguru.hpp"
|
||||
|
||||
SQLite::SQLite(const std::string& dbPath)
|
||||
{
|
||||
if (sqlite3_open(dbPath.c_str(), &m_db) != SQLITE_OK) {
|
||||
LOG_F(WARNING, "Can't open database: %s", sqlite3_errmsg(m_db));
|
||||
SQLite::SQLite(const std::string& dbPath) {
|
||||
try {
|
||||
if (sqlite3_open(dbPath.c_str(), &m_db) != SQLITE_OK) {
|
||||
LOG_F(ERROR, "无法打开数据库: %s", sqlite3_errmsg(m_db));
|
||||
m_db = nullptr;
|
||||
}
|
||||
m_dbPath = dbPath;
|
||||
} catch (...) {
|
||||
LOG_F(ERROR, "SQLite构造函数发生异常");
|
||||
m_db = nullptr;
|
||||
}
|
||||
m_dbPath = dbPath;
|
||||
}
|
||||
|
||||
SQLite::~SQLite()
|
||||
@@ -71,9 +75,15 @@ bool SQLite::createTable()
|
||||
o2_concentration2 INTEGER,
|
||||
ch3oh_concentration1 INTEGER,
|
||||
ch3oh_concentration2 INTEGER,
|
||||
reserved1_1 INTEGER, reserved1_2 INTEGER, reserved1_3 INTEGER, reserved1_4 INTEGER,
|
||||
reserved1_5 INTEGER, reserved1_6 INTEGER, reserved1_7 INTEGER, reserved1_8 INTEGER,
|
||||
reserved1_9 INTEGER, reserved1_10 INTEGER,
|
||||
reserved1_1 INTEGER, reserved1_2 INTEGER,
|
||||
emergency_battery1_voltage INTEGER,
|
||||
emergency_battery1_current INTEGER,
|
||||
emergency_battery1_max_temp INTEGER,
|
||||
emergency_battery1_fault_word INTEGER,
|
||||
emergency_battery2_voltage INTEGER,
|
||||
emergency_battery2_current INTEGER,
|
||||
emergency_battery2_max_temp INTEGER,
|
||||
emergency_battery2_fault_word INTEGER,
|
||||
cabin_ox_concentration INTEGER,
|
||||
cabin_temperature INTEGER,
|
||||
cabin_humidity INTEGER,
|
||||
@@ -269,7 +279,7 @@ bool SQLite::createTable()
|
||||
workCondition INTEGER,
|
||||
fcuCmd INTEGER,
|
||||
fcuPowerEfficiency INTEGER,
|
||||
fcuInsEfficiency INTEGER,
|
||||
insChargeEnable INTEGER,
|
||||
insBatCmd INTEGER,
|
||||
powerBatCmd INTEGER,
|
||||
powerBatEfficiency INTEGER,
|
||||
@@ -375,8 +385,9 @@ bool SQLite::insertData(const ccuState data) {
|
||||
h2_concentration1, h2_concentration2, h2_concentration3,
|
||||
o2_concentration1, o2_concentration2,
|
||||
ch3oh_concentration1, ch3oh_concentration2,
|
||||
reserved1_1, reserved1_2, reserved1_3, reserved1_4, reserved1_5,
|
||||
reserved1_6, reserved1_7, reserved1_8, reserved1_9, reserved1_10,
|
||||
reserved1_1, reserved1_2,
|
||||
emergency_battery1_voltage, emergency_battery1_current, emergency_battery1_max_temp, emergency_battery1_fault_word,
|
||||
emergency_battery2_voltage, emergency_battery2_current, emergency_battery2_max_temp, emergency_battery2_fault_word,
|
||||
cabin_ox_concentration, cabin_temperature, cabin_humidity, cabin_pressure,
|
||||
power_cabin_ox_concentration, power_cabin_temperature,
|
||||
power_cabin_humidity, power_cabin_pressure,
|
||||
@@ -417,7 +428,9 @@ bool SQLite::insertData(const ccuState data) {
|
||||
?, ?,
|
||||
?, ?,
|
||||
?, ?, ?, ?, ?,
|
||||
?, ?, ?, ?, ?,
|
||||
?, ?,
|
||||
?, ?, ?, ?,
|
||||
?, ?, ?, ?,
|
||||
?, ?, ?, ?,
|
||||
?, ?, ?, ?,
|
||||
?,
|
||||
@@ -430,8 +443,6 @@ bool SQLite::insertData(const ccuState data) {
|
||||
?, ?,
|
||||
?, ?,
|
||||
?, ?,
|
||||
?, ?,
|
||||
?, ?,
|
||||
?, ?, ?,
|
||||
?, ?,
|
||||
?, ?, ?,
|
||||
@@ -443,7 +454,7 @@ bool SQLite::insertData(const ccuState data) {
|
||||
?, ?, ?,
|
||||
?, ?,
|
||||
?, ?,
|
||||
?, ?
|
||||
?
|
||||
);
|
||||
)";
|
||||
|
||||
@@ -497,7 +508,16 @@ bool SQLite::insertData(const ccuState data) {
|
||||
BIND_16(data.ch3oh_concentration1);
|
||||
BIND_16(data.ch3oh_concentration2);
|
||||
|
||||
for (int i = 0; i < 10; ++i) BIND_16(data.reserved1[i]);
|
||||
for (int i = 0; i < 2; ++i) BIND_16(data.reserved1[i]);
|
||||
|
||||
BIND_16(data.emergency_battery1_voltage);
|
||||
BIND_16(data.emergency_battery1_current);
|
||||
BIND_16(data.emergency_battery1_max_temp);
|
||||
BIND_16(data.emergency_battery1_fault_word);
|
||||
BIND_16(data.emergency_battery2_voltage);
|
||||
BIND_16(data.emergency_battery2_current);
|
||||
BIND_16(data.emergency_battery2_max_temp);
|
||||
BIND_16(data.emergency_battery2_fault_word);
|
||||
|
||||
BIND_16(data.cabin_ox_concentration);
|
||||
BIND_16(data.cabin_temperature);
|
||||
@@ -626,8 +646,6 @@ bool SQLite::insertData(const ccuColCmd cmd) {
|
||||
if (!success) {
|
||||
std::cerr << "执行插入失败: " << sqlite3_errmsg(m_db) << std::endl;
|
||||
}
|
||||
|
||||
|
||||
sqlite3_finalize(stmt);
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -33,5 +33,4 @@ public:
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -205,6 +205,16 @@ public:
|
||||
unsigned char insfaultCode;
|
||||
|
||||
|
||||
//应急电池
|
||||
double emergency_battery1_voltage; // 应急电池1总电压 [V]
|
||||
double emergency_battery1_current; // 应急电池1总电流 [A]
|
||||
double emergency_battery1_max_temp; // 应急电池1最高温度 [°C]
|
||||
uint16_t emergency_battery1_fault_word; // 应急电池1故障字
|
||||
double emergency_battery2_voltage; // 应急电池2总电压 [V]
|
||||
double emergency_battery2_current; // 应急电池2总电流 [A]
|
||||
double emergency_battery2_max_temp; // 应急电池2最高温度 [°C]
|
||||
uint16_t emergency_battery2_fault_word; // 应急电池2故障字
|
||||
|
||||
// MOOSD 状态
|
||||
bool moosd_status;
|
||||
//配电系统状态
|
||||
@@ -522,15 +532,15 @@ public:
|
||||
};
|
||||
~SystemData(){};
|
||||
|
||||
void updateCommonStatus(double time_out=3){
|
||||
void updateCommonStatus(double time_out=10){
|
||||
//更新时间
|
||||
double currentTime = MOOSTime();
|
||||
//判断是否超时
|
||||
device_common_status.ccu_status.isTimeout = (currentTime - device_common_status.ccu_status.lastUpdateTime) > time_out;
|
||||
device_common_status.dis_hv_c1.isTimeout = (currentTime - device_common_status.dis_hv_c1.lastUpdateTime) > time_out;
|
||||
device_common_status.dis_hv_c2.isTimeout = (currentTime - device_common_status.dis_hv_c2.lastUpdateTime) > time_out;
|
||||
device_common_status.dis_lv_c1.isTimeout = (currentTime - device_common_status.dis_lv_c1.lastUpdateTime) > time_out;
|
||||
device_common_status.dis_lv_c2.isTimeout = (currentTime - device_common_status.dis_lv_c2.lastUpdateTime) > time_out;
|
||||
device_common_status.ccu_status.isTimeout = abs(currentTime - device_common_status.ccu_status.lastUpdateTime) > time_out;
|
||||
device_common_status.dis_hv_c1.isTimeout = abs(currentTime - device_common_status.dis_hv_c1.lastUpdateTime) > time_out;
|
||||
device_common_status.dis_hv_c2.isTimeout = abs(currentTime - device_common_status.dis_hv_c2.lastUpdateTime) > time_out;
|
||||
device_common_status.dis_lv_c1.isTimeout = abs(currentTime - device_common_status.dis_lv_c1.lastUpdateTime) > time_out;
|
||||
device_common_status.dis_lv_c2.isTimeout = abs(currentTime - device_common_status.dis_lv_c2.lastUpdateTime) > time_out;
|
||||
};
|
||||
|
||||
void updateSystemData(ccuState data){
|
||||
@@ -695,6 +705,17 @@ public:
|
||||
water_leak_status_from_dynbat = (data.dyn_water_leak_status >> 4) & 0x0F; // 00 正常,01 异常漏水
|
||||
dcdc_status_from_insbat = (data.ins_water_leak_dcdc_status) & 0x0F; // 00 正常,01 故障
|
||||
|
||||
|
||||
//应急电池
|
||||
emergency_battery1_voltage = data.emergency_battery1_voltage * 0.1;
|
||||
emergency_battery1_current = data.emergency_battery1_current * 0.05;
|
||||
emergency_battery1_max_temp = data.emergency_battery1_max_temp * 0.1;
|
||||
emergency_battery1_fault_word = data.emergency_battery1_fault_word;
|
||||
emergency_battery2_voltage = data.emergency_battery2_voltage * 0.1;
|
||||
emergency_battery2_current = data.emergency_battery2_current * 0.05;
|
||||
emergency_battery2_max_temp = data.emergency_battery2_max_temp * 0.1;
|
||||
emergency_battery2_fault_word = data.emergency_battery2_fault_word;
|
||||
|
||||
//心跳计数器
|
||||
heartbeat = data.heartbeat;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/* json 格式 XC阵控制软件→复合能源管控系统
|
||||
{
|
||||
"xcLowVoltageAdd_int32 " : XX //命令类型:“无命令”0,“申请仪表上电”1,“申请仪表断电”2;类型:int
|
||||
"xcHighVoltageAdd_int32 " : XX, //命令类型:“无命令”0,“申请高压上电”1,“申请高压断电”2;类型:int
|
||||
}
|
||||
*/
|
||||
#ifndef UDETECT_XCVOLTAGE_CMD_H
|
||||
#define UDETECT_XCVOLTAGE_CMD_H
|
||||
#include "../logc/loguru.hpp"
|
||||
#include "json/json.h"
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
class uDetect_xcVoltage_cmd
|
||||
{
|
||||
private:
|
||||
/* data */
|
||||
public:
|
||||
uDetect_xcVoltage_cmd(){};
|
||||
~uDetect_xcVoltage_cmd(){};
|
||||
|
||||
int xcLowVoltageAdd_int32;
|
||||
int xcHighVoltageAdd_int32;
|
||||
|
||||
static std::string key;
|
||||
|
||||
std::string toJsonString()
|
||||
{
|
||||
Json::Value j;
|
||||
j["xcLowVoltageAdd_int32"] = xcLowVoltageAdd_int32;
|
||||
j["xcHighVoltageAdd_int32"] = xcHighVoltageAdd_int32;
|
||||
|
||||
Json::StreamWriterBuilder builder;
|
||||
builder.settings_["indentation"] = "";
|
||||
return Json::writeString(builder, j);
|
||||
}
|
||||
bool fromJsonString(std::string jsonString)
|
||||
{
|
||||
Json::CharReaderBuilder readerBuilder;
|
||||
std::unique_ptr<Json::CharReader> reader(readerBuilder.newCharReader());
|
||||
Json::Value j;
|
||||
std::string errors;
|
||||
|
||||
bool parsingSuccessful = reader->parse(jsonString.c_str(), jsonString.c_str() + jsonString.length(), &j, &errors);
|
||||
if (!parsingSuccessful) {
|
||||
LOG_F(ERROR, "Failed to parse JSON: %s", errors.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (j.isMember("xcLowVoltageAdd_int32") && j.isMember("xcHighVoltageAdd_int32")) {
|
||||
xcLowVoltageAdd_int32 = j["xcLowVoltageAdd_int32"].asInt();
|
||||
xcHighVoltageAdd_int32 = j["xcHighVoltageAdd_int32"].asInt();
|
||||
LOG_F(INFO, "xcLowVoltageAdd_int32: %d", xcLowVoltageAdd_int32);
|
||||
LOG_F(INFO, "xcHighVoltageAdd_int32: %d", xcHighVoltageAdd_int32);
|
||||
LOG_F(INFO, "jsonString: %s", jsonString.c_str());
|
||||
return true;
|
||||
}
|
||||
LOG_F(ERROR, "JSON does not contain required fields");
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,58 @@
|
||||
/* json 格式 XC阵控制软件→复合能源管控系统
|
||||
{
|
||||
"zdpVoltageAdd_int32 " : XX //命令类型:“无命令”0,“申请仪表上电”1,“申请仪表断电”2;类型:int
|
||||
}
|
||||
*/
|
||||
#ifndef UDETECT_ZDPVOLTAGE_CMD_H
|
||||
#define UDETECT_ZDPVOLTAGE_CMD_H
|
||||
#include "../logc/loguru.hpp"
|
||||
#include "json/json.h"
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
class uDetect_zdpVoltage_cmd
|
||||
{
|
||||
private:
|
||||
/* data */
|
||||
public:
|
||||
uDetect_zdpVoltage_cmd(){};
|
||||
~uDetect_zdpVoltage_cmd(){};
|
||||
|
||||
int zdpVoltageAdd_int32;
|
||||
|
||||
static std::string key;
|
||||
|
||||
std::string toJsonString()
|
||||
{
|
||||
Json::Value j;
|
||||
j["zdpVoltageAdd_int32"] = zdpVoltageAdd_int32;
|
||||
|
||||
Json::StreamWriterBuilder builder;
|
||||
builder.settings_["indentation"] = "";
|
||||
return Json::writeString(builder, j);
|
||||
}
|
||||
bool fromJsonString(std::string jsonString)
|
||||
{
|
||||
Json::CharReaderBuilder readerBuilder;
|
||||
std::unique_ptr<Json::CharReader> reader(readerBuilder.newCharReader());
|
||||
Json::Value j;
|
||||
std::string errors;
|
||||
|
||||
bool parsingSuccessful = reader->parse(jsonString.c_str(), jsonString.c_str() + jsonString.length(), &j, &errors);
|
||||
if (!parsingSuccessful) {
|
||||
LOG_F(ERROR, "Failed to parse JSON: %s", errors.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (j.isMember("zdpVoltageAdd_int32")) {
|
||||
zdpVoltageAdd_int32 = j["zdpVoltageAdd_int32"].asInt();
|
||||
LOG_F(INFO, "zdpVoltageAdd_int32: %d", zdpVoltageAdd_int32);
|
||||
LOG_F(INFO, "jsonString: %s", jsonString.c_str());
|
||||
return true;
|
||||
}
|
||||
LOG_F(ERROR, "JSON does not contain required fields");
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "uDetect_zdpVoltage_cmd.h"
|
||||
#include "uDetect_xcVoltage_cmd.h"
|
||||
|
||||
// 定义静态成员变量
|
||||
std::string uDetect_zdpVoltage_cmd::key = "uDetect_zdpVoltage_cmd";
|
||||
std::string uDetect_xcVoltage_cmd::key = "uDetect_xcVoltage_cmd";
|
||||
+16
-31
@@ -1,44 +1,29 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(SQLiteDBTest)
|
||||
project(H100PowerMangerTests)
|
||||
|
||||
# 设置 C++ 标准
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
#############################################SQLiteDBTest####################################################################
|
||||
# 查找 SQLiteDB 项目库
|
||||
find_library(SQLiteDB_LIB NAMES SQLiteDB PATHS /home/zjk/project/H100/H100PowerManger/lib)
|
||||
if(NOT SQLiteDB_LIB)
|
||||
message(FATAL_ERROR "SQLiteDB library not found!")
|
||||
endif()
|
||||
|
||||
# 查找 Catch2 测试框架
|
||||
find_package(Catch2 REQUIRED)
|
||||
|
||||
# 添加测试可执行文件
|
||||
add_executable(SQLiteDBTest SQLiteDBTest.cpp)
|
||||
# 链接库文件(注意顺序:先项目库后系统库)
|
||||
target_link_libraries(SQLiteDBTest
|
||||
${SQLiteDB_LIB} # 项目SQLiteDB库
|
||||
Catch2::Catch2WithMain # 测试框架
|
||||
sqlite3
|
||||
jsoncpp
|
||||
################################################SQLiteTest####################################################################
|
||||
# 添加 SQLite 测试可执行文件(不使用第三方测试库)
|
||||
add_executable(SQLiteTest
|
||||
until/testSqlitdb.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/pPowerManger/sqlit3/SQLite.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/pPowerManger/sqlit3/sqlite3.c
|
||||
${CMAKE_SOURCE_DIR}/src/pPowerManger/logc/loguru.cpp
|
||||
)
|
||||
|
||||
################################################udpCommTest####################################################################
|
||||
# 查找 udpComm 项目库
|
||||
find_library(UDPCOMM_LIB NAMES UDPComm PATHS /home/zjk/project/H100/H100PowerManger/lib)
|
||||
if(NOT UDPCOMM_LIB)
|
||||
message(FATAL_ERROR "udpComm library not found!")
|
||||
endif()
|
||||
# 包含目录
|
||||
target_include_directories(SQLiteTest PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/src/pPowerManger
|
||||
${CMAKE_SOURCE_DIR}/src/pPowerManger/sqlit3
|
||||
)
|
||||
|
||||
# 添加 udpComm 测试可执行文件
|
||||
add_executable(udpCommTest udpCommTest.cpp)
|
||||
|
||||
# 链接库文件(注意顺序:先项目库后系统库)
|
||||
target_link_libraries(udpCommTest
|
||||
${UDPCOMM_LIB} # 项目udpComm库
|
||||
${MOOS_LIBRARIES}
|
||||
Catch2::Catch2WithMain # 测试框架
|
||||
# 链接库文件
|
||||
target_link_libraries(SQLiteTest
|
||||
pthread
|
||||
)
|
||||
|
||||
################################################PowerMangerTest####################################################################
|
||||
|
||||
@@ -70,13 +70,13 @@ class PowerManagerApp:
|
||||
|
||||
# 高压配电板端口
|
||||
self.disSysPortC1 = 6000
|
||||
# self.disSysHostC1 = '192.168.1.154'
|
||||
self.disSysHostC1 = '127.0.0.1'
|
||||
self.disSysHostC1 = '192.168.1.154'
|
||||
# self.disSysHostC1 = '127.0.0.1'
|
||||
|
||||
# 仪表配电板端口
|
||||
self.disSysPortC2 = 6000
|
||||
# self.disSysHostC2 = '192.168.1.158'
|
||||
self.disSysHostC2 = '127.0.0.1'
|
||||
self.disSysHostC2 = '192.168.1.158'
|
||||
# self.disSysHostC2 = '127.0.0.1'
|
||||
|
||||
# 数据库配置
|
||||
self.db = DB(os.path.join(os.path.dirname(__file__), 'test.db'))
|
||||
@@ -419,6 +419,8 @@ class PowerManagerApp:
|
||||
menubar.add_cascade(label="配电操作", menu=dis_options_menu)
|
||||
|
||||
menubar.add_command(label="DCDC状态", command=lambda: self.show_popup_window("DCDC状态"))
|
||||
menubar.add_command(label="复合管控面板", command=lambda: self.show_compound_control_window("复合管控面板"))
|
||||
menubar.add_command(label="软件说明", command=lambda: self.show_help_window("程序说明"))
|
||||
# 配置菜单栏
|
||||
self.root.config(menu=menubar)
|
||||
|
||||
@@ -1826,6 +1828,70 @@ class PowerManagerApp:
|
||||
close_button = ttk.Button(popup, text="关闭", command=popup.destroy)
|
||||
close_button.pack(pady=10)
|
||||
|
||||
def show_compound_control_window(self, title):
|
||||
"""创建并显示弹出窗口"""
|
||||
popup = tk.Toplevel(self.root)
|
||||
popup.title(title)
|
||||
frame = ttk.Frame(popup)
|
||||
popup.geometry("600x400")
|
||||
popup.resizable(True, True)
|
||||
frame.pack(fill="both", expand=True, padx=5, pady=5)
|
||||
|
||||
def show_help_window(self, title):
|
||||
"""显示程序说明弹窗"""
|
||||
popup = tk.Toplevel(self.root)
|
||||
popup.title(title)
|
||||
popup.geometry("600x400")
|
||||
popup.resizable(True, True)
|
||||
|
||||
# 创建文本框和滚动条
|
||||
frame = ttk.Frame(popup)
|
||||
frame.pack(fill="both", expand=True, padx=10, pady=10)
|
||||
|
||||
text_widget = tk.Text(frame, wrap="word", font=("Microsoft YaHei", 10))
|
||||
scrollbar = ttk.Scrollbar(frame, orient="vertical", command=text_widget.yview)
|
||||
text_widget.configure(yscrollcommand=scrollbar.set)
|
||||
|
||||
text_widget.pack(side="left", fill="both", expand=True)
|
||||
scrollbar.pack(side="right", fill="y")
|
||||
|
||||
# 程序说明内容
|
||||
help_text = """H100动力管理系统程序说明
|
||||
|
||||
版本:v1.0
|
||||
|
||||
功能概述:
|
||||
1. 高压母线状态监控 - 实时显示动力母线电压、电流及断路器状态
|
||||
2. 高压A母线状态监控 - 监控汇流排B电压电流及断路器状态
|
||||
3. 仪表主母线状态监控 - 显示仪表母线电压电流及配电状态
|
||||
4. 仪表母线状态监控 - 监控应急电源系统状态
|
||||
5. 配电指令控制 - 支持远程断路器合分操作
|
||||
6. 数据记录 - 所有状态数据自动保存到SQLite数据库
|
||||
7. 模拟模式 - 支持离线模拟测试
|
||||
|
||||
通信协议:
|
||||
- 采用UDP协议与分布式系统通信
|
||||
- 消息ID范围:0x0001-0x0008
|
||||
- 支持实时状态反馈和指令下发
|
||||
|
||||
操作说明:
|
||||
1. 主界面显示各母线实时状态
|
||||
2. 通过菜单栏可打开各配电控制面板
|
||||
3. 断路器状态:黄色=合闸,黑色=分闸,红色=故障
|
||||
4. 启用模拟模式可进行离线测试
|
||||
|
||||
注意事项:
|
||||
- 操作前请确认系统连接正常
|
||||
- 重要操作需双重确认
|
||||
- 定期检查数据库存储状态"""
|
||||
|
||||
text_widget.insert("1.0", help_text)
|
||||
text_widget.config(state="disabled") # 设置为只读
|
||||
|
||||
# 关闭按钮
|
||||
close_btn = ttk.Button(popup, text="关闭", command=popup.destroy)
|
||||
close_btn.pack(pady=10)
|
||||
|
||||
if __name__ == "__main__":
|
||||
root = tk.Tk()
|
||||
app = PowerManagerApp(root)
|
||||
|
||||
@@ -59,8 +59,8 @@ class PowerManagerApp:
|
||||
# self.udp_control_host = "127.0.0.1"
|
||||
|
||||
# 下位机端口
|
||||
# self.udp_ip = "127.0.0.1"
|
||||
self.udp_ip = "192.168.0.140"
|
||||
self.udp_ip = "127.0.0.1"
|
||||
# self.udp_ip = "192.168.0.140"
|
||||
self.udp_port = 7000
|
||||
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
self.sock.bind((self.udp_ip, self.udp_port))
|
||||
@@ -1666,4 +1666,4 @@ if __name__ == "__main__":
|
||||
root.protocol("WM_DELETE_WINDOW", app.on_closing)
|
||||
print('start')
|
||||
root.mainloop()
|
||||
print('end')
|
||||
print('end')
|
||||
@@ -0,0 +1,636 @@
|
||||
import struct
|
||||
import datetime
|
||||
|
||||
class msg_ccUFbMsg:
|
||||
def __init__(self):
|
||||
# 消息头
|
||||
self.start1 = 0x20
|
||||
self.start2 = 0x20
|
||||
self.id = 0x0051 # CCU_STATE_FB_ID
|
||||
self.length = 0
|
||||
self.checkCode = 0x00
|
||||
|
||||
# CCU状态数据 - 根据ccuState结构体定义
|
||||
self.fc_mode = 0x00
|
||||
self.fc_status = 0x00
|
||||
self.fc_fault_level = 0x00
|
||||
|
||||
self.output_power_limit = 0
|
||||
self.total_generation_time = 0
|
||||
self.total_generation_power = 0
|
||||
self.fault_level_1 = 0
|
||||
self.fault_level_2 = 0
|
||||
self.fault_level_3 = 0
|
||||
self.fault_level_4 = 0
|
||||
|
||||
self.hydrogen_capacity = 0
|
||||
self.liquid_oxygen_capacity = 0
|
||||
|
||||
self.palladium_temp = 0
|
||||
self.main_pipe_pressure = 0
|
||||
self.aux_pipe_pressure = 0
|
||||
|
||||
self.cabin_pressure1 = 0
|
||||
self.cabin_pressure2 = 0
|
||||
self.cabin_temp1 = 0
|
||||
self.cabin_temp2 = 0
|
||||
self.cabin_humidity1 = 0
|
||||
self.cabin_humidity2 = 0
|
||||
|
||||
self.flame_detector1 = 0x00
|
||||
self.flame_detector2 = 0x00
|
||||
|
||||
self.h2_concentration1 = 0
|
||||
self.h2_concentration2 = 0
|
||||
self.h2_concentration3 = 0
|
||||
self.o2_concentration1 = 0
|
||||
self.o2_concentration2 = 0
|
||||
self.ch3oh_concentration1 = 0
|
||||
self.ch3oh_concentration2 = 0
|
||||
|
||||
self.reserved1 = [0, 0]
|
||||
self.emergency_battery1_voltage = 0
|
||||
self.emergency_battery1_current = 0
|
||||
self.emergency_battery1_max_temp = 0
|
||||
self.emergency_battery1_fault_word = 0
|
||||
self.emergency_battery2_voltage = 0
|
||||
self.emergency_battery2_current = 0
|
||||
self.emergency_battery2_max_temp = 0
|
||||
self.emergency_battery2_fault_word = 0
|
||||
|
||||
self.cabin_ox_concentration = 0
|
||||
self.cabin_temperature = 0
|
||||
self.cabin_humidity = 0
|
||||
self.cabin_pressure = 0
|
||||
|
||||
self.power_cabin_ox_concentration = 0
|
||||
self.power_cabin_temperature = 0
|
||||
self.power_cabin_humidity = 0
|
||||
self.power_cabin_pressure = 0
|
||||
self.reserved2 = [0]
|
||||
|
||||
self.dyn_alarm_flag = [0] * 6
|
||||
self.ins_alarm_flag = [0] * 6
|
||||
|
||||
self.ins_relay_status1 = 0x00
|
||||
self.ins_relay_status2 = 0x00
|
||||
self.dyn_relay_status1 = 0x00
|
||||
self.dyn_relay_status2 = 0x00
|
||||
|
||||
self.ins_max_discharge_power = 0
|
||||
self.dyn_max_discharge_power = 0
|
||||
|
||||
self.ins_soc = 0
|
||||
self.dyn_soc = 0
|
||||
|
||||
self.ins_total_energy = 0
|
||||
self.dyn_total_energy = 0
|
||||
|
||||
self.ins_power_input = 0
|
||||
self.dyn_power_input = 0
|
||||
|
||||
self.ins_charge_status = 0x00
|
||||
self.dyn_charge_status = 0x00
|
||||
|
||||
self.ins_voltage_link = 0
|
||||
self.ins_voltage_pack = 0
|
||||
self.ins_current = 0
|
||||
self.ins_resistance_pos = 0
|
||||
self.ins_resistance_neg = 0
|
||||
|
||||
self.dyn_voltage_link = 0
|
||||
self.dyn_voltage_pack = 0
|
||||
self.dyn_current = 0
|
||||
self.dyn_resistance_pos = 0
|
||||
self.dyn_resistance_neg = 0
|
||||
|
||||
self.ins_emergency_status = 0x00
|
||||
self.dyn_emergency_status = 0x00
|
||||
|
||||
self.reserved3 = [0] * 2
|
||||
|
||||
self.ins_soc_threshold1 = 0
|
||||
self.ins_soc_threshold2 = 0
|
||||
self.ins_soc_threshold3 = 0
|
||||
self.dyn_soc_threshold1 = 0
|
||||
self.dyn_soc_threshold2 = 0
|
||||
self.dyn_soc_threshold3 = 0
|
||||
|
||||
self.ins_power_limit1 = 0
|
||||
self.ins_power_limit2 = 0
|
||||
self.dyn_power_limit1 = 0
|
||||
self.dyn_power_limit2 = 0
|
||||
|
||||
self.device_online_flag1 = 0
|
||||
self.device_online_flag2 = 0
|
||||
|
||||
self.dyn_charge_level = 0x00
|
||||
self.dyn_water_leak_status = 0x00
|
||||
self.ins_water_leak_dcdc_status = 0x00
|
||||
self.reserved4 = 0x00
|
||||
self.heartbeat = 0
|
||||
|
||||
def pack(self):
|
||||
"""打包消息为字节数据"""
|
||||
# 重置校验码
|
||||
self.checkCode = 0x00
|
||||
|
||||
# 打包消息头
|
||||
data = struct.pack('<BBHH',
|
||||
self.start1,
|
||||
self.start2,
|
||||
self.id,
|
||||
self.length)
|
||||
|
||||
# 打包CCU状态数据
|
||||
data += struct.pack('<BBB',
|
||||
self.fc_mode,
|
||||
self.fc_status,
|
||||
self.fc_fault_level)
|
||||
|
||||
data += struct.pack('<HHHHHHH',
|
||||
self.output_power_limit,
|
||||
self.total_generation_time,
|
||||
self.total_generation_power,
|
||||
self.fault_level_1,
|
||||
self.fault_level_2,
|
||||
self.fault_level_3,
|
||||
self.fault_level_4)
|
||||
|
||||
data += struct.pack('<BB',
|
||||
self.hydrogen_capacity,
|
||||
self.liquid_oxygen_capacity)
|
||||
|
||||
data += struct.pack('<HHH',
|
||||
self.palladium_temp,
|
||||
self.main_pipe_pressure,
|
||||
self.aux_pipe_pressure)
|
||||
|
||||
data += struct.pack('<HHHHHH',
|
||||
self.cabin_pressure1,
|
||||
self.cabin_pressure2,
|
||||
self.cabin_temp1,
|
||||
self.cabin_temp2,
|
||||
self.cabin_humidity1,
|
||||
self.cabin_humidity2)
|
||||
|
||||
data += struct.pack('<BB',
|
||||
self.flame_detector1,
|
||||
self.flame_detector2)
|
||||
|
||||
data += struct.pack('<HHHHHHH',
|
||||
self.h2_concentration1,
|
||||
self.h2_concentration2,
|
||||
self.h2_concentration3,
|
||||
self.o2_concentration1,
|
||||
self.o2_concentration2,
|
||||
self.ch3oh_concentration1,
|
||||
self.ch3oh_concentration2)
|
||||
|
||||
# 保留字段和应急电池数据
|
||||
data += struct.pack('<HHHHHHHH',
|
||||
self.reserved1[0], self.reserved1[1],
|
||||
self.emergency_battery1_voltage,
|
||||
self.emergency_battery1_current,
|
||||
self.emergency_battery1_max_temp,
|
||||
self.emergency_battery1_fault_word,
|
||||
self.emergency_battery2_voltage,
|
||||
self.emergency_battery2_current)
|
||||
|
||||
data += struct.pack('<HHHH',
|
||||
self.emergency_battery2_max_temp,
|
||||
self.emergency_battery2_fault_word,
|
||||
self.cabin_ox_concentration,
|
||||
self.cabin_temperature)
|
||||
|
||||
data += struct.pack('<HHHHHHHH',
|
||||
self.cabin_humidity,
|
||||
self.cabin_pressure,
|
||||
self.power_cabin_ox_concentration,
|
||||
self.power_cabin_temperature,
|
||||
self.power_cabin_humidity,
|
||||
self.power_cabin_pressure,
|
||||
self.reserved2[0], 0) # 填充第二个reserved2字节
|
||||
|
||||
# 报警标志数组
|
||||
for flag in self.dyn_alarm_flag:
|
||||
data += struct.pack('<B', flag)
|
||||
for flag in self.ins_alarm_flag:
|
||||
data += struct.pack('<B', flag)
|
||||
|
||||
# 继电器状态
|
||||
data += struct.pack('<BBBB',
|
||||
self.ins_relay_status1,
|
||||
self.ins_relay_status2,
|
||||
self.dyn_relay_status1,
|
||||
self.dyn_relay_status2)
|
||||
|
||||
# 功率和SOC数据
|
||||
data += struct.pack('<HHBBHHHH',
|
||||
self.ins_max_discharge_power,
|
||||
self.dyn_max_discharge_power,
|
||||
self.ins_soc,
|
||||
self.dyn_soc,
|
||||
self.ins_total_energy,
|
||||
self.dyn_total_energy,
|
||||
self.ins_power_input,
|
||||
self.dyn_power_input)
|
||||
|
||||
# 充电状态
|
||||
data += struct.pack('<BB',
|
||||
self.ins_charge_status,
|
||||
self.dyn_charge_status)
|
||||
|
||||
# 电压电流和绝缘电阻
|
||||
data += struct.pack('<HHHHHHHHHH',
|
||||
self.ins_voltage_link,
|
||||
self.ins_voltage_pack,
|
||||
self.ins_current,
|
||||
self.ins_resistance_pos,
|
||||
self.ins_resistance_neg,
|
||||
self.dyn_voltage_link,
|
||||
self.dyn_voltage_pack,
|
||||
self.dyn_current,
|
||||
self.dyn_resistance_pos,
|
||||
self.dyn_resistance_neg)
|
||||
|
||||
# 紧急状态和保留字段
|
||||
data += struct.pack('<BB',
|
||||
self.ins_emergency_status,
|
||||
self.dyn_emergency_status)
|
||||
|
||||
data += struct.pack('<BB',
|
||||
self.reserved3[0], self.reserved3[1])
|
||||
|
||||
# SOC门限值
|
||||
data += struct.pack('<BBBBBB',
|
||||
self.ins_soc_threshold1,
|
||||
self.ins_soc_threshold2,
|
||||
self.ins_soc_threshold3,
|
||||
self.dyn_soc_threshold1,
|
||||
self.dyn_soc_threshold2,
|
||||
self.dyn_soc_threshold3)
|
||||
|
||||
# 功率限制值
|
||||
data += struct.pack('<BBBB',
|
||||
self.ins_power_limit1,
|
||||
self.ins_power_limit2,
|
||||
self.dyn_power_limit1,
|
||||
self.dyn_power_limit2)
|
||||
|
||||
# 设备在线状态和心跳
|
||||
data += struct.pack('<II',
|
||||
self.device_online_flag1,
|
||||
self.device_online_flag2)
|
||||
|
||||
data += struct.pack('<BBBB',
|
||||
self.dyn_charge_level,
|
||||
self.dyn_water_leak_status,
|
||||
self.ins_water_leak_dcdc_status,
|
||||
self.reserved4)
|
||||
|
||||
data += struct.pack('<I', self.heartbeat)
|
||||
|
||||
# 计算校验码
|
||||
self.checkCode = 0
|
||||
for byte in data:
|
||||
self.checkCode = (self.checkCode + byte) & 0xFF
|
||||
|
||||
# 添加校验码
|
||||
data += struct.pack('<B', self.checkCode)
|
||||
|
||||
# 更新长度字段
|
||||
self.length = len(data) - 6 # 减去头部6字节
|
||||
|
||||
return data
|
||||
|
||||
def unpack(self, data):
|
||||
"""从字节数据解包消息"""
|
||||
if len(data) < 10: # 最小消息长度检查
|
||||
return False
|
||||
|
||||
# 解析消息头
|
||||
self.start1 = data[0]
|
||||
self.start2 = data[1]
|
||||
self.id = struct.unpack_from('<H', data, 2)[0]
|
||||
self.length = struct.unpack_from('<H', data, 4)[0]
|
||||
|
||||
offset = 6 # 头部结束位置
|
||||
|
||||
# 检查数据长度是否足够
|
||||
if len(data) < offset + self.length + 1: # +1 for checksum
|
||||
return False
|
||||
|
||||
# 解析CCU状态数据
|
||||
(self.fc_mode, self.fc_status, self.fc_fault_level) = struct.unpack_from('<BBB', data, offset); offset += 3
|
||||
|
||||
(self.output_power_limit, self.total_generation_time, self.total_generation_power,
|
||||
self.fault_level_1, self.fault_level_2, self.fault_level_3, self.fault_level_4) = struct.unpack_from('<HHHHHHH', data, offset); offset += 14
|
||||
|
||||
(self.hydrogen_capacity, self.liquid_oxygen_capacity) = struct.unpack_from('<BB', data, offset); offset += 2
|
||||
|
||||
(self.palladium_temp, self.main_pipe_pressure, self.aux_pipe_pressure) = struct.unpack_from('<HHH', data, offset); offset += 6
|
||||
|
||||
(self.cabin_pressure1, self.cabin_pressure2, self.cabin_temp1, self.cabin_temp2,
|
||||
self.cabin_humidity1, self.cabin_humidity2) = struct.unpack_from('<HHHHHH', data, offset); offset += 12
|
||||
|
||||
(self.flame_detector1, self.flame_detector2) = struct.unpack_from('<BB', data, offset); offset += 2
|
||||
|
||||
(self.h2_concentration1, self.h2_concentration2, self.h2_concentration3,
|
||||
self.o2_concentration1, self.o2_concentration2, self.ch3oh_concentration1,
|
||||
self.ch3oh_concentration2) = struct.unpack_from('<HHHHHHH', data, offset); offset += 14
|
||||
|
||||
# 保留字段和应急电池数据
|
||||
(self.reserved1[0], self.reserved1[1], self.emergency_battery1_voltage,
|
||||
self.emergency_battery1_current, self.emergency_battery1_max_temp,
|
||||
self.emergency_battery1_fault_word, self.emergency_battery2_voltage,
|
||||
self.emergency_battery2_current) = struct.unpack_from('<HHHHHHHH', data, offset); offset += 16
|
||||
|
||||
(self.emergency_battery2_max_temp, self.emergency_battery2_fault_word,
|
||||
self.cabin_ox_concentration, self.cabin_temperature) = struct.unpack_from('<HHHH', data, offset); offset += 8
|
||||
|
||||
(self.cabin_humidity, self.cabin_pressure, self.power_cabin_ox_concentration,
|
||||
self.power_cabin_temperature, self.power_cabin_humidity, self.power_cabin_pressure,
|
||||
reserved2_0, reserved2_1) = struct.unpack_from('<HHHHHHBB', data, offset); offset += 16
|
||||
self.reserved2 = [reserved2_0, reserved2_1]
|
||||
|
||||
# 报警标志数组
|
||||
for i in range(6):
|
||||
self.dyn_alarm_flag[i] = data[offset]; offset += 1
|
||||
for i in range(6):
|
||||
self.ins_alarm_flag[i] = data[offset]; offset += 1
|
||||
|
||||
# 继电器状态
|
||||
(self.ins_relay_status1, self.ins_relay_status2,
|
||||
self.dyn_relay_status1, self.dyn_relay_status2) = struct.unpack_from('<BBBB', data, offset); offset += 4
|
||||
|
||||
# 功率和SOC数据
|
||||
(self.ins_max_discharge_power, self.dyn_max_discharge_power,
|
||||
self.ins_soc, self.dyn_soc, self.ins_total_energy, self.dyn_total_energy,
|
||||
self.ins_power_input, self.dyn_power_input) = struct.unpack_from('<HHBBHHHH', data, offset); offset += 14
|
||||
|
||||
# 充电状态
|
||||
(self.ins_charge_status, self.dyn_charge_status) = struct.unpack_from('<BB', data, offset); offset += 2
|
||||
|
||||
# 电压电流和绝缘电阻
|
||||
(self.ins_voltage_link, self.ins_voltage_pack, self.ins_current,
|
||||
self.ins_resistance_pos, self.ins_resistance_neg, self.dyn_voltage_link,
|
||||
self.dyn_voltage_pack, self.dyn_current, self.dyn_resistance_pos,
|
||||
self.dyn_resistance_neg) = struct.unpack_from('<HHHHHHHHHH', data, offset); offset += 20
|
||||
|
||||
# 紧急状态和保留字段
|
||||
(self.ins_emergency_status, self.dyn_emergency_status) = struct.unpack_from('<BB', data, offset); offset += 2
|
||||
|
||||
(self.reserved3[0], self.reserved3[1]) = struct.unpack_from('<BB', data, offset); offset += 2
|
||||
|
||||
# SOC门限值
|
||||
(self.ins_soc_threshold1, self.ins_soc_threshold2, self.ins_soc_threshold3,
|
||||
self.dyn_soc_threshold1, self.dyn_soc_threshold2, self.dyn_soc_threshold3) = struct.unpack_from('<BBBBBB', data, offset); offset += 6
|
||||
|
||||
# 功率限制值
|
||||
(self.ins_power_limit1, self.ins_power_limit2,
|
||||
self.dyn_power_limit1, self.dyn_power_limit2) = struct.unpack_from('<BBBB', data, offset); offset += 4
|
||||
|
||||
# 设备在线状态和心跳
|
||||
(self.device_online_flag1, self.device_online_flag2) = struct.unpack_from('<II', data, offset); offset += 8
|
||||
|
||||
(self.dyn_charge_level, self.dyn_water_leak_status,
|
||||
self.ins_water_leak_dcdc_status, self.reserved4) = struct.unpack_from('<BBBB', data, offset); offset += 4
|
||||
|
||||
(self.heartbeat,) = struct.unpack_from('<I', data, offset); offset += 4
|
||||
|
||||
# 校验校验码
|
||||
checkCode = 0
|
||||
for byte in data[:-1]: # 不包括校验码本身
|
||||
checkCode = (checkCode + byte) & 0xFF
|
||||
|
||||
return checkCode == data[-1]
|
||||
|
||||
def print_info(self):
|
||||
"""打印消息信息"""
|
||||
print(f"消息头: start1=0x{self.start1:02X}, start2=0x{self.start2:02X}, id=0x{self.id:04X}, length={self.length}")
|
||||
print(f"燃料电池模式: 0x{self.fc_mode:02X}")
|
||||
print(f"燃料电池状态: 0x{self.fc_status:02X}")
|
||||
print(f"故障等级: 0x{self.fc_fault_level:02X}")
|
||||
print(f"输出功率限制: {self.output_power_limit}W")
|
||||
print(f"累计发电时间: {self.total_generation_time * 0.1}小时")
|
||||
print(f"发电总功率: {self.total_generation_power}W")
|
||||
print(f"储氢容量: {self.hydrogen_capacity}%")
|
||||
print(f"液氧容量: {self.liquid_oxygen_capacity}%")
|
||||
print(f"钯膜温度: {self.palladium_temp}℃")
|
||||
print(f"主水路压力: {self.main_pipe_pressure * 0.01}kPa")
|
||||
print(f"辅水路压力: {self.aux_pipe_pressure * 0.01}kPa")
|
||||
print(f"仪表SOC: {self.ins_soc}%")
|
||||
print(f"动力SOC: {self.dyn_soc}%")
|
||||
print(f"心跳计数器: {self.heartbeat}")
|
||||
print(f"校验码: 0x{self.checkCode:02X}")
|
||||
|
||||
|
||||
class msg_ccUCmdMsg:
|
||||
def __init__(self):
|
||||
# 消息头
|
||||
self.start1 = 0x20
|
||||
self.start2 = 0x20
|
||||
self.id = 0x0040 # CCU_CMD_ID
|
||||
self.length = 0
|
||||
self.checkCode = 0x00
|
||||
|
||||
# 时间戳
|
||||
self.year = 0
|
||||
self.month = 0
|
||||
self.day = 0
|
||||
self.hour = 0
|
||||
self.minute = 0
|
||||
self.second = 0
|
||||
self.milliseconds = 0
|
||||
|
||||
# 复合管控器操作指令
|
||||
self.fcmode = 0x00 # 燃料电池运行模式
|
||||
self.fcuCmd = 0x00 # 燃料电池控制命令
|
||||
self.fcuPowerEfficiency = 0x00 # 燃料电池功率效率
|
||||
self.insChargeEnable = 0x00 # 仪表电池充电使能
|
||||
self.insBatCmd = 0x00 # 仪表电池命令
|
||||
self.powerBatCmd = 0x00 # 动力电池命令
|
||||
self.powerBatEfficiency = 0 # 动力电池功率效率
|
||||
self.heartbeat = 0 # 心跳
|
||||
self.masterState = 0x00 # 主控状态
|
||||
self.paceholder1 = 0 # 占位符1
|
||||
self.paceholder2 = 0 # 占位符2
|
||||
|
||||
def pack(self):
|
||||
"""打包消息为字节数据"""
|
||||
# 重置校验码
|
||||
self.checkCode = 0x00
|
||||
|
||||
# 打包消息头
|
||||
data = struct.pack('<BBHH',
|
||||
self.start1,
|
||||
self.start2,
|
||||
self.id,
|
||||
self.length)
|
||||
|
||||
# 打包时间戳
|
||||
data += struct.pack('<HBBBBBB',
|
||||
self.year,
|
||||
self.month,
|
||||
self.day,
|
||||
self.hour,
|
||||
self.minute,
|
||||
self.second,
|
||||
self.milliseconds)
|
||||
|
||||
# 打包复合管控器操作指令
|
||||
data += struct.pack('<BBBBBBHBBII',
|
||||
self.fcmode,
|
||||
self.fcuCmd,
|
||||
self.fcuPowerEfficiency,
|
||||
self.insChargeEnable,
|
||||
self.insBatCmd,
|
||||
self.powerBatCmd,
|
||||
self.powerBatEfficiency,
|
||||
self.heartbeat,
|
||||
self.masterState,
|
||||
self.paceholder1,
|
||||
self.paceholder2)
|
||||
|
||||
# 计算校验码
|
||||
self.checkCode = 0
|
||||
for byte in data:
|
||||
self.checkCode = (self.checkCode + byte) & 0xFF
|
||||
|
||||
# 添加校验码
|
||||
data += struct.pack('<B', self.checkCode)
|
||||
|
||||
# 更新长度字段
|
||||
self.length = len(data) - 6 # 减去头部6字节
|
||||
|
||||
return data
|
||||
|
||||
def unpack(self, data):
|
||||
"""从字节数据解包消息"""
|
||||
if len(data) < 10: # 最小消息长度检查
|
||||
return False
|
||||
|
||||
# 解析消息头
|
||||
self.start1 = data[0]
|
||||
self.start2 = data[1]
|
||||
self.id = struct.unpack_from('<H', data, 2)[0]
|
||||
self.length = struct.unpack_from('<H', data, 4)[0]
|
||||
|
||||
offset = 6 # 头部结束位置
|
||||
|
||||
# 检查数据长度是否足够
|
||||
if len(data) < offset + self.length + 1: # +1 for checksum
|
||||
return False
|
||||
|
||||
# 解析时间戳
|
||||
(self.year, self.month, self.day, self.hour,
|
||||
self.minute, self.second, self.milliseconds) = struct.unpack_from('<HBBBBBB', data, offset); offset += 8
|
||||
|
||||
# 解析复合管控器操作指令
|
||||
(self.fcmode, self.fcuCmd, self.fcuPowerEfficiency,
|
||||
self.insChargeEnable, self.insBatCmd, self.powerBatCmd,
|
||||
self.powerBatEfficiency, self.heartbeat, self.masterState,
|
||||
self.paceholder1, self.paceholder2) = struct.unpack_from('<BBBBBBHBBII', data, offset); offset += 20
|
||||
|
||||
# 校验校验码
|
||||
checkCode = 0
|
||||
for byte in data[:-1]: # 不包括校验码本身
|
||||
checkCode = (checkCode + byte) & 0xFF
|
||||
|
||||
return checkCode == data[-1]
|
||||
|
||||
def print_info(self):
|
||||
"""打印消息信息"""
|
||||
print(f"消息头: start1=0x{self.start1:02X}, start2=0x{self.start2:02X}, id=0x{self.id:04X}, length={self.length}")
|
||||
print(f"时间戳: {self.year}-{self.month:02d}-{self.day:02d} {self.hour:02d}:{self.minute:02d}:{self.second:02d}.{self.milliseconds:03d}")
|
||||
print(f"燃料电池模式: 0x{self.fcmode:02X}")
|
||||
print(f"燃料电池控制命令: 0x{self.fcuCmd:02X}")
|
||||
print(f"燃料电池功率效率: {self.fcuPowerEfficiency}%")
|
||||
print(f"仪表电池充电使能: 0x{self.insChargeEnable:02X}")
|
||||
print(f"仪表电池命令: 0x{self.insBatCmd:02X}")
|
||||
print(f"动力电池命令: 0x{self.powerBatCmd:02X}")
|
||||
print(f"动力电池功率效率: {self.powerBatEfficiency}%")
|
||||
print(f"心跳: {self.heartbeat}")
|
||||
print(f"主控状态: 0x{self.masterState:02X}")
|
||||
print(f"占位符1: {self.paceholder1}")
|
||||
print(f"占位符2: {self.paceholder2}")
|
||||
print(f"校验码: 0x{self.checkCode:02X}")
|
||||
|
||||
|
||||
# 测试函数
|
||||
def test_msg_ccUFbMsg():
|
||||
"""测试msg_ccUFbMsg类"""
|
||||
msg = msg_ccUFbMsg()
|
||||
|
||||
# 设置一些测试数据
|
||||
msg.fc_mode = 0x02 # 自动模式
|
||||
msg.fc_status = 0x06 # 运行状态
|
||||
msg.output_power_limit = 15000
|
||||
msg.total_generation_time = 100 # 10小时
|
||||
msg.hydrogen_capacity = 80
|
||||
msg.liquid_oxygen_capacity = 75
|
||||
msg.ins_soc = 85
|
||||
msg.dyn_soc = 90
|
||||
msg.heartbeat = 12345
|
||||
|
||||
# 打包消息
|
||||
data = msg.pack()
|
||||
print(f"打包后的数据长度: {len(data)} 字节")
|
||||
|
||||
# 解包消息
|
||||
msg2 = msg_ccUFbMsg()
|
||||
if msg2.unpack(data):
|
||||
print("解包成功!")
|
||||
msg2.print_info()
|
||||
else:
|
||||
print("解包失败!")
|
||||
|
||||
return msg2
|
||||
|
||||
|
||||
def test_msg_ccUCmdMsg():
|
||||
"""测试msg_ccUCmdMsg类"""
|
||||
msg = msg_ccUCmdMsg()
|
||||
|
||||
# 设置一些测试数据
|
||||
msg.year = 2025
|
||||
msg.month = 9
|
||||
msg.day = 11
|
||||
msg.hour = 17
|
||||
msg.minute = 5
|
||||
msg.second = 30
|
||||
msg.milliseconds = 123
|
||||
|
||||
msg.fcmode = 0x02 # 自动模式
|
||||
msg.fcuCmd = 0x02 # 启动命令
|
||||
msg.fcuPowerEfficiency = 85 # 85%效率
|
||||
msg.insChargeEnable = 0x01 # 使能充电
|
||||
msg.insBatCmd = 0x10 # 仪表电池启动
|
||||
msg.powerBatCmd = 0x10 # 动力电池启动
|
||||
msg.powerBatEfficiency = 90 # 90%效率
|
||||
msg.heartbeat = 123
|
||||
msg.masterState = 0x01 # 主控正常
|
||||
msg.paceholder1 = 0
|
||||
msg.paceholder2 = 0
|
||||
|
||||
# 打包消息
|
||||
data = msg.pack()
|
||||
print(f"CCU命令消息打包后的数据长度: {len(data)} 字节")
|
||||
|
||||
# 解包消息
|
||||
msg2 = msg_ccUCmdMsg()
|
||||
if msg2.unpack(data):
|
||||
print("CCU命令消息解包成功!")
|
||||
msg2.print_info()
|
||||
else:
|
||||
print("CCU命令消息解包失败!")
|
||||
|
||||
return msg2
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("=== 测试CCU状态反馈消息 ===")
|
||||
test_msg_ccUFbMsg()
|
||||
print("\n=== 测试CCU命令消息 ===")
|
||||
test_msg_ccUCmdMsg()
|
||||
@@ -0,0 +1,213 @@
|
||||
import tkinter as tk
|
||||
from tkinter import ttk, scrolledtext
|
||||
import sys
|
||||
import os
|
||||
|
||||
# 添加当前目录到Python路径,以便能够导入ccuMsg
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
import ccuMsg
|
||||
from datetime import datetime
|
||||
|
||||
class CCUStatusSummaryDialog:
|
||||
"""CCU状态汇总弹窗"""
|
||||
def __init__(self, parent, ccu_status=None, title="CCU状态汇总"):
|
||||
self.parent = parent
|
||||
self.ccu_status = ccu_status or ccuMsg.msg_ccUFbMsg()
|
||||
|
||||
# 创建弹窗
|
||||
self.dialog = tk.Toplevel(parent)
|
||||
self.dialog.title(title)
|
||||
self.dialog.geometry("1000x700")
|
||||
self.dialog.transient(parent) # 设置为父窗口的临时窗口
|
||||
self.dialog.grab_set() # 模态对话框
|
||||
|
||||
# 创建主框架
|
||||
main_frame = ttk.Frame(self.dialog, padding="10")
|
||||
main_frame.pack(fill=tk.BOTH, expand=True)
|
||||
|
||||
# 标题
|
||||
title_label = ttk.Label(main_frame, text="CCU状态详细信息", font=('Arial', 16, 'bold'))
|
||||
title_label.pack(pady=10)
|
||||
|
||||
# 时间标签
|
||||
self.time_label = ttk.Label(main_frame, text="", font=('Arial', 10))
|
||||
self.time_label.pack(pady=5)
|
||||
|
||||
# 创建滚动文本框
|
||||
self.summary_text = scrolledtext.ScrolledText(main_frame, width=90, height=30, wrap=tk.WORD, font=('Courier', 10))
|
||||
self.summary_text.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
|
||||
|
||||
# 按钮框架
|
||||
button_frame = ttk.Frame(main_frame)
|
||||
button_frame.pack(pady=10)
|
||||
|
||||
# 关闭按钮
|
||||
close_btn = ttk.Button(button_frame, text="关闭", command=self.dialog.destroy)
|
||||
close_btn.pack(side=tk.LEFT, padx=5)
|
||||
|
||||
# 刷新按钮
|
||||
refresh_btn = ttk.Button(button_frame, text="刷新", command=self.update_display)
|
||||
refresh_btn.pack(side=tk.LEFT, padx=5)
|
||||
|
||||
# 初始更新显示
|
||||
self.update_display()
|
||||
|
||||
def update_display(self):
|
||||
"""更新显示数据"""
|
||||
# 更新时间标签
|
||||
self.time_label.config(text=f"更新时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
||||
|
||||
# 生成汇总信息
|
||||
summary = self.generate_summary()
|
||||
|
||||
# 清空并插入新的汇总信息
|
||||
self.summary_text.delete(1.0, tk.END)
|
||||
self.summary_text.insert(1.0, summary)
|
||||
|
||||
def generate_summary(self):
|
||||
"""生成汇总信息"""
|
||||
return f"""CCU状态汇总 - {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
|
||||
|
||||
燃料电池状态:
|
||||
运行模式: 0x{self.ccu_status.fc_mode:02X}
|
||||
运行状态: 0x{self.ccu_status.fc_status:02X}
|
||||
故障等级: 0x{self.ccu_status.fc_fault_level:02X}
|
||||
输出功率限制: {self.ccu_status.output_power_limit}W
|
||||
累计发电时间: {self.ccu_status.total_generation_time * 0.1:.1f}小时
|
||||
发电总功率: {self.ccu_status.total_generation_power}W
|
||||
故障等级1-4: {self.ccu_status.fault_level_1}, {self.ccu_status.fault_level_2}, {self.ccu_status.fault_level_3}, {self.ccu_status.fault_level_4}
|
||||
储氢容量: {self.ccu_status.hydrogen_capacity}%
|
||||
液氧容量: {self.ccu_status.liquid_oxygen_capacity}%
|
||||
|
||||
传感器数据:
|
||||
钯膜温度: {self.ccu_status.palladium_temp}℃
|
||||
主水路压力: {self.ccu_status.main_pipe_pressure * 0.01:.2f}kPa
|
||||
辅水路压力: {self.ccu_status.aux_pipe_pressure * 0.01:.2f}kPa
|
||||
舱室压力1/2: {self.ccu_status.cabin_pressure1}/{self.ccu_status.cabin_pressure2}Pa
|
||||
舱室温度1/2: {self.ccu_status.cabin_temp1}/{self.ccu_status.cabin_temp2}℃
|
||||
舱室湿度1/2: {self.ccu_status.cabin_humidity1}/{self.ccu_status.cabin_humidity2}%
|
||||
火焰探测器1/2: 0x{self.ccu_status.flame_detector1:02X}/0x{self.ccu_status.flame_detector2:02X}
|
||||
|
||||
浓度检测:
|
||||
H2浓度1/2/3: {self.ccu_status.h2_concentration1}/{self.ccu_status.h2_concentration2}/{self.ccu_status.h2_concentration3}
|
||||
O2浓度1/2: {self.ccu_status.o2_concentration1}/{self.ccu_status.o2_concentration2}
|
||||
CH3OH浓度1/2: {self.ccu_status.ch3oh_concentration1}/{self.ccu_status.ch3oh_concentration2}
|
||||
|
||||
应急电池:
|
||||
电池1电压/电流: {self.ccu_status.emergency_battery1_voltage}V/{self.ccu_status.emergency_battery1_current}A
|
||||
电池1最高温度: {self.ccu_status.emergency_battery1_max_temp}℃
|
||||
电池1故障字: 0x{self.ccu_status.emergency_battery1_fault_word:04X}
|
||||
电池2电压/电流: {self.ccu_status.emergency_battery2_voltage}V/{self.ccu_status.emergency_battery2_current}A
|
||||
电池2最高温度: {self.ccu_status.emergency_battery2_max_temp}℃
|
||||
电池2故障字: 0x{self.ccu_status.emergency_battery2_fault_word:04X}
|
||||
|
||||
舱室环境:
|
||||
舱室氧浓度: {self.ccu_status.cabin_ox_concentration}
|
||||
舱室温度: {self.ccu_status.cabin_temperature}℃
|
||||
舱室湿度: {self.ccu_status.cabin_humidity}%
|
||||
舱室压力: {self.ccu_status.cabin_pressure}Pa
|
||||
动力舱氧浓度: {self.ccu_status.power_cabin_ox_concentration}
|
||||
动力舱温度: {self.ccu_status.power_cabin_temperature}℃
|
||||
动力舱湿度: {self.ccu_status.power_cabin_humidity}%
|
||||
动力舱压力: {self.ccu_status.power_cabin_pressure}Pa
|
||||
|
||||
报警状态:
|
||||
动态报警标志: {[flag for flag in self.ccu_status.dyn_alarm_flag]}
|
||||
绝缘报警标志: {[flag for flag in self.ccu_status.ins_alarm_flag]}
|
||||
动态报警总数: {sum(self.ccu_status.dyn_alarm_flag)}
|
||||
绝缘报警总数: {sum(self.ccu_status.ins_alarm_flag)}
|
||||
|
||||
继电器状态:
|
||||
仪表继电器1/2: 0x{self.ccu_status.ins_relay_status1:02X}/0x{self.ccu_status.ins_relay_status2:02X}
|
||||
动力继电器1/2: 0x{self.ccu_status.dyn_relay_status1:02X}/0x{self.ccu_status.dyn_relay_status2:02X}
|
||||
|
||||
功率信息:
|
||||
仪表最大放电功率: {self.ccu_status.ins_max_discharge_power}W
|
||||
动力最大放电功率: {self.ccu_status.dyn_max_discharge_power}W
|
||||
仪表SOC: {self.ccu_status.ins_soc}%
|
||||
动力SOC: {self.ccu_status.dyn_soc}%
|
||||
仪表总能量: {self.ccu_status.ins_total_energy}Wh
|
||||
动力总能量: {self.ccu_status.dyn_total_energy}Wh
|
||||
仪表功率输入: {self.ccu_status.ins_power_input}W
|
||||
动力功率输入: {self.ccu_status.dyn_power_input}W
|
||||
|
||||
充电状态:
|
||||
仪表充电状态: 0x{self.ccu_status.ins_charge_status:02X}
|
||||
动力充电状态: 0x{self.ccu_status.dyn_charge_status:02X}
|
||||
|
||||
电气参数:
|
||||
仪表链路电压: {self.ccu_status.ins_voltage_link * 0.1:.1f}V
|
||||
仪表电池电压: {self.ccu_status.ins_voltage_pack * 0.1:.1f}V
|
||||
仪表电流: {self.ccu_status.ins_current * 0.1:.1f}A
|
||||
仪表正极绝缘电阻: {self.ccu_status.ins_resistance_pos}Ω
|
||||
仪表负极绝缘电阻: {self.ccu_status.ins_resistance_neg}Ω
|
||||
动力链路电压: {self.ccu_status.dyn_voltage_link * 0.1:.1f}V
|
||||
动力电池电压: {self.ccu_status.dyn_voltage_pack * 0.1:.1f}V
|
||||
动力电流: {self.ccu_status.dyn_current * 0.1:.1f}A
|
||||
动力正极绝缘电阻: {self.ccu_status.dyn_resistance_pos}Ω
|
||||
动力负极绝缘电阻: {self.ccu_status.dyn_resistance_neg}Ω
|
||||
|
||||
紧急状态:
|
||||
仪表紧急状态: 0x{self.ccu_status.ins_emergency_status:02X}
|
||||
动力紧急状态: 0x{self.ccu_status.dyn_emergency_status:02X}
|
||||
|
||||
SOC门限值:
|
||||
仪表SOC门限1/2/3: {self.ccu_status.ins_soc_threshold1}/{self.ccu_status.ins_soc_threshold2}/{self.ccu_status.ins_soc_threshold3}%
|
||||
动力SOC门限1/2/3: {self.ccu_status.dyn_soc_threshold1}/{self.ccu_status.dyn_soc_threshold2}/{self.ccu_status.dyn_soc_threshold3}%
|
||||
|
||||
功率限制值:
|
||||
仪表功率限制1/2: {self.ccu_status.ins_power_limit1}/{self.ccu_status.ins_power_limit2}W
|
||||
动力功率限制1/2: {self.ccu_status.dyn_power_limit1}/{self.ccu_status.dyn_power_limit2}W
|
||||
|
||||
设备在线状态:
|
||||
设备在线标志1: 0x{self.ccu_status.device_online_flag1:08X}
|
||||
设备在线标志2: 0x{self.ccu_status.device_online_flag2:08X}
|
||||
|
||||
其他状态:
|
||||
动力充电等级: 0x{self.ccu_status.dyn_charge_level:02X}
|
||||
动力漏水状态: 0x{self.ccu_status.dyn_water_leak_status:02X}
|
||||
仪表漏水DCDC状态: 0x{self.ccu_status.ins_water_leak_dcdc_status:02X}
|
||||
心跳计数器: {self.ccu_status.heartbeat}
|
||||
"""
|
||||
|
||||
def set_ccu_status(self, ccu_status):
|
||||
"""设置CCU状态数据"""
|
||||
self.ccu_status = ccu_status
|
||||
self.update_display()
|
||||
|
||||
|
||||
# 测试函数
|
||||
def test_ccu_summary_dialog():
|
||||
"""测试CCU状态汇总弹窗"""
|
||||
root = tk.Tk()
|
||||
root.withdraw() # 隐藏主窗口
|
||||
|
||||
# 设置一些测试数据
|
||||
test_status = ccuMsg.msg_ccUFbMsg()
|
||||
test_status.fc_mode = 0x02 # 自动模式
|
||||
test_status.fc_status = 0x06 # 运行状态
|
||||
test_status.output_power_limit = 15000
|
||||
test_status.total_generation_time = 100 # 10小时
|
||||
test_status.hydrogen_capacity = 80
|
||||
test_status.liquid_oxygen_capacity = 75
|
||||
test_status.ins_soc = 85
|
||||
test_status.dyn_soc = 90
|
||||
test_status.heartbeat = 12345
|
||||
test_status.palladium_temp = 65
|
||||
test_status.main_pipe_pressure = 1500 # 15.00 kPa
|
||||
test_status.aux_pipe_pressure = 800 # 8.00 kPa
|
||||
|
||||
# 设置一些报警标志
|
||||
test_status.dyn_alarm_flag[0] = 1
|
||||
test_status.ins_alarm_flag[2] = 1
|
||||
|
||||
# 创建弹窗
|
||||
dialog = CCUStatusSummaryDialog(root, test_status)
|
||||
|
||||
# 等待弹窗关闭
|
||||
root.wait_window(dialog.dialog)
|
||||
root.destroy()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_ccu_summary_dialog()
|
||||
Executable
+15
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 编译测试程序
|
||||
g++ -std=c++11 -I../../src/pPowerManger -I../../src/pPowerManger/sqlit3 \
|
||||
testSqlitdb.cpp ../../src/pPowerManger/sqlit3/SQLite.cpp ../../src/pPowerManger/sqlit3/sqlite3.c \
|
||||
-o testSqlitdb -lsqlite3 -lpthread
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "编译成功!"
|
||||
echo "运行测试:"
|
||||
./testSqlitdb
|
||||
else
|
||||
echo "编译失败!"
|
||||
exit 1
|
||||
fi
|
||||
@@ -0,0 +1,316 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include "../../src/pPowerManger/sqlit3/SQLite.h"
|
||||
|
||||
// 简单的测试框架
|
||||
#define TEST_CASE(name) void test_##name()
|
||||
#define RUN_TEST(name) \
|
||||
std::cout << "Running test: " << #name << std::endl; \
|
||||
test_##name(); \
|
||||
std::cout << "Test " << #name << " passed!" << std::endl
|
||||
|
||||
// 测试数据生成函数
|
||||
ccuState createTestCcuState() {
|
||||
ccuState state = {};
|
||||
|
||||
// 填充一些测试数据
|
||||
state.fc_mode = 2; // 自动模式
|
||||
state.fc_status = 6; // 运行状态
|
||||
state.fc_fault_level = 0; // 无故障
|
||||
|
||||
state.output_power_limit = 15000;
|
||||
state.total_generation_time = 100;
|
||||
state.total_generation_power = 50000;
|
||||
|
||||
state.hydrogen_capacity = 80;
|
||||
state.liquid_oxygen_capacity = 75;
|
||||
|
||||
state.palladium_temp = 450;
|
||||
state.main_pipe_pressure = 1000;
|
||||
state.aux_pipe_pressure = 800;
|
||||
|
||||
state.cabin_pressure1 = 1013;
|
||||
state.cabin_pressure2 = 1012;
|
||||
state.cabin_temp1 = 2500;
|
||||
state.cabin_temp2 = 2490;
|
||||
state.cabin_humidity1 = 6000;
|
||||
state.cabin_humidity2 = 6100;
|
||||
|
||||
state.flame_detector1 = 0;
|
||||
state.flame_detector2 = 0;
|
||||
|
||||
state.h2_concentration1 = 50;
|
||||
state.h2_concentration2 = 48;
|
||||
state.h2_concentration3 = 52;
|
||||
state.o2_concentration1 = 2100;
|
||||
state.o2_concentration2 = 2090;
|
||||
|
||||
state.emergency_battery1_voltage = 480;
|
||||
state.emergency_battery1_current = 25;
|
||||
state.emergency_battery1_max_temp = 35;
|
||||
|
||||
state.ins_soc = 85;
|
||||
state.dyn_soc = 90;
|
||||
|
||||
state.heartbeat = 12345;
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
ccuColCmd createTestCcuColCmd() {
|
||||
ccuColCmd cmd = {};
|
||||
cmd.fcmode = 2;
|
||||
cmd.fcuCmd = 2;
|
||||
cmd.fcuPowerEfficiency = 80;
|
||||
cmd.insChargeEnable = 1;
|
||||
cmd.insBatCmd = 1;
|
||||
cmd.powerBatCmd = 1;
|
||||
cmd.powerBatEfficiency = 85;
|
||||
cmd.heartbeat = 123; // 修复unsigned char溢出警告
|
||||
cmd.masterState = 1;
|
||||
return cmd;
|
||||
}
|
||||
|
||||
disHighVolBusState createTestDisHighVolBusState() {
|
||||
disHighVolBusState state = {};
|
||||
state.fuelCellCircuitBreaker = 0x55;
|
||||
state.powerLithiumBatteryCircuitBreaker = 0x55;
|
||||
state.propulsionMotorCircuitBreaker = 0x55;
|
||||
state.powerBusVoltage = 4800;
|
||||
state.dcDc5ModuleCurrent = 100;
|
||||
state.powerBusCurrent = 500;
|
||||
state.busbarAVoltage = 4750;
|
||||
return state;
|
||||
}
|
||||
|
||||
disHighAVolBusState createTestDisHighAVolBusState() {
|
||||
disHighAVolBusState state = {};
|
||||
state.bowFTDevice123CircuitBreaker = 0x55;
|
||||
state.actuatorCircuitBreaker = 0x55;
|
||||
state.busbarBVoltage = 4800;
|
||||
state.busbarBCurrent = 200;
|
||||
return state;
|
||||
}
|
||||
|
||||
disLowMainBusState createTestDisLowMainBusState() {
|
||||
disLowMainBusState state = {};
|
||||
state.lithiumBatteryGroupInstrumentCircuitBreaker = 0x55;
|
||||
state.bowLowVoltageDistributionBoxCircuitBreaker = 0x55;
|
||||
state.instrumentBusbarVoltage = 480;
|
||||
state.bowLowVoltageDistributionBoxCurrent = 50;
|
||||
return state;
|
||||
}
|
||||
|
||||
disLowBusState createTestDisLowBusState() {
|
||||
disLowBusState state = {};
|
||||
state.unit1CircuitBreaker = 0x55;
|
||||
state.unit2CircuitBreaker = 0x55;
|
||||
state.instrumentBusbarVoltage = 480;
|
||||
state.instrumentBusbarCurrent = 100;
|
||||
return state;
|
||||
}
|
||||
|
||||
disHighVolBusCmd createTestDisHighVolBusCmd() {
|
||||
disHighVolBusCmd cmd = {};
|
||||
cmd.fuelCellCircuitBreaker = 0x55;
|
||||
cmd.powerLithiumBatteryCircuitBreaker = 0x55;
|
||||
cmd.propulsionMotorCircuitBreaker = 0x55;
|
||||
cmd.dcdc5Module = 1;
|
||||
cmd.coolingSystem = 1;
|
||||
return cmd;
|
||||
}
|
||||
|
||||
disHighAVolBusCmd createTestDisHighAVolBusCmd() {
|
||||
disHighAVolBusCmd cmd = {};
|
||||
cmd.bowFTDevice123CircuitBreaker = 0x55;
|
||||
cmd.actuatorCircuitBreaker = 0x55;
|
||||
return cmd;
|
||||
}
|
||||
|
||||
disLowMainBusCmd createTestDisLowMainBusCmd() {
|
||||
disLowMainBusCmd cmd = {};
|
||||
cmd.lithiumBatteryGroupInstrumentCircuitBreaker = 0x55;
|
||||
cmd.bowLowVoltageDistributionBoxCircuitBreaker = 0x55;
|
||||
return cmd;
|
||||
}
|
||||
|
||||
disLowBusCmd createTestDisLowBusCmd() {
|
||||
disLowBusCmd cmd = {};
|
||||
cmd.unit1CircuitBreaker = 0x55;
|
||||
cmd.unit2CircuitBreaker = 0x55;
|
||||
return cmd;
|
||||
}
|
||||
|
||||
// 测试用例
|
||||
TEST_CASE(constructor_and_destructor) {
|
||||
// 测试正常构造
|
||||
SQLite db(":memory:");
|
||||
assert(db.m_dbPath == ":memory:");
|
||||
|
||||
// 测试无效路径
|
||||
SQLite invalidDb("/invalid/path/test.db");
|
||||
// 这里应该检查数据库是否成功打开,但由于是内存数据库,我们主要测试构造函数不崩溃
|
||||
}
|
||||
|
||||
TEST_CASE(create_table) {
|
||||
SQLite db(":memory:");
|
||||
|
||||
// 测试创建默认表
|
||||
bool result = db.createTable();
|
||||
assert(result == true);
|
||||
|
||||
// 测试创建自定义表
|
||||
result = db.createTable("test_table", "id INTEGER PRIMARY KEY, name TEXT");
|
||||
assert(result == true);
|
||||
}
|
||||
|
||||
TEST_CASE(insert_ccu_state) {
|
||||
SQLite db(":memory:");
|
||||
db.createTable();
|
||||
|
||||
ccuState state = createTestCcuState();
|
||||
bool result = db.insertData(state);
|
||||
assert(result == true);
|
||||
}
|
||||
|
||||
TEST_CASE(insert_ccu_col_cmd) {
|
||||
SQLite db(":memory:");
|
||||
db.createTable();
|
||||
|
||||
ccuColCmd cmd = createTestCcuColCmd();
|
||||
bool result = db.insertData(cmd);
|
||||
assert(result == true);
|
||||
}
|
||||
|
||||
TEST_CASE(insert_dis_high_vol_bus_state) {
|
||||
SQLite db(":memory:");
|
||||
db.createTable();
|
||||
|
||||
disHighVolBusState state = createTestDisHighVolBusState();
|
||||
bool result = db.insertData(state);
|
||||
assert(result == true);
|
||||
}
|
||||
|
||||
TEST_CASE(insert_dis_high_a_vol_bus_state) {
|
||||
SQLite db(":memory:");
|
||||
db.createTable();
|
||||
|
||||
disHighAVolBusState state = createTestDisHighAVolBusState();
|
||||
bool result = db.insertData(state);
|
||||
assert(result == true);
|
||||
}
|
||||
|
||||
TEST_CASE(insert_dis_low_main_bus_state) {
|
||||
SQLite db(":memory:");
|
||||
db.createTable();
|
||||
|
||||
disLowMainBusState state = createTestDisLowMainBusState();
|
||||
bool result = db.insertData(state);
|
||||
assert(result == true);
|
||||
}
|
||||
|
||||
TEST_CASE(insert_dis_low_bus_state) {
|
||||
SQLite db(":memory:");
|
||||
db.createTable();
|
||||
|
||||
disLowBusState state = createTestDisLowBusState();
|
||||
bool result = db.insertData(state);
|
||||
assert(result == true);
|
||||
}
|
||||
|
||||
TEST_CASE(insert_dis_high_vol_bus_cmd) {
|
||||
SQLite db(":memory:");
|
||||
db.createTable();
|
||||
|
||||
disHighVolBusCmd cmd = createTestDisHighVolBusCmd();
|
||||
bool result = db.insertData(cmd);
|
||||
assert(result == true);
|
||||
}
|
||||
|
||||
TEST_CASE(insert_dis_high_a_vol_bus_cmd) {
|
||||
SQLite db(":memory:");
|
||||
db.createTable();
|
||||
|
||||
disHighAVolBusCmd cmd = createTestDisHighAVolBusCmd();
|
||||
bool result = db.insertData(cmd);
|
||||
assert(result == true);
|
||||
}
|
||||
|
||||
TEST_CASE(insert_dis_low_main_bus_cmd) {
|
||||
SQLite db(":memory:");
|
||||
db.createTable();
|
||||
|
||||
disLowMainBusCmd cmd = createTestDisLowMainBusCmd();
|
||||
bool result = db.insertData(cmd);
|
||||
assert(result == true);
|
||||
}
|
||||
|
||||
TEST_CASE(insert_dis_low_bus_cmd) {
|
||||
SQLite db(":memory:");
|
||||
db.createTable();
|
||||
|
||||
disLowBusCmd cmd = createTestDisLowBusCmd();
|
||||
bool result = db.insertData(cmd);
|
||||
assert(result == true);
|
||||
}
|
||||
|
||||
TEST_CASE(multiple_inserts) {
|
||||
SQLite db(":memory:");
|
||||
db.createTable();
|
||||
|
||||
// 插入多种类型的数据
|
||||
ccuState state = createTestCcuState();
|
||||
assert(db.insertData(state) == true);
|
||||
|
||||
ccuColCmd cmd = createTestCcuColCmd();
|
||||
assert(db.insertData(cmd) == true);
|
||||
|
||||
disHighVolBusState busState = createTestDisHighVolBusState();
|
||||
assert(db.insertData(busState) == true);
|
||||
}
|
||||
|
||||
TEST_CASE(invalid_database) {
|
||||
// 测试无效数据库路径
|
||||
SQLite db("/invalid/path/test.db");
|
||||
|
||||
// 尝试创建表应该失败
|
||||
bool result = db.createTable();
|
||||
assert(result == false);
|
||||
|
||||
// 尝试插入数据应该失败
|
||||
ccuState state = createTestCcuState();
|
||||
result = db.insertData(state);
|
||||
assert(result == false);
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::cout << "Starting SQLite database tests..." << std::endl;
|
||||
|
||||
try {
|
||||
RUN_TEST(constructor_and_destructor);
|
||||
RUN_TEST(create_table);
|
||||
RUN_TEST(insert_ccu_state);
|
||||
RUN_TEST(insert_ccu_col_cmd);
|
||||
RUN_TEST(insert_dis_high_vol_bus_state);
|
||||
RUN_TEST(insert_dis_high_a_vol_bus_state);
|
||||
RUN_TEST(insert_dis_low_main_bus_state);
|
||||
RUN_TEST(insert_dis_low_bus_state);
|
||||
RUN_TEST(insert_dis_high_vol_bus_cmd);
|
||||
RUN_TEST(insert_dis_high_a_vol_bus_cmd);
|
||||
RUN_TEST(insert_dis_low_main_bus_cmd);
|
||||
RUN_TEST(insert_dis_low_bus_cmd);
|
||||
RUN_TEST(multiple_inserts);
|
||||
RUN_TEST(invalid_database);
|
||||
|
||||
std::cout << "\nAll tests passed successfully!" << std::endl;
|
||||
return 0;
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "Test failed with exception: " << e.what() << std::endl;
|
||||
return 1;
|
||||
} catch (...) {
|
||||
std::cerr << "Test failed with unknown exception" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user