Skip to content

TenoDX Hub ​

H503 控制器的本地伴侣程序:查看控制器信息 + 一键从资源服务器拉取并刷入固件。

  • 轻量:后端只用 Python 标准库 http.server,唯一第三方依赖是 pyserial(与现有 DFU 刷写工具一致)。无 Electron、无 Node、无 Web 框架。
  • 现代 UI:单页深色界面,左侧列表,无构建步骤。
  • 服务端纯 API:固件资源服务器没有浏览器界面,Hub 通过 REST 拉取版本、时间与更新说明。

快速开始 ​

powershell
# 1) 开隧道(资源服务器只监听服务器本机)
powershell -NoProfile -ExecutionPolicy Bypass -File ..\..\server-info\scripts\tunnel.ps1 -Service fw

# 2) 启动 Hub(会自动申请管理员权限)
powershell -ExecutionPolicy Bypass -File .\run.ps1 -Registry http://127.0.0.1:18000

浏览器自动打开 http://127.0.0.1:8787/。

为什么要管理员权限:刷写需要访问 USB DFU 设备并调用 STM32_Programmer_CLI.exe,非管理员会失败。hub.py 会自己弹 UAC。 调试时可加 --no-elevate 跳过(此时只能看控制器信息,不能刷写)。

参数 ​

powershell
.\run.ps1                                  # 默认 registry http://127.0.0.1:8000
.\run.ps1 -Registry http://127.0.0.1:18000 # 指向隧道
.\run.ps1 -Channel beta                    # 看 beta 通道
.\run.ps1 -Port 9000                       # 换本地端口
.\run.ps1 -NoElevate -NoBrowser            # 调试用

也可以直接跑:

powershell
python hub.py --registry http://127.0.0.1:18000 --channel stable

打包为 exe ​

powershell
cd tools\TenoDXHub
powershell -ExecutionPolicy Bypass -File .\build.ps1

产物:dist\TenoDXHub.exe(单文件,约 9.3 MB,UI 已内嵌,无需额外文件)。

build.ps1 会依次:检查 hub.py + static\index.html → 缺 pyserial/PyInstaller 则自动安装 (固定用 py -3.14,与 tools/h503_dfu_flasher 一致)→ PyInstaller --onefile 打包 → 启动产物做冒烟测试(探 /api/app,失败会明确提示)。

单文件 exe 的路径处理(关键) ​

PyInstaller onefile 会把内容解压到一个只读、退出即删的 _MEIPASS 临时目录。因此:

内容位置原因
static/index.html(UI)打进 exe,运行时读 _MEIPASS只读即可
.cache/(下载的固件)exe 同级目录需要可写、需要跨次运行保留
hub.config.jsonexe 同级目录同上

⚠️ 所以不要把 exe 放进只读目录(如 Program Files 根下)。 放在任意用户可写目录(桌面、D:\Tools\)即可。

为什么保留控制台窗口 ​

没有加 --noconsole:控制台会打印服务地址,也是 Ctrl+C 停止服务的唯一方式。 关掉黑框即等于停掉 Hub。

为什么没有加 --uac-admin ​

hub.py 自己是运行时提权的(ShellExecuteW runas),所以 exe 仍然支持 --no-elevate 用于不提权调试(只看控制器信息、不刷写)。 加 --uac-admin 会让程序无法在非管理员下运行,灵活性反而变差。

已验证(2026-11-08) ​

检查结果
产物TenoDXHub.exe 9.28 MB
启动 + /api/app✅ 200,TenoDX Hub v1.0.0
UI 从 exe 内提供✅ / 200,14361 B,左侧两项都在
pyserial 打进 exe✅ 枚举到 6 个串口
真实 H503 控制器✅ COM25 识别成功,USB 序列 3514343932345103,Magic 能力 0x01 0x02
/api/versions 无服务器时✅ 优雅降级(ok:false)

界面 ​

┌──────────────┬─────────────────────────────────────────────┐
│  TenoDX Hub  │  控制器信息                                  │
│              │  ┌───────────────────────────────────────┐  │
│ ▸ 控制器信息  │  │ 连接状态  ● 已连接                     │  │
│   固件更新    │  │ 调试串口   COM7                        │  │
│              │  │ 设备描述   TenoDX Debug Port           │  │
│              │  │ USB 序列号 ...                          │  │
│              │  │ Magic 能力 0x01 0x02                   │  │
│              │  └───────────────────────────────────────┘  │
│ 资源服务器    │  ┌───────────────────────────────────────┐  │
│ 目标 h503     │  │ 固件更新  v1.2.3  [stable] 下载并刷入  │  │
│              │  │ 发布时间 / 大小 / SHA256               │  │
│              │  │ 更新说明 ...                            │  │
│              │  │ 刷写日志 ...                            │  │
│              │  └───────────────────────────────────────┘  │
└──────────────┴─────────────────────────────────────────────┘

左侧列表目前两项(按需求):控制器信息 与 固件更新。 侧边栏的徽标实时反映控制器连接状态和服务器上的最新版本号。


控制器识别方式 ​

不靠 COM 号猜(Windows 换 USB 拓扑会重新分配)。 对每个串口发 Magic light info(module=0x20, cmd=0x05), 只有合法 Magic 响应且能力字段包含 0x01 0x02 的才算 TenoDX Debug 口。

这与 tools/h503_dfu_flasher 的判定完全一致。


刷写流程(与现有工具一致) ​

  1. 找到 TenoDX Debug 口
  2. 发 Magic module=0x00, cmd=0x84, payload=0xA5 进入 DFU
  3. 等 0483:DF11 DFU 设备枚举(超时 25s)
  4. STM32_Programmer_CLI.exe -c port=USB1 -w <固件> [0x08000000] -v -rst
  5. 只要出现 Download verified successfully 即判定成功 (H503 的 ROM DFU 有时不支持 -rst,会额外报错,属已知现象)
  6. 提示用户拔插设备以运行新固件

固件下载后会在 .cache/ 里按 SHA256 校验,校验不过直接拒绝刷写。

依赖 ​

  • Windows 10/11
  • Python 3.10+
  • pyserial(run.ps1 会自动装)
  • STM32CubeProgrammer 或 STM32CubeCLT(提供 STM32_Programmer_CLI.exe) 自动搜索 PATH 与以下位置:
    • D:\Programs\STM32CubeCLT_1.19.0\STM32CubeProgrammer\bin
    • C:\Program Files\STMicroelectronics\STM32Cube\STM32CubeProgrammer\bin
    • C:\Program Files (x86)\...

找不到 CLI 时会明确报错并指向 tools/h503_dfu_flasher 的 dfu-util 兜底路径 (那个工具内置了 dfu-util,Hub 没有重复打包)。


本地 HTTP 接口 ​

Hub 只监听 127.0.0.1,不对外。

方法路径说明
GET/UI
GET/api/app版本、当前 registry、是否管理员
GET/api/controller扫描串口 + Magic 探测
GET/api/versions代理资源服务器列表(失败也返回 200 + ok:false)
GET/api/flash/status刷写任务状态与日志
POST/api/settings改 registry / channel(内存态)
POST/api/update{"id": <firmware id>} → 下载 + 刷写

排障 ​

现象原因 / 处理
「未检测」但设备已插驱动没装或不是 Debug 口。换根线/换 USB 口,或用 tools/set_com_ports 检查
「服务器不可达」资源服务器只绑服务器 loopback,必须先开隧道 -Service fw
刷写卡在「等待设备枚举」固件里没有 Magic 0x84 的进 DFU 命令;或 DFU 驱动(WinUSB)没装
提示找不到 STM32_Programmer_CLI.exe装 STM32CubeProgrammer,或用 tools/h503_dfu_flasher 兜底
UAC 被拒绝只能看控制器信息。右键「以管理员身份运行」PowerShell 再启动
端口一直超时Windows 可能还指向旧句柄 —— 拔插设备后点「刷新」

后续可扩展(未做,避免过度设计) ​

  • 侧边栏加「诊断」「配置」项(可复用 tools/TenoDXConfigurationTool)
  • 刷写历史记录与回滚到上一版本
  • 多控制器并行管理
  • 自动检查更新(当前是点刷新才查)

按需求"列表目前只有主界面和控制器的更新按钮",只做了这两项。

TenoDX · 内部文档