fix(led): swap WiFi(play)/LAN(wifi+eth), LAN carrier via CLAWD_ETH_IFACE, faster alarm
- WifiLed drives play; LanLed drives wifi+eth pair (matches panel silkscreen) - hasLanCableCarrier(): CLAWD_ETH_IFACE-only carrier when set (reliable unplug) - LAN poll 1s; config.activated persisted for immediate setApps on boot/reconnect - setApps double vfdOn alarm after 50ms for slow OpenVFD - Clear activated + setSetup on credential errors - install.sh env comment for CLAWD_ETH_IFACE Made-with: Cursor
This commit is contained in:
@@ -171,6 +171,8 @@ CLAWD_LOG_FILE=1
|
||||
# CLAWD_DISABLE_BT=1
|
||||
# OpenVFD sysfs 根路径(默认 /sys/class/leds/openvfd)
|
||||
# CLAWD_OPENVFD_PATH=/sys/class/leds/openvfd
|
||||
# LAN 灯跟 carrier:务必设为实际以太网口(如 end0),拔网线才能可靠熄灭
|
||||
# CLAWD_ETH_IFACE=end0
|
||||
EOF
|
||||
info "环境变量文件已创建:$ENV_FILE ✓"
|
||||
fi
|
||||
|
||||
@@ -83,8 +83,11 @@ class ClawClient {
|
||||
async start() {
|
||||
log.info('clawd', `启动中... 服务器 = ${this._cfg.server}`);
|
||||
|
||||
// 启动时全灭,WS 连接后由 _applyStatus() 按实际状态设置
|
||||
// 启动时关 alarm;若本地已记为已激活,立即亮 pwr(不等首包 connected)
|
||||
led.status.off();
|
||||
if (this._cfg.activated) {
|
||||
led.status.setApps();
|
||||
}
|
||||
|
||||
this._startSdNotify();
|
||||
|
||||
@@ -213,6 +216,9 @@ class ClawClient {
|
||||
this._backoff = 1_000;
|
||||
this._wsFailCount = 0; // 连接成功,重置失败计数
|
||||
this._hasEverConnected = true; // 标记已成功连接过
|
||||
if (this._cfg.activated) {
|
||||
led.status.setApps();
|
||||
}
|
||||
this._sendConnect();
|
||||
this._startPing();
|
||||
// 显示由 _onConnected 根据 status 设置,不在此处提前 showTime
|
||||
@@ -332,12 +338,16 @@ class ClawClient {
|
||||
log.warn('clawd', '硬件指纹不符,清除凭证重新注册...');
|
||||
this._cfg.claw_id = null;
|
||||
this._cfg.token = null;
|
||||
this._cfg.activated = false;
|
||||
config.save(this._cfg);
|
||||
led.status.setSetup();
|
||||
} else if (msg.msg && msg.msg.includes('invalid')) {
|
||||
log.warn('clawd', '凭证无效,清除凭证重新注册...');
|
||||
this._cfg.claw_id = null;
|
||||
this._cfg.token = null;
|
||||
this._cfg.activated = false;
|
||||
config.save(this._cfg);
|
||||
led.status.setSetup();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -369,6 +379,8 @@ class ClawClient {
|
||||
|
||||
_applyStatus(msg) {
|
||||
if (msg.status === 'inactive') {
|
||||
this._cfg.activated = false;
|
||||
config.save(this._cfg);
|
||||
led.status.setSetup();
|
||||
led.display.showPin(msg.pin);
|
||||
const id = String(this._cfg.claw_id || '').padEnd(6);
|
||||
@@ -383,6 +395,8 @@ class ClawClient {
|
||||
log.info('clawd', '等待激活,心跳正常运行...');
|
||||
this._updateOpenClawOrigin('0000');
|
||||
} else {
|
||||
this._cfg.activated = true;
|
||||
config.save(this._cfg);
|
||||
led.status.setApps();
|
||||
led.display.showTime();
|
||||
log.info('clawd', `已激活 claw_id = ${this._cfg.claw_id}`);
|
||||
|
||||
@@ -17,6 +17,8 @@ const DEFAULTS = {
|
||||
claw_id: null,
|
||||
token: null,
|
||||
heartbeat_interval: 30, // 秒
|
||||
/** 云端已激活:用于启动/重连时立即点亮 alarm(pwr),不等首包 connected */
|
||||
activated: false,
|
||||
};
|
||||
|
||||
function load() {
|
||||
|
||||
25
lib/led.js
25
lib/led.js
@@ -2,15 +2,15 @@
|
||||
|
||||
const fs = require('fs');
|
||||
const log = require('./logger');
|
||||
const { hasWiredCarrier } = require('./network');
|
||||
const { hasLanCableCarrier } = require('./network');
|
||||
|
||||
/**
|
||||
* OpenVFD 图标:/sys/class/leds/openvfd/led_on|led_off(写入图标名)。
|
||||
*
|
||||
* 映射:
|
||||
* wifi + eth 同亮/同灭 → 产品 WiFi 灯
|
||||
* 映射(与面板丝印一致:play=WiFi 状态,wifi+eth=有线链路):
|
||||
* play → 产品 WiFi 灯(配网逻辑 on/off/blink)
|
||||
* wifi + eth 同亮/同灭 → LAN(有线插拔,见 hasLanCableCarrier / CLAWD_ETH_IFACE)
|
||||
* alarm → pwr(SETUP=灭 / APPS=亮)
|
||||
* play → lan(有线 carrier)
|
||||
* BT → 无 sysfs,仅日志
|
||||
*
|
||||
* 数码管(AP/Conn/时间等):仍仅 debug 输出,不接 sysfs。
|
||||
@@ -19,7 +19,7 @@ const { hasWiredCarrier } = require('./network');
|
||||
*/
|
||||
|
||||
const BLINK_INTERVAL_MS = 500;
|
||||
const LAN_POLL_MS = 3000;
|
||||
const LAN_POLL_MS = 1000;
|
||||
|
||||
const VFD_BASE = process.env.CLAWD_OPENVFD_PATH || '/sys/class/leds/openvfd';
|
||||
|
||||
@@ -100,8 +100,9 @@ class WifiLed {
|
||||
|
||||
_write(val) {
|
||||
const on = !!val;
|
||||
log.debug('led', `[vfd] WiFi(wifi+eth)<= ${on ? 1 : 0}`);
|
||||
vfdWifiPair(on);
|
||||
log.debug('led', `[vfd] WiFi(play)<= ${on ? 1 : 0}`);
|
||||
if (on) vfdOn('play');
|
||||
else vfdOff('play');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,6 +232,8 @@ class StatusLed {
|
||||
|
||||
setApps() {
|
||||
vfdOn('alarm');
|
||||
// 部分 OpenVFD 驱动单次写入生效慢,短延迟再写一次
|
||||
setTimeout(() => vfdOn('alarm'), 50);
|
||||
log.debug('led', '[vfd] alarm(pwr)<= 1');
|
||||
log.info('led', '状态灯 → APPS(已激活)');
|
||||
}
|
||||
@@ -257,20 +260,20 @@ class LanLed {
|
||||
clearInterval(this._timer);
|
||||
this._timer = null;
|
||||
}
|
||||
vfdOff('play');
|
||||
vfdWifiPair(false);
|
||||
this._current = null;
|
||||
}
|
||||
|
||||
_sync() {
|
||||
const up = hasWiredCarrier();
|
||||
const up = hasLanCableCarrier();
|
||||
if (up) {
|
||||
if (this._current !== 'on') {
|
||||
vfdOn('play');
|
||||
vfdWifiPair(true);
|
||||
this._current = 'on';
|
||||
log.info('led', 'LAN(有线 carrier)→ 亮');
|
||||
}
|
||||
} else if (this._current !== 'off') {
|
||||
vfdOff('play');
|
||||
vfdWifiPair(false);
|
||||
this._current = 'off';
|
||||
log.info('led', 'LAN(有线 carrier)→ 灭');
|
||||
}
|
||||
|
||||
@@ -62,6 +62,22 @@ function hasWiredCarrier() {
|
||||
return getWiredIfaceWithCarrier() !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* LAN 面板灯专用:若设置 CLAWD_ETH_IFACE,只认该口 carrier(拔网线必灭);
|
||||
* 未设置时退回 hasWiredCarrier()(可能受其它网口影响,建议在 box 上配置 end0 等)。
|
||||
*/
|
||||
function hasLanCableCarrier() {
|
||||
const explicit = process.env.CLAWD_ETH_IFACE;
|
||||
if (explicit) {
|
||||
try {
|
||||
return fs.readFileSync(`/sys/class/net/${explicit}/carrier`, 'utf8').trim() === '1';
|
||||
} catch (_) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return hasWiredCarrier();
|
||||
}
|
||||
|
||||
function _tryPingInternet() {
|
||||
try {
|
||||
run('ping -c 1 -W 3 8.8.8.8');
|
||||
@@ -312,6 +328,7 @@ function getLocalIps() {
|
||||
module.exports = {
|
||||
hasInternet,
|
||||
hasWiredCarrier,
|
||||
hasLanCableCarrier,
|
||||
hasWiredInternetProbe,
|
||||
getWiredIfaceWithCarrier,
|
||||
hasSavedWifiConnection,
|
||||
|
||||
Reference in New Issue
Block a user