diff --git a/lib/led.js b/lib/led.js index d3e24f6..f41b6b8 100644 --- a/lib/led.js +++ b/lib/led.js @@ -11,7 +11,7 @@ function loadImpl() { if (forced) { name = forced; } else if (isRK3588()) { - name = 'noop'; + name = 'rk3588-lvgl'; } else if (isRK3566()) { name = 'rk3566'; } else { @@ -23,6 +23,10 @@ function loadImpl() { log.info('led', `LED/VFD backend → rk3566-openvfd (${model || 'unknown model'})`); return require('./led/rk3566-openvfd'); } + if (name === 'rk3588-lvgl' || name === '3588' || name === 'rk3588') { + log.info('led', `LED/VFD backend → rk3588-lvgl (${model || 'unknown model'})`); + return require('./led/rk3588-lvgl'); + } if (name === 'noop' || name === 'none' || name === 'off') { log.info('led', `LED/VFD backend → noop (${model || 'unknown model'})`); return require('./led/noop'); diff --git a/lib/led/rk3588-lvgl.js b/lib/led/rk3588-lvgl.js new file mode 100644 index 0000000..28cb85e --- /dev/null +++ b/lib/led/rk3588-lvgl.js @@ -0,0 +1,81 @@ +'use strict'; + +const fs = require('fs'); +const log = require('../logger'); + +const LVGL_CMD_FIFO = process.env.CLAWD_LVGL_CMD_FIFO || '/tmp/lvgl_cmd'; + +function writeLvglCommand(command) { + try { + const fd = fs.openSync(LVGL_CMD_FIFO, fs.constants.O_WRONLY | fs.constants.O_NONBLOCK); + fs.writeSync(fd, `${command}\n`); + fs.closeSync(fd); + return true; + } catch (e) { + log.warn('display', `lvgl cmd failed (${command}): ${e.message}`); + return false; + } +} + +class BasicLed { + constructor(name) { + this.name = name; + this._current = null; + } + on() { this._current = 'on'; log.debug('led', `[rk3588-lvgl] ${this.name} on`); } + off() { this._current = 'off'; log.debug('led', `[rk3588-lvgl] ${this.name} off`); } + blink() { this._current = 'blink'; log.debug('led', `[rk3588-lvgl] ${this.name} blink`); } + destroy() { this._current = 'off'; log.debug('led', `[rk3588-lvgl] ${this.name} destroy`); } +} + +class StatusLed { + setSetup() { log.debug('led', '[rk3588-lvgl] status setup'); } + setApps() { log.debug('led', '[rk3588-lvgl] status apps'); } + off() { log.debug('led', '[rk3588-lvgl] status off'); } +} + +class Display { + showAP() { + if (writeLvglCommand('show_text:AP')) { + log.info('display', '显示屏 → AP'); + } + } + + showConn() { + if (writeLvglCommand('show_text:Conn')) { + log.info('display', '显示屏 → Conn'); + } + } + + showErr0() { + if (writeLvglCommand('show_text:Err0')) { + log.info('display', '显示屏 → Err0'); + } + } + + showTime() { + if (writeLvglCommand('show_time')) { + log.info('display', '显示屏 → 时间'); + } + } + + showPin(pin) { + const s = String(pin || '').padStart(4, '0').slice(-4); + if (writeLvglCommand(`show_text:${s}`)) { + log.info('display', `显示屏 → PIN: ${s}`); + } + } +} + +class LanLed { + start() { log.debug('led', '[rk3588-lvgl] LAN start ignored'); } + stop() { log.debug('led', '[rk3588-lvgl] LAN stop ignored'); } +} + +const led = new BasicLed('wifi'); +led.bt = new BasicLed('bt'); +led.status = new StatusLed(); +led.display = new Display(); +led.lan = new LanLed(); + +module.exports = led;