Files
H100PowerManger/test/disSysTest/PowerManagerApp.py
T

1360 lines
69 KiB
Python

import tkinter as tk
from tkinter import ttk
import socket
import threading
import time
from db import DB
import os
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_ip = "192.168.0.140"
self.udp_port = 7000
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.sock.bind((self.udp_ip, self.udp_port))
self.disSysPortC1 = 6000
self.disSysHostC1 = '192.168.1.154'
self.disSysPortC2 = 6000
self.disSysHostC2 = '192.168.1.158'
# 数据库配置
# self.db = DB('/home/zjk/project/H100/H100PowerManger/test/disSysTest/test.db')
self.db = DB(os.path.join(os.path.dirname(__file__), '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,
"dcdc_temp":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,
"进水报警": 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=10, pady=2, sticky=tk.W)
ttk.Label(btn_frame, text=name, width=20).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=10, pady=2, sticky=tk.W)
ttk.Label(btn_frame, text=name, width=20).pack(side=tk.LEFT)
on_btn = ttk.Button(btn_frame, text="合", width=3,
command=lambda n=name: self.send_hvba_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_hvba_cmd(n, 0xAA))
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=10, pady=2, sticky=tk.W)
ttk.Label(btn_frame, text=name, width=20).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=10, pady=2, sticky=tk.W)
ttk.Label(btn_frame, text=name, width=20).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):
"""发送动力母线配电指令"""
# print(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.dcdc5Module = state
elif breaker_name == "冷却系统启动":
cmd.coolingSystem = state
# self.send_udp_command(cmd.pack())
self.send_udp_command(cmd.pack(), self.disSysHostC1, self.disSysPortC1)
self.db.insertHighVolBusCmd(cmd)
if state==0x55:
buntu=True
else:
buntu=False
self.log_message(f"发送动力母线配电指令: {breaker_name} {'合' if buntu 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
if state==0x55:
buntu=True
else:
buntu=False
self.log_message(f"发送动力汇流排A配电指令: {breaker_name} {'合' if buntu else '分'}")
# self.send_udp_command(cmd.pack())
self.send_udp_command(cmd.pack(), self.disSysHostC1, self.disSysPortC1)
self.db.insertHighAVolBusCmd(cmd)
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.send_udp_command(cmd.pack(), self.disSysHostC2, self.disSysPortC2)
self.db.insertLowMainBusCmd(cmd)
if state==0x55:
buntu=True
else:
buntu=False
self.log_message(f"发送仪表母线配电指令: {breaker_name} {'合' if buntu 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.send_udp_command(cmd.pack(), self.disSysHostC2, self.disSysPortC2)
self.db.insertLowBusCmd(cmd)
if state==0x55:
buntu=True
else:
buntu=False
self.log_message(f"发送仪表汇流排配电指令: {breaker_name} {'合' if buntu 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=2, pady=2)
# 使用网格布局管理器
frame.grid_columnconfigure(0, weight=1)
frame.grid_columnconfigure(1, weight=1)
frame.grid_columnconfigure(2, weight=1)
frame.grid_columnconfigure(3, 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.0V")
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.0V")
self.high_vol_a_voltage.grid(row=0, 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故障", "冷却水泄漏", "冷却泵1运行状态", "冷却泵2运行状态", "保留"]
# DC/DC故障显示
fault_frame = ttk.Frame(frame)
fault_frame.grid(row=10, column=0, columnspan=4, sticky=tk.W, pady=2)
ttk.Label(fault_frame, text="DC/DC故障字1:").grid(row=0, column=0, sticky=tk.W)
for i, label in enumerate(fault_labels1):
ttk.Label(fault_frame, text=label).grid(row=1+i//4, column=(i%4)*2, sticky=tk.W, padx=2)
canvas = tk.Canvas(fault_frame, width=16, height=16, bg="white", highlightthickness=1)
canvas.grid(row=1+i//4, column=(i%4)*2+1, sticky=tk.W, padx=2)
self.high_vol_dcdc_fault1_bits.append(canvas)
ttk.Label(fault_frame, text="DC/DC故障字2:").grid(row=3, column=0, sticky=tk.W)
for i, label in enumerate(fault_labels2):
ttk.Label(fault_frame, text=label).grid(row=4+i//4, column=(i%4)*2, sticky=tk.W, padx=2)
canvas = tk.Canvas(fault_frame, width=16, height=16, bg="white", highlightthickness=1)
canvas.grid(row=4+i//4, column=(i%4)*2+1, sticky=tk.W, padx=2)
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="正常")
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="正常")
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装置4/5电流(A):", "sternFTDevice45Current"),
("TYZ预留开关电流(A):", "tyzReservedSwitchCurrent"),
("艉舵开关1电流(A):", "sternRudderSwitch1Current"),
("艉舵开关2电流(A):", "sternRudderSwitch2Current"),
("FB预留开关电流(A):", "fbReservedSwitchCurrent"),
("备用电流1(A):", "reservedCurrent1"),
("备用电流2(A):", "reservedCurrent2"),
("备用电流3(A):", "reservedCurrent3")
]
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.0A")
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=24, column=0, sticky=tk.W)
self.high_vol_cool_water_pressure = ttk.Label(frame, text="0.00KPa")
self.high_vol_cool_water_pressure.grid(row=24, column=1, sticky=tk.W)
# 冷却水压力
ttk.Label(frame, text="DC/DC温度:").grid(row=24, column=3, sticky=tk.W)
self.high_vol_dcdc_temp = ttk.Label(frame, text="0.00摄氏度")
self.high_vol_dcdc_temp.grid(row=24, column=4, sticky=tk.W)
ttk.Label(frame, text="仪表失电信号:").grid(row=25, column=0, sticky=tk.W)
self.high_vol_losspower_insulation = ttk.Label(frame, text="正常")
self.high_vol_losspower_insulation.grid(row=25, column=1, sticky=tk.W)
ttk.Label(frame, text="应急失电信号").grid(row=25, column=2, sticky=tk.W)
self.high_vol_loss_emerpower_insulation = ttk.Label(frame, text="正常")
self.high_vol_loss_emerpower_insulation.grid(row=25, column=3, 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 V")
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 A")
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 A")
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 A")
self.high_a_vol_actuator_current.grid(row=3, column=1, sticky=tk.W)
# 补充缺失的电流显示项
ttk.Label(frame, text="桅杆舵机控制箱电流(A):").grid(row=4, column=0, sticky=tk.W)
self.high_a_vol_mast_steering_current = ttk.Label(frame, text="0.0 A")
self.high_a_vol_mast_steering_current.grid(row=4, column=1, sticky=tk.W)
ttk.Label(frame, text="XCZ电流(A):").grid(row=4, column=2, sticky=tk.W)
self.high_a_vol_xcz_current = ttk.Label(frame, text="0.0 A")
self.high_a_vol_xcz_current.grid(row=4, column=3, sticky=tk.W)
ttk.Label(frame, text="艏舵控制箱电流(A):").grid(row=5, column=0, sticky=tk.W)
self.high_a_vol_bow_rudder_current = ttk.Label(frame, text="0.0 A")
self.high_a_vol_bow_rudder_current.grid(row=5, column=1, sticky=tk.W)
ttk.Label(frame, text="敞水盖启动电缸电流(A):").grid(row=5, column=2, sticky=tk.W)
self.high_a_vol_open_cover_current = ttk.Label(frame, text="0.0 A")
self.high_a_vol_open_cover_current.grid(row=5, column=3, sticky=tk.W)
# 断路器状态 - 添加详细说明
ttk.Label(frame, text="高压A母线断路器状态:").grid(row=10, 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=8+i//2, column=(i%2)*2, sticky=tk.W)
canvas = tk.Canvas(frame, width=20, height=20, bg="white")
canvas.grid(row=8+i//2, column=(i%2)*2+1, sticky=tk.W)
self.high_a_vol_breakers[name] = canvas
# 报警状态 - 更详细描述
ttk.Label(frame, text="仪表电源失电信号:").grid(row=11, 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=11, column=1, sticky=tk.W)
ttk.Label(frame, text="应急电源失电信号:").grid(row=11, 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=11, column=3, sticky=tk.W)
ttk.Label(frame, text="进水报警:").grid(row=12, column=0, sticky=tk.W)
self.high_a_vol_water_alarm = ttk.Label(frame, text="无")
self.high_a_vol_water_alarm.grid(row=12, column=1, sticky=tk.W)
def process_udp_message(self, data):
"""处理接收到的UDP消息"""
try:
msg_id = int.from_bytes(data[2:4], byteorder='little')
print('----------------------------',hex(msg_id))
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"]["燃料电池断路器"] = 1 if msg.fuelCellCircuitBreaker == 0x55 else 0
# bus["breakers"]["动力锂电池断路器"] = 1 if msg.powerLithiumBatteryCircuitBreaker == 0x55 else 0
# bus["breakers"]["推进电机断路器"] = 1 if msg.propulsionMotorCircuitBreaker == 0x55 else 0
# bus["breakers"]["锂电池组仪表断路器"] = 1 if msg.lithiumBatteryGroupInstrumentCircuitBreaker == 0x55 else 0
# bus["breakers"]["DC/DC模块断路器"] = 1 if msg.dcDc5ModuleCircuitBreaker == 0x55 else 0
# bus["breakers"]["艏高压配电盒断路器"] = 1 if msg.bowHighVoltageDistributionBoxCircuitBreaker == 0x55 else 0
# bus["breakers"]["艉FT设备45断路器"] = 1 if msg.sternFTDevice45CircuitBreaker == 0x55 else 0
# bus["breakers"]["艉舵机开关1断路器"] = 1 if msg.sternRudderSwitch1CircuitBreaker == 0x55 else 0
# bus["breakers"]["艉舵机开关2断路器"] = 1 if msg.sternRudderSwitch2CircuitBreaker == 0x55 else 0
# bus["breakers"]["FB备用断路器"] = 1 if msg.fbReservedCircuitBreaker == 0x55 else 0
# bus["breakers"]["TYZ备用断路器"] = 1 if msg.tyzReservedCircuitBreaker == 0x55 else 0
# bus["breakers"]["备用断路器"] = 1 if msg.reservedCircuitBreaker == 0x55 else 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
# print('----------------------------',bus["breakers"])
bus["faults"]["DC/DC故障1"] = msg.dcDcFaultWord1
bus["faults"]["DC/DC故障2"] = msg.dcDcFaultWord2
if msg.powerBusInsulationStatus == 0x55:
bus["insulation"]["动力母线绝缘状态"] = 0
else:
bus["insulation"]["动力母线绝缘状态"] = 1
if msg.aBusInsulationStatus == 0x55:
bus["insulation"]["A母线绝缘状态"] = 0
else:
bus["insulation"]["A母线绝缘状态"] = 1
# if msg.meterPowerLossSignal == 0x55:
# bus["alarms"]["仪表电源丢失信号"] = 0
# else:
# bus["alarms"]["仪表电源丢失信号"] = 1
bus["alarms"]["应急电源丢失信号"] = msg.emergencyPowerLossSignal
bus["alarms"]["仪表电源丢失信号"] = msg.meterPowerLossSignal
# if msg.emergencyPowerLossSignal == 0x55:
# bus["alarms"]["应急电源丢失信号"] = 0
# else:
# bus["alarms"]["应急电源丢失信号"] = 1
bus["cool_water_pressure"] = msg.coolWaterPressure / 10.0
bus["dcdc_temp"] = msg.dcdcTemperature-40
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断路器"] = 1 if msg.bowFTDevice123CircuitBreaker == 0x55 else 0
# bus["breakers"]["执行机构断路器"] = 1 if msg.actuatorCircuitBreaker == 0x55 else 0
# bus["breakers"]["桅舵机控制箱断路器"] = 1 if msg.mastSteeringGearControlBoxCircuitBreaker == 0x55 else 0
# bus["breakers"]["XCZ断路器"] = 1 if msg.xczCircuitBreaker == 0x55 else 0
# bus["breakers"]["艏舵控制箱断路器"] = 1 if msg.bowRudderControlBoxCircuitBreaker == 0x55 else 0
# bus["breakers"]["开盖启动气缸断路器"] = 1 if msg.openWaterCoverStartCylinderCircuitBreaker == 0x55 else 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"]["锂电池组仪表断路器"] = 1 if msg.lithiumBatteryGroupInstrumentCircuitBreaker == 0x55 else 0
# bus["breakers"]["艏低压配电盒断路器"] = 1 if msg.bowLowVoltageDistributionBoxCircuitBreaker == 0x55 else 0
# bus["breakers"]["单元4仪表48V断路器"] = 1 if msg.unit4InstrumentDC48VCircuitBreaker == 0x55 else 0
# bus["breakers"]["DC/C1直流配电板断路器"] = 1 if msg.dcC1DCDistributionPanelCircuitBreaker == 0x55 else 0
# bus["breakers"]["备用断路器1"] = 1 if msg.reservedCircuitBreaker1 == 0x55 else 0
# bus["breakers"]["备用断路器2"] = 1 if msg.reservedCircuitBreaker2 == 0x55 else 0
# bus["breakers"]["应急锂电池组2断路器"] = 1 if msg.emergencyLithiumBatteryGroup2CircuitBreaker == 0x55 else 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
# 0x55 正常
# 0xaa 故障
# if msg.instrumentPowerFailureSignal == 0x55:
# bus["alarms"]["仪表电源故障"] = 0
# else:
# bus["alarms"]["仪表电源故障"] = 1
bus["alarms"]["仪表电源故障"] = msg.instrumentPowerFailureSignal
# if msg.emergencyPowerFailureSignal == 0x55:
# bus["alarms"]["应急电源故障"] = 0
# else:
# bus["alarms"]["应急电源故障"] = 1
bus["alarms"]["应急电源故障"] = msg.emergencyPowerFailureSignal
# bus["insulation"] = msg.instrumentBusbarInsulationLow
if msg.instrumentBusbarInsulationLow == 0x55:
bus["insulation"] = 0
else:
bus["insulation"] = 1
self.log_message("收到仪表主母线状态更新")
else:
print("仪表主母线状态","解析失败")
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断路器"] = 1 if msg.unit1CircuitBreaker == 0x55 else 0
# bus["breakers"]["单元2断路器"] = 1 if msg.unit2CircuitBreaker == 0x55 else 0
# bus["breakers"]["单元3断路器"] = 1 if msg.unit3CircuitBreaker == 0x55 else 0
# bus["breakers"]["单元5断路器"] = 1 if msg.unit5CircuitBreaker == 0x55 else 0
# bus["breakers"]["艏PZ设备断路器"] = 1 if msg.bowPZDeviceCircuitBreaker == 0x55 else 0
# bus["breakers"]["备用断路器1"] = 1 if msg.reservedCircuitBreaker1 == 0x55 else 0
# bus["breakers"]["备用断路器2"] = 1 if msg.reservedCircuitBreaker2 == 0x55 else 0
# bus["breakers"]["应急锂电池组1断路器"] = 1 if msg.emergencyLithiumBatteryGroup1CircuitBreaker == 0x55 else 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.instrumentPowerFailureSignal
bus["alarms"]["应急电源故障"] = msg.emergencyPowerFailureSignal
bus["alarms"]["进水报警"] = msg.waterIngressionAlarm
self.log_message("收到仪表母线状态更新")
else:
print("仪表母线状态","解析失败")
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=2, pady=2)
# 显式配置4列网格布局
frame.grid_columnconfigure(0, weight=1)
frame.grid_columnconfigure(1, weight=1)
frame.grid_columnconfigure(2, weight=1)
frame.grid_columnconfigure(3, weight=1)
# 电压显示
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="DC-C1(直流配电板1)仪表DC48V电流(A):").grid(row=2, column=0, sticky=tk.W)
self.low_main_dcc1_current = ttk.Label(frame, text="0.0")
self.low_main_dcc1_current.grid(row=2, column=1, sticky=tk.W)
ttk.Label(frame, text="应急锂电池组2电流(A):").grid(row=2, column=2, sticky=tk.W)
self.low_main_emergency2_current = ttk.Label(frame, text="0.0")
self.low_main_emergency2_current.grid(row=2, column=3, sticky=tk.W)
ttk.Label(frame, text="单元4仪表48V电流(A):").grid(row=3, column=0, sticky=tk.W)
self.low_main_unit4_current = ttk.Label(frame, text="0.0")
self.low_main_unit4_current.grid(row=3, column=1, sticky=tk.W)
ttk.Label(frame, text="复合能源管控系统应急DC48V电流(A):").grid(row=3, column=2, sticky=tk.W)
self.low_main_energy_current = ttk.Label(frame, text="0.0")
self.low_main_energy_current.grid(row=3, column=3, sticky=tk.W)
ttk.Label(frame, text="燃料电池安保系统应急DC48V电流(A):").grid(row=4, column=0, sticky=tk.W)
self.low_main_fuelcell_current = ttk.Label(frame, text="0.0")
self.low_main_fuelcell_current.grid(row=4, column=1, sticky=tk.W)
ttk.Label(frame, text="PLC控制电源电流(A):").grid(row=4, column=2, sticky=tk.W)
self.low_main_plc_current = ttk.Label(frame, text="0.0")
self.low_main_plc_current.grid(row=4, column=3, sticky=tk.W)
# 断路器状态
ttk.Label(frame, text="断路器状态:").grid(row=5, column=0, columnspan=4, sticky=tk.W)
self.low_main_breakers = {}
breaker_names = list(self.status_data["low_main_bus"]["breakers"].keys())
# 断路器状态 - 调整为每行3个断路器,从行6开始
for i, name in enumerate(breaker_names):
row = 6 + i//3
col = (i%3)*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=9, column=0, sticky=tk.W)
self.low_main_instrument_fault = ttk.Label(frame, text="无")
self.low_main_instrument_fault.grid(row=9, column=1, sticky=tk.W)
ttk.Label(frame, text="应急电源失电信号 :").grid(row=9, column=2, sticky=tk.W)
self.low_main_emergency_fault = ttk.Label(frame, text="无")
self.low_main_emergency_fault.grid(row=9, column=3, sticky=tk.W)
# 绝缘状态
ttk.Label(frame, text="仪表汇流排绝缘低 :").grid(row=10, column=0, sticky=tk.W)
self.low_main_insulation = ttk.Label(frame, text="正常")
self.low_main_insulation.grid(row=10, column=1, sticky=tk.W)
# 备用电流
ttk.Label(frame, text="备用电流1 :").grid(row=11, column=0, sticky=tk.W)
self.low_main_reserved1 = ttk.Label(frame, text="0.0")
self.low_main_reserved1.grid(row=11, column=1, sticky=tk.W)
ttk.Label(frame, text="备用电流2 :").grid(row=11, column=2, sticky=tk.W)
self.low_main_reserved2 = ttk.Label(frame, text="0.0")
self.low_main_reserved2.grid(row=11, column=3, 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=2, pady=2)
# 显式配置4列网格布局
frame.grid_columnconfigure(0, weight=1)
frame.grid_columnconfigure(1, weight=1)
frame.grid_columnconfigure(2, weight=1)
frame.grid_columnconfigure(3, weight=1)
# 电压显示
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="仪表母排电流(A):").grid(row=2, column=0, sticky=tk.W)
self.low_bus_main_current = ttk.Label(frame, text="0.0")
self.low_bus_main_current.grid(row=2, column=1, sticky=tk.W)
ttk.Label(frame, text="单元3电流(A):").grid(row=2, column=2, sticky=tk.W)
self.low_bus_unit3_current = ttk.Label(frame, text="0.0")
self.low_bus_unit3_current.grid(row=2, column=3, sticky=tk.W)
ttk.Label(frame, text="单元5电流(A):").grid(row=3, column=0, sticky=tk.W)
self.low_bus_unit5_current = ttk.Label(frame, text="0.0")
self.low_bus_unit5_current.grid(row=3, column=1, sticky=tk.W)
ttk.Label(frame, text="艏PZ设备电流(A):").grid(row=3, column=2, sticky=tk.W)
self.low_bus_bow_pz_current = ttk.Label(frame, text="0.0")
self.low_bus_bow_pz_current.grid(row=3, column=3, sticky=tk.W)
ttk.Label(frame, text="应急锂电池组1电流(A):").grid(row=4, column=0, sticky=tk.W)
self.low_bus_emergency1_current = ttk.Label(frame, text="0.0")
self.low_bus_emergency1_current.grid(row=4, column=1, sticky=tk.W)
# 断路器状态
ttk.Label(frame, text="断路器状态:").grid(row=5, 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 = 6 + 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=10, column=0, sticky=tk.W)
self.low_bus_power_fault = ttk.Label(frame, text="无")
self.low_bus_power_fault.grid(row=10, column=1, sticky=tk.W)
ttk.Label(frame, text="应急电失电信号 :").grid(row=11, column=0, sticky=tk.W)
self.low_bus_emgpower_fault = ttk.Label(frame, text="无")
self.low_bus_emgpower_fault.grid(row=11, column=1, sticky=tk.W)
ttk.Label(frame, text="浸水报警 :").grid(row=10, column=2, sticky=tk.W)
self.low_bus_water_alarm = ttk.Label(frame, text="无")
self.low_bus_water_alarm.grid(row=10, column=3, sticky=tk.W)
return frame
def send_udp_command(self, data, ip, port):
"""发送UDP命令"""
try:
# self.sock.sendto(data, (self.udp_ip, self.udp_port + 1))
self.sock.sendto(data, (ip, port))
print(f"发送命令到 {ip}:{port} ", data)
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} V")
self.high_vol_a_voltage.config(text=f"{status['voltage']['A母线电压']:.1f} V")
# # 更新电流显示
# 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备用开关电流'),
('reservedCurrent1', '备用电流1'),
('reservedCurrent2', '备用电流2'),
('reservedCurrent3', '备用电流3')
]
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} A")
# 更新断路器状态
for name, state in status['breakers'].items():
if name in self.high_vol_breakers:
canvas = self.high_vol_breakers[name]
# color = 'green' if state else 'red'
# print(name, hex(state))
if state == 0x55:
color = "green"
elif state == 0xAA:
color = "black"
elif state == 0x5A:
color = "red"
else:
color = "white"
canvas.delete("all")
canvas.create_oval(2, 2, 18, 18, fill=color, outline="black")
# 更新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"正常"
a_text = "故障" if insulation_a else f"正常"
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']:.1f} Kpa")
# # 更新温度状态
self.high_vol_dcdc_temp.config(text=f"{status['dcdc_temp']} 摄氏度")
# "仪表电源丢失信号": 0,
# "应急电源丢失信号": 0
# 更新失电故障显示
self.high_vol_losspower_insulation.config(text="正常" if status['alarms']['仪表电源丢失信号'] == 0x55 else "故障")
self.high_vol_loss_emerpower_insulation.config(text="正常" if status['alarms']['应急电源丢失信号'] == 0x55 else "故障")
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")
# 更新新增的电流显示项
self.high_a_vol_mast_steering_current.config(text=f"{high_a_vol['current']['桅舵机控制箱电流']:.1f} A")
self.high_a_vol_xcz_current.config(text=f"{high_a_vol['current']['XCZ电流']:.1f} A")
self.high_a_vol_bow_rudder_current.config(text=f"{high_a_vol['current']['艏舵控制箱电流']:.1f} A")
self.high_a_vol_open_cover_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)
if state == 0x55:
color = "green"
elif state == 0xAA:
color = "black"
elif state == 0x5A:
color = "red"
else:
color = "white"
# 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"
if state == 0x55:
color = "green"
elif state == 0xAA:
color = "black"
elif state == 0x5A:
color = "red"
else:
color = "white"
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"
if state == 0x55:
color = "green"
elif state == 0xAA:
color = "black"
elif state == 0x5A:
color = "red"
else:
color = "white"
canvas.create_oval(2, 2, 18, 18, fill=color, outline="black")
self.high_a_vol_instrument_power_fault.config(
text="正常" if high_a_vol["alarms"]["仪表电源故障"]==0x55 else "故障"
)
self.high_a_vol_emergency_power_fault.config(
text="正常" if high_a_vol["alarms"]["应急电源故障"]==0x55 else "故障"
)
self.high_a_vol_water_alarm.config(
text="正常" if high_a_vol["alarms"]["进水报警"]==0x55 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} A")
self.low_main_battery_current.config(text=f"{low_main['current']['锂电池组仪表电流']:.1f} A")
# 更新新增的电流显示项
self.low_main_dcc1_current.config(text=f"{low_main['current']['DC/C1仪表48V电流']:.1f} A")
self.low_main_emergency2_current.config(text=f"{low_main['current']['应急锂电池组2电流']:.1f} A")
self.low_main_unit4_current.config(text=f"{low_main['current']['单元4仪表48V电流']:.1f} A")
self.low_main_energy_current.config(text=f"{low_main['current']['综合能量管理系统应急DC48V电流']:.1f} A")
self.low_main_fuelcell_current.config(text=f"{low_main['current']['燃料电池安全系统应急DC48V电流']:.1f} A")
self.low_main_plc_current.config(text=f"{low_main['current']['PLC控制电源电流']:.1f} A")
# 新增加备用电流
self.low_main_reserved1.config(text=f"{low_main['current']['备用电流1']:.1f} A")
self.low_main_reserved2.config(text=f"{low_main['current']['备用电流2']:.1f} A")
for name, canvas in self.low_main_breakers.items():
state = low_main["breakers"].get(name, 0)
# color = "green" if state else "red"
if state == 0x55:
color = "green"
elif state == 0xAA:
color = "black"
elif state == 0x5A:
color = "red"
else:
color = "white"
canvas.create_oval(2, 2, 18, 18, fill=color, outline="black")
self.low_main_instrument_fault.config(
text="正常" if low_main["alarms"]["仪表电源故障"]==0x55 else "故障"
)
self.low_main_emergency_fault.config(
text="正常" if low_main["alarms"]["应急电源故障"]==0x55 else "故障"
)
self.low_main_insulation.config(
text="正常" if low_main["insulation"]==0x55 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} A")
self.low_bus_unit2_current.config(text=f"{low_bus['current']['单元2电流']:.1f} A")
# 更新新增的电流显示项
self.low_bus_main_current.config(text=f"{low_bus['current']['仪表母线电流']:.1f} A")
self.low_bus_unit3_current.config(text=f"{low_bus['current']['单元3电流']:.1f} A")
self.low_bus_unit5_current.config(text=f"{low_bus['current']['单元5电流']:.1f} A")
self.low_bus_bow_pz_current.config(text=f"{low_bus['current']['艏PZ设备电流']:.1f} A")
self.low_bus_emergency1_current.config(text=f"{low_bus['current']['应急锂电池组1电流']:.1f} A")
for name, canvas in self.low_bus_breakers.items():
state = low_bus["breakers"].get(name, 0)
# color = "green" if state else "red"
if state == 0x55:
color = "green"
elif state == 0xAA:
color = "black"
elif state == 0x5A:
color = "red"
else:
color = "white"
canvas.create_oval(2, 2, 18, 18, fill=color, outline="black")
self.low_bus_power_fault.config(
text="正常" if low_bus["alarms"]["仪表电源故障"]==0x55 else "故障"
)
self.low_bus_emgpower_fault.config(
text="正常" if low_bus["alarms"]["应急电源故障"]==0x55 else "故障"
)
self.low_bus_water_alarm.config(
text="正常" if low_bus["alarms"]["进水报警"]==0x55 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")
# 获取当前所有行数
line_count = int(self.log_text.index('end-1c').split('.')[0])
# 如果超过50行,删除最旧的行
if line_count > 50:
self.log_text.delete(1.0, 2.0)
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')