docs(frontend): 添加前端架构约定与回归清单文档

添加了完整的前端架构约定文档 (frontend_architecture.md),
包含以下主要内容:

- 架构总览:Web资源本地托管方式和零构建方案
- 页面薄入口范式:HTML结构与ES Modules入口约定
- JS分层架构:common/ota/ble/can/motor等目录结构说明
- 缓存戳约定:版本管理强制要求
- 公共层API契约:baseUrl/toast/polling等接口规范
- motor页特殊性:独立主题和轮询链路处理
- 红线区域:不可动代码范围说明
- 回归清单:各页面功能验证checklist

同时移除了build相关的临时文件
This commit is contained in:
小龙虾
2026-07-27 01:50:48 +08:00
parent 2138a572ee
commit 33b41fd50a
19 changed files with 3555 additions and 3927 deletions
+96
View File
@@ -0,0 +1,96 @@
# 前端架构约定与回归清单(tools/ Web 界面)
> 2026-07 网页框架化重构产物。本文档固化 tools/ 目录的模块化约定,
> 所有新增页面/模块必须遵循;同时提供改动后的回归验证清单。
## 1. 架构总览
- **托管方式**:Web 资源不嵌入固件,由 `tools/serve.bat`(`python -m http.server 8080`)本地托管;
浏览器跨源调用 ESP32 REST API(路由表见 `main/server/wifi_ota.cpp` kHttpRoutes)。
改动 web 文件无需重编译固件。
- **零构建**:原生 ES Modules,无打包器/无 CDN 依赖;页面必须经 http 访问(ES module 有 file:// CORS 限制)。
### 页面薄入口范式
每个页面 = HTML(纯结构,无内联 script/style/事件)+ 单个 `type="module"` 入口:
| 页面 | 入口 | 说明 |
|---|---|---|
| index.html | js/app.js + js/ota/console-mode.js + js/ble_ota.js | OTA 控制台(WiFi/BLE 双通道,三入口历史原因保留) |
| motor.html | js/motor/main.js | 电机控制台(独立 seed 主题,见 §4) |
| can.html | js/can.js | CAN 工具 |
| can_monitor.html | js/can_monitor.js | CAN 接收监控 |
### JS 分层
```
js/
├── common/ 跨页面公共层:base-url(IP存取) / toast / log / polling / connection / utils
├── ota/ OTA 状态机与上传流程(高风险区,见 §5)
├── ble/ BLE OTA 传输时序(高风险区,见 §5)
├── can/ CAN 子系统(dbc 为基础层,导出共享 state/el)
├── motor/ 电机控制台
└── *.js 页面入口(薄装配层)
```
## 2. 缓存戳约定(强制)
- **JS 间 import 一律不带 `?v=`**——同一模块带不同 query 会被浏览器实例化两次,
导致模块级单例(state/toast 去抖等)分裂。
- 版本戳只出现在 HTML 的 `<script>/<link>` 标签上;改动任何 JS/CSS 后,
**必须更新对应页面入口标签的 `?v=`**(格式 `?v=YYYYMMDD<字母>`),否则浏览器可能混载新旧模块。
## 3. 公共层 API 契约
- `common/base-url.js`:设备 IP 唯一存取点(localStorage `dcu_esp_ip`,OTA/CAN/电机页共用)。
页面特有回退(CAN 页 `el.toolIp`、OTA 页 `#espIp` 输入框)由各自入口在此基础上包装,
不得绕过它直接读写 localStorage。
- `common/toast.js`:单例 toast(`#toast/#toastIco/#toastMsg` + components.css 样式),
内置 5s 去重。适用于 index/can/can_monitor;motor 页因独立主题使用自有堆叠式 toast(§4)。
- `common/polling.js`:递归 setTimeout 轮询 + in-flight 守卫 + Page Visibility 补偿。
依赖 app.js 先挂载 window.OtaSessionState 等(见文件头注释的 window.* 清单),加载顺序不可变。
- index.html 按钮事件:统一 `data-action`/`data-arg` 属性 + app.js 末尾的事件委托,
**禁止新增内联 onclick**;window.* 函数挂载保留(polling/ota 模块间仍经 window 总线)。
## 4. motor 页特殊性
- 独立视觉主题(seed tokens,`css/motor.css`),**不引入** base.css/components.css
(两者与 motor.css 存在 `.btn/.toast/.toolbar` 等同名类,混用会破坏视觉)。
- 自有堆叠式 toast(`#toastContainer`,多条并存),与 common/toast.js 的单例 DOM 契约不同,
不做统一。
- 三条轮询链路(/motor/state、/can/feedback、/system/status)必须互不阻塞
(服务端约束,见 wifi_ota.cpp 注释)。
## 5. 红线(不可动区域)
- `js/ble/*`:Web Bluetooth 包发送时序、重试退避、FINISH 中止——大量真机实测调优。
- `js/ota/{session,stages,progress,upload-esp32,upload-gd32}.js`:OTA 状态机与
window.* 状态总线(activePhase/otaSessionState/currentOtaTarget 等)。
- index.html 视觉:shimmer / logoPulse 动画(css/responsive.css,仅 transform/opacity)不得削弱。
- 性能规范:高频更新走增量渲染 + write-before-compare + rAF 批量;CSS 动画仅 transform/opacity。
## 6. 回归清单
验证方式:`tools/serve.bat` 启动 → 浏览器打开 `http://localhost:8080/<页面>` → 真机 IP 连接。
### index.html(OTA 控制台)
- [ ] WiFi/BLE 模式切换、GD32/ESP32 目标切换(顶部按钮)
- [ ] 固件选择:点击/拖拽上传区、清除按钮、SHA-256 显示、FSAPI 热重载
- [ ] ESP32 上传 → 阶段流程条驱动 → 重启 → 版本核对
- [ ] GD32 OTA relay → 进度/阶段 → 完成 toast
- [ ] 日志面板:过滤、自动滚动、清空;JSON 状态面板;任务排序
- [ ] 断线/重连:连接胶囊状态、"测试"按钮、重启 ESP32 按钮
- [ ] 视觉:shimmer/logoPulse 动画正常,无掉帧
- [ ] BLE 模式:连接、一键刷写、中止、清除文件、拖拽选文件
### motor.html(电机控制台)
- [ ] 三条轮询链路存活(节点列表 1Hz 刷新、状态栏 RX/TX、健康检查)
- [ ] 控制指令发送、周期重发、模式切换、PID 配置
- [ ] 版本查询、NodeID 设置、电机 OTA relay
- [ ] 输入持久化(刷新后回填)、波形显示、console 无报错
- [ ] `window.phaseDebug` 调试句柄可用
### can.html / can_monitor.html
- [ ] DBC 导入/解析/合并、报文列表/信号编辑、发送(单发/批量/手动)
- [ ] 发送历史、会话持久化、接收监控(独立页 + 抽屉)
- [ ] toast 仅弹一次(无双实例重复弹)
@@ -1,180 +0,0 @@
esp-idf/main/CMakeFiles/__idf_main.dir/monitor/debug_log.cpp.obj: \
G:\Robot_v2\DCU\ESP32_COMM\main\monitor\debug_log.cpp \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/string.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/sys/cdefs.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/cdefs.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/config.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/machine/ieeefp.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/features.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/picolibc.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/15.2.0/include/float.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/machine/_default_types.h \
G:/Robot_v2/DCU/ESP32_COMM/build/config/sdkconfig.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/stdint.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/15.2.0/include/stddef.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/_intsup.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/_stdint.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/_locale.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/strings.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/_types.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/machine/_types.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/string.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/stdio.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/stdio.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/15.2.0/include/stdarg.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/sys/lock.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/lock.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/port/esp32xx/include/sys/socket.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/include/lwip/sockets.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/sockets.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/opt.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/port/include/lwipopts.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/stdlib.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/machine/stdlib.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/alloca.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/_wait.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/unistd.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/sys/unistd.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/types.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/machine/endian.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/machine/_endian.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/_pthreadtypes.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/sched.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/_timespec.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/machine/types.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/sys/select.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/select.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/_sigset.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/_timeval.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/_select.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/unistd.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/sys/fcntl.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/fcntl.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/_default_fcntl.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/time.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/time.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/sys/time.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/time.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/machine/_time.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/sys/ioctl.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/sys/poll.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_system/include/esp_task.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/FreeRTOS.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/config/include/freertos/FreeRTOSConfig.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/assert.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/assert.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/config/riscv/include/freertos/FreeRTOSConfig_arch.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/projdefs.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/portable.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/deprecated_definitions.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/portable/riscv/include/freertos/portmacro.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/15.2.0/include/stdbool.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_hw_support/include/spinlock.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_hw_support/include/esp_cpu.h \
F:/software/.espressif/v6.0/esp-idf/components/soc/esp32c3/include/soc/soc_caps.h \
F:/software/.espressif/v6.0/esp-idf/components/soc/include/soc/soc_caps_eval.h \
F:/software/.espressif/v6.0/esp-idf/components/riscv/include/riscv/csr.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/param.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/syslimits.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/machine/param.h \
F:/software/.espressif/v6.0/esp-idf/components/riscv/include/riscv/encoding.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_common/include/esp_assert.h \
F:/software/.espressif/v6.0/esp-idf/components/riscv/include/riscv/rv_utils.h \
F:/software/.espressif/v6.0/esp-idf/components/soc/esp32c3/include/soc/interrupt_reg.h \
F:/software/.espressif/v6.0/esp-idf/components/soc/esp32c3/register/soc/interrupt_core0_reg.h \
F:/software/.espressif/v6.0/esp-idf/components/soc/esp32c3/include/soc/soc.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_common/include/esp_bit_defs.h \
F:/software/.espressif/v6.0/esp-idf/components/soc/esp32c3/register/soc/reg_base.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_common/include/esp_attr.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_common/include/esp_assert.h \
F:/software/.espressif/v6.0/esp-idf/components/riscv/include/riscv/interrupt.h \
F:/software/.espressif/v6.0/esp-idf/components/riscv/include/esp_private/interrupt_intc.h \
F:/software/.espressif/v6.0/esp-idf/components/riscv/include/riscv/csr_pie.h \
F:/software/.espressif/v6.0/esp-idf/components/riscv/include/riscv/csr_dsp.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_hw_support/include/esp_intr_alloc.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_common/include/esp_err.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_common/include/esp_compiler.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_hw_support/include/esp_intr_types.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_common/include/esp_macros.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_rom/include/esp_rom_sys.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/inttypes.h \
F:/software/.espressif/v6.0/esp-idf/components/soc/esp32c3/include/soc/reset_reasons.h \
F:/software/.espressif/v6.0/esp-idf/components/heap/include/esp_heap_caps.h \
F:/software/.espressif/v6.0/esp-idf/components/heap/include/multi_heap.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_system/include/esp_system.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_common/include/esp_idf_version.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/esp_newlib.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/sys/reent.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/limits.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/15.2.0/include/limits.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/mpu_wrappers.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/esp_additions/include/freertos/idf_additions.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/task.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/list.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/queue.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/task.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/semphr.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/queue.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/stream_buffer.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/message_buffer.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/stream_buffer.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/event_groups.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/timers.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_hw_support/include/esp_random.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/port/include/sntp/sntp_get_set_time.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/port/include/sockets_ext.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/port/freertos/include/arch/sys_arch.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/debug.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/arch.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/port/esp32xx/include/arch/cc.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/errno.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/sys/errno.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/errno.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/ctype.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/ip_addr.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/def.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/ip4_addr.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/ip6_addr.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/def.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/ip6_zone.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/netif.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/err.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/pbuf.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/stats.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/mem.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/memp.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/priv/memp_std.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/priv/memp_priv.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/priv/mem_priv.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/inet.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/errno.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/net/if.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/if_api.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/port/include/netdb.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/include/lwip/netdb.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/netdb.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/port/include/arpa/inet.h \
F:/software/.espressif/v6.0/esp-idf/components/log/include/esp_log.h \
F:/software/.espressif/v6.0/esp-idf/components/log/include/esp_log_config.h \
F:/software/.espressif/v6.0/esp-idf/components/log/include/esp_log_level.h \
F:/software/.espressif/v6.0/esp-idf/components/log/include/esp_log_color.h \
F:/software/.espressif/v6.0/esp-idf/components/log/include/esp_log_buffer.h \
F:/software/.espressif/v6.0/esp-idf/components/log/include/esp_log_timestamp.h \
F:/software/.espressif/v6.0/esp-idf/components/log/include/esp_log_write.h \
F:/software/.espressif/v6.0/esp-idf/components/log/include/esp_log_format.h \
F:/software/.espressif/v6.0/esp-idf/components/log/include/esp_log_args.h \
F:/software/.espressif/v6.0/esp-idf/components/log/include/esp_log_attr.h \
F:/software/.espressif/v6.0/esp-idf/components/log/include/esp_private/log_attr.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_driver_uart/include/driver/uart.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_hal_uart/include/hal/uart_types.h \
F:/software/.espressif/v6.0/esp-idf/components/soc/esp32c3/include/soc/clk_tree_defs.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_common/include/esp_check.h \
G:\Robot_v2\DCU\ESP32_COMM\main\monitor\debug_log.h \
G:/Robot_v2/DCU/ESP32_COMM/main/include/app_config.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/riscv32-esp-elf/include/c++/15.2.0/cstdint \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/riscv32-esp-elf/include/c++/15.2.0/riscv32-esp-elf/rv32imc_zicsr_zifencei/ilp32/no-rtti/bits/c++config.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/riscv32-esp-elf/include/c++/15.2.0/riscv32-esp-elf/rv32imc_zicsr_zifencei/ilp32/no-rtti/bits/os_defines.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/riscv32-esp-elf/include/c++/15.2.0/riscv32-esp-elf/rv32imc_zicsr_zifencei/ilp32/no-rtti/bits/cpu_defines.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/riscv32-esp-elf/include/c++/15.2.0/pstl/pstl_config.h \
G:/Robot_v2/DCU/ESP32_COMM/main/include/version.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/port/include/netinet/in.h
@@ -1,180 +0,0 @@
esp-idf/main/CMakeFiles/__idf_main.dir/monitor/health_monitor.cpp.obj: \
G:\Robot_v2\DCU\ESP32_COMM\main\monitor\health_monitor.cpp \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/stdio.h \
G:/Robot_v2/DCU/ESP32_COMM/build/config/sdkconfig.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/15.2.0/include/stddef.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/features.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/picolibc.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/stdio.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/sys/cdefs.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/cdefs.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/config.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/machine/ieeefp.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/15.2.0/include/float.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/machine/_default_types.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/stdint.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/_intsup.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/_stdint.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/15.2.0/include/stdarg.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/sys/lock.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/lock.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/_types.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/machine/_types.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/string.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/_locale.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/strings.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/string.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/FreeRTOS.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/config/include/freertos/FreeRTOSConfig.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/assert.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/stdlib.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/machine/stdlib.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/alloca.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/_wait.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/assert.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/config/riscv/include/freertos/FreeRTOSConfig_arch.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/projdefs.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/portable.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/deprecated_definitions.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/portable/riscv/include/freertos/portmacro.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/15.2.0/include/stdbool.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_hw_support/include/spinlock.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_hw_support/include/esp_cpu.h \
F:/software/.espressif/v6.0/esp-idf/components/soc/esp32c3/include/soc/soc_caps.h \
F:/software/.espressif/v6.0/esp-idf/components/soc/include/soc/soc_caps_eval.h \
F:/software/.espressif/v6.0/esp-idf/components/riscv/include/riscv/csr.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/param.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/syslimits.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/machine/endian.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/machine/_endian.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/machine/param.h \
F:/software/.espressif/v6.0/esp-idf/components/riscv/include/riscv/encoding.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_common/include/esp_assert.h \
F:/software/.espressif/v6.0/esp-idf/components/riscv/include/riscv/rv_utils.h \
F:/software/.espressif/v6.0/esp-idf/components/soc/esp32c3/include/soc/interrupt_reg.h \
F:/software/.espressif/v6.0/esp-idf/components/soc/esp32c3/register/soc/interrupt_core0_reg.h \
F:/software/.espressif/v6.0/esp-idf/components/soc/esp32c3/include/soc/soc.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_common/include/esp_bit_defs.h \
F:/software/.espressif/v6.0/esp-idf/components/soc/esp32c3/register/soc/reg_base.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_common/include/esp_attr.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_common/include/esp_assert.h \
F:/software/.espressif/v6.0/esp-idf/components/riscv/include/riscv/interrupt.h \
F:/software/.espressif/v6.0/esp-idf/components/riscv/include/esp_private/interrupt_intc.h \
F:/software/.espressif/v6.0/esp-idf/components/riscv/include/riscv/csr_pie.h \
F:/software/.espressif/v6.0/esp-idf/components/riscv/include/riscv/csr_dsp.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_hw_support/include/esp_intr_alloc.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_common/include/esp_err.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_common/include/esp_compiler.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_hw_support/include/esp_intr_types.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_common/include/esp_macros.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_rom/include/esp_rom_sys.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/inttypes.h \
F:/software/.espressif/v6.0/esp-idf/components/soc/esp32c3/include/soc/reset_reasons.h \
F:/software/.espressif/v6.0/esp-idf/components/heap/include/esp_heap_caps.h \
F:/software/.espressif/v6.0/esp-idf/components/heap/include/multi_heap.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_system/include/esp_system.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_common/include/esp_idf_version.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/esp_newlib.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/sys/reent.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/limits.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/15.2.0/include/limits.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/mpu_wrappers.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/esp_additions/include/freertos/idf_additions.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/task.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/list.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/queue.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/task.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/semphr.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/queue.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/stream_buffer.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/message_buffer.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/stream_buffer.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/event_groups.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/timers.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_wifi/include/esp_wifi.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_wifi/include/esp_wifi_types.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_wifi/include/esp_wifi_types_generic.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_event/include/esp_event_base.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_wifi/include/local/esp_wifi_types_native.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_wifi/include/esp_wifi_types_generic.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_event/include/esp_event.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_wifi/include/esp_wifi_crypto_types.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_wifi/include/esp_wifi_default.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_netif/include/esp_netif.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_netif/include/esp_netif_ip_addr.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_netif/include/esp_netif_types.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_netif/include/esp_netif_defaults.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_timer/include/esp_timer.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_hw_support/etm/include/esp_etm.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_driver_tsens/include/driver/temperature_sensor.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_hal_ana_conv/include/hal/temperature_sensor_types.h \
F:/software/.espressif/v6.0/esp-idf/components/soc/esp32c3/include/soc/clk_tree_defs.h \
G:\Robot_v2\DCU\ESP32_COMM\main\monitor\health_monitor.h \
G:/Robot_v2/DCU/ESP32_COMM/main/include/app_config.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/riscv32-esp-elf/include/c++/15.2.0/cstdint \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/riscv32-esp-elf/include/c++/15.2.0/riscv32-esp-elf/rv32imc_zicsr_zifencei/ilp32/no-rtti/bits/c++config.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/riscv32-esp-elf/include/c++/15.2.0/riscv32-esp-elf/rv32imc_zicsr_zifencei/ilp32/no-rtti/bits/os_defines.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/riscv32-esp-elf/include/c++/15.2.0/riscv32-esp-elf/rv32imc_zicsr_zifencei/ilp32/no-rtti/bits/cpu_defines.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/riscv32-esp-elf/include/c++/15.2.0/pstl/pstl_config.h \
G:/Robot_v2/DCU/ESP32_COMM/main/include/version.h \
G:\Robot_v2\DCU\ESP32_COMM\main\monitor\debug_log.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/port/esp32xx/include/sys/socket.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/include/lwip/sockets.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/sockets.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/opt.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/port/include/lwipopts.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/unistd.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/sys/unistd.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/types.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/_pthreadtypes.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/sched.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/_timespec.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/machine/types.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/sys/select.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/select.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/_sigset.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/_timeval.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/_select.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/unistd.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/sys/fcntl.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/fcntl.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/_default_fcntl.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/time.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/time.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/sys/time.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/time.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/machine/_time.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/sys/ioctl.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/sys/poll.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_system/include/esp_task.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_hw_support/include/esp_random.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/port/include/sntp/sntp_get_set_time.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/port/include/sockets_ext.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/port/freertos/include/arch/sys_arch.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/debug.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/arch.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/port/esp32xx/include/arch/cc.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/errno.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/sys/errno.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/errno.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/ctype.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/ip_addr.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/def.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/ip4_addr.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/ip6_addr.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/def.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/ip6_zone.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/netif.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/err.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/pbuf.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/stats.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/mem.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/memp.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/priv/memp_std.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/priv/memp_priv.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/priv/mem_priv.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/inet.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/errno.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/net/if.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/if_api.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/port/include/netinet/in.h
@@ -1,165 +0,0 @@
esp-idf/transport/CMakeFiles/__idf_transport.dir/__/__/main/transport/protocol.cpp.obj: \
G:\Robot_v2\DCU\ESP32_COMM\main\transport\protocol.cpp \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/string.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/sys/cdefs.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/cdefs.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/config.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/machine/ieeefp.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/features.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/picolibc.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/15.2.0/include/float.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/machine/_default_types.h \
G:/Robot_v2/DCU/ESP32_COMM/build/config/sdkconfig.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/stdint.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/15.2.0/include/stddef.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/_intsup.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/_stdint.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/_locale.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/strings.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/_types.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/machine/_types.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/string.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/stdio.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/stdio.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/15.2.0/include/stdarg.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/sys/lock.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/lock.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_hw_support/include/esp_random.h \
F:/software/.espressif/v6.0/esp-idf/components/mbedtls/port/include/aes/esp_aes.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_common/include/esp_types.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/15.2.0/include/stdbool.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_hal_security/include/hal/aes_types.h \
G:/Robot_v2/DCU/ESP32_COMM/main/include/app_config.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/riscv32-esp-elf/include/c++/15.2.0/cstdint \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/riscv32-esp-elf/include/c++/15.2.0/riscv32-esp-elf/rv32imc_zicsr_zifencei/ilp32/no-rtti/bits/c++config.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/riscv32-esp-elf/include/c++/15.2.0/riscv32-esp-elf/rv32imc_zicsr_zifencei/ilp32/no-rtti/bits/os_defines.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/riscv32-esp-elf/include/c++/15.2.0/riscv32-esp-elf/rv32imc_zicsr_zifencei/ilp32/no-rtti/bits/cpu_defines.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/riscv32-esp-elf/include/c++/15.2.0/pstl/pstl_config.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/FreeRTOS.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/config/include/freertos/FreeRTOSConfig.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/assert.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/stdlib.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/machine/stdlib.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/alloca.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/_wait.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/assert.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/config/riscv/include/freertos/FreeRTOSConfig_arch.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/projdefs.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/portable.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/deprecated_definitions.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/portable/riscv/include/freertos/portmacro.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_hw_support/include/spinlock.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_hw_support/include/esp_cpu.h \
F:/software/.espressif/v6.0/esp-idf/components/soc/esp32c3/include/soc/soc_caps.h \
F:/software/.espressif/v6.0/esp-idf/components/soc/include/soc/soc_caps_eval.h \
F:/software/.espressif/v6.0/esp-idf/components/riscv/include/riscv/csr.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/param.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/syslimits.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/machine/endian.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/machine/_endian.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/machine/param.h \
F:/software/.espressif/v6.0/esp-idf/components/riscv/include/riscv/encoding.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_common/include/esp_assert.h \
F:/software/.espressif/v6.0/esp-idf/components/riscv/include/riscv/rv_utils.h \
F:/software/.espressif/v6.0/esp-idf/components/soc/esp32c3/include/soc/interrupt_reg.h \
F:/software/.espressif/v6.0/esp-idf/components/soc/esp32c3/register/soc/interrupt_core0_reg.h \
F:/software/.espressif/v6.0/esp-idf/components/soc/esp32c3/include/soc/soc.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_common/include/esp_bit_defs.h \
F:/software/.espressif/v6.0/esp-idf/components/soc/esp32c3/register/soc/reg_base.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_common/include/esp_attr.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_common/include/esp_assert.h \
F:/software/.espressif/v6.0/esp-idf/components/riscv/include/riscv/interrupt.h \
F:/software/.espressif/v6.0/esp-idf/components/riscv/include/esp_private/interrupt_intc.h \
F:/software/.espressif/v6.0/esp-idf/components/riscv/include/riscv/csr_pie.h \
F:/software/.espressif/v6.0/esp-idf/components/riscv/include/riscv/csr_dsp.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_hw_support/include/esp_intr_alloc.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_common/include/esp_err.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_common/include/esp_compiler.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_hw_support/include/esp_intr_types.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_common/include/esp_macros.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_rom/include/esp_rom_sys.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/inttypes.h \
F:/software/.espressif/v6.0/esp-idf/components/soc/esp32c3/include/soc/reset_reasons.h \
F:/software/.espressif/v6.0/esp-idf/components/heap/include/esp_heap_caps.h \
F:/software/.espressif/v6.0/esp-idf/components/heap/include/multi_heap.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_system/include/esp_system.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_common/include/esp_idf_version.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/esp_newlib.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/sys/reent.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/limits.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/15.2.0/include/limits.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/mpu_wrappers.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/esp_additions/include/freertos/idf_additions.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/task.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/list.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/queue.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/task.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/semphr.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/queue.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/stream_buffer.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/message_buffer.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/stream_buffer.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/event_groups.h \
F:/software/.espressif/v6.0/esp-idf/components/freertos/FreeRTOS-Kernel/include/freertos/timers.h \
G:/Robot_v2/DCU/ESP32_COMM/main/include/version.h \
G:\Robot_v2\DCU\ESP32_COMM\main\transport\protocol.h \
G:/Robot_v2/DCU/ESP32_COMM/main/monitor/debug_log.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/port/esp32xx/include/sys/socket.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/include/lwip/sockets.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/sockets.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/opt.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/port/include/lwipopts.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/unistd.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/sys/unistd.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/types.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/_pthreadtypes.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/sched.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/_timespec.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/machine/types.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/sys/select.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/select.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/_sigset.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/_timeval.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/_select.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/unistd.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/sys/fcntl.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/fcntl.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/_default_fcntl.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/time.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/time.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/sys/time.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/time.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/machine/_time.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/sys/ioctl.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/sys/poll.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_system/include/esp_task.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/port/include/sntp/sntp_get_set_time.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/port/include/sockets_ext.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/port/freertos/include/arch/sys_arch.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/debug.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/arch.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/port/esp32xx/include/arch/cc.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/errno.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/sys/errno.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/sys/errno.h \
C:/Espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/picolibc/include/ctype.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/ip_addr.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/def.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/ip4_addr.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/ip6_addr.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/def.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/ip6_zone.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/netif.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/err.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/pbuf.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/stats.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/mem.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/memp.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/priv/memp_std.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/priv/memp_priv.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/priv/mem_priv.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/inet.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/errno.h \
F:/software/.espressif/v6.0/esp-idf/components/esp_libc/platform_include/net/if.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/lwip/src/include/lwip/if_api.h \
F:/software/.espressif/v6.0/esp-idf/components/lwip/port/include/netinet/in.h
+1 -1
View File
@@ -327,6 +327,6 @@
<span id="toastMsg">操作成功</span>
</div>
<script type="module" src="js/can.js?v=fad32c3a"></script>
<script type="module" src="js/can.js?v=20260727a"></script>
</body>
</html>
+1 -1
View File
@@ -182,6 +182,6 @@
<span id="toastMsg">操作成功</span>
</div>
<script type="module" src="js/can_monitor.js?v=9547d2a1"></script>
<script type="module" src="js/can_monitor.js?v=20260727a"></script>
</body>
</html>
+670
View File
@@ -0,0 +1,670 @@
/* motor.css - 电机控制台页面样式
* 由 motor.html 内联 <style>(原 L7-L675)机械外提,内容未改。
* 独立主题(seed tokens),不依赖 base.css/components.css。 */
/* ═══════════════════════ SEED TOKENS ═══════════════════════ */
:root {
--seed-bg: #090e15;
--seed-surface: #0f161f;
--seed-fg: #e2e9f2;
--seed-primary: #22d3ee;
--seed-accent: #f59e0b;
--seed-radius: 10px;
/* derived tokens */
--bg-root: var(--seed-bg);
--bg-panel: var(--seed-surface);
--bg-raised: color-mix(in srgb, var(--seed-surface) 82%, #ffffff 4%);
--fg: var(--seed-fg);
--fg-muted: color-mix(in srgb, var(--seed-fg) 55%, transparent);
--fg-dim: color-mix(in srgb, var(--seed-fg) 35%, transparent);
--border: color-mix(in srgb, var(--seed-fg) 10%, transparent);
--border-strong: color-mix(in srgb, var(--seed-fg) 18%, transparent);
--primary: var(--seed-primary);
--primary-dim: color-mix(in srgb, var(--seed-primary) 18%, transparent);
--primary-glow: color-mix(in srgb, var(--seed-primary) 30%, transparent);
--warn: var(--seed-accent);
--warn-dim: color-mix(in srgb, var(--seed-accent) 15%, transparent);
--ok: #34d399;
--ok-dim: color-mix(in srgb, #34d399 14%, transparent);
--danger: #f87171;
--danger-dim: color-mix(in srgb, #f87171 14%, transparent);
--radius: var(--seed-radius);
--radius-sm: calc(var(--seed-radius) * 0.6);
--radius-lg: calc(var(--seed-radius) * 1.4);
--font-body: "PingFang SC", "Microsoft YaHei", "Noto Sans SC", system-ui, sans-serif;
--font-mono: "Cascadia Code", "Fira Code", "SF Mono", "JetBrains Mono", Consolas, monospace;
--sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 20px; --sp-6: 24px;
--toolbar-h: 54px;
--statusbar-h: 42px;
}
/* ═══════════════════════ RESET & BASE ═══════════════════════ */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { font-size: 15px; }
body {
font-family: var(--font-body);
background: var(--bg-root);
color: var(--fg);
line-height: 1.5;
height: 100vh;
overflow: hidden;
display: grid;
grid-template-rows: var(--toolbar-h) 1fr var(--statusbar-h);
}
/* ambient grid texture */
body::before {
content: "";
position: fixed; inset: 0; z-index: 0; pointer-events: none;
background-image:
linear-gradient(color-mix(in srgb, var(--seed-primary) 3%, transparent) 1px, transparent 1px),
linear-gradient(90deg, color-mix(in srgb, var(--seed-primary) 3%, transparent) 1px, transparent 1px);
background-size: 48px 48px;
mask-image: radial-gradient(ellipse 90% 70% at 50% 30%, black 20%, transparent 80%);
}
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: var(--fg-dim); }
button { font: inherit; cursor: pointer; border: none; background: none; color: inherit; }
input, select { font: inherit; color: inherit; }
label { display: block; }
/* ═══════════════════════ TOOLBAR ═══════════════════════ */
.toolbar {
position: relative; z-index: 10;
display: flex; align-items: center; gap: var(--sp-4);
padding: 0 var(--sp-5);
background: var(--bg-panel);
border-bottom: 1px solid var(--border);
}
.toolbar-brand {
display: flex; align-items: center; gap: var(--sp-3);
font-weight: 600; font-size: 1.05rem; letter-spacing: -0.01em;
white-space: nowrap;
}
.toolbar-brand svg { flex-shrink: 0; }
.toolbar-brand .sub {
font-size: 0.72rem; font-weight: 400; color: var(--fg-muted);
letter-spacing: 0.08em; text-transform: uppercase;
font-family: var(--font-mono);
}
.toolbar-sep { width: 1px; height: 26px; background: var(--border-strong); flex-shrink: 0; }
.conn-group { display: flex; align-items: center; gap: var(--sp-2); }
.conn-ip-label {
font-family: var(--font-mono); font-size: 0.82rem;
color: var(--fg-muted); padding: 4px 8px;
background: var(--bg-root); border: 1px solid var(--border);
border-radius: var(--radius-sm); letter-spacing: 0.02em;
min-width: 7.5em;
}
.toolbar-right a.btn {
text-decoration: none; color: var(--fg-muted);
border-color: var(--border-strong);
}
.toolbar-right a.btn:hover { color: var(--primary); border-color: color-mix(in srgb, var(--seed-primary) 40%, transparent); }
.btn {
display: inline-flex; align-items: center; gap: 6px;
padding: 6px 14px; border-radius: var(--radius-sm);
font-size: 0.85rem; font-weight: 550; letter-spacing: 0.02em;
border: 1px solid var(--border-strong);
background: var(--bg-raised);
transition: background .15s, border-color .15s, transform .1s;
white-space: nowrap;
}
.btn:hover { background: color-mix(in srgb, var(--seed-surface) 60%, #ffffff 8%); }
.btn:active { transform: translateY(1px); }
.btn-primary {
background: color-mix(in srgb, var(--seed-primary) 16%, var(--seed-surface));
border-color: color-mix(in srgb, var(--seed-primary) 40%, transparent);
color: var(--primary);
}
.btn-primary:hover { background: color-mix(in srgb, var(--seed-primary) 24%, var(--seed-surface)); }
.btn-danger {
background: var(--danger-dim); border-color: color-mix(in srgb, var(--danger) 40%, transparent);
color: var(--danger);
}
.btn-sm { padding: 4px 10px; font-size: 0.78rem; }
.btn:disabled { opacity: .4; pointer-events: none; }
.led {
width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0;
background: var(--fg-dim); transition: background .3s, box-shadow .3s;
}
.led-on { background: var(--ok); box-shadow: 0 0 6px var(--ok); }
.led-warn { background: var(--warn); box-shadow: 0 0 6px var(--warn); }
.led-err { background: var(--danger); box-shadow: 0 0 6px var(--danger); }
.led-pulse { animation: ledPulse 1.2s ease-in-out infinite; }
@keyframes ledPulse { 0%,100% { opacity: 1; } 50% { opacity: .35; } }
.ch-select {
padding: 5px 8px; background: var(--bg-root);
border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
font-family: var(--font-mono); font-size: 0.82rem; outline: none;
}
.ch-select:focus { border-color: var(--primary); }
/* 刷新速度输入框:与 .ch-select 同风格,宽度收窄 */
.refresh-input {
width: 64px; padding: 5px 6px; background: var(--bg-root);
border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
font-family: var(--font-mono); font-size: 0.82rem; outline: none;
text-align: center;
}
.refresh-input:focus { border-color: var(--primary); }
.refresh-input::-webkit-inner-spin-button { opacity: .5; }
.refresh-hint { font-size: .68rem; color: var(--fg-dim); font-family: var(--font-mono); letter-spacing: .04em; }
.toolbar-right { margin-left: auto; display: flex; align-items: center; gap: var(--sp-3); }
.node-badge {
font-family: var(--font-mono); font-size: 0.8rem;
padding: 4px 12px; border-radius: 99px;
background: var(--primary-dim); color: var(--primary);
border: 1px solid color-mix(in srgb, var(--seed-primary) 30%, transparent);
letter-spacing: 0.02em;
}
/* ═══════════════════════ MAIN LAYOUT ═══════════════════════ */
.main-grid {
position: relative; z-index: 1;
display: grid;
grid-template-columns: minmax(240px, 290px) minmax(0, 0.9fr) minmax(420px, 1.1fr);
gap: var(--sp-3);
padding: var(--sp-3);
overflow: hidden;
min-height: 0;
}
.panel {
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
display: flex; flex-direction: column;
min-height: 0; overflow: hidden;
}
.panel-head {
display: flex; align-items: center; gap: var(--sp-2);
padding: var(--sp-3) var(--sp-4);
border-bottom: 1px solid var(--border);
flex-shrink: 0;
}
.panel-title {
font-size: 0.78rem; font-weight: 600;
letter-spacing: 0.08em; text-transform: uppercase;
color: var(--fg-muted); font-family: var(--font-mono);
}
.panel-body { flex: 1; overflow-y: auto; min-height: 0; }
/* ═══════════════════════ LEFT: NODE LIST ═══════════════════════ */
.node-list { padding: var(--sp-2); display: flex; flex-direction: column; gap: var(--sp-2); }
.node-empty { padding: var(--sp-5); text-align: center; color: var(--fg-dim); font-size: .8rem; line-height: 1.7; }
.node-card {
position: relative;
padding: var(--sp-3) var(--sp-4);
border-radius: var(--radius);
border: 1px solid var(--border);
background: var(--bg-root);
cursor: pointer;
transition: border-color .2s, background .2s, transform .12s;
}
.node-card:hover { border-color: var(--border-strong); transform: translateX(2px); }
.node-card.active {
border-color: color-mix(in srgb, var(--seed-primary) 55%, transparent);
background: color-mix(in srgb, var(--seed-primary) 6%, var(--bg-root));
}
.node-card.fault { border-color: color-mix(in srgb, var(--danger) 55%, transparent); }
.node-card.fault.active { border-color: var(--danger); }
.node-card.offline { opacity: .5; }
/* 独立 BOOT 徽章:总线上有电机在 Bootloader(0x103 心跳),不归属任何 Nx
* 注意:不要用内联 style="display:none",否则 .show 的 display:flex 盖不过。 */
.boot-badge {
display: none; align-items: center; gap: var(--sp-2);
margin-bottom: var(--sp-2); padding: var(--sp-2) var(--sp-3);
border: 1px solid color-mix(in srgb, var(--warn) 55%, transparent);
border-radius: var(--radius); background: color-mix(in srgb, var(--warn) 12%, transparent);
font-family: var(--font-mono); font-size: .72rem; color: var(--warn);
font-weight: 600; letter-spacing: 0.02em;
}
.boot-badge.show { display: flex; }
.boot-badge .boot-dot {
width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;
background: var(--warn); box-shadow: 0 0 6px var(--warn);
animation: bootpulse 1s ease-in-out infinite;
}
.boot-badge .boot-sub { opacity: .75; font-weight: 400; margin-left: auto; }
@keyframes bootpulse { 0%,100% { opacity: 1; } 50% { opacity: .35; } }
.nc-top { display: flex; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-2); }
.nc-id {
font-family: var(--font-mono); font-weight: 700; font-size: 1.05rem;
letter-spacing: -0.02em; min-width: 2.2em;
}
.nc-mode {
font-size: 0.7rem; padding: 2px 8px; border-radius: 99px;
background: var(--primary-dim); color: var(--primary);
font-weight: 550; letter-spacing: 0.02em;
}
.nc-mode.mode-off { background: color-mix(in srgb, var(--fg) 8%, transparent); color: var(--fg-muted); }
.nc-mode.mode-fault { background: var(--danger-dim); color: var(--danger); }
.nc-status-text {
margin-left: auto; font-size: 0.68rem; color: var(--fg-muted);
font-family: var(--font-mono); max-width: 7.5em;
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
letter-spacing: 0.01em;
}
.node-card.fault .nc-status-text { color: var(--danger); font-weight: 600; }
.nc-readings {
display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-1);
font-family: var(--font-mono); font-size: 0.78rem;
}
.nc-reading { display: flex; flex-direction: column; gap: 1px; }
.nc-reading .lbl { font-size: 0.62rem; color: var(--fg-dim); letter-spacing: 0.06em; text-transform: uppercase; }
.nc-reading .val { color: var(--fg); transition: color .3s; }
.nc-faults {
position: absolute; top: var(--sp-2); right: var(--sp-2);
display: flex; gap: 3px;
}
.fault-dot {
width: 7px; height: 7px; border-radius: 2px;
background: var(--danger); opacity: .9;
animation: ledPulse 1s ease-in-out infinite;
}
.fault-dot:nth-child(2) { animation-delay: .2s; }
.fault-dot:nth-child(3) { animation-delay: .4s; }
/* ═══════════════════════ CENTER: CONTROL ═══════════════════════ */
.center-panel { display: flex; flex-direction: column; min-height: 0; }
.cmd-section { padding: var(--sp-4); flex-shrink: 0; }
.cmd-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: var(--sp-4);
}
.field { display: flex; flex-direction: column; gap: var(--sp-1); }
.field-label {
font-size: 0.72rem; font-weight: 550; color: var(--fg-muted);
letter-spacing: 0.06em; text-transform: uppercase; font-family: var(--font-mono);
}
.field-unit { color: var(--fg-dim); text-transform: none; letter-spacing: 0; }
.field select, .field input[type="number"], .field input[type="text"] {
padding: 7px 10px; background: var(--bg-root);
border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
font-family: var(--font-mono); font-size: 0.88rem; outline: none;
transition: border-color .2s;
width: 100%;
}
.field select:focus, .field input:focus { border-color: var(--primary); }
.mode-desc {
font-size: 0.75rem; color: var(--fg-dim); margin-top: 2px;
min-height: 1.2em;
}
.pid-group {
display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-3);
}
.cmd-actions {
display: flex; gap: var(--sp-3); margin-top: var(--sp-4);
padding-top: var(--sp-3); border-top: 1px solid var(--border);
align-items: center; flex-wrap: wrap;
}
.send-hint { font-size: 0.72rem; color: var(--fg-dim); margin-left: auto; font-family: var(--font-mono); }
.target-hidden { display: none !important; }
.repeat-period {
display: inline-flex; align-items: center; gap: 4px;
font-family: var(--font-mono); font-size: 0.75rem; color: var(--fg-muted);
user-select: none;
}
.repeat-period input {
width: 4.6em; padding: 5px 6px; background: var(--bg-root);
border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
font-family: var(--font-mono); font-size: 0.8rem; color: var(--fg);
outline: none; text-align: right; transition: border-color .2s;
}
.repeat-period input:focus { border-color: var(--primary); }
/* tabs */
.tabs-bar {
display: flex; gap: 2px; padding: 0 var(--sp-4);
border-top: 1px solid var(--border); flex-shrink: 0;
background: color-mix(in srgb, var(--bg-root) 50%, var(--bg-panel));
}
.tab-btn {
padding: 9px 16px; font-size: 0.8rem; font-weight: 550;
color: var(--fg-muted); border-bottom: 2px solid transparent;
transition: color .2s, border-color .2s; letter-spacing: 0.02em;
}
.tab-btn:hover { color: var(--fg); }
.tab-btn.active { color: var(--primary); border-bottom-color: var(--primary); }
.tab-content { flex: 1; overflow-y: auto; min-height: 0; padding: var(--sp-4); }
.tab-page { display: none; }
.tab-page.active { display: block; }
/* config tab */
.config-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--sp-3); }
.config-btn {
display: flex; flex-direction: column; align-items: center; gap: var(--sp-2);
padding: var(--sp-4); border-radius: var(--radius);
border: 1px solid var(--border-strong); background: var(--bg-root);
transition: border-color .2s, background .2s, transform .1s;
}
.config-btn:hover { border-color: var(--fg-dim); transform: translateY(-1px); }
.config-btn:active { transform: translateY(1px); }
.config-btn svg { opacity: .8; }
.config-btn .cb-name { font-size: 0.82rem; font-weight: 550; }
.config-btn .cb-sig { font-size: 0.68rem; color: var(--fg-dim); font-family: var(--font-mono); }
.config-btn.danger-action:hover { border-color: color-mix(in srgb, var(--danger) 50%, transparent); }
/* version tab */
.version-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-3); }
.ver-card {
padding: var(--sp-4); border-radius: var(--radius);
border: 1px solid var(--border); background: var(--bg-root); text-align: center;
}
.ver-card .ver-type { font-size: 0.68rem; color: var(--fg-muted); letter-spacing: 0.08em; text-transform: uppercase; font-family: var(--font-mono); margin-bottom: var(--sp-2); }
.ver-card .ver-date { font-family: var(--font-mono); font-size: 1.05rem; font-weight: 600; letter-spacing: -0.01em; }
.ver-empty { color: var(--fg-dim); font-size: 0.85rem; }
/* node id tab */
.nodeid-row { display: flex; gap: var(--sp-3); align-items: flex-end; flex-wrap: wrap; }
.nodeid-result {
margin-top: var(--sp-3); padding: var(--sp-3) var(--sp-4);
border-radius: var(--radius-sm); background: var(--bg-root);
border: 1px solid var(--border); font-family: var(--font-mono); font-size: 0.85rem;
color: var(--fg-muted); min-height: 2.6em;
}
/* OTA tab */
.ota-stages {
display: flex; gap: 0; margin-bottom: var(--sp-4); overflow-x: auto;
padding-bottom: var(--sp-1);
}
.ota-stage {
display: flex; align-items: center; gap: var(--sp-2);
padding: var(--sp-2) var(--sp-3);
font-size: 0.72rem; color: var(--fg-dim); white-space: nowrap;
position: relative;
}
.ota-stage::after {
content: ""; width: 20px; height: 1px; background: var(--border-strong);
margin-left: var(--sp-2); flex-shrink: 0;
}
.ota-stage:last-child::after { display: none; }
.ota-stage .st-dot {
width: 20px; height: 20px; border-radius: 50%; flex-shrink: 0;
border: 1.5px solid var(--border-strong);
display: flex; align-items: center; justify-content: center;
font-family: var(--font-mono); font-size: 0.62rem;
transition: border-color .3s, background .3s, color .3s;
}
.ota-stage.done .st-dot { border-color: var(--ok); background: var(--ok-dim); color: var(--ok); }
.ota-stage.current .st-dot { border-color: var(--primary); background: var(--primary-dim); color: var(--primary); animation: ledPulse 1.4s infinite; }
.ota-stage.current { color: var(--fg); }
.ota-stage.done { color: var(--fg-muted); }
.ota-progress-wrap { margin-bottom: var(--sp-4); }
.ota-progress-bar {
height: 8px; border-radius: 4px; background: var(--bg-root);
border: 1px solid var(--border); overflow: hidden;
}
.ota-progress-fill {
height: 100%; width: 0%; border-radius: 4px;
background: linear-gradient(90deg, color-mix(in srgb, var(--seed-primary) 70%, var(--bg-root)), var(--primary));
transition: width .3s ease;
}
.ota-stats {
display: flex; gap: var(--sp-5); margin-top: var(--sp-2);
font-family: var(--font-mono); font-size: 0.78rem; color: var(--fg-muted);
flex-wrap: wrap;
}
.ota-stats .hl { color: var(--primary); }
.ota-file-row { display: flex; gap: var(--sp-3); align-items: center; margin-bottom: var(--sp-4); flex-wrap: wrap; }
.ota-file-name { font-family: var(--font-mono); font-size: 0.8rem; color: var(--fg-muted); }
.ota-log {
margin-top: var(--sp-3); padding: var(--sp-3);
background: var(--bg-root); border: 1px solid var(--border);
border-radius: var(--radius-sm); font-family: var(--font-mono);
font-size: 0.72rem; line-height: 1.7; color: var(--fg-muted);
max-height: 160px; overflow-y: auto;
}
.ota-log .log-ok { color: var(--ok); }
.ota-log .log-err { color: var(--danger); }
.ota-log .log-info { color: var(--primary); }
.ota-log-toolbar {
display: flex; justify-content: flex-end; gap: 6px;
margin-top: var(--sp-3); margin-bottom: -2px;
}
.ota-log-toolbar button {
font-size: 0.68rem; padding: 2px 8px;
border-radius: var(--radius-sm); border: 1px solid var(--border);
background: var(--bg-card); color: var(--fg-muted);
cursor: pointer; transition: background .15s, color .15s;
}
.ota-log-toolbar button:hover { background: rgba(255,255,255,.08); color: var(--fg); }
.ota-log-toolbar button.copied { background: rgba(34,197,94,.18); color: #86efac; }
/* ═══════════════════════ RIGHT: STATUS PANEL ═══════════════════════ */
.status-panel .panel-body { padding: var(--sp-4); display: flex; flex-direction: column; gap: var(--sp-4); }
.big-readings { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-3); }
.big-reading {
padding: var(--sp-3) var(--sp-3); text-align: center;
background: var(--bg-root); border: 1px solid var(--border);
border-radius: var(--radius);
transition: border-color .3s, background .2s;
cursor: pointer; position: relative;
}
.big-reading:hover { border-color: var(--border-strong); background: color-mix(in srgb, var(--seed-primary) 4%, var(--bg-root)); }
.big-reading.open { border-color: color-mix(in srgb, var(--seed-primary) 50%, transparent); }
.br-toggle {
font-size: 0.55rem; color: var(--fg-dim); letter-spacing: 0.06em;
opacity: 0; transition: opacity .2s, color .2s; margin-left: 4px;
}
.big-reading:hover .br-toggle { opacity: .8; }
.big-reading.open .br-toggle { opacity: 1; color: var(--primary); }
.br-scope {
max-height: 0; overflow: hidden; margin-top: 0;
transition: max-height .35s cubic-bezier(.4,0,.2,1), margin-top .35s;
}
.big-reading.open .br-scope { max-height: 96px; margin-top: var(--sp-2); }
.br-scope canvas {
width: 100%; height: 84px; display: block;
border-radius: var(--radius-sm);
background: color-mix(in srgb, var(--seed-bg) 78%, #000000 14%);
border: 1px solid var(--border);
}
.big-reading .br-val {
font-family: var(--font-mono); font-size: clamp(1.5rem, 2vw, 2.4rem);
font-weight: 700; letter-spacing: -0.02em; line-height: 1.2;
transition: color .25s;
}
.big-reading .br-val.flash { color: var(--primary); }
.big-reading .br-unit { font-size: 0.65rem; color: var(--fg-dim); font-family: var(--font-mono); }
.big-reading .br-lbl {
font-size: 0.62rem; color: var(--fg-muted); margin-top: 2px;
letter-spacing: 0.08em; text-transform: uppercase; font-family: var(--font-mono);
}
.status-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-3); }
.temp-block {
padding: var(--sp-3); background: var(--bg-root); border: 1px solid var(--border);
border-radius: var(--radius);
transition: border-color .3s, background .2s; cursor: pointer;
}
.temp-block:hover { border-color: var(--border-strong); background: color-mix(in srgb, var(--seed-primary) 4%, var(--bg-root)); }
.temp-block.open { border-color: color-mix(in srgb, var(--seed-primary) 50%, transparent); }
.temp-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: var(--sp-2); }
.temp-name { font-size: 0.68rem; color: var(--fg-muted); letter-spacing: 0.06em; text-transform: uppercase; font-family: var(--font-mono); }
.temp-toggle {
font-size: 0.55rem; color: var(--fg-dim); letter-spacing: 0.06em;
opacity: 0; transition: opacity .2s, color .2s; margin-left: 6px;
}
.temp-block:hover .temp-toggle { opacity: .8; }
.temp-block.open .temp-toggle { opacity: 1; color: var(--primary); }
.temp-val { font-family: var(--font-mono); font-size: 0.95rem; font-weight: 600; }
.temp-bar { height: 5px; border-radius: 3px; background: var(--border); overflow: hidden; }
.temp-block .br-scope { max-height: 0; overflow: hidden; margin-top: 0; transition: max-height .35s cubic-bezier(.4,0,.2,1), margin-top .35s; }
.temp-block.open .br-scope { max-height: 80px; margin-top: var(--sp-2); }
.temp-block .br-scope canvas { height: 68px; }
.temp-fill {
height: 100%; border-radius: 3px; transition: width .6s ease, background .6s;
background: var(--ok);
}
.temp-fill.warm { background: var(--warn); }
.temp-fill.hot { background: var(--danger); }
.phase-currents { padding: var(--sp-3); background: var(--bg-root); border: 1px solid var(--border); border-radius: var(--radius); }
.pc-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); margin-bottom: var(--sp-2); flex-wrap: wrap; }
.pc-title { font-size: 0.68rem; color: var(--fg-muted); letter-spacing: 0.06em; text-transform: uppercase; font-family: var(--font-mono); }
.pc-live-vals { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.pc-chip {
display: inline-flex; align-items: center; gap: 4px;
font-family: var(--font-mono); font-size: 0.72rem; color: var(--fg-muted);
padding: 2px 8px; border-radius: 99px;
background: color-mix(in srgb, var(--ch-color) 10%, transparent);
border: 1px solid color-mix(in srgb, var(--ch-color) 30%, transparent);
}
.pc-chip b { color: var(--ch-color); font-weight: 600; min-width: 4.2em; text-align: right; }
.scope-wrap { position: relative; height: 172px; border-radius: var(--radius-sm); overflow: hidden; background: color-mix(in srgb, var(--seed-bg) 80%, #000000 12%); border: 1px solid var(--border); }
.scope-wrap canvas { width: 100%; height: 100%; display: block; }
.scope-grid-labels {
position: absolute; left: 6px; top: 0; bottom: 0;
display: flex; flex-direction: column; justify-content: space-between;
font-family: var(--font-mono); font-size: 0.58rem; color: var(--fg-dim);
padding: 4px 0; pointer-events: none;
}
.misc-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-3); }
.misc-item {
padding: var(--sp-3); background: var(--bg-root);
border: 1px solid var(--border); border-radius: var(--radius);
display: flex; flex-direction: column; gap: 2px;
}
.misc-item .mi-lbl { font-size: 0.62rem; color: var(--fg-muted); letter-spacing: 0.08em; text-transform: uppercase; font-family: var(--font-mono); }
.misc-item .mi-val { font-family: var(--font-mono); font-size: 1rem; font-weight: 600; }
.flag-lights { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: var(--sp-2); padding: var(--sp-3); background: var(--bg-root); border: 1px solid var(--border); border-radius: var(--radius); }
.flag-item {
display: flex; align-items: center; gap: var(--sp-2);
font-size: 0.75rem; font-family: var(--font-mono); color: var(--fg-muted);
padding: var(--sp-2) var(--sp-3); border-radius: var(--radius-sm);
border: 1px solid var(--border);
background: color-mix(in srgb, var(--seed-surface) 60%, transparent);
transition: background .3s, border-color .3s, color .3s, box-shadow .3s;
}
.flag-item .flag-state { margin-left: auto; font-size: 0.62rem; letter-spacing: 0.08em; text-transform: uppercase; opacity: .7; }
.flag-item.is-ok { border-color: color-mix(in srgb, var(--ok) 25%, transparent); }
.flag-item.is-ok .flag-state { color: var(--ok); }
.flag-item.is-fault {
background: color-mix(in srgb, var(--danger) 16%, var(--seed-bg));
border-color: color-mix(in srgb, var(--danger) 65%, transparent);
color: var(--danger); font-weight: 700;
box-shadow: 0 0 12px color-mix(in srgb, var(--danger) 25%, transparent), inset 0 0 8px color-mix(in srgb, var(--danger) 8%, transparent);
animation: faultPulse 1.1s ease-in-out infinite;
}
.flag-item.is-fault .flag-state { color: var(--danger); opacity: 1; }
@keyframes faultPulse {
0%, 100% { box-shadow: 0 0 12px color-mix(in srgb, var(--danger) 30%, transparent), inset 0 0 8px color-mix(in srgb, var(--danger) 10%, transparent); }
50% { box-shadow: 0 0 22px color-mix(in srgb, var(--danger) 50%, transparent), inset 0 0 12px color-mix(in srgb, var(--danger) 16%, transparent); }
}
.flag-led { width: 9px; height: 9px; border-radius: 50%; background: var(--border-strong); transition: background .3s, box-shadow .3s; flex-shrink: 0; }
.flag-led.on-ok { background: var(--ok); box-shadow: 0 0 6px var(--ok); }
.flag-led.on-err { background: var(--danger); box-shadow: 0 0 8px var(--danger); animation: ledPulse .8s infinite; }
.cpu-ring-wrap { display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-3); background: var(--bg-root); border: 1px solid var(--border); border-radius: var(--radius); }
.cpu-ring { position: relative; width: 52px; height: 52px; flex-shrink: 0; }
.cpu-ring svg { transform: rotate(-90deg); }
.cpu-ring .ring-bg { fill: none; stroke: var(--border); stroke-width: 5; }
.cpu-ring .ring-fg { fill: none; stroke: var(--primary); stroke-width: 5; stroke-linecap: round; transition: stroke-dashoffset .6s ease; }
.cpu-pct {
position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
font-family: var(--font-mono); font-size: 0.72rem; font-weight: 700;
}
.cpu-info { display: flex; flex-direction: column; gap: 2px; }
.cpu-info .mi-lbl { font-size: 0.62rem; color: var(--fg-muted); letter-spacing: 0.08em; text-transform: uppercase; font-family: var(--font-mono); }
.cpu-info .mi-sub { font-size: 0.72rem; color: var(--fg-dim); font-family: var(--font-mono); }
.offline-overlay {
display: none; flex-direction: column; align-items: center; justify-content: center;
gap: var(--sp-3); padding: var(--sp-6); color: var(--fg-dim); text-align: center;
}
.offline-overlay.show { display: flex; }
.offline-overlay .off-icon { opacity: .4; }
.status-live { display: flex; flex-direction: column; gap: var(--sp-4); }
.status-live.hide { display: none; }
/* ═══════════════════════ STATUS BAR ═══════════════════════ */
.statusbar {
position: relative; z-index: 10;
display: flex; align-items: center; gap: var(--sp-4);
padding: 0 var(--sp-5);
background: var(--bg-panel);
border-top: 1px solid var(--border);
font-family: var(--font-mono); font-size: 0.72rem; color: var(--fg-muted);
overflow: hidden;
}
.sb-item { display: flex; align-items: center; gap: var(--sp-2); white-space: nowrap; }
.sb-item .sb-val { color: var(--fg); }
.sb-sep { width: 1px; height: 16px; background: var(--border); flex-shrink: 0; }
.sb-last-send { margin-left: auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 40%; color: var(--fg-dim); }
/* ═══════════════════════ TOAST & MODAL ═══════════════════════ */
.toast-container {
position: fixed; bottom: 60px; left: 50%; transform: translateX(-50%);
display: flex; flex-direction: column; gap: var(--sp-2); z-index: 1000;
pointer-events: none;
}
.toast {
padding: 10px 20px; border-radius: var(--radius);
background: var(--bg-raised); border: 1px solid var(--border-strong);
font-size: 0.82rem; box-shadow: 0 8px 32px rgba(0,0,0,.5);
animation: toastIn .25s ease;
display: flex; align-items: center; gap: var(--sp-2);
max-width: 80vw;
}
.toast.ok { border-color: color-mix(in srgb, var(--ok) 40%, transparent); }
.toast.err { border-color: color-mix(in srgb, var(--danger) 40%, transparent); }
.toast.warn { border-color: color-mix(in srgb, var(--warn) 40%, transparent); }
.toast.out { animation: toastOut .2s ease forwards; }
@keyframes toastIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
@keyframes toastOut { to { opacity: 0; transform: translateY(6px); } }
.modal-mask {
position: fixed; inset: 0; z-index: 900;
background: rgba(4, 8, 14, .75);
display: none; align-items: center; justify-content: center;
}
.modal-mask.show { display: flex; }
.modal-box {
background: var(--bg-panel); border: 1px solid var(--border-strong);
border-radius: var(--radius-lg); padding: var(--sp-6);
min-width: 320px; max-width: 420px;
box-shadow: 0 24px 64px rgba(0,0,0,.6);
animation: toastIn .2s ease;
}
.modal-title { font-size: 1rem; font-weight: 600; margin-bottom: var(--sp-2); }
.modal-desc { font-size: 0.82rem; color: var(--fg-muted); margin-bottom: var(--sp-5); line-height: 1.6; }
.modal-actions { display: flex; gap: var(--sp-3); justify-content: flex-end; }
/* disconnected banner */
.net-banner {
display: none; align-items: center; gap: var(--sp-2);
padding: 4px var(--sp-5); font-size: .72rem; font-family: var(--font-mono);
background: var(--danger-dim); color: var(--danger);
border-bottom: 1px solid color-mix(in srgb, var(--danger) 30%, transparent);
}
.net-banner.show { display: flex; }
/* ═══════════════════════ RESPONSIVE ═══════════════════════ */
@media (max-width: 1365px) {
.main-grid {
grid-template-columns: 1fr minmax(380px, 1.1fr);
grid-template-rows: auto 1fr;
}
.nodes-panel {
grid-column: 1 / -1; grid-row: 1;
}
.nodes-panel .panel-body { overflow-x: auto; overflow-y: hidden; }
.node-list { flex-direction: row; min-width: max-content; }
.node-card { min-width: 200px; }
.center-panel { grid-column: 1; grid-row: 2; }
.status-panel { grid-column: 2; grid-row: 2; }
}
@media (max-width: 900px) {
.main-grid { grid-template-columns: 1fr; grid-template-rows: auto 1fr auto; }
.center-panel { grid-column: 1; grid-row: 2; }
.status-panel { grid-column: 1; grid-row: 3; max-height: 380px; }
.toolbar { flex-wrap: wrap; height: auto; padding: var(--sp-2) var(--sp-4); }
body { grid-template-rows: auto 1fr var(--statusbar-h); overflow: auto; }
}
+18 -22
View File
@@ -63,15 +63,15 @@
</div>
<div class="card-body">
<div style="display:flex;gap:6px;margin-bottom:14px;">
<button id="modeWifiBtn" class="btn btn-primary" style="flex:1;font-size:12px;padding:7px 10px;" onclick="setConsoleMode('wifi')">WiFi OTA</button>
<button id="modeBleBtn" class="btn btn-outline" style="flex:1;font-size:12px;padding:7px 10px;" onclick="setConsoleMode('ble')">BLE 蓝牙</button>
<button id="modeWifiBtn" class="btn btn-primary" style="flex:1;font-size:12px;padding:7px 10px;" data-action="set-console-mode" data-arg="wifi">WiFi OTA</button>
<button id="modeBleBtn" class="btn btn-outline" style="flex:1;font-size:12px;padding:7px 10px;" data-action="set-console-mode" data-arg="ble">BLE 蓝牙</button>
</div>
<div id="wifiModeCards">
<div class="form-row">
<label class="form-label" for="espIp">ESP32 IP 地址</label>
<div class="input-group">
<input class="input" type="text" id="espIp" value="192.168.31.127" placeholder="输入 IP 地址">
<button class="btn btn-outline" onclick="testConnection()">测试</button>
<button id="testConnBtn" class="btn btn-outline" data-action="test-connection">测试</button>
</div>
</div>
</div>
@@ -84,20 +84,20 @@
<div class="card-head"><span class="ico">🎯</span> 升级目标、固件文件与执行操作</div>
<div class="card-body">
<div style="display:flex;gap:6px;margin-bottom:14px;">
<button id="targetGd32Tab" class="btn btn-outline" style="flex:1;font-size:12px;padding:7px 10px;" onclick="selectFlashTarget('gd32')">GD32</button>
<button id="targetEsp32Tab" class="btn btn-primary" style="flex:1;font-size:12px;padding:7px 10px;" onclick="selectFlashTarget('esp32')">ESP32</button>
<button id="targetGd32Tab" class="btn btn-outline" style="flex:1;font-size:12px;padding:7px 10px;" data-action="select-flash-target" data-arg="gd32">GD32</button>
<button id="targetEsp32Tab" class="btn btn-primary" style="flex:1;font-size:12px;padding:7px 10px;" data-action="select-flash-target" data-arg="esp32">ESP32</button>
</div>
<div style="border-top:1px solid var(--border);margin:0 -16px 14px;padding-top:14px;padding-left:16px;padding-right:16px;">
<div id="wifiEsp32UploadPane">
<div class="upload-zone upload-zone-sm" id="uploadZoneEsp32" onclick="pickSharedFirmware('esp32')">
<div class="upload-zone upload-zone-sm" id="uploadZoneEsp32" data-action="pick-shared-firmware" data-arg="esp32">
<div class="upload-ico">📤</div>
<h4>点击或拖拽 ESP32 固件</h4>
</div>
<input type="file" id="fileInputEsp32" accept=".bin" onchange="handleSharedFileSelect(event, 'esp32')" style="display:none;">
<input type="file" id="fileInputEsp32" accept=".bin" style="display:none;">
<div class="file-info" id="fileInfoEsp32">
<div class="file-info-row">
<span style="font-weight:600;">📄 <span id="fileNameEsp32">-</span></span>
<button class="btn btn-ghost btn-sm" onclick="clearSharedFirmware('esp32')">清除</button>
<button class="btn btn-ghost btn-sm" data-action="clear-shared-firmware" data-arg="esp32">清除</button>
</div>
<div class="file-info-grid">
<div class="file-meta-item"><span>类型</span><b id="fileTypeEsp32">-</b></div>
@@ -111,16 +111,16 @@
</div>
<div id="wifiGd32UploadPane" style="display:none;">
<div class="upload-zone upload-zone-sm" id="uploadZoneGd32" onclick="pickSharedFirmware('gd32')">
<div class="upload-zone upload-zone-sm" id="uploadZoneGd32" data-action="pick-shared-firmware" data-arg="gd32">
<div class="upload-ico">📤</div>
<h4>点击或拖拽 GD32 固件</h4>
<p>支持 .bin 和 .hex(自动转换)</p>
</div>
<input type="file" id="fileInputGd32" accept=".hex,.bin" onchange="handleSharedFileSelect(event, 'gd32')" style="display:none;">
<input type="file" id="fileInputGd32" accept=".hex,.bin" style="display:none;">
<div class="file-info" id="fileInfoGd32">
<div class="file-info-row">
<span style="font-weight:600;">📄 <span id="fileNameGd32">-</span></span>
<button class="btn btn-ghost btn-sm" onclick="clearSharedFirmware('gd32')">清除</button>
<button class="btn btn-ghost btn-sm" data-action="clear-shared-firmware" data-arg="gd32">清除</button>
</div>
<div class="file-info-grid">
<div class="file-meta-item"><span>类型</span><b id="fileTypeGd32">-</b></div>
@@ -134,11 +134,7 @@
</div>
<div id="bleUploadPane" style="display:none;">
<div class="upload-zone upload-zone-sm" id="uploadZone" style="margin-bottom:12px;"
onclick="document.getElementById('firmwareFile').click()"
ondragover="event.preventDefault();this.classList.add('dragover')"
ondragleave="this.classList.remove('dragover')"
ondrop="event.preventDefault();this.classList.remove('dragover');var f=event.dataTransfer.files[0];if(f&&window.bleOta)window.bleOta.notifyFileChange(f,null);">
<div class="upload-zone upload-zone-sm" id="uploadZone" style="margin-bottom:12px;" data-action="ble-pick-file">
<div class="upload-ico">📤</div>
<h4>点击或拖拽文件到此处</h4>
<p>支持 .bin 和 .hex 格式</p>
@@ -147,7 +143,7 @@
<div class="file-info" id="fileInfo">
<div class="file-info-row">
<span style="font-weight:600;">📄 <span id="fileName">-</span></span>
<button id="clearFileBtn" class="btn btn-outline btn-sm" onclick="if(window.bleOta)window.bleOta.clearFile()">清除</button>
<button id="clearFileBtn" class="btn btn-outline btn-sm" data-action="ble-clear-file">清除</button>
</div>
<div class="file-info-grid">
<div class="file-meta-item"><span>类型</span><b id="fileType">-</b></div>
@@ -164,12 +160,12 @@
</div>
<div style="height:12px"></div>
<div id="wifiEsp32ActionPane">
<button class="btn btn-primary btn-block" id="uploadEsp32Btn" onclick="startUpload('esp32')" disabled>
<button class="btn btn-primary btn-block" id="uploadEsp32Btn" data-action="start-upload" data-arg="esp32" disabled>
上传并升级 ESP32
</button>
</div>
<div id="wifiGd32ActionPane" style="display:none;">
<button class="btn btn-success btn-block" id="uploadGd32Btn" onclick="startUpload('gd32')" disabled>
<button class="btn btn-success btn-block" id="uploadGd32Btn" data-action="start-upload" data-arg="gd32" disabled>
GD32 OTA
</button>
</div>
@@ -236,7 +232,7 @@
<div class="svi-row"><span class="svi-key">校验结果</span><span class="svi-val" id="sviResult">-</span></div>
</div>
<div style="margin-top:12px;">
<button class="btn btn-outline btn-block" onclick="restartEsp32()">重启 ESP32</button>
<button class="btn btn-outline btn-block" data-action="restart-esp32">重启 ESP32</button>
</div>
</div>
</div>
@@ -300,7 +296,7 @@
<div class="card card--mem" style="display:none">
<div class="card-head">
<span class="ico">🧾</span> 系统状态 (/system/status)
<button class="btn btn-ghost btn-sm card-head-btn" onclick="refreshSystemStatusNow(event)">刷新</button>
<button class="btn btn-ghost btn-sm card-head-btn" data-action="refresh-system-status">刷新</button>
</div>
<div class="card-body">
<div class="status-kv-grid">
@@ -514,7 +510,7 @@
<span id="toastMsg">操作成功</span>
</div>
<script type="module" src="js/app.js?v=953c41e9"></script>
<script type="module" src="js/app.js?v=20260727a"></script>
<script type="module" src="js/ota/console-mode.js?v=06b7189e"></script>
<script type="module" src="js/ble_ota.js?v=01d3cb4e"></script>
</body>
+49
View File
@@ -212,6 +212,55 @@ window.applyRebootingRuntimeState = applyRebootingRuntimeState;
window.applyUploadingRuntimeState = applyUploadingRuntimeState;
window.applyDeviceBusyRuntimeState = applyDeviceBusyRuntimeState;
// ==================== data-action 事件委托(替代 HTML 内联 onclick) ====================
// 处理函数分散在 app.js / ota/console-mode.js / ble_ota.js 三个入口,均挂载在
// window 上;委托在点击时才解引用,天然规避模块加载顺序问题。
document.addEventListener('click', function (ev) {
var target = ev.target.closest('[data-action]');
if (!target) return;
var arg = target.getAttribute('data-arg');
switch (target.getAttribute('data-action')) {
case 'set-console-mode': if (window.setConsoleMode) window.setConsoleMode(arg); break;
case 'test-connection': testConnection(); break;
case 'select-flash-target': if (window.selectFlashTarget) window.selectFlashTarget(arg); break;
case 'pick-shared-firmware': if (window.pickSharedFirmware) window.pickSharedFirmware(arg); break;
case 'clear-shared-firmware': if (window.clearSharedFirmware) window.clearSharedFirmware(arg); break;
case 'ble-pick-file': var fi = document.getElementById('firmwareFile'); if (fi) fi.click(); break;
case 'ble-clear-file': if (window.bleOta) window.bleOta.clearFile(); break;
case 'start-upload': startUpload(arg); break;
case 'restart-esp32': restartEsp32(); break;
case 'refresh-system-status': refreshSystemStatusNow(ev); break;
}
});
// 共享固件文件选择(原内联 onchange="handleSharedFileSelect(event, chip)")
['esp32', 'gd32'].forEach(function (chip) {
var input = document.getElementById(chip === 'esp32' ? 'fileInputEsp32' : 'fileInputGd32');
if (input) {
input.addEventListener('change', function (ev) {
if (window.handleSharedFileSelect) window.handleSharedFileSelect(ev, chip);
});
}
});
// BLE 上传区拖拽(原内联 ondragover/ondragleave/ondrop)
var bleZone = document.getElementById('uploadZone');
if (bleZone) {
bleZone.addEventListener('dragover', function (ev) {
ev.preventDefault();
bleZone.classList.add('dragover');
});
bleZone.addEventListener('dragleave', function () {
bleZone.classList.remove('dragover');
});
bleZone.addEventListener('drop', function (ev) {
ev.preventDefault();
bleZone.classList.remove('dragover');
var f = ev.dataTransfer.files[0];
if (f && window.bleOta) window.bleOta.notifyFileChange(f, null);
});
}
// ==================== 顶层副作用(原 app.js 末尾的初始化) ====================
setupDropZone('uploadZoneEsp32', 'esp32');
setupDropZone('uploadZoneGd32', 'gd32');
+10 -9
View File
@@ -16,11 +16,12 @@
* (操作不同的 DOM 元素集),此处保留原 can.js 版本以保证行为一致。
*/
/* 子模块 import 带同一 ?v=,避免浏览器缓存旧 dbc.js(无 getDeviceIp)且保证单例 state */
/* JS 间 import 一律不带 ?v=,版本戳只出现在 HTML 入口标签上,
* 避免同一模块因 query 不同被浏览器实例化两次(state/toast 单例分裂) */
import {
state, el, getBaseUrl, getDeviceIp, setDeviceIp, parseDbc, readDbcText, buildSummary,
rebuildMergedDbc, makeDbcSourceId
} from './can/dbc.js?v=20260717x';
} from './can/dbc.js';
import {
updateDbcFileInfo,
filterMessages,
@@ -30,11 +31,11 @@ import {
recomputeTransmitterFilterEmpty,
updateNodeFilterLabel,
updateBatchUi
} from './can/messages.js?v=20260717x';
} from './can/messages.js';
import {
ensureMessageDefaults,
updateEncodedPreview
} from './can/signals.js?v=20260717x';
} from './can/signals.js';
import {
renderHistory,
sendSelectedMessage,
@@ -43,15 +44,15 @@ import {
sendManualFrame,
resetManualFields,
loadPreviewToManual
} from './can/send.js?v=20260720b';
} from './can/send.js';
import {
scheduleCanPersist,
loadCanSession,
bindCanPersistLifecycle
} from './can/persist.js?v=20260717x';
import { escapeHtml as sanitizeHtml, formatUptime } from './common/utils.js?v=20260717x';
import { showToast } from './common/toast.js?v=20260717x';
import { initCanMonitor } from './can_monitor.js?v=20260719s';
} from './can/persist.js';
import { escapeHtml as sanitizeHtml, formatUptime } from './common/utils.js';
import { showToast } from './common/toast.js';
import { initCanMonitor } from './can_monitor.js';
// ==================== 本地工具 ====================
// 原 can.js 的 formatUptime 输出格式与 common/utils.js 略有差异(d>0 时只到 h),
+8 -8
View File
@@ -6,6 +6,9 @@
* 本模块是 can 子系统的基础层,不依赖其他 can 子模块;state/el 在此导出,
* 供 messages/signals/send 共享(ES Module 的 live binding 保证引用一致)。
*/
import {
DEFAULT_ESP_IP, getSavedDeviceIp, saveDeviceIp
} from '../common/base-url.js';
// ==================== 共享状态 ====================
export var state = {
@@ -31,15 +34,12 @@ export var state = {
export var el = {};
// ==================== 基础工具 ====================
var LS_ESP_IP = 'dcu_esp_ip';
var DEFAULT_ESP_IP = '192.168.31.127';
// IP 存取通用实现在 common/base-url.js,此处包装 CAN 页特有的 el.toolIp 回退。
/** @description 设备 IP:优先 localStorage(与 OTA 页共用),否则默认。 */
/** @description 设备 IP:优先 localStorage(与 OTA 页共用),其次页面输入框,否则默认。 */
export function getDeviceIp() {
try {
var saved = localStorage.getItem(LS_ESP_IP);
if (saved && saved.trim()) return saved.trim();
} catch (_) {}
var saved = getSavedDeviceIp();
if (saved) return saved;
if (el.toolIp && el.toolIp.value && el.toolIp.value.trim()) {
return el.toolIp.value.trim();
}
@@ -50,7 +50,7 @@ export function getDeviceIp() {
export function setDeviceIp(ip) {
if (!ip || !String(ip).trim()) return;
var v = String(ip).trim();
try { localStorage.setItem(LS_ESP_IP, v); } catch (_) {}
saveDeviceIp(v);
if (el.toolIp) el.toolIp.value = v;
}
+4 -4
View File
@@ -7,10 +7,10 @@
* common/utils.js(escapeHtml/formatBytes)、
* signals.js(renderInlineSignalGrid/ensureMessageDefaults/updateEncodedPreview)。
*/
import { state, el, padHex, normalizeWhitespace, cssEscape, findMessageByKey } from './dbc.js?v=20260717x';
import { escapeHtml, formatBytes } from '../common/utils.js?v=20260717x';
import { renderInlineSignalGrid, ensureMessageDefaults, updateEncodedPreview } from './signals.js?v=20260717x';
import { scheduleCanPersist } from './persist.js?v=20260717x';
import { state, el, padHex, normalizeWhitespace, cssEscape, findMessageByKey } from './dbc.js';
import { escapeHtml, formatBytes } from '../common/utils.js';
import { renderInlineSignalGrid, ensureMessageDefaults, updateEncodedPreview } from './signals.js';
import { scheduleCanPersist } from './persist.js';
// ==================== DBC 文件信息 ====================
/** @description 更新 DBC 文件信息卡片(文件名/报文数/信号数/节点数/大小),并刷新多 DBC 摘要条与文件 chip 列表。 */
+1 -1
View File
@@ -6,7 +6,7 @@
*
* 依赖:dbc.js(state/el/parseDbc/rebuildMergedDbc)
*/
import { state, el, parseDbc, rebuildMergedDbc } from './dbc.js?v=20260717x';
import { state, el, parseDbc, rebuildMergedDbc } from './dbc.js';
var LS_KEY = 'dcu_can_session_v1';
var MAX_HISTORY = 200;
+6 -6
View File
@@ -12,12 +12,12 @@
* 注意:formatTime 保留本地实现(HH:MM:SS,不含毫秒),与 common/utils.js
* 的 formatTime(含毫秒)不同,以保证发送历史时间戳输出格式一致。
*/
import { state, el, getBaseUrl, padHex, bytesToHex, parseNumericId } from './dbc.js?v=20260717x';
import { escapeHtml } from '../common/utils.js?v=20260717x';
import { showToast } from '../common/toast.js?v=20260717x';
import { updateBatchUi } from './messages.js?v=20260717x';
import { ensureMessageDefaults, getSignalValueMap, getSelectedMessage, updateEncodedPreview, encodeMessageData } from './signals.js?v=20260717x';
import { scheduleCanPersist } from './persist.js?v=20260717x';
import { state, el, getBaseUrl, padHex, bytesToHex, parseNumericId } from './dbc.js';
import { escapeHtml } from '../common/utils.js';
import { showToast } from '../common/toast.js';
import { updateBatchUi } from './messages.js';
import { ensureMessageDefaults, getSignalValueMap, getSelectedMessage, updateEncodedPreview, encodeMessageData } from './signals.js';
import { scheduleCanPersist } from './persist.js';
// ==================== 本地工具(保持与原 can.js 一致) ====================
function formatTime(date) {
+3 -3
View File
@@ -5,9 +5,9 @@
*
* 依赖:dbc.js(state/el/padHex/bytesToHex/cssEscape/findSignal)、common/utils.js(escapeHtml)。
*/
import { state, el, padHex, bytesToHex, cssEscape, findSignal, findMessageByKey } from './dbc.js?v=20260717x';
import { escapeHtml as sanitizeHtml } from '../common/utils.js?v=20260717x';
import { scheduleCanPersist } from './persist.js?v=20260717x';
import { state, el, padHex, bytesToHex, cssEscape, findSignal, findMessageByKey } from './dbc.js';
import { escapeHtml as sanitizeHtml } from '../common/utils.js';
import { scheduleCanPersist } from './persist.js';
// ==================== 信号值存取 ====================
/** @description 确保报文有 signalValues bag,并为每个信号填充默认值。返回 bag。 */
+1 -1
View File
@@ -1,7 +1,7 @@
/**
* can_monitor.js - CAN 接收监控(独立页 can_monitor.html 与 can.html 右侧抽屉共用)
*/
import { showToast } from './common/toast.js?v=20260717x';
import { showToast } from './common/toast.js';
import { escapeHtml } from './common/utils.js';
var state = { fbTimer: null, fbInFlight: false };
+34
View File
@@ -0,0 +1,34 @@
/**
* base-url.js - 设备 IP / 基础 URL 公共助手
*
* 各页面共用 localStorage key dcu_esp_ip(OTA / CAN / 电机页一致)。
* 本模块只提供纯 localStorage + 默认值的通用实现;页面特有的输入框回退
* (如 CAN 页 el.toolIp、OTA 页 #espIp)由各自入口在此基础上包装。
*/
export var LS_ESP_IP = 'dcu_esp_ip';
export var DEFAULT_ESP_IP = '192.168.31.127';
/** @description 读取 localStorage 中保存的设备 IP,无有效值返回空串。 */
export function getSavedDeviceIp() {
try {
var saved = localStorage.getItem(LS_ESP_IP);
if (saved && saved.trim()) return saved.trim();
} catch (_) {}
return '';
}
/** @description 保存设备 IP 到 localStorage(空值忽略)。 */
export function saveDeviceIp(ip) {
if (!ip || !String(ip).trim()) return;
try { localStorage.setItem(LS_ESP_IP, String(ip).trim()); } catch (_) {}
}
/** @description 设备 IP:localStorage 优先,否则默认值。 */
export function getDeviceIp() {
return getSavedDeviceIp() || DEFAULT_ESP_IP;
}
/** @description 拼接设备基础 URL(http://<ip>)。 */
export function getBaseUrl() {
return 'http://' + getDeviceIp();
}
File diff suppressed because it is too large Load Diff
+3 -3346
View File
File diff suppressed because it is too large Load Diff