feat(link): DeviceLink 外壳单例统一 ESP32/ECAT/BLE 健康态
各页只共用 IP、各自 fetch 导致同屏「已连接/连接失败」分裂。 外壳 Owner 轮询 /system/status 与 EtherCAT 状态,BroadcastChannel 广播快照;连接灯只认共享层,SPI 失败单独文案不覆盖设备离线。
This commit is contained in:
+37
-10
@@ -186,6 +186,31 @@
|
||||
var $ = function (id) { return document.getElementById(id); };
|
||||
var logBox = $("log");
|
||||
|
||||
/* DeviceLink 统一健康态(外壳 Owner 经 BroadcastChannel 广播)。
|
||||
SPI 0xA2 失败 ≠ 设备离线:灯只认共享层;命令错误单独文案。 */
|
||||
window.__pmSetConn = null;
|
||||
|
||||
function setConn(ok, text) {
|
||||
var p = $("pillConn");
|
||||
p.className = "pill " + (ok ? "online" : "offline");
|
||||
$("pillConnTxt").textContent = text;
|
||||
}
|
||||
window.__pmSetConn = setConn;
|
||||
|
||||
/** SPI/业务失败:不得把「设备离线」打红(除非共享层已判离线)。 */
|
||||
function setSpiFail(msg) {
|
||||
log(msg, "err");
|
||||
var dl = window.__pmDeviceLink;
|
||||
var s = dl && dl.getSnapshot ? dl.getSnapshot() : null;
|
||||
if (s && s.links && s.links.esp32 && s.links.esp32.online) {
|
||||
setConn(true, "设备在线 · SPI 失败");
|
||||
} else if (!s) {
|
||||
/* 无外壳/尚未收到快照:退回旧语义 */
|
||||
setConn(false, "连接失败 · 5s 后重试");
|
||||
}
|
||||
/* 有快照且 offline:留给 DeviceLink subscribe 刷新灯 */
|
||||
}
|
||||
|
||||
/* 与 js/common/base-url.js 同 key 同默认值:全局唯一设备 IP,不设独立连接区 */
|
||||
var LS_IP = "dcu_esp_ip", DEFAULT_IP = "192.168.31.127";
|
||||
function deviceIp() {
|
||||
@@ -302,11 +327,6 @@
|
||||
* 事务本身会唤醒睡眠中的芯片,轮询等于不停叫醒它);连败 3 次标红停轮。
|
||||
* pollGen:丢弃 enterMode/唤醒 之后仍在途的过期 1E 响应,避免竞态覆盖 UI。 ---- */
|
||||
var pollFail = 0, pollTimer = null, pollPaused = false, pollGen = 0;
|
||||
function setConn(ok, text) {
|
||||
var p = $("pillConn");
|
||||
p.className = "pill " + (ok ? "online" : "offline");
|
||||
$("pillConnTxt").textContent = text;
|
||||
}
|
||||
function bumpPollGen() { return ++pollGen; }
|
||||
/* 仅在确认芯片已离开睡眠(唤醒成功 / 读到 SLEEP_EN=0 / NRST)时清 flag */
|
||||
function markAwake() {
|
||||
@@ -336,7 +356,7 @@
|
||||
if (gen !== pollGen || pollPaused) return;
|
||||
pollFail++;
|
||||
if (pollFail >= 3) {
|
||||
setConn(false, "连接失败 · 5s 后重试");
|
||||
setSpiFail("SPI 轮询失败 ×3(IP " + deviceIp() + ")· 5s 后重试");
|
||||
pollTimer = setTimeout(probe, 5000);
|
||||
} else {
|
||||
pollTimer = setTimeout(pollOnce, 2000);
|
||||
@@ -359,8 +379,7 @@
|
||||
log("ESP32 可达: " + deviceIp() + "(未读 LAN9252,保持睡眠)", "ok");
|
||||
})
|
||||
.catch(function (e) {
|
||||
setConn(false, "连接失败 · 5s 后重试");
|
||||
log("连接失败: " + e.message + "(IP 取自 OTA 页的设备地址 " + deviceIp() + ")", "err");
|
||||
setSpiFail("ESP32 探测失败: " + e.message + "(IP " + deviceIp() + ")");
|
||||
pollTimer = setTimeout(probeEspOnly, 5000);
|
||||
});
|
||||
}
|
||||
@@ -374,8 +393,7 @@
|
||||
pollOnce();
|
||||
})
|
||||
.catch(function (e) {
|
||||
setConn(false, "连接失败 · 5s 后重试");
|
||||
log("连接失败: " + e.message + "(IP 取自 OTA 页的设备地址 " + deviceIp() + ")", "err");
|
||||
setSpiFail("ESP32 探测失败: " + e.message + "(IP " + deviceIp() + ")");
|
||||
pollTimer = setTimeout(probe, 5000);
|
||||
});
|
||||
}
|
||||
@@ -604,5 +622,14 @@
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<script type="module">
|
||||
import { deviceLink } from '../js/common/device-link.js?v=20260916a';
|
||||
window.__pmDeviceLink = deviceLink;
|
||||
deviceLink.subscribe(function (s) {
|
||||
if (!s || !s.links || !window.__pmSetConn) return;
|
||||
var e = s.links.esp32;
|
||||
window.__pmSetConn(!!e.online, e.online ? '已连接' : '离线');
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user