feat: 添加蓝牙指示灯(b6)控制

led.js: 新增 BtLed 类,路径 /sys/devices/platform/openvfd/attr/b6
  - blink() AP 配网进行中
  - on()    配网成功 / WiFi 已连接
  - off()   蓝牙不工作 / 初始/停止状态

provisioning.js: 各配网状态同步驱动 BT 灯
  - AP 模式 / 等待自动重连 → 闪烁
  - WiFi 连接成功 → 常亮
  - stop() → 熄灭

Made-with: Cursor
This commit is contained in:
stswangzhiping
2026-03-24 22:58:10 +08:00
parent 935d5ba176
commit 37e93c66eb
2 changed files with 99 additions and 12 deletions

View File

@@ -12,15 +12,21 @@ const log = require('./logger');
* - WiFi 连接中(正在尝试) → 闪烁
* - WiFi 未连接 / 无互联网 → 熄灭
*
* BT 灯 (b6): 1 = 亮, 0 = 灭(正逻辑)
* - BLE 配网进行中 → 闪烁
* - BLE 配网成功 → 常亮
* - 蓝牙不工作 → 熄灭
*
* SETUP 灯 (b2): 0 = 亮, 1 = 灭(反逻辑,与 APPS 互斥)
* APPS 灯 (b1): 0 = 亮, 1 = 灭(反逻辑,与 SETUP 互斥)
* - claw 未激活 → SETUP 亮APPS 灭
* - claw 已激活 → APPS 亮SETUP 灭
*/
const LED_PATH = process.env.CLAWD_LED_PATH || '/sys/devices/platform/openvfd/attr/b5';
const SETUP_LED_PATH = '/sys/devices/platform/openvfd/attr/b1'; // 物理 SETUP 灯
const APPS_LED_PATH = '/sys/devices/platform/openvfd/attr/b2'; // 物理 APPS
const LED_PATH = process.env.CLAWD_LED_PATH || '/sys/devices/platform/openvfd/attr/b5';
const BT_LED_PATH = process.env.CLAWD_BT_LED_PATH || '/sys/devices/platform/openvfd/attr/b6';
const SETUP_LED_PATH = '/sys/devices/platform/openvfd/attr/b1'; // 物理 SETUP
const APPS_LED_PATH = '/sys/devices/platform/openvfd/attr/b2'; // 物理 APPS 灯
const BLINK_INTERVAL_MS = 500; // 闪烁间隔ms
class WifiLed {
@@ -87,6 +93,76 @@ class WifiLed {
}
}
// ── 蓝牙指示灯 ───────────────────────────────────────────────────────────────
/**
* BT 指示灯b6正逻辑1 = 亮0 = 灭。
* blink() — BLE 配网进行中
* on() — BLE 配网成功 / 蓝牙功能正常
* off() — 蓝牙不工作
*/
class BtLed {
constructor() {
this._blinkTimer = null;
this._blinkState = false;
this._current = null; // 'on' | 'off' | 'blink'
}
/** 常亮(配网成功) */
on() {
if (this._current === 'on') return;
this._stopBlink();
this._write(1);
this._current = 'on';
log.info('led', 'BT 指示灯 → 常亮');
}
/** 熄灭(蓝牙不工作) */
off() {
if (this._current === 'off') return;
this._stopBlink();
this._write(0);
this._current = 'off';
log.info('led', 'BT 指示灯 → 熄灭');
}
/** 闪烁BLE 配网进行中) */
blink(intervalMs = BLINK_INTERVAL_MS) {
if (this._current === 'blink') return;
this._stopBlink();
this._blinkState = true;
this._write(1);
this._blinkTimer = setInterval(() => {
this._blinkState = !this._blinkState;
this._write(this._blinkState ? 1 : 0);
}, intervalMs);
this._current = 'blink';
log.info('led', 'BT 指示灯 → 闪烁');
}
/** 释放资源,关灯 */
destroy() {
this._stopBlink();
this._write(0);
this._current = 'off';
}
_stopBlink() {
if (this._blinkTimer) {
clearInterval(this._blinkTimer);
this._blinkTimer = null;
}
}
_write(val) {
try {
fs.writeFileSync(BT_LED_PATH, String(val));
} catch (e) {
log.warn('led', `写入失败 (${BT_LED_PATH}): ${e.message}`);
}
}
}
// ── VFD 显示屏 ────────────────────────────────────────────────────────────────
const DISPLAY_PATH = '/sys/devices/platform/openvfd/attr/led';
@@ -207,5 +283,6 @@ class StatusLed {
// 全局单例,整个进程共用
module.exports = new WifiLed();
module.exports.bt = new BtLed();
module.exports.status = new StatusLed();
module.exports.display = new Display();