feat: BtMonitor 监控 bluetoothctl 状态驱动 BT 指示灯

新增 lib/bt-monitor.js:
- 每 3 秒轮询 bluetoothctl show + hcitool con
- connected(ACL 连接存在)→ 常亮
- scanning/connecting(Discovering: yes)→ 闪烁
- 无 adapter / Powered: no / 静止 → 熄灭

client.js:启动时开启 BtMonitor,stop() 时清理
provisioning.js:移除所有 led.bt 调用,BT 灯统一由 BtMonitor 管理

Made-with: Cursor
This commit is contained in:
stswangzhiping
2026-03-24 23:14:02 +08:00
parent dcc20e2cad
commit 837cb8865f
3 changed files with 123 additions and 19 deletions

View File

@@ -35,14 +35,12 @@ class ProvisionManager extends EventEmitter {
isApMode() { return this._state === 'ap'; }
async start() {
led.off(); // WiFi 灯初始状态:熄灭
led.bt.off(); // BT 灯初始状态:熄灭
led.off(); // WiFi 灯初始状态:熄灭
// WiFi STA 已连接 → 直接进入 STA 模式
if (isWifiStaConnected()) {
this._state = 'sta';
log.info('provision', 'WiFi STA 已连接AP 不启动');
led.bt.on(); // 已配网BT 灯常亮
this._emitNetworkReady();
this._startMonitor();
return;
@@ -63,12 +61,10 @@ class ProvisionManager extends EventEmitter {
if (hasSavedWifiConnection()) {
log.info('provision', '发现已保存的 WiFi 配置,等待 NetworkManager 自动连接...');
led.blink(); // WiFi 灯:等待自动重连期间闪烁
// BT 灯:等待 NM 自动重连不属于 BLE 搜索/连接阶段,保持熄灭
const connected = await this._waitForWifiConnect();
if (connected) {
this._state = 'sta';
log.info('provision', 'WiFi 自动连接成功AP 不启动');
led.bt.on(); // 自动重连成功BT 灯常亮
this._emitNetworkReady();
this._startMonitor();
return;
@@ -118,8 +114,7 @@ class ProvisionManager extends EventEmitter {
this._stopMonitor();
this._stopAll();
this._state = 'idle';
led.destroy(); // WiFi 灯:停止时关灯、释放闪烁定时器
led.bt.destroy(); // BT 灯:停止时关灯
led.destroy(); // WiFi 灯:停止时关灯、释放闪烁定时器
}
// ── 进入 AP 模式 ─────────────────────────────────────────────────────────
@@ -127,8 +122,7 @@ class ProvisionManager extends EventEmitter {
_enterAP() {
if (this._state === 'ap') return;
led.off(); // AP 模式WiFi 未连接WiFi 灯熄灭
led.bt.blink(); // AP 模式BLE 配网进行中BT 灯闪烁
led.off(); // AP 模式WiFi 未连接WiFi 灯熄灭
if (!hasInternet()) led.display.showAP(); // 无网时立即显示 AP有线时等 WS 连接后再定
try {
@@ -174,14 +168,13 @@ class ProvisionManager extends EventEmitter {
if (result.success) {
this._state = 'sta';
log.info('provision', `WiFi 已连接: ${ssid}`);
led.on(); // WiFi 灯:连接成功 → 常亮
led.bt.on(); // BT 灯:配网成功 → 常亮
led.on(); // WiFi 灯:连接成功 → 常亮
this.emit('network-ready');
return result;
}
log.warn('provision', `WiFi 连接失败: ${result.error},重新启动 AP`);
this._enterAP(); // _enterAP 内部会调用 led.off() / led.bt.blink()
this._enterAP();
return result;
}
@@ -203,7 +196,6 @@ class ProvisionManager extends EventEmitter {
log.info('provision', 'WiFi 已外部连接,关闭 AP');
this._stopAPServices();
this._state = 'sta';
led.bt.on(); // 外部连接成功BT 灯常亮
this.emit('network-ready');
}
@@ -211,13 +203,11 @@ class ProvisionManager extends EventEmitter {
if (this._state === 'sta') {
if (hasInternet()) {
led.on();
led.bt.on(); // 有网 → BT 灯常亮
} else {
led.off(); // WiFi 已连接但无互联网
led.bt.off(); // 无互联网时 BT 灯也熄灭
led.off(); // WiFi 已连接但无互联网
}
}
// AP 模式下 led/bt 已在 _enterAP() 中设置,无需重复操作
// AP 模式下 led 已在 _enterAP() 中熄灭,无需重复操作
}, MONITOR_INTERVAL_MS);
}