From 6f5de4b6148eac796818d99161e6abb42229760d Mon Sep 17 00:00:00 2001 From: zhaojingkui <1553836110@qq.com> Date: Thu, 6 Feb 2025 12:01:18 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86=E6=96=B0=E7=9A=84?= =?UTF-8?q?=E8=B0=83=E8=AF=95=E7=95=8C=E9=9D=A2,=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E4=BA=86=E4=B8=80=E4=BA=9B=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 6 +- data/msg/uPower_disSysState_st.json | 8 +- data/msg/uPower_fcsState_st.json | 52 ++--- data/msg/uPower_liBatState_st.json | 54 ++--- src/pPowerManger/PowerManger.cpp | 63 +++++- src/pPowerManger/PowerManger.h | 6 + src/pPowerManger/pmSysvariable.h | 3 + src/pPowerManger/udpComm.cpp | 11 +- src/pPowerManger/udpComm.h | 6 +- test/scripts/TestGUI.py | 14 +- test/scripts/ccuSys.py | 325 +++++++++++++++++++++++++++- test/scripts/disSys.py | 109 ++++++++++ test/scripts/udpComm.py | 76 ++----- test/scripts/udpmsg.py | 142 +++++++++++- 14 files changed, 718 insertions(+), 157 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 369f06d..8cb75a6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -56,5 +56,9 @@ "queue": "cpp" }, "C_Cpp.errorSquiggles": "disabled", - "marscode.chatLanguage": "cn" + "marscode.chatLanguage": "cn", + "marscode.codeCompletionPro": { + "enableCodeCompletionPro": true + }, + "marscode.enableInlineCommand": true } \ No newline at end of file diff --git a/data/msg/uPower_disSysState_st.json b/data/msg/uPower_disSysState_st.json index af47382..ffc37b2 100644 --- a/data/msg/uPower_disSysState_st.json +++ b/data/msg/uPower_disSysState_st.json @@ -1,8 +1,8 @@ { - "HVolABusBreaker_unit16": 63, - "HVolBBusBreaker_unit16": 113, - "HVolBusBreaker_uint16": 4090, - "LVolBusBreaker_uint16": 113, + "HVolABusBreaker_unit16": 0, + "HVolBBusBreaker_unit16": 127, + "HVolBusBreaker_uint16": 0, + "LVolBusBreaker_uint16": 127, "faultCode_array": [ 0 diff --git a/data/msg/uPower_fcsState_st.json b/data/msg/uPower_fcsState_st.json index cb8b10a..df58b39 100644 --- a/data/msg/uPower_fcsState_st.json +++ b/data/msg/uPower_fcsState_st.json @@ -1,30 +1,30 @@ { - "backpressure1_fp32": -1.6155215737897056e+25, - "backpressure2_fp32": 1.9618178500547439e-44, - "ch4oConcent1_fp32": 1687.0, - "ch4oConcent2_fp32": 1.1726195870227251e-38, - "ch4o_fp32": 1.1753983618774813e-38, - "excTemp_fp32": 1.1726195870227251e-38, - "faultCode1_uint16": 38848, - "faultCode2_uint16": 21499, + "backpressure1_fp32": 0.0, + "backpressure2_fp32": 9.0, + "ch4oConcent1_fp32": 72.0, + "ch4oConcent2_fp32": 3.0, + "ch4o_fp32": 0.0, + "excTemp_fp32": 46.0, + "faultCode1_uint16": 0, + "faultCode2_uint16": 0, "faultCode3_uint16": 0, - "fcuCurIns_fp32": 2.1062722967662487e+22, - "fcuCurPower_fp32": 7.9041248815135621e-39, - "fcuCur_fp32": 1.7755460477889746e-38, - "fcuFaultLeve_uint8": 226, - "fcuOutIns_fp32": 0.0, - "fcuOutPower_fp32": 2.152394441202919e-42, - "fcuState_uint8": 124, + "fcuCurIns_fp32": 0.0, + "fcuCurPower_fp32": 0.0, + "fcuCur_fp32": 61.0, + "fcuFaultLeve_uint8": 0, + "fcuOutIns_fp32": 94.0, + "fcuOutPower_fp32": 536.0, + "fcuState_uint8": 0, "fcuVolIns_fp32": 0.0, - "fcuVolPower_fp32": 1.1725886183266636e-38, - "fcuVol_fp32": 1.1753983618774813e-38, - "flameDet_uint8": 0, - "h2Concent1_fp32": 1715.25, - "h2Concent2_fp32": 1.1726195870227251e-38, - "o2Concent1_fp32": 19.4140625, - "o2Concent2_fp32": 1.1726195870227251e-38, - "o2Level_fp32": 1.1725886183266636e-38, - "o2_fp32": -1.5729414295823943e+36, - "powLimit_fp32": 1.1726194468928787e-38, - "powerGen_fp32": -1.5732659481360528e+36 + "fcuVolPower_fp32": 0.0, + "fcuVol_fp32": 319.0, + "flameDet_uint8": 1, + "h2Concent1_fp32": 30.0, + "h2Concent2_fp32": 10.0, + "o2Concent1_fp32": 53.0, + "o2Concent2_fp32": 0.0, + "o2Level_fp32": 0.0, + "o2_fp32": 0.0, + "powLimit_fp32": 60.0, + "powerGen_fp32": 155.0 } \ No newline at end of file diff --git a/data/msg/uPower_liBatState_st.json b/data/msg/uPower_liBatState_st.json index 031c1ab..b48ef8b 100644 --- a/data/msg/uPower_liBatState_st.json +++ b/data/msg/uPower_liBatState_st.json @@ -1,38 +1,38 @@ { - "fcuCurToInsLimit1_uint8": 127, + "fcuCurToInsLimit1_uint8": 0, "fcuCurToinsLimit2_uint8": 0, "insBatCurElect_uint16": 0, - "insBatLimit_uint16": 0, - "insBatSoc_uint8": 0, - "insBatTotalElect_uint16": 2, - "insChargeState_uint8": 71, - "insCurSocHold1_uint8": 65, - "insCurSocHold2_uint8": 221, - "insCurSocHold3_uint8": 175, - "insCurrent_uint16": 0, - "insLinkVol_uint16": 56547, - "insNegRelayState_uint8": 0, - "insNegRes_uint16": 56641, - "insPackVol_uint16": 32687, + "insBatLimit_uint16": 95, + "insBatSoc_uint8": 11, + "insBatTotalElect_uint16": 631, + "insChargeState_uint8": 0, + "insCurSocHold1_uint8": 0, + "insCurSocHold2_uint8": 0, + "insCurSocHold3_uint8": 0, + "insCurrent_uint16": 89, + "insLinkVol_uint16": 0, + "insNegRelayState_uint8": 1, + "insNegRes_uint16": 0, + "insPackVol_uint16": 0, "insPosRelayState_uint8": 0, - "insPosRes_uint16": 38968, - "insfaultCode_uint8": 176, + "insPosRes_uint16": 0, + "insfaultCode_uint8": 0, "powBatCurElect_uint16": 0, - "powBatSoc_uint8": 0, - "powBatTotalElect_uint16": 0, - "powChargeState_uint8": 241, + "powBatSoc_uint8": 86, + "powBatTotalElect_uint16": 826, + "powChargeState_uint8": 0, "powCurSocHold1_uint8": 0, - "powCurSocHold2_uint8": 228, - "powCurSocHold3_uint8": 85, - "powCurToInsLimit1_uint8": 48, + "powCurSocHold2_uint8": 0, + "powCurSocHold3_uint8": 0, + "powCurToInsLimit1_uint8": 0, "powCurToinsLimit2_uint8": 0, - "powCur_uint16": 15376, - "powLinkVol_uint16": 32687, + "powCur_uint16": 41, + "powLinkVol_uint16": 0, "powNegRelayState_uint8": 0, - "powNegRes_uint16": 32687, + "powNegRes_uint16": 0, "powPosRelayState_uint8": 0, - "powPosRes_uint16": 56623, - "powerBatLimit_uint16": 0, + "powPosRes_uint16": 0, + "powerBatLimit_uint16": 71, "powerPackVol_uint16": 0, - "powfaultCode_uint8": 148 + "powfaultCode_uint8": 0 } \ No newline at end of file diff --git a/src/pPowerManger/PowerManger.cpp b/src/pPowerManger/PowerManger.cpp index ff70386..5ddc4c8 100644 --- a/src/pPowerManger/PowerManger.cpp +++ b/src/pPowerManger/PowerManger.cpp @@ -32,6 +32,7 @@ PowerManger::PowerManger() soc = 0; sustainableTime = 0; m_connected = false; + m_faultNum = 0; faultCode.push_back(0); //注册状态机 @@ -783,15 +784,8 @@ bool PowerManger::saveStringToJsonFile(const string &strJson, const string &file //TODO:配电系统操作函数 bool PowerManger::disSystemOperation(disBreaker optBreaker, disBreakerOpt) { - // switch (disBreaker) - // { - // case bus1_fuelCellCircuitBreaker : - // // send() - // break; - - // default: - // break; - // } + + return true; } int PowerManger::handleInite_s1(FSM_State &fsm, void* pData) @@ -814,9 +808,10 @@ int PowerManger::handleInite_s1(FSM_State &fsm, void* pData) if(dft > 10) { pm->m_pmState = pm->m_Fault_s99; + pm->m_faultNum = 1; // 通信超时 break; } - string desp = "等待复合管控消息 : 超时 : " + to_string(10-dft); + string desp = "等待复合管控消息 : " + to_string(10-dft); pm->printState(fsm,desp); usleep(1000000); } @@ -837,12 +832,49 @@ int PowerManger::handleInite_s1(FSM_State &fsm, void* pData) pm->m_pmState = pm->m_Fault_s99; } //3. 检查当前配电装置状态 - // 首先闭合应急电源开关 + //a. 断开高压母线的主要断路器 //TODO 检查并配置当前配电装置状态 disHighVolBusCmd a; a.fuelCellCircuitBreaker = DIS_BREAKER_OFF; a.propulsionMotorCircuitBreaker = DIS_BREAKER_OFF; + a.bowHighVoltageDistributionBoxCircuitBreaker = DIS_BREAKER_OFF; + a.tyzReservedCircuitBreaker = DIS_BREAKER_OFF; + a.sternFTDevice45CircuitBreaker = DIS_BREAKER_OFF; + a.sternRudderSwitch1CircuitBreaker = DIS_BREAKER_OFF; + a.sternRudderSwitch2CircuitBreaker = DIS_BREAKER_OFF; + a.reservedCircuitBreaker = DIS_BREAKER_OFF; + a.fbReservedCircuitBreaker = DIS_BREAKER_OFF; pm->m_udpComm.sendDisSysCmd(a); + //b. 断开艏部高压设备的主要断路器 + disHighAVolBusCmd b; + b.bowFTDevice123CircuitBreaker = DIS_BREAKER_OFF; + b.actuatorCircuitBreaker = DIS_BREAKER_OFF; + b.mastSteeringGearControlBoxCircuitBreaker = DIS_BREAKER_OFF; + b.xczCircuitBreaker = DIS_BREAKER_OFF; + b.bowRudderControlBoxCircuitBreaker = DIS_BREAKER_OFF; + b.openWaterCoverStartCylinderCircuitBreaker = DIS_BREAKER_OFF; + pm->m_udpComm.sendDisSysCmd(b); + //c. 闭合低压母线的断路器 + disHighBVolBusCmd c; + c.lithiumBatteryGroupInstrumentCircuitBreaker = DIS_BREAKER_ON; + c.bowLowVoltageDistributionBoxCircuitBreaker = DIS_BREAKER_ON; + c.unit4InstrumentDC48VCircuitBreaker = DIS_BREAKER_ON; + c.dcC1DCDistributionPanelCircuitBreaker = DIS_BREAKER_ON; + c.reservedCircuitBreaker1 = DIS_BREAKER_ON; + c.reservedCircuitBreaker2 = DIS_BREAKER_ON; + c.emergencyLithiumBatteryGroup2CircuitBreaker = DIS_BREAKER_ON; + pm->m_udpComm.sendDisSysCmd(c); + //d. 闭合低压汇流排断路器 + disLowBusCmd d; + d.unit1CircuitBreaker = DIS_BREAKER_ON; + d.unit2CircuitBreaker = DIS_BREAKER_ON; + d.unit3CircuitBreaker = DIS_BREAKER_ON; + d.unit5CircuitBreaker = DIS_BREAKER_ON; + d.bowPZDeviceCircuitBreaker = DIS_BREAKER_ON; + d.reservedCircuitBreaker1 = DIS_BREAKER_ON; + d.reservedCircuitBreaker2 = DIS_BREAKER_ON; + d.emergencyLithiumBatteryGroup1CircuitBreaker = DIS_BREAKER_ON; + pm->m_udpComm.sendDisSysCmd(d); MOOSPause(1000); // pm->workCondition = ""; return 0; @@ -852,6 +884,15 @@ int PowerManger::handleFault_s99(FSM_State &fsm, void* pData) { // cout << fsm.name << endl; PowerManger* pm = (PowerManger*)pData; + switch (pm->m_faultNum) + { + case 1: + pm->printState(fsm,"通信故障"); + break; + + default: + break; + } pm->printState(fsm,"故障"); return 0; } diff --git a/src/pPowerManger/PowerManger.h b/src/pPowerManger/PowerManger.h index 16af5cb..e097bd7 100644 --- a/src/pPowerManger/PowerManger.h +++ b/src/pPowerManger/PowerManger.h @@ -102,6 +102,7 @@ class PowerManger : public AppCastingMOOSApp unsigned int m_nReceiveBufferSizeKB; unsigned int m_nSendBufferSizeKB; double m_current_time; + unsigned int m_faultNum; // CMOOSThread m_SendThread; private: // @@ -113,6 +114,11 @@ class PowerManger : public AppCastingMOOSApp void printState(FSM_State st, string desp){ cout << MOOS::ConsoleColours::Yellow() << "STATE " << st.id << " [" << st.name << "] " << MOOS::ConsoleColours::reset(); cout << MOOS::ConsoleColours::Blue() << " -> " << MOOS::ConsoleColours::reset(); + // 检查desp是否有“故障” + if (desp.find("故障") != string::npos) { + cout << MOOS::ConsoleColours::Red() << desp << MOOS::ConsoleColours::reset() << endl; + return; + } cout << MOOS::ConsoleColours::Green() << desp << MOOS::ConsoleColours::reset() << endl; } diff --git a/src/pPowerManger/pmSysvariable.h b/src/pPowerManger/pmSysvariable.h index 19604d2..e9d8fe0 100644 --- a/src/pPowerManger/pmSysvariable.h +++ b/src/pPowerManger/pmSysvariable.h @@ -211,6 +211,9 @@ typedef struct disHighVolBusCmd unsigned char fbReservedCircuitBreaker; unsigned char tyzReservedCircuitBreaker; unsigned char reservedCircuitBreaker; + unsigned char dcdc5Module; + unsigned char inputWater; + unsigned char outputWater; }disHighVolBusCmd; typedef struct disHighAVolBusCmd diff --git a/src/pPowerManger/udpComm.cpp b/src/pPowerManger/udpComm.cpp index e78e4c4..6f34eed 100644 --- a/src/pPowerManger/udpComm.cpp +++ b/src/pPowerManger/udpComm.cpp @@ -395,12 +395,12 @@ bool udpComm::sendDisSysCmd(const disHighVolBusCmd cmd) return true; } -bool udpComm::snedDisSysCmd(const disHighAVolBusCmd cmd) +bool udpComm::sendDisSysCmd(const disHighAVolBusCmd cmd) { unsigned char* msgBuf; Checksum cc; msg_disHVBACmd* msg = new msg_disHVBACmd; - msg->header.id = DIS_HVBUS_CMD_ID; + msg->header.id = DIS_HVBUSA_CMD_ID; msg->header.start1 = DIS_MSG_HEAD1; msg->header.start2 = DIS_MSG_HEAD2; msg->header.length = sizeof(disHighAVolBusCmd); @@ -420,12 +420,12 @@ bool udpComm::snedDisSysCmd(const disHighAVolBusCmd cmd) return true; } -bool udpComm::snedDisSysCmd(const disHighBVolBusCmd cmd) +bool udpComm::sendDisSysCmd(const disHighBVolBusCmd cmd) { unsigned char* msgBuf; Checksum cc; msg_disHVBBCmd* msg = new msg_disHVBBCmd; - msg->header.id = DIS_HVBUS_CMD_ID; + msg->header.id = DIS_HVBUSB_CMD_ID; msg->header.start1 = DIS_MSG_HEAD1; msg->header.start2 = DIS_MSG_HEAD2; msg->header.length = sizeof(disHighBVolBusCmd); @@ -435,6 +435,7 @@ bool udpComm::snedDisSysCmd(const disHighBVolBusCmd cmd) msg->checkCode = static_cast(cc & 0xFF); try { + // cout << "=========" <<(int)sizeof(msg_disHVBBCmd) << endl; sendMsg(msgBuf,sizeof(msg_disHVBBCmd)); } catch(const std::exception& e) @@ -450,7 +451,7 @@ bool udpComm::sendDisSysCmd(const disLowBusCmd cmd) unsigned char* msgBuf; Checksum cc; msg_disLVBCmd* msg = new msg_disLVBCmd; - msg->header.id = DIS_HVBUS_CMD_ID; + msg->header.id = DIS_LVBUS_CMD_ID; msg->header.start1 = DIS_MSG_HEAD1; msg->header.start2 = DIS_MSG_HEAD2; msg->header.length = sizeof(disLowBusCmd); diff --git a/src/pPowerManger/udpComm.h b/src/pPowerManger/udpComm.h index 3a5bfeb..11ca352 100644 --- a/src/pPowerManger/udpComm.h +++ b/src/pPowerManger/udpComm.h @@ -46,12 +46,14 @@ public: bool sendCcuColCmd(const msg_CcuColCmdMsg m); bool sendCcuSetParmCmd(const msg_CcuSetParmMsg m); + bool sendDisSysCmd(const disHighVolBusCmd cmd); - bool snedDisSysCmd(const disHighAVolBusCmd cmd); - bool snedDisSysCmd(const disHighBVolBusCmd cmd); + bool sendDisSysCmd(const disHighAVolBusCmd cmd); + bool sendDisSysCmd(const disHighBVolBusCmd cmd); bool sendDisSysCmd(const disLowBusCmd cmd); bool sendMsg(const unsigned char* msg,unsigned int size){ udpScoket->iSendMessageTo((void*) msg, size, ccuPort, ccuHost); + return true; } bool getMsgId(char *m,unsigned short &id); diff --git a/test/scripts/TestGUI.py b/test/scripts/TestGUI.py index b224d1b..473696e 100644 --- a/test/scripts/TestGUI.py +++ b/test/scripts/TestGUI.py @@ -7,6 +7,7 @@ from datetime import datetime from disSys import * from logWin import * from udpComm import * +from ccuSys import * # 创建UDP通信套接字 @@ -21,8 +22,8 @@ sock.bind(server_address) root = tk.Tk() root.title("能源管理系统调试") # 创建消息显示窗口 -logFrame = tk.LabelFrame(root, text="消息显示") -logFrame.grid(row=1, columnspan=3 ,column=0, sticky='nsw') +logFrame = tk.LabelFrame(root, text="消息") +logFrame.grid(row=0, rowspan=3,column=1, sticky='ns') logwin = logWin(logFrame) logwin.grid(row=0, column=0, sticky='nesw') # 创建配电窗口 @@ -30,16 +31,21 @@ disSysFrame = tk.LabelFrame(root, text="配电系统") disSysFrame.grid(row=0, column=0, sticky='ne') disSysWin = disSys(disSysFrame) disSysWin.grid(row=0, column=0, sticky='ne') +# 创建ccu消息窗口 +ccuSysFrame = tk.LabelFrame(root, text="ccu消息") +ccuSysFrame.grid(row=1, column=0, sticky='swe') +ccuSysWin = ccuSys(ccuSysFrame) +# ccuSysWin.grid(row=0, column=0, sticky='ne') # 创建并启动接收和发送消息的线程 thread = threading.Thread(target=receive_messages, args=(sock, logwin, disSysWin)) thread.daemon = True thread.start() -thread2 = threading.Thread(target=send_messages, args=(sock, logwin, disSysWin)) + +thread2 = threading.Thread(target=send_messages, args=(sock, logwin, disSysWin,ccuSysWin)) thread2.daemon = True thread2.start() - # 运行主循环 root.mainloop() # 关闭套接字 diff --git a/test/scripts/ccuSys.py b/test/scripts/ccuSys.py index ece51a8..abd6903 100644 --- a/test/scripts/ccuSys.py +++ b/test/scripts/ccuSys.py @@ -2,19 +2,332 @@ import socket import struct import tkinter as tk import threading +import random from udpmsg import * +from udpmsg import msg_CcuStateFbMsg from datetime import datetime from tkinter import font -from guiEle import ElementDisplayApp -from until import * -from guiInput import InputGUI from tkinter import Frame - +from tkinter.ttk import * class ccuSys(Frame): - def __init__(self,root): + def __init__(self, root): super().__init__(root) + # Initialize CCU state + self.ccuState = msg_CcuStateFbMsg() + self.col_frames = [] + self.state_entries = [] + + # Timer settings + self.update_interval = 1000 # Default update interval in milliseconds + + # Network settings + self.udp_ip = "127.0.0.1" + self.udp_port = 5005 + self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + self.sock.settimeout(1.0) + + # Initialize GUI + self.master = root self.createWidgets() + + # Start data update thread + self.running = True + self.update_thread = threading.Thread(target=self._update_thread) + self.update_thread.daemon = True + self.update_thread.start() + + # Start timer for periodic display update + self.update_timer = None + self.start_update_timer() def createWidgets(self): - pass \ No newline at end of file + # Main window configuration + # self.master.title("CCU Monitoring System") + # self.master.geometry("1200x800") + + # Create status display area + self.status_frame = tk.Frame(self.master) + self.status_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10) + + # Create status columns + self._create_status_column("FCU Status", [ + "fcuState", "fcuFaultLeve", "powerLimit", + "totalPowerGeneration", "fcuVoltage", "fcuCurrent", + "fcuOutPower", "fcuOutIns" + ]) + + self._create_status_column("Battery Status", [ + "insBatSoc", "powerBatSoc", "insBatLimit", + "powerBatLimit", "insBatTotalElectricity", + "powerBatTotalElectricity", "insCurrent", + "powerCurrent" + ]) + + self._create_status_column("Sensor Status", [ + "h2Concentration1", "h2Concentration2", + "o2Concentration1", "o2Concentration2", + "ch4oConcentration1", "ch4oConcentration2", + "backpressure1", "backpressure2" + ]) + + self._create_status_column("System Status", [ + "insPosRelayState", "insNegRelayState", + "powerPosRelayState", "powerNegRelayState", + "flameDetection", "exchangerTemperature", + "insEmergencyStatusWord", "powerEmergencyStatusWord" + ]) + + # Create control panel + self.control_frame = tk.Frame(self.master) + self.control_frame.pack(fill=tk.X, padx=10, pady=5) + + # Add control buttons + self.refresh_btn = tk.Button( + self.control_frame, text="Refresh", command=self.update_display + ) + self.refresh_btn.pack(side=tk.LEFT, padx=5) + + self.export_btn = tk.Button( + self.control_frame, text="Export Data", command=self.export_data + ) + self.export_btn.pack(side=tk.LEFT, padx=5) + + # Timer control + self.timer_frame = tk.Frame(self.control_frame) + self.timer_frame.pack(side=tk.RIGHT, padx=10) + + # Timer interval label + tk.Label(self.timer_frame, text="Update Interval (ms):").pack(side=tk.LEFT) + + # Timer interval entry + self.interval_entry = tk.Entry(self.timer_frame, width=6) + self.interval_entry.insert(0, str(self.update_interval)) + self.interval_entry.pack(side=tk.LEFT, padx=5) + + # Set interval button + self.set_interval_btn = tk.Button( + self.timer_frame, + text="Set", + command=self.set_update_interval + ) + self.set_interval_btn.pack(side=tk.LEFT) + + # Status indicator + self.status_indicator = tk.Label( + self.timer_frame, text="●", fg="green", font=("Arial", 16) + ) + self.status_indicator.pack(side=tk.RIGHT, padx=10) + + # FCU control panel + self.fcu_frame = tk.Frame(self.control_frame) + self.fcu_frame.pack(side=tk.LEFT, padx=10) + + # FCU state control + tk.Label(self.fcu_frame, text="FCU State:").pack(side=tk.LEFT) + self.fcu_state_var = tk.IntVar(value=0) + self.fcu_state_menu = tk.OptionMenu( + self.fcu_frame, self.fcu_state_var, + *range(4), command=self.set_fcu_state + ) + self.fcu_state_menu.pack(side=tk.LEFT, padx=5) + + # FCU fault level control + tk.Label(self.fcu_frame, text="Fault Level:").pack(side=tk.LEFT) + self.fcu_fault_var = tk.IntVar(value=0) + self.fcu_fault_menu = tk.OptionMenu( + self.fcu_frame, self.fcu_fault_var, + *range(4), command=self.set_fcu_fault_level + ) + self.fcu_fault_menu.pack(side=tk.LEFT, padx=5) + + def _create_status_column(self, title, fields): + """Create a status column with specified fields""" + col_frame = tk.LabelFrame( + self.status_frame, text=title, bd=2, relief=tk.GROOVE + ) + col_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5, pady=5) + + for field in fields: + field_frame = tk.Frame(col_frame) + field_frame.pack(fill=tk.X, padx=5, pady=2) + + # Field name + name_label = tk.Label( + field_frame, text=field, width=20, anchor=tk.W + ) + name_label.pack(side=tk.LEFT) + + # Value display + value_entry = tk.Entry( + field_frame, width=15, state='readonly' + ) + value_entry.pack(side=tk.RIGHT, fill=tk.X, expand=True) + + # Store reference for updates + self.state_entries.append((field, value_entry)) + + def generate_simulated_data(self): + """Generate simulated CCU state data""" + self.ccuState.fcuState = self.fcu_state_var.get() + self.ccuState.fcuFaultLeve = self.fcu_fault_var.get() + self.ccuState.powerLimit = random.randint(0, 100) + self.ccuState.totalPowerGeneration = int(random.uniform(0, 1000)) + self.ccuState.fcuVoltage = int(random.uniform(200, 400)) + self.ccuState.fcuCurrent = int(random.uniform(0, 100)) + self.ccuState.fcuOutPower = random.randint(0, 1000) + self.ccuState.fcuOutIns = random.randint(0, 100) + + self.ccuState.insBatSoc = random.randint(0, 100) + self.ccuState.powerBatSoc = random.randint(0, 100) + self.ccuState.insBatLimit = random.randint(0, 100) + self.ccuState.powerBatLimit = random.randint(0, 100) + self.ccuState.insBatTotalElectricity = random.randint(0, 1000) + self.ccuState.powerBatTotalElectricity = random.randint(0, 1000) + self.ccuState.insCurrent = random.randint(0, 100) + self.ccuState.powerCurrent = random.randint(0, 100) + + self.ccuState.h2Concentration1 = random.randint(0, 100) + self.ccuState.h2Concentration2 = random.randint(0, 100) + self.ccuState.o2Concentration1 = random.randint(0, 100) + self.ccuState.o2Concentration2 = random.randint(0, 100) + self.ccuState.ch4oConcentration1 = random.randint(0, 100) + self.ccuState.ch4oConcentration2 = random.randint(0, 100) + self.ccuState.backpressure1 = random.randint(0, 10) + self.ccuState.backpressure2 = random.randint(0, 10) + + self.ccuState.insPosRelayState = random.randint(0, 1) + self.ccuState.insNegRelayState = random.randint(0, 1) + self.ccuState.powerPosRelayState = random.randint(0, 1) + self.ccuState.powerNegRelayState = random.randint(0, 1) + self.ccuState.flameDetection = random.randint(0, 1) + self.ccuState.exchangerTemperature = random.randint(20, 100) + self.ccuState.insEmergencyStatusWord = random.randint(0, 255) + self.ccuState.powerEmergencyStatusWord = random.randint(0, 255) + + def update_display(self): + """Update all displayed values""" + # Generate simulated data if no real data available + if not hasattr(self.ccuState, 'fcuState'): + self.generate_simulated_data() + + for field, entry in self.state_entries: + value = getattr(self.ccuState, field, "N/A") + entry.config(state='normal') + entry.delete(0, tk.END) + entry.insert(0, str(value)) + entry.config(state='readonly') + + # Update status indicator + self._update_status_indicator() + + def _update_status_indicator(self): + """Update the status indicator based on system state""" + if self.ccuState.fcuFaultLeve > 0: + self.status_indicator.config(fg="red") + else: + self.status_indicator.config(fg="green") + + def export_data(self): + """Export current status data to file""" + timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") + filename = f"ccu_status_{timestamp}.log" + try: + with open(filename, 'w') as f: + for field, _ in self.state_entries: + value = getattr(self.ccuState, field, "N/A") + f.write(f"{field}: {value}\n") + print(f"Data exported to {filename}") + except Exception as e: + print(f"Export failed: {str(e)}") + + def _update_thread(self): + """Thread for updating CCU state""" + while self.running: + try: + # Receive data from UDP + data, _ = self.sock.recvfrom(1024) + self.ccuState.unpack(data) + + except socket.timeout: + continue + except Exception as e: + print(f"Update error: {str(e)}") + break + + def set_update_interval(self): + """Set new update interval from GUI input""" + try: + new_interval = int(self.interval_entry.get()) + if new_interval < 100: + raise ValueError("Interval must be >= 100ms") + self.update_interval = new_interval + self.stop_update_timer() + self.start_update_timer() + except ValueError as e: + print(f"Invalid interval: {str(e)}") + + def set_fcu_state(self, state): + """Set FCU state and update display""" + self.ccuState.fcuState = state + self.update_display() + + def set_fcu_fault_level(self, level): + """Set FCU fault level and update display""" + self.ccuState.fcuFaultLeve = level + self.update_display() + + def start_update_timer(self): + """Start the periodic display update timer""" + if not hasattr(self, 'data_update_thread'): + self.data_update_running = True + self.data_update_thread = threading.Thread( + target=self._data_update_loop + ) + self.data_update_thread.daemon = True + self.data_update_thread.start() + + self._update_display_loop() + + def _update_display_loop(self): + """Periodically update the display""" + self.generate_simulated_data() + self.update_display() + self.update_timer = self.master.after( + self.update_interval, + self._update_display_loop + ) + + def _data_update_loop(self): + """Periodically update data from network""" + while self.data_update_running: + try: + # Receive data from UDP + data, _ = self.sock.recvfrom(1024) + self.ccuState.unpack(data) + time.sleep(self.update_interval / 1000) + except socket.timeout: + continue + except Exception as e: + print(f"Data update error: {str(e)}") + break + + def stop_update_timer(self): + """Stop the periodic display update timer""" + if self.update_timer: + self.master.after_cancel(self.update_timer) + self.update_timer = None + + def __del__(self): + """Clean up resources""" + self.running = False + self.stop_update_timer() + if hasattr(self, 'update_thread'): + self.update_thread.join() + self.sock.close() + +if __name__ == "__main__": + root = tk.Tk() + app = ccuSys(root) + app.pack(fill=tk.BOTH, expand=True) + root.mainloop() diff --git a/test/scripts/disSys.py b/test/scripts/disSys.py index a884531..361026e 100644 --- a/test/scripts/disSys.py +++ b/test/scripts/disSys.py @@ -547,6 +547,115 @@ class disSys(Frame): c = self.disHVBB.pack() d = self.disLVB.pack() return a,b,c,d + + def update_fromMsg(self, data): + '''通过这个可以更新数据''' + try: + # 解析消息头 + headBuf = data[:6] + header = struct.unpack('接收到来自 {address} | 高压母线配电指令:\n") logWin.display_log(logwin,f"{formatted_time}->接收到来自 {address} | 高压母线配电指令:") - if(msg.fuelCellCircuitBreaker==0x55): - disSysWin.dict1['燃料电池断路器']='闭合' - elif(msg.fuelCellCircuitBreaker==0xAA): - disSysWin.dict1['燃料电池断路器']='断开' - - if(msg.powerLithiumBatteryCircuitBreaker==0x55): - disSysWin.dict1['动力锂电池断路器']='闭合' - elif(msg.powerLithiumBatteryCircuitBreaker==0xAA): - disSysWin.dict1['动力锂电池断路器']='断开' - - if(msg.propulsionMotorCircuitBreaker==0x55): - disSysWin.dict1['推进电机断路器']='闭合' - elif(msg.propulsionMotorCircuitBreaker==0xAA): - disSysWin.dict1['推进电机断路器']='断开' - - if(msg.lithiumBatteryGroupInstrumentCircuitBreaker==0x55): - disSysWin.dict1['仪表锂电池断路器']='闭合' - elif(msg.lithiumBatteryGroupInstrumentCircuitBreaker==0xAA): - disSysWin.dict1['仪表锂电池断路器']='断开' - - if(msg.dcDc5ModuleCircuitBreaker==0x55): - disSysWin.dict1['DC/DC5模块断路器']='闭合' - elif(msg.dcDc5ModuleCircuitBreaker==0xAA): - disSysWin.dict1['DC/DC5模块断路器']='断开' - - if(msg.bowHighVoltageDistributionBoxCircuitBreaker==0x55): - disSysWin.dict1['艏部高压配电断路器']='闭合' - elif(msg.bowHighVoltageDistributionBoxCircuitBreaker==0xAA): - disSysWin.dict1['艏部高压配电断路器']='断开' - - if(msg.sternFTDevice45CircuitBreaker==0x55): - disSysWin.dict1['艏部FT4/5断路器']='闭合' - elif(msg.sternFTDevice45CircuitBreaker==0xAA): - disSysWin.dict1['艏部FT4/5断路器']='断开' - - if(msg.sternRudderSwitch1CircuitBreaker==0x55): - disSysWin.dict1['艉舵1/2断路器']='闭合' - elif(msg.sternRudderSwitch1CircuitBreaker==0xAA): - disSysWin.dict1['艉舵1/2断路器']='断开' - - if(msg.sternRudderSwitch2CircuitBreaker==0x55): - disSysWin.dict1['艉舵3/4断路器']='闭合' - elif(msg.sternRudderSwitch2CircuitBreaker==0xAA): - disSysWin.dict1['艉舵3/4断路器']='断开' - - if(msg.fbReservedCircuitBreaker==0x55): - disSysWin.dict1['FB预留断路器']='闭合' - elif(msg.fbReservedCircuitBreaker==0xAA): - disSysWin.dict1['FB预留断路器']='断开' - - if(msg.tyzReservedCircuitBreaker==0x55): - disSysWin.dict1['TYZ预留断路器']='闭合' - elif(msg.tyzReservedCircuitBreaker==0xAA): - disSysWin.dict1['TYZ预留断路器']='断开' - - if(msg.reservedCircuitBreaker==0x55): - disSysWin.dict1['预留断路器']='闭合' - elif(msg.reservedCircuitBreaker==0xAA): - disSysWin.dict1['预留断路器']='断开' - disSysWin.update_disp() + elif(msg_id==0x0002): + logWin.display_log(logwin,f"{formatted_time}->接收到来自 {address} | 高压汇流排A配电指令:") + elif(msg_id==0x0003): + logWin.display_log(logwin,f"{formatted_time}->接收到来自 {address} | 高压汇流排B配电指令:") + elif(msg_id==0x0004): + logWin.display_log(logwin,f"{formatted_time}->接收到来自 {address} | 低压母线配电指令:") -def send_messages(sock, logwin:logWin, disSysWin:disSys): +def send_messages(sock, logwin:logWin, disSysWin:disSys,ccuSysWin:ccuSys): while True: # 配电消息反馈 - a,b,c,d = disSysWin.updata_data() + a,b,c,d = disSysWin.get_date() sock.sendto(a, (target_ip, target_port)) sock.sendto(b, (target_ip, target_port)) sock.sendto(c, (target_ip, target_port)) sock.sendto(d, (target_ip, target_port)) #TODO复合管控消息反馈 - + #TODOccu消息反馈 + e = ccuSysWin.ccuState.pack() + sock.sendto(e, (target_ip, target_port)) threading.Event().wait(1) # 每隔1秒发送一次消息 diff --git a/test/scripts/udpmsg.py b/test/scripts/udpmsg.py index 62a780f..9ff5e6a 100644 --- a/test/scripts/udpmsg.py +++ b/test/scripts/udpmsg.py @@ -173,15 +173,15 @@ class msg_CcuStateFbMsg: for i in range(len(data)): self.checkCode += data[i] - print(self.checkCode) + # print(self.checkCode) data += struct.pack('