diff --git a/install.sh b/install.sh index 5fb4968..fe9922b 100644 --- a/install.sh +++ b/install.sh @@ -189,8 +189,6 @@ Wants=NetworkManager.service [Service] Type=simple EnvironmentFile=$ENV_FILE -# 部分机型无 openvfd 或路径不同;不存在则跳过(3528 等新板可忽略) -ExecStartPre=/bin/sh -c 'for p in /sys/devices/platform/openvfd/attr/b1 /sys/devices/platform/openvfd/attr/b2; do [ -e "$p" ] && echo 1 >"$p" 2>/dev/null || true; done' ExecStart=$NODE_BIN $INSTALL_DIR/bin/clawd.js WorkingDirectory=$INSTALL_DIR diff --git a/lib/led.js b/lib/led.js index 31655db..a05d78e 100644 --- a/lib/led.js +++ b/lib/led.js @@ -1,42 +1,27 @@ 'use strict'; -const fs = require('fs'); -const { execSync } = require('child_process'); -const log = require('./logger'); +const log = require('./logger'); /** - * 前面板指示灯控制 - * - * WiFi 灯 (b5): 1 = 亮, 0 = 灭(正逻辑) - * - WiFi 已连接且互联网畅通 → 常亮 - * - WiFi 连接中(正在尝试) → 闪烁 - * - WiFi 未连接 / 无互联网 → 熄灭 + * 前面板指示灯 / VFD 逻辑(原 openvfd sysfs)。 + * 硬件路径因板型而异,当前不直接写 sysfs:仅在 debug 记录拟写入内容,业务状态仍以 info 输出。 * + * WiFi 灯 (b5): 1 = 亮, 0 = 灭(正逻辑) * BT 灯 (b6): 1 = 亮, 0 = 灭(正逻辑) - * - BLE 配网进行中 → 闪烁 - * - BLE 配网成功 → 常亮 - * - 蓝牙不工作 → 熄灭 + * SETUP/APPS (b1/b2): 反逻辑,与 claw 激活状态互斥 * - * SETUP 灯 (b2): 0 = 亮, 1 = 灭(反逻辑,与 APPS 互斥) - * APPS 灯 (b1): 0 = 亮, 1 = 灭(反逻辑,与 SETUP 互斥) - * - claw 未激活 → SETUP 亮,APPS 灭 - * - claw 已激活 → APPS 亮,SETUP 灭 + * 恢复真机显示时:可在此类 _write 中接新驱动或 CLAWD_* 路径。 */ -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) +const BLINK_INTERVAL_MS = 500; class WifiLed { constructor() { this._blinkTimer = null; this._blinkState = false; - this._current = null; // 'on' | 'off' | 'blink' + this._current = null; } - /** 常亮 */ on() { if (this._current === 'on') return; this._stopBlink(); @@ -45,7 +30,6 @@ class WifiLed { log.info('led', 'WiFi 指示灯 → 常亮'); } - /** 熄灭 */ off() { if (this._current === 'off') return; this._stopBlink(); @@ -54,7 +38,6 @@ class WifiLed { log.info('led', 'WiFi 指示灯 → 熄灭'); } - /** 闪烁(连接中) */ blink(intervalMs = BLINK_INTERVAL_MS) { if (this._current === 'blink') return; this._stopBlink(); @@ -68,15 +51,12 @@ class WifiLed { log.info('led', 'WiFi 指示灯 → 闪烁'); } - /** 释放资源,关灯 */ destroy() { this._stopBlink(); this._write(0); this._current = 'off'; } - // ── 内部 ────────────────────────────────────────────────────────────────── - _stopBlink() { if (this._blinkTimer) { clearInterval(this._blinkTimer); @@ -85,30 +65,17 @@ class WifiLed { } _write(val) { - try { - fs.writeFileSync(LED_PATH, String(val)); - } catch (e) { - log.warn('led', `写入失败 (${LED_PATH}): ${e.message}`); - } + log.debug('led', `[vfd] WiFi LED (b5) <= ${val}`); } } -// ── 蓝牙指示灯 ─────────────────────────────────────────────────────────────── - -/** - * BT 指示灯(b6)正逻辑:1 = 亮,0 = 灭。 - * blink() — BLE 配网进行中 - * on() — BLE 配网成功 / 蓝牙功能正常 - * off() — 蓝牙不工作 - */ class BtLed { constructor() { this._blinkTimer = null; this._blinkState = false; - this._current = null; // 'on' | 'off' | 'blink' + this._current = null; } - /** 常亮(配网成功) */ on() { if (this._current === 'on') return; this._stopBlink(); @@ -117,7 +84,6 @@ class BtLed { log.info('led', 'BT 指示灯 → 常亮'); } - /** 熄灭(蓝牙不工作) */ off() { if (this._current === 'off') return; this._stopBlink(); @@ -126,7 +92,6 @@ class BtLed { log.info('led', 'BT 指示灯 → 熄灭'); } - /** 闪烁(BLE 配网进行中) */ blink(intervalMs = BLINK_INTERVAL_MS) { if (this._current === 'blink') return; this._stopBlink(); @@ -140,7 +105,6 @@ class BtLed { log.info('led', 'BT 指示灯 → 闪烁'); } - /** 释放资源,关灯 */ destroy() { this._stopBlink(); this._write(0); @@ -155,36 +119,21 @@ class BtLed { } _write(val) { - try { - fs.writeFileSync(BT_LED_PATH, String(val)); - } catch (e) { - log.warn('led', `写入失败 (${BT_LED_PATH}): ${e.message}`); - } + log.debug('led', `[vfd] BT LED (b6) <= ${val}`); } } -// ── VFD 显示屏 ──────────────────────────────────────────────────────────────── - -const DISPLAY_PATH = '/sys/devices/platform/openvfd/attr/led'; - -/** - * VFD 显示屏控制。 - * #m3 手动模式,显示指定文字 - * #s1 系统时钟模式,显示当前时间 - */ class Display { constructor() { this._blinkTimer = null; } - /** 网络断开 / AP 模式 → 显示 "AP " */ showAP() { this._stopBlink(); this._write('#m3AP '); log.info('display', '显示屏 → AP'); } - /** WS 连接中(失败次数 < 3)→ 显示 "Conn" 闪烁 */ showConn() { this._stopBlink(); this._write('#m3Conn'); @@ -198,27 +147,23 @@ class Display { this._blinkTimer = setTimeout(blink, 1000); } - /** 网络正常但 VPS 不可达 → 显示 "Err0" */ showErr0() { this._stopBlink(); this._write('#m3Err0'); log.info('display', '显示屏 → Err0'); } - /** 网络已连接 → 显示时间 */ showTime() { this._stopBlink(); this._write('#s1'); log.info('display', '显示屏 → 时间'); } - /** 未激活 + 连网 → 显示 PIN 码(4 位数字)并闪烁 */ showPin(pin) { this._stopBlink(); const s = String(pin || '').padStart(4, '0').slice(-4); this._write('#m2' + s); log.info('display', `显示屏 → PIN: ${s}(闪烁)`); - // 亮 1s → 灭 0.5s → 循环 let visible = true; const blink = () => { visible = !visible; @@ -237,51 +182,33 @@ class Display { } _write(val) { - try { - execSync(`echo "${val}" | tee ${DISPLAY_PATH} > /dev/null`, { timeout: 3000 }); - } catch (e) { - log.warn('display', `写入失败: ${e.message}`); - } + log.debug('display', `[vfd] ${val}`); } } -// ── SETUP / APPS 状态灯 ─────────────────────────────────────────────────────── - -/** - * SETUP 灯(b2)与 APPS 灯(b1)互斥控制。 - * 两灯均为反逻辑:写 0 = 亮,写 1 = 灭。 - */ class StatusLed { - /** claw 未激活 → SETUP 亮,APPS 灭 */ setSetup() { - this._write(SETUP_LED_PATH, 0); // SETUP 亮 - this._write(APPS_LED_PATH, 1); // APPS 灭 + this._write('SETUP', 0); + this._write('APPS', 1); log.info('led', '状态灯 → SETUP(未激活)'); } - /** claw 已激活 → APPS 亮,SETUP 灭 */ setApps() { - this._write(SETUP_LED_PATH, 1); // SETUP 灭 - this._write(APPS_LED_PATH, 0); // APPS 亮 + this._write('SETUP', 1); + this._write('APPS', 0); log.info('led', '状态灯 → APPS(已激活)'); } - /** 两灯全灭(进程退出时调用) */ off() { - this._write(SETUP_LED_PATH, 1); - this._write(APPS_LED_PATH, 1); + this._write('SETUP', 1); + this._write('APPS', 1); } - _write(path, val) { - try { - fs.writeFileSync(path, String(val)); - } catch (e) { - log.warn('led', `写入失败 (${path}): ${e.message}`); - } + _write(which, val) { + log.debug('led', `[vfd] 状态灯 ${which} (b1/b2 反逻辑) <= ${val}`); } } -// 全局单例,整个进程共用 module.exports = new WifiLed(); module.exports.bt = new BtLed(); module.exports.status = new StatusLed();