diff --git a/.vscode/settings.json b/.vscode/settings.json index c211e4a..ce284e2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -74,7 +74,18 @@ "thread": "cpp", "typeindex": "cpp", "variant": "cpp", - "*.ipp": "cpp" + "*.ipp": "cpp", + "cassert": "cpp", + "cerrno": "cpp", + "cfloat": "cpp", + "ciso646": "cpp", + "climits": "cpp", + "filesystem": "cpp", + "ios": "cpp", + "locale": "cpp", + "stack": "cpp", + "cstdbool": "cpp", + "version": "cpp" }, "C_Cpp.errorSquiggles": "disabled", "marscode.chatLanguage": "cn", diff --git a/data/msg/uPower_currentState_st.json b/data/msg/uPower_currentState_st.json index 0edf428..41648bf 100644 --- a/data/msg/uPower_currentState_st.json +++ b/data/msg/uPower_currentState_st.json @@ -1,48 +1,47 @@ -{"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 -} -} +{ + "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 +} \ No newline at end of file diff --git a/data/msg/uPower_disSysState_st.json b/data/msg/uPower_disSysState_st.json index adb658e..ed8e1bf 100644 --- a/data/msg/uPower_disSysState_st.json +++ b/data/msg/uPower_disSysState_st.json @@ -1,11 +1,10 @@ -{"uPower_disSysState_st":{ - "HVolABusBreaker_unit16" : 0, - "HVolBBusBreaker_unit16" : 0, - "HVolBusBreaker_uint16" : 0, - "LVolBusBreaker_uint16" : 0, - "faultCode_array" : - [ - 0 - ] -} -} +{ + "HVolABusBreaker_unit16": 0, + "HVolBBusBreaker_unit16": 0, + "HVolBusBreaker_uint16": 0, + "LVolBusBreaker_uint16": 0, + "faultCode_array": + [ + 0 + ] +} \ No newline at end of file diff --git a/data/msg/uPower_fcsState_st.json b/data/msg/uPower_fcsState_st.json index 2e81843..31141fb 100644 --- a/data/msg/uPower_fcsState_st.json +++ b/data/msg/uPower_fcsState_st.json @@ -1,31 +1,30 @@ -{"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, - "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 -} -} +{ + "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, + "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 +} \ No newline at end of file diff --git a/data/msg/uPower_liBatState_st.json b/data/msg/uPower_liBatState_st.json index 9c92b81..b3e9fd4 100644 --- a/data/msg/uPower_liBatState_st.json +++ b/data/msg/uPower_liBatState_st.json @@ -1,39 +1,38 @@ -{"uPower_liBatState_st":{ - "fcuCurToInsLimit1_uint8" : 0, - "fcuCurToinsLimit2_uint8" : 0, - "insBatCurElect_uint16" : 0, - "insBatLimit_uint16" : 0, - "insBatSoc_uint8" : 0, - "insBatTotalElect_uint16" : 0, - "insChargeState_uint8" : 0, - "insCurSocHold1_uint8" : 0, - "insCurSocHold2_uint8" : 0, - "insCurSocHold3_uint8" : 0, - "insCurrent_uint16" : 0, - "insLinkVol_uint16" : 0, - "insNegRelayState_uint8" : 0, - "insNegRes_uint16" : 0, - "insPackVol_uint16" : 0, - "insPosRelayState_uint8" : 0, - "insPosRes_uint16" : 0, - "insfaultCode_uint8" : 0, - "powBatCurElect_uint16" : 0, - "powBatSoc_uint8" : 0, - "powBatTotalElect_uint16" : 0, - "powChargeState_uint8" : 0, - "powCurSocHold1_uint8" : 0, - "powCurSocHold2_uint8" : 0, - "powCurSocHold3_uint8" : 0, - "powCurToInsLimit1_uint8" : 0, - "powCurToinsLimit2_uint8" : 0, - "powCur_uint16" : 0, - "powLinkVol_uint16" : 0, - "powNegRelayState_uint8" : 0, - "powNegRes_uint16" : 0, - "powPosRelayState_uint8" : 0, - "powPosRes_uint16" : 0, - "powerBatLimit_uint16" : 0, - "powerPackVol_uint16" : 0, - "powfaultCode_uint8" : 0 -} -} +{ + "fcuCurToInsLimit1_uint8": 0, + "fcuCurToinsLimit2_uint8": 0, + "insBatCurElect_uint16": 0, + "insBatLimit_uint16": 0, + "insBatSoc_uint8": 0, + "insBatTotalElect_uint16": 0, + "insChargeState_uint8": 0, + "insCurSocHold1_uint8": 0, + "insCurSocHold2_uint8": 0, + "insCurSocHold3_uint8": 0, + "insCurrent_uint16": 0, + "insLinkVol_uint16": 0, + "insNegRelayState_uint8": 0, + "insNegRes_uint16": 0, + "insPackVol_uint16": 0, + "insPosRelayState_uint8": 0, + "insPosRes_uint16": 0, + "insfaultCode_uint8": 0, + "powBatCurElect_uint16": 0, + "powBatSoc_uint8": 0, + "powBatTotalElect_uint16": 0, + "powChargeState_uint8": 0, + "powCurSocHold1_uint8": 0, + "powCurSocHold2_uint8": 0, + "powCurSocHold3_uint8": 0, + "powCurToInsLimit1_uint8": 0, + "powCurToinsLimit2_uint8": 0, + "powCur_uint16": 0, + "powLinkVol_uint16": 0, + "powNegRelayState_uint8": 0, + "powNegRes_uint16": 0, + "powPosRelayState_uint8": 0, + "powPosRes_uint16": 0, + "powerBatLimit_uint16": 0, + "powerPackVol_uint16": 0, + "powfaultCode_uint8": 0 +} \ No newline at end of file diff --git a/data/msg/uPower_pmState_fb.json b/data/msg/uPower_pmState_fb.json index debded9..5896dea 100644 --- a/data/msg/uPower_pmState_fb.json +++ b/data/msg/uPower_pmState_fb.json @@ -1,12 +1,13 @@ { - "currentMod_uint8": 1, - "falutLevel_uint8": 0, + "currentMod_uint8": 0, "faultCode_array": [ 0 ], + "faultLevel_uint8": 0, + "leakage_uint8": 0, "powerState_uint8": 0, - "soc_uint32": 0, - "sustainableTime_uint32": 0, - "workCondition_uint8": 5 + "soc_uint16": 0, + "sustainableTime_int64": 0, + "workCondition_uint8": 1 } \ No newline at end of file diff --git a/docs/PowerManager_UI_Design.md b/docs/PowerManager_UI_Design.md new file mode 100644 index 0000000..0c1597c --- /dev/null +++ b/docs/PowerManager_UI_Design.md @@ -0,0 +1,277 @@ +# 上位机控制程序设计文档 + +## 1. 程序架构设计 + +采用MVC模式设计,主要分为以下模块: + +### 1.0 系统架构图 +```mermaid +graph TD + A[用户界面] -->|控制指令| B[控制器] + B -->|发送命令| C[通信模块] + C -->|UDP协议| D[下位机] + D -->|状态反馈| C + C -->|解析数据| B + B -->|更新状态| A + B -->|记录数据| E[数据库] +``` + +### 1.1 消息处理流程 +1. 接收原始UDP数据 +2. 根据消息ID选择解析器 +3. 验证校验码 +4. 解析为结构化数据 +5. 触发状态更新事件 +6. 存储到数据库 + +### 1.1 通信模块 (Model) - 详细设计 + +#### 消息类型映射表 +| 消息ID | 消息名称 | 处理函数 | 更新频率 | +|--------|----------|----------|----------| +| 0x0005 | 高压母线状态 | parse_high_vol_bus | 1Hz | +| 0x0006 | 高压A母线状态 | parse_high_a_vol_bus | 1Hz | +| 0x0007 | 低压主母线状态 | parse_low_main_bus | 1Hz | +| 0x0008 | 低压汇流排状态 | parse_low_bus | 1Hz | + +#### 异常处理机制 +1. 校验失败:丢弃数据并记录错误日志 +2. 超时处理:3次重试后标记设备离线 +3. 数据异常:触发告警并显示在界面 +```python +class UDPMessageHandler: + """UDP消息处理基类""" + def __init__(self, ip, port): + self.ip = ip + self.port = port + self.socket = None + + def connect(self): + """建立UDP连接""" + pass + + def send_message(self, msg): + """发送消息""" + pass + + def receive_message(self): + """接收消息""" + pass + + def close(self): + """关闭连接""" + pass + +class PowerMessageHandler(UDPMessageHandler): + """电源管理专用消息处理器""" + def __init__(self, ip, port): + super().__init__(ip, port) + self.message_parsers = { + 0x0005: self.parse_high_vol_bus, + 0x0006: self.parse_high_a_vol_bus, + # 其他消息类型... + } + + def parse_high_vol_bus(self, data): + """解析高压母线消息""" + pass + + # 其他消息解析方法... +``` + +### 1.2 界面模块 (View) - 详细设计 + +#### 主界面布局 +```mermaid +graph LR + A[标题栏] --> B[状态区] + B --> C[电压电流仪表盘] + B --> D[断路器状态指示灯] + A --> E[控制区] + E --> F[电源控制按钮组] + E --> G[参数设置面板] + A --> H[日志区] + H --> I[实时消息列表] + H --> J[历史记录查询] +``` + +#### 组件说明 +1. 电压电流仪表盘:实时显示各母线电压电流值 +2. 断路器状态指示灯:绿色-闭合,红色-断开 +3. 电源控制按钮组:带防误触保护(需长按3秒) +4. 参数设置面板:输入验证和范围检查 +```python +class MainWindow(tk.Tk): + """主窗口""" + def __init__(self): + super().__init__() + self.title("电源管理系统") + self.geometry("1200x800") + + self.create_widgets() + + def create_widgets(self): + """创建界面组件""" + self.status_frame = StatusFrame(self) + self.control_frame = ControlFrame(self) + self.log_frame = LogFrame(self) + + # 布局管理 + self.status_frame.pack(side=tk.TOP, fill=tk.X) + self.control_frame.pack(side=tk.LEFT, fill=tk.Y) + self.log_frame.pack(side=tk.RIGHT, expand=True, fill=tk.BOTH) + +class StatusFrame(tk.Frame): + """状态显示面板""" + def update_status(self, data): + """更新状态显示""" + pass + +class ControlFrame(tk.Frame): + """控制面板""" + def create_buttons(self): + """创建控制按钮""" + pass +``` + +### 1.3 控制器模块 (Controller) - 详细设计 + +#### 状态管理机制 +1. 使用有限状态机(FSM)管理电源系统状态 +2. 状态转换规则: + - 仅当所有预检通过才允许上电 + - 故障时自动进入安全状态 + - 人工确认后才能复位 + +#### 命令处理流程 +```mermaid +sequenceDiagram + 用户->>界面: 点击控制按钮 + 界面->>控制器: 发送控制命令 + 控制器->>业务逻辑: 验证命令有效性 + 业务逻辑->>通信模块: 发送UDP指令 + 通信模块->>下位机: 传输控制报文 + 下位机-->>通信模块: 返回应答 + 通信模块->>控制器: 更新命令状态 + 控制器->>界面: 显示操作结果 + 控制器->>数据库: 记录操作日志 +``` +```python +class PowerManagerController: + """主控制器""" + def __init__(self): + self.message_handler = PowerMessageHandler("192.168.1.100", 5000) + self.view = MainWindow() + + # 绑定事件 + self.bind_events() + + def bind_events(self): + """绑定UI事件""" + self.view.control_frame.on_button_click = self.handle_control_command + + def handle_control_command(self, cmd): + """处理控制命令""" + pass + + def start(self): + """启动应用程序""" + self.message_handler.connect() + self.view.mainloop() +``` + +## 2. 接口规范 + +### 2.1 模块交互架构 +```mermaid +classDiagram + class Communication { + +send_command(cmd: dict) bool + +get_status() dict + +subscribe(callback: function) + +on_message_received(data: bytes) + } + + class Controller { + +handle_ui_event(event: dict) + +update_system_status(status: dict) + +log_operation(log: dict) + } + + class UI { + +update_status(data: dict) + +show_alert(level: int, msg: str) + +log_message(source: str, msg: str) + } + + Communication --> Controller : 状态更新通知 + Controller --> UI : 界面更新指令 + UI --> Controller : 用户操作事件 +``` + +### 2.2 详细接口定义 + +#### 通信模块 → 控制器 +```python +# 状态更新通知 +{ + "msg_type": "status_update", + "timestamp": "2025-05-04T10:20:00", + "data": { + "voltage": 220.5, + "current": 15.2, + "breaker_state": True + } +} + +# 错误通知 +{ + "msg_type": "error", + "code": 1001, + "message": "校验失败" +} +``` + +#### 控制器 → 界面 +```python +# 状态显示更新 +{ + "component": "voltage_meter", + "value": 220.5, + "unit": "V", + "normal_range": [210, 230] +} + +# 告警信息 +{ + "level": 2, # 1-警告 2-错误 3-严重 + "message": "A相电压过高", + "suggestion": "检查A相负载" +} +``` + +#### 界面 → 控制器 +```python +# 按钮操作事件 +{ + "event_type": "button_click", + "button_id": "power_on", + "timestamp": "2025-05-04T10:20:01" +} + +# 参数设置事件 +{ + "event_type": "param_set", + "param": "voltage_limit", + "value": 230, + "unit": "V" +} +``` + +### 2.3 错误处理规范 +1. 通信错误:自动重试3次后通知控制器 +2. 业务逻辑错误:记录详细日志并通知界面 +3. 界面错误:显示友好提示并保持最后正常状态 + +## 3. 数据库设计 +(之前已完成的数据库表结构...) \ No newline at end of file diff --git a/src/pPowerManger/LowerCommManager.h b/src/pPowerManger/LowerCommManager.h index c3bd91c..cc75d78 100644 --- a/src/pPowerManger/LowerCommManager.h +++ b/src/pPowerManger/LowerCommManager.h @@ -54,7 +54,7 @@ public: msg_CcuStateFbMsg m_CcuCurrentState; msg_disHighVolBusFbMsg m_disHighVolBusCurrentState; msg_disHighAVolBusFbMsg m_disHighAVolBusCurrentState; - msg_disHighBVolBusFbMsg m_disHighBVolBusCurrentState; + msg_disLowMainBusFbMsg m_disHighBVolBusCurrentState; msg_disLowBusFbMsg m_disLowBusState; // 配电和CCU的反馈状态时间戳 double msg_CcuStateFbMsg_Update_time; diff --git a/src/pPowerManger/PowerManagerFsm.cpp b/src/pPowerManger/PowerManagerFsm.cpp index f634a7a..fe040a8 100644 --- a/src/pPowerManger/PowerManagerFsm.cpp +++ b/src/pPowerManger/PowerManagerFsm.cpp @@ -11,6 +11,37 @@ void PowerManagerFsm::react(TaskStopEvent const &e) { transit(); LOG_F(INFO, "使命结束"); }; + +void PowerManagerFsm::react(CycleTriggeredEvent const &){ + if(pm->currentMod != RunMode::Debug) + { + + } +} +bool PowerManagerFsm::handPowerProtection(DevCmdExt const &e){ + if(pm->workCondition > WorkCondition::REMOTE_CONTROL){ + LOG_F(INFO, "上电保护,执行任务时候禁止操作设备"); + return false; + } + if(e.id == DeviceId::singleBeamSonar1 || + e.id == DeviceId::singleBeamSonar2 || + e.id == DeviceId::singleBeamSonar3 || + e.id == DeviceId::singleBeamSonar4 || + e.id == DeviceId::singleBeamSonar5 || + e.id == DeviceId::singleBeamSonar6 || + e.id == DeviceId::singleBeamSonar7 || + e.id == DeviceId::singleBeamSonar8 || + e.id == DeviceId::sideSonar || + e.id == DeviceId::forwardSonar || + e.id == DeviceId::lowFreqSonar || + e.id == DeviceId::DVL || + e.id == DeviceId::USBL){ + if(e.cmd == 1){ + LOG_F(INFO, "水声设备操作上电保护 %d 已关闭", e.id); + return false; + } + } +} void PowerManagerFsm::react(TaskStartEvent const &e){ LOG_F(INFO, "TaskStartEvent received - type: %d, enableBowRudder: %d, enableBuoyancyAdjustment: %d", e.type, e.enableBowRudder, e.enableBuoyancyAdjustment); switch (e.type) @@ -44,7 +75,7 @@ void PowerManagerFsm::react(TaskStartEvent const &e){ } } -void PowerManagerFsm::react(DevCmdExt const &e) { +void PowerManagerFsm::react(DevCmdExt const &e) { LOG_F(INFO, "DevCmdExt received - id: %d, cmd: %d", e.id, e.cmd); switch (e.id) { @@ -1704,6 +1735,33 @@ void PowerManagerFsm::react(DevCmdExt const &e) { break; } } + +void StandbyState::react(DevCmdExt const &e) +{ + LOG_F(INFO, "StandbyState::react(DevCmdExt const &e)"); + //正常模式下,不允许执行DevCmdExt + if (pm->currentMod == RunMode::Normal ) + { + LOG_F(INFO, "正常模式下,不允许执行DevCmdExt"); + } + else if (pm->currentMod == RunMode::Test) + { + if(handPowerProtection(e)) + PowerManagerFsm::react(e); + else + LOG_F(INFO, "DevCmdExt 执行失败"); + } + else if (pm->currentMod == RunMode::Debug) + { + LOG_F(INFO, "调试模式下,直接执行DevCmdExt"); + PowerManagerFsm::react(e); + } + else + { + LOG_F(INFO, "当前模式未知"); + } +} + void PowerManagerFsm::basicNavigationFault(FaultEvent const &e) { LOG_F(INFO, "basicNavigationFault"); @@ -1712,6 +1770,7 @@ void PowerManagerFsm::basicNavigationFault(FaultEvent const &e) LOG_F(INFO, "部分深度计失效"); pm->faultCode.push_back(0x1102); pm->faultCode.push_back(0x1103); + pm->faultCode.push_back(0x1104); } if(FaultEnable::BasicNavigationFault_2) { @@ -2003,7 +2062,7 @@ void StandbyState::react(MasterCommandEvent const &) { } void StandbyState::handlePowerOn() { - PowerManagerFsm::pm->m_pmEvent = "动力电上电"; + LOG_F(INFO,"动力电上电"); PowerManagerFsm::pm->m_CcuColCmd.powerBatCmd = 0x10; if(PowerManagerFsm::pm->m_pmCurrentState.ccustate.fcuState == 0x04) PowerManagerFsm::pm->m_CcuColCmd.fcuCmd = 0x02; @@ -2326,6 +2385,8 @@ void RemoteControl::entry() { LOG_F(INFO, "进入遥控工况"); } + + // void StandbyState::react(TaskStart const &) // { // LOG_F(INFO, "接收到任务启动信息"); diff --git a/src/pPowerManger/PowerManagerFsm.hpp b/src/pPowerManger/PowerManagerFsm.hpp index aa3d06c..bf230b6 100644 --- a/src/pPowerManger/PowerManagerFsm.hpp +++ b/src/pPowerManger/PowerManagerFsm.hpp @@ -23,9 +23,6 @@ enum class PowerSystemState { struct InitEvent : tinyfsm::Event { }; struct StandbyEvent : tinyfsm::Event { }; struct TaskStopEvent : tinyfsm::Event { }; - -//==================状态流程事件============================ -struct MasterCommandEvent : tinyfsm::Event {}; struct TaskStartEvent : tinyfsm::Event { int type; bool enableBowRudder; @@ -33,14 +30,17 @@ struct TaskStartEvent : tinyfsm::Event { TaskStartEvent() : type(0), enableBowRudder(false), enableBuoyancyAdjustment(false) {}; TaskStartEvent(int type, bool bowRudder, bool buoyancyAdjustment) : type(type), enableBowRudder(bowRudder), enableBuoyancyAdjustment(buoyancyAdjustment) {}; }; -struct DeviceCmd : tinyfsm::Event { }; +//==================状态流程事件============================ +struct CycleTriggeredEvent : tinyfsm::Event {}; +struct MasterCommandEvent : tinyfsm::Event {}; +struct DeviceCmd : tinyfsm::Event {}; struct DevCmdExt : tinyfsm::Event { int id; int cmd; DevCmdExt() : id(0), cmd(0) {}; DevCmdExt(int id, int cmd) : id(id), cmd(cmd) {}; }; -struct FaultEvent : tinyfsm::Event { +struct FaultEvent : tinyfsm::Event { unsigned int subDisSysFaultCode; unsigned int disSysFaultCode; unsigned int powerFaultCode; @@ -78,12 +78,15 @@ public: virtual void react(TaskStartEvent const &e); virtual void react(FaultEvent const &e); virtual void react(TaskStopEvent const &e); + virtual void react(CycleTriggeredEvent const &); //操作函数 void handelPowerCmd(); void handleModCmd(); void handleWorkCmd(); void handleDeviceCmd(); + + bool handPowerProtection(DevCmdExt const &e); //故障处理 void basicNavigationFault(FaultEvent const &e); void extendedNavigationFault(FaultEvent const &e); @@ -141,6 +144,7 @@ class StandbyState : public PowerManagerFsm { public: void entry() override; void react(StandbyEvent const &) override; + void react(DevCmdExt const &e) override; void react(MasterCommandEvent const &) override; private: void handlePowerOn(); diff --git a/src/pPowerManger/PowerManger.cpp b/src/pPowerManger/PowerManger.cpp index 2bdd2e4..68897a0 100644 --- a/src/pPowerManger/PowerManger.cpp +++ b/src/pPowerManger/PowerManger.cpp @@ -34,6 +34,7 @@ PowerManger::PowerManger() sustainableTime = 0; m_faultNum = 0; m_ticker = 0; + m_leakage = 0; faultCode.push_back(0); m_pmCurrentState = {}; diff --git a/src/pPowerManger/PowerManger.h b/src/pPowerManger/PowerManger.h index df730ec..31a7b41 100644 --- a/src/pPowerManger/PowerManger.h +++ b/src/pPowerManger/PowerManger.h @@ -98,7 +98,8 @@ class PowerManger : public AppCastingMOOSApp unsigned int sustainableTime; unsigned int m_faultNum; Driver m_driver; //设备表处理 - std::string m_pmEvent; // 状态机事件描述 + unsigned char m_leakage; + // std::string m_pmEvent; // 状态机事件描述 //===========================CONFIG======================================== long m_lPort; unsigned int m_nReceiveBufferSizeKB; @@ -106,7 +107,6 @@ class PowerManger : public AppCastingMOOSApp double m_current_time; unsigned int m_ticker; int connectState; - //=============================过程函数====================================== void initControlCmd(); diff --git a/src/pPowerManger/UpperCommManager.cpp b/src/pPowerManger/UpperCommManager.cpp index 4c5f7fa..153253f 100644 --- a/src/pPowerManger/UpperCommManager.cpp +++ b/src/pPowerManger/UpperCommManager.cpp @@ -385,6 +385,8 @@ void UpperCommManager::buildSystemReport() { suffix = getTypeName(typeid(m_pm->sustainableTime).name()); pms["sustainableTime_int64"] = m_pm->sustainableTime; + + pms["leakage_uint8"] = m_pm->m_leakage; //2.构建燃料电池状态报告 suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.fcuState).name()); diff --git a/src/pPowerManger/UpperCommManager.h b/src/pPowerManger/UpperCommManager.h index 3cc774c..ea8216f 100644 --- a/src/pPowerManger/UpperCommManager.h +++ b/src/pPowerManger/UpperCommManager.h @@ -27,7 +27,7 @@ using namespace std; //决策消息 #define DB_TO_PM_DEEPTH "uDevice_depth_st" -#define DB_TO_PM_MISSION "uPlan_taskReport_st" +#define DB_TO_PM_MISSION "uPlan_taskStart_cmd" #define DB_TO_PM_TASKSTOP "uPlan_planStop_cmd" //外部通信消息 diff --git a/src/pPowerManger/ccuUdpMsg.h b/src/pPowerManger/ccuUdpMsg.h index 299b7ad..f4af522 100644 --- a/src/pPowerManger/ccuUdpMsg.h +++ b/src/pPowerManger/ccuUdpMsg.h @@ -77,12 +77,12 @@ typedef struct cChecksum checkCode; }msg_disHVBACmd; -typedef struct +typedef struct msg_disHVBBCmd { m_header header; disHighBVolBusCmd data; cChecksum checkCode; -}msg_disHVBBCmd; +}msg_disLVMBCmd; typedef struct { @@ -121,12 +121,12 @@ typedef struct { cChecksum checkCode; } msg_disHighAVolBusFbMsg; -// 高压母线B配电反馈 +// 仪表母线配电反馈 typedef struct { m_header header; - disHighBVolBusState data; + disLowMainBusState data; cChecksum checkCode; -} msg_disHighBVolBusFbMsg; +} msg_disLowMainBusFbMsg; //仪表汇流排配电反馈 typedef struct { diff --git a/src/pPowerManger/pmSysvariable.h b/src/pPowerManger/pmSysvariable.h index 48d7da8..4661b8e 100644 --- a/src/pPowerManger/pmSysvariable.h +++ b/src/pPowerManger/pmSysvariable.h @@ -120,149 +120,292 @@ typedef struct { typedef struct disHighVolBusState { + //断路器状态 + // 5: 燃料电池断路器 unsigned char fuelCellCircuitBreaker; + // 6: 动力锂电池断路器 unsigned char powerLithiumBatteryCircuitBreaker; + // 7: 推进电机断路器 unsigned char propulsionMotorCircuitBreaker; + // 8: 锂电池组仪表断路器 unsigned char lithiumBatteryGroupInstrumentCircuitBreaker; + // 9: DC/DC5模块断路器 unsigned char dcDc5ModuleCircuitBreaker; + // 10: 艏部高压配电箱断路器 unsigned char bowHighVoltageDistributionBoxCircuitBreaker; + // 11: 艉部FT装置4/5断路器 unsigned char sternFTDevice45CircuitBreaker; + // 12: 艉舵开关1断路器 unsigned char sternRudderSwitch1CircuitBreaker; + // 13: 艉舵开关2断路器 unsigned char sternRudderSwitch2CircuitBreaker; + // 14: FB预留断路器 unsigned char fbReservedCircuitBreaker; + // 15: TYZ预留断路器 unsigned char tyzReservedCircuitBreaker; + // 16: 预留断路器 unsigned char reservedCircuitBreaker; - unsigned char busInsulationLow; - unsigned char busAInsulationHigh; - unsigned char lostPower; - unsigned char lostEmerPower; + // unsigned char busInsulationLow; + // unsigned char busAInsulationHigh; + // 17: DC/DC5故障字低 + // 0x00: 正常状态 + // Bit0: DC/DC模块过温关机 + // Bit1: 输出过流 + // Bit2: 输出过压 + // Bit3: 输出欠压 + // Bit4: 输入过压 + // Bit5: 输入欠压 + // Bit6: 输出短路保护 + // Bit7: 内部故障 + // 18: DC/DC5故障字高 + unsigned char dcDcFaultWord1; + // 0x00: 正常状态 + // Bit0: 通讯故障报警 + // Bit1: 工作状态 + // Bit2: 冷却泵1故障 + // Bit3: 冷却泵2故障 + // Bit4: 冷却水泄露 + unsigned char dcDcFaultWord2; + // 19: 动力母排绝缘状态(0x55 正常,0xAA 绝缘低) + unsigned char powerBusInsulationStatus; + // 20: A汇流排绝缘状态(0x55 正常,0xAA 绝缘低) + unsigned char aBusInsulationStatus; + // 21: 仪表电源状态 (0x55 正常,0xAA 故障) + unsigned char meterPowerLossSignal; + // 22: 应急电源状态 (0x55 正常,0xAA 故障) + unsigned char emergencyPowerLossSignal; + // 23: 动力汇流排电压 unsigned short powerBusVoltage; + // 24: DC/DC5模块电流 unsigned short dcDc5ModuleCurrent; + // 25: 动力汇流排电流 unsigned short powerBusCurrent; + // 26: A汇流排电压 unsigned short busbarAVoltage; + // 27: 推进电机控制箱电流 unsigned short propulsionMotorControlBoxCurrent; + // 28: A汇流排电流 unsigned short busbarACurrent; + // 29: 锂电池组(仪表)电流 unsigned short lithiumBatteryGroupMeterCurrent; + // 30: 艏部高压配电箱电流 unsigned short bowHighVoltageDistributionBoxCurrent; + // 31: 艉部FT装置4/5电流 unsigned short sternFTDevice45Current; + // 32: TYZ预留开关电流 unsigned short tyzReservedSwitchCurrent; + // 33: 艉舵开关1电流 unsigned short sternRudderSwitch1Current; + // 34: 预留电流 unsigned short reservedCurrent1; // 改为 reservedCurrent1 以避免重名 + // 35: 艉舵开关2电流 unsigned short sternRudderSwitch2Current; + // 36: 预留电流2 unsigned short reservedCurrent2; // 改为 reservedCurrent2 以避免重名 + // 37: FB预留电流 unsigned short fbReservedSwitchCurrent; + // 38: 预留电流3 unsigned short reservedCurrent3; // 改为 reservedCurrent3 以避免重名 + // 39: 冷却水压力 + unsigned short coolWaterPressure; }disHighVolBusState; typedef struct disHighAVolBusState { + //5. 艏部FT装置1/2/3断路器 unsigned char bowFTDevice123CircuitBreaker; + //6. 启闭机构断路器 unsigned char actuatorCircuitBreaker; + //7. 桅杆舵机控制箱断路器 unsigned char mastSteeringGearControlBoxCircuitBreaker; + //8. XCZ断路器 unsigned char xczCircuitBreaker; + //9. 艏舵控制箱断路器 unsigned char bowRudderControlBoxCircuitBreaker; + //10. 敞水盖启动电缸断路器 unsigned char openWaterCoverStartCylinderCircuitBreaker; + //11. 仪表电源失电信号 (0x55 正常,0xAA 故障) unsigned char instrumentPowerFailureSignal; + //12. 应急电源失电信号 (0x55 正常,0xAA 故障) unsigned char emergencyPowerFailureSignal; + //13. 浸水报警 + // unsigned char busbarBInsulationStatus; unsigned char waterIngressionAlarm; + //14. 汇流排B电压 unsigned short busbarBVoltage; + //15. 汇流排B电流 unsigned short busbarBCurrent; + //16. 艏部FT装置1/2/3电流 unsigned short bowFTDevice123Current; + //17. 启闭机构电流 unsigned short actuatorCurrent; + //18. 桅杆舵机控制箱电流 unsigned short mastSteeringGearControlBoxCurrent; + //19. XCZ电流 unsigned short xczCurrent; + //20. 艏舵控制箱电流 unsigned short bowRudderControlBoxCurrent; + //21. 敞水盖启动电缸电流 unsigned short openWaterCoverStartCylinderCurrent; }disHighAVolBusState; typedef struct disHighBVolBusState { + //5. 锂电池组(仪表)断路器 unsigned char lithiumBatteryGroupInstrumentCircuitBreaker; + //6. 艏部低压配电箱断路器 unsigned char bowLowVoltageDistributionBoxCircuitBreaker; + //7. UNIT4仪表DC48V断路器 unsigned char unit4InstrumentDC48VCircuitBreaker; + //8. DC-C1直流配电板断路器 unsigned char dcC1DCDistributionPanelCircuitBreaker; + //9. 预留断路器1 unsigned char reservedCircuitBreaker1; // 为了区分,添加了数字后缀 + //10. 预留断路器2 unsigned char reservedCircuitBreaker2; // 为了区分,添加了数字后缀 + //11. 应急锂电池组2断路器 unsigned char emergencyLithiumBatteryGroup2CircuitBreaker; + //12. 仪表电源失电信号 (0x55 正常,0xAA 故障) unsigned char instrumentPowerFailureSignal; + //13. 应急电源失电信号 (0x55 正常,0xAA 故障) unsigned char emergencyPowerFailureSignal; + //14. 仪表汇流排绝缘低 (0x55 正常,0xAA 绝缘低) unsigned char instrumentBusbarInsulationLow; + //15. 仪表母排电压 unsigned short instrumentBusbarVoltage; + //16. 艏部低压配电箱电流 unsigned short bowLowVoltageDistributionBoxCurrent; + //17. DC-C1(直流配电板1)仪表DC48V电流 unsigned short dcC1InstrumentDC48VCurrent; + //18. 预留电流 unsigned short reservedCurrent1; // 为了区分,添加了数字后缀 + //19. 应急锂电池组2电流 unsigned short emergencyLithiumBatteryGroup2Current; + //20. 锂电池组(仪表)电流 unsigned short lithiumBatteryGroupInstrumentCurrent; + //21. UNIT4仪表DC48V电流 unsigned short unit4InstrumentDC48VCurrent; + //22. Ushort 预留电流 unsigned short reservedCurrent2; // 为了区分,添加了数字后缀 + //23. 应急2汇流排电压 unsigned short emergency2BusbarVoltage; + //24. 复合能源管控系统应急DC48V电流 unsigned short compositeEnergyManagementSystemEmergencyDC48VCurrent; + //25. 燃料电池安全系统应急DC48V电流 unsigned short fuelCellSecuritySystemEmergencyDC48VCurrent; + //26. PLC控制电源电流 unsigned short plcControlPowerCurrent; -}disHighBVolBusState; +}disLowMainBusState; typedef struct disLowBusState { + //5. UNIT1断路器 unsigned char unit1CircuitBreaker; + //6. UNIT2断路器 unsigned char unit2CircuitBreaker; + //7. UNIT3断路器 unsigned char unit3CircuitBreaker; + //8. UNIT5断路器 unsigned char unit5CircuitBreaker; + //9. 艏部PZ装置断路器 unsigned char bowPZDeviceCircuitBreaker; + //10. 预留断路器1 unsigned char reservedCircuitBreaker1; // 为了区分,添加了数字后缀 + //11. 预留断路器2 unsigned char reservedCircuitBreaker2; // 为了区分,添加了数字后缀 + //12. 应急锂电池组1断路器 unsigned char emergencyLithiumBatteryGroup1CircuitBreaker; + //13. 仪表电源失电信号 (0x55 正常,0xAA 故障) unsigned char powerFailureSignal; + //14. 浸水报警 (0x55 正常,0xAA 故障) unsigned char waterIngressionAlarm; + //15. 仪表母排电压 unsigned short instrumentBusbarVoltage; + //16. 仪表母排电流 unsigned short instrumentBusbarCurrent; + //17. UNIT1电流 unsigned short unit1Current; + //18. UNIT2电流 unsigned short unit2Current; + //19. UNIT3电流 unsigned short unit3Current; + //20. UNIT5电流 unsigned short unit5Current; + //21. 艏部PZ装置电流 unsigned short bowPZDeviceCurrent; + //22. 应急锂电池组1电流 unsigned short emergencyLithiumBatteryGroup1Current; + //23. 应急1汇流排电压 unsigned short emergency1BusbarVoltage; }disLowBusState; typedef struct disHighVolBusCmd { + // 5: 燃料电池断路器 unsigned char fuelCellCircuitBreaker; + // 6: 动力锂电池断路器 unsigned char powerLithiumBatteryCircuitBreaker; + // 7: 推进电机断路器 unsigned char propulsionMotorCircuitBreaker; + // 8: 锂电池组仪表断路器 unsigned char lithiumBatteryGroupInstrumentCircuitBreaker; + // 9: DC/DC5模块断路器 unsigned char dcDc5ModuleCircuitBreaker; + // 10: 艏部高压配电箱断路器 unsigned char bowHighVoltageDistributionBoxCircuitBreaker; + // 11: 艉部FT装置4/5断路器 unsigned char sternFTDevice45CircuitBreaker; + // 12: 艉舵开关1断路器 unsigned char sternRudderSwitch1CircuitBreaker; + // 13: 艉舵开关2断路器 unsigned char sternRudderSwitch2CircuitBreaker; + // 14: FB预留断路器 unsigned char fbReservedCircuitBreaker; + // 15: TYZ预留断路器 unsigned char tyzReservedCircuitBreaker; + // 16: 预留断路器 unsigned char reservedCircuitBreaker; + // 17: DC/DC5模块启动 unsigned char dcdc5Module; - unsigned char inputWater; - unsigned char outputWater; + // 18: 冷却系统启动 + unsigned char coolingSystem; + // unsigned char inputWater; + // unsigned char outputWater; }disHighVolBusCmd; typedef struct disHighAVolBusCmd { + //5. 艏部FT装置1/2/3断路器 unsigned char bowFTDevice123CircuitBreaker; + //6. 启闭机构断路器 unsigned char actuatorCircuitBreaker; + //7. 桅杆舵机控制箱断路器 unsigned char mastSteeringGearControlBoxCircuitBreaker; + //8. XCZ断路器 unsigned char xczCircuitBreaker; + //9. 艏舵控制箱断路器 unsigned char bowRudderControlBoxCircuitBreaker; + //10. 敞水盖启动电缸断路器 unsigned char openWaterCoverStartCylinderCircuitBreaker; }disHighAVolBusCmd; typedef struct disHighBVolBusCmd { + //5. 锂电池组(仪表)断路器 unsigned char lithiumBatteryGroupInstrumentCircuitBreaker; + //6. 艏部低压配电箱断路器 unsigned char bowLowVoltageDistributionBoxCircuitBreaker; + //7. UNIT4仪表DC48V断路器 unsigned char unit4InstrumentDC48VCircuitBreaker; + //8. DC-C1直流配电板断路器 unsigned char dcC1DCDistributionPanelCircuitBreaker; + //9. 预留断路器1 unsigned char reservedCircuitBreaker1; // 为了区分,添加了数字后缀 + //10. 预留断路器2 unsigned char reservedCircuitBreaker2; // 为了区分,添加了数字后缀 + //11. 应急锂电池组2断路器 unsigned char emergencyLithiumBatteryGroup2CircuitBreaker; -}disHighBVolBusCmd; +}disLowMainBusCmd; typedef struct disLowBusCmd { @@ -284,7 +427,7 @@ typedef struct pmState ccuState ccustate; disHighVolBusState bus1State; disHighAVolBusState bus2State; - disHighBVolBusState bus3State; + disLowMainBusState bus3State; disLowBusState bus4State; } PmState; @@ -439,6 +582,17 @@ namespace WorkCondition { }; }; +namespace RunMode { + enum Type : unsigned char { + //正常模式 + Normal = 0, + //测试模式 + Test = 1, + //调试模式 + Debug = 2 + }; +}; + namespace TaskType { enum Type : unsigned char { THROW_LOAD = 1, // 抛载 @@ -510,55 +664,122 @@ struct DeviceSwitchCmd int cmd; }; +namespace DeviceId { + enum Type : unsigned char { + singleBeamSonar1 = 0, + singleBeamSonar2 = 1, + singleBeamSonar3 = 2, + singleBeamSonar4 = 3, + singleBeamSonar5 = 4, + singleBeamSonar6 = 5, + singleBeamSonar7 = 6, + singleBeamSonar8 = 7, + forwardSonar = 8, + bowCover1 = 9, + bowCover2 = 10, + bowCover3 = 11, + bowCover4 = 12, + bowCover5 = 13, + bowCover6 = 14, + bowRudderDeploy = 15, + bowRudderServo1 = 16, + bowRudderServo2 = 17, + depth1 = 18, + depth2 = 19, + depth3 = 20, + overDeep1 = 21, + overDeep2 = 22, + ctd1 = 23, + ctd2 = 24, + soundVeloc = 25, + waterInject = 26, + bowWaterlnet1 = 27, + bowWaterlnet2 = 28, + bowWaterlnet3 = 29, + bowWaterlnet4 = 30, + bowWaterlnet5 = 31, + bowWaterlnet6 = 32, + bowWaterlnet7 = 33, + bowWaterlnet8 = 34, + sideSonar = 35, + lowFreqSonar = 36, + launchControler = 37, + photoSensor = 38, + electSensor = 39, + commMast = 40, + mastLiftingServo = 41, + USBL = 42, + DVL = 43, + buoyancyAdjust1 = 44, + buoyancyAdjust2 = 45, + buoyancyAdjust3 = 46, + buoyancyAdjust4 = 47, + buoyancyAdjust5 = 48, + sternRudderServo1 = 49, + sternRudderServo2 = 50, + sternRudderServo3 = 51, + sternRudderServo4 = 52, + thruster = 53, + bowThrow = 54, + sternThrow = 55, + buoyage = 56, + ins = 57, + ntp = 58, + inputWaterSensor1 = 59, + inputWaterSensor2 = 60, + inputWaterSensor3 = 61, + }; +} + namespace FaultEnable { enum Type : bool { BasicNavigationFault_1 = true, // 使能故障 - BasicNavigationFault_2 = false, - BasicNavigationFault_3 = false, - BasicNavigationFault_4 = false, - BasicNavigationFault_5 = false, - BasicNavigationFault_6 = false, - BasicNavigationFault_7 = false, - BasicNavigationFault_8 = false, - BasicNavigationFault_9 = false, - BasicNavigationFault_10 = false, + BasicNavigationFault_2 = true, + BasicNavigationFault_3 = true, + BasicNavigationFault_4 = true, + BasicNavigationFault_5 = true, + BasicNavigationFault_6 = true, + BasicNavigationFault_7 = true, + BasicNavigationFault_8 = true, + BasicNavigationFault_9 = true, + BasicNavigationFault_10 = true, - ExtendedNavigationFault_1 = false, // 使能故障 - ExtendedNavigationFault_2 = false, - ExtendedNavigationFault_3 = false, - ExtendedNavigationFault_4 = false, + ExtendedNavigationFault_1 = true, // 使能故障 + ExtendedNavigationFault_2 = true, + ExtendedNavigationFault_3 = true, + ExtendedNavigationFault_4 = true, - ObstacleAvoidanceFault_1 = false, // 使能故障 - ObstacleAvoidanceFault_2 = false, - ObstacleAvoidanceFault_3 = false, + ObstacleAvoidanceFault_1 = true, // 使能故障 + ObstacleAvoidanceFault_2 = true, + ObstacleAvoidanceFault_3 = true, - BuoyancyControlFault_1 = false, // 使能故障 - BuoyancyControlFault_2 = false, - BuoyancyControlFault_3 = false, - BuoyancyControlFault_4 = false, + BuoyancyControlFault_1 = true, // 使能故障 + BuoyancyControlFault_2 = true, + BuoyancyControlFault_3 = true, + BuoyancyControlFault_4 = true, - CommunicationSystemFault_1 = false, // 使能故障 - CommunicationSystemFault_2 = false, - CommunicationSystemFault_3 = false, + CommunicationSystemFault_1 = true, // 使能故障 + CommunicationSystemFault_2 = true, + CommunicationSystemFault_3 = true, - PayloadSystemFault_1 = false, // 使能故障 - PayloadSystemFault_2 = false, - PayloadSystemFault_3 = false, - PayloadSystemFault_4 = false, - PayloadSystemFault_5 = false, - PayloadSystemFault_6 = false, - PayloadSystemFault_7 = false, + PayloadSystemFault_1 = true, // 使能故障 + PayloadSystemFault_2 = true, + PayloadSystemFault_3 = true, + PayloadSystemFault_4 = true, + PayloadSystemFault_5 = true, + PayloadSystemFault_6 = true, + PayloadSystemFault_7 = true, - EmergencySystemFault_1 = false, // 使能故障 - EmergencySystemFault_2 = false, - EmergencySystemFault_3 = false, - EmergencySystemFault_4 = false, - EmergencySystemFault_5 = false, - EmergencySystemFault_6 = false, + EmergencySystemFault_1 = true, // 使能故障 + EmergencySystemFault_2 = true, + EmergencySystemFault_3 = true, + EmergencySystemFault_4 = true, + EmergencySystemFault_5 = true, + EmergencySystemFault_6 = true, - SensorSystemFault_1 = false, // 使能故障 - SensorSystemFault_2 = false, - SensorSystemFault_3 = false, + SensorSystemFault_1 = true, // 使能故障 + SensorSystemFault_2 = true, + SensorSystemFault_3 = true, }; } diff --git a/src/pPowerManger/udpComm.cpp b/src/pPowerManger/udpComm.cpp index fdc28e3..398de47 100644 --- a/src/pPowerManger/udpComm.cpp +++ b/src/pPowerManger/udpComm.cpp @@ -112,12 +112,12 @@ bool udpComm::getMsgFromBuff(char *m, msg_disHighAVolBusFbMsg &s) s = *p; return true; } -bool udpComm::getMsgFromBuff(char *m, msg_disHighBVolBusFbMsg &s) +bool udpComm::getMsgFromBuff(char *m, msg_disLowMainBusFbMsg &s) { cChecksum sum; - msg_disHighBVolBusFbMsg *p; - p = reinterpret_cast(m); - sum = calculateChecksum((unsigned char*)m, sizeof(msg_disHighBVolBusFbMsg), sizeof(cChecksum)) & 0xFF; + msg_disLowMainBusFbMsg *p; + p = reinterpret_cast(m); + sum = calculateChecksum((unsigned char*)m, sizeof(msg_disLowMainBusFbMsg), sizeof(cChecksum)) & 0xFF; if (sum!= p->checkCode) { sError.push_back("DisSys HVBBus Msg Check error"); return false; @@ -252,7 +252,7 @@ bool udpComm::pushMsgToQueue(unsigned char *m) } case DIS_HVBUSB_FB_ID: //DIS_HVBUSB_FB 0x0007 { - msg_disHighBVolBusFbMsg s; + msg_disLowMainBusFbMsg s; if(getMsgFromBuff((char *)Buff,s)) { if(m_qReceiveDisHighBVolBusBuffer.size()> m_qReceiveCcuSetParmBuffer; std::queue> m_qReceiveDisHighVolBusBuffer; std::queue> m_qReceiveDisHighAVolBusBuffer; - std::queue> m_qReceiveDisHighBVolBusBuffer; + std::queue> m_qReceiveDisHighBVolBusBuffer; std::queue> m_qReceiveDisLowBusBuffer; private: diff --git a/test/disSysTest/PowerManagerApp.py b/test/disSysTest/PowerManagerApp.py new file mode 100644 index 0000000..510e121 --- /dev/null +++ b/test/disSysTest/PowerManagerApp.py @@ -0,0 +1,1072 @@ +import tkinter as tk +from tkinter import ttk +import socket +import threading +import time +from db import DB +from udpMsg import ( + msg_disHighVolBusFbMsg, + msg_disHighAVolBusFbMsg, + msg_disLowMainBusFbMsg, + msg_disLowBusFbMsg, + msg_disHVBCmdMsg, + msg_disHVBACmdMsg, + msg_disLVMBCmdMsg, + msg_disLVBCmdMsg +) + +class PowerManagerApp: + def __init__(self, root): + self.root = root + + # 解决字体模糊问题 + style = ttk.Style() + style.configure('.', font=('Microsoft YaHei', 10)) + + self.root.title("电源管理系统") + self.root.geometry("1200x800") + self.root.tk.call('tk', 'scaling', 1.5) # 适配高DPI显示 + + # UDP通信配置 + self.udp_ip = "127.0.0.1" + self.udp_port = 5000 + self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + self.sock.bind((self.udp_ip, self.udp_port)) + + # 数据库配置 + self.db = DB('/home/zjk/project/H100/H100PowerManger/test/disSysTest/test.db') + self.db.connect() + + # 状态数据 - 完全匹配udpMsg.py中的定义 + self.status_data = { + "high_vol_bus": { + "breakers": { + "燃料电池断路器": 0, + "动力锂电池断路器": 0, + "推进电机断路器": 0, + "锂电池组仪表断路器": 0, + "DC/DC模块断路器": 0, + "艏高压配电盒断路器": 0, + "艉FT设备45断路器": 0, + "艉舵机开关1断路器": 0, + "艉舵机开关2断路器": 0, + "FB备用断路器": 0, + "TYZ备用断路器": 0, + "备用断路器": 0 + }, + "faults": { + "DC/DC故障1": 0, + "DC/DC故障2": 0 + }, + "insulation": { + "动力母线绝缘状态": 0, + "A母线绝缘状态": 0 + }, + "alarms": { + "仪表电源丢失信号": 0, + "应急电源丢失信号": 0 + }, + "voltage": { + "动力母线电压": 0.0, + "A母线电压": 0.0 + }, + "current": { + "动力母线电流": 0.0, + "DC/DC5模块电流": 0.0, + "推进电机控制箱电流": 0.0, + "A母线电流": 0.0, + "锂电池组仪表电流": 0.0, + "艏高压配电盒电流": 0.0, + "艉FT设备45电流": 0.0, + "TYZ备用开关电流": 0.0, + "艉舵机开关1电流": 0.0, + "备用电流1": 0.0, + "艉舵机开关2电流": 0.0, + "备用电流2": 0.0, + "FB备用开关电流": 0.0, + "备用电流3": 0.0 + }, + "cool_water_pressure": 0.0 + }, + "high_a_vol_bus": { + "breakers": { + "艏FT设备123断路器": 0, + "执行机构断路器": 0, + "桅舵机控制箱断路器": 0, + "XCZ断路器": 0, + "艏舵控制箱断路器": 0, + "开盖启动气缸断路器": 0 + }, + "alarms": { + "仪表电源故障": 0, + "应急电源故障": 0, + "进水报警": 0 + }, + "voltage": { + "B母线电压": 0.0 + }, + "current": { + "B母线电流": 0.0, + "艏FT设备123电流": 0.0, + "执行机构电流": 0.0, + "桅舵机控制箱电流": 0.0, + "XCZ电流": 0.0, + "艏舵控制箱电流": 0.0, + "开盖启动气缸电流": 0.0 + } + }, + "low_main_bus": { + "breakers": { + "锂电池组仪表断路器": 0, + "艏低压配电盒断路器": 0, + "单元4仪表48V断路器": 0, + "DC/C1直流配电板断路器": 0, + "备用断路器1": 0, + "备用断路器2": 0, + "应急锂电池组2断路器": 0 + }, + "alarms": { + "仪表电源故障": 0, + "应急电源故障": 0 + }, + "insulation": 0, + "voltage": { + "仪表母线电压": 0.0, + "应急2母线电压": 0.0 + }, + "current": { + "艏低压配电盒电流": 0.0, + "DC/C1仪表48V电流": 0.0, + "备用电流1": 0.0, + "应急锂电池组2电流": 0.0, + "锂电池组仪表电流": 0.0, + "单元4仪表48V电流": 0.0, + "备用电流2": 0.0, + "综合能量管理系统应急DC48V电流": 0.0, + "燃料电池安全系统应急DC48V电流": 0.0, + "PLC控制电源电流": 0.0 + } + }, + "low_bus": { + "breakers": { + "单元1断路器": 0, + "单元2断路器": 0, + "单元3断路器": 0, + "单元5断路器": 0, + "艏PZ设备断路器": 0, + "备用断路器1": 0, + "备用断路器2": 0, + "应急锂电池组1断路器": 0 + }, + "alarms": { + "电源故障信号": 0, + "进水报警": 0 + }, + "voltage": { + "仪表母线电压": 0.0, + "应急1母线电压": 0.0 + }, + "current": { + "仪表母线电流": 0.0, + "单元1电流": 0.0, + "单元2电流": 0.0, + "单元3电流": 0.0, + "单元5电流": 0.0, + "艏PZ设备电流": 0.0, + "应急锂电池组1电流": 0.0 + } + } + } + + # 初始化界面 + self.setup_ui() + + # 启动UDP接收线程 + self.running = True + self.recv_thread = threading.Thread(target=self.udp_receive_loop) + self.recv_thread.daemon = True + self.recv_thread.start() + + # 启动状态更新定时器 + self.update_ui() + + def setup_ui(self): + """初始化用户界面""" + # 主框架 + main_frame = ttk.Frame(self.root, padding="10") + main_frame.pack(fill=tk.BOTH, expand=True) + + # 状态显示区 + status_frame = ttk.LabelFrame(main_frame, text="系统状态", padding="10") + status_frame.pack(fill=tk.X, pady=5) + + # 状态显示区 - 使用Notebook组织不同母线状态 + self.notebook = ttk.Notebook(status_frame) + self.notebook.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) + + # 高压母线状态页 + high_vol_frame = ttk.Frame(self.notebook) + self.notebook.add(high_vol_frame, text="高压母线") + self.setup_high_vol_ui(high_vol_frame) + + # 高压A母线状态页 + high_a_vol_frame = ttk.Frame(self.notebook) + self.notebook.add(high_a_vol_frame, text="高压A母线") + self.setup_high_a_vol_ui(high_a_vol_frame) + + # 仪表主母线状态页 + low_main_frame = ttk.Frame(self.notebook) + self.notebook.add(low_main_frame, text="仪表主母线") + self.setup_low_main_ui(low_main_frame) + + # 仪表母线状态页 + low_bus_frame = ttk.Frame(self.notebook) + self.notebook.add(low_bus_frame, text="仪表母线") + self.setup_low_bus_ui(low_bus_frame) + + # 控制区 + control_frame = ttk.LabelFrame(main_frame, text="控制面板", padding="10") + control_frame.pack(fill=tk.BOTH, expand=True, pady=5) + + # 状态显示区 - 使用Notebook组织不同母线状态 + self.notebook_c = ttk.Notebook(control_frame) + self.notebook_c.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) + + high_vol_control_frame = ttk.Frame(self.notebook_c) + self.notebook_c.add(high_vol_control_frame, text="高压母线") + self.setup_hvb_control(high_vol_control_frame) + + high_a_vol_control_frame = ttk.Frame(self.notebook_c) + self.notebook_c.add(high_a_vol_control_frame, text="高压A母线") + self.setup_hvba_control(high_a_vol_control_frame) + + low_main_control_frame = ttk.Frame(self.notebook_c) + self.notebook_c.add(low_main_control_frame, text="仪表主母线") + self.setup_lvmb_control(low_main_control_frame) + + low_bus_control_frame = ttk.Frame(self.notebook_c) + self.notebook_c.add(low_bus_control_frame, text="仪表母线") + self.setup_lvb_control(low_bus_control_frame) + + # 日志区 + log_frame = ttk.LabelFrame(main_frame, text="系统日志", padding="10") + log_frame.pack(fill=tk.BOTH, expand=True, pady=5) + + self.log_text = tk.Text(log_frame, height=10, state=tk.DISABLED) + self.log_text.pack(fill=tk.BOTH, expand=True) + + scrollbar = ttk.Scrollbar(log_frame, orient=tk.VERTICAL, command=self.log_text.yview) + scrollbar.pack(side=tk.RIGHT, fill=tk.Y) + self.log_text.config(yscrollcommand=scrollbar.set) + + def setup_hvb_control(self, parent): + """设置动力母线配电指令控制面板""" + frame = ttk.LabelFrame(parent, text="动力母线配电指令", padding="10") + frame.pack(fill=tk.X, pady=5) + + # 断路器控制按钮 + breaker_names = [ + "燃料电池断路器", "动力锂电池断路器", "推进电机断路器", + "锂电池组仪表断路器", "DC/DC模块断路器", "艏高压配电盒断路器", + "艉FT设备45断路器", "艉舵机开关1断路器", "艉舵机开关2断路器", + "FB备用断路器", "TYZ备用断路器", "备用断路器", "DC/DC模块启动","冷却系统启动" + ] + + for i, name in enumerate(breaker_names): + row = i // 3 + col = i % 3 + btn_frame = ttk.Frame(frame) + btn_frame.grid(row=row, column=col, padx=5, pady=2, sticky=tk.W) + + ttk.Label(btn_frame, text=name).pack(side=tk.LEFT) + on_btn = ttk.Button(btn_frame, text="合", width=3, + command=lambda n=name: self.send_hvb_cmd(n, 0x55)) + on_btn.pack(side=tk.LEFT, padx=2) + off_btn = ttk.Button(btn_frame, text="分", width=3, + command=lambda n=name: self.send_hvb_cmd(n, 0xAA)) + off_btn.pack(side=tk.LEFT, padx=2) + + def setup_hvba_control(self, parent): + """设置动力汇流排A配电指令控制面板""" + frame = ttk.LabelFrame(parent, text="动力汇流排A配电指令", padding="10") + frame.pack(fill=tk.X, pady=5) + + # 断路器控制按钮 + breaker_names = [ + "艏FT设备123断路器", "执行机构断路器", "桅舵机控制箱断路器", + "XCZ断路器", "艏舵控制箱断路器", "开盖启动气缸断路器" + ] + + for i, name in enumerate(breaker_names): + row = i // 3 + col = i % 3 + btn_frame = ttk.Frame(frame) + btn_frame.grid(row=row, column=col, padx=5, pady=2, sticky=tk.W) + + ttk.Label(btn_frame, text=name).pack(side=tk.LEFT) + on_btn = ttk.Button(btn_frame, text="合", width=3, + command=lambda n=name: self.send_hvba_cmd(n, 1)) + on_btn.pack(side=tk.LEFT, padx=2) + off_btn = ttk.Button(btn_frame, text="分", width=3, + command=lambda n=name: self.send_hvba_cmd(n, 0)) + off_btn.pack(side=tk.LEFT, padx=2) + + def setup_lvmb_control(self, parent): + """设置仪表母线配电指令控制面板""" + frame = ttk.LabelFrame(parent, text="仪表母线配电指令", padding="10") + frame.pack(fill=tk.X, pady=5) + + # 断路器控制按钮 + breaker_names = [ + "锂电池组仪表断路器", "艏低压配电盒断路器", "单元4仪表48V断路器", + "DC/C1直流配电板断路器", "备用断路器1", "备用断路器2", + "应急锂电池组2断路器" + ] + + for i, name in enumerate(breaker_names): + row = i // 3 + col = i % 3 + btn_frame = ttk.Frame(frame) + btn_frame.grid(row=row, column=col, padx=5, pady=2, sticky=tk.W) + + ttk.Label(btn_frame, text=name).pack(side=tk.LEFT) + on_btn = ttk.Button(btn_frame, text="合", width=3, + command=lambda n=name: self.send_lvmb_cmd(n, 0x55)) + on_btn.pack(side=tk.LEFT, padx=2) + off_btn = ttk.Button(btn_frame, text="分", width=3, + command=lambda n=name: self.send_lvmb_cmd(n, 0xaa)) + off_btn.pack(side=tk.LEFT, padx=2) + + def setup_lvb_control(self, parent): + """设置仪表汇流排配电指令控制面板""" + frame = ttk.LabelFrame(parent, text="仪表汇流排配电指令", padding="10") + frame.pack(fill=tk.X, pady=5) + + # 断路器控制按钮 + breaker_names = [ + "单元1断路器", "单元2断路器", "单元3断路器", + "单元5断路器", "艏PZ设备断路器", "备用断路器1", + "备用断路器2", "应急锂电池组1断路器" + ] + + for i, name in enumerate(breaker_names): + row = i // 3 + col = i % 3 + btn_frame = ttk.Frame(frame) + btn_frame.grid(row=row, column=col, padx=5, pady=2, sticky=tk.W) + + ttk.Label(btn_frame, text=name).pack(side=tk.LEFT) + on_btn = ttk.Button(btn_frame, text="合", width=3, + command=lambda n=name: self.send_lvb_cmd(n, 0x55)) + on_btn.pack(side=tk.LEFT, padx=2) + off_btn = ttk.Button(btn_frame, text="分", width=3, + command=lambda n=name: self.send_lvb_cmd(n, 0xaa)) + off_btn.pack(side=tk.LEFT, padx=2) + + def send_hvb_cmd(self, breaker_name, state): + """发送动力母线配电指令""" + cmd = msg_disHVBCmdMsg() + if breaker_name == "燃料电池断路器": + cmd.fuelCellCircuitBreaker = state + elif breaker_name == "动力锂电池断路器": + cmd.powerLithiumBatteryCircuitBreaker = state + elif breaker_name == "推进电机断路器": + cmd.propulsionMotorCircuitBreaker = state + elif breaker_name == "锂电池组仪表断路器": + cmd.lithiumBatteryGroupInstrumentCircuitBreaker = state + elif breaker_name == "DC/DC模块断路器": + cmd.dcDc5ModuleCircuitBreaker = state + elif breaker_name == "艏高压配电盒断路器": + cmd.bowHighVoltageDistributionBoxCircuitBreaker = state + elif breaker_name == "艉FT设备45断路器": + cmd.sternFTDevice45CircuitBreaker = state + elif breaker_name == "艉舵机开关1断路器": + cmd.sternRudderSwitch1CircuitBreaker = state + elif breaker_name == "艉舵机开关2断路器": + cmd.sternRudderSwitch2CircuitBreaker = state + elif breaker_name == "FB备用断路器": + cmd.fbReservedCircuitBreaker = state + elif breaker_name == "TYZ备用断路器": + cmd.tyzReservedCircuitBreaker = state + elif breaker_name == "备用断路器": + cmd.reservedCircuitBreaker = state + elif breaker_name == "DC/DC模块启动": + cmd.dcDcModuleStart = state + elif breaker_name == "冷却系统启动": + cmd.coolingSystemStart = state + + self.send_udp_command(cmd.pack()) + self.db.insertHighVolBusCmd(cmd) + self.log_message(f"发送动力母线配电指令: {breaker_name} {'合' if state else '分'}") + + def send_hvba_cmd(self, breaker_name, state): + """发送动力汇流排A配电指令""" + cmd = msg_disHVBACmdMsg() + + if breaker_name == "艏FT设备123断路器": + cmd.bowFTDevice123CircuitBreaker = state + elif breaker_name == "执行机构断路器": + cmd.actuatorCircuitBreaker = state + elif breaker_name == "桅舵机控制箱断路器": + cmd.mastSteeringGearControlBoxCircuitBreaker = state + elif breaker_name == "XCZ断路器": + cmd.xczCircuitBreaker = state + elif breaker_name == "艏舵控制箱断路器": + cmd.bowRudderControlBoxCircuitBreaker = state + elif breaker_name == "开盖启动气缸断路器": + cmd.openWaterCoverStartCylinderCircuitBreaker = state + + self.send_udp_command(cmd.pack()) + self.db.insertHighAVolBusCmd(cmd) + self.log_message(f"发送动力汇流排A配电指令: {breaker_name} {'合' if state else '分'}") + + def send_lvmb_cmd(self, breaker_name, state): + """发送仪表母线配电指令""" + cmd = msg_disLVMBCmdMsg() + if breaker_name == "锂电池组仪表断路器": + cmd.lithiumBatteryGroupInstrumentCircuitBreaker = state + elif breaker_name == "艏低压配电盒断路器": + cmd.bowLowVoltageDistributionBoxCircuitBreaker = state + elif breaker_name == "单元4仪表48V断路器": + cmd.unit4InstrumentDC48VCircuitBreaker = state + elif breaker_name == "DC/C1直流配电板断路器": + cmd.dcC1DCDistributionPanelCircuitBreaker = state + elif breaker_name == "备用断路器1": + cmd.reservedCircuitBreaker1 = state + elif breaker_name == "备用断路器2": + cmd.reservedCircuitBreaker2 = state + elif breaker_name == "应急锂电池组2断路器": + cmd.emergencyLithiumBatteryGroup2CircuitBreaker = state + + self.send_udp_command(cmd.pack()) + self.db.insertLowMainBusCmd(cmd) + self.log_message(f"发送仪表母线配电指令: {breaker_name} {'合' if state else '分'}") + + def send_lvb_cmd(self, breaker_name, state): + """发送仪表汇流排配电指令""" + cmd = msg_disLVBCmdMsg() + if breaker_name == "单元1断路器": + cmd.unit1CircuitBreaker = state + elif breaker_name == "单元2断路器": + cmd.unit2CircuitBreaker = state + elif breaker_name == "单元3断路器": + cmd.unit3CircuitBreaker = state + elif breaker_name == "单元5断路器": + cmd.unit5CircuitBreaker = state + elif breaker_name == "艏PZ设备断路器": + cmd.bowPZDeviceCircuitBreaker = state + elif breaker_name == "备用断路器1": + cmd.reservedCircuitBreaker1 = state + elif breaker_name == "备用断路器2": + cmd.reservedCircuitBreaker2 = state + elif breaker_name == "应急锂电池组1断路器": + cmd.emergencyLithiumBatteryGroup1CircuitBreaker = state + + self.send_udp_command(cmd.pack()) + self.db.insertLowBusCmd(cmd) + self.log_message(f"发送仪表汇流排配电指令: {breaker_name} {'合' if state else '分'}") + + def udp_receive_loop(self): + """UDP接收消息循环""" + while self.running: + print('接收中') + try: + data, addr = self.sock.recvfrom(1024) + self.process_udp_message(data) + print('接收成功') + except Exception as e: + self.log_message(f"接收错误: {str(e)}") + + def setup_high_vol_ui(self, parent): + """设置高压母线状态界面""" + # 初始化故障位列表 + self.high_vol_dcdc_fault1_bits = [] + self.high_vol_dcdc_fault2_bits = [] + + frame = ttk.LabelFrame(parent, text="高压母线状态") + frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) + + # 使用网格布局管理器 + frame.grid_columnconfigure(0, weight=1) + frame.grid_columnconfigure(1, weight=1) + frame.grid_columnconfigure(2, weight=1) + + # 电压显示 + ttk.Label(frame, text="动力母线电压(V):").grid(row=0, column=0, sticky=tk.W) + self.high_vol_power_voltage = ttk.Label(frame, text="0.0") + self.high_vol_power_voltage.grid(row=0, column=1, sticky=tk.W) + + ttk.Label(frame, text="A母线电压(V):").grid(row=0, column=2, sticky=tk.W) + self.high_vol_a_voltage = ttk.Label(frame, text="0.0") + self.high_vol_a_voltage.grid(row=0, column=3, sticky=tk.W) + + # 电流显示 + ttk.Label(frame, text="动力母线电流(A):").grid(row=1, column=0, sticky=tk.W) + self.high_vol_power_current = ttk.Label(frame, text="0.0") + self.high_vol_power_current.grid(row=1, column=1, sticky=tk.W) + + ttk.Label(frame, text="A母线电流(A):").grid(row=1, column=2, sticky=tk.W) + self.high_vol_a_current = ttk.Label(frame, text="0.0") + self.high_vol_a_current.grid(row=1, column=3, sticky=tk.W) + + # 断路器状态 + ttk.Label(frame, text="断路器状态:").grid(row=2, column=0, columnspan=4, sticky=tk.W) + self.high_vol_breakers = {} + breaker_names = list(self.status_data["high_vol_bus"]["breakers"].keys()) + + for i, name in enumerate(breaker_names): + ttk.Label(frame, text=name).grid(row=3+i//3, column=(i%3)*2, sticky=tk.W) + canvas = tk.Canvas(frame, width=20, height=20, bg="white") + canvas.grid(row=3+i//3, column=(i%3)*2+1, sticky=tk.W) + self.high_vol_breakers[name] = canvas + + # 绝缘状态 + ttk.Label(frame, text="动力母线绝缘:").grid(row=9, column=0, sticky=tk.W) + self.high_vol_power_insulation = ttk.Label(frame, text="正常") + self.high_vol_power_insulation.grid(row=9, column=1, sticky=tk.W) + + ttk.Label(frame, text="A母线绝缘:").grid(row=9, column=2, sticky=tk.W) + self.high_vol_a_insulation = ttk.Label(frame, text="正常") + self.high_vol_a_insulation.grid(row=9, column=3, sticky=tk.W) + + # 故障状态 - 扩展显示所有故障位 + fault_labels1 = ["过温关机", "输出过流", "输出过压", "输出欠压", "输入过压", "输入欠压", "输出短路保护", "内部故障"] + fault_labels2 = ["通信故障", "工作状态", "冷却泵1故障", "冷却泵2故障", "冷却水泄漏", "保留", "保留", "保留"] + + ttk.Label(frame, text="DC/DC故障字1:").grid(row=10, column=0, sticky=tk.W) + for i, label in enumerate(fault_labels1): + ttk.Label(frame, text=label).grid(row=11+i//4, column=(i%4)*2, sticky=tk.W) + canvas = tk.Canvas(frame, width=20, height=20, bg="white") + canvas.grid(row=11+i//4, column=(i%4)*2+1, sticky=tk.W) + self.high_vol_dcdc_fault1_bits.append(canvas) + + ttk.Label(frame, text="DC/DC故障字2:").grid(row=13, column=0, sticky=tk.W) + for i, label in enumerate(fault_labels2): + ttk.Label(frame, text=label).grid(row=14+i//4, column=(i%4)*2, sticky=tk.W) + canvas = tk.Canvas(frame, width=20, height=20, bg="white") + canvas.grid(row=14+i//4, column=(i%4)*2+1, sticky=tk.W) + self.high_vol_dcdc_fault2_bits.append(canvas) + + # 绝缘状态 - 详细显示 + ttk.Label(frame, text="动力母线绝缘:").grid(row=16, column=0, sticky=tk.W) + self.high_vol_power_insulation = ttk.Label(frame, text="正常(0.0MΩ)") + self.high_vol_power_insulation.grid(row=16, column=1, sticky=tk.W) + + ttk.Label(frame, text="A母线绝缘:").grid(row=16, column=2, sticky=tk.W) + self.high_vol_a_insulation = ttk.Label(frame, text="正常(0.0MΩ)") + self.high_vol_a_insulation.grid(row=16, column=3, sticky=tk.W) + + # 电流值显示 + current_labels = [ + ("动力母线电流(A):", "powerBusCurrent"), + ("A母线电流(A):", "busbarACurrent"), + ("DC/DC5模块电流(A):", "dcDc5ModuleCurrent"), + ("推进电机控制箱电流(A):", "propulsionMotorControlBoxCurrent"), + ("锂电池组表电流(A):", "lithiumBatteryGroupMeterCurrent"), + ("艏高压配电箱电流(A):", "bowHighVoltageDistributionBoxCurrent"), + ("艉FT设备45电流(A):", "sternFTDevice45Current"), + ("TYZ备用开关电流(A):", "tyzReservedSwitchCurrent"), + ("艉舵机开关1电流(A):", "sternRudderSwitch1Current"), + ("艉舵机开关2电流(A):", "sternRudderSwitch2Current"), + ("FB备用开关电流(A):", "fbReservedSwitchCurrent") + ] + + for i, (label, _) in enumerate(current_labels): + ttk.Label(frame, text=label).grid(row=17+i//2, column=(i%2)*2, sticky=tk.W) + label_var = ttk.Label(frame, text="0.0") + label_var.grid(row=17+i//2, column=(i%2)*2+1, sticky=tk.W) + setattr(self, f"high_vol_{current_labels[i][1]}", label_var) + + # 冷却水压力 + ttk.Label(frame, text="冷却水压力(MPa):").grid(row=23, column=0, sticky=tk.W) + self.high_vol_cool_water_pressure = ttk.Label(frame, text="0.00") + self.high_vol_cool_water_pressure.grid(row=23, column=1, sticky=tk.W) + + def setup_high_a_vol_ui(self, parent): + """设置高压A母线状态界面""" + frame = ttk.LabelFrame(parent, text="高压A母线状态") + frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) + + # 使用网格布局管理器 + frame.grid_columnconfigure(0, weight=1) + frame.grid_columnconfigure(1, weight=1) + frame.grid_columnconfigure(2, weight=1) + + # 电压显示 - 添加详细说明 + ttk.Label(frame, text="高压B母线电压(V):").grid(row=0, column=0, sticky=tk.W) + self.high_a_vol_voltage = ttk.Label(frame, text="0.0") + self.high_a_vol_voltage.grid(row=0, column=1, sticky=tk.W) + + # 电流显示 - 统一格式 + ttk.Label(frame, text="高压B母线电流(A):").grid(row=1, column=0, sticky=tk.W) + self.high_a_vol_current = ttk.Label(frame, text="0.0") + self.high_a_vol_current.grid(row=1, column=1, sticky=tk.W) + + ttk.Label(frame, text="艏部FT设备123电流(A):").grid(row=2, column=0, sticky=tk.W) + self.high_a_vol_bow_ft_current = ttk.Label(frame, text="0.0") + self.high_a_vol_bow_ft_current.grid(row=2, column=1, sticky=tk.W) + + ttk.Label(frame, text="执行机构工作电流(A):").grid(row=3, column=0, sticky=tk.W) + self.high_a_vol_actuator_current = ttk.Label(frame, text="0.0") + self.high_a_vol_actuator_current.grid(row=3, column=1, sticky=tk.W) + + # 断路器状态 - 添加详细说明 + ttk.Label(frame, text="高压A母线断路器状态:").grid(row=4, column=0, columnspan=4, sticky=tk.W) + self.high_a_vol_breakers = {} + breaker_names = list(self.status_data["high_a_vol_bus"]["breakers"].keys()) + + for i, name in enumerate(breaker_names): + ttk.Label(frame, text=f"{name}状态:").grid(row=5+i//2, column=(i%2)*2, sticky=tk.W) + canvas = tk.Canvas(frame, width=20, height=20, bg="white") + canvas.grid(row=5+i//2, column=(i%2)*2+1, sticky=tk.W) + self.high_a_vol_breakers[name] = canvas + + # 报警状态 - 更详细描述 + ttk.Label(frame, text="仪表电源故障状态:").grid(row=8, column=0, sticky=tk.W) + self.high_a_vol_instrument_power_fault = ttk.Label(frame, text="正常") + self.high_a_vol_instrument_power_fault.grid(row=8, column=1, sticky=tk.W) + + ttk.Label(frame, text="应急电源故障状态:").grid(row=8, column=2, sticky=tk.W) + self.high_a_vol_emergency_power_fault = ttk.Label(frame, text="正常") + self.high_a_vol_emergency_power_fault.grid(row=8, column=3, sticky=tk.W) + + ttk.Label(frame, text="进水报警:").grid(row=9, column=0, sticky=tk.W) + self.high_a_vol_water_alarm = ttk.Label(frame, text="无") + self.high_a_vol_water_alarm.grid(row=9, column=1, sticky=tk.W) + + def process_udp_message(self, data): + """处理接收到的UDP消息""" + try: + msg_id = int.from_bytes(data[2:4], byteorder='little') + + if msg_id == 0x0005: # 高压母线状态 + msg = msg_disHighVolBusFbMsg() + if msg.unpack(data): + self.db.insertHighVolBusData(msg) + # self.update_high_vol_ui(bus) + bus = self.status_data["high_vol_bus"] + bus["voltage"]["动力母线电压"] = msg.powerBusVoltage / 10.0 + bus["voltage"]["A母线电压"] = msg.busbarAVoltage / 10.0 + bus["current"]["动力母线电流"] = msg.powerBusCurrent / 10.0 + bus["current"]["DC/DC5模块电流"] = msg.dcDc5ModuleCurrent / 10.0 + bus["current"]["推进电机控制箱电流"] = msg.propulsionMotorControlBoxCurrent / 10.0 + bus["current"]["A母线电流"] = msg.busbarACurrent / 10.0 + bus["current"]["锂电池组仪表电流"] = msg.lithiumBatteryGroupMeterCurrent / 10.0 + bus["current"]["艏高压配电盒电流"] = msg.bowHighVoltageDistributionBoxCurrent / 10.0 + bus["current"]["艉FT设备45电流"] = msg.sternFTDevice45Current / 10.0 + bus["current"]["TYZ备用开关电流"] = msg.tyzReservedSwitchCurrent / 10.0 + bus["current"]["艉舵机开关1电流"] = msg.sternRudderSwitch1Current / 10.0 + bus["current"]["备用电流1"] = msg.reservedCurrent1 / 10.0 + bus["current"]["艉舵机开关2电流"] = msg.sternRudderSwitch2Current / 10.0 + bus["current"]["备用电流2"] = msg.reservedCurrent2 / 10.0 + bus["current"]["FB备用开关电流"] = msg.fbReservedSwitchCurrent / 10.0 + bus["current"]["备用电流3"] = msg.reservedCurrent3 / 10.0 + + bus["breakers"]["燃料电池断路器"] = msg.fuelCellCircuitBreaker + bus["breakers"]["动力锂电池断路器"] = msg.powerLithiumBatteryCircuitBreaker + bus["breakers"]["推进电机断路器"] = msg.propulsionMotorCircuitBreaker + bus["breakers"]["锂电池组仪表断路器"] = msg.lithiumBatteryGroupInstrumentCircuitBreaker + bus["breakers"]["DC/DC模块断路器"] = msg.dcDc5ModuleCircuitBreaker + bus["breakers"]["艏高压配电盒断路器"] = msg.bowHighVoltageDistributionBoxCircuitBreaker + bus["breakers"]["艉FT设备45断路器"] = msg.sternFTDevice45CircuitBreaker + bus["breakers"]["艉舵机开关1断路器"] = msg.sternRudderSwitch1CircuitBreaker + bus["breakers"]["艉舵机开关2断路器"] = msg.sternRudderSwitch2CircuitBreaker + bus["breakers"]["FB备用断路器"] = msg.fbReservedCircuitBreaker + bus["breakers"]["TYZ备用断路器"] = msg.tyzReservedCircuitBreaker + bus["breakers"]["备用断路器"] = msg.reservedCircuitBreaker + + bus["faults"]["DC/DC故障1"] = msg.dcDcFaultWord1 + bus["faults"]["DC/DC故障2"] = msg.dcDcFaultWord2 + bus["insulation"]["动力母线绝缘状态"] = msg.powerBusInsulationStatus + bus["insulation"]["A母线绝缘状态"] = msg.aBusInsulationStatus + bus["alarms"]["仪表电源丢失信号"] = msg.meterPowerLossSignal + bus["alarms"]["应急电源丢失信号"] = msg.emergencyPowerLossSignal + bus["cool_water_pressure"] = msg.coolWaterPressure / 10.0 + + self.status_data["high_vol_bus"] = bus + # 更新UI显示 + print(self.status_data) + + self.log_message("收到高压母线状态更新") + elif msg_id == 0x0006: # 高压A母线状态 + msg = msg_disHighAVolBusFbMsg() + if msg.unpack(data): + self.db.insertHighAVolBusData(msg) + bus = self.status_data["high_a_vol_bus"] + bus["voltage"]["B母线电压"] = msg.busbarBVoltage / 10.0 + bus["current"]["B母线电流"] = msg.busbarBCurrent / 10.0 + bus["current"]["艏FT设备123电流"] = msg.bowFTDevice123Current / 10.0 + bus["current"]["执行机构电流"] = msg.actuatorCurrent / 10.0 + bus["current"]["桅舵机控制箱电流"] = msg.mastSteeringGearControlBoxCurrent / 10.0 + bus["current"]["XCZ电流"] = msg.xczCurrent / 10.0 + bus["current"]["艏舵控制箱电流"] = msg.bowRudderControlBoxCurrent / 10.0 + bus["current"]["开盖启动气缸电流"] = msg.openWaterCoverStartCylinderCurrent / 10.0 + + bus["breakers"]["艏FT设备123断路器"] = msg.bowFTDevice123CircuitBreaker + bus["breakers"]["执行机构断路器"] = msg.actuatorCircuitBreaker + bus["breakers"]["桅舵机控制箱断路器"] = msg.mastSteeringGearControlBoxCircuitBreaker + bus["breakers"]["XCZ断路器"] = msg.xczCircuitBreaker + bus["breakers"]["艏舵控制箱断路器"] = msg.bowRudderControlBoxCircuitBreaker + bus["breakers"]["开盖启动气缸断路器"] = msg.openWaterCoverStartCylinderCircuitBreaker + + bus["alarms"]["仪表电源故障"] = msg.instrumentPowerFailureSignal + bus["alarms"]["应急电源故障"] = msg.emergencyPowerFailureSignal + bus["alarms"]["进水报警"] = msg.waterIngressionAlarm + + self.log_message("收到高压A母线状态更新") + elif msg_id == 0x0007: # 仪表主母线状态 + msg = msg_disLowMainBusFbMsg() + if msg.unpack(data): + self.db.insertLowMainBusData(msg) + bus = self.status_data["low_main_bus"] + bus["voltage"]["仪表母线电压"] = msg.instrumentBusbarVoltage / 10.0 + bus["voltage"]["应急2母线电压"] = msg.emergency2BusbarVoltage / 10.0 + bus["current"]["艏低压配电盒电流"] = msg.bowLowVoltageDistributionBoxCurrent / 10.0 + bus["current"]["DC/C1仪表48V电流"] = msg.dcC1InstrumentDC48VCurrent / 10.0 + bus["current"]["备用电流1"] = msg.reservedCurrent1 / 10.0 + bus["current"]["应急锂电池组2电流"] = msg.emergencyLithiumBatteryGroup2Current / 10.0 + bus["current"]["锂电池组仪表电流"] = msg.lithiumBatteryGroupInstrumentCurrent / 10.0 + bus["current"]["单元4仪表48V电流"] = msg.unit4InstrumentDC48VCurrent / 10.0 + bus["current"]["备用电流2"] = msg.reservedCurrent2 / 10.0 + bus["current"]["综合能量管理系统应急DC48V电流"] = msg.compositeEnergyManagementSystemEmergencyDC48VCurrent / 10.0 + bus["current"]["燃料电池安全系统应急DC48V电流"] = msg.fuelCellSecuritySystemEmergencyDC48VCurrent / 10.0 + bus["current"]["PLC控制电源电流"] = msg.plcControlPowerCurrent / 10.0 + + bus["breakers"]["锂电池组仪表断路器"] = msg.lithiumBatteryGroupInstrumentCircuitBreaker + bus["breakers"]["艏低压配电盒断路器"] = msg.bowLowVoltageDistributionBoxCircuitBreaker + bus["breakers"]["单元4仪表48V断路器"] = msg.unit4InstrumentDC48VCircuitBreaker + bus["breakers"]["DC/C1直流配电板断路器"] = msg.dcC1DCDistributionPanelCircuitBreaker + bus["breakers"]["备用断路器1"] = msg.reservedCircuitBreaker1 + bus["breakers"]["备用断路器2"] = msg.reservedCircuitBreaker2 + bus["breakers"]["应急锂电池组2断路器"] = msg.emergencyLithiumBatteryGroup2CircuitBreaker + + bus["alarms"]["仪表电源故障"] = msg.instrumentPowerFailureSignal + bus["alarms"]["应急电源故障"] = msg.emergencyPowerFailureSignal + bus["insulation"] = msg.instrumentBusbarInsulationLow + + self.log_message("收到仪表主母线状态更新") + + elif msg_id == 0x0008: # 仪表母线状态 + msg = msg_disLowBusFbMsg() + if msg.unpack(data): + self.db.insertLowBusData(msg) + bus = self.status_data["low_bus"] + bus["voltage"]["仪表母线电压"] = msg.instrumentBusbarVoltage / 10.0 + bus["voltage"]["应急1母线电压"] = msg.emergency1BusbarVoltage / 10.0 + bus["current"]["仪表母线电流"] = msg.instrumentBusbarCurrent / 10.0 + bus["current"]["单元1电流"] = msg.unit1Current / 10.0 + bus["current"]["单元2电流"] = msg.unit2Current / 10.0 + bus["current"]["单元3电流"] = msg.unit3Current / 10.0 + bus["current"]["单元5电流"] = msg.unit5Current / 10.0 + bus["current"]["艏PZ设备电流"] = msg.bowPZDeviceCurrent / 10.0 + bus["current"]["应急锂电池组1电流"] = msg.emergencyLithiumBatteryGroup1Current / 10.0 + + bus["breakers"]["单元1断路器"] = msg.unit1CircuitBreaker + bus["breakers"]["单元2断路器"] = msg.unit2CircuitBreaker + bus["breakers"]["单元3断路器"] = msg.unit3CircuitBreaker + bus["breakers"]["单元5断路器"] = msg.unit5CircuitBreaker + bus["breakers"]["艏PZ设备断路器"] = msg.bowPZDeviceCircuitBreaker + bus["breakers"]["备用断路器1"] = msg.reservedCircuitBreaker1 + bus["breakers"]["备用断路器2"] = msg.reservedCircuitBreaker2 + bus["breakers"]["应急锂电池组1断路器"] = msg.emergencyLithiumBatteryGroup1CircuitBreaker + + bus["alarms"]["电源故障信号"] = msg.powerFailureSignal + bus["alarms"]["进水报警"] = msg.waterIngressionAlarm + self.log_message("收到仪表母线状态更新") + + else: + self.log_message("消息解析失败") + print('消息处理完成') + + except Exception as e: + self.log_message(f"消息处理错误: {str(e)}") + + def setup_low_main_ui(self, parent): + """设置仪表主母线状态界面""" + frame = ttk.LabelFrame(parent, text="仪表主母线状态") + frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) + + # 电压显示 + ttk.Label(frame, text="仪表母线电压(V):").grid(row=0, column=0, sticky=tk.W) + self.low_main_instrument_voltage = ttk.Label(frame, text="0.0") + self.low_main_instrument_voltage.grid(row=0, column=1, sticky=tk.W) + + ttk.Label(frame, text="应急2母线电压(V):").grid(row=0, column=2, sticky=tk.W) + self.low_main_emergency2_voltage = ttk.Label(frame, text="0.0") + self.low_main_emergency2_voltage.grid(row=0, column=3, sticky=tk.W) + + # 电流显示 + ttk.Label(frame, text="艏低压配电盒电流(A):").grid(row=1, column=0, sticky=tk.W) + self.low_main_bow_current = ttk.Label(frame, text="0.0") + self.low_main_bow_current.grid(row=1, column=1, sticky=tk.W) + + ttk.Label(frame, text="锂电池组仪表电流(A):").grid(row=1, column=2, sticky=tk.W) + self.low_main_battery_current = ttk.Label(frame, text="0.0") + self.low_main_battery_current.grid(row=1, column=3, sticky=tk.W) + + # 断路器状态 + ttk.Label(frame, text="断路器状态:").grid(row=2, column=0, columnspan=4, sticky=tk.W) + self.low_main_breakers = {} + breaker_names = list(self.status_data["low_main_bus"]["breakers"].keys()) + + for i, name in enumerate(breaker_names): + row = 3 + i//2 + col = (i%2)*2 + ttk.Label(frame, text=name).grid(row=row, column=col, sticky=tk.W) + canvas = tk.Canvas(frame, width=20, height=20, bg="white") + canvas.grid(row=row, column=col+1, sticky=tk.W) + self.low_main_breakers[name] = canvas + + # 报警状态 + ttk.Label(frame, text="仪表电源故障:").grid(row=8, column=0, sticky=tk.W) + self.low_main_instrument_fault = ttk.Label(frame, text="无") + self.low_main_instrument_fault.grid(row=8, column=1, sticky=tk.W) + + ttk.Label(frame, text="应急电源故障:").grid(row=8, column=2, sticky=tk.W) + self.low_main_emergency_fault = ttk.Label(frame, text="无") + self.low_main_emergency_fault.grid(row=8, column=3, sticky=tk.W) + + # 报警状态 + ttk.Label(frame, text="仪表电源故障:").grid(row=8, column=0, sticky=tk.W) + self.low_main_instrument_fault = ttk.Label(frame, text="无") + self.low_main_instrument_fault.grid(row=8, column=1, sticky=tk.W) + + ttk.Label(frame, text="应急电源故障:").grid(row=8, column=2, sticky=tk.W) + self.low_main_emergency_fault = ttk.Label(frame, text="无") + self.low_main_emergency_fault.grid(row=8, column=3, sticky=tk.W) + + # 绝缘状态 + ttk.Label(frame, text="绝缘状态:").grid(row=9, column=0, sticky=tk.W) + self.low_main_insulation = ttk.Label(frame, text="正常") + self.low_main_insulation.grid(row=9, column=1, sticky=tk.W) + + return frame + + def setup_low_bus_ui(self, parent): + """设置仪表母线状态界面""" + frame = ttk.LabelFrame(parent, text="仪表母线状态") + frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) + + # 电压显示 + ttk.Label(frame, text="仪表母线电压(V):").grid(row=0, column=0, sticky=tk.W) + self.low_bus_instrument_voltage = ttk.Label(frame, text="0.0") + self.low_bus_instrument_voltage.grid(row=0, column=1, sticky=tk.W) + + ttk.Label(frame, text="应急1母线电压(V):").grid(row=0, column=2, sticky=tk.W) + self.low_bus_emergency1_voltage = ttk.Label(frame, text="0.0") + self.low_bus_emergency1_voltage.grid(row=0, column=3, sticky=tk.W) + + # 电流显示 + ttk.Label(frame, text="单元1电流(A):").grid(row=1, column=0, sticky=tk.W) + self.low_bus_unit1_current = ttk.Label(frame, text="0.0") + self.low_bus_unit1_current.grid(row=1, column=1, sticky=tk.W) + + ttk.Label(frame, text="单元2电流(A):").grid(row=1, column=2, sticky=tk.W) + self.low_bus_unit2_current = ttk.Label(frame, text="0.0") + self.low_bus_unit2_current.grid(row=1, column=3, sticky=tk.W) + + # 断路器状态 + ttk.Label(frame, text="断路器状态:").grid(row=2, column=0, columnspan=4, sticky=tk.W) + self.low_bus_breakers = {} + breaker_names = list(self.status_data["low_bus"]["breakers"].keys()) + + for i, name in enumerate(breaker_names): + row = 3 + i//2 + col = (i%2)*2 + ttk.Label(frame, text=name).grid(row=row, column=col, sticky=tk.W) + canvas = tk.Canvas(frame, width=20, height=20, bg="white") + canvas.grid(row=row, column=col+1, sticky=tk.W) + self.low_bus_breakers[name] = canvas + + # 报警状态 + ttk.Label(frame, text="电源故障信号:").grid(row=8, column=0, sticky=tk.W) + self.low_bus_power_fault = ttk.Label(frame, text="无") + self.low_bus_power_fault.grid(row=8, column=1, sticky=tk.W) + + ttk.Label(frame, text="进水报警:").grid(row=8, column=2, sticky=tk.W) + self.low_bus_water_alarm = ttk.Label(frame, text="无") + self.low_bus_water_alarm.grid(row=8, column=3, sticky=tk.W) + + # 报警状态 + ttk.Label(frame, text="电源故障信号:").grid(row=8, column=0, sticky=tk.W) + self.low_bus_power_fault = ttk.Label(frame, text="无") + self.low_bus_power_fault.grid(row=8, column=1, sticky=tk.W) + + ttk.Label(frame, text="进水报警:").grid(row=8, column=2, sticky=tk.W) + self.low_bus_water_alarm = ttk.Label(frame, text="无") + self.low_bus_water_alarm.grid(row=8, column=3, sticky=tk.W) + + return frame + + def send_udp_command(self, data): + """发送UDP命令""" + try: + self.sock.sendto(data, (self.udp_ip, self.udp_port + 1)) + except Exception as e: + self.log_message(f"发送命令失败: {str(e)}") + + def update_high_vol_ui(self, status): + """更新高压母线UI显示""" + # 更新电压显示 + self.high_vol_power_voltage.config(text=f"{status['voltage']['动力母线电压']:.1f}") + self.high_vol_a_voltage.config(text=f"{status['voltage']['A母线电压']:.1f}") + + # 更新电流显示 + self.high_vol_power_current.config(text=f"{status['current']['动力母线电流']:.1f}") + self.high_vol_a_current.config(text=f"{status['current']['A母线电流']:.1f}") + + # 更新所有电流值 + current_vars = [ + ('powerBusCurrent', '动力母线电流'), + ('busbarACurrent', 'A母线电流'), + ('dcDc5ModuleCurrent', 'DC/DC5模块电流'), + ('propulsionMotorControlBoxCurrent', '推进电机控制箱电流'), + ('lithiumBatteryGroupMeterCurrent', '锂电池组仪表电流'), + ('bowHighVoltageDistributionBoxCurrent', '艏高压配电盒电流'), + ('sternFTDevice45Current', '艉FT设备45电流'), + ('tyzReservedSwitchCurrent', 'TYZ备用开关电流'), + ('sternRudderSwitch1Current', '艉舵机开关1电流'), + ('sternRudderSwitch2Current', '艉舵机开关2电流'), + ('fbReservedSwitchCurrent', 'FB备用开关电流') + ] + + for var_name, data_key in current_vars: + label = getattr(self, f"high_vol_{var_name}") + label.config(text=f"{status['current'][data_key]:.1f}") + + # 更新断路器状态 + for name, state in status['breakers'].items(): + if name in self.high_vol_breakers: + color = 'green' if state else 'red' + self.high_vol_breakers[name].config(background=color) + + # 更新DC/DC故障状态 + dcdc_fault1 = status['faults']['DC/DC故障1'] + dcdc_fault2 = status['faults']['DC/DC故障2'] + + for i in range(8): + color1 = 'red' if (dcdc_fault1 & (1 << i)) else 'green' + color2 = 'red' if (dcdc_fault2 & (1 << i)) else 'green' + self.high_vol_dcdc_fault1_bits[i].config(bg=color1) + self.high_vol_dcdc_fault2_bits[i].config(bg=color2) + + # 更新绝缘状态 + insulation_power = status['insulation']['动力母线绝缘状态'] + insulation_a = status['insulation']['A母线绝缘状态'] + + power_text = "故障" if insulation_power else f"正常({status['voltage']['动力母线电压']:.1f}MΩ)" + a_text = "故障" if insulation_a else f"正常({status['voltage']['A母线电压']:.1f}MΩ)" + + self.high_vol_power_insulation.config(text=power_text) + self.high_vol_a_insulation.config(text=a_text) + + # 更新冷却水压力 + self.high_vol_cool_water_pressure.config(text=f"{status['cool_water_pressure']:.2f}") + + def update_ui(self): + """更新界面状态""" + # 更新高压母线状态 + high_vol = self.status_data["high_vol_bus"] + self.update_high_vol_ui(high_vol) + # 更新高压A母线状态 + high_a_vol = self.status_data["high_a_vol_bus"] + self.high_a_vol_voltage.config(text=f"{high_a_vol['voltage']['B母线电压']:.1f} V") + self.high_a_vol_current.config(text=f"{high_a_vol['current']['B母线电流']:.1f} A") + self.high_a_vol_bow_ft_current.config(text=f"{high_a_vol['current']['艏FT设备123电流']:.1f} A") + self.high_a_vol_actuator_current.config(text=f"{high_a_vol['current']['执行机构电流']:.1f} A") + + for name, canvas in self.high_a_vol_breakers.items(): + state = high_a_vol["breakers"].get(name, 0) + color = "green" if state else "red" + canvas.create_oval(2, 2, 18, 18, fill=color, outline="black") + + # 更新仪表主母线状态 + low_main = self.status_data["low_main_bus"] + for name, canvas in self.low_main_breakers.items(): + state = low_main["breakers"].get(name, 0) + color = "green" if state else "red" + canvas.create_oval(2, 2, 18, 18, fill=color, outline="black") + + # 更新仪表母线状态 + low_bus = self.status_data["low_bus"] + for name, canvas in self.low_bus_breakers.items(): + state = low_bus["breakers"].get(name, 0) + color = "green" if state else "red" + canvas.create_oval(2, 2, 18, 18, fill=color, outline="black") + + self.high_a_vol_instrument_power_fault.config( + text="无" if not high_a_vol["alarms"]["仪表电源故障"] else "有" + ) + self.high_a_vol_emergency_power_fault.config( + text="无" if not high_a_vol["alarms"]["应急电源故障"] else "有" + ) + self.high_a_vol_water_alarm.config( + text="无" if not high_a_vol["alarms"]["进水报警"] else "有" + ) + + # 更新仪表主母线状态 + low_main = self.status_data["low_main_bus"] + self.low_main_instrument_voltage.config(text=f"{low_main['voltage']['仪表母线电压']:.1f} V") + self.low_main_emergency2_voltage.config(text=f"{low_main['voltage']['应急2母线电压']:.1f} V") + self.low_main_bow_current.config(text=f"{low_main['current']['艏低压配电盒电流']:.1f}") + self.low_main_battery_current.config(text=f"{low_main['current']['锂电池组仪表电流']:.1f} A") + self.low_main_bow_current.config(text=f"{low_main['current']['艏低压配电盒电流']:.1f} A") + + for name, canvas in self.low_main_breakers.items(): + state = low_main["breakers"].get(name, 0) + color = "green" if state else "red" + canvas.create_oval(2, 2, 18, 18, fill=color, outline="black") + + self.low_main_instrument_fault.config( + text="无" if not low_main["alarms"]["仪表电源故障"] else "有" + ) + self.low_main_emergency_fault.config( + text="无" if not low_main["alarms"]["应急电源故障"] else "有" + ) + self.low_main_insulation.config( + text="正常" if not low_main["insulation"] else "异常" + ) + + # 更新仪表母线状态 + low_bus = self.status_data["low_bus"] + self.low_bus_instrument_voltage.config(text=f"{low_bus['voltage']['仪表母线电压']:.1f} V") + self.low_bus_emergency1_voltage.config(text=f"{low_bus['voltage']['应急1母线电压']:.1f} V") + self.low_bus_unit1_current.config(text=f"{low_bus['current']['单元1电流']:.1f}") + self.low_bus_unit2_current.config(text=f"{low_bus['current']['单元2电流']:.1f}") + + for name, canvas in self.low_bus_breakers.items(): + state = low_bus["breakers"].get(name, 0) + color = "green" if state else "red" + canvas.create_oval(2, 2, 18, 18, fill=color, outline="black") + + self.low_bus_power_fault.config( + text="无" if not low_bus["alarms"]["电源故障信号"] else "有" + ) + self.low_bus_water_alarm.config( + text="无" if not low_bus["alarms"]["进水报警"] else "有" + ) + print('update_ui') + # 每500ms更新一次 + self.root.after(1000, self.update_ui) + + def log_message(self, message): + """记录日志消息""" + timestamp = time.strftime("%Y-%m-%d %H:%M:%S") + self.log_text.config(state=tk.NORMAL) + self.log_text.insert(tk.END, f"[{timestamp}] {message}\n") + self.log_text.config(state=tk.DISABLED) + self.log_text.see(tk.END) + + def on_closing(self): + """窗口关闭事件处理""" + self.running = False + self.sock.close() + self.root.destroy() +if __name__ == "__main__": + root = tk.Tk() + app = PowerManagerApp(root) + + root.protocol("WM_DELETE_WINDOW", app.on_closing) + print('start') + root.mainloop() + print('end') diff --git a/test/disSysTest/db.py b/test/disSysTest/db.py new file mode 100644 index 0000000..49fce68 --- /dev/null +++ b/test/disSysTest/db.py @@ -0,0 +1,649 @@ +import sqlite3 +import threading +from datetime import datetime +from udpMsg import ( + msg_disHighVolBusFbMsg, + msg_disHighAVolBusFbMsg, + msg_disLowMainBusFbMsg, + msg_disLowBusFbMsg, + msg_disHVBCmdMsg, + msg_disHVBACmdMsg, + msg_disLVMBCmdMsg, + msg_disLVBCmdMsg +) + +class DB: + def __init__(self, db_name): + self.db_name = db_name + self.conn = None + self.lock = threading.Lock() + + def setPath(self, path): + self.db_name = path + + def connect(self): + self.conn = sqlite3.connect(self.db_name, check_same_thread=False) + self.conn.row_factory = sqlite3.Row + self.createTable() + print("数据库连接成功") + + def createTable(self): + '''创建UDP消息数据表''' + cursor = self.conn.cursor() + + # 高压母线配电反馈表 + cursor.execute(''' + CREATE TABLE IF NOT EXISTS msg_disHighVolBusFbMsg ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, + fuelCellCircuitBreaker INTEGER, + powerLithiumBatteryCircuitBreaker INTEGER, + propulsionMotorCircuitBreaker INTEGER, + lithiumBatteryGroupInstrumentCircuitBreaker INTEGER, + dcDc5ModuleCircuitBreaker INTEGER, + bowHighVoltageDistributionBoxCircuitBreaker INTEGER, + sternFTDevice45CircuitBreaker INTEGER, + sternRudderSwitch1CircuitBreaker INTEGER, + sternRudderSwitch2CircuitBreaker INTEGER, + fbReservedCircuitBreaker INTEGER, + tyzReservedCircuitBreaker INTEGER, + reservedCircuitBreaker INTEGER, + dcDcFaultWord1 INTEGER, + dcDcFaultWord2 INTEGER, + powerBusInsulationStatus INTEGER, + aBusInsulationStatus INTEGER, + meterPowerLossSignal INTEGER, + emergencyPowerLossSignal INTEGER, + powerBusVoltage INTEGER, + dcDc5ModuleCurrent INTEGER, + powerBusCurrent INTEGER, + busbarAVoltage INTEGER, + propulsionMotorControlBoxCurrent INTEGER, + busbarACurrent INTEGER, + lithiumBatteryGroupMeterCurrent INTEGER, + bowHighVoltageDistributionBoxCurrent INTEGER, + sternFTDevice45Current INTEGER, + tyzReservedSwitchCurrent INTEGER, + sternRudderSwitch1Current INTEGER, + reservedCurrent1 INTEGER, + sternRudderSwitch2Current INTEGER, + reservedCurrent2 INTEGER, + fbReservedSwitchCurrent INTEGER, + reservedCurrent3 INTEGER, + coolWaterPressure INTEGER + ) + ''') + + # 高压母线A配电反馈表 + cursor.execute(''' + CREATE TABLE IF NOT EXISTS msg_disHighAVolBusFbMsg ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, + bowFTDevice123CircuitBreaker INTEGER, + actuatorCircuitBreaker INTEGER, + mastSteeringGearControlBoxCircuitBreaker INTEGER, + xczCircuitBreaker INTEGER, + bowRudderControlBoxCircuitBreaker INTEGER, + openWaterCoverStartCylinderCircuitBreaker INTEGER, + instrumentPowerFailureSignal INTEGER, + emergencyPowerFailureSignal INTEGER, + waterIngressionAlarm INTEGER, + busbarBVoltage INTEGER, + busbarBCurrent INTEGER, + bowFTDevice123Current INTEGER, + actuatorCurrent INTEGER, + mastSteeringGearControlBoxCurrent INTEGER, + xczCurrent INTEGER, + bowRudderControlBoxCurrent INTEGER, + openWaterCoverStartCylinderCurrent INTEGER + ) + ''') + + # 仪表母线配电反馈表 + cursor.execute(''' + CREATE TABLE IF NOT EXISTS msg_disLowMainBusFbMsg ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, + lithiumBatteryGroupInstrumentCircuitBreaker INTEGER, + bowLowVoltageDistributionBoxCircuitBreaker INTEGER, + unit4InstrumentDC48VCircuitBreaker INTEGER, + dcC1DCDistributionPanelCircuitBreaker INTEGER, + reservedCircuitBreaker1 INTEGER, + reservedCircuitBreaker2 INTEGER, + emergencyLithiumBatteryGroup2CircuitBreaker INTEGER, + instrumentPowerFailureSignal INTEGER, + emergencyPowerFailureSignal INTEGER, + instrumentBusbarInsulationLow INTEGER, + instrumentBusbarVoltage INTEGER, + bowLowVoltageDistributionBoxCurrent INTEGER, + dcC1InstrumentDC48VCurrent INTEGER, + reservedCurrent1 INTEGER, + emergencyLithiumBatteryGroup2Current INTEGER, + lithiumBatteryGroupInstrumentCurrent INTEGER, + unit4InstrumentDC48VCurrent INTEGER, + reservedCurrent2 INTEGER, + emergency2BusbarVoltage INTEGER, + compositeEnergyManagementSystemEmergencyDC48VCurrent INTEGER, + fuelCellSecuritySystemEmergencyDC48VCurrent INTEGER, + plcControlPowerCurrent INTEGER + ) + ''') + + # 仪表汇流排配电反馈表 + cursor.execute(''' + CREATE TABLE IF NOT EXISTS msg_disLowBusFbMsg ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, + unit1CircuitBreaker INTEGER, + unit2CircuitBreaker INTEGER, + unit3CircuitBreaker INTEGER, + unit5CircuitBreaker INTEGER, + bowPZDeviceCircuitBreaker INTEGER, + reservedCircuitBreaker1 INTEGER, + reservedCircuitBreaker2 INTEGER, + emergencyLithiumBatteryGroup1CircuitBreaker INTEGER, + powerFailureSignal INTEGER, + waterIngressionAlarm INTEGER, + instrumentBusbarVoltage INTEGER, + instrumentBusbarCurrent INTEGER, + unit1Current INTEGER, + unit2Current INTEGER, + unit3Current INTEGER, + unit5Current INTEGER, + bowPZDeviceCurrent INTEGER, + emergencyLithiumBatteryGroup1Current INTEGER, + emergency1BusbarVoltage INTEGER + ) + ''') + + # 高压母线命令表 + cursor.execute(''' + CREATE TABLE IF NOT EXISTS msg_disHVBCmdMsg ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, + fuelCellCircuitBreakerCmd INTEGER, + powerLithiumBatteryCircuitBreakerCmd INTEGER, + propulsionMotorCircuitBreakerCmd INTEGER, + lithiumBatteryGroupInstrumentCircuitBreakerCmd INTEGER, + dcDc5ModuleCircuitBreakerCmd INTEGER, + bowHighVoltageDistributionBoxCircuitBreakerCmd INTEGER, + sternFTDevice45CircuitBreakerCmd INTEGER, + sternRudderSwitch1CircuitBreakerCmd INTEGER, + sternRudderSwitch2CircuitBreakerCmd INTEGER, + fbReservedCircuitBreakerCmd INTEGER, + tyzReservedCircuitBreakerCmd INTEGER, + reservedCircuitBreakerCmd INTEGER, + dcdc5ModuleCmd INTEGER, + coolingSystemCmd INTEGER + ) + ''') + + # 高压母线A命令表 + cursor.execute(''' + CREATE TABLE IF NOT EXISTS msg_disHVBACmdMsg ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, + bowFTDevice123CircuitBreakerCmd INTEGER, + actuatorCircuitBreakerCmd INTEGER, + mastSteeringGearControlBoxCircuitBreakerCmd INTEGER, + xczCircuitBreakerCmd INTEGER, + bowRudderControlBoxCircuitBreakerCmd INTEGER, + openWaterCoverStartCylinderCircuitBreakerCmd INTEGER + ) + ''') + + # 仪表母线命令表 + cursor.execute(''' + CREATE TABLE IF NOT EXISTS msg_disLVMBCmdMsg ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, + lithiumBatteryGroupInstrumentCircuitBreakerCmd INTEGER, + bowLowVoltageDistributionBoxCircuitBreakerCmd INTEGER, + unit4InstrumentDC48VCircuitBreakerCmd INTEGER, + dcC1DCDistributionPanelCircuitBreakerCmd INTEGER, + reservedCircuitBreakerCmd1 INTEGER, + reservedCircuitBreakerCmd2 INTEGER, + emergencyLithiumBatteryGroup2CircuitBreakerCmd INTEGER + ) + ''') + + # 仪表汇流排命令表 + cursor.execute(''' + CREATE TABLE IF NOT EXISTS msg_disLVBCmdMsg ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, + unit1CircuitBreakerCmd INTEGER, + unit2CircuitBreakerCmd INTEGER, + unit3CircuitBreakerCmd INTEGER, + unit5CircuitBreakerCmd INTEGER, + bowPZDeviceCircuitBreakerCmd INTEGER, + reservedCircuitBreakerCmd1 INTEGER, + reservedCircuitBreakerCmd2 INTEGER, + emergencyLithiumBatteryGroup1CircuitBreakerCmd INTEGER + ) + ''') + + self.conn.commit() + + def _insert_data(self, table_name, data_dict): + print('-----------------insert_data start') + '''内部方法:执行实际的数据库插入操作''' + with self.lock: + try: + # 检查并建立连接 + if not self.conn: + print('-----------------connecting to database') + self.connect() + + print(f'-----------------connection status: {"connected" if self.conn else "disconnected"}') + if not self.conn: + print('-----------------connection failed') + return False + + print(f'-----------------connection object: {self.conn}') + + # 创建cursor + try: + print('-----------------creating cursor') + cursor = self.conn.cursor() + print('-----------------cursor created successfully') + except sqlite3.Error as e: + print(f'-----------------cursor creation failed: {e}') + return False + + # 准备查询 + columns = ', '.join(data_dict.keys()) + placeholders = ', '.join(['?'] * len(data_dict)) + query = f'INSERT INTO {table_name} ({columns}) VALUES ({placeholders})' + print(f'-----------------prepared query: {query}') + + # 执行查询 + try: + print('-----------------executing query') + cursor.execute(query, list(data_dict.values())) + self.conn.commit() + print(f"-----------------Data inserted successfully into {table_name}") + return True + except sqlite3.Error as e: + print(f"-----------------Error executing query: {e}") + return False + + except Exception as e: + print(f'-----------------unexpected error in _insert_data: {e}') + return False + + def insertHighVolBusData(self, data:msg_disHighVolBusFbMsg): + '''插入高压母线配电反馈数据''' + print('-----------------insertHighVolBusData') + data_dict = { + 'fuelCellCircuitBreaker': data.fuelCellCircuitBreaker, + 'powerLithiumBatteryCircuitBreaker': data.powerLithiumBatteryCircuitBreaker, + 'propulsionMotorCircuitBreaker': data.propulsionMotorCircuitBreaker, + 'lithiumBatteryGroupInstrumentCircuitBreaker': data.lithiumBatteryGroupInstrumentCircuitBreaker, + 'dcDc5ModuleCircuitBreaker': data.dcDc5ModuleCircuitBreaker, + 'bowHighVoltageDistributionBoxCircuitBreaker': data.bowHighVoltageDistributionBoxCircuitBreaker, + 'sternFTDevice45CircuitBreaker': data.sternFTDevice45CircuitBreaker, + 'sternRudderSwitch1CircuitBreaker': data.sternRudderSwitch1CircuitBreaker, + 'sternRudderSwitch2CircuitBreaker': data.sternRudderSwitch2CircuitBreaker, + 'fbReservedCircuitBreaker': data.fbReservedCircuitBreaker, + 'tyzReservedCircuitBreaker': data.tyzReservedCircuitBreaker, + 'reservedCircuitBreaker': data.reservedCircuitBreaker, + 'dcDcFaultWord1': data.dcDcFaultWord1, + 'dcDcFaultWord2': data.dcDcFaultWord2, + 'powerBusInsulationStatus': data.powerBusInsulationStatus, + 'aBusInsulationStatus': data.aBusInsulationStatus, + 'meterPowerLossSignal': data.meterPowerLossSignal, + 'emergencyPowerLossSignal': data.emergencyPowerLossSignal, + 'powerBusVoltage': data.powerBusVoltage, + 'dcDc5ModuleCurrent': data.dcDc5ModuleCurrent, + 'powerBusCurrent': data.powerBusCurrent, + 'busbarAVoltage': data.busbarAVoltage, + 'propulsionMotorControlBoxCurrent': data.propulsionMotorControlBoxCurrent, + 'busbarACurrent': data.busbarACurrent, + 'lithiumBatteryGroupMeterCurrent': data.lithiumBatteryGroupMeterCurrent, + 'bowHighVoltageDistributionBoxCurrent': data.bowHighVoltageDistributionBoxCurrent, + 'sternFTDevice45Current': data.sternFTDevice45Current, + 'tyzReservedSwitchCurrent': data.tyzReservedSwitchCurrent, + 'sternRudderSwitch1Current': data.sternRudderSwitch1Current, + 'reservedCurrent1': data.reservedCurrent1, + 'sternRudderSwitch2Current': data.sternRudderSwitch2Current, + 'reservedCurrent2': data.reservedCurrent2, + 'fbReservedSwitchCurrent': data.fbReservedSwitchCurrent, + 'reservedCurrent3': data.reservedCurrent3, + 'coolWaterPressure': data.coolWaterPressure + } + return self._insert_data('msg_disHighVolBusFbMsg', data_dict) + + def insertHighAVolBusData(self, data:msg_disHighAVolBusFbMsg): + '''插入高压母线A配电反馈数据''' + data_dict = { + 'bowFTDevice123CircuitBreaker': data.bowFTDevice123CircuitBreaker, + 'actuatorCircuitBreaker': data.actuatorCircuitBreaker, + 'mastSteeringGearControlBoxCircuitBreaker': data.mastSteeringGearControlBoxCircuitBreaker, + 'xczCircuitBreaker': data.xczCircuitBreaker, + 'bowRudderControlBoxCircuitBreaker': data.bowRudderControlBoxCircuitBreaker, + 'openWaterCoverStartCylinderCircuitBreaker': data.openWaterCoverStartCylinderCircuitBreaker, + 'instrumentPowerFailureSignal': data.instrumentPowerFailureSignal, + 'emergencyPowerFailureSignal': data.emergencyPowerFailureSignal, + 'waterIngressionAlarm': data.waterIngressionAlarm, + 'busbarBVoltage': data.busbarBVoltage, + 'busbarBCurrent': data.busbarBCurrent, + 'bowFTDevice123Current': data.bowFTDevice123Current, + 'actuatorCurrent': data.actuatorCurrent, + 'mastSteeringGearControlBoxCurrent': data.mastSteeringGearControlBoxCurrent, + 'xczCurrent': data.xczCurrent, + 'bowRudderControlBoxCurrent': data.bowRudderControlBoxCurrent, + 'openWaterCoverStartCylinderCurrent': data.openWaterCoverStartCylinderCurrent + } + return self._insert_data('msg_disHighAVolBusFbMsg', data_dict) + + def insertLowMainBusData(self, data:msg_disLowMainBusFbMsg): + '''插入仪表母线配电反馈数据''' + data_dict = { + 'lithiumBatteryGroupInstrumentCircuitBreaker': data.lithiumBatteryGroupInstrumentCircuitBreaker, + 'bowLowVoltageDistributionBoxCircuitBreaker': data.bowLowVoltageDistributionBoxCircuitBreaker, + 'unit4InstrumentDC48VCircuitBreaker': data.unit4InstrumentDC48VCircuitBreaker, + 'dcC1DCDistributionPanelCircuitBreaker': data.dcC1DCDistributionPanelCircuitBreaker, + 'reservedCircuitBreaker1': data.reservedCircuitBreaker1, + 'reservedCircuitBreaker2': data.reservedCircuitBreaker2, + 'emergencyLithiumBatteryGroup2CircuitBreaker': data.emergencyLithiumBatteryGroup2CircuitBreaker, + 'instrumentPowerFailureSignal': data.instrumentPowerFailureSignal, + 'emergencyPowerFailureSignal': data.emergencyPowerFailureSignal, + 'instrumentBusbarInsulationLow': data.instrumentBusbarInsulationLow, + 'instrumentBusbarVoltage': data.instrumentBusbarVoltage, + 'bowLowVoltageDistributionBoxCurrent': data.bowLowVoltageDistributionBoxCurrent, + 'dcC1InstrumentDC48VCurrent': data.dcC1InstrumentDC48VCurrent, + 'reservedCurrent1': data.reservedCurrent1, + 'emergencyLithiumBatteryGroup2Current': data.emergencyLithiumBatteryGroup2Current, + 'lithiumBatteryGroupInstrumentCurrent': data.lithiumBatteryGroupInstrumentCurrent, + 'unit4InstrumentDC48VCurrent': data.unit4InstrumentDC48VCurrent, + 'reservedCurrent2': data.reservedCurrent2, + 'emergency2BusbarVoltage': data.emergency2BusbarVoltage, + 'compositeEnergyManagementSystemEmergencyDC48VCurrent': data.compositeEnergyManagementSystemEmergencyDC48VCurrent, + 'fuelCellSecuritySystemEmergencyDC48VCurrent': data.fuelCellSecuritySystemEmergencyDC48VCurrent, + 'plcControlPowerCurrent': data.plcControlPowerCurrent + } + return self._insert_data('msg_disLowMainBusFbMsg', data_dict) + + def insertLowBusData(self, data:msg_disLowBusFbMsg): + '''插入仪表汇流排配电反馈数据''' + data_dict = { + 'unit1CircuitBreaker': data.unit1CircuitBreaker, + 'unit2CircuitBreaker': data.unit2CircuitBreaker, + 'unit3CircuitBreaker': data.unit3CircuitBreaker, + 'unit5CircuitBreaker': data.unit5CircuitBreaker, + 'bowPZDeviceCircuitBreaker': data.bowPZDeviceCircuitBreaker, + 'reservedCircuitBreaker1': data.reservedCircuitBreaker1, + 'reservedCircuitBreaker2': data.reservedCircuitBreaker2, + 'emergencyLithiumBatteryGroup1CircuitBreaker': data.emergencyLithiumBatteryGroup1CircuitBreaker, + 'powerFailureSignal': data.powerFailureSignal, + 'waterIngressionAlarm': data.waterIngressionAlarm, + 'instrumentBusbarVoltage': data.instrumentBusbarVoltage, + 'instrumentBusbarCurrent': data.instrumentBusbarCurrent, + 'unit1Current': data.unit1Current, + 'unit2Current': data.unit2Current, + 'unit3Current': data.unit3Current, + 'unit5Current': data.unit5Current, + 'bowPZDeviceCurrent': data.bowPZDeviceCurrent, + 'emergencyLithiumBatteryGroup1Current': data.emergencyLithiumBatteryGroup1Current, + 'emergency1BusbarVoltage': data.emergency1BusbarVoltage + } + return self._insert_data('msg_disLowBusFbMsg', data_dict) + + def insertHighVolBusCmd(self, data:msg_disHVBCmdMsg): + '''插入高压母线命令数据''' + data_dict = { + 'fuelCellCircuitBreakerCmd': data.fuelCellCircuitBreaker, + 'powerLithiumBatteryCircuitBreakerCmd': data.powerLithiumBatteryCircuitBreaker, + 'propulsionMotorCircuitBreakerCmd': data.propulsionMotorCircuitBreaker, + 'lithiumBatteryGroupInstrumentCircuitBreakerCmd': data.lithiumBatteryGroupInstrumentCircuitBreaker, + 'dcDc5ModuleCircuitBreakerCmd': data.dcDc5ModuleCircuitBreaker, + 'bowHighVoltageDistributionBoxCircuitBreakerCmd': data.bowHighVoltageDistributionBoxCircuitBreaker, + 'sternFTDevice45CircuitBreakerCmd': data.sternFTDevice45CircuitBreaker, + 'sternRudderSwitch1CircuitBreakerCmd': data.sternRudderSwitch1CircuitBreaker, + 'sternRudderSwitch2CircuitBreakerCmd': data.sternRudderSwitch2CircuitBreaker, + 'fbReservedCircuitBreakerCmd': data.fbReservedCircuitBreaker, + 'tyzReservedCircuitBreakerCmd': data.tyzReservedCircuitBreaker, + 'reservedCircuitBreakerCmd': data.reservedCircuitBreaker, + 'dcdc5ModuleCmd': data.dcdc5Module, + 'coolingSystemCmd': data.coolingSystem + } + return self._insert_data('msg_disHVBCmdMsg', data_dict) + + def insertHighAVolBusCmd(self, data:msg_disHVBACmdMsg): + '''插入高压母线A命令数据''' + data_dict = { + 'bowFTDevice123CircuitBreakerCmd': data.bowFTDevice123CircuitBreaker, + 'actuatorCircuitBreakerCmd': data.actuatorCircuitBreaker, + 'mastSteeringGearControlBoxCircuitBreakerCmd': data.mastSteeringGearControlBoxCircuitBreaker, + 'xczCircuitBreakerCmd': data.xczCircuitBreaker, + 'bowRudderControlBoxCircuitBreakerCmd': data.bowRudderControlBoxCircuitBreaker, + 'openWaterCoverStartCylinderCircuitBreakerCmd': data.openWaterCoverStartCylinderCircuitBreaker + } + return self._insert_data('msg_disHVBACmdMsg', data_dict) + + def insertLowMainBusCmd(self, data:msg_disLVMBCmdMsg): + '''插入仪表母线命令数据''' + data_dict = { + 'lithiumBatteryGroupInstrumentCircuitBreakerCmd': data.lithiumBatteryGroupInstrumentCircuitBreaker, + 'bowLowVoltageDistributionBoxCircuitBreakerCmd': data.bowLowVoltageDistributionBoxCircuitBreaker, + 'unit4InstrumentDC48VCircuitBreakerCmd': data.unit4InstrumentDC48VCircuitBreaker, + 'dcC1DCDistributionPanelCircuitBreakerCmd': data.dcC1DCDistributionPanelCircuitBreaker, + 'reservedCircuitBreakerCmd1': data.reservedCircuitBreaker1, + 'reservedCircuitBreakerCmd2': data.reservedCircuitBreaker2, + 'emergencyLithiumBatteryGroup2CircuitBreakerCmd': data.emergencyLithiumBatteryGroup2CircuitBreaker + } + return self._insert_data('msg_disLVMBCmdMsg', data_dict) + + + + def insertLowBusCmd(self, data:msg_disLVBCmdMsg): + '''插入仪表汇流排命令数据''' + data_dict = { + 'unit1CircuitBreakerCmd': data.unit1CircuitBreaker, + 'unit2CircuitBreakerCmd': data.unit2CircuitBreaker, + 'unit3CircuitBreakerCmd': data.unit3CircuitBreaker, + 'unit5CircuitBreakerCmd': data.unit5CircuitBreaker, + 'bowPZDeviceCircuitBreakerCmd': data.bowPZDeviceCircuitBreaker, + 'reservedCircuitBreakerCmd1': data.reservedCircuitBreaker1, + 'reservedCircuitBreakerCmd2': data.reservedCircuitBreaker2, + 'emergencyLithiumBatteryGroup1CircuitBreakerCmd': data.emergencyLithiumBatteryGroup1CircuitBreaker + } + return self._insert_data('msg_disLVBCmdMsg', data_dict) + + + def close(self): + if self.conn: + self.conn.close() + +if __name__ == "__main__": + # 创建数据库实例 + db = DB('/home/zjk/project/H100/H100PowerManger/test/disSysTest/test.db') + db.connect() + + # 创建测试数据 + from udpMsg import ( + msg_disHighVolBusFbMsg, + msg_disHighAVolBusFbMsg, + msg_disLowMainBusFbMsg, + msg_disLowBusFbMsg, + msg_disHVBCmdMsg, + msg_disHVBACmdMsg, + msg_disLVMBCmdMsg, + msg_disLVBCmdMsg + ) + + # 测试反馈消息存储 + fb1 = msg_disHighVolBusFbMsg() + fb1.fuelCellCircuitBreaker = 1 + fb1.powerLithiumBatteryCircuitBreaker = 1 + fb1.propulsionMotorCircuitBreaker = 1 + fb1.lithiumBatteryGroupInstrumentCircuitBreaker = 1 + fb1.dcDc5ModuleCircuitBreaker = 1 + fb1.bowHighVoltageDistributionBoxCircuitBreaker = 1 + fb1.sternFTDevice45CircuitBreaker = 1 + fb1.sternRudderSwitch1CircuitBreaker = 1 + fb1.sternRudderSwitch2CircuitBreaker = 1 + fb1.fbReservedCircuitBreaker = 1 + fb1.tyzReservedCircuitBreaker = 1 + fb1.reservedCircuitBreaker = 1 + fb1.dcDcFaultWord1 = 0 + fb1.dcDcFaultWord2 = 0 + fb1.powerBusInsulationStatus = 1 + fb1.aBusInsulationStatus = 1 + fb1.meterPowerLossSignal = 0 + fb1.emergencyPowerLossSignal = 0 + fb1.powerBusVoltage = 220 + fb1.dcDc5ModuleCurrent = 10 + fb1.powerBusCurrent = 100 + fb1.busbarAVoltage = 220 + fb1.propulsionMotorControlBoxCurrent = 50 + fb1.busbarACurrent = 100 + fb1.lithiumBatteryGroupMeterCurrent = 10 + fb1.bowHighVoltageDistributionBoxCurrent = 20 + fb1.sternFTDevice45Current = 30 + fb1.tyzReservedSwitchCurrent = 0 + fb1.sternRudderSwitch1Current = 10 + fb1.reservedCurrent1 = 0 + fb1.sternRudderSwitch2Current = 10 + fb1.reservedCurrent2 = 0 + fb1.fbReservedSwitchCurrent = 0 + fb1.reservedCurrent3 = 0 + fb1.coolWaterPressure = 100 + + fb2 = msg_disHighAVolBusFbMsg() + fb2.bowFTDevice123CircuitBreaker = 1 + fb2.actuatorCircuitBreaker = 1 + fb2.mastSteeringGearControlBoxCircuitBreaker = 1 + fb2.xczCircuitBreaker = 1 + fb2.bowRudderControlBoxCircuitBreaker = 1 + fb2.openWaterCoverStartCylinderCircuitBreaker = 1 + fb2.instrumentPowerFailureSignal = 0 + fb2.emergencyPowerFailureSignal = 0 + fb2.waterIngressionAlarm = 0 + fb2.busbarBVoltage = 220 + fb2.busbarBCurrent = 100 + fb2.bowFTDevice123Current = 20 + fb2.actuatorCurrent = 30 + fb2.mastSteeringGearControlBoxCurrent = 10 + fb2.xczCurrent = 5 + fb2.bowRudderControlBoxCurrent = 15 + fb2.openWaterCoverStartCylinderCurrent = 5 + + fb3 = msg_disLowMainBusFbMsg() + fb3.lithiumBatteryGroupInstrumentCircuitBreaker = 1 + fb3.bowLowVoltageDistributionBoxCircuitBreaker = 1 + fb3.unit4InstrumentDC48VCircuitBreaker = 1 + fb3.dcC1DCDistributionPanelCircuitBreaker = 1 + fb3.reservedCircuitBreaker1 = 0 + fb3.reservedCircuitBreaker2 = 0 + fb3.emergencyLithiumBatteryGroup2CircuitBreaker = 1 + fb3.instrumentPowerFailureSignal = 0 + fb3.emergencyPowerFailureSignal = 0 + fb3.instrumentBusbarInsulationLow = 0 + fb3.instrumentBusbarVoltage = 48 + fb3.bowLowVoltageDistributionBoxCurrent = 10 + fb3.dcC1InstrumentDC48VCurrent = 5 + fb3.reservedCurrent1 = 0 + fb3.emergencyLithiumBatteryGroup2Current = 10 + fb3.lithiumBatteryGroupInstrumentCurrent = 5 + fb3.unit4InstrumentDC48VCurrent = 5 + fb3.reservedCurrent2 = 0 + fb3.emergency2BusbarVoltage = 48 + fb3.compositeEnergyManagementSystemEmergencyDC48VCurrent = 5 + fb3.fuelCellSecuritySystemEmergencyDC48VCurrent = 5 + fb3.plcControlPowerCurrent = 5 + + fb4 = msg_disLowBusFbMsg() + fb4.unit1CircuitBreaker = 1 + fb4.unit2CircuitBreaker = 1 + fb4.unit3CircuitBreaker = 1 + fb4.unit5CircuitBreaker = 1 + fb4.bowPZDeviceCircuitBreaker = 1 + fb4.reservedCircuitBreaker1 = 0 + fb4.reservedCircuitBreaker2 = 0 + fb4.emergencyLithiumBatteryGroup1CircuitBreaker = 1 + fb4.powerFailureSignal = 0 + fb4.waterIngressionAlarm = 0 + fb4.instrumentBusbarVoltage = 48 + fb4.instrumentBusbarCurrent = 10 + fb4.unit1Current = 2 + fb4.unit2Current = 2 + fb4.unit3Current = 2 + fb4.unit5Current = 2 + fb4.bowPZDeviceCurrent = 2 + fb4.emergencyLithiumBatteryGroup1Current = 10 + fb4.emergency1BusbarVoltage = 48 + + db.insertHighVolBusData(fb1) + db.insertHighAVolBusData(fb2) + db.insertLowMainBusData(fb3) + db.insertLowBusData(fb4) + db.insertHighVolBusData(fb1) + db.insertHighAVolBusData(fb2) + db.insertLowMainBusData(fb3) + db.insertLowBusData(fb4) + db.insertHighVolBusData(fb1) + db.insertHighAVolBusData(fb2) + db.insertLowMainBusData(fb3) + db.insertLowBusData(fb4) + # 测试命令消息存储 + cmd1 = msg_disHVBCmdMsg() + cmd1.fuelCellCircuitBreaker = 1 + cmd1.powerLithiumBatteryCircuitBreaker = 1 + cmd1.propulsionMotorCircuitBreaker = 1 + cmd1.lithiumBatteryGroupInstrumentCircuitBreaker = 1 + cmd1.dcDc5ModuleCircuitBreaker = 1 + cmd1.bowHighVoltageDistributionBoxCircuitBreaker = 1 + cmd1.sternFTDevice45CircuitBreaker = 1 + cmd1.sternRudderSwitch1CircuitBreaker = 1 + cmd1.sternRudderSwitch2CircuitBreaker = 1 + cmd1.fbReservedCircuitBreaker = 0 + cmd1.tyzReservedCircuitBreaker = 0 + cmd1.reservedCircuitBreaker = 0 + cmd1.dcdc5Module = 1 + cmd1.coolingSystem = 1 + + cmd2 = msg_disHVBACmdMsg() + cmd2.bowFTDevice123CircuitBreaker = 1 + cmd2.actuatorCircuitBreaker = 1 + cmd2.mastSteeringGearControlBoxCircuitBreaker = 1 + cmd2.xczCircuitBreaker = 1 + cmd2.bowRudderControlBoxCircuitBreaker = 1 + cmd2.openWaterCoverStartCylinderCircuitBreaker = 1 + + cmd3 = msg_disLVMBCmdMsg() + cmd3.lithiumBatteryGroupInstrumentCircuitBreaker = 1 + cmd3.bowLowVoltageDistributionBoxCircuitBreaker = 1 + cmd3.unit4InstrumentDC48VCircuitBreaker = 1 + cmd3.dcC1DCDistributionPanelCircuitBreaker = 1 + cmd3.reservedCircuitBreaker1 = 0 + cmd3.reservedCircuitBreaker2 = 0 + cmd3.emergencyLithiumBatteryGroup2CircuitBreaker = 1 + + cmd4 = msg_disLVBCmdMsg() + cmd4.unit1CircuitBreaker = 1 + cmd4.unit2CircuitBreaker = 1 + cmd4.unit3CircuitBreaker = 1 + cmd4.unit5CircuitBreaker = 1 + cmd4.bowPZDeviceCircuitBreaker = 1 + cmd4.reservedCircuitBreaker1 = 0 + cmd4.reservedCircuitBreaker2 = 0 + cmd4.emergencyLithiumBatteryGroup1CircuitBreaker = 1 + + db.insertHighVolBusCmd(cmd1) + db.insertHighAVolBusCmd(cmd2) + db.insertLowMainBusCmd(cmd3) + db.insertLowBusCmd(cmd4) + + db.insertHighVolBusCmd(cmd1) + db.insertHighAVolBusCmd(cmd2) + db.insertLowMainBusCmd(cmd3) + db.insertLowBusCmd(cmd4) + + db.insertHighVolBusCmd(cmd1) + db.insertHighAVolBusCmd(cmd2) + db.insertLowMainBusCmd(cmd3) + db.insertLowBusCmd(cmd4) + + print("测试数据已成功插入数据库") diff --git a/test/disSysTest/main.py b/test/disSysTest/main.py new file mode 100644 index 0000000..1234299 --- /dev/null +++ b/test/disSysTest/main.py @@ -0,0 +1,19 @@ +import tkinter as tk +from PowerManagerApp import PowerManagerApp +from db import DB + +def main(): + # 创建Tkinter根窗口 + root = tk.Tk() + + # 创建PowerManagerApp实例 + app = PowerManagerApp(root) + + # 设置窗口关闭事件处理 + root.protocol("WM_DELETE_WINDOW", app.on_closing) + + # 启动主循环 + root.mainloop() + +if __name__ == "__main__": + main() diff --git a/test/disSysTest/main.py.bak b/test/disSysTest/main.py.bak new file mode 100644 index 0000000..0b62334 --- /dev/null +++ b/test/disSysTest/main.py.bak @@ -0,0 +1,1063 @@ +import tkinter as tk +from tkinter import ttk +import socket +import threading +import time +from udpMsg import ( + msg_disHighVolBusFbMsg, + msg_disHighAVolBusFbMsg, + msg_disLowMainBusFbMsg, + msg_disLowBusFbMsg, + msg_disHVBCmdMsg, + msg_disHVBACmdMsg, + msg_disLVMBCmdMsg, + msg_disLVBCmdMsg +) + +class PowerManagerApp: + def __init__(self, root): + self.root = root + + # 解决字体模糊问题 + style = ttk.Style() + style.configure('.', font=('Microsoft YaHei', 10)) + + self.root.title("电源管理系统") + self.root.geometry("1200x800") + self.root.tk.call('tk', 'scaling', 1.5) # 适配高DPI显示 + + # UDP通信配置 + self.udp_ip = "127.0.0.1" + self.udp_port = 5000 + self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + self.sock.bind((self.udp_ip, self.udp_port)) + + # 状态数据 - 完全匹配udpMsg.py中的定义 + self.status_data = { + "high_vol_bus": { + "breakers": { + "燃料电池断路器": 0, + "动力锂电池断路器": 0, + "推进电机断路器": 0, + "锂电池组仪表断路器": 0, + "DC/DC模块断路器": 0, + "艏高压配电盒断路器": 0, + "艉FT设备45断路器": 0, + "艉舵机开关1断路器": 0, + "艉舵机开关2断路器": 0, + "FB备用断路器": 0, + "TYZ备用断路器": 0, + "备用断路器": 0 + }, + "faults": { + "DC/DC故障1": 0, + "DC/DC故障2": 0 + }, + "insulation": { + "动力母线绝缘状态": 0, + "A母线绝缘状态": 0 + }, + "alarms": { + "仪表电源丢失信号": 0, + "应急电源丢失信号": 0 + }, + "voltage": { + "动力母线电压": 0.0, + "A母线电压": 0.0 + }, + "current": { + "动力母线电流": 0.0, + "DC/DC5模块电流": 0.0, + "推进电机控制箱电流": 0.0, + "A母线电流": 0.0, + "锂电池组仪表电流": 0.0, + "艏高压配电盒电流": 0.0, + "艉FT设备45电流": 0.0, + "TYZ备用开关电流": 0.0, + "艉舵机开关1电流": 0.0, + "备用电流1": 0.0, + "艉舵机开关2电流": 0.0, + "备用电流2": 0.0, + "FB备用开关电流": 0.0, + "备用电流3": 0.0 + }, + "cool_water_pressure": 0.0 + }, + "high_a_vol_bus": { + "breakers": { + "艏FT设备123断路器": 0, + "执行机构断路器": 0, + "桅舵机控制箱断路器": 0, + "XCZ断路器": 0, + "艏舵控制箱断路器": 0, + "开盖启动气缸断路器": 0 + }, + "alarms": { + "仪表电源故障": 0, + "应急电源故障": 0, + "进水报警": 0 + }, + "voltage": { + "B母线电压": 0.0 + }, + "current": { + "B母线电流": 0.0, + "艏FT设备123电流": 0.0, + "执行机构电流": 0.0, + "桅舵机控制箱电流": 0.0, + "XCZ电流": 0.0, + "艏舵控制箱电流": 0.0, + "开盖启动气缸电流": 0.0 + } + }, + "low_main_bus": { + "breakers": { + "锂电池组仪表断路器": 0, + "艏低压配电盒断路器": 0, + "单元4仪表48V断路器": 0, + "DC/C1直流配电板断路器": 0, + "备用断路器1": 0, + "备用断路器2": 0, + "应急锂电池组2断路器": 0 + }, + "alarms": { + "仪表电源故障": 0, + "应急电源故障": 0 + }, + "insulation": 0, + "voltage": { + "仪表母线电压": 0.0, + "应急2母线电压": 0.0 + }, + "current": { + "艏低压配电盒电流": 0.0, + "DC/C1仪表48V电流": 0.0, + "备用电流1": 0.0, + "应急锂电池组2电流": 0.0, + "锂电池组仪表电流": 0.0, + "单元4仪表48V电流": 0.0, + "备用电流2": 0.0, + "综合能量管理系统应急DC48V电流": 0.0, + "燃料电池安全系统应急DC48V电流": 0.0, + "PLC控制电源电流": 0.0 + } + }, + "low_bus": { + "breakers": { + "单元1断路器": 0, + "单元2断路器": 0, + "单元3断路器": 0, + "单元5断路器": 0, + "艏PZ设备断路器": 0, + "备用断路器1": 0, + "备用断路器2": 0, + "应急锂电池组1断路器": 0 + }, + "alarms": { + "电源故障信号": 0, + "进水报警": 0 + }, + "voltage": { + "仪表母线电压": 0.0, + "应急1母线电压": 0.0 + }, + "current": { + "仪表母线电流": 0.0, + "单元1电流": 0.0, + "单元2电流": 0.0, + "单元3电流": 0.0, + "单元5电流": 0.0, + "艏PZ设备电流": 0.0, + "应急锂电池组1电流": 0.0 + } + } + } + + # 初始化界面 + self.setup_ui() + + # 启动UDP接收线程 + self.running = True + self.recv_thread = threading.Thread(target=self.udp_receive_loop) + self.recv_thread.daemon = True + self.recv_thread.start() + + # 启动状态更新定时器 + self.update_ui() + + def setup_ui(self): + """初始化用户界面""" + # 主框架 + main_frame = ttk.Frame(self.root, padding="10") + main_frame.pack(fill=tk.BOTH, expand=True) + + # 状态显示区 + status_frame = ttk.LabelFrame(main_frame, text="系统状态", padding="10") + status_frame.pack(fill=tk.X, pady=5) + + # 状态显示区 - 使用Notebook组织不同母线状态 + self.notebook = ttk.Notebook(status_frame) + self.notebook.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) + + # 高压母线状态页 + high_vol_frame = ttk.Frame(self.notebook) + self.notebook.add(high_vol_frame, text="高压母线") + self.setup_high_vol_ui(high_vol_frame) + + # 高压A母线状态页 + high_a_vol_frame = ttk.Frame(self.notebook) + self.notebook.add(high_a_vol_frame, text="高压A母线") + self.setup_high_a_vol_ui(high_a_vol_frame) + + # 仪表主母线状态页 + low_main_frame = ttk.Frame(self.notebook) + self.notebook.add(low_main_frame, text="仪表主母线") + self.setup_low_main_ui(low_main_frame) + + # 仪表母线状态页 + low_bus_frame = ttk.Frame(self.notebook) + self.notebook.add(low_bus_frame, text="仪表母线") + self.setup_low_bus_ui(low_bus_frame) + + # 控制区 + control_frame = ttk.LabelFrame(main_frame, text="控制面板", padding="10") + control_frame.pack(fill=tk.BOTH, expand=True, pady=5) + + # 状态显示区 - 使用Notebook组织不同母线状态 + self.notebook_c = ttk.Notebook(control_frame) + self.notebook_c.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) + + high_vol_control_frame = ttk.Frame(self.notebook_c) + self.notebook_c.add(high_vol_control_frame, text="高压母线") + self.setup_hvb_control(high_vol_control_frame) + + high_a_vol_control_frame = ttk.Frame(self.notebook_c) + self.notebook_c.add(high_a_vol_control_frame, text="高压A母线") + self.setup_hvba_control(high_a_vol_control_frame) + + low_main_control_frame = ttk.Frame(self.notebook_c) + self.notebook_c.add(low_main_control_frame, text="仪表主母线") + self.setup_lvmb_control(low_main_control_frame) + + low_bus_control_frame = ttk.Frame(self.notebook_c) + self.notebook_c.add(low_bus_control_frame, text="仪表母线") + self.setup_lvb_control(low_bus_control_frame) + + # 日志区 + log_frame = ttk.LabelFrame(main_frame, text="系统日志", padding="10") + log_frame.pack(fill=tk.BOTH, expand=True, pady=5) + + self.log_text = tk.Text(log_frame, height=10, state=tk.DISABLED) + self.log_text.pack(fill=tk.BOTH, expand=True) + + scrollbar = ttk.Scrollbar(log_frame, orient=tk.VERTICAL, command=self.log_text.yview) + scrollbar.pack(side=tk.RIGHT, fill=tk.Y) + self.log_text.config(yscrollcommand=scrollbar.set) + + def setup_hvb_control(self, parent): + """设置动力母线配电指令控制面板""" + frame = ttk.LabelFrame(parent, text="动力母线配电指令", padding="10") + frame.pack(fill=tk.X, pady=5) + + # 断路器控制按钮 + breaker_names = [ + "燃料电池断路器", "动力锂电池断路器", "推进电机断路器", + "锂电池组仪表断路器", "DC/DC模块断路器", "艏高压配电盒断路器", + "艉FT设备45断路器", "艉舵机开关1断路器", "艉舵机开关2断路器", + "FB备用断路器", "TYZ备用断路器", "备用断路器" + ] + + for i, name in enumerate(breaker_names): + row = i // 3 + col = i % 3 + btn_frame = ttk.Frame(frame) + btn_frame.grid(row=row, column=col, padx=5, pady=2, sticky=tk.W) + + ttk.Label(btn_frame, text=name).pack(side=tk.LEFT) + on_btn = ttk.Button(btn_frame, text="合", width=3, + command=lambda n=name: self.send_hvb_cmd(n, 1)) + on_btn.pack(side=tk.LEFT, padx=2) + off_btn = ttk.Button(btn_frame, text="分", width=3, + command=lambda n=name: self.send_hvb_cmd(n, 0)) + off_btn.pack(side=tk.LEFT, padx=2) + + def setup_hvba_control(self, parent): + """设置动力汇流排A配电指令控制面板""" + frame = ttk.LabelFrame(parent, text="动力汇流排A配电指令", padding="10") + frame.pack(fill=tk.X, pady=5) + + # 断路器控制按钮 + breaker_names = [ + "艏FT设备123断路器", "执行机构断路器", "桅舵机控制箱断路器", + "XCZ断路器", "艏舵控制箱断路器", "开盖启动气缸断路器" + ] + + for i, name in enumerate(breaker_names): + row = i // 3 + col = i % 3 + btn_frame = ttk.Frame(frame) + btn_frame.grid(row=row, column=col, padx=5, pady=2, sticky=tk.W) + + ttk.Label(btn_frame, text=name).pack(side=tk.LEFT) + on_btn = ttk.Button(btn_frame, text="合", width=3, + command=lambda n=name: self.send_hvba_cmd(n, 1)) + on_btn.pack(side=tk.LEFT, padx=2) + off_btn = ttk.Button(btn_frame, text="分", width=3, + command=lambda n=name: self.send_hvba_cmd(n, 0)) + off_btn.pack(side=tk.LEFT, padx=2) + + def setup_lvmb_control(self, parent): + """设置仪表母线配电指令控制面板""" + frame = ttk.LabelFrame(parent, text="仪表母线配电指令", padding="10") + frame.pack(fill=tk.X, pady=5) + + # 断路器控制按钮 + breaker_names = [ + "锂电池组仪表断路器", "艏低压配电盒断路器", "单元4仪表48V断路器", + "DC/C1直流配电板断路器", "备用断路器1", "备用断路器2", + "应急锂电池组2断路器" + ] + + for i, name in enumerate(breaker_names): + row = i // 3 + col = i % 3 + btn_frame = ttk.Frame(frame) + btn_frame.grid(row=row, column=col, padx=5, pady=2, sticky=tk.W) + + ttk.Label(btn_frame, text=name).pack(side=tk.LEFT) + on_btn = ttk.Button(btn_frame, text="合", width=3, + command=lambda n=name: self.send_lvmb_cmd(n, 1)) + on_btn.pack(side=tk.LEFT, padx=2) + off_btn = ttk.Button(btn_frame, text="分", width=3, + command=lambda n=name: self.send_lvmb_cmd(n, 0)) + off_btn.pack(side=tk.LEFT, padx=2) + + def setup_lvb_control(self, parent): + """设置仪表汇流排配电指令控制面板""" + frame = ttk.LabelFrame(parent, text="仪表汇流排配电指令", padding="10") + frame.pack(fill=tk.X, pady=5) + + # 断路器控制按钮 + breaker_names = [ + "单元1断路器", "单元2断路器", "单元3断路器", + "单元5断路器", "艏PZ设备断路器", "备用断路器1", + "备用断路器2", "应急锂电池组1断路器" + ] + + for i, name in enumerate(breaker_names): + row = i // 3 + col = i % 3 + btn_frame = ttk.Frame(frame) + btn_frame.grid(row=row, column=col, padx=5, pady=2, sticky=tk.W) + + ttk.Label(btn_frame, text=name).pack(side=tk.LEFT) + on_btn = ttk.Button(btn_frame, text="合", width=3, + command=lambda n=name: self.send_lvb_cmd(n, 1)) + on_btn.pack(side=tk.LEFT, padx=2) + off_btn = ttk.Button(btn_frame, text="分", width=3, + command=lambda n=name: self.send_lvb_cmd(n, 0)) + off_btn.pack(side=tk.LEFT, padx=2) + + def send_hvb_cmd(self, breaker_name, state): + """发送动力母线配电指令""" + cmd = msg_disHVBCmdMsg() + if breaker_name == "燃料电池断路器": + cmd.fuelCellCircuitBreaker = state + elif breaker_name == "动力锂电池断路器": + cmd.powerLithiumBatteryCircuitBreaker = state + elif breaker_name == "推进电机断路器": + cmd.propulsionMotorCircuitBreaker = state + elif breaker_name == "锂电池组仪表断路器": + cmd.lithiumBatteryGroupInstrumentCircuitBreaker = state + elif breaker_name == "DC/DC模块断路器": + cmd.dcDc5ModuleCircuitBreaker = state + elif breaker_name == "艏高压配电盒断路器": + cmd.bowHighVoltageDistributionBoxCircuitBreaker = state + elif breaker_name == "艉FT设备45断路器": + cmd.sternFTDevice45CircuitBreaker = state + elif breaker_name == "艉舵机开关1断路器": + cmd.sternRudderSwitch1CircuitBreaker = state + elif breaker_name == "艉舵机开关2断路器": + cmd.sternRudderSwitch2CircuitBreaker = state + elif breaker_name == "FB备用断路器": + cmd.fbReservedCircuitBreaker = state + elif breaker_name == "TYZ备用断路器": + cmd.tyzReservedCircuitBreaker = state + elif breaker_name == "备用断路器": + cmd.reservedCircuitBreaker = state + + self.send_udp_command(cmd.pack()) + self.log_message(f"发送动力母线配电指令: {breaker_name} {'合' if state else '分'}") + + def send_hvba_cmd(self, breaker_name, state): + """发送动力汇流排A配电指令""" + cmd = msg_disHVBACmdMsg() + if breaker_name == "艏FT设备123断路器": + cmd.bowFTDevice123CircuitBreaker = state + elif breaker_name == "执行机构断路器": + cmd.actuatorCircuitBreaker = state + elif breaker_name == "桅舵机控制箱断路器": + cmd.mastSteeringGearControlBoxCircuitBreaker = state + elif breaker_name == "XCZ断路器": + cmd.xczCircuitBreaker = state + elif breaker_name == "艏舵控制箱断路器": + cmd.bowRudderControlBoxCircuitBreaker = state + elif breaker_name == "开盖启动气缸断路器": + cmd.openWaterCoverStartCylinderCircuitBreaker = state + + self.send_udp_command(cmd.pack()) + self.log_message(f"发送动力汇流排A配电指令: {breaker_name} {'合' if state else '分'}") + + def send_lvmb_cmd(self, breaker_name, state): + """发送仪表母线配电指令""" + cmd = msg_disLVMBCmdMsg() + if breaker_name == "锂电池组仪表断路器": + cmd.lithiumBatteryGroupInstrumentCircuitBreaker = state + elif breaker_name == "艏低压配电盒断路器": + cmd.bowLowVoltageDistributionBoxCircuitBreaker = state + elif breaker_name == "单元4仪表48V断路器": + cmd.unit4InstrumentDC48VCircuitBreaker = state + elif breaker_name == "DC/C1直流配电板断路器": + cmd.dcC1DCDistributionPanelCircuitBreaker = state + elif breaker_name == "备用断路器1": + cmd.reservedCircuitBreaker1 = state + elif breaker_name == "备用断路器2": + cmd.reservedCircuitBreaker2 = state + elif breaker_name == "应急锂电池组2断路器": + cmd.emergencyLithiumBatteryGroup2CircuitBreaker = state + + self.send_udp_command(cmd.pack()) + self.log_message(f"发送仪表母线配电指令: {breaker_name} {'合' if state else '分'}") + + def send_lvb_cmd(self, breaker_name, state): + """发送仪表汇流排配电指令""" + cmd = msg_disLVBCmdMsg() + if breaker_name == "单元1断路器": + cmd.unit1CircuitBreaker = state + elif breaker_name == "单元2断路器": + cmd.unit2CircuitBreaker = state + elif breaker_name == "单元3断路器": + cmd.unit3CircuitBreaker = state + elif breaker_name == "单元5断路器": + cmd.unit5CircuitBreaker = state + elif breaker_name == "艏PZ设备断路器": + cmd.bowPZDeviceCircuitBreaker = state + elif breaker_name == "备用断路器1": + cmd.reservedCircuitBreaker1 = state + elif breaker_name == "备用断路器2": + cmd.reservedCircuitBreaker2 = state + elif breaker_name == "应急锂电池组1断路器": + cmd.emergencyLithiumBatteryGroup1CircuitBreaker = state + + self.send_udp_command(cmd.pack()) + self.log_message(f"发送仪表汇流排配电指令: {breaker_name} {'合' if state else '分'}") + + def udp_receive_loop(self): + """UDP接收消息循环""" + while self.running: + try: + data, addr = self.sock.recvfrom(1024) + self.process_udp_message(data) + except Exception as e: + self.log_message(f"接收错误: {str(e)}") + + def setup_high_vol_ui(self, parent): + """设置高压母线状态界面""" + # 初始化故障位列表 + self.high_vol_dcdc_fault1_bits = [] + self.high_vol_dcdc_fault2_bits = [] + + frame = ttk.LabelFrame(parent, text="高压母线状态") + frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) + + # 使用网格布局管理器 + frame.grid_columnconfigure(0, weight=1) + frame.grid_columnconfigure(1, weight=1) + frame.grid_columnconfigure(2, weight=1) + + # 电压显示 + ttk.Label(frame, text="动力母线电压(V):").grid(row=0, column=0, sticky=tk.W) + self.high_vol_power_voltage = ttk.Label(frame, text="0.0") + self.high_vol_power_voltage.grid(row=0, column=1, sticky=tk.W) + + ttk.Label(frame, text="A母线电压(V):").grid(row=0, column=2, sticky=tk.W) + self.high_vol_a_voltage = ttk.Label(frame, text="0.0") + self.high_vol_a_voltage.grid(row=0, column=3, sticky=tk.W) + + # 电流显示 + ttk.Label(frame, text="动力母线电流(A):").grid(row=1, column=0, sticky=tk.W) + self.high_vol_power_current = ttk.Label(frame, text="0.0") + self.high_vol_power_current.grid(row=1, column=1, sticky=tk.W) + + ttk.Label(frame, text="A母线电流(A):").grid(row=1, column=2, sticky=tk.W) + self.high_vol_a_current = ttk.Label(frame, text="0.0") + self.high_vol_a_current.grid(row=1, column=3, sticky=tk.W) + + # 断路器状态 + ttk.Label(frame, text="断路器状态:").grid(row=2, column=0, columnspan=4, sticky=tk.W) + self.high_vol_breakers = {} + breaker_names = list(self.status_data["high_vol_bus"]["breakers"].keys()) + + for i, name in enumerate(breaker_names): + ttk.Label(frame, text=name).grid(row=3+i//3, column=(i%3)*2, sticky=tk.W) + canvas = tk.Canvas(frame, width=20, height=20, bg="white") + canvas.grid(row=3+i//3, column=(i%3)*2+1, sticky=tk.W) + self.high_vol_breakers[name] = canvas + + # 绝缘状态 + ttk.Label(frame, text="动力母线绝缘:").grid(row=9, column=0, sticky=tk.W) + self.high_vol_power_insulation = ttk.Label(frame, text="正常") + self.high_vol_power_insulation.grid(row=9, column=1, sticky=tk.W) + + ttk.Label(frame, text="A母线绝缘:").grid(row=9, column=2, sticky=tk.W) + self.high_vol_a_insulation = ttk.Label(frame, text="正常") + self.high_vol_a_insulation.grid(row=9, column=3, sticky=tk.W) + + # 故障状态 - 扩展显示所有故障位 + fault_labels1 = ["过压", "欠压", "过流", "过热", "通讯", "硬件", "软件", "保留"] + fault_labels2 = ["模块1", "模块2", "模块3", "模块4", "模块5", "保留", "保留", "保留"] + + ttk.Label(frame, text="DC/DC故障字1:").grid(row=10, column=0, sticky=tk.W) + for i, label in enumerate(fault_labels1): + ttk.Label(frame, text=label).grid(row=11+i//4, column=(i%4)*2, sticky=tk.W) + canvas = tk.Canvas(frame, width=20, height=20, bg="white") + canvas.grid(row=11+i//4, column=(i%4)*2+1, sticky=tk.W) + self.high_vol_dcdc_fault1_bits.append(canvas) + + ttk.Label(frame, text="DC/DC故障字2:").grid(row=13, column=0, sticky=tk.W) + for i, label in enumerate(fault_labels2): + ttk.Label(frame, text=label).grid(row=14+i//4, column=(i%4)*2, sticky=tk.W) + canvas = tk.Canvas(frame, width=20, height=20, bg="white") + canvas.grid(row=14+i//4, column=(i%4)*2+1, sticky=tk.W) + self.high_vol_dcdc_fault2_bits.append(canvas) + + # 绝缘状态 - 详细显示 + ttk.Label(frame, text="动力母线绝缘:").grid(row=16, column=0, sticky=tk.W) + self.high_vol_power_insulation = ttk.Label(frame, text="正常(0.0MΩ)") + self.high_vol_power_insulation.grid(row=16, column=1, sticky=tk.W) + + ttk.Label(frame, text="A母线绝缘:").grid(row=16, column=2, sticky=tk.W) + self.high_vol_a_insulation = ttk.Label(frame, text="正常(0.0MΩ)") + self.high_vol_a_insulation.grid(row=16, column=3, sticky=tk.W) + + # 电流值显示 + current_labels = [ + ("动力母线电流(A):", "powerBusCurrent"), + ("A母线电流(A):", "busbarACurrent"), + ("DC/DC5模块电流(A):", "dcDc5ModuleCurrent"), + ("推进电机控制箱电流(A):", "propulsionMotorControlBoxCurrent"), + ("锂电池组表电流(A):", "lithiumBatteryGroupMeterCurrent"), + ("艏高压配电箱电流(A):", "bowHighVoltageDistributionBoxCurrent"), + ("艉FT设备45电流(A):", "sternFTDevice45Current"), + ("TYZ备用开关电流(A):", "tyzReservedSwitchCurrent"), + ("艉舵机开关1电流(A):", "sternRudderSwitch1Current"), + ("艉舵机开关2电流(A):", "sternRudderSwitch2Current"), + ("FB备用开关电流(A):", "fbReservedSwitchCurrent") + ] + + for i, (label, _) in enumerate(current_labels): + ttk.Label(frame, text=label).grid(row=17+i//2, column=(i%2)*2, sticky=tk.W) + label_var = ttk.Label(frame, text="0.0") + label_var.grid(row=17+i//2, column=(i%2)*2+1, sticky=tk.W) + setattr(self, f"high_vol_{current_labels[i][1]}", label_var) + + # 冷却水压力 + ttk.Label(frame, text="冷却水压力(MPa):").grid(row=23, column=0, sticky=tk.W) + self.high_vol_cool_water_pressure = ttk.Label(frame, text="0.00") + self.high_vol_cool_water_pressure.grid(row=23, column=1, sticky=tk.W) + + def setup_high_a_vol_ui(self, parent): + """设置高压A母线状态界面""" + frame = ttk.LabelFrame(parent, text="高压A母线状态") + frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) + + # 使用网格布局管理器 + frame.grid_columnconfigure(0, weight=1) + frame.grid_columnconfigure(1, weight=1) + frame.grid_columnconfigure(2, weight=1) + + # 电压显示 - 添加详细说明 + ttk.Label(frame, text="高压B母线电压(V):").grid(row=0, column=0, sticky=tk.W) + self.high_a_vol_voltage = ttk.Label(frame, text="0.0") + self.high_a_vol_voltage.grid(row=0, column=1, sticky=tk.W) + + # 电流显示 - 统一格式 + ttk.Label(frame, text="高压B母线电流(A):").grid(row=1, column=0, sticky=tk.W) + self.high_a_vol_current = ttk.Label(frame, text="0.0") + self.high_a_vol_current.grid(row=1, column=1, sticky=tk.W) + + ttk.Label(frame, text="艏部FT设备123电流(A):").grid(row=2, column=0, sticky=tk.W) + self.high_a_vol_bow_ft_current = ttk.Label(frame, text="0.0") + self.high_a_vol_bow_ft_current.grid(row=2, column=1, sticky=tk.W) + + ttk.Label(frame, text="执行机构工作电流(A):").grid(row=3, column=0, sticky=tk.W) + self.high_a_vol_actuator_current = ttk.Label(frame, text="0.0") + self.high_a_vol_actuator_current.grid(row=3, column=1, sticky=tk.W) + + # 断路器状态 - 添加详细说明 + ttk.Label(frame, text="高压A母线断路器状态:").grid(row=4, column=0, columnspan=4, sticky=tk.W) + self.high_a_vol_breakers = {} + breaker_names = list(self.status_data["high_a_vol_bus"]["breakers"].keys()) + + for i, name in enumerate(breaker_names): + ttk.Label(frame, text=f"{name}状态:").grid(row=5+i//2, column=(i%2)*2, sticky=tk.W) + canvas = tk.Canvas(frame, width=20, height=20, bg="white") + canvas.grid(row=5+i//2, column=(i%2)*2+1, sticky=tk.W) + self.high_a_vol_breakers[name] = canvas + + # 报警状态 - 更详细描述 + ttk.Label(frame, text="仪表电源故障状态:").grid(row=8, column=0, sticky=tk.W) + self.high_a_vol_instrument_power_fault = ttk.Label(frame, text="正常") + self.high_a_vol_instrument_power_fault.grid(row=8, column=1, sticky=tk.W) + + ttk.Label(frame, text="应急电源故障状态:").grid(row=8, column=2, sticky=tk.W) + self.high_a_vol_emergency_power_fault = ttk.Label(frame, text="正常") + self.high_a_vol_emergency_power_fault.grid(row=8, column=3, sticky=tk.W) + + ttk.Label(frame, text="进水报警:").grid(row=9, column=0, sticky=tk.W) + self.high_a_vol_water_alarm = ttk.Label(frame, text="无") + self.high_a_vol_water_alarm.grid(row=9, column=1, sticky=tk.W) + + def process_udp_message(self, data): + """处理接收到的UDP消息""" + try: + msg_id = int.from_bytes(data[2:4], byteorder='little') + + if msg_id == 0x0005: # 高压母线状态 + msg = msg_disHighVolBusFbMsg() + if msg.unpack(data): + bus = self.status_data["high_vol_bus"] + bus["voltage"]["动力母线电压"] = msg.powerBusVoltage / 10.0 + bus["voltage"]["A母线电压"] = msg.busbarAVoltage / 10.0 + bus["current"]["动力母线电流"] = msg.powerBusCurrent / 10.0 + bus["current"]["DC/DC5模块电流"] = msg.dcDc5ModuleCurrent / 10.0 + bus["current"]["推进电机控制箱电流"] = msg.propulsionMotorControlBoxCurrent / 10.0 + bus["current"]["A母线电流"] = msg.busbarACurrent / 10.0 + bus["current"]["锂电池组仪表电流"] = msg.lithiumBatteryGroupMeterCurrent / 10.0 + bus["current"]["艏高压配电盒电流"] = msg.bowHighVoltageDistributionBoxCurrent / 10.0 + bus["current"]["艉FT设备45电流"] = msg.sternFTDevice45Current / 10.0 + bus["current"]["TYZ备用开关电流"] = msg.tyzReservedSwitchCurrent / 10.0 + bus["current"]["艉舵机开关1电流"] = msg.sternRudderSwitch1Current / 10.0 + bus["current"]["备用电流1"] = msg.reservedCurrent1 / 10.0 + bus["current"]["艉舵机开关2电流"] = msg.sternRudderSwitch2Current / 10.0 + bus["current"]["备用电流2"] = msg.reservedCurrent2 / 10.0 + bus["current"]["FB备用开关电流"] = msg.fbReservedSwitchCurrent / 10.0 + bus["current"]["备用电流3"] = msg.reservedCurrent3 / 10.0 + + bus["breakers"]["燃料电池断路器"] = msg.fuelCellCircuitBreaker + bus["breakers"]["动力锂电池断路器"] = msg.powerLithiumBatteryCircuitBreaker + bus["breakers"]["推进电机断路器"] = msg.propulsionMotorCircuitBreaker + bus["breakers"]["锂电池组仪表断路器"] = msg.lithiumBatteryGroupInstrumentCircuitBreaker + bus["breakers"]["DC/DC模块断路器"] = msg.dcDc5ModuleCircuitBreaker + bus["breakers"]["艏高压配电盒断路器"] = msg.bowHighVoltageDistributionBoxCircuitBreaker + bus["breakers"]["艉FT设备45断路器"] = msg.sternFTDevice45CircuitBreaker + bus["breakers"]["艉舵机开关1断路器"] = msg.sternRudderSwitch1CircuitBreaker + bus["breakers"]["艉舵机开关2断路器"] = msg.sternRudderSwitch2CircuitBreaker + bus["breakers"]["FB备用断路器"] = msg.fbReservedCircuitBreaker + bus["breakers"]["TYZ备用断路器"] = msg.tyzReservedCircuitBreaker + bus["breakers"]["备用断路器"] = msg.reservedCircuitBreaker + + bus["faults"]["DC/DC故障1"] = msg.dcDcFaultWord1 + bus["faults"]["DC/DC故障2"] = msg.dcDcFaultWord2 + bus["insulation"]["动力母线绝缘状态"] = msg.powerBusInsulationStatus + bus["insulation"]["A母线绝缘状态"] = msg.aBusInsulationStatus + bus["alarms"]["仪表电源丢失信号"] = msg.meterPowerLossSignal + bus["alarms"]["应急电源丢失信号"] = msg.emergencyPowerLossSignal + bus["cool_water_pressure"] = msg.coolWaterPressure / 10.0 + + # 更新UI显示 + self.update_high_vol_ui(bus) + self.log_message("收到高压母线状态更新") + + elif msg_id == 0x0006: # 高压A母线状态 + msg = msg_disHighAVolBusFbMsg() + if msg.unpack(data): + bus = self.status_data["high_a_vol_bus"] + bus["voltage"]["B母线电压"] = msg.busbarBVoltage / 10.0 + bus["current"]["B母线电流"] = msg.busbarBCurrent / 10.0 + bus["current"]["艏FT设备123电流"] = msg.bowFTDevice123Current / 10.0 + bus["current"]["执行机构电流"] = msg.actuatorCurrent / 10.0 + bus["current"]["桅舵机控制箱电流"] = msg.mastSteeringGearControlBoxCurrent / 10.0 + bus["current"]["XCZ电流"] = msg.xczCurrent / 10.0 + bus["current"]["艏舵控制箱电流"] = msg.bowRudderControlBoxCurrent / 10.0 + bus["current"]["开盖启动气缸电流"] = msg.openWaterCoverStartCylinderCurrent / 10.0 + + bus["breakers"]["艏FT设备123断路器"] = msg.bowFTDevice123CircuitBreaker + bus["breakers"]["执行机构断路器"] = msg.actuatorCircuitBreaker + bus["breakers"]["桅舵机控制箱断路器"] = msg.mastSteeringGearControlBoxCircuitBreaker + bus["breakers"]["XCZ断路器"] = msg.xczCircuitBreaker + bus["breakers"]["艏舵控制箱断路器"] = msg.bowRudderControlBoxCircuitBreaker + bus["breakers"]["开盖启动气缸断路器"] = msg.openWaterCoverStartCylinderCircuitBreaker + + bus["alarms"]["仪表电源故障"] = msg.instrumentPowerFailureSignal + bus["alarms"]["应急电源故障"] = msg.emergencyPowerFailureSignal + bus["alarms"]["进水报警"] = msg.waterIngressionAlarm + + self.log_message("收到高压A母线状态更新") + + elif msg_id == 0x0007: # 仪表主母线状态 + msg = msg_disLowMainBusFbMsg() + if msg.unpack(data): + bus = self.status_data["low_main_bus"] + bus["voltage"]["仪表母线电压"] = msg.instrumentBusbarVoltage / 10.0 + bus["voltage"]["应急2母线电压"] = msg.emergency2BusbarVoltage / 10.0 + bus["current"]["艏低压配电盒电流"] = msg.bowLowVoltageDistributionBoxCurrent / 10.0 + bus["current"]["DC/C1仪表48V电流"] = msg.dcC1InstrumentDC48VCurrent / 10.0 + bus["current"]["备用电流1"] = msg.reservedCurrent1 / 10.0 + bus["current"]["应急锂电池组2电流"] = msg.emergencyLithiumBatteryGroup2Current / 10.0 + bus["current"]["锂电池组仪表电流"] = msg.lithiumBatteryGroupInstrumentCurrent / 10.0 + bus["current"]["单元4仪表48V电流"] = msg.unit4InstrumentDC48VCurrent / 10.0 + bus["current"]["备用电流2"] = msg.reservedCurrent2 / 10.0 + bus["current"]["综合能量管理系统应急DC48V电流"] = msg.compositeEnergyManagementSystemEmergencyDC48VCurrent / 10.0 + bus["current"]["燃料电池安全系统应急DC48V电流"] = msg.fuelCellSecuritySystemEmergencyDC48VCurrent / 10.0 + bus["current"]["PLC控制电源电流"] = msg.plcControlPowerCurrent / 10.0 + + bus["breakers"]["锂电池组仪表断路器"] = msg.lithiumBatteryGroupInstrumentCircuitBreaker + bus["breakers"]["艏低压配电盒断路器"] = msg.bowLowVoltageDistributionBoxCircuitBreaker + bus["breakers"]["单元4仪表48V断路器"] = msg.unit4InstrumentDC48VCircuitBreaker + bus["breakers"]["DC/C1直流配电板断路器"] = msg.dcC1DCDistributionPanelCircuitBreaker + bus["breakers"]["备用断路器1"] = msg.reservedCircuitBreaker1 + bus["breakers"]["备用断路器2"] = msg.reservedCircuitBreaker2 + bus["breakers"]["应急锂电池组2断路器"] = msg.emergencyLithiumBatteryGroup2CircuitBreaker + + bus["alarms"]["仪表电源故障"] = msg.instrumentPowerFailureSignal + bus["alarms"]["应急电源故障"] = msg.emergencyPowerFailureSignal + bus["insulation"] = msg.instrumentBusbarInsulationLow + + self.log_message("收到仪表主母线状态更新") + + elif msg_id == 0x0008: # 仪表母线状态 + msg = msg_disLowBusFbMsg() + if msg.unpack(data): + bus = self.status_data["low_bus"] + bus["voltage"]["仪表母线电压"] = msg.instrumentBusbarVoltage / 10.0 + bus["voltage"]["应急1母线电压"] = msg.emergency1BusbarVoltage / 10.0 + bus["current"]["仪表母线电流"] = msg.instrumentBusbarCurrent / 10.0 + bus["current"]["单元1电流"] = msg.unit1Current / 10.0 + bus["current"]["单元2电流"] = msg.unit2Current / 10.0 + bus["current"]["单元3电流"] = msg.unit3Current / 10.0 + bus["current"]["单元5电流"] = msg.unit5Current / 10.0 + bus["current"]["艏PZ设备电流"] = msg.bowPZDeviceCurrent / 10.0 + bus["current"]["应急锂电池组1电流"] = msg.emergencyLithiumBatteryGroup1Current / 10.0 + + bus["breakers"]["单元1断路器"] = msg.unit1CircuitBreaker + bus["breakers"]["单元2断路器"] = msg.unit2CircuitBreaker + bus["breakers"]["单元3断路器"] = msg.unit3CircuitBreaker + bus["breakers"]["单元5断路器"] = msg.unit5CircuitBreaker + bus["breakers"]["艏PZ设备断路器"] = msg.bowPZDeviceCircuitBreaker + bus["breakers"]["备用断路器1"] = msg.reservedCircuitBreaker1 + bus["breakers"]["备用断路器2"] = msg.reservedCircuitBreaker2 + bus["breakers"]["应急锂电池组1断路器"] = msg.emergencyLithiumBatteryGroup1CircuitBreaker + + bus["alarms"]["电源故障信号"] = msg.powerFailureSignal + bus["alarms"]["进水报警"] = msg.waterIngressionAlarm + + self.log_message("收到仪表母线状态更新") + + except Exception as e: + self.log_message(f"消息处理错误: {str(e)}") + + def update_high_vol_ui(self, status): + """更新高压母线UI显示""" + # 更新电压值 + self.high_vol_power_voltage.config(text=f"{status['voltage']['动力母线电压']:.1f}") + self.high_vol_a_voltage.config(text=f"{status['voltage']['A母线电压']:.1f}") + + # 更新故障位显示 + for i in range(8): + color = "red" if (status['faults']['DC/DC故障1'] & (1 << i)) else "green" + self.high_vol_dcdc_fault1_bits[i].delete("all") + self.high_vol_dcdc_fault1_bits[i].create_oval(2, 2, 18, 18, fill=color) + + color = "red" if (status['faults']['DC/DC故障2'] & (1 << i)) else "green" + self.high_vol_dcdc_fault2_bits[i].delete("all") + self.high_vol_dcdc_fault2_bits[i].create_oval(2, 2, 18, 18, fill=color) + + # 更新绝缘状态 + power_insul = "正常" if status['insulation']['动力母线绝缘状态'] == 0 else "异常" + a_insul = "正常" if status['insulation']['A母线绝缘状态'] == 0 else "异常" + self.high_vol_power_insulation.config(text=f"{power_insul}") + self.high_vol_a_insulation.config(text=f"{a_insul}") + + # 更新电流值 + for current_name in status['current']: + if hasattr(self, f"high_vol_{current_name}"): + getattr(self, f"high_vol_{current_name}").config(text=f"{status['current'][current_name]:.1f}") + + # 更新冷却水压力 + self.high_vol_cool_water_pressure.config(text=f"{status['cool_water_pressure']:.2f}") + + def setup_low_main_ui(self, parent): + """设置仪表主母线状态界面""" + frame = ttk.LabelFrame(parent, text="仪表主母线状态") + frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) + + # 电压显示 + ttk.Label(frame, text="仪表母线电压(V):").grid(row=0, column=0, sticky=tk.W) + self.low_main_instrument_voltage = ttk.Label(frame, text="0.0") + self.low_main_instrument_voltage.grid(row=0, column=1, sticky=tk.W) + + ttk.Label(frame, text="应急2母线电压(V):").grid(row=0, column=2, sticky=tk.W) + self.low_main_emergency2_voltage = ttk.Label(frame, text="0.0") + self.low_main_emergency2_voltage.grid(row=0, column=3, sticky=tk.W) + + # 电流显示 + ttk.Label(frame, text="艏低压配电盒电流(A):").grid(row=1, column=0, sticky=tk.W) + self.low_main_bow_current = ttk.Label(frame, text="0.0") + self.low_main_bow_current.grid(row=1, column=1, sticky=tk.W) + + ttk.Label(frame, text="锂电池组仪表电流(A):").grid(row=1, column=2, sticky=tk.W) + self.low_main_battery_current = ttk.Label(frame, text="0.0") + self.low_main_battery_current.grid(row=1, column=3, sticky=tk.W) + + # 断路器状态 + ttk.Label(frame, text="断路器状态:").grid(row=2, column=0, columnspan=4, sticky=tk.W) + self.low_main_breakers = {} + breaker_names = list(self.status_data["low_main_bus"]["breakers"].keys()) + + for i, name in enumerate(breaker_names): + row = 3 + i//2 + col = (i%2)*2 + ttk.Label(frame, text=name).grid(row=row, column=col, sticky=tk.W) + canvas = tk.Canvas(frame, width=20, height=20, bg="white") + canvas.grid(row=row, column=col+1, sticky=tk.W) + self.low_main_breakers[name] = canvas + + # 报警状态 + ttk.Label(frame, text="仪表电源故障:").grid(row=8, column=0, sticky=tk.W) + self.low_main_instrument_fault = ttk.Label(frame, text="无") + self.low_main_instrument_fault.grid(row=8, column=1, sticky=tk.W) + + ttk.Label(frame, text="应急电源故障:").grid(row=8, column=2, sticky=tk.W) + self.low_main_emergency_fault = ttk.Label(frame, text="无") + self.low_main_emergency_fault.grid(row=8, column=3, sticky=tk.W) + + # 报警状态 + ttk.Label(frame, text="仪表电源故障:").grid(row=8, column=0, sticky=tk.W) + self.low_main_instrument_fault = ttk.Label(frame, text="无") + self.low_main_instrument_fault.grid(row=8, column=1, sticky=tk.W) + + ttk.Label(frame, text="应急电源故障:").grid(row=8, column=2, sticky=tk.W) + self.low_main_emergency_fault = ttk.Label(frame, text="无") + self.low_main_emergency_fault.grid(row=8, column=3, sticky=tk.W) + + # 绝缘状态 + ttk.Label(frame, text="绝缘状态:").grid(row=9, column=0, sticky=tk.W) + self.low_main_insulation = ttk.Label(frame, text="正常") + self.low_main_insulation.grid(row=9, column=1, sticky=tk.W) + + return frame + + def setup_low_bus_ui(self, parent): + """设置仪表母线状态界面""" + frame = ttk.LabelFrame(parent, text="仪表母线状态") + frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) + + # 电压显示 + ttk.Label(frame, text="仪表母线电压(V):").grid(row=0, column=0, sticky=tk.W) + self.low_bus_instrument_voltage = ttk.Label(frame, text="0.0") + self.low_bus_instrument_voltage.grid(row=0, column=1, sticky=tk.W) + + ttk.Label(frame, text="应急1母线电压(V):").grid(row=0, column=2, sticky=tk.W) + self.low_bus_emergency1_voltage = ttk.Label(frame, text="0.0") + self.low_bus_emergency1_voltage.grid(row=0, column=3, sticky=tk.W) + + # 电流显示 + ttk.Label(frame, text="单元1电流(A):").grid(row=1, column=0, sticky=tk.W) + self.low_bus_unit1_current = ttk.Label(frame, text="0.0") + self.low_bus_unit1_current.grid(row=1, column=1, sticky=tk.W) + + ttk.Label(frame, text="单元2电流(A):").grid(row=1, column=2, sticky=tk.W) + self.low_bus_unit2_current = ttk.Label(frame, text="0.0") + self.low_bus_unit2_current.grid(row=1, column=3, sticky=tk.W) + + # 断路器状态 + ttk.Label(frame, text="断路器状态:").grid(row=2, column=0, columnspan=4, sticky=tk.W) + self.low_bus_breakers = {} + breaker_names = list(self.status_data["low_bus"]["breakers"].keys()) + + for i, name in enumerate(breaker_names): + row = 3 + i//2 + col = (i%2)*2 + ttk.Label(frame, text=name).grid(row=row, column=col, sticky=tk.W) + canvas = tk.Canvas(frame, width=20, height=20, bg="white") + canvas.grid(row=row, column=col+1, sticky=tk.W) + self.low_bus_breakers[name] = canvas + + # 报警状态 + ttk.Label(frame, text="电源故障信号:").grid(row=8, column=0, sticky=tk.W) + self.low_bus_power_fault = ttk.Label(frame, text="无") + self.low_bus_power_fault.grid(row=8, column=1, sticky=tk.W) + + ttk.Label(frame, text="进水报警:").grid(row=8, column=2, sticky=tk.W) + self.low_bus_water_alarm = ttk.Label(frame, text="无") + self.low_bus_water_alarm.grid(row=8, column=3, sticky=tk.W) + + # 报警状态 + ttk.Label(frame, text="电源故障信号:").grid(row=8, column=0, sticky=tk.W) + self.low_bus_power_fault = ttk.Label(frame, text="无") + self.low_bus_power_fault.grid(row=8, column=1, sticky=tk.W) + + ttk.Label(frame, text="进水报警:").grid(row=8, column=2, sticky=tk.W) + self.low_bus_water_alarm = ttk.Label(frame, text="无") + self.low_bus_water_alarm.grid(row=8, column=3, sticky=tk.W) + + return frame + + def send_udp_command(self, data): + """发送UDP命令""" + try: + self.sock.sendto(data, (self.udp_ip, self.udp_port + 1)) + except Exception as e: + self.log_message(f"发送命令失败: {str(e)}") + + def update_ui(self): + """更新界面状态""" + # 更新高压母线状态 + high_vol = self.status_data["high_vol_bus"] + self.high_vol_power_voltage.config(text=f"{high_vol['voltage']['动力母线电压']:.1f} V") + self.high_vol_a_voltage.config(text=f"{high_vol['voltage']['A母线电压']:.1f} V") + self.high_vol_power_current.config(text=f"{high_vol['current']['动力母线电流']:.1f} A") + self.high_vol_a_current.config(text=f"{high_vol['current']['A母线电流']:.1f} A") + + for name, canvas in self.high_vol_breakers.items(): + state = high_vol["breakers"].get(name, 0) + color = "green" if state else "red" + canvas.create_oval(2, 2, 18, 18, fill=color, outline="black") + + self.high_vol_power_insulation.config( + text="正常" if high_vol["insulation"]["动力母线绝缘状态"] == 0 else "异常" + ) + self.high_vol_a_insulation.config( + text="正常" if high_vol["insulation"]["A母线绝缘状态"] == 0 else "异常" + ) + + faults = [] + if high_vol["faults"]["DC/DC故障1"]: + faults.append("DC/DC故障1") + if high_vol["faults"]["DC/DC故障2"]: + faults.append("DC/DC故障2") + + # 更新故障位显示 + for i in range(8): + color = "red" if (high_vol["faults"]["DC/DC故障1"] & (1 << i)) else "green" + self.high_vol_dcdc_fault1_bits[i].delete("all") + self.high_vol_dcdc_fault1_bits[i].create_oval(2, 2, 18, 18, fill=color) + + color = "red" if (high_vol["faults"]["DC/DC故障2"] & (1 << i)) else "green" + self.high_vol_dcdc_fault2_bits[i].delete("all") + self.high_vol_dcdc_fault2_bits[i].create_oval(2, 2, 18, 18, fill=color) + + # 更新高压A母线状态 + high_a_vol = self.status_data["high_a_vol_bus"] + self.high_a_vol_voltage.config(text=f"{high_a_vol['voltage']['B母线电压']:.1f} V") + self.high_a_vol_current.config(text=f"{high_a_vol['current']['B母线电流']:.1f} A") + + for name, canvas in self.high_a_vol_breakers.items(): + state = high_a_vol["breakers"].get(name, 0) + color = "green" if state else "red" + canvas.create_oval(2, 2, 18, 18, fill=color, outline="black") + + # 更新仪表主母线状态 + low_main = self.status_data["low_main_bus"] + for name, canvas in self.low_main_breakers.items(): + state = low_main["breakers"].get(name, 0) + color = "green" if state else "red" + canvas.create_oval(2, 2, 18, 18, fill=color, outline="black") + + # 更新仪表母线状态 + low_bus = self.status_data["low_bus"] + for name, canvas in self.low_bus_breakers.items(): + state = low_bus["breakers"].get(name, 0) + color = "green" if state else "red" + canvas.create_oval(2, 2, 18, 18, fill=color, outline="black") + + self.high_a_vol_instrument_power_fault.config( + text="无" if not high_a_vol["alarms"]["仪表电源故障"] else "有" + ) + self.high_a_vol_emergency_power_fault.config( + text="无" if not high_a_vol["alarms"]["应急电源故障"] else "有" + ) + self.high_a_vol_water_alarm.config( + text="无" if not high_a_vol["alarms"]["进水报警"] else "有" + ) + + # 更新仪表主母线状态 + low_main = self.status_data["low_main_bus"] + self.low_main_instrument_voltage.config(text=f"{low_main['voltage']['仪表母线电压']:.1f}") + self.low_main_emergency2_voltage.config(text=f"{low_main['voltage']['应急2母线电压']:.1f}") + self.low_main_bow_current.config(text=f"{low_main['current']['艏低压配电盒电流']:.1f}") + self.low_main_battery_current.config(text=f"{low_main['current']['锂电池组仪表电流']:.1f}") + + for name, canvas in self.low_main_breakers.items(): + state = low_main["breakers"].get(name, 0) + color = "green" if state else "red" + canvas.create_oval(2, 2, 18, 18, fill=color, outline="black") + + self.low_main_instrument_fault.config( + text="无" if not low_main["alarms"]["仪表电源故障"] else "有" + ) + self.low_main_emergency_fault.config( + text="无" if not low_main["alarms"]["应急电源故障"] else "有" + ) + self.low_main_insulation.config( + text="正常" if not low_main["insulation"] else "异常" + ) + + # 更新仪表母线状态 + low_bus = self.status_data["low_bus"] + self.low_bus_instrument_voltage.config(text=f"{low_bus['voltage']['仪表母线电压']:.1f}") + self.low_bus_emergency1_voltage.config(text=f"{low_bus['voltage']['应急1母线电压']:.1f}") + self.low_bus_unit1_current.config(text=f"{low_bus['current']['单元1电流']:.1f}") + self.low_bus_unit2_current.config(text=f"{low_bus['current']['单元2电流']:.1f}") + + for name, canvas in self.low_bus_breakers.items(): + state = low_bus["breakers"].get(name, 0) + color = "green" if state else "red" + canvas.create_oval(2, 2, 18, 18, fill=color, outline="black") + + self.low_bus_power_fault.config( + text="无" if not low_bus["alarms"]["电源故障信号"] else "有" + ) + self.low_bus_water_alarm.config( + text="无" if not low_bus["alarms"]["进水报警"] else "有" + ) + + # 每500ms更新一次 + self.root.after(500, self.update_ui) + + def log_message(self, message): + """记录日志消息""" + timestamp = time.strftime("%Y-%m-%d %H:%M:%S") + self.log_text.config(state=tk.NORMAL) + self.log_text.insert(tk.END, f"[{timestamp}] {message}\n") + self.log_text.config(state=tk.DISABLED) + self.log_text.see(tk.END) + + def on_closing(self): + """窗口关闭事件处理""" + self.running = False + self.sock.close() + self.root.destroy() +if __name__ == "__main__": + root = tk.Tk() + app = PowerManagerApp(root) + + root.protocol("WM_DELETE_WINDOW", app.on_closing) + root.mainloop() + while True: + app.status_data["high_vol_bus"]["voltage"]["动力母线电压"] += 0.1 + app.status_data["high_vol_bus"]["voltage"]["A母线电压"] += 0.1 + app.status_data["high_vol_bus"]["current"]["动力母线电流"] += 0.1 + app.status_data["high_vol_bus"]["current"]["A母线电流"] += 0.1 + # app.status_data["insulation"]["动力母线绝缘状态"] =0 + app.status_data["high_vol_bus"]["insulation"]["A母线绝缘状态"] = 1 + app.status_data["high_vol_bus"]["faults"]["DC/DC故障1"] = 1 + app.status_data["high_vol_bus"]["faults"]["DC/DC故障2"] = 1 + app.status_data["high_vol_bus"]["breakers"]["燃料电池断路器"] = 1 + app.status_data["high_vol_bus"]["breakers"]["动力锂电池断路器"] = 1 + app.status_data["high_vol_bus"]["breakers"]["推进电机断路器"] = 1 + app.status_data["high_vol_bus"]["breakers"]["锂电池组仪表断路器"] = 1 + app.update_ui() + time.sleep(1) + pass diff --git a/test/disSysTest/test.py b/test/disSysTest/test.py new file mode 100644 index 0000000..7a6f5c0 --- /dev/null +++ b/test/disSysTest/test.py @@ -0,0 +1,230 @@ +import socket +import struct +import threading +import time +from udpMsg import ( + msg_disHighVolBusFbMsg, + msg_disHighAVolBusFbMsg, + msg_disLowMainBusFbMsg, + msg_disLowBusFbMsg, + msg_disHVBCmdMsg, + msg_disHVBACmdMsg, + msg_disLVMBCmdMsg, + msg_disLVBCmdMsg +) + +class PowerManagerSimulator: + def __init__(self, host='127.0.0.1', port=5001): + self.host = host + self.port = port + self.running = False + self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + self.sock.bind((host, port)) + + # 初始化消息对象 + self.high_vol_fb = msg_disHighVolBusFbMsg() + self.high_a_vol_fb = msg_disHighAVolBusFbMsg() + self.low_main_fb = msg_disLowMainBusFbMsg() + self.low_bus_fb = msg_disLowBusFbMsg() + + # 模拟数据初始化 + self._init_sim_data() + + def _init_sim_data(self): + """初始化模拟数据""" + # 高压母线反馈数据 - 测试所有成员 + self.high_vol_fb.fuelCellCircuitBreaker = 1 + self.high_vol_fb.powerLithiumBatteryCircuitBreaker = 1 + self.high_vol_fb.propulsionMotorCircuitBreaker = 1 + self.high_vol_fb.lithiumBatteryGroupInstrumentCircuitBreaker = 1 + self.high_vol_fb.dcDc5ModuleCircuitBreaker = 1 + self.high_vol_fb.bowHighVoltageDistributionBoxCircuitBreaker = 1 + self.high_vol_fb.sternFTDevice45CircuitBreaker = 1 + self.high_vol_fb.sternRudderSwitch1CircuitBreaker = 1 + self.high_vol_fb.sternRudderSwitch2CircuitBreaker = 1 + self.high_vol_fb.fbReservedCircuitBreaker = 0 + self.high_vol_fb.tyzReservedCircuitBreaker = 0 + self.high_vol_fb.reservedCircuitBreaker = 0 + self.high_vol_fb.dcDcFaultWord1 = 0x55 # 测试故障模式 + self.high_vol_fb.dcDcFaultWord2 = 0xAA + self.high_vol_fb.powerBusInsulationStatus = 1 + self.high_vol_fb.aBusInsulationStatus = 1 + self.high_vol_fb.meterPowerLossSignal = 0 + self.high_vol_fb.emergencyPowerLossSignal = 0 + self.high_vol_fb.powerBusVoltage = 600 # 正常值 + self.high_vol_fb.dcDc5ModuleCurrent = 50 + self.high_vol_fb.powerBusCurrent = 100 + self.high_vol_fb.busbarAVoltage = 600 + self.high_vol_fb.propulsionMotorControlBoxCurrent = 80 + self.high_vol_fb.busbarACurrent = 50 + self.high_vol_fb.lithiumBatteryGroupMeterCurrent = 30 + self.high_vol_fb.bowHighVoltageDistributionBoxCurrent = 20 + self.high_vol_fb.sternFTDevice45Current = 15 + self.high_vol_fb.tyzReservedSwitchCurrent = 0 + self.high_vol_fb.sternRudderSwitch1Current = 10 + self.high_vol_fb.reservedCurrent1 = 0 + self.high_vol_fb.sternRudderSwitch2Current = 10 + self.high_vol_fb.reservedCurrent2 = 0 + self.high_vol_fb.fbReservedSwitchCurrent = 0 + self.high_vol_fb.reservedCurrent3 = 0 + self.high_vol_fb.coolWaterPressure = 100 + + # 高压A母线反馈数据 - 测试所有成员 + self.high_a_vol_fb.bowFTDevice123CircuitBreaker = 1 + self.high_a_vol_fb.actuatorCircuitBreaker = 1 + self.high_a_vol_fb.mastSteeringGearControlBoxCircuitBreaker = 1 + self.high_a_vol_fb.xczCircuitBreaker = 1 + self.high_a_vol_fb.bowRudderControlBoxCircuitBreaker = 1 + self.high_a_vol_fb.openWaterCoverStartCylinderCircuitBreaker = 0 + self.high_a_vol_fb.instrumentPowerFailureSignal = 0 + self.high_a_vol_fb.emergencyPowerFailureSignal = 0 + self.high_a_vol_fb.waterIngressionAlarm = 0 + self.high_a_vol_fb.busbarBVoltage = 600 + self.high_a_vol_fb.busbarBCurrent = 30 + self.high_a_vol_fb.bowFTDevice123Current = 20 + self.high_a_vol_fb.actuatorCurrent = 15 + self.high_a_vol_fb.mastSteeringGearControlBoxCurrent = 10 + self.high_a_vol_fb.xczCurrent = 5 + self.high_a_vol_fb.bowRudderControlBoxCurrent = 8 + self.high_a_vol_fb.openWaterCoverStartCylinderCurrent = 0 + + # 仪表主母线反馈数据 - 测试所有成员 + self.low_main_fb.lithiumBatteryGroupInstrumentCircuitBreaker = 1 + self.low_main_fb.bowLowVoltageDistributionBoxCircuitBreaker = 1 + self.low_main_fb.unit4InstrumentDC48VCircuitBreaker = 1 + self.low_main_fb.dcC1DCDistributionPanelCircuitBreaker = 1 + self.low_main_fb.reservedCircuitBreaker1 = 0 + self.low_main_fb.reservedCircuitBreaker2 = 0 + self.low_main_fb.emergencyLithiumBatteryGroup2CircuitBreaker = 0 + self.low_main_fb.instrumentPowerFailureSignal = 0 + self.low_main_fb.emergencyPowerFailureSignal = 0 + self.low_main_fb.instrumentBusbarInsulationLow = 0 + self.low_main_fb.instrumentBusbarVoltage = 48 + self.low_main_fb.bowLowVoltageDistributionBoxCurrent = 10 + self.low_main_fb.dcC1InstrumentDC48VCurrent = 5 + self.low_main_fb.reservedCurrent1 = 0 + self.low_main_fb.emergencyLithiumBatteryGroup2Current = 0 + self.low_main_fb.lithiumBatteryGroupInstrumentCurrent = 20 + self.low_main_fb.unit4InstrumentDC48VCurrent = 5 + self.low_main_fb.reservedCurrent2 = 0 + self.low_main_fb.emergency2BusbarVoltage = 48 + self.low_main_fb.compositeEnergyManagementSystemEmergencyDC48VCurrent = 2 + self.low_main_fb.fuelCellSecuritySystemEmergencyDC48VCurrent = 2 + self.low_main_fb.plcControlPowerCurrent = 1 + + # 仪表汇流排反馈数据 - 测试所有成员 + self.low_bus_fb.unit1CircuitBreaker = 1 + self.low_bus_fb.unit2CircuitBreaker = 1 + self.low_bus_fb.unit3CircuitBreaker = 1 + self.low_bus_fb.unit5CircuitBreaker = 1 + self.low_bus_fb.bowPZDeviceCircuitBreaker = 1 + self.low_bus_fb.reservedCircuitBreaker1 = 0 + self.low_bus_fb.reservedCircuitBreaker2 = 0 + self.low_bus_fb.emergencyLithiumBatteryGroup1CircuitBreaker = 0 + self.low_bus_fb.powerFailureSignal = 0 + self.low_bus_fb.waterIngressionAlarm = 0 + self.low_bus_fb.instrumentBusbarVoltage = 48 + self.low_bus_fb.instrumentBusbarCurrent = 500 + self.low_bus_fb.unit1Current = 100 + self.low_bus_fb.unit2Current = 100 + self.low_bus_fb.unit3Current = 100 + self.low_bus_fb.unit5Current = 100 + self.low_bus_fb.bowPZDeviceCurrent = 50 + self.low_bus_fb.emergencyLithiumBatteryGroup1Current = 0 + self.low_bus_fb.emergency1BusbarVoltage = 48 + + def start(self): + """启动模拟器""" + self.running = True + # 启动发送线程 + self.send_thread = threading.Thread(target=self._send_loop) + self.send_thread.daemon = True + self.send_thread.start() + + # 启动接收线程 + self.recv_thread = threading.Thread(target=self._recv_loop) + self.recv_thread.daemon = True + self.recv_thread.start() + + def stop(self): + """停止模拟器""" + self.running = False + self.sock.close() + + def _send_loop(self): + """周期性发送反馈消息""" + while self.running: + try: + # 发送高压母线反馈 + data = self.high_vol_fb.pack() + self.sock.sendto(data, (self.host, 5000)) + + # 发送高压A母线反馈 + data = self.high_a_vol_fb.pack() + self.sock.sendto(data, (self.host, 5000)) + + # 发送仪表主母线反馈 + data = self.low_main_fb.pack() + self.sock.sendto(data, (self.host, 5000)) + + # 发送仪表汇流排反馈 + data = self.low_bus_fb.pack() + self.sock.sendto(data, (self.host, 5000)) + + time.sleep(1) # 每秒发送一次 + + except Exception as e: + print(f"发送消息出错: {e}") + break + + def _recv_loop(self): + """接收并处理命令消息""" + while self.running: + try: + data, addr = self.sock.recvfrom(1024) + if len(data) < 6: # 最小消息长度检查 + continue + + msg_id = struct.unpack_from('