- 新增 pCCU 复合管控器程序(src/pCCU):FC/PM 双链路(UDP)、协议编解码器 (FcProtocol/PmProtocol/Frame/Message/MessageRegistry)、快照与落库(DbStore)、 内置 WebServer;挂入 src/CMakeLists.txt 与板卡 mission(h100.moos) - 惯导/深度数据:新增 uDevice_insData 消息解析,接入 UpperCommManager, pPowerMangerHost 注册监视,UpmsgTest 覆盖 - pPowerMangerHost 设备控制页增强(web/index.html) - 部署/运维脚本改为 4 个 systemd 服务(moosdb/pPowerManger/pPowerMangerHost/pCCU): deploy/clean-data/fetch-data 同步适配 - 协议文档:归档 0824 控制主机与复合管控器通信协议 xlsx 及关联 docx,移除旧 md - 测试:新增 pccu 单元/集成测试与 disSysTest Python 配电仿真 - 清理:移除未使用的 CCU 状态调试打印 coutMsg;.gitignore 补充编译产物/临时文件忽略
441 lines
19 KiB
Python
441 lines
19 KiB
Python
"""数据驱动的状态/操作面板构建器。
|
|
|
|
由 BusSpec / CmdSpec 声明式描述每个母线的字段、显示方式与控制项,
|
|
build_bus_page / update_bus_page 负责创建与刷新界面,
|
|
避免每个母线重复手写布局与 if/elif 更新逻辑。
|
|
"""
|
|
|
|
import tkinter as tk
|
|
from dataclasses import dataclass
|
|
from tkinter import ttk
|
|
|
|
from . import protocol
|
|
from .protocol import BREAKER_ON, BREAKER_OFF, BREAKER_FAULT
|
|
|
|
# 配色
|
|
GREEN = "#2e7d32"
|
|
RED = "#d32f2f"
|
|
BLACK = "#212121"
|
|
GRAY = "#9e9e9e"
|
|
|
|
|
|
def breaker_color(raw):
|
|
if raw == BREAKER_ON:
|
|
return GREEN
|
|
if raw == BREAKER_OFF:
|
|
return BLACK
|
|
if raw == BREAKER_FAULT:
|
|
return RED
|
|
return GRAY
|
|
|
|
|
|
def bool_ok(raw, ok=BREAKER_ON):
|
|
return raw == ok
|
|
|
|
|
|
def make_light(parent, size=18):
|
|
canvas = tk.Canvas(parent, width=size, height=size, bg="white",
|
|
highlightthickness=0)
|
|
canvas.create_oval(2, 2, size - 2, size - 2, fill=GRAY, outline="black")
|
|
return canvas
|
|
|
|
|
|
def set_light(canvas, color):
|
|
canvas.delete("all")
|
|
canvas.create_oval(2, 2, int(canvas["width"]) - 2,
|
|
int(canvas["height"]) - 2, fill=color, outline="black")
|
|
|
|
|
|
# ------------------------------------------------------------------
|
|
@dataclass
|
|
class BusSpec:
|
|
key: str # 总线标识
|
|
title: str # 页标题
|
|
msg_cls: type
|
|
breakers: list # [(label, field)]
|
|
voltages: list # [(label, field, scale, unit)]
|
|
currents: list # [(label, field, scale, unit)]
|
|
booleans: list # [(label, field)] ok=BREAKER_ON 为正常
|
|
derived: list # [(label, getter)] getter(msg)->(text, color)
|
|
|
|
|
|
HIGH_VOL_BUS = BusSpec(
|
|
key="high_vol",
|
|
title="动力母线状态",
|
|
msg_cls=protocol.MsgDisHighVolBusFb,
|
|
breakers=[
|
|
("燃料电池断路器", "fuelCellCircuitBreaker"),
|
|
("动力锂电池断路器", "powerLithiumBatteryCircuitBreaker"),
|
|
("推进电机断路器", "propulsionMotorCircuitBreaker"),
|
|
("锂电池组仪表断路器", "lithiumBatteryGroupInstrumentCircuitBreaker"),
|
|
("DC/DC模块断路器", "dcDc5ModuleCircuitBreaker"),
|
|
("艏高压配电盒断路器", "bowHighVoltageDistributionBoxCircuitBreaker"),
|
|
("艉FT设备45断路器", "sternFTDevice45CircuitBreaker"),
|
|
("艉舵机开关1断路器", "sternRudderSwitch1CircuitBreaker"),
|
|
("艉舵机开关2断路器", "sternRudderSwitch2CircuitBreaker"),
|
|
("FB备用断路器", "fbReservedCircuitBreaker"),
|
|
("TYZ备用断路器", "tyzReservedCircuitBreaker"),
|
|
("备用断路器", "reservedCircuitBreaker"),
|
|
],
|
|
voltages=[
|
|
("动力母线电压", "powerBusVoltage", 0.1, "V"),
|
|
("A母线电压", "busbarAVoltage", 0.1, "V"),
|
|
],
|
|
currents=[
|
|
("动力母线电流", "powerBusCurrent", 0.1, "A"),
|
|
("A汇流排电流", "busbarACurrent", 0.1, "A"),
|
|
("DC/DC5模块电流", "dcDc5ModuleCurrent", 0.1, "A"),
|
|
("推进电机控制箱电流", "propulsionMotorControlBoxCurrent", 0.1, "A"),
|
|
("锂电池组(仪表)电流", "lithiumBatteryGroupMeterCurrent", 0.1, "A"),
|
|
("艏部高压配电箱电流", "bowHighVoltageDistributionBoxCurrent", 0.1, "A"),
|
|
("艉部FT装置4/5电流", "sternFTDevice45Current", 0.1, "A"),
|
|
("TYZ预留开关电流", "tyzReservedSwitchCurrent", 0.1, "A"),
|
|
("艉舵开关1电流", "sternRudderSwitch1Current", 0.1, "A"),
|
|
("艉舵开关2电流", "sternRudderSwitch2Current", 0.1, "A"),
|
|
("FB预留开关电流", "fbReservedSwitchCurrent", 0.1, "A"),
|
|
("备用电流1", "reservedCurrent1", 0.1, "A"),
|
|
("备用电流2", "reservedCurrent2", 0.1, "A"),
|
|
("备用电流3", "reservedCurrent3", 0.1, "A"),
|
|
],
|
|
booleans=[
|
|
("仪表失电信号", "meterPowerLossSignal"),
|
|
("应急失电信号", "emergencyPowerLossSignal"),
|
|
("动力母线绝缘", "powerBusInsulationStatus"),
|
|
("艏高压绝缘", "aBusInsulationStatus"),
|
|
],
|
|
derived=[
|
|
("冷却水压力", lambda m: (f"{m.coolWaterPressure * 0.1:.1f} kPa", BLACK)),
|
|
("DC/DC温度", lambda m: (f"{m.dcdcTemperature - 40} ℃", BLACK)),
|
|
],
|
|
)
|
|
|
|
HIGH_A_VOL_BUS = BusSpec(
|
|
key="high_a_vol",
|
|
title="艏部高压状态",
|
|
msg_cls=protocol.MsgDisHighAVolBusFb,
|
|
breakers=[
|
|
("艏FT设备123断路器", "bowFTDevice123CircuitBreaker"),
|
|
("执行机构断路器", "actuatorCircuitBreaker"),
|
|
("桅舵机控制箱断路器", "mastSteeringGearControlBoxCircuitBreaker"),
|
|
("XCZ断路器", "xczCircuitBreaker"),
|
|
("艏舵控制箱断路器", "bowRudderControlBoxCircuitBreaker"),
|
|
("开盖启动气缸断路器", "openWaterCoverStartCylinderCircuitBreaker"),
|
|
],
|
|
voltages=[
|
|
("汇流排B电压", "busbarBVoltage", 0.1, "V"),
|
|
],
|
|
currents=[
|
|
("汇流排B电流", "busbarBCurrent", 0.1, "A"),
|
|
("艏部FT设备123电流", "bowFTDevice123Current", 0.1, "A"),
|
|
("启闭机构电流", "actuatorCurrent", 0.1, "A"),
|
|
("桅杆舵机控制箱电流", "mastSteeringGearControlBoxCurrent", 0.1, "A"),
|
|
("XCZ电流", "xczCurrent", 0.1, "A"),
|
|
("艏舵控制箱电流", "bowRudderControlBoxCurrent", 0.1, "A"),
|
|
("敞水盖启动电缸电流", "openWaterCoverStartCylinderCurrent", 0.1, "A"),
|
|
],
|
|
booleans=[
|
|
("仪表电源失电信号", "instrumentPowerFailureSignal"),
|
|
("应急电源失电信号", "emergencyPowerFailureSignal"),
|
|
("进水报警", "waterIngressionAlarm"),
|
|
],
|
|
derived=[],
|
|
)
|
|
|
|
LOW_MAIN_BUS = BusSpec(
|
|
key="low_main",
|
|
title="仪表母线状态",
|
|
msg_cls=protocol.MsgDisLowMainBusFb,
|
|
breakers=[
|
|
("锂电池组仪表断路器", "lithiumBatteryGroupInstrumentCircuitBreaker"),
|
|
("艏低压配电盒断路器", "bowLowVoltageDistributionBoxCircuitBreaker"),
|
|
("单元4仪表48V断路器", "unit4InstrumentDC48VCircuitBreaker"),
|
|
("DC/C1直流配电板断路器", "dcC1DCDistributionPanelCircuitBreaker"),
|
|
("备用断路器1", "reservedCircuitBreaker1"),
|
|
("备用断路器2", "reservedCircuitBreaker2"),
|
|
("应急锂电池组2断路器", "emergencyLithiumBatteryGroup2CircuitBreaker"),
|
|
],
|
|
voltages=[
|
|
("仪表母线电压", "instrumentBusbarVoltage", 0.1, "V"),
|
|
("应急2汇流排电压", "emergency2BusbarVoltage", 0.1, "V"),
|
|
],
|
|
currents=[
|
|
("艏部低压配电箱电流", "bowLowVoltageDistributionBoxCurrent", 0.1, "A"),
|
|
("锂电池组(仪表)电流", "lithiumBatteryGroupInstrumentCurrent", 0.1, "A"),
|
|
("DC-C1仪表DC48V电流", "dcC1InstrumentDC48VCurrent", 0.1, "A"),
|
|
("应急锂电池组2电流", "emergencyLithiumBatteryGroup2Current", 0.1, "A"),
|
|
("单元4仪表48V电流", "unit4InstrumentDC48VCurrent", 0.1, "A"),
|
|
("复合能源管控应急DC48V电流", "compositeEnergyManagementSystemEmergencyDC48VCurrent", 0.1, "A"),
|
|
("燃料电池安保应急DC48V电流", "fuelCellSecuritySystemEmergencyDC48VCurrent", 0.1, "A"),
|
|
("PLC控制电源电流", "plcControlPowerCurrent", 0.1, "A"),
|
|
("备用电流1", "reservedCurrent1", 0.1, "A"),
|
|
("备用电流2", "reservedCurrent2", 0.1, "A"),
|
|
],
|
|
booleans=[
|
|
("仪表电源失电信号", "instrumentPowerFailureSignal"),
|
|
("应急电源失电信号", "emergencyPowerFailureSignal"),
|
|
("仪表汇流排绝缘低", "instrumentBusbarInsulationLow"),
|
|
],
|
|
derived=[],
|
|
)
|
|
|
|
LOW_BUS = BusSpec(
|
|
key="low_bus",
|
|
title="艏部低压状态",
|
|
msg_cls=protocol.MsgDisLowBusFb,
|
|
breakers=[
|
|
("单元1断路器", "unit1CircuitBreaker"),
|
|
("单元2断路器", "unit2CircuitBreaker"),
|
|
("单元3断路器", "unit3CircuitBreaker"),
|
|
("单元5断路器", "unit5CircuitBreaker"),
|
|
("艏PZ设备断路器", "bowPZDeviceCircuitBreaker"),
|
|
("备用断路器1", "reservedCircuitBreaker1"),
|
|
("备用断路器2", "reservedCircuitBreaker2"),
|
|
("应急锂电池组1断路器", "emergencyLithiumBatteryGroup1CircuitBreaker"),
|
|
],
|
|
voltages=[
|
|
("仪表母排电压", "instrumentBusbarVoltage", 0.1, "V"),
|
|
("应急1母线电压", "emergency1BusbarVoltage", 0.1, "V"),
|
|
],
|
|
currents=[
|
|
("仪表母排电流", "instrumentBusbarCurrent", 0.1, "A"),
|
|
("单元1电流", "unit1Current", 0.1, "A"),
|
|
("单元2电流", "unit2Current", 0.1, "A"),
|
|
("单元3电流", "unit3Current", 0.1, "A"),
|
|
("单元5电流", "unit5Current", 0.1, "A"),
|
|
("艏PZ设备电流", "bowPZDeviceCurrent", 0.1, "A"),
|
|
("应急锂电池组1电流", "emergencyLithiumBatteryGroup1Current", 0.1, "A"),
|
|
],
|
|
booleans=[
|
|
("仪表电失电信号", "instrumentPowerFailureSignal"),
|
|
("应急电失电信号", "emergencyPowerFailureSignal"),
|
|
("浸水报警", "waterIngressionAlarm"),
|
|
],
|
|
derived=[],
|
|
)
|
|
|
|
BUS_SPECS = {spec.key: spec for spec in (HIGH_VOL_BUS, HIGH_A_VOL_BUS,
|
|
LOW_MAIN_BUS, LOW_BUS)}
|
|
|
|
|
|
# ------------------------------------------------------------------
|
|
# 状态页构建 / 刷新
|
|
# ------------------------------------------------------------------
|
|
def build_bus_page(parent, spec):
|
|
"""构建一个母线状态页,返回用于刷新的 refs 字典。"""
|
|
page = ttk.Frame(parent, padding=6)
|
|
page.grid_columnconfigure(0, weight=1)
|
|
|
|
# ---- 顶部:电压 + 断路器 ----
|
|
top = ttk.LabelFrame(page, text="电压与断路器状态", padding=8)
|
|
top.grid(row=0, column=0, sticky="nsew", pady=(0, 6))
|
|
for c in range(3):
|
|
top.grid_columnconfigure(c, weight=1)
|
|
|
|
voltage_widgets = {}
|
|
for i, (label, field, scale, unit) in enumerate(spec.voltages):
|
|
sub = ttk.Frame(top)
|
|
sub.grid(row=0, column=i, padx=10, pady=4, sticky="w")
|
|
ttk.Label(sub, text=f"{label}({unit}):", width=20, anchor="w").pack(side="left")
|
|
value_lbl = ttk.Label(sub, text="--", width=10, anchor="e", relief="groove")
|
|
value_lbl.pack(side="right")
|
|
voltage_widgets[field] = {"widget": value_lbl, "scale": scale, "unit": unit}
|
|
|
|
ttk.Label(top, text="断路器状态:",
|
|
font=("Arial", 10, "bold")).grid(row=1, column=0,
|
|
columnspan=6, sticky="w", pady=(10, 4))
|
|
|
|
breaker_lights = {}
|
|
field_for_label = {label: f for label, f in spec.breakers}
|
|
for i, (label, _f) in enumerate(spec.breakers):
|
|
bf = tk.Frame(top, relief="solid", borderwidth=1, padx=6, pady=2)
|
|
bf.grid(row=2 + i // 3, column=i % 3, padx=6, pady=4, sticky="w")
|
|
ttk.Label(bf, text=label, width=20, anchor="w").pack(side="left")
|
|
light = make_light(bf)
|
|
light.pack(side="right")
|
|
breaker_lights[label] = light
|
|
|
|
# ---- 下部:电流 / 布尔量 / 派生量 ----
|
|
group = ttk.LabelFrame(page, text="系统状态", padding=8)
|
|
group.grid(row=1, column=0, sticky="nsew")
|
|
page.grid_rowconfigure(1, weight=1)
|
|
for c in range(3):
|
|
group.grid_columnconfigure(c, weight=1)
|
|
|
|
values = {}
|
|
booleans = {}
|
|
derived = {}
|
|
|
|
items = []
|
|
for it in spec.currents:
|
|
items.append(("value", it))
|
|
for it in spec.booleans:
|
|
items.append(("bool", it))
|
|
for it in spec.derived:
|
|
items.append(("derived", it))
|
|
|
|
for i, (kind, it) in enumerate(items):
|
|
f = ttk.Frame(group)
|
|
f.grid(row=i // 3, column=i % 3, sticky="w", padx=8, pady=3)
|
|
if kind == "value":
|
|
label, field, scale, unit = it
|
|
ttk.Label(f, text=f"{label}({unit}):", width=26, anchor="w").pack(side="left")
|
|
v = ttk.Label(f, text="--", width=10, anchor="e", relief="groove")
|
|
v.pack(side="right")
|
|
values[field] = {"widget": v, "scale": scale, "unit": unit}
|
|
elif kind == "bool":
|
|
label, field = it
|
|
ttk.Label(f, text=f"{label}:", width=26, anchor="w").pack(side="left")
|
|
v = ttk.Label(f, text="--", width=10, anchor="e", relief="groove")
|
|
v.pack(side="right")
|
|
booleans[field] = {"widget": v}
|
|
else:
|
|
label, getter = it
|
|
ttk.Label(f, text=f"{label}:", width=26, anchor="w").pack(side="left")
|
|
v = ttk.Label(f, text="--", width=10, anchor="e", relief="groove")
|
|
v.pack(side="right")
|
|
derived[label] = {"widget": v, "getter": getter}
|
|
|
|
return {
|
|
"frame": page,
|
|
"field_for_label": field_for_label,
|
|
"breaker_lights": breaker_lights,
|
|
"voltage_widgets": voltage_widgets,
|
|
"values": values,
|
|
"booleans": booleans,
|
|
"derived": derived,
|
|
}
|
|
|
|
|
|
def update_bus_page(spec, refs, msg):
|
|
"""用最新反馈消息刷新状态页。msg 为 None 时跳过。"""
|
|
if msg is None:
|
|
return
|
|
for label, light in refs["breaker_lights"].items():
|
|
field = refs["field_for_label"][label]
|
|
set_light(light, breaker_color(getattr(msg, field)))
|
|
for field, info in refs["voltage_widgets"].items():
|
|
v = getattr(msg, field) * info["scale"]
|
|
info["widget"].config(text=f"{v:.1f} {info['unit']}")
|
|
for field, info in refs["values"].items():
|
|
v = getattr(msg, field) * info["scale"]
|
|
info["widget"].config(text=f"{v:.1f} {info['unit']}")
|
|
for field, info in refs["booleans"].items():
|
|
ok = bool_ok(getattr(msg, field))
|
|
info["widget"].config(text="正常" if ok else "故障",
|
|
foreground=GREEN if ok else RED)
|
|
for label, info in refs["derived"].items():
|
|
text, color = info["getter"](msg)
|
|
info["widget"].config(text=text, foreground=color)
|
|
|
|
|
|
# ------------------------------------------------------------------
|
|
# 控制面板
|
|
# ------------------------------------------------------------------
|
|
@dataclass
|
|
class CmdSpec:
|
|
key: str
|
|
title: str
|
|
msg_cls: type
|
|
dest: str # 'c1' / 'c2'
|
|
actions: list # [(label, field)]
|
|
|
|
|
|
HVB_CMD = CmdSpec("hvb", "动力母线配电指令", protocol.MsgDisHVBCmd, "c1", [
|
|
("燃料电池断路器", "fuelCellCircuitBreaker"),
|
|
("动力锂电池断路器", "powerLithiumBatteryCircuitBreaker"),
|
|
("推进电机断路器", "propulsionMotorCircuitBreaker"),
|
|
("锂电池组仪表断路器", "lithiumBatteryGroupInstrumentCircuitBreaker"),
|
|
("DC/DC模块断路器", "dcDc5ModuleCircuitBreaker"),
|
|
("艏高压配电盒断路器", "bowHighVoltageDistributionBoxCircuitBreaker"),
|
|
("艉FT设备45断路器", "sternFTDevice45CircuitBreaker"),
|
|
("艉舵机开关1断路器", "sternRudderSwitch1CircuitBreaker"),
|
|
("艉舵机开关2断路器", "sternRudderSwitch2CircuitBreaker"),
|
|
("FB备用断路器", "fbReservedCircuitBreaker"),
|
|
("TYZ备用断路器", "tyzReservedCircuitBreaker"),
|
|
("备用断路器", "reservedCircuitBreaker"),
|
|
("DC/DC模块启动", "dcdc5Module"),
|
|
("冷却系统启动", "coolingSystem"),
|
|
])
|
|
|
|
HVBA_CMD = CmdSpec("hvba", "艏部高压配电指令", protocol.MsgDisHVBACmd, "c1", [
|
|
("艏FT设备123断路器", "bowFTDevice123CircuitBreaker"),
|
|
("执行机构断路器", "actuatorCircuitBreaker"),
|
|
("桅舵机控制箱断路器", "mastSteeringGearControlBoxCircuitBreaker"),
|
|
("XCZ断路器", "xczCircuitBreaker"),
|
|
("艏舵控制箱断路器", "bowRudderControlBoxCircuitBreaker"),
|
|
("开盖启动气缸断路器", "openWaterCoverStartCylinderCircuitBreaker"),
|
|
])
|
|
|
|
LVMB_CMD = CmdSpec("lvmb", "仪表母线配电指令", protocol.MsgDisLVMBCmd, "c2", [
|
|
("锂电池组仪表断路器", "lithiumBatteryGroupInstrumentCircuitBreaker"),
|
|
("艏低压配电盒断路器", "bowLowVoltageDistributionBoxCircuitBreaker"),
|
|
("单元4仪表48V断路器", "unit4InstrumentDC48VCircuitBreaker"),
|
|
("DC/C1直流配电板断路器", "dcC1DCDistributionPanelCircuitBreaker"),
|
|
("备用断路器1", "reservedCircuitBreaker1"),
|
|
("备用断路器2", "reservedCircuitBreaker2"),
|
|
("应急锂电池组2断路器", "emergencyLithiumBatteryGroup2CircuitBreaker"),
|
|
])
|
|
|
|
LVB_CMD = CmdSpec("lvb", "艏部低压配电指令", protocol.MsgDisLVBCmd, "c2", [
|
|
("单元1断路器", "unit1CircuitBreaker"),
|
|
("单元2断路器", "unit2CircuitBreaker"),
|
|
("单元3断路器", "unit3CircuitBreaker"),
|
|
("单元5断路器", "unit5CircuitBreaker"),
|
|
("艏PZ设备断路器", "bowPZDeviceCircuitBreaker"),
|
|
("备用断路器1", "reservedCircuitBreaker1"),
|
|
("备用断路器2", "reservedCircuitBreaker2"),
|
|
("应急锂电池组1断路器", "emergencyLithiumBatteryGroup1CircuitBreaker"),
|
|
])
|
|
|
|
CMD_SPECS = {spec.key: spec for spec in (HVB_CMD, HVBA_CMD, LVMB_CMD, LVB_CMD)}
|
|
|
|
|
|
def build_control_panel(parent, spec, on_cmd):
|
|
"""构建控制面板。on_cmd(spec, field, state)。"""
|
|
frame = ttk.LabelFrame(parent, text=spec.title, padding=10)
|
|
frame.pack(fill="x", pady=5)
|
|
for i, (label, field) in enumerate(spec.actions):
|
|
row, col = i // 3, i % 3
|
|
bf = ttk.Frame(frame)
|
|
bf.grid(row=row, column=col, padx=10, pady=2, sticky="w")
|
|
ttk.Label(bf, text=label, width=20).pack(side="left")
|
|
ttk.Button(bf, text="合", width=3,
|
|
command=lambda f=field: on_cmd(spec, f, BREAKER_ON)).pack(side="left", padx=2)
|
|
ttk.Button(bf, text="分", width=3,
|
|
command=lambda f=field: on_cmd(spec, f, BREAKER_OFF)).pack(side="left", padx=2)
|
|
return frame
|
|
|
|
|
|
# ------------------------------------------------------------------
|
|
# DC/DC 故障字显示(供状态页与独立弹窗复用)
|
|
# ------------------------------------------------------------------
|
|
FAULT1_LABELS = ["过温关机", "输出过流", "输出过压", "输出欠压",
|
|
"输入过压", "输入欠压", "输出短路保护", "内部故障"]
|
|
FAULT2_LABELS = ["通信故障", "工作状态", "冷却泵1故障", "冷却泵2故障",
|
|
"冷却水泄漏", "冷却泵1运行状态", "冷却泵2运行状态", "保留"]
|
|
|
|
|
|
def build_dcdc_display(parent, title="DC/DC 故障字"):
|
|
"""构建 DC/DC 故障字灯组,返回 refs={"words": {1: [canvas...], 2: [...]}}。"""
|
|
frame = ttk.LabelFrame(parent, text=title, padding=8)
|
|
frame.grid_columnconfigure(0, weight=1)
|
|
words = {1: [], 2: []}
|
|
for wi, labels in ((1, FAULT1_LABELS), (2, FAULT2_LABELS)):
|
|
ttk.Label(frame, text=f"DC/DC故障字{wi}:",
|
|
font=("Microsoft YaHei", 9, "bold")).grid(
|
|
row=(wi - 1) * 2, column=0, sticky="w", pady=(6, 2))
|
|
for i, label in enumerate(labels):
|
|
pf = tk.Frame(frame, borderwidth=1, relief="solid", padx=4, pady=2)
|
|
pf.grid(row=(wi - 1) * 2 + 1 + i // 4, column=i % 4, padx=5, pady=3, sticky="w")
|
|
ttk.Label(pf, text=label).pack(side="left", padx=(0, 6))
|
|
light = make_light(pf, 18)
|
|
light.pack(side="right")
|
|
words[wi].append(light)
|
|
return {"widget": frame, "words": words}
|
|
|
|
|
|
def update_dcdc_display(refs, word1, word2):
|
|
for i in range(8):
|
|
set_light(refs["words"][1][i], RED if (word1 & (1 << i)) else GREEN)
|
|
set_light(refs["words"][2][i], RED if (word2 & (1 << i)) else GREEN)
|