From 3719c5e318cb604d6835ffb8ae53765523898566 Mon Sep 17 00:00:00 2001 From: YuanHongbin <975559679@qq.com> Date: Mon, 7 Sep 2026 16:16:39 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A0=87=E9=A2=98=E6=A0=8F=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E6=A0=87=E8=AF=86=EF=BC=9A=E7=BD=91=E5=85=B3?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E5=B7=A5=E5=85=B7=20V1.2(=E7=AA=84=E5=B8=A6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gateway_config.py | 292 +++++++++++++++++++++++----------------------- 1 file changed, 146 insertions(+), 146 deletions(-) diff --git a/gateway_config.py b/gateway_config.py index 0ab30a0..0ffe76c 100644 --- a/gateway_config.py +++ b/gateway_config.py @@ -1,6 +1,6 @@ """ -网关配置工具 -串口配置:波特率500000(可修改),数据位8,停止位1,校验位None +ù +ã500000(޸)λ8ֹͣλ1УλNone """ import sys @@ -30,18 +30,18 @@ def resource_path(relative_path): return os.path.join(os.path.abspath(os.path.dirname(__file__)), relative_path) -# ── 传感器通用串口升级协议 V1.1 ───────────────────────────── +# ͨôЭ V1.1 FRAME_HEADER = 0x7D -UPG_PACKET_DATA = 200 # 每包数据长度上限 -CMD_ANNOUNCE = 0x81 # 主机->从机:下发APP请求 -CMD_ACK = 0x01 # 从机->主机:应答(Response=0x14) -CMD_REQ_PKG = 0x02 # 从机->主机:请求包序号 -CMD_SEND_PKG = 0x82 # 主机->从机:下发包 +UPG_PACKET_DATA = 200 # ÿݳ +CMD_ANNOUNCE = 0x81 # ->ӻ·APP +CMD_ACK = 0x01 # ӻ->Ӧ(Response=0x14) +CMD_REQ_PKG = 0x02 # ӻ-> +CMD_SEND_PKG = 0x82 # ->ӻ· PKG_DATALEN_MAX = 200 def crc16_modbus(data): - """MODBUS CRC16,多项式0x8005(反射),返回16位整数。""" + """MODBUS CRC16ʽ0x8005()16λ""" crc = 0xFFFF for b in data: crc ^= b @@ -54,14 +54,14 @@ def crc16_modbus(data): def build_frame(dev_mac, cmd, payload): - """0x7D + DevMac(6) + Cmd + PayloadLen + Payload + CRC16(小端)。""" + """0x7D + DevMac(6) + Cmd + PayloadLen + Payload + CRC16(С)""" body = bytes([FRAME_HEADER]) + bytes(dev_mac) + bytes([cmd, len(payload)]) + bytes(payload) crc = crc16_modbus(body) return body + struct.pack(' bytes(6),无效返回 None。""" + """'81-00-00-06-00-00' -> bytes(6)Ч None""" if not s: return None parts = s.strip().replace('-', ':').split(':') @@ -93,7 +93,7 @@ class SerialThread(QThread): self.data_received_raw.emit(data) buf = self._buffer + data text = None - # 优先 UTF-8;若结尾是不完整字符序列则保留尾部待下次拼接,避免乱码缺字 + # UTF-8βDzַβ´ƴӣȱ for enc in ('utf-8', 'gbk'): try: text = buf.decode(enc) @@ -133,7 +133,7 @@ class GatewayConfigTool(QMainWindow): self.serial_thread = None self._recv_buffer = "" self._para_mode = False - # para 大数据量返回时,用定时器延迟解析,避免每段数据全量解析阻塞UI导致串口缓冲溢出丢包 + # para ʱöʱӳٽÿȫUI´ڻ self._para_timer = QTimer(self) self._para_timer.setSingleShot(True) self._para_timer.setInterval(250) @@ -144,8 +144,8 @@ class GatewayConfigTool(QMainWindow): self.refresh_ports() def init_ui(self): - self.setWindowTitle("网关配置工具") - self.setWindowIcon(QIcon(resource_path("物联网网关.png"))) + self.setWindowTitle("ù V1.2(խ)") + self.setWindowIcon(QIcon(resource_path(".png"))) self.setMinimumSize(940, 640) self.resize(1000, 700) @@ -155,35 +155,35 @@ class GatewayConfigTool(QMainWindow): main_layout.setSpacing(4) main_layout.setContentsMargins(4, 4, 4, 4) - # === 串口连接区 === - conn_group = QGroupBox("串口连接") + # === === + conn_group = QGroupBox("") conn_layout = QHBoxLayout(conn_group) - conn_layout.addWidget(QLabel("串口:")) + conn_layout.addWidget(QLabel(":")) self.combo_port = QComboBox() self.combo_port.setMinimumWidth(120) conn_layout.addWidget(self.combo_port) - self.btn_refresh = QPushButton("刷新") + self.btn_refresh = QPushButton("ˢ") self.btn_refresh.setFixedWidth(60) self.btn_refresh.clicked.connect(self.refresh_ports) conn_layout.addWidget(self.btn_refresh) conn_layout.addSpacing(20) - conn_layout.addWidget(QLabel("波特率:")) + conn_layout.addWidget(QLabel(":")) self.combo_baud = QComboBox() self.combo_baud.setEditable(True) self.combo_baud.addItems(["115200", "230400", "460800", "500000", "921600", "1000000"]) self.combo_baud.setCurrentText("500000") self.combo_baud.setFixedWidth(90) conn_layout.addWidget(self.combo_baud) - conn_layout.addWidget(QLabel("数据位: 8")) - conn_layout.addWidget(QLabel("停止位: 1")) - conn_layout.addWidget(QLabel("校验: None")) + conn_layout.addWidget(QLabel("λ: 8")) + conn_layout.addWidget(QLabel("ֹͣλ: 1")) + conn_layout.addWidget(QLabel("У: None")) conn_layout.addStretch() - self.btn_connect = QPushButton("打开串口") + self.btn_connect = QPushButton("򿪴") self.btn_connect.setFixedWidth(100) self.btn_connect.setStyleSheet("font-weight:bold;") self.btn_connect.clicked.connect(self.toggle_serial) @@ -191,17 +191,17 @@ class GatewayConfigTool(QMainWindow): main_layout.addWidget(conn_group) - # === 参数配置区 === - config_group = QGroupBox("参数配置") + # === === + config_group = QGroupBox("") config_group_layout = QVBoxLayout(config_group) config_group_layout.setSpacing(4) - # Lora 参数(子分组) - lora_group = QGroupBox("Lora 参数") + # Lora ӷ飩 + lora_group = QGroupBox("Lora ") lora_layout = QHBoxLayout(lora_group) lora_layout.setSpacing(6) - lora_layout.addWidget(QLabel("信道频率(fc):")) + lora_layout.addWidget(QLabel("ŵƵ(fc):")) self.combo_lora_fc = QComboBox() self.combo_lora_fc.setFixedWidth(200) lora_freqs = [] @@ -209,7 +209,7 @@ class GatewayConfigTool(QMainWindow): ch_idx = 0 while fc_hz <= 492600000: mhz = fc_hz / 1000000 - lora_freqs.append((str(fc_hz), f"信道{ch_idx}: {mhz:.1f}MHz")) + lora_freqs.append((str(fc_hz), f"ŵ{ch_idx}: {mhz:.1f}MHz")) fc_hz += 500000 ch_idx += 1 for freq, desc in lora_freqs: @@ -221,40 +221,40 @@ class GatewayConfigTool(QMainWindow): ) lora_layout.addWidget(self.combo_lora_fc) - self.btn_lora_fc = QPushButton("发送") + self.btn_lora_fc = QPushButton("") self.btn_lora_fc.setFixedWidth(60) self.btn_lora_fc.setStyleSheet("font-weight:bold;") self.btn_lora_fc.clicked.connect(self.on_lora_send) lora_layout.addWidget(self.btn_lora_fc) - lora_hint = QLabel("设置LoRa通信信道频率") + lora_hint = QLabel("LoRaͨŵƵ") lora_hint.setStyleSheet("color:#909090;") lora_layout.addWidget(lora_hint) lora_layout.addStretch() config_group_layout.addWidget(lora_group) - # 查看配置按钮 + 提示 + # 鿴ðť + ʾ btn_row = QHBoxLayout() btn_row.setSpacing(6) - self.btn_para = QPushButton("查看配置(para)") + self.btn_para = QPushButton("鿴(para)") self.btn_para.setFixedWidth(130) self.btn_para.clicked.connect(self.on_para_clicked) btn_row.addWidget(self.btn_para) - self.btn_upgrade = QPushButton("设备升级") + self.btn_upgrade = QPushButton("豸") self.btn_upgrade.setFixedWidth(100) self.btn_upgrade.setStyleSheet("background-color:#1976D2; color:white; font-weight:bold;") self.btn_upgrade.clicked.connect(self.on_upgrade_clicked) btn_row.addWidget(self.btn_upgrade) - self.btn_dev_mgmt = QPushButton("设备管理") + self.btn_dev_mgmt = QPushButton("豸") self.btn_dev_mgmt.setFixedWidth(100) self.btn_dev_mgmt.setStyleSheet("background-color:#388E3C; color:white; font-weight:bold;") self.btn_dev_mgmt.clicked.connect(self.on_dev_mgmt_clicked) btn_row.addWidget(self.btn_dev_mgmt) - para_hint = QLabel("配置后可通过para命令验证是否成功") + para_hint = QLabel("úͨpara֤Ƿɹ") para_hint.setStyleSheet("color:#909090;") btn_row.addWidget(para_hint) btn_row.addStretch() @@ -262,8 +262,8 @@ class GatewayConfigTool(QMainWindow): main_layout.addWidget(config_group) - # === 设备参数信息区 === - info_group = QGroupBox("设备参数信息") + # === 豸Ϣ === + info_group = QGroupBox("豸Ϣ") info_grid = QGridLayout(info_group) info_grid.setSpacing(8) info_grid.setContentsMargins(12, 8, 12, 8) @@ -274,34 +274,34 @@ class GatewayConfigTool(QMainWindow): return lb row = 0 - info_grid.addWidget(QLabel("软件版本:"), row, 0) + info_grid.addWidget(QLabel("汾:"), row, 0) self.label_sw_ver = _val_label() info_grid.addWidget(self.label_sw_ver, row, 1) - info_grid.addWidget(QLabel("硬件版本:"), row, 2) + info_grid.addWidget(QLabel("Ӳ汾:"), row, 2) self.label_hw_ver = _val_label() info_grid.addWidget(self.label_hw_ver, row, 3) row = 1 - info_grid.addWidget(QLabel("电池电量:"), row, 0) + info_grid.addWidget(QLabel("ص:"), row, 0) self.label_battery = _val_label() info_grid.addWidget(self.label_battery, row, 1) - info_grid.addWidget(QLabel("注册状态:"), row, 2) + info_grid.addWidget(QLabel("ע״̬:"), row, 2) self.label_reg_status = _val_label() info_grid.addWidget(self.label_reg_status, row, 3) row = 2 - info_grid.addWidget(QLabel("通讯方式:"), row, 0) + info_grid.addWidget(QLabel("ͨѶʽ:"), row, 0) self.label_cur_comm = _val_label() info_grid.addWidget(self.label_cur_comm, row, 1) - info_grid.addWidget(QLabel("Lora频率:"), row, 2) + info_grid.addWidget(QLabel("LoraƵ:"), row, 2) self.label_cur_lora_fc = _val_label() info_grid.addWidget(self.label_cur_lora_fc, row, 3) row = 3 - info_grid.addWidget(QLabel("网关MAC:"), row, 0) + info_grid.addWidget(QLabel("MAC:"), row, 0) self.label_gw_mac = _val_label() info_grid.addWidget(self.label_gw_mac, row, 1) - info_grid.addWidget(QLabel("通讯单元读取间隔:"), row, 2) + info_grid.addWidget(QLabel("ͨѶԪȡ:"), row, 2) self.label_comm_interval = _val_label() info_grid.addWidget(self.label_comm_interval, row, 3) @@ -315,13 +315,13 @@ class GatewayConfigTool(QMainWindow): main_layout.addWidget(info_group) - # === 下方:通讯日志 + 自定义指令 === + # === ·ͨѶ־ + Զָ === bottom_widget = QWidget() bottom_layout = QHBoxLayout(bottom_widget) bottom_layout.setContentsMargins(0, 0, 0, 0) bottom_layout.setSpacing(4) - log_group = QGroupBox("通讯日志") + log_group = QGroupBox("ͨѶ־") log_inner = QVBoxLayout(log_group) self.text_log = QTextEdit() @@ -333,23 +333,23 @@ class GatewayConfigTool(QMainWindow): log_inner.addWidget(self.text_log) log_btn_layout = QHBoxLayout() - self.btn_clear_log = QPushButton("清空日志") + self.btn_clear_log = QPushButton("־") self.btn_clear_log.clicked.connect(self.text_log.clear) log_btn_layout.addWidget(self.btn_clear_log) log_btn_layout.addStretch() log_inner.addLayout(log_btn_layout) - custom_group = QGroupBox("自定义指令") + custom_group = QGroupBox("Զָ") custom_inner = QVBoxLayout(custom_group) custom_inner.setSpacing(6) - custom_inner.addWidget(QLabel("指令:")) + custom_inner.addWidget(QLabel("ָ:")) self.edit_custom = QLineEdit() - self.edit_custom.setPlaceholderText("输入指令...") + self.edit_custom.setPlaceholderText("ָ...") self.edit_custom.returnPressed.connect(self.send_custom_command) custom_inner.addWidget(self.edit_custom) - self.btn_custom_send = QPushButton("发送") + self.btn_custom_send = QPushButton("") self.btn_custom_send.setStyleSheet("font-weight:bold;") self.btn_custom_send.clicked.connect(self.send_custom_command) custom_inner.addWidget(self.btn_custom_send) @@ -359,20 +359,20 @@ class GatewayConfigTool(QMainWindow): bottom_layout.addWidget(custom_group, 1) main_layout.addWidget(bottom_widget, 1) - self.statusBar().showMessage("就绪 - 请选择串口并连接") + self.statusBar().showMessage(" - ѡ񴮿ڲ") def refresh_ports(self): self.combo_port.clear() ports = serial.tools.list_ports.comports() if not ports: - self.combo_port.addItem("无可用串口") + self.combo_port.addItem("޿ô") return for p in ports: self.combo_port.addItem(f"{p.device} - {p.description}") def get_port_name(self): text = self.combo_port.currentText() - if not text or text.startswith("无"): + if not text or text.startswith(""): return None return text.split(" - ")[0] @@ -385,12 +385,12 @@ class GatewayConfigTool(QMainWindow): def open_serial(self): port_name = self.get_port_name() if not port_name: - QMessageBox.warning(self, "错误", "请选择有效的串口!") + QMessageBox.warning(self, "", "ѡЧĴڣ") return try: baud = int(self.combo_baud.currentText().strip()) except ValueError: - QMessageBox.warning(self, "错误", "波特率无效,请输入数字!") + QMessageBox.warning(self, "", "Ч֣") return try: self.serial_port = serial.Serial( @@ -406,12 +406,12 @@ class GatewayConfigTool(QMainWindow): self.serial_thread.data_received_raw.connect(self.on_upgrade_data) self.serial_thread.start() - self.btn_connect.setText("关闭串口") + self.btn_connect.setText("رմ") self.btn_connect.setStyleSheet("background-color:#f44336; color:white; font-weight:bold;") - self.log_send(f"已连接 {port_name} @ {baud}") - self.statusBar().showMessage(f"已连接: {port_name}") + self.log_send(f" {port_name} @ {baud}") + self.statusBar().showMessage(f": {port_name}") except Exception as e: - QMessageBox.critical(self, "串口错误", f"无法打开串口:\n{e}") + QMessageBox.critical(self, "ڴ", f"޷򿪴:\n{e}") def close_serial(self): if self.serial_thread: @@ -420,12 +420,12 @@ class GatewayConfigTool(QMainWindow): if self.serial_port and self.serial_port.is_open: port_name = self.serial_port.port self.serial_port.close() - self.log_send(f"已断开 {port_name}") + self.log_send(f"ѶϿ {port_name}") self.serial_port = None - self.btn_connect.setText("打开串口") + self.btn_connect.setText("򿪴") self.btn_connect.setStyleSheet("font-weight:bold;") - self.statusBar().showMessage("已断开") + self.statusBar().showMessage("ѶϿ") def on_para_clicked(self): self._recv_buffer = "" @@ -446,28 +446,28 @@ class GatewayConfigTool(QMainWindow): def send_command(self, cmd): if not self.serial_port or not self.serial_port.is_open: - QMessageBox.warning(self, "错误", "请先打开串口!") + QMessageBox.warning(self, "", "ȴ򿪴ڣ") return try: data = (cmd + "\r\n").encode('utf-8') self.serial_port.write(data) self.log_send(f">>> {cmd}") except Exception as e: - self.log_send(f"[发送错误] {e}") + self.log_send(f"[ʹ] {e}") def send_raw(self, data): if not self.serial_port or not self.serial_port.is_open: - QMessageBox.warning(self, "错误", "请先打开串口!") + QMessageBox.warning(self, "", "ȴ򿪴ڣ") return False try: self.serial_port.write(data) self.log_send(f">>> {data.hex(' ').upper()}") return True except Exception as e: - self.log_send(f"[发送错误] {e}") + self.log_send(f"[ʹ] {e}") return False - # ── 设备升级 ───────────────────────────────────────── + # 豸 def on_upgrade_clicked(self): if self.upgrade_dialog is None: self.upgrade_dialog = UpgradeDialog(self) @@ -480,10 +480,10 @@ class GatewayConfigTool(QMainWindow): def upgrade_active(self): return self.upgrade_dialog is not None and self.upgrade_dialog.isUpgrading() - # ── 设备管理(查询/删除) ──────────────────────────── + # 豸ѯ/ɾ def on_dev_mgmt_clicked(self): if not self.serial_port or not self.serial_port.is_open: - QMessageBox.warning(self, "错误", "请先打开串口!") + QMessageBox.warning(self, "", "ȴ򿪴ڣ") return if self.dev_dialog is None: self.dev_dialog = DeviceDialog(self) @@ -517,7 +517,7 @@ class GatewayConfigTool(QMainWindow): buf = self._recv_buffer.replace('\r', '') lines_all = [l.strip() for l in buf.split('\n')] - # 查找 *** 包围的块 + # *** ΧĿ star_indices = [i for i, l in enumerate(lines_all) if l and all(c == '*' for c in l)] if len(star_indices) < 2: return @@ -543,7 +543,7 @@ class GatewayConfigTool(QMainWindow): _update(self.label_hw_ver, m.group(2)) continue - # Key: Value 行 + # Key: Value m = re.match(r'([\w\s/()]+?):\s*(.*)', line) if not m: continue @@ -563,11 +563,11 @@ class GatewayConfigTool(QMainWindow): elif key == 'CommUnitReadInterval': _update(self.label_comm_interval, f"{val} s") elif key == 'MuchReg': - status_map = {"true": "已注册", "false": "未注册", "null": "未注册"} + status_map = {"true": "ע", "false": "δע", "null": "δע"} _update(self.label_reg_status, status_map.get(val, val)) # --- LTENet (Cat1) section --- elif key == 'DestAddr' and 'Cat1' in section: - pass # Cat1远端地址暂不单独显示 + pass # Cat1Զ˵ַݲʾ elif key == 'DestPort' and 'Cat1' in section: pass elif key == 'LocalAddr': @@ -586,7 +586,7 @@ class GatewayConfigTool(QMainWindow): self._para_mode = False self._recv_buffer = "" - self.statusBar().showMessage("配置读取完成") + self.statusBar().showMessage("öȡ") @staticmethod def _escape_html(s): @@ -605,16 +605,16 @@ class GatewayConfigTool(QMainWindow): class UpgradeDialog(QDialog): - """设备升级对话框:参照通用串口升级协议V1.1。""" + """豸Ի򣺲ͨôЭV1.1""" def __init__(self, main_window): super().__init__(main_window) self.main = main_window - self.setWindowTitle("设备升级 - 通用串口升级协议V1.1") + self.setWindowTitle("豸 - ͨôЭV1.1") self.setModal(False) self.resize(720, 520) - self.running = False # 升级进行中 + self.running = False # self._mac = None self._fw_data = b"" self._pkg_num = 0 @@ -628,33 +628,33 @@ class UpgradeDialog(QDialog): root.setContentsMargins(8, 8, 8, 8) root.setSpacing(6) - # ── 升级设置 ── - cfg = QGroupBox("升级设置") + # + cfg = QGroupBox("") cfg_layout = QGridLayout(cfg) cfg_layout.setSpacing(6) - cfg_layout.addWidget(QLabel("固件文件(.bin):"), 0, 0) + cfg_layout.addWidget(QLabel("̼ļ(.bin):"), 0, 0) self.fw_edit = QLineEdit() - self.fw_edit.setPlaceholderText("选择固件文件...") + self.fw_edit.setPlaceholderText("ѡ̼ļ...") cfg_layout.addWidget(self.fw_edit, 0, 1) - btn_browse = QPushButton("浏览") + btn_browse = QPushButton("") btn_browse.clicked.connect(self._choose_file) cfg_layout.addWidget(btn_browse, 0, 2) - cfg_layout.addWidget(QLabel("设备MAC:"), 1, 0) + cfg_layout.addWidget(QLabel("豸MAC:"), 1, 0) default_mac = main_window.label_gw_mac.text() self.mac_edit = QLineEdit(default_mac if default_mac != "-" else "") self.mac_edit.setPlaceholderText("81-00-00-06-00-00") cfg_layout.addWidget(self.mac_edit, 1, 1) - mac_hint = QLabel("6字节从机MAC地址") + mac_hint = QLabel("6ֽڴӻMACַ") mac_hint.setStyleSheet("color:#909090;") cfg_layout.addWidget(mac_hint, 1, 2) btn_row = QHBoxLayout() - self.start_btn = QPushButton("开始升级") + self.start_btn = QPushButton("ʼ") self.start_btn.clicked.connect(self._start) btn_row.addWidget(self.start_btn) - btn_close = QPushButton("关闭") + btn_close = QPushButton("ر") btn_close.clicked.connect(self.close) btn_row.addWidget(btn_close) btn_row.addStretch() @@ -663,7 +663,7 @@ class UpgradeDialog(QDialog): self.progress = QProgressBar() self.progress.setRange(0, 100) self.progress.setValue(0) - # 固定进度条颜色,避免窗口失活(点击弹窗外)时变色 + # ̶ɫⴰʧ()ʱɫ self.progress.setStyleSheet(""" QProgressBar { border: 1px solid #B0B0B0; @@ -676,19 +676,19 @@ class UpgradeDialog(QDialog): } """) cfg_layout.addWidget(self.progress, 3, 0, 1, 2) - self.status_lbl = QLabel("就绪") + self.status_lbl = QLabel("") cfg_layout.addWidget(self.status_lbl, 3, 2) root.addWidget(cfg) - # ── 升级日志 ── - log_group = QGroupBox("升级日志") + # ־ + log_group = QGroupBox("־") log_layout = QVBoxLayout(log_group) self.log_text = QTextEdit() self.log_text.setReadOnly(True) self.log_text.setFont(QFont("Consolas", 9)) log_btn_row = QHBoxLayout() - btn_clear_log = QPushButton("清空日志") + btn_clear_log = QPushButton("־") btn_clear_log.clicked.connect(self.log_text.clear) log_btn_row.addStretch() log_btn_row.addWidget(btn_clear_log) @@ -700,7 +700,7 @@ class UpgradeDialog(QDialog): return self.running def _reset_ui(self): - """重置弹窗 UI 到初始状态,避免关闭后重新打开时界面卡住。""" + """õ UI ʼ״̬رպ´ʱ濨ס""" self.running = False self._timer.stop() self._buf = b"" @@ -710,11 +710,11 @@ class UpgradeDialog(QDialog): self._pkg_num = 0 self.start_btn.setEnabled(True) self.progress.setValue(0) - self.status_lbl.setText("就绪") + self.status_lbl.setText("") def _choose_file(self): path, _ = QFileDialog.getOpenFileName( - self, "选择固件文件", "", "固件文件 (*.bin);;所有文件 (*)" + self, "ѡ̼ļ", "", "̼ļ (*.bin);;ļ (*)" ) if path: self.fw_edit.setText(path) @@ -729,7 +729,7 @@ class UpgradeDialog(QDialog): if any(0x20 <= b <= 0x7E for b in data): text = data.decode('utf-8', errors='replace').strip('\x00\r\n ') if text: - self._log(f"[设备] {text}") + self._log(f"[豸] {text}") def _start(self): if self.running: @@ -737,22 +737,22 @@ class UpgradeDialog(QDialog): path = self.fw_edit.text().strip() mac = parse_mac(self.mac_edit.text()) if not path or not os.path.exists(path): - QMessageBox.warning(self, "提示", "请先选择固件文件") + QMessageBox.warning(self, "ʾ", "ѡ̼ļ") return if mac is None: - QMessageBox.warning(self, "提示", "设备MAC格式错误,应为 81-00-00-06-00-00") + QMessageBox.warning(self, "ʾ", "豸MACʽӦΪ 81-00-00-06-00-00") return if not self.main.serial_port or not self.main.serial_port.is_open: - QMessageBox.warning(self, "提示", "请先打开串口") + QMessageBox.warning(self, "ʾ", "ȴ򿪴") return try: with open(path, 'rb') as f: fw = f.read() except Exception as e: - QMessageBox.critical(self, "错误", f"读取固件失败: {e}") + QMessageBox.critical(self, "", f"ȡ̼ʧ: {e}") return if not fw: - QMessageBox.warning(self, "提示", "固件文件为空") + QMessageBox.warning(self, "ʾ", "̼ļΪ") return self._mac = mac @@ -763,14 +763,14 @@ class UpgradeDialog(QDialog): self.running = True self.start_btn.setEnabled(False) self.progress.setValue(0) - self.status_lbl.setText("等待握手...") + self.status_lbl.setText("ȴ...") app_crc = zlib.crc32(fw) & 0xFFFFFFFF payload = struct.pack('= 11: idx = self._buf.find(bytes([FRAME_HEADER])) if idx < 0: - # 无帧头,保留末尾字节以防跨包帧头 + # ֡ͷĩβֽԷ֡ͷ self._buf = self._buf[-1:] return None if idx > 0: @@ -804,23 +804,23 @@ class UpgradeDialog(QDialog): if crc16_modbus(frame[:-2]) == (frame[-2] | (frame[-1] << 8)): self._buf = self._buf[total:] return (cmd, payload) - # 误判的帧头,丢弃继续寻找 + # е֡ͷѰ self._buf = self._buf[1:] return None def _handle(self, cmd, payload): self._timer.start(5000) if cmd == CMD_ACK: - self._log("收到从机应答(0x01)", "ok") - self.status_lbl.setText("设备就绪") + self._log("յӻӦ(0x01)", "ok") + self.status_lbl.setText("豸") return if cmd == CMD_REQ_PKG: if len(payload) < 4: - self._log("从机请求包帧格式错误", "err") + self._log("ӻ֡ʽ", "err") return idx, total = struct.unpack('= self._pkg_num: - self._log(f"从机请求包序号越界({idx}),视为完成", "ok") + self._log(f"ӻԽ({idx})Ϊ", "ok") self._finish() return start = idx * UPG_PACKET_DATA @@ -831,22 +831,22 @@ class UpgradeDialog(QDialog): self._sent.add(idx) pct = len(self._sent) * 100.0 / self._pkg_num self.progress.setValue(int(pct)) - self.status_lbl.setText(f"{len(self._sent)}/{self._pkg_num} 包") + self.status_lbl.setText(f"{len(self._sent)}/{self._pkg_num} ") if len(self._sent) >= self._pkg_num: self._finish() return - self._log(f"收到其他帧 Cmd={cmd:#04x}", "err") + self._log(f"յ֡ Cmd={cmd:#04x}", "err") def _finish(self): self.running = False self._timer.stop() self.start_btn.setEnabled(True) if len(self._sent) >= self._pkg_num: - self._log(f"升级完成 (已发送全部 {len(self._sent)} 包)", "ok") + self._log(f" (ѷȫ {len(self._sent)} )", "ok") self.progress.setValue(100) - self.status_lbl.setText("完成") + self.status_lbl.setText("") else: - self._log(f"升级未完成,已发送 {len(self._sent)}/{self._pkg_num} 包", "err") + self._log(f"δɣѷ {len(self._sent)}/{self._pkg_num} ", "err") def _on_timeout(self): if not self.running: @@ -854,8 +854,8 @@ class UpgradeDialog(QDialog): self.running = False self._timer.stop() self.start_btn.setEnabled(True) - self._log("升级超时(5秒无响应)", "err") - self.status_lbl.setText("超时") + self._log("ʱ(5Ӧ)", "err") + self.status_lbl.setText("ʱ") def closeEvent(self, event): self._reset_ui() @@ -863,17 +863,17 @@ class UpgradeDialog(QDialog): class DeviceDialog(QDialog): - """设备管理对话框:通过 culs 查询已注册通讯单元,cudel 删除设备。""" + """豸Իͨ culs ѯעͨѶԪcudel ɾ豸""" def __init__(self, main_window): super().__init__(main_window) self.main = main_window - self.setWindowTitle("设备管理 - 查询/删除") + self.setWindowTitle("豸 - ѯ/ɾ") self.setModal(False) self.resize(860, 520) self._buf = "" - self._pending_del = None # 等待删除结果的MAC,"all"表示删除全部 + self._pending_del = None # ȴɾMAC"all"ʾɾȫ self._quiet = QTimer(self) self._quiet.setSingleShot(True) self._quiet.timeout.connect(self._on_quiet) @@ -883,25 +883,25 @@ class DeviceDialog(QDialog): root.setSpacing(6) btn_row = QHBoxLayout() - self.btn_refresh = QPushButton("刷新查询") + self.btn_refresh = QPushButton("ˢ²ѯ") self.btn_refresh.clicked.connect(self.query) btn_row.addWidget(self.btn_refresh) - self.btn_del_all = QPushButton("删除全部设备") + self.btn_del_all = QPushButton("ɾȫ豸") self.btn_del_all.setStyleSheet("color:#D32F2F; font-weight:bold;") self.btn_del_all.clicked.connect(self._del_all) btn_row.addWidget(self.btn_del_all) - btn_close = QPushButton("关闭") + btn_close = QPushButton("ر") btn_close.clicked.connect(self.close) btn_row.addWidget(btn_close) btn_row.addStretch() - self.status_lbl = QLabel("就绪") + self.status_lbl = QLabel("") btn_row.addWidget(self.status_lbl) root.addLayout(btn_row) self.table = QTableWidget(0, 11) self.table.setHorizontalHeaderLabels( - ["DevType", "设备MAC", "传感器类型", "Laser", "电量", - "RSSI", "SNR", "FPO", "LpCfg", "在线", "操作"]) + ["DevType", "豸MAC", "", "Laser", "", + "RSSI", "SNR", "FPO", "LpCfg", "", ""]) self.table.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents) self.table.horizontalHeader().setStretchLastSection(True) self.table.setEditTriggers(QAbstractItemView.NoEditTriggers) @@ -911,18 +911,18 @@ class DeviceDialog(QDialog): def _serial_ok(self): if not self.main.serial_port or not self.main.serial_port.is_open: - QMessageBox.warning(self, "错误", "请先打开串口!") + QMessageBox.warning(self, "", "ȴ򿪴ڣ") return False return True - # ── 查询 ── + # ѯ def query(self): if not self._serial_ok(): return self._buf = "" self._pending_del = None self._quiet.stop() - self.status_lbl.setText("查询中...") + self.status_lbl.setText("ѯ...") self.main.send_command("culs") self._quiet.start(800) @@ -934,13 +934,13 @@ class DeviceDialog(QDialog): if self._pending_del is not None: buf = self._buf if "deleted" in buf.lower(): - self.status_lbl.setText(f"删除成功 ({self._pending_del})") + self.status_lbl.setText(f"ɾɹ ({self._pending_del})") elif "not registered" in buf: - self.status_lbl.setText("删除失败:设备未注册") + self.status_lbl.setText("ɾʧܣ豸δע") elif "Para Error" in buf: - self.status_lbl.setText("删除失败:指令参数错误") + self.status_lbl.setText("ɾʧܣָ") else: - self.status_lbl.setText("删除失败:设备无响应") + self.status_lbl.setText("ɾʧܣ豸Ӧ") self._pending_del = None self.query() return @@ -951,14 +951,14 @@ class DeviceDialog(QDialog): cur = None for raw in self._buf.replace('\r', '').split('\n'): line = raw.strip() - # Lora通讯单元:DevType: XXXX, SensorNum: N + # LoraͨѶԪDevType: XXXX, SensorNum: N m = re.match(r'DevType:\s*([0-9A-Fa-f]{4}),\s*SensorNum:\s*(\d+)', line) if m: cur = {"type": m.group(1).upper(), "builtin": False, "macs": [], "types": [], "bat": "", "rssi": "", "snr": "", "online": ""} devices.append(cur) continue - # RS485内置通讯单元:DevType: XXXX(单独一行) + # RS485ͨѶԪDevType: XXXXһУ m = re.match(r'DevType:\s*([0-9A-Fa-f]{4})$', line) if m: cur = {"type": m.group(1).upper(), "builtin": True, @@ -1008,7 +1008,7 @@ class DeviceDialog(QDialog): for dev in devices: row = self.table.rowCount() self.table.insertRow(row) - type_str = dev["type"] + ("(内置)" if dev["builtin"] else "") + type_str = dev["type"] + ("()" if dev["builtin"] else "") macs = "\n".join(f"{role}: {mac}" for role, mac in dev["macs"]) types = " ".join(dev["types"]) if dev["types"] else "-" online = dev["online"] or "-" @@ -1026,38 +1026,38 @@ class DeviceDialog(QDialog): self.table.setItem(row, col, item) master = next((mac for role, mac in dev["macs"] if role == "Master"), None) if master and not dev["builtin"]: - btn = QPushButton("删除") + btn = QPushButton("ɾ") btn.setStyleSheet("color:#D32F2F;") btn.clicked.connect(lambda _, m=master: self._del_one(m)) self.table.setCellWidget(row, 10, btn) else: self.table.setItem(row, 10, QTableWidgetItem("-" if dev["builtin"] else "")) - self.status_lbl.setText(f"共 {len(devices)} 个设备") + self.status_lbl.setText(f" {len(devices)} 豸") - # ── 删除 ── + # ɾ def _del_one(self, mac): if not self._serial_ok(): return - ret = QMessageBox.question(self, "确认删除", f"确定删除设备 {mac} 吗?", + ret = QMessageBox.question(self, "ȷɾ", f"ȷɾ豸 {mac} ", QMessageBox.Yes | QMessageBox.No) if ret != QMessageBox.Yes: return self._buf = "" self._pending_del = mac - self.status_lbl.setText(f"正在删除 {mac} ...") + self.status_lbl.setText(f"ɾ {mac} ...") self.main.send_command(f"cudel {mac}") self._quiet.start(800) def _del_all(self): if not self._serial_ok(): return - ret = QMessageBox.question(self, "确认删除", "确定删除全部已注册设备吗?", + ret = QMessageBox.question(self, "ȷɾ", "ȷɾȫע豸", QMessageBox.Yes | QMessageBox.No) if ret != QMessageBox.Yes: return self._buf = "" self._pending_del = "all" - self.status_lbl.setText("正在删除全部设备 ...") + self.status_lbl.setText("ɾȫ豸 ...") self.main.send_command("cudel all") self._quiet.start(800)