自用串口工具分享
自用串口工具分享
粘土,一个面向嵌入式调试的串口工具,支持 多串口同时连接、自定义常用命令、
自动高亮匹配行、条件触发任务,以及 跨端口联动(在 A 口检测到指定字符串时,
向 B 口发送预置命令)。命令模板和匹配规则支持 正则表达式与参数化,并可接入
大模型,用自然语言生成配置。

主界面:每个串口一个页签,底部选择端口/波特率连接,中部为快捷命令按钮栏。

深色主题(工具栏 🌙 按钮切换)。
✨ 功能特性
- 多串口并行:每个串口一个标签页,独立连接/收发/显示,互不干扰。
- 高亮显示:按正则匹配整行着色(前景/背景/粗体/斜体),规则按顺序生效。
- 条件触发:收到匹配行后,可用表达式过滤(如
m1 > target_temp),再执行动作。 - 跨端口联动:A 口匹配 → 向 B 口发送渲染后的命令(核心特性)。
- 参数化命令:模板支持正则捕获组
${match.1}、内置变量${timestamp}/${date}/${time}/${port}、
用户变量${var_name},以及字符串处理管道:
|upper |lower |hex |unhex |replace(a,b) |substr(0,4) |trim |pad(8,0),可链式。 - 大模型助手:OpenAI 兼容接口(智谱 GLM / OpenAI / DeepSeek / 本地 Ollama 等),
自然语言描述需求 → 生成 YAML 配置 → 预览确认后合并保存。 - 配置持久化:所有端口、规则、变量、命令、LLM 设置存于
config/config.yaml。 - 快捷命令栏:每个端口标签页底部显示指向该端口的常用命令按钮。
🚀 快速开始
1. 安装依赖
⚠️ 本机
python指向 Windows Store 桩,请使用pylauncher。
py -m pip install -r requirements.txt
依赖:PySide6、pyserial、PyYAML、openai
2. 启动
py main.py
首次启动会加载 config/default_config.yaml(含示例:两个端口、若干高亮/触发规则)。
界面修改后会自动写入 config/config.yaml。
3. 配置大模型
首次使用 LLM 助手前,确认 ⚙ 配置 → 大模型配置 的连接参数。
📖 使用说明
设备管理(页签)
每个设备对应主窗口中的一个页签,工具栏左侧的 ➕ 新增设备 可添加。页签支持完整的增删改与排序,所有改动自动写入 config/config.yaml。
新增设备
点工具栏 ➕ 新增设备,会生成一个不重名的设备(新设备、新设备2 …),默认参数为:第一个可用 COM 口、115200 / 8 / N / 1。新建后该页签自动被选中,可直接:
- 在页签顶部的下拉框里改 端口 / 波特率,点 连接;
- 点波特率右侧的箭头展开 数据位 / 校验 / 停止位(默认折叠),修改后 tooltip 会显示当前帧格式预览(如
8N1)。
下拉框中修改的连接参数会立即保存;若设备已连接,则保持当前连接,新参数在下次连接时生效。
复制设备
右键 设备页签 → 复制设备 → 输入新名字(默认「源名_副本」)。复制时会一并带走:
- 连接参数(COM 口、波特率、数据位、校验、停止位);
- 该设备在高亮 / 触发规则上的每设备启用状态;
- 快捷命令:原本指向源设备的命令,会同时指向新设备。
重命名
双击 设备页签 → 输入新名字。校验:不能为空、不能与其它设备重名、不能含特殊字符
(:、#、[、]、{、}、&、*、!、|、>、'、"、%、@、`)。
重命名会全局更新所有引用:触发规则的 source_device、动作的 target_device、快捷命令的 target_device、显示配置、规则启用状态,以及已连接的串口 worker —— 因此重命名不会丢消息或错乱按钮状态。
删除设备
点页签右侧的 X → 确认后会断开连接并从配置中移除。
拖动页签改变顺序
设备页签可拖动:按住页签左右拖动,松手即改变位置(VSCode 风格)——拖动时原页签变半透明,鼠标位置出现半透明的浮动页签副本,插入位置由蓝色竖线指示。顺序在松手时才同步到配置里的 devices 列表(拖动过程中不写盘),下次启动保持一致。
页签上的 X 关闭按钮 与 圆点指示 在拖动时也会跟随移动(已自绘,不会错位)。
页签选中色与连接指示
当前选中的设备页签以主题主色(蓝色)整块填色并显示白字,其余页签为中性灰底。
页签左侧的圆点表示连接状态:
- 当前选中页签:已连接 = 白色实心圆;未连接 = 白色空心圆(仅描边)。
- 非选中页签:已连接 = 绿色实心圆;未连接 = 灰色实心圆。
连接串口
每个设备标签页底部选择端口、波特率等参数,点 连接。日志区会实时显示接收数据(带高亮),
底部输入框可发送命令(Enter 发送,Shift+Enter 换行)。
快捷命令
每个设备页签中部有一排快捷命令按钮,点击即发送预设命令。按钮只显示指向本设备的命令(或设为「所有设备」的命令)。命令模板支持变量和字符串管道(见后文「命令模板可用变量」)。
新增 / 管理
点页面左侧的 ➕ 打开「快捷命令管理」对话框:
- 上半部分列出系统中所有快捷命令,勾选即加入本设备,取消勾选即从本设备移除。
「目标设备」列显示该命令当前归属哪些设备(「所有设备」表示对全部设备可见)。 - 取消勾选一个「所有设备」命令时,会自动转为「显式列出其它所有设备」(不影响别的设备)。
- 下半部分可直接新增:填写名称、发送字符串、可选的周期间隔 / 持续时长、按钮颜色,点「添加到列表」。

「快捷命令管理」对话框:勾选控制命令在本设备的可见性,下方可直接新增。
编辑 / 删除
右键 任一按钮 → 编辑… 或 删除。编辑对话框可修改名称、发送字符串、周期参数、颜色。
拖动改顺序
按住按钮拖动到目标位置释放即可调整顺序(VSCode 风格):拖动时原按钮半透明,鼠标跟随一个半透明的放大预览图(带阴影),插入位置由蓝色竖线指示。顺序在松手时写回配置,所有设备共享同一份命令列表。
周期发送
在周期间隔里填数字(秒),该命令按钮会带 ⏰ 前缀,表示是周期命令:
- 点击 启动周期发送(立即发一次,之后按间隔循环),按钮变蓝高亮;
- 再次点击 停止。
- 「持续时长」留空或 0 = 无限循环;填数字 = 持续若干秒后自动停止。
按钮颜色
新增 / 编辑时可给按钮选一种背景色。提供 10 种柔和预设色,文字颜色会根据背景亮度自动取蓝色或同色相深色(保证可读):
| 0 浅红 | 1 浅橙 | 2 浅黄 | 3 浅黄绿 | 4 浅绿 |
|---|---|---|---|---|
| 5 浅青绿 | 6 浅青 | 7 浅蓝 | 8 浅紫 | 9 浅粉 |
配置写法
快捷命令存在 config.yaml 的 quick_commands 列表里,可手编;也可在 ⚙ 配置 → 快捷命令 里表格化管理(名称、目标设备、命令、周期、颜色):

quick_commands:
- name: "复位"
command: "RESET\n"
target_device: "调试口A" # 单个设备;留空=所有设备;也可写成列表
- name: "读温度"
command: "GET TEMP"
target_device: ["调试口A", "设备口B"]
color: 4 # 0~9,见上表;省略=默认无背景色
interval: 2.0 # 周期间隔(秒);省略=单次发送
duration: 30 # 持续时长(秒);省略或 0=无限
高亮规则
在 ⚙ 配置 → 高亮规则 增删改。每条规则:
- name: "错误"
pattern: "(?i)error|fail|exception" # Python 正则
foreground: "#FFFFFF"
background: "#C62828"
bold: true

⚙ 配置 → 高亮规则:逐条编辑正则、前景/背景色、粗体。
工具栏 ☰ 规则概览(Ctrl+R)可按当前设备勾选启用/停用每条规则,无需打开配置对话框:

触发规则(跨端口联动)
在 ⚙ 配置 → 触发规则 配置。这是工具的核心:
- name: "温度超限 -> B口降速"
enabled: true
source_port: "调试口A" # 在此端口接收的行做匹配
pattern: "temp=([0-9.]+)" # 正则,可带捕获组
condition: "m1 > target_temp" # 可选;m0=整行,m1..=捕获组,可直接用变量名
actions:
- type: send # 跨端口发送
target_port: "设备口B" # 可与 source_port 不同
command: "SET_FAN ${match.1} ON" # ${match.N} 引用捕获组
- type: log # 记录提示
message: "⚠ 温度 ${match.1} 超过阈值 ${target_temp}"

⚙ 配置 → 触发规则:源设备 + 正则 + 条件 + 动作列表,双击动作单元格可编辑。
命令模板可用变量
| 写法 | 含义 |
|---|---|
${match.0} | 整个匹配行 |
${match.1} … ${match.9} | 正则捕获组 |
${timestamp} | 完整时间戳 2026-08-08 14:30:05 |
${date} / ${time} | 日期 / 时间 |
${port} | 来源端口名 |
${变量名} | 用户自定义变量(配置 → 变量) |
变量在 ⚙ 配置 → 变量 里维护(键值对),命令模板与条件表达式均可引用:

字符串处理管道(可链式)
${match.1|upper} 转大写
${match.1|lower} 转小写
${match.1|trim} 去首尾空白
${match.1|hex} 十进制转十六进制
${match.1|unhex} 十六进制转十进制
${match.1|replace(-,_)} 替换
${match.1|substr(0,4)} 取子串
${match.1|pad(8,0)} 左填充到 8 位用 '0'
组合示例:${match.1|trim|upper}
条件表达式
condition 为可选布尔表达式,使用安全求值(白名单 AST,禁危险函数)。
匹配组可用 m0/m1/..,变量直接用名字:
condition: "m1 > target_temp" # 捕获组1 大于 变量
condition: "int(m1) >= 50" # 显式取整比较
condition: "m1 in ('OK', 'READY')" # 成员判断
condition: "m1 > 50 and port == 'A'" # 组合
表达式中数值会自动尝试转换,便于直接比较。
动作类型
actions 支持四种动作,可写多条依次执行:
| type | 作用 | 关键字段 |
|---|---|---|
send | 向设备发送命令(可跨设备) | target_device、command |
log | 在来源设备日志区显示一条提示(warn 风格) | message |
set_port_param | 运行时修改端口参数(已连接即时生效,并写入配置) | baudrate/bytesize/parity/stopbits/port |
message | 生成一条消息,显示到「消息」面板并持久化 | content(或 message) |
message 动作示例(配合下文「消息面板」使用):
- name: "温度告警记录"
enabled: true
source_device: "调试口A"
pattern: "temp=([0-9.]+)"
condition: "m1 > target_temp"
actions:
- type: message
content: "⚠ 温度 ${match.1} 超过阈值 ${target_temp}" # 显示在消息面板
- type: send
target_device: "设备口B"
command: "SET_FAN ${match.1} ON"
消息面板
点工具栏 💬 消息(或 Ctrl+M)打开右侧的消息面板。它以表格形式收集并展示由触发规则生成的消息(即 type: message 动作的输出),适合用来集中查看各设备的告警、状态摘要等。
界面构成
- 工具条第一行:设备过滤下拉框(默认「全部设备」)、自动滚动开关、当前消息计数。
- 工具条第二行:删除该设备 / 删除选中 / 清空全部。
- 表格:三列 —— 时间、设备、消息。整行选中,不可直接编辑单元格。
设备分色
不同设备的消息行使用不同的浅色背景(淡蓝、淡靛蓝、淡青、淡绿、淡橙、淡紫、淡粉、淡深紫 …),按设备创建顺序循环,便于在一堆消息里快速识别来源。
设备过滤
下拉框选某个具体设备,则只显示该设备的消息。此时「删除该设备」按钮可用;选「全部设备」时该按钮禁用。
删除
- 删除该设备:删除当前过滤设备的全部消息(需先在过滤里选定设备)。
- 删除选中:删掉表格中选中(可多选)的行。
- 清空全部:删掉所有消息。
以上操作均有二次确认。
自动滚动
「自动滚动」勾选时,新消息到来会自动滚动到底部;取消勾选则保持当前位置,方便查阅历史。最多保留 2000 条,超出后自动丢弃最早的。
持久化
消息会自动保存到 config/messages.json(防抖写入:1 秒内多次改动只写一次)。程序重启后自动加载历史消息,所以关掉再打开面板,之前的消息仍在;退出程序时也会立即保存。
消息面板默认隐藏,需要时用工具栏按钮或
Ctrl+M打开;面板显示时会自动收窄到默认宽度,避免把主窗口撑宽。
大模型助手
点击 ✨ LLM 助手(或 Ctrl+L),用自然语言描述需求,例如:
当调试口A 收到 temp= 开头且数值大于 50 时,向设备口B 发送 SET_FAN 加上该数值和 ON

粘土助手:左侧描述需求 → 流式生成 YAML → 确认后「应用(合并到配置)」。
模型会生成对应 YAML ,可手动编辑后点 应用 合并到配置并保存。
生成过程流式显示,出错会提示。
🗂️ 项目结构
serial_tool/
├── main.py # 入口
├── requirements.txt
├── config/
│ ├── default_config.yaml # 默认模板(只读)
│ └── config.yaml # 用户配置(运行时生成)
├── core/
│ ├── serial_worker.py # 单串口读写线程
│ ├── port_manager.py # 多端口生命周期
│ ├── highlight_engine.py # 高亮规则匹配
│ ├── command_engine.py # 命令渲染与触发
│ ├── config_store.py # YAML 读写校验
│ └── llm_service.py # OpenAI 兼容客户端
├── ui/
│ ├── main_window.py # 主窗口
│ ├── port_tab.py # 端口标签页
│ ├── log_view.py # 高亮日志显示
│ ├── config_dialog.py # 配置编辑
│ └── llm_panel.py # LLM 助手
├── utils/
│ ├── expression.py # 表达式/参数引擎
│ └── logger.py # 日志
└── README.md
🏗️ 架构要点
- 线程模型:每个串口一个
SerialWorker(QObject.moveToThread),读循环在子线程,
通过Signal(str)把整行回传主线程。绝不跨线程操作 GUI/串口对象。 - 主线程集中处理:高亮匹配、命令渲染、触发调度都在主线程完成,避免锁。
- 跨端口联动:主窗口收到某端口的行 → 喂给
CommandEngine→ 渲染动作 → 调目标端口的
worker 发送(worker 的send是 slot,Qt 自动排队跨线程)。 - 性能:日志显示用
QTimer50ms 批量 flush,QPlainTextEdit.setMaximumBlockCount(5000)
防内存膨胀。 - 安全:LLM 生成的配置 预览确认后才写入,配置保存前经
validate校验。
🔧 打包成 exe(可选)
py -m pip install pyinstaller
py -m PyInstaller --noconsole --name Nento main.py
# 产物在 dist/Nento/
📝 备注
- COM 口冲突:同一物理口不能被两个程序同时打开。
- LLM 调用走外网,请确保网络可达;用 Ollama 则全程本地。
- 日志文件在
serial_tool/logs/serial_tool.log(滚动 2MB×3)。
📥 下载
更多推荐




所有评论(0)