Commit Graph
74 Commits
Author SHA1 Message Date
stswangzhiping 85026cdf47 docs: add repo paths and module overview table to README
Made-with: Cursor
2026-03-27 10:16:18 +08:00
stswangzhiping 837cb8865f 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
2026-03-24 23:14:02 +08:00
stswangzhiping dcc20e2cad fix: BT 灯仅在搜索热点和连接热点时闪烁
等待 NM 自动重连已保存 WiFi 不属于 BLE 搜索/连接阶段,
该阶段 BT 灯保持熄灭,不再闪烁。

Made-with: Cursor
2026-03-24 23:00:07 +08:00
stswangzhiping 37e93c66eb 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
2026-03-24 22:58:10 +08:00
stswangzhiping 935d5ba176 fix: 用 js-yaml 正确解析 config.yaml 获取 dashboard token
替换正则提取方式,使用 js-yaml 解析 YAML 文件,
通过 config.gateway.auth.token 和 config.gateway.port 读取字段。

Made-with: Cursor
2026-03-24 17:00:33 +08:00
stswangzhiping cdb2ddc688 fix: getDashboardInfo 改为读取 config.yaml
openclaw 配置文件路径从 openclaw.json 迁移到
config/config.yaml,用正则提取 token 和 port 字段。

Made-with: Cursor
2026-03-24 16:47:35 +08:00
stswangzhiping 7c03a59c57 refactor: 重构 OpenClaw config.yaml 更新逻辑
- _configureOpenClaw 改名为 _updateOpenClawOrigin(targetId)
- active 时传真实 claw_id,inactive 时传 '0000'
- 每次 _applyStatus(含 status_update)都调用,文件无变化则幂等跳过
- 有变化时 pkill -9 -x openclaw-gateway,不再依赖 openclaw CLI 或 systemctl --user
- 移除 _openClawConfigured 标志位

Made-with: Cursor
2026-03-24 16:22:05 +08:00
stswangzhiping 4a1a2de300 fix: only run configureOpenClaw once per clawId, not on every WS reconnect
Made-with: Cursor
2026-03-24 14:31:31 +08:00
stswangzhiping 029f7fe0a9 fix: edit openclaw config.yaml directly and restart as sts user
Made-with: Cursor
2026-03-24 14:07:22 +08:00
stswangzhiping 1a63e90055 fix: use full path to find openclaw binary for root service
Made-with: Cursor
2026-03-24 13:13:00 +08:00
stswangzhiping cefbab28b7 feat: configure openclaw allowedOrigins on activation
Made-with: Cursor
2026-03-24 11:38:58 +08:00
stswangzhiping ffa13b7c81 fix: captive portal 改用 IP 地址 10.42.0.1 替代域名
Made-with: Cursor
2026-03-22 08:04:20 +08:00
stswangzhiping 4716cc9820 fix: replace unstable disk serial with wired MAC for hardware fingerprint
Made-with: Cursor
2026-03-22 07:38:05 +08:00
stswangzhiping 86859a5e0d fix: 过滤AP热点IP,改用checkip.amazonaws.com获取外网IP,新增ipplus360地理位置
Made-with: Cursor
2026-03-21 09:20:00 +08:00
stswangzhiping 878f3592bf feat: connect 消息上报 local_ip 和 external_ip
Made-with: Cursor
2026-03-21 08:18:27 +08:00
stswangzhiping af5248f2a6 fix: emit network-ready immediately when wired internet available, setup AP async
Made-with: Cursor
2026-03-20 08:41:39 +08:00
stswangzhiping 108bea4ed7 fix: use fixed 5s retry on cert-not-yet-valid to avoid 70s exponential backoff before NTP sync
Made-with: Cursor
2026-03-20 08:34:53 +08:00
stswangzhiping d3bd5ca3e7 fix: replace network-online.target with NetworkManager.service to avoid 60s+ startup delay
Made-with: Cursor
2026-03-20 08:28:55 +08:00
stswangzhiping e94e2bb10c fix: add AP net monitor to detect cable unplug within 5s, reduce ping interval to 10s
Made-with: Cursor
2026-03-20 08:14:31 +08:00
stswangzhiping 5ba8b7bffa fix: fast-path hasInternet() via carrier check to avoid nmcli cache delay
Made-with: Cursor
2026-03-20 08:00:25 +08:00
stswangzhiping 08fa4eefaa feat: skip WS in AP+no-internet, poll every 5s until network available
Made-with: Cursor
2026-03-20 07:43:51 +08:00
stswangzhiping c13ed3ba6d fix(vfd): use isApMode() instead of hasInternet() to decide AP vs Err0
Made-with: Cursor
2026-03-19 23:45:16 +08:00
stswangzhiping 8f158eeeb2 fix: turn off LEDs on service start, suppress Err0 before first WS success
Made-with: Cursor
2026-03-19 23:27:42 +08:00
stswangzhiping 9b4287db1d feat(vfd): showConn blink on WS connecting, showErr0 on VPS unreachable
Made-with: Cursor
2026-03-19 23:17:08 +08:00
stswangzhiping 53b9804c72 feat(led): showErr(code) + WS fail>=3 shows ERRa or AP on VFD
Made-with: Cursor
2026-03-19 22:44:56 +08:00
stswangzhiping e36bec8660 refactor(led): startup all-off, AP shows VFD, WS close no VFD change
Made-with: Cursor
2026-03-19 22:08:47 +08:00
stswangzhiping d68d673cdc perf(heartbeat): 10s interval, collect metrics every 3rd beat (30s)
Made-with: Cursor
2026-03-19 09:58:48 +08:00
stswangzhiping 5824cf089a feat(ws): unified status_update handler, extract _applyStatus()
Made-with: Cursor
2026-03-19 09:43:29 +08:00
stswangzhiping 16f82d6ab8 feat(ws): handle activated message from server, switch to APPS+time
Made-with: Cursor
2026-03-19 09:24:10 +08:00
stswangzhiping fba9d401c2 feat(display): PIN 显示时加闪烁效果(亮1s灭0.5s)
Made-with: Cursor
2026-03-19 09:13:07 +08:00
stswangzhiping b4fa850445 feat(display): PIN 改为 4 位,showPinMiddle4 → showPin
Made-with: Cursor
2026-03-19 08:57:44 +08:00
stswangzhiping ce7f9f028e fix(display): 改用 #m2 模式显示 PIN 数字,修复 #m3 不支持数字导致的显示错误
Made-with: Cursor
2026-03-19 08:52:52 +08:00
stswangzhiping 33046948b9 fix(display): 用 printf 代替 echo,修复 VFD 写入失败及数字显示偏移问题
Made-with: Cursor
2026-03-19 08:37:00 +08:00
stswangzhiping e887f5b8e2 fix(display): 不在 ws.open 时 showTime,避免覆盖未激活时的 PIN 显示
Made-with: Cursor
2026-03-19 07:44:28 +08:00
stswangzhiping 57c0a1b6f8 feat(display): 未激活+连网时 VFD 显示 PIN 码中间4位
Made-with: Cursor
2026-03-19 07:37:57 +08:00
stswangzhiping cf2973946f fix(captive): 密码默认隐藏,眼睛图标初始为半透明
Made-with: Cursor
2026-03-18 21:54:40 +08:00
stswangzhiping 7d3477454c feat(captive): 密码框增加眼睛图标切换可见性
Made-with: Cursor
2026-03-18 21:35:28 +08:00
stswangzhiping 9e7dcada05 feat(captive): 将WiFi 网络改为请选择下列WiFi 网络
Made-with: Cursor
2026-03-18 21:26:58 +08:00
stswangzhiping 959a2b67f2 refactor(display): tie VFD display to WS connection state only
Made-with: Cursor
2026-03-18 21:17:36 +08:00
stswangzhiping a737101c2e fix(display): use execSync shell pipe instead of fs.writeFileSync to avoid EINVAL
Made-with: Cursor
2026-03-18 21:11:22 +08:00
stswangzhiping 9da4cd0aa1 feat: VFD display shows AP when disconnected, time when connected
Made-with: Cursor
2026-03-18 21:10:14 +08:00
stswangzhiping a0f767f267 fix(led): swap SETUP/APPS paths, WiFi LED off in AP mode
Made-with: Cursor
2026-03-18 20:56:49 +08:00
stswangzhiping 90bba5f348 feat: add SETUP/APPS status LEDs (b2/b1), toggle on activation
Made-with: Cursor
2026-03-18 20:25:54 +08:00
stswangzhiping 06b670d5ec docs: add update instructions using /opt/clawd
Made-with: Cursor
2026-03-18 20:09:44 +08:00
stswangzhiping b95e909d48 fix(led): use log.info for LED state, show write errors and hasInternet failures
Made-with: Cursor
2026-03-18 20:07:31 +08:00
stswangzhiping 875e69a454 feat: add WiFi LED indicator (openvfd b5)
Made-with: Cursor
2026-03-18 19:47:20 +08:00
stswangzhiping d66558c9de fix: read dashboard token from ~/.openclaw/openclaw.json instead of running openclaw dashboard command
Made-with: Cursor
2026-03-18 14:00:57 +08:00
stswangzhiping 5f5b976f5b fix: split su command into separate args for ttyd
Made-with: Cursor
2026-03-16 16:21:11 +08:00
stswangzhiping 9dc559a43a fix: run ttyd shell as normal user (sts) instead of root
Made-with: Cursor
2026-03-16 16:15:13 +08:00
stswangzhiping 17d0711f67 ui: redesign WiFi list with signal bars and cleaner layout
- Replace <select> with scrollable list of clickable items
- Show signal strength as 4-bar icon instead of percentage text
- Remove security info from parentheses, show lock icon only
- Smaller font size for compact mobile display

Made-with: Cursor
2026-03-16 13:11:23 +08:00
stswangzhiping c6f55c8c15 fix: pre-scan WiFi before entering AP mode
wlan0 cannot scan while in AP mode (hardware limitation).
Now scan nearby networks before starting hotspot and cache
the results for the captive portal page.

Made-with: Cursor
2026-03-16 13:04:00 +08:00
stswangzhiping 64f4050014 fix: EROFS dns config, double WS connection, and watchdog timeout
1. EROFS: install.sh pre-writes DNS hijack config to dnsmasq-shared.d
   since /etc may be read-only at runtime. dns-hijack.js gracefully
   falls back to checking if config already exists.

2. Double WS: add _connectionStarted guard to prevent _proceedWithConnection
   from being called twice (via event + hasInternet check).

3. Watchdog: move _startSdNotify() to start() beginning so READY=1
   is sent immediately, not delayed until network is ready.

Made-with: Cursor
2026-03-16 12:54:46 +08:00
stswangzhiping 9392f0f3d4 docs: add WiFi provisioning user manual to README
Made-with: Cursor
2026-03-16 12:45:10 +08:00
stswangzhiping 9d8af52bf4 fix: stop killing NM's dnsmasq - use dnsmasq-shared.d instead
Killing all dnsmasq processes caused NetworkManager to detect its
hotspot dnsmasq died and tear down the hotspot (AP appears briefly
then disappears).

Now leverage NM's built-in dnsmasq-shared.d config directory:
write DNS hijack config before starting AP so NM's own dnsmasq
picks it up. No separate dnsmasq process needed.

Made-with: Cursor
2026-03-16 12:40:19 +08:00
stswangzhiping f58db93b64 fix: wait for NM auto-reconnect before starting AP on reboot
After WiFi is configured and device reboots, NetworkManager needs
a few seconds to auto-connect to saved WiFi. Without waiting,
AP starts immediately and occupies wlan0, preventing NM reconnect.

- Add hasSavedWifiConnection() to check for saved WiFi profiles
- Wait up to 20s for NM auto-connect before falling back to AP
- First boot (no saved WiFi) still starts AP immediately

Made-with: Cursor
2026-03-16 12:27:25 +08:00
stswangzhiping b42e59fab8 feat: AP always-on mode - hotspot stays until WiFi STA connects
Redesign provisioning from one-shot blocking to persistent background manager:
- AP hotspot starts at boot regardless of eth0 status
- Captive portal runs alongside AP for WiFi configuration
- AP automatically shuts down only when WiFi STA connects
- WiFi drops at runtime -> AP auto-restarts
- WiFi connect fails -> AP auto-restarts for retry
- client.js no longer blocks on network; connects WS when ready

Made-with: Cursor
2026-03-16 12:18:35 +08:00
stswangzhiping dac68f78b4 fix: clawd-rfkill.service failed due to systemd $ expansion
systemd expands $rf as env var (empty), breaking the inline script.
Move rfkill logic to standalone script to avoid escaping issues.
Also use quoted heredoc to prevent bash expansion in install.sh.

Made-with: Cursor
2026-03-16 11:49:07 +08:00
stswangzhiping 7a80c03028 fix: kill NetworkManager's dnsmasq before starting our own
NetworkManager auto-starts its own dnsmasq when creating a hotspot,
which conflicts with our DNS-hijacking dnsmasq on the same interface.
Now kill ALL dnsmasq instances before starting ours.

Made-with: Cursor
2026-03-16 11:19:04 +08:00
stswangzhiping 92906bcd4b fix: set AP hotspot password to fixed WPA2 PSK "12345678"
Open network was not viable as nmcli generates random password by default.
Use a simple fixed password since the AP is only for short-lived provisioning.

Made-with: Cursor
2026-03-16 10:44:26 +08:00
stswangzhiping 8a6e5b3666 fix: dnsmasq path detection and WiFi rfkill persistence
- dns-hijack.js: replace `which` with multi-path search (/usr/sbin etc.)
  since dnsmasq is often not in normal user PATH
- install.sh: auto-enable NetworkManager for WiFi provisioning
- install.sh: unblock WiFi rfkill at install time
- install.sh: create clawd-rfkill.service for persistent boot-time unlock

Made-with: Cursor
2026-03-16 10:06:30 +08:00
stswangzhiping eb9f4ab1c3 feat: add WiFi provisioning for headless devices (AP + Captive Portal)
- Add lib/network.js: WiFi scan, connect, AP hotspot via nmcli
- Add lib/dns-hijack.js: dnsmasq management for DNS hijack + DHCP
- Add lib/captive-server.js: embedded HTTP captive portal with WiFi setup page
- Add lib/provisioning.js: orchestrator (detect network -> AP mode -> wait -> exit)
- Update client.js: call ensureNetwork() before WS connection
- Update install.sh: auto-install dnsmasq dependency

Made-with: Cursor
2026-03-16 08:58:51 +08:00
stswangzhiping b3770d21d4 feat: add structured logging, process watchdog, and systemd hardening
- Add lib/logger.js: timestamped structured logging with 5MB x 5 file rotation
- Add lib/watchdog.js: generic child process supervisor with rate-limited restarts
- Enhance client.js: WS ping/pong liveness detection, uncaughtException/unhandledRejection handlers, systemd sd-notify integration
- Refactor frpc.js: FrpcManager now delegates to Watchdog instead of manual spawn/exit
- Enhance install.sh: environment file, log directory, systemd resource limits, security hardening, WatchdogSec=60
- Replace all console.log/warn/error with structured logger across modules

Made-with: Cursor
2026-03-16 07:31:19 +08:00
stswangzhiping 42d1d361dc style(ttyd): enable cursor blink via client option
Made-with: Cursor
2026-03-15 23:25:36 +08:00
stswangzhiping 1ff9fd90e5 fix(ttyd): add -W writable and -i 127.0.0.1 flags
Made-with: Cursor
2026-03-15 23:22:05 +08:00
stswangzhiping 54476c82b6 fix(frpc): ttyd switch to tcp proxy to fix ws bidirectional issue
Made-with: Cursor
2026-03-15 22:55:27 +08:00
stswangzhiping c0c445b61d feat: add ttyd terminal support, parallel startup in frpc.js
Made-with: Cursor
2026-03-15 21:39:05 +08:00
stswangzhiping abf2cacac7 fix: use total-available for mem_used, aggregate real filesystems for disk
Made-with: Cursor
2026-03-15 21:29:51 +08:00
stswangzhiping f5ae8b0710 fix: use shell background + polling to get dashboard info reliably
Made-with: Cursor
2026-03-15 14:29:03 +08:00
stswangzhiping 64cd7432e1 fix: getDashboardInfo uses spawn+Promise to handle long-running process
Made-with: Cursor
2026-03-15 14:09:41 +08:00
stswangzhiping 516d0d26ee feat: integrate frpc manager and send dashboard info via WebSocket
Made-with: Cursor
2026-03-15 11:10:33 +08:00
stswangzhiping a9a7816e16 fix: show claw_id in activation box, remove noisy startup logs
Made-with: Cursor
2026-03-14 22:46:49 +08:00
stswangzhiping 3b7fc0c0d4 fix: combine machine-id+cpu+disk serial for box_id to prevent ghost clone collision
Made-with: Cursor
2026-03-14 22:21:13 +08:00
stswangzhiping aba21bf8b7 fix: replace MAC address with CPU serial / disk serial / DMI UUID for box_id
Made-with: Cursor
2026-03-14 21:18:57 +08:00
stswangzhiping 222c38a707 feat: initial clawd implementation - WebSocket daemon for claw box
Made-with: Cursor
2026-03-14 20:41:26 +08:00