feat: DBNetClient Loop命令完善 + vd960DBN 发送调试打印

vd960DBN:
- loop_uart_proto.c: 所有发送函数添加 LUP Tx 调试打印
- tcp_json_srv.c: 新增 loop_version_query/loop_reset/loop_factory_init/
  loop_sens_read/loop_sens_write 命令处理器 + 延迟响应解析
- 修复 loop_sens_write 未设置命令状态机和错误使用解析函数的问题

DBNetClient:
- tcp_json_client.py: 新增 full Loop MCU API (6 条命令)
- main.py: 线圈参数标签页增加版本/复位/出厂/灵敏度操作按钮
This commit is contained in:
wangfq
2026-07-02 10:33:11 +08:00
parent e9b58a660e
commit e9c24ae736
4 changed files with 296 additions and 27 deletions

View File

@@ -184,14 +184,44 @@ class DBNetApp:
def _tab_loop(self, parent):
f = ttk.Frame(parent, padding=10)
ttk.Button(f, text="查询线圈参数 (loop_param_query)",
command=self._do_loop_param_query).pack(anchor=tk.W, pady=3)
ttk.Label(f, text="参数设置通过 BLE/小程序,或 Raw JSON 标签页发送。",
foreground="gray").pack(anchor=tk.W, pady=5)
self.loop_text = scrolledtext.ScrolledText(f, height=12, wrap=tk.WORD,
# Row 0: Version + System
ttk.Label(f, text="地感MCU 操作:", font=("", 10, "bold")).grid(row=0, column=0, sticky=tk.W, pady=(0,5))
btn_row = ttk.Frame(f)
btn_row.grid(row=1, column=0, columnspan=2, sticky=tk.W, pady=2)
ttk.Button(btn_row, text="查询版本", command=self._do_loop_version).pack(side=tk.LEFT, padx=2)
ttk.Button(btn_row, text="复位MCU", command=self._do_loop_reset).pack(side=tk.LEFT, padx=2)
ttk.Button(btn_row, text="出厂初始化", command=self._do_loop_factory_init).pack(side=tk.LEFT, padx=2)
ttk.Separator(f, orient=tk.HORIZONTAL).grid(row=2, column=0, columnspan=2,
sticky=tk.EW, pady=8)
# Row 3: 灵敏度
ttk.Label(f, text="线圈灵敏度 (0x8A):", font=("", 10, "bold")).grid(row=3, column=0, sticky=tk.W)
sens_row = ttk.Frame(f)
sens_row.grid(row=4, column=0, columnspan=2, sticky=tk.W, pady=2)
ttk.Button(sens_row, text="读取灵敏度", command=self._do_loop_sens_read).pack(side=tk.LEFT, padx=2)
ttk.Separator(f, orient=tk.HORIZONTAL).grid(row=5, column=0, columnspan=2,
sticky=tk.EW, pady=8)
# Row 6: 参数
ttk.Label(f, text="线圈参数 (0x63/0x64):", font=("", 10, "bold")).grid(row=6, column=0, sticky=tk.W)
param_row = ttk.Frame(f)
param_row.grid(row=7, column=0, columnspan=2, sticky=tk.W, pady=2)
ttk.Button(param_row, text="查询参数", command=self._do_loop_param_query).pack(side=tk.LEFT, padx=2)
ttk.Label(param_row, text="参数设置通过 Raw JSON 标签页发送 loop_param_set。",
foreground="gray").pack(side=tk.LEFT, padx=10)
ttk.Separator(f, orient=tk.HORIZONTAL).grid(row=8, column=0, columnspan=2,
sticky=tk.EW, pady=8)
# Response display
self.loop_text = scrolledtext.ScrolledText(f, height=14, wrap=tk.WORD,
font=("Consolas", 9))
self.loop_text.pack(fill=tk.BOTH, expand=True)
self.loop_text.grid(row=9, column=0, columnspan=2, sticky="nsew")
f.rowconfigure(9, weight=1)
f.columnconfigure(0, weight=1)
return f
def _tab_system(self, parent):
@@ -418,7 +448,27 @@ class DBNetApp:
topic_sub=self.iot_vars["topic_sub"].get().strip()),
lambda r: self._show_label(self.iot_resp, r))
# Loop
# Loop MCU
def _do_loop_version(self):
self._bg_run(lambda: self.client.loop_version_query(),
lambda r: self._show_resp(self.loop_text, r))
def _do_loop_reset(self):
if not messagebox.askyesno("确认", "复位地感MCU确定"):
return
self._bg_run(lambda: self.client.loop_reset(),
lambda r: self._show_resp(self.loop_text, r))
def _do_loop_factory_init(self):
if not messagebox.askyesno("确认", "地感MCU恢复出厂设置确定"):
return
self._bg_run(lambda: self.client.loop_factory_init(),
lambda r: self._show_resp(self.loop_text, r))
def _do_loop_sens_read(self):
self._bg_run(lambda: self.client.loop_sens_read(),
lambda r: self._show_resp(self.loop_text, r))
def _do_loop_param_query(self):
self._bg_run(lambda: self.client.loop_param_query(),
lambda r: self._show_resp(self.loop_text, r))

View File

@@ -273,12 +273,41 @@ class DBNetClient:
def device_reset(self) -> dict:
return self._tcp.send_command("device_reset")
# Loop
# Loop MCU Commands
def loop_version_query(self) -> dict:
"""获取地感MCU版本号 (CMD 0x4A)"""
return self._tcp.send_command("loop_version_query")
def loop_reset(self) -> dict:
"""复位地感MCU (CMD 0x6D)"""
return self._tcp.send_command("loop_reset")
def loop_factory_init(self) -> dict:
"""地感MCU出厂初始化 (CMD 0x92)"""
return self._tcp.send_command("loop_factory_init")
def loop_sens_read(self) -> dict:
"""读取线圈灵敏度列表 (CMD 0x8A Read)"""
return self._tcp.send_command("loop_sens_read")
def loop_sens_write(self, channels: list[dict]) -> dict:
"""写入线圈灵敏度列表 (CMD 0x8A Write)
channels: [{"ch": 1, "sens_in": 100, "sens_out": 80}, ...]
"""
return self._tcp.send_command("loop_sens_write",
{"channels": channels})
def loop_param_query(self) -> dict:
"""读取地感多路参数 (CMD 0x64)"""
return self._tcp.send_command("loop_param_query")
def loop_param_set(self, channels: list[dict],
auto_mode: bool = False) -> dict:
"""设置地感多路参数 (CMD 0x63)
channels: [{"ch": 1, "sensitivity": 7, "freq_level": 0, ...}, ...]
"""
return self._tcp.send_command("loop_param_set",
{"auto_mode": auto_mode,
"channels": channels})