优化界面及参数解析
This commit is contained in:
+98
-73
@@ -17,7 +17,7 @@ class LaserTracingConfigApp:
|
|||||||
def __init__(self, root):
|
def __init__(self, root):
|
||||||
self.root = root
|
self.root = root
|
||||||
self.root.title("激光示踪配置工具")
|
self.root.title("激光示踪配置工具")
|
||||||
self.root.geometry("960x720")
|
self.root.geometry("900x700")
|
||||||
self.root.resizable(True, True)
|
self.root.resizable(True, True)
|
||||||
|
|
||||||
self.serial_port = None
|
self.serial_port = None
|
||||||
@@ -42,19 +42,19 @@ class LaserTracingConfigApp:
|
|||||||
self.port_combo.grid(row=0, column=1, padx=2)
|
self.port_combo.grid(row=0, column=1, padx=2)
|
||||||
ttk.Button(conn_frame, text="刷新", width=5, command=self._refresh_ports).grid(row=0, column=2, padx=2)
|
ttk.Button(conn_frame, text="刷新", width=5, command=self._refresh_ports).grid(row=0, column=2, padx=2)
|
||||||
|
|
||||||
ttk.Label(conn_frame, text="波特率:").grid(row=0, column=3, sticky=tk.W, padx=(12, 2))
|
ttk.Label(conn_frame, text="波特率:").grid(row=0, column=3, sticky=tk.W, padx=2)
|
||||||
self.baudrate_var = tk.StringVar(value="9600")
|
self.baudrate_var = tk.StringVar(value="9600")
|
||||||
ttk.Label(conn_frame, textvariable=self.baudrate_var, width=8).grid(row=0, column=4, padx=2)
|
ttk.Label(conn_frame, textvariable=self.baudrate_var, width=8).grid(row=0, column=4, padx=2)
|
||||||
|
|
||||||
ttk.Label(conn_frame, text="数据位:").grid(row=0, column=5, sticky=tk.W, padx=(12, 2))
|
ttk.Label(conn_frame, text="数据位:").grid(row=0, column=5, sticky=tk.W, padx=2)
|
||||||
self.databits_var = tk.StringVar(value="8")
|
self.databits_var = tk.StringVar(value="8")
|
||||||
ttk.Label(conn_frame, textvariable=self.databits_var, width=4).grid(row=0, column=6, padx=2)
|
ttk.Label(conn_frame, textvariable=self.databits_var, width=4).grid(row=0, column=6, padx=2)
|
||||||
|
|
||||||
ttk.Label(conn_frame, text="停止位:").grid(row=0, column=7, sticky=tk.W, padx=(12, 2))
|
ttk.Label(conn_frame, text="停止位:").grid(row=0, column=7, sticky=tk.W, padx=2)
|
||||||
self.stopbits_var = tk.StringVar(value="1")
|
self.stopbits_var = tk.StringVar(value="1")
|
||||||
ttk.Label(conn_frame, textvariable=self.stopbits_var, width=4).grid(row=0, column=8, padx=2)
|
ttk.Label(conn_frame, textvariable=self.stopbits_var, width=4).grid(row=0, column=8, padx=2)
|
||||||
|
|
||||||
ttk.Label(conn_frame, text="校验:").grid(row=0, column=9, sticky=tk.W, padx=(12, 2))
|
ttk.Label(conn_frame, text="校验:").grid(row=0, column=9, sticky=tk.W, padx=2)
|
||||||
self.parity_var = tk.StringVar(value="None")
|
self.parity_var = tk.StringVar(value="None")
|
||||||
ttk.Label(conn_frame, textvariable=self.parity_var, width=6).grid(row=0, column=10, padx=2)
|
ttk.Label(conn_frame, textvariable=self.parity_var, width=6).grid(row=0, column=10, padx=2)
|
||||||
|
|
||||||
@@ -95,34 +95,54 @@ class LaserTracingConfigApp:
|
|||||||
ttk.Label(query_frame, text="配置后可通过para命令验证是否成功",
|
ttk.Label(query_frame, text="配置后可通过para命令验证是否成功",
|
||||||
foreground="gray").pack(side=tk.LEFT, padx=8)
|
foreground="gray").pack(side=tk.LEFT, padx=8)
|
||||||
|
|
||||||
# 参数显示区域
|
# 参数显示区域 - 改用grid布局每行两个参数
|
||||||
para_frame = ttk.LabelFrame(self.root, text="设备参数信息", padding=8)
|
para_frame = ttk.LabelFrame(self.root, text="设备参数信息", padding=8)
|
||||||
para_frame.pack(fill=tk.BOTH, expand=True, padx=8, pady=4)
|
para_frame.pack(fill=tk.X, padx=8, pady=4)
|
||||||
|
|
||||||
# 使用Treeview展示解析后的参数(双列无表头,不可选定)
|
# 配置两列均匀分布
|
||||||
columns = ("参数", "值")
|
para_frame.columnconfigure(0, weight=1)
|
||||||
self.para_tree = ttk.Treeview(para_frame, columns=columns, show="tree headings",
|
para_frame.columnconfigure(1, weight=1)
|
||||||
height=10, selectmode="none")
|
para_frame.columnconfigure(2, weight=1)
|
||||||
self.para_tree.heading("#0", text="")
|
para_frame.columnconfigure(3, weight=1)
|
||||||
self.para_tree.heading("参数", text="")
|
|
||||||
self.para_tree.heading("值", text="")
|
|
||||||
self.para_tree.column("#0", width=0, stretch=False)
|
|
||||||
self.para_tree.column("参数", width=180, anchor=tk.W)
|
|
||||||
self.para_tree.column("值", width=380, anchor=tk.W)
|
|
||||||
tree_scroll = ttk.Scrollbar(para_frame, orient=tk.VERTICAL, command=self.para_tree.yview)
|
|
||||||
self.para_tree.configure(yscrollcommand=tree_scroll.set)
|
|
||||||
self.para_tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
|
|
||||||
tree_scroll.pack(side=tk.RIGHT, fill=tk.Y)
|
|
||||||
|
|
||||||
# 预填充参数表格(值为"-"待读取后更新)
|
# 参数按顺序每两个一组
|
||||||
self._para_order = ["软件版本", "硬件版本", "本机MAC", "电池电量", "设备类型",
|
self._para_order = ["软件版本", "硬件版本", "本机MAC", "电池电量", "设备类型",
|
||||||
"通信方式", "设备标识", "网关MAC", "注册状态",
|
"通信方式", "设备标识", "网关MAC", "注册状态", "Lora频率"]
|
||||||
"RS485_1", "RS485_2", "Lora参数", "低功耗配置",
|
|
||||||
"设备时间", "错误信息"]
|
# 创建标签对
|
||||||
self._para_value_items = {}
|
self._para_labels = {}
|
||||||
for key in self._para_order:
|
for idx, key in enumerate(self._para_order):
|
||||||
item_id = self.para_tree.insert("", tk.END, values=(key, "-"))
|
row = idx // 2
|
||||||
self._para_value_items[key] = item_id
|
col = (idx % 2) * 2
|
||||||
|
|
||||||
|
# 参数名标签
|
||||||
|
name_label = ttk.Label(para_frame, text=f"{key}:", font=("SimSun", 9))
|
||||||
|
name_label.grid(row=row, column=col, sticky=tk.W, padx=(0, 2), pady=2)
|
||||||
|
|
||||||
|
# 参数值标签
|
||||||
|
value_label = ttk.Label(para_frame, text="-", font=("SimSun", 9), foreground="green")
|
||||||
|
value_label.grid(row=row, column=col + 1, sticky=tk.W + tk.E, padx=(0, 10), pady=2)
|
||||||
|
|
||||||
|
self._para_labels[key] = value_label
|
||||||
|
|
||||||
|
# 低功耗配置单独区块 - 布局与设备参数信息一致
|
||||||
|
lp_frame = ttk.LabelFrame(self.root, text="低功耗配置", padding=6)
|
||||||
|
lp_frame.pack(fill=tk.X, padx=8, pady=4)
|
||||||
|
|
||||||
|
lp_frame.columnconfigure(0, weight=1)
|
||||||
|
lp_frame.columnconfigure(1, weight=1)
|
||||||
|
lp_frame.columnconfigure(2, weight=1)
|
||||||
|
lp_frame.columnconfigure(3, weight=1)
|
||||||
|
|
||||||
|
self._lp_labels = {}
|
||||||
|
lp_params = [("CI", "采集间隔"), ("RI", "上报时间"), ("EI", "紧急上报间隔"), ("ET", "紧急上报时长")]
|
||||||
|
for idx, (key, label) in enumerate(lp_params):
|
||||||
|
row = idx // 2
|
||||||
|
col = (idx % 2) * 2
|
||||||
|
ttk.Label(lp_frame, text=f"{label}:", font=("SimSun", 9)).grid(row=row, column=col, sticky=tk.W, padx=(0, 2), pady=2)
|
||||||
|
val_label = ttk.Label(lp_frame, text="-", font=("SimSun", 9), foreground="green")
|
||||||
|
val_label.grid(row=row, column=col + 1, sticky=tk.W + tk.E, padx=(0, 10), pady=2)
|
||||||
|
self._lp_labels[key] = val_label
|
||||||
|
|
||||||
# 通讯日志区域
|
# 通讯日志区域
|
||||||
log_frame = ttk.LabelFrame(self.root, text="通讯日志", padding=4)
|
log_frame = ttk.LabelFrame(self.root, text="通讯日志", padding=4)
|
||||||
@@ -281,15 +301,11 @@ class LaserTracingConfigApp:
|
|||||||
# ─────────────────── 回应解析 ───────────────────
|
# ─────────────────── 回应解析 ───────────────────
|
||||||
|
|
||||||
def _parse_para_response(self, text):
|
def _parse_para_response(self, text):
|
||||||
# 清空Treeview
|
|
||||||
for item in self.para_tree.get_children():
|
|
||||||
self.para_tree.delete(item)
|
|
||||||
|
|
||||||
lines = text.replace("\r\n", "\n").replace("\r", "\n").split("\n")
|
lines = text.replace("\r\n", "\n").replace("\r", "\n").split("\n")
|
||||||
|
|
||||||
key_value_patterns = [
|
key_value_patterns = [
|
||||||
(r"SoftWare V:(.*)", "软件版本"),
|
(r"[Ss]oft[Ww]are\s*[Vv]:\s*(\d+\.\d+)", "软件版本"),
|
||||||
(r"HardWare V:(.*)", "硬件版本"),
|
(r"[Hh]ard[Ww]are\s*[Vv]:\s*(\d+\.\d+)", "硬件版本"),
|
||||||
(r"Local MAC:\s*(.*)", "本机MAC"),
|
(r"Local MAC:\s*(.*)", "本机MAC"),
|
||||||
(r"Battery:\s*(.*)", "电池电量"),
|
(r"Battery:\s*(.*)", "电池电量"),
|
||||||
(r"LocalType:\s*(.*)", "设备类型"),
|
(r"LocalType:\s*(.*)", "设备类型"),
|
||||||
@@ -297,9 +313,7 @@ class LaserTracingConfigApp:
|
|||||||
(r"DeviceSign:\s*(.*)", "设备标识"),
|
(r"DeviceSign:\s*(.*)", "设备标识"),
|
||||||
(r"GateWay MAC:\s*(.*)", "网关MAC"),
|
(r"GateWay MAC:\s*(.*)", "网关MAC"),
|
||||||
(r"Register Status:\s*(.*)", "注册状态"),
|
(r"Register Status:\s*(.*)", "注册状态"),
|
||||||
(r"RS485h1:\s*(.*)", "RS485_1"),
|
(r"Lora.*?fc\s*(\d+)", "Lora频率"),
|
||||||
(r"RS485h2:\s*(.*)", "RS485_2"),
|
|
||||||
(r"Lora:\s*(.*)", "Lora参数"),
|
|
||||||
(r"LpCfg:\s*(.*)", "低功耗配置"),
|
(r"LpCfg:\s*(.*)", "低功耗配置"),
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -310,46 +324,57 @@ class LaserTracingConfigApp:
|
|||||||
if m:
|
if m:
|
||||||
found[label] = m.group(1).strip()
|
found[label] = m.group(1).strip()
|
||||||
|
|
||||||
# 解析日期时间
|
# 更新参数显示
|
||||||
dt_match = re.search(r"(\d{4}/\d{1,2}/\d{1,2}-\d{1,2}:\d{2}:\d{2})", text)
|
|
||||||
if dt_match:
|
|
||||||
found["设备时间"] = dt_match.group(1)
|
|
||||||
|
|
||||||
# 检查Error
|
|
||||||
err_match = re.search(r"Error:\s*(.*)", text)
|
|
||||||
if err_match:
|
|
||||||
found["错误信息"] = err_match.group(1).strip()
|
|
||||||
|
|
||||||
# 重建参数表格(每次收到完整响应时)
|
|
||||||
for item in self.para_tree.get_children():
|
|
||||||
self.para_tree.delete(item)
|
|
||||||
self._para_value_items = {}
|
|
||||||
for key in self._para_order:
|
for key in self._para_order:
|
||||||
value = found.get(key, "-")
|
value = found.get(key, "-")
|
||||||
item_id = self.para_tree.insert("", tk.END, values=(key, value))
|
if key in self._para_labels:
|
||||||
self._para_value_items[key] = item_id
|
self._para_labels[key].configure(text=value)
|
||||||
|
|
||||||
# 解析Lora详细参数并更新配置界面
|
# 更新Lora频率下拉框
|
||||||
if "Lora参数" in found:
|
if "Lora频率" in found:
|
||||||
lora_str = found["Lora参数"]
|
fc_val = found["Lora频率"]
|
||||||
fc_match = re.search(r"fc\s+(\d+)", lora_str)
|
display = self._fc_value_to_display.get(fc_val)
|
||||||
if fc_match:
|
if display:
|
||||||
fc_val = fc_match.group(1)
|
self.lora_fc_display_var.set(display)
|
||||||
display = self._fc_value_to_display.get(fc_val)
|
else:
|
||||||
if display:
|
new_display = f"自定义: {int(fc_val) / 1000000:.1f}MHz"
|
||||||
self.lora_fc_display_var.set(display)
|
self._fc_display_to_value[new_display] = fc_val
|
||||||
|
self._fc_value_to_display[fc_val] = new_display
|
||||||
|
self.lora_fc_combo["values"] = list(self.lora_fc_combo["values"]) + [new_display]
|
||||||
|
self.lora_fc_display_var.set(new_display)
|
||||||
|
|
||||||
|
# 解析低功耗配置参数
|
||||||
|
if "低功耗配置" in found:
|
||||||
|
lp_str = found["低功耗配置"]
|
||||||
|
|
||||||
|
ci_match = re.search(r"CI[:#\s]*(\d+)", lp_str)
|
||||||
|
ri_match = re.search(r"RI[:#\s]*(\d+)", lp_str)
|
||||||
|
ei_match = re.search(r"EI[:#\s]*(\d+)", lp_str)
|
||||||
|
et_match = re.search(r"ET[:#\s]*(\d+)", lp_str)
|
||||||
|
|
||||||
|
def format_sec(val):
|
||||||
|
return f"{val}秒"
|
||||||
|
|
||||||
|
def format_min(val):
|
||||||
|
val = int(val)
|
||||||
|
if val >= 60:
|
||||||
|
hours = val // 60
|
||||||
|
mins = val % 60
|
||||||
|
if mins == 0:
|
||||||
|
return f"{hours}时"
|
||||||
|
else:
|
||||||
|
return f"{hours}时{mins}分钟"
|
||||||
else:
|
else:
|
||||||
new_display = f"自定义: {int(fc_val) / 1000000:.1f}MHz"
|
return f"{val}分钟"
|
||||||
self._fc_display_to_value[new_display] = fc_val
|
|
||||||
self._fc_value_to_display[fc_val] = new_display
|
|
||||||
self.lora_fc_combo["values"] = list(self.lora_fc_combo["values"]) + [new_display]
|
|
||||||
self.lora_fc_display_var.set(new_display)
|
|
||||||
|
|
||||||
# 解析RS485波特率并提示
|
if ci_match:
|
||||||
if "RS485_1" in found:
|
self._lp_labels["CI"].configure(text=format_sec(ci_match.group(1)))
|
||||||
baud_match = re.search(r"Baudrate\s+(\d+)", found["RS485_1"])
|
if ri_match:
|
||||||
if baud_match:
|
self._lp_labels["RI"].configure(text=format_min(ri_match.group(1)))
|
||||||
self.baudrate_var.set(baud_match.group(1))
|
if ei_match:
|
||||||
|
self._lp_labels["EI"].configure(text=format_min(ei_match.group(1)))
|
||||||
|
if et_match:
|
||||||
|
self._lp_labels["ET"].configure(text=format_min(et_match.group(1)))
|
||||||
|
|
||||||
# ─────────────────── 日志 ───────────────────
|
# ─────────────────── 日志 ───────────────────
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user