refactor: 按角色分 web/ diag/ launch/ 三层, 根目录只留主程序
18 个文件平铺根目录太乱, 按角色归拢: web/ ecat.html/css + motor.html/js —— 前端资源 diag/ ecat_scan / ecat_sniff / ecat_esc_regs —— 独立诊断脚本, 互不依赖 launch/ 5 个 .bat/.vbs 双击入口 根目录只留 ecat_server / ecat_tool / ecat_flash_eeprom / test_motor_backend: 这几个互相 import(tool→flash_eeprom, test→server), 挪进子目录就得改 import 或加包, 收益不抵成本。 配套改动: _STATIC_MAP 的值加 web/ 前缀 —— URL 路径刻意保持不变(/、/ecat.css、 /motor.html), 页面内相对引用、书签、外部链接一律不用改。 launch/ 里 %~dp0 现在指向 launch\, 五个启动器统一改为先取上一层作 ROOT (bat 用 %~dp0.., vbs 用两次 GetParentFolderName), run_scan 顺带指向 diag\ecat_scan.py。 验证: 7 个 py 全编译通过; test_motor_backend 8 项全通过; 服务实起后 6 条 静态路由全 200 且 MIME 正确(js 是 application/javascript)、404 兜底正常; Edge headless 渲染主页与 motor 页, CSS 294 规则加载、9 个节点样式生效、 零加载失败零 JS 异常; bat/vbs 的 ROOT 解析实测指到项目根, 五个目标文件 全部命中; ecat_tool adapters 与 diag/ecat_scan.py 实跑正常。
This commit is contained in:
@@ -16,29 +16,47 @@ py -3.12 -m venv venv
|
||||
venv\Scripts\python.exe -m pip install -r requirements.txt
|
||||
```
|
||||
|
||||
## 目录内容
|
||||
## 目录结构
|
||||
|
||||
```
|
||||
ecat/
|
||||
├─ ecat_server.py 网页控制台后端(REST API + 静态文件), 默认端口 8090
|
||||
├─ ecat_tool.py 一体化命令行主站
|
||||
├─ ecat_flash_eeprom.py 经网线烧写 SII 镜像(被 ecat_tool flash 复用)
|
||||
├─ test_motor_backend.py 电机后端自测(不接硬件)
|
||||
├─ web/ 前端资源(URL 路径不变, 仍是 / 与 /motor.html)
|
||||
├─ diag/ 独立诊断脚本(互不依赖, 直接单跑)
|
||||
├─ launch/ 双击入口(.bat/.vbs)
|
||||
└─ venv/ 本地虚拟环境(不入库)
|
||||
```
|
||||
|
||||
根目录只放主程序:`ecat_tool.py` import `ecat_flash_eeprom`、
|
||||
`test_motor_backend.py` import `ecat_server`,这几个互相 import 的必须同层,
|
||||
挪进子目录就得改 import 或加包,不值得。
|
||||
|
||||
| 文件 | 说明 |
|
||||
|------|------|
|
||||
| `ecat_tool.py` | 一体化命令行主站:`adapters` / `status` / `flash` / `eeprom` / `sdo` / `send` 等子命令 |
|
||||
| `ecat_server.py` | 网页控制台后端(REST API + 静态文件),默认端口 **8090**(8080 已被 ESP32 tools 占用) |
|
||||
| `ecat.html` / `ecat.css` | 网页控制台前端 |
|
||||
| `ecat_scan.py` | 最小化 bring-up 扫描:从站身份 + SII dump,`--op` 追加 PDO 测试 |
|
||||
| `ecat_esc_regs.py` | 从**网络侧**直读 LAN9252 ESC 寄存器,绕开 GD32/PDI,用于判断 EEPROM 加载是否真的失败;支持 `--reload` |
|
||||
| `ecat_flash_eeprom.py` | 通过网线烧写 `gen_eeprom.py` 生成的 SII 镜像,逐字回读校验(烧完需断电重启让 ESC 重新加载) |
|
||||
| `ecat_sniff.py` | 旁路抓包,hexdump SOEM 自己发出的帧,用于对照裸帧格式 |
|
||||
| `motor.html` / `motor.js` | 电机控制台:N1–N9 九节点,走 EtherCAT 过程数据(不经 WiFi/HTTP)。节点总览、8 种 Control_Mode、STATUS 实时解码、示波器曲线 |
|
||||
| `test_motor_backend.py` | 电机后端自测,**不接硬件**(假从站模拟 GD32 buildInput/processOutput)。跑法:`venv\Scripts\python.exe test_motor_backend.py` |
|
||||
| `web/ecat.html` + `web/ecat.css` | 网页控制台前端 |
|
||||
| `web/motor.html` + `web/motor.js` | 电机控制台:N1–N9 九节点,走 EtherCAT 过程数据(不经 WiFi/HTTP)。节点总览、8 种 Control_Mode、STATUS 实时解码、示波器曲线 |
|
||||
| `diag/ecat_scan.py` | 最小化 bring-up 扫描:从站身份 + SII dump,`--op` 追加 PDO 测试 |
|
||||
| `diag/ecat_esc_regs.py` | 从**网络侧**直读 LAN9252 ESC 寄存器,绕开 GD32/PDI,用于判断 EEPROM 加载是否真的失败;支持 `--reload` |
|
||||
| `diag/ecat_sniff.py` | 旁路抓包,hexdump SOEM 自己发出的帧,用于对照裸帧格式 |
|
||||
|
||||
## 启动方式
|
||||
|
||||
双击 `launch/` 里的入口即可(脚本自己会定位到项目根,不必在特定目录下运行):
|
||||
|
||||
| 入口 | 效果 |
|
||||
|------|------|
|
||||
| `ecat_app.vbs` | pywebview 桌面窗口,无控制台无浏览器标签(已针对部分 GPU 驱动白屏加 `--disable-gpu-compositing`) |
|
||||
| `ecat_web.vbs` | 后台起服务并打开浏览器标签,无控制台窗口 |
|
||||
| `ecat_web.bat` | 控制台模式,可见日志,调试用 |
|
||||
| `ecat.bat` | 命令行工具入口,如 `ecat.bat status`、`ecat.bat flash` |
|
||||
| `run_scan.bat` | 直接跑 bring-up 扫描,无参数则列出 Npcap 适配器 |
|
||||
| `launch/ecat_app.vbs` | pywebview 桌面窗口,无控制台无浏览器标签(已针对部分 GPU 驱动白屏加 `--disable-gpu-compositing`) |
|
||||
| `launch/ecat_web.vbs` | 后台起服务并打开浏览器标签,无控制台窗口 |
|
||||
| `launch/ecat_web.bat` | 控制台模式,可见日志,调试用 |
|
||||
| `launch/ecat.bat` | 命令行工具入口,如 `ecat.bat status`、`ecat.bat flash` |
|
||||
| `launch/run_scan.bat` | 直接跑 bring-up 扫描,无参数则列出 Npcap 适配器 |
|
||||
|
||||
电机控制台在服务起来后从主页右上「电机控制台」进入,或直接访问 `/motor.html`。
|
||||
它只读写 EtherCAT 过程数据,需先在主页点「连接」并让从站进入 OP。
|
||||
@@ -52,5 +70,5 @@ venv\Scripts\python.exe -m pip install -r requirements.txt
|
||||
断电才清零。固件 <1.5.52 无自愈需断电重启,1.5.52+ 有守护自动写回。
|
||||
`config_map` 失败时后端会自动转储 4 个 SM 现场,可直接对照。
|
||||
- 前端 CSS/JS 改动后记得 bump `?v=` 缓存版本,否则浏览器会加载旧代码。
|
||||
`ecat.css` 被 `ecat.html` 与 `motor.html` 共用,两处版本号要一起改。
|
||||
`web/ecat.css` 被 `web/ecat.html` 与 `web/motor.html` 共用,两处版本号要一起改。
|
||||
- EEPROM 烧写后必须断电冷启动,ESC 才会重新加载配置。
|
||||
|
||||
+8
-6
@@ -1552,15 +1552,17 @@ class Handler(BaseHTTPRequestHandler):
|
||||
# - .js 用 text/html 会被浏览器的严格 MIME 检查拒掉(module script 与 Worker
|
||||
# 都会直接报错不执行),这是加新页面最容易踩的坑;
|
||||
# - 只有 HTML 才注入 _RELOAD_SNIPPET(注入到 js/css 里会破坏文件)。
|
||||
# URL 路径保持不变(/、/ecat.css、/motor.html…),只是磁盘上挪进了 web/,
|
||||
# 所以页面内的相对引用、书签、外部链接都不用改。
|
||||
_STATIC_MAP = {
|
||||
"/": "ecat.html",
|
||||
"/ecat.html": "ecat.html",
|
||||
"/index.html": "ecat.html",
|
||||
"/ecat.css": "ecat.css",
|
||||
"/": "web/ecat.html",
|
||||
"/ecat.html": "web/ecat.html",
|
||||
"/index.html": "web/ecat.html",
|
||||
"/ecat.css": "web/ecat.css",
|
||||
# 电机控制台(EtherCAT 版)。样式直接复用 ecat.css —— 它本身就是 ESP32
|
||||
# motor.css 的副本(md5 一致),再拷一份 motor.css 只会多出一处会漂移的副本。
|
||||
"/motor.html": "motor.html",
|
||||
"/motor.js": "motor.js",
|
||||
"/motor.html": "web/motor.html",
|
||||
"/motor.js": "web/motor.js",
|
||||
}
|
||||
_CTYPE_BY_EXT = {
|
||||
".html": "text/html; charset=utf-8",
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
@echo off
|
||||
rem DCU EtherCAT master web console (serves ecat.html + pysoem API)
|
||||
chcp 65001 >nul
|
||||
set PYTHONUTF8=1
|
||||
cd /d "%~dp0"
|
||||
"%~dp0venv\Scripts\python.exe" ecat_server.py
|
||||
pause
|
||||
@@ -1,8 +1,10 @@
|
||||
@echo off
|
||||
rem EtherCAT master tool for DCU LAN9252 (scan/flash/send/monitor)
|
||||
rem Examples: ecat.bat status | ecat.bat flash | ecat.bat send --u64 0x1,0x2,0x3,0x4 --duration 5
|
||||
rem 本文件在 launch\ 下, %~dp0 指向 launch\, 故 ROOT 取其上一层。
|
||||
chcp 65001 >nul
|
||||
set PYTHONUTF8=1
|
||||
cd /d "%~dp0"
|
||||
"%~dp0venv\Scripts\python.exe" ecat_tool.py %*
|
||||
set "ROOT=%~dp0.."
|
||||
cd /d "%ROOT%"
|
||||
"%ROOT%\venv\Scripts\python.exe" ecat_tool.py %*
|
||||
pause
|
||||
@@ -1,8 +1,10 @@
|
||||
' DCU EtherCAT desktop window (pywebview/WebView2). No console, no browser tab.
|
||||
' Browser-tab launcher: ecat_web.vbs Console-mode debug launcher: ecat_web.bat
|
||||
' 本文件在 launch\ 下: 先取自身所在目录, 再上一层拿到项目根。
|
||||
Set sh = CreateObject("WScript.Shell")
|
||||
Set fso = CreateObject("Scripting.FileSystemObject")
|
||||
base = fso.GetParentFolderName(WScript.ScriptFullName)
|
||||
here = fso.GetParentFolderName(WScript.ScriptFullName)
|
||||
base = fso.GetParentFolderName(here)
|
||||
sh.CurrentDirectory = base
|
||||
sh.Environment("PROCESS")("PYTHONUTF8") = "1"
|
||||
' WebView2: keep GPU rasterization but disable GPU compositing.
|
||||
@@ -0,0 +1,9 @@
|
||||
@echo off
|
||||
rem DCU EtherCAT master web console (serves web\ecat.html + pysoem API)
|
||||
rem 本文件在 launch\ 下, %~dp0 指向 launch\, 故 ROOT 取其上一层。
|
||||
chcp 65001 >nul
|
||||
set PYTHONUTF8=1
|
||||
set "ROOT=%~dp0.."
|
||||
cd /d "%ROOT%"
|
||||
"%ROOT%\venv\Scripts\python.exe" ecat_server.py
|
||||
pause
|
||||
@@ -1,8 +1,10 @@
|
||||
' DCU EtherCAT web console - hidden launcher (no console window).
|
||||
' Double-click me. Console-mode debug launcher (visible logs): ecat_web.bat
|
||||
' 本文件在 launch\ 下: 先取自身所在目录, 再上一层拿到项目根。
|
||||
Set sh = CreateObject("WScript.Shell")
|
||||
Set fso = CreateObject("Scripting.FileSystemObject")
|
||||
base = fso.GetParentFolderName(WScript.ScriptFullName)
|
||||
here = fso.GetParentFolderName(WScript.ScriptFullName)
|
||||
base = fso.GetParentFolderName(here)
|
||||
sh.CurrentDirectory = base
|
||||
sh.Environment("PROCESS")("PYTHONUTF8") = "1"
|
||||
sh.Run """" & base & "\venv\Scripts\python.exe"" """ & base & "\ecat_server.py""", 0, False
|
||||
@@ -2,8 +2,11 @@
|
||||
rem EtherCAT master bring-up scan (LAN9252)
|
||||
rem Usage: run_scan.bat -> list Npcap adapters
|
||||
rem run_scan.bat I226 -> scan EtherCAT slaves (add --op for PDO test)
|
||||
rem 本文件在 launch\ 下, %~dp0 指向 launch\, 故 ROOT 取其上一层;
|
||||
rem 扫描脚本已挪进 diag\。
|
||||
chcp 65001 >nul
|
||||
set PYTHONUTF8=1
|
||||
cd /d "%~dp0"
|
||||
"%~dp0venv\Scripts\python.exe" ecat_scan.py %*
|
||||
set "ROOT=%~dp0.."
|
||||
cd /d "%ROOT%"
|
||||
"%ROOT%\venv\Scripts\python.exe" diag\ecat_scan.py %*
|
||||
pause
|
||||
Reference in New Issue
Block a user