From 144730fb3abd00ad449c339ae857461da65f6903 Mon Sep 17 00:00:00 2001 From: hulk Date: Fri, 18 Sep 2026 15:32:34 +0800 Subject: [PATCH] =?UTF-8?q?fix(DLPilot):=20=E4=BA=8C=E8=BF=9B=E5=88=B6?= =?UTF-8?q?=E8=BD=BD=E8=8D=B7=E6=97=A5=E5=BF=97=E8=A1=8C=E4=BB=A5=20hex=20?= =?UTF-8?q?=E5=B1=95=E7=A4=BA=20=E2=80=94=E2=80=94=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=A4=8D=E5=88=B6=E8=A2=AB=20NUL=20=E6=88=AA=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DLPilot/src/dlpc_rs485.py | 24 +++++++++++++++++++----- DLPilot/src/selftest_rs485.py | 6 ++++++ 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/DLPilot/src/dlpc_rs485.py b/DLPilot/src/dlpc_rs485.py index c22c087..7668204 100644 --- a/DLPilot/src/dlpc_rs485.py +++ b/DLPilot/src/dlpc_rs485.py @@ -185,15 +185,29 @@ class FrameParser: del self._buf[:1] +def _clean(s): + """控制字符 -> '·': 二进制载荷按 ASCII 解出的 NUL 等会污染日志行, + 且 Windows 剪贴板遇 NUL 直接截断复制内容""" + return ''.join(c if ord(c) >= 0x20 and ord(c) != 0x7F else '·' for c in s) + + def describe(fr): - """响应帧 -> 人读文本: TYPE 译码 + payload, err:N 追加 DLPC 错误释义""" + """响应帧 -> 人读文本: TYPE 译码 + payload, err:N 追加 DLPC 错误释义。 + + 二进制载荷(M303/M304/M305 电源实测)不以 ASCII 展示 —— 改显 hex, + 避免乱码与 NUL 截断剪贴板(值由 GUI 读数框/CLI format_power 译码)。""" + pl = fr.payload + if any(ord(c) < 0x20 or ord(c) == 0x7F for c in pl): + pl = f'[二进制载荷 {fr.raw[3:-1].hex(" ").upper()}]' + else: + pl = _clean(pl) if fr.type_code == 0xF0: - text = fr.payload or 'ok' + text = pl or 'ok' else: text = TYPE_NAMES.get(fr.type_code, f'TYPE=0x{fr.type_code:02X}') - if fr.payload: - text += f' {fr.payload}' - m = re.search(r'err:(\d+)', fr.payload) + if pl: + text += f' {pl}' + m = re.search(r'err:(\d+)', pl) if m: text += f'({DLPC_ERR_NAMES.get(int(m.group(1)), "未知错误码")})' return text diff --git a/DLPilot/src/selftest_rs485.py b/DLPilot/src/selftest_rs485.py index 13ea406..28b1bf4 100644 --- a/DLPilot/src/selftest_rs485.py +++ b/DLPilot/src/selftest_rs485.py @@ -97,5 +97,11 @@ check('M305 功率(0x8CA0=36000mW)', d.format_power('M305', frames[0]), check('M305 拒绝双字节载荷', d.format_power( 'M305', d.FrameParser().feed(bytes.fromhex('B5 F0 02 8C A0 1E'))[0]), None) +# 10) 二进制载荷的日志行安全: 无控制字符(NUL 会截断 Windows 剪贴板), 以 hex 展示 +frames = d.FrameParser().feed(bytes.fromhex('B5 F0 02 00 34 26')) # M304 应答(含 NUL) +desc = d.describe(frames[0]) +check('二进制载荷 hex 展示', desc, '[二进制载荷 00 34]') +check('日志行无控制字符', any(ord(c) < 0x20 for c in desc), False) + print('RESULT:', 'FAIL:' + ','.join(fails) if fails else 'ALL PASS') sys.exit(1 if fails else 0)