根目录原本平铺 7 个 HTML, 而 js/ 已按功能域分子目录, 两级结构不对称; 且自包含实验页与主功能页平级摆放, 看不出可随时删除。现按角色分三层: tabs.html 标签外壳留在根 = 工具入口 pages/ index / can / can_monitor / motor 主功能页 lab/ continuity_test / spi_test 自包含实验页(零外部依赖) scripts/ build_mem.bat 随迁修正(全部实跑验证): - pages/ 下 4 页共 22 处 css/js 引用加 ../ 前缀; 页面互链同目录无需改 - js/motor/main.js 的 Worker URL 改用 import.meta.url 解析: 原文档相对 路径 "js/motor/tick.worker.js" 在 pages/ 下会解析成 /pages/js/... 而 404, 静默退化到 setTimeout 兜底、丢失后台不节流能力(已验证旧写法 404) - tabs.html 的 TABS 登记新路径; pageToTab 改按文件名匹配, 旧版 localStorage 存的裸文件名(can.html)自动迁移到 pages/can.html - esp32_server.py: GET / 与 /index.html 302 到 /tabs.html(根下已无 index.html); 注入脚本的 ⌂ 主页判定基准由 index.html 改为 tabs.html - serve.bat 打印外壳与 OTA 页新地址; README 补目录结构与路径约定 验证: 39/39 静态资源 200, 7 页 200 且注入生效, 逐页解析引用 0 坏链, 路由 / 与 /index.html 302、未知页 404, node --check 与 py_compile 通过。
189 lines
11 KiB
HTML
189 lines
11 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>ESP32 CAN 接收监控</title>
|
||
<!-- 空 favicon:阻止浏览器自动请求 /favicon.ico(本地静态服务无此文件会 404) -->
|
||
<link rel="icon" href="data:,">
|
||
<link rel="stylesheet" href="../css/base.css?v=857f83a5">
|
||
<link rel="stylesheet" href="../css/layout.css?v=acd17001">
|
||
<link rel="stylesheet" href="../css/components.css?v=7bc7d5db">
|
||
<link rel="stylesheet" href="../css/can.css?v=c06f5688">
|
||
<link rel="stylesheet" href="../css/responsive.css?v=46449483">
|
||
</head>
|
||
<body class="can-page">
|
||
<div class="container can-container">
|
||
|
||
<header class="header-bar can-header">
|
||
<div class="header-brand">
|
||
<span class="dot-mark"></span>
|
||
<strong>ESP32 CAN 接收监控</strong>
|
||
</div>
|
||
<div class="header-status">
|
||
<span class="pill offline" id="monConnPill"><span class="indicator"></span><span id="monConnTxt">未连接</span></span>
|
||
<span class="pill" id="fbModePill">模式: --</span>
|
||
<span class="pill" id="fbPollStatus">轮询: 待连接</span>
|
||
</div>
|
||
<div class="header-sub can-header-actions">
|
||
<a class="pill can-link-pill" href="can.html">CAN 发送控制台</a>
|
||
<a class="pill can-link-pill" href="index.html">返回 OTA 控制台</a>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- ═══ 工作台 ═══ -->
|
||
<section class="card can-toolbar-card">
|
||
<div class="card-head"><span class="ico">🧰</span> 连接设置</div>
|
||
<div class="card-body">
|
||
<div class="can-toolbar-grid" style="grid-template-columns: minmax(260px, 1.2fr) 1fr;">
|
||
<div class="can-toolbar-block">
|
||
<label class="form-label" for="monIp">ESP32 IP</label>
|
||
<div class="input-group">
|
||
<input class="input" type="text" id="monIp" value="192.168.31.127" placeholder="输入 IP 地址">
|
||
<button class="btn btn-outline" id="monTestBtn" type="button">测试</button>
|
||
</div>
|
||
</div>
|
||
<div class="can-toolbar-block">
|
||
<label class="form-label">接收模式</label>
|
||
<div class="input-group">
|
||
<button class="btn btn-primary btn-sm" id="btnModeAllPass" type="button">全收模式</button>
|
||
<button class="btn btn-outline btn-sm" id="btnModeFilter" type="button">过滤模式</button>
|
||
<button class="btn btn-outline btn-sm" id="btnModeBridge" type="button" title="CAN0 收到的每一帧按原帧格式自动转发到 CAN1 与 CAN2">CAN0→1/2 桥接</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="can-toolbar-foot">
|
||
<div class="conn-indicator err" id="monConnIndicator">
|
||
<span class="light"></span>
|
||
<span id="monConnIndicatorTxt">等待连接测试</span>
|
||
</div>
|
||
<div class="helper-note" id="monHelper">
|
||
页面每 1 秒通过 <code>/can/feedback</code> 拉取三路 CAN 通道快照。无 RX 的通道显示 <b>空(无 RX)</b>。<br><b>桥接模式</b>:CAN0 收到的每一帧(11/29 位、FD、BRS)自动由 CAN1 与 CAN2 转发出去。
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ═══ 三路反馈 ═══ -->
|
||
<section class="card can-feedback-card">
|
||
<div class="card-head"><span class="ico">📊</span> 三路 CAN 通道反馈(1Hz)</div>
|
||
<div class="card-body">
|
||
<div class="feedback-grid">
|
||
<div class="feedback-channel collapsed" id="fbCh0">
|
||
<div class="feedback-ch-head" role="button" tabindex="0" title="点击展开/折叠详情">
|
||
<span class="ch-dot ch0"></span> CAN0
|
||
<span class="feedback-expand-caret">▾</span>
|
||
</div>
|
||
<div class="feedback-primary">
|
||
<div class="feedback-row"><span class="fb-label">状态</span><span class="fb-val" id="fb0State">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">接收数</span><span class="fb-val" id="fb0Rx">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">发送数</span><span class="fb-val" id="fb0Tx">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">丢帧</span><span class="fb-val" id="fb0Drop">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">错误</span><span class="fb-val" id="fb0Err">--</span></div>
|
||
</div>
|
||
<div class="feedback-detail">
|
||
<div class="feedback-row"><span class="fb-label">TEC</span><span class="fb-val" id="fb0Tec">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">REC</span><span class="fb-val" id="fb0Rec">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">总线状态</span><span class="fb-val" id="fb0Bus">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">最新ID</span><span class="fb-val mono" id="fb0LastId">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">DLC</span><span class="fb-val" id="fb0Dlc">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">FD/BRS/ESI</span><span class="fb-val" id="fb0Flags">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">Seq</span><span class="fb-val" id="fb0Seq">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">Δrx/s</span><span class="fb-val" id="fb0Delta">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">最新HEX</span><span class="fb-val mono fb-data-cell" id="fb0LastData">--</span></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="feedback-channel collapsed" id="fbCh1">
|
||
<div class="feedback-ch-head" role="button" tabindex="0" title="点击展开/折叠详情">
|
||
<span class="ch-dot ch1"></span> CAN1
|
||
<span class="feedback-expand-caret">▾</span>
|
||
</div>
|
||
<div class="feedback-primary">
|
||
<div class="feedback-row"><span class="fb-label">状态</span><span class="fb-val" id="fb1State">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">接收数</span><span class="fb-val" id="fb1Rx">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">发送数</span><span class="fb-val" id="fb1Tx">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">丢帧</span><span class="fb-val" id="fb1Drop">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">错误</span><span class="fb-val" id="fb1Err">--</span></div>
|
||
</div>
|
||
<div class="feedback-detail">
|
||
<div class="feedback-row"><span class="fb-label">TEC</span><span class="fb-val" id="fb1Tec">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">REC</span><span class="fb-val" id="fb1Rec">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">总线状态</span><span class="fb-val" id="fb1Bus">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">最新ID</span><span class="fb-val mono" id="fb1LastId">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">DLC</span><span class="fb-val" id="fb1Dlc">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">FD/BRS/ESI</span><span class="fb-val" id="fb1Flags">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">Seq</span><span class="fb-val" id="fb1Seq">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">Δrx/s</span><span class="fb-val" id="fb1Delta">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">最新HEX</span><span class="fb-val mono fb-data-cell" id="fb1LastData">--</span></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="feedback-channel collapsed" id="fbCh2">
|
||
<div class="feedback-ch-head" role="button" tabindex="0" title="点击展开/折叠详情">
|
||
<span class="ch-dot ch2"></span> CAN2
|
||
<span class="feedback-expand-caret">▾</span>
|
||
</div>
|
||
<div class="feedback-primary">
|
||
<div class="feedback-row"><span class="fb-label">状态</span><span class="fb-val" id="fb2State">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">接收数</span><span class="fb-val" id="fb2Rx">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">发送数</span><span class="fb-val" id="fb2Tx">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">丢帧</span><span class="fb-val" id="fb2Drop">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">错误</span><span class="fb-val" id="fb2Err">--</span></div>
|
||
</div>
|
||
<div class="feedback-detail">
|
||
<div class="feedback-row"><span class="fb-label">TEC</span><span class="fb-val" id="fb2Tec">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">REC</span><span class="fb-val" id="fb2Rec">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">总线状态</span><span class="fb-val" id="fb2Bus">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">最新ID</span><span class="fb-val mono" id="fb2LastId">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">DLC</span><span class="fb-val" id="fb2Dlc">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">FD/BRS/ESI</span><span class="fb-val" id="fb2Flags">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">Seq</span><span class="fb-val" id="fb2Seq">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">Δrx/s</span><span class="fb-val" id="fb2Delta">--</span></div>
|
||
<div class="feedback-row"><span class="fb-label">最新HEX</span><span class="fb-val mono fb-data-cell" id="fb2LastData">--</span></div>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ═══ 每 ID 快照表 ═══ -->
|
||
<section class="card" id="idSnapshotSection" style="margin-top:18px;">
|
||
<div class="card-head"><span class="ico">🔬</span> 每 ID 快照表(1Hz 刷新)
|
||
<div class="feedback-controls">
|
||
<select class="input" id="idsnapChannel" style="width:100px;">
|
||
<option value="0">CAN0</option>
|
||
<option value="1">CAN1</option>
|
||
<option value="2">CAN2</option>
|
||
</select>
|
||
<span class="pill" id="idsnapStatus">--</span>
|
||
</div>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="idsnap-table-wrap">
|
||
<table class="idsnap-table" id="idsnapTable">
|
||
<thead>
|
||
<tr>
|
||
<th>#</th><th>CAN ID</th><th>DLC</th>
|
||
<th>FD</th><th>BRS</th><th>ESI</th><th>数据 (HEX)</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="idsnapBody">
|
||
<tr><td colspan="7" class="status-empty">等待数据...</td></tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
</div>
|
||
|
||
<div class="toast" id="toast">
|
||
<span class="toast-ico" id="toastIco">✓</span>
|
||
<span id="toastMsg">操作成功</span>
|
||
</div>
|
||
|
||
<script type="module" src="../js/can_monitor.js?v=20260727a"></script>
|
||
</body>
|
||
</html> |