@zke-wuhu/agent-only-rgb 0.8.4 → 0.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +226 -231
- package/assets/SKILL.md +3 -4
- package/assets/ble_sop8.py +6 -6
- package/assets/firmware/manifest.json +1 -1
- package/assets/ota_client.py +370 -371
- package/assets/ota_source.py +11 -11
- package/assets/rgb-light.sh +1 -1
- package/assets/skill_hooks.json +2 -2
- package/package.json +50 -50
- package/setup.js +783 -847
- package/tests/interactive-install.js +11 -0
- package/tests/pty-install.py +12 -1
package/README.md
CHANGED
|
@@ -1,231 +1,226 @@
|
|
|
1
|
-
# 让 AI 干活的时候,桌上的灯带跟着变色
|
|
2
|
-
|
|
3
|
-
一块 SOP8 小板子,用 USB 插到电脑上。装一次,之后 AI 开始思考、等你回答、
|
|
4
|
-
干完活、出错,灯带会用不同颜色和节奏告诉你 —— 不用一直盯着屏幕。
|
|
5
|
-
|
|
6
|
-
**只有板子、没买灯带也能用**:板子上自带 1 颗灯,效果就跑在它上面。
|
|
7
|
-
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
## 我要准备什么
|
|
11
|
-
|
|
12
|
-
| | 说明 |
|
|
13
|
-
|---|---|
|
|
14
|
-
| 板子 | 手里这块,用 **USB 数据线**插电脑(有些线只能充电,会读不到设备) |
|
|
15
|
-
| 灯带 | 可选。WS2812 / SK6812,按灯带上的箭头方向接到板子的灯带接口;**灯珠多的时候按灯带说明单独供电**,别只靠 USB 口带 |
|
|
16
|
-
| 电脑 | Windows / macOS / Linux;需要 Python 3.7+ 和 Node.js 14+(安装器会自己找、自己装依赖) |
|
|
17
|
-
| AI 工具 | WorkBuddy / Claude Code / CodeBuddy / Trae 任选;用别的 AI 也可以在安装时自己填配置目录名;还可以**先只用命令行**,让灯先亮起来 |
|
|
18
|
-
| 驱动 | Windows / macOS 免驱;Linux 若提示权限不足,见下面「灯没亮?」 |
|
|
19
|
-
|
|
20
|
-
## 三步装好
|
|
21
|
-
|
|
22
|
-
**1)** 把板子用 USB 插到电脑上。
|
|
23
|
-
|
|
24
|
-
**2)** 在终端执行这一条:
|
|
25
|
-
|
|
26
|
-
```bash
|
|
27
|
-
npx @zke-wuhu/agent-only-rgb
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
它只会问你两件事:
|
|
31
|
-
|
|
32
|
-
- **外接灯带有几颗?** 没接就填 `0`;接了就填灯带上的灯珠数(最多 100)。
|
|
33
|
-
- **平时用哪个 AI?** 一路回车用推荐配置即可,也可以逐个时机挑,
|
|
34
|
-
或选「让我的 AI 自己决定」「我自己打字描述想要的效果」。
|
|
35
|
-
|
|
36
|
-
**3)** 看到灯从中间亮起来、向两边铺满 → 成了。
|
|
37
|
-
|
|
38
|
-
> 只要这一条命令。**不用 `npm i -g`、不用记安装路径、不用理解「钩子」是什么。**
|
|
39
|
-
> 以后所有操作都长这样:`npx @zke-wuhu/agent-only-rgb <命令>`。
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
|
54
|
-
|
|
55
|
-
|
|
|
56
|
-
|
|
|
57
|
-
|
|
|
58
|
-
|
|
|
59
|
-
|
|
|
60
|
-
|
|
|
61
|
-
|
|
|
62
|
-
|
|
|
63
|
-
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
npx @zke-wuhu/agent-only-rgb
|
|
153
|
-
npx @zke-wuhu/agent-only-rgb
|
|
154
|
-
npx @zke-wuhu/agent-only-rgb
|
|
155
|
-
npx @zke-wuhu/agent-only-rgb
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
npx @zke-wuhu/agent-only-rgb
|
|
171
|
-
npx @zke-wuhu/agent-only-rgb
|
|
172
|
-
npx @zke-wuhu/agent-only-rgb
|
|
173
|
-
npx @zke-wuhu/agent-only-rgb
|
|
174
|
-
npx @zke-wuhu/agent-only-rgb
|
|
175
|
-
npx @zke-wuhu/agent-only-rgb
|
|
176
|
-
npx @zke-wuhu/agent-only-rgb
|
|
177
|
-
npx @zke-wuhu/agent-only-rgb
|
|
178
|
-
npx @zke-wuhu/agent-only-rgb
|
|
179
|
-
npx @zke-wuhu/agent-only-rgb
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
`
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
## 依赖
|
|
228
|
-
|
|
229
|
-
- Python 3.7+;`hidapi`(USB 通道)、`bleak`(蓝牙通道)、`certifi`(HTTPS)
|
|
230
|
-
- Node.js 14+(只是启动器;实机操作都在 Python 脚本里)
|
|
231
|
-
- 所有脚本**不含任何密钥**,可以放心分发
|
|
1
|
+
# 让 AI 干活的时候,桌上的灯带跟着变色
|
|
2
|
+
|
|
3
|
+
一块 SOP8 小板子,用 USB 插到电脑上。装一次,之后 AI 开始思考、等你回答、
|
|
4
|
+
干完活、出错,灯带会用不同颜色和节奏告诉你 —— 不用一直盯着屏幕。
|
|
5
|
+
|
|
6
|
+
**只有板子、没买灯带也能用**:板子上自带 1 颗灯,效果就跑在它上面。
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 我要准备什么
|
|
11
|
+
|
|
12
|
+
| | 说明 |
|
|
13
|
+
|---|---|
|
|
14
|
+
| 板子 | 手里这块,用 **USB 数据线**插电脑(有些线只能充电,会读不到设备) |
|
|
15
|
+
| 灯带 | 可选。WS2812 / SK6812,按灯带上的箭头方向接到板子的灯带接口;**灯珠多的时候按灯带说明单独供电**,别只靠 USB 口带 |
|
|
16
|
+
| 电脑 | Windows / macOS / Linux;需要 Python 3.7+ 和 Node.js 14+(安装器会自己找、自己装依赖) |
|
|
17
|
+
| AI 工具 | WorkBuddy / Claude Code / CodeBuddy / Trae 任选;用别的 AI 也可以在安装时自己填配置目录名;还可以**先只用命令行**,让灯先亮起来 |
|
|
18
|
+
| 驱动 | Windows / macOS 免驱;Linux 若提示权限不足,见下面「灯没亮?」 |
|
|
19
|
+
|
|
20
|
+
## 三步装好
|
|
21
|
+
|
|
22
|
+
**1)** 把板子用 USB 插到电脑上。
|
|
23
|
+
|
|
24
|
+
**2)** 在终端执行这一条:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npx @zke-wuhu/agent-only-rgb
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
它只会问你两件事:
|
|
31
|
+
|
|
32
|
+
- **外接灯带有几颗?** 没接就填 `0`;接了就填灯带上的灯珠数(最多 100)。
|
|
33
|
+
- **平时用哪个 AI?** 一路回车用推荐配置即可,也可以逐个时机挑,
|
|
34
|
+
或选「让我的 AI 自己决定」「我自己打字描述想要的效果」。
|
|
35
|
+
|
|
36
|
+
**3)** 看到灯从中间亮起来、向两边铺满 → 成了。
|
|
37
|
+
|
|
38
|
+
> 只要这一条命令。**不用 `npm i -g`、不用记安装路径、不用理解「钩子」是什么。**
|
|
39
|
+
> 以后所有操作都长这样:`npx @zke-wuhu/agent-only-rgb <命令>`。
|
|
40
|
+
|
|
41
|
+
## 装完我能干嘛
|
|
42
|
+
|
|
43
|
+
在 AI 里(**把当前会话关掉、重新开一个**,技能才会加载)直接说人话:
|
|
44
|
+
|
|
45
|
+
> 「现在怎么样」 · 「晚上有点刺眼」 · 「关灯」 · 「演示一下」 · 「换个夜间风格」
|
|
46
|
+
|
|
47
|
+
不想开 AI,或者想先确认灯是好的,就在终端里:
|
|
48
|
+
|
|
49
|
+
| 想做的事 | 命令(`npx @zke-wuhu/agent-only-rgb` 后面加) |
|
|
50
|
+
|---|---|
|
|
51
|
+
| 现在什么状态、有没有问题 | `brief` |
|
|
52
|
+
| **灯不亮 / 排查问题** | `doctor` |
|
|
53
|
+
| 把所有灯效依次看一遍 | `demo` |
|
|
54
|
+
| 换风格 `pulse` / `night` / `focus` / `vivid` | `theme night` |
|
|
55
|
+
| **先预览某风格再决定切不切**(不写入) | `theme-demo night` |
|
|
56
|
+
| **整体快慢**(慢/正常/快,换主题保留) | `pace slow` / `pace normal` / `pace fast` |
|
|
57
|
+
| **主题内微调单个状态**(亮度/周期/颜色) | `tune working brightness 90`,`tune reset` 清空 |
|
|
58
|
+
| 整体调亮暗(1~100,掉电保持) | `brightness 50` |
|
|
59
|
+
| 直接说人话 | `say '太亮了'` |
|
|
60
|
+
| 重配「AI 什么时候亮什么灯」 | `hooks` |
|
|
61
|
+
| 灯珠数填错了 / 想改用的 AI | `install`(重跑一次) |
|
|
62
|
+
| 检查 / 升级板子固件 | `check` / `update` |
|
|
63
|
+
| 重新走一遍开箱向导 | `quickstart` |
|
|
64
|
+
|
|
65
|
+
完整命令表:`npx @zke-wuhu/agent-only-rgb --help`。
|
|
66
|
+
|
|
67
|
+
## 灯珠数:最容易填错的一步
|
|
68
|
+
|
|
69
|
+
板子上自带 **1 颗灯**,它固定是链上的第 0 颗:
|
|
70
|
+
|
|
71
|
+
- **没接外接灯带** → 填 `0`。这时板载那颗就是**唯一的效果显示器**,所有灯效跑在它上面。
|
|
72
|
+
- **接了 N 颗灯带** → 填 `N`(最多 100)。这时板载那颗只做设备自身状态指示
|
|
73
|
+
(升级 / 故障 / 等待),灯效跑在外接的 `N` 颗上;设备里存的链上总数是 `N+1`。
|
|
74
|
+
|
|
75
|
+
不确定填得对不对:装完跑一次 `demo` 或看开场那次铺满 ——
|
|
76
|
+
**灯应该一直亮到灯带最末端**。末端有灯不亮,就是颗数填少了;
|
|
77
|
+
还有一段永远不亮,多半是填多了或接线方向反了。改数字重跑 `install` 即可,
|
|
78
|
+
配置记在 `~/.agent-only-rgb.json`。
|
|
79
|
+
|
|
80
|
+
非交互环境(CI、管道)一律不猜、不改动设备里已有的数量。
|
|
81
|
+
|
|
82
|
+
## 灯没亮?按顺序查
|
|
83
|
+
|
|
84
|
+
1. **跑 `npx @zke-wuhu/agent-only-rgb doctor`** —— 它会逐项告诉你
|
|
85
|
+
缺哪个依赖、钩子有没有绑上、设备连没连上、AI 工具找到几个。
|
|
86
|
+
2. **读不到设备**:换一根确定能传数据的 USB 线、换一个电脑口;
|
|
87
|
+
终端里跑 `npx @zke-wuhu/agent-only-rgb info`,能打印固件版本就是连上了。
|
|
88
|
+
3. **Linux 提示权限不足**:加一条 udev 规则后重新插拔
|
|
89
|
+
(VID `1209` / PID `A002`):
|
|
90
|
+
```bash
|
|
91
|
+
echo 'SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="a002", MODE="0666", TAG+="uaccess"' \
|
|
92
|
+
| sudo tee /etc/udev/rules.d/99-ble-agent-rgb.rules
|
|
93
|
+
sudo udevadm control --reload-rules && sudo udevadm trigger
|
|
94
|
+
```
|
|
95
|
+
4. **灯亮了但只亮一小截 / 位置不对**:回到上面「灯珠数」,重跑 `install` 改数字。
|
|
96
|
+
5. **效果不对、或直接报错**:板子里的固件可能比较老,插着 USB 跑
|
|
97
|
+
`npx @zke-wuhu/agent-only-rgb update`,升级后重跑一次 `install`。
|
|
98
|
+
6. **终端命令都正常,但 AI 里说话没反应**:关掉当前 AI 会话重新开一个
|
|
99
|
+
(技能在会话启动时加载);再跑 `hooks` 确认绑定,或 `doctor` 看结果。
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
# 进阶:它到底做了什么
|
|
104
|
+
|
|
105
|
+
## 装在什么地方
|
|
106
|
+
|
|
107
|
+
安装器会:找到可用的 Python 3 → 装 `hidapi` / `bleak` / `certifi` →
|
|
108
|
+
在你选的 AI 工具的 `skills/agent-only-rgb/` 下装一份技能
|
|
109
|
+
(脚本 + 灯光配置 + 钩子声明)→ 写下灯珠数 → 按你的选择绑定钩子 →
|
|
110
|
+
连上板子自检、下发默认灯光档案、亮一次灯给你看。
|
|
111
|
+
|
|
112
|
+
**所有命令都转发到这份已安装的脚本**(`~/.agent-only-rgb.json` 里记着位置),
|
|
113
|
+
所以 `theme` / `brightness` 改的配置和 AI 读的是同一份;`npx` 缓存清理也不会丢配置。
|
|
114
|
+
|
|
115
|
+
## 钩子:AI 在什么时候亮什么灯
|
|
116
|
+
|
|
117
|
+
不用理解「钩子」这个词,它就是「AI 在什么时刻亮什么灯」。安装第 2 步有三种选法:
|
|
118
|
+
|
|
119
|
+
- **默认 · 用 AI 推荐**(回车即可):4 个常用时机 —— 你发消息 = 金色从中间扩散、
|
|
120
|
+
新会话 = 绿色铺满后渐灭、回答结束 / 会话结束 = 渐灭;
|
|
121
|
+
另外 3 个高频时机(通知、工具调用前后)默认不绑定。
|
|
122
|
+
- **依次配置**:逐个时机挑,每个都列出几种灯效,**最后两项固定是**
|
|
123
|
+
「让我的 AI 自己决定」和「我自己打字描述想要的效果」。
|
|
124
|
+
前者由 AI 在运行时按当时语义挑灯效;后者把你写的那句人话**原样**交给 AI
|
|
125
|
+
翻译成灯效(例如「柔和的紫色慢慢呼吸」)。
|
|
126
|
+
- **保持现状**:重装 / 升级时不改动已有的任何绑定。
|
|
127
|
+
|
|
128
|
+
选择写进技能目录的 `hook_choices.json`,安装器对**检测到的每个 AI 工具**
|
|
129
|
+
各写一份 `settings.json`;其它技能装的钩子一条都不会被覆盖,选「不绑定」
|
|
130
|
+
也会把该事件的旧绑定清掉。以后改配置**不用重装**:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
npx @zke-wuhu/agent-only-rgb hooks
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
设计语言(中轴生长、金=工作 / 绿=交互与完成 / 红=错误 / 淡蓝=待机、禁止白色)
|
|
137
|
+
写在 `lighting.json` 的 `design` 段,AI 会遵守,不会凭记忆乱配色。
|
|
138
|
+
|
|
139
|
+
## 灯光配置(全部由主机下发)
|
|
140
|
+
|
|
141
|
+
颜色、节奏、呼吸曲线都来自技能目录的 `lighting.json`,用 `lighting apply`
|
|
142
|
+
写进设备 flash,断电保持。固件里只留一份保守兜底值,所以**改灯效不需要重新烧录**。
|
|
143
|
+
|
|
144
|
+
主题是整套预设(亮度 + 节奏):`pulse` 标准 / `night` 夜间 / `focus` 专注 /
|
|
145
|
+
`vivid` 展示;`brightness 50` 是叠加在主题上的总亮度档。两者都写 flash。
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
npx @zke-wuhu/agent-only-rgb lighting show # 回读设备当前配置
|
|
149
|
+
npx @zke-wuhu/agent-only-rgb lighting apply # 整套下发 + 回读校验
|
|
150
|
+
npx @zke-wuhu/agent-only-rgb lighting apply my.json # 自定义配置
|
|
151
|
+
npx @zke-wuhu/agent-only-rgb lighting reset # 恢复出厂兜底
|
|
152
|
+
npx @zke-wuhu/agent-only-rgb tuning get # 14 项调参的当前值与范围
|
|
153
|
+
npx @zke-wuhu/agent-only-rgb tuning set breathe_ms=3000 --save
|
|
154
|
+
npx @zke-wuhu/agent-only-rgb curve get # 16 点呼吸曲线
|
|
155
|
+
npx @zke-wuhu/agent-only-rgb curve set 0,0,0,0,2,7,17,29,46,64,88,117,139,179,213,255 --save
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
`lighting.json` 结构:`master`(总亮度)、`design`(设计语言)、`themes` /
|
|
159
|
+
`active_theme`(风格预设)、`states`(状态表:颜色/模式/亮度/周期)、
|
|
160
|
+
`map`(逐颗颜色)、`tuning`(14 项节奏/几何参数)、`curve`(16 点呼吸曲线,
|
|
161
|
+
0..255 单调不减)。`apply` 会逐项回读校验,任何一项对不上都会报错并指出名字。
|
|
162
|
+
|
|
163
|
+
## 命令行全表
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
npx @zke-wuhu/agent-only-rgb info # 设备信息 / APP 还是 AGENT
|
|
167
|
+
npx @zke-wuhu/agent-only-rgb status # 当前显示的场景/灯效/租约
|
|
168
|
+
npx @zke-wuhu/agent-only-rgb led FF0000 # 常亮红(默认 60 秒后自动熄灭)
|
|
169
|
+
npx @zke-wuhu/agent-only-rgb led 00FF00 --stat breathe --period 2000 --brightness 60
|
|
170
|
+
npx @zke-wuhu/agent-only-rgb led 00FF00 --forever # 常亮,不自动熄灭
|
|
171
|
+
npx @zke-wuhu/agent-only-rgb led 00FF00 --hold 300 # 保持 300 秒
|
|
172
|
+
npx @zke-wuhu/agent-only-rgb off # 关灯
|
|
173
|
+
npx @zke-wuhu/agent-only-rgb count 101 # 链上总颗数(板载 1 + 外接 100)
|
|
174
|
+
npx @zke-wuhu/agent-only-rgb colors FF0000,00FF00,... # 逐颗写颜色
|
|
175
|
+
npx @zke-wuhu/agent-only-rgb state working # 按语义状态切灯
|
|
176
|
+
npx @zke-wuhu/agent-only-rgb onboard-check # 核对板载指示:效果区纯红、链首暗青
|
|
177
|
+
npx @zke-wuhu/agent-only-rgb ota app.ota # 刷本地 .ota
|
|
178
|
+
npx @zke-wuhu/agent-only-rgb ota app.ota --dry-run # 只校验包结构
|
|
179
|
+
npx @zke-wuhu/agent-only-rgb --ble check # 走蓝牙(--ble 放哪都行)
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
`--stat` 可选:`on`(默认)、`breathe`、`blink`、`fast`、`marquee`、
|
|
183
|
+
`expand`、`fadeout`、`fill`、`off`。颜色是 RGB332(硬件只有 3/3/2 位精度),
|
|
184
|
+
`FF0000` 会显示成偏暗的红。
|
|
185
|
+
|
|
186
|
+
`led` 默认带 **60 秒租约**:设备自己倒计时,到点熄灭,所以主机进程被杀、
|
|
187
|
+
USB 拔掉之后灯不会一直亮着。要常亮用 `--forever`,要指定时长用
|
|
188
|
+
`--hold <秒>`(1–254)。租约通过 8 字节报文的保留字节 `[7]` 传递,
|
|
189
|
+
老固件会忽略它(退化为原来的常亮)。
|
|
190
|
+
|
|
191
|
+
## 自动升级
|
|
192
|
+
|
|
193
|
+
默认固件源:npm 包内自带(`assets/firmware/`,随 `npm update @zke-wuhu/agent-only-rgb` 更新),不依赖任何外部远程仓库。需要离线 / 自托管镜像时用 `--repo <本地目录>`。
|
|
194
|
+
|
|
195
|
+
发布方在仓库根目录放 `manifest.json` 即可:
|
|
196
|
+
|
|
197
|
+
```json
|
|
198
|
+
{
|
|
199
|
+
"product": "bleAgentRGB_SOP8",
|
|
200
|
+
"latest": {
|
|
201
|
+
"img_ver": 38,
|
|
202
|
+
"file": "firmware/AgentRGB_SOP8_v38.ota",
|
|
203
|
+
"sha256": "可选,有就校验",
|
|
204
|
+
"notes": "可选,更新说明"
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
没有 `manifest.json` 时会 `git clone --depth 1` 扫描仓库里所有 `*.ota`,
|
|
210
|
+
取包头 `img_ver` 最大的那个。`--repo` 也可以指向本地目录(离线 / 内网镜像):
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
npx @zke-wuhu/agent-only-rgb --repo D:\firmware update
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
本机上次成功升级的 `img_ver` 记在 `~/.agent-only-rgb/state.json`
|
|
217
|
+
(可用 `BLE_AGENT_HOME` 改目录),所以重复执行 `update` 不会白刷同一个版本。
|
|
218
|
+
|
|
219
|
+
安全边界:`.ota` 是正式发布的固件包,包内容由设备自行校验;设备还会拒绝
|
|
220
|
+
低于已记录版本的旧包,防止降级。
|
|
221
|
+
|
|
222
|
+
## 依赖
|
|
223
|
+
|
|
224
|
+
- Python 3.7+;`hidapi`(USB 通道)、`bleak`(蓝牙通道)、`certifi`(HTTPS)
|
|
225
|
+
- Node.js 14+(只是启动器;实机操作都在 Python 脚本里)
|
|
226
|
+
- 所有脚本均为可公开分发的通用实现
|
package/assets/SKILL.md
CHANGED
|
@@ -150,8 +150,7 @@ python ble_sop8.py brightness # 查看当前
|
|
|
150
150
|
**灯效是租约,默认 60 秒**:设备自己倒计时,到点熄灭——所以助手被停止、进程被杀、
|
|
151
151
|
USB 拔掉,灯都不会一直亮着。要长时间保持就加 `--forever`,要指定时长加 `--hold 秒`。
|
|
152
152
|
连续发 `led` 会续约,不用手动清理。
|
|
153
|
-
3. **升级只能刷 `.ota` 包**,不能刷裸 `.bin
|
|
154
|
-
解密和设备校验都在设备里做。拿错包会直接报"不是 .ota 文件"。
|
|
153
|
+
3. **升级只能刷 `.ota` 包**,不能刷裸 `.bin`。包内容由设备负责校验。拿错包会直接报"不是 .ota 文件"。
|
|
155
154
|
4. **升级过程中不要拔线**。整个过程约 10–60 秒,冒号后面会打进度。
|
|
156
155
|
设备在 APP 也能直接刷:脚本会先发 `ERASE` 把设备切到 AGENT(灯变蓝、会复位一次)。
|
|
157
156
|
BLE 下这一步要等 5–20 秒(Windows 清理旧链路),属正常现象,别急着重试。
|
|
@@ -251,7 +250,7 @@ COMMIT_CONFIG(写 flash)→ **逐项回读校验**。哪一项回读不一
|
|
|
251
250
|
> → `py -3 __SKILL_DIR__/ble_sop8.py led 0000FF --stat breathe`
|
|
252
251
|
|
|
253
252
|
> 用户:现在版本多少?能升级吗?
|
|
254
|
-
> → 先 `info`,再根据
|
|
253
|
+
> → 先 `info`,再根据 `升级支持` 那行回答;能升就用 `ota`
|
|
255
254
|
|
|
256
255
|
> 用户:我下载了 app.ota,刷一下
|
|
257
256
|
> → `py -3 __SKILL_DIR__/ble_sop8.py ota app.ota`,边跑边把进度念给用户
|
|
@@ -262,6 +261,6 @@ COMMIT_CONFIG(写 flash)→ **逐项回读校验**。哪一项回读不一
|
|
|
262
261
|
|
|
263
262
|
## 协议说明(内部实现,外部无需了解)
|
|
264
263
|
|
|
265
|
-
灯带通过 USB HID / BLE
|
|
264
|
+
灯带通过 USB HID / BLE 与主机通信,固件升级走正式发布包。这些都是**内部实现细节**,
|
|
266
265
|
AI 与用户都**不需要、也不应该**去了解或复现协议——所有操作都通过上面的命令表完成。
|
|
267
266
|
不要试图手动构造报文或自行实现刷机工具。
|
package/assets/ble_sop8.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
"""bleAgentRGB SOP8
|
|
2
|
+
"""bleAgentRGB SOP8 设备命令行(用户侧)。
|
|
3
3
|
|
|
4
4
|
AI 助手通过这个脚本来"使用设备":看状态、改灯效、升级固件。
|
|
5
5
|
|
|
@@ -8,7 +8,7 @@ AI 助手通过这个脚本来"使用设备":看状态、改灯效、升级固
|
|
|
8
8
|
python ble_sop8.py led 00FF00 --stat breathe --period 2000 --brightness 60
|
|
9
9
|
python ble_sop8.py led 00FF00 --forever # 常亮,不自动熄灭
|
|
10
10
|
python ble_sop8.py off # 关灯
|
|
11
|
-
python ble_sop8.py ota app.ota #
|
|
11
|
+
python ble_sop8.py ota app.ota # 刷固件包
|
|
12
12
|
python ble_sop8.py check # 去远程仓库看有没有新固件
|
|
13
13
|
python ble_sop8.py update # 检查 + 下载 + 升级到最新
|
|
14
14
|
python ble_sop8.py --ble led FF0000 # 走蓝牙(需 pip install bleak)
|
|
@@ -1986,9 +1986,9 @@ def cmd_info(dev):
|
|
|
1986
1986
|
if r[2] == 1:
|
|
1987
1987
|
health = {0: "可用", 1: "试跑中", 2: "已损坏"}.get(r[29], r[29])
|
|
1988
1988
|
print("APP 健康 : %s(tries %d/%d)" % (health, r[30], r[31]))
|
|
1989
|
-
print("
|
|
1989
|
+
print("升级支持 : %s" % ("支持(v%d)" % r[32] if r[32] >= 2
|
|
1990
1990
|
else "不支持(老固件)"))
|
|
1991
|
-
print("
|
|
1991
|
+
print("设备批次 : %d%s" % (r[33], "(未初始化,无法升级)"
|
|
1992
1992
|
if r[33] == 0 else ""))
|
|
1993
1993
|
if len(r) >= 38:
|
|
1994
1994
|
print("最低版本 : %d(低于它的包会被拒,防回滚)"
|
|
@@ -1997,7 +1997,7 @@ def cmd_info(dev):
|
|
|
1997
1997
|
|
|
1998
1998
|
|
|
1999
1999
|
def cmd_ota(ota_path, use_ble=False, dry_run=False):
|
|
2000
|
-
"""
|
|
2000
|
+
"""交给升级客户端处理。"""
|
|
2001
2001
|
client = os.path.join(_HERE, "ota_client.py")
|
|
2002
2002
|
if not os.path.exists(client):
|
|
2003
2003
|
sys.exit("找不到 ota_client.py(安装不完整,重跑安装器)")
|
|
@@ -2221,7 +2221,7 @@ def main():
|
|
|
2221
2221
|
help="idle=空闲 working=执行中 ask=有未回答的问题 "
|
|
2222
2222
|
"error=出错 done=完成提示(8s) off=关灯 "
|
|
2223
2223
|
"fade=逐渐熄灭 session-start=绿色铺开后逐渐熄灭")
|
|
2224
|
-
p_ota = sub.add_parser("ota", help="
|
|
2224
|
+
p_ota = sub.add_parser("ota", help="刷固件包")
|
|
2225
2225
|
p_ota.add_argument("file", help=".ota 路径")
|
|
2226
2226
|
p_ota.add_argument("--dry-run", action="store_true",
|
|
2227
2227
|
help="只校验包结构,不连设备")
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
"img_ver": 40,
|
|
5
5
|
"sha256": "524640d1ef3b43e447af0c3961aaebb528507f61080eb40f386b3c6ee3f7e4b7",
|
|
6
6
|
"file": "AgentRGB_SOP8_v40.ota",
|
|
7
|
-
"notes": "v40(zke-wuhu):USB 产品名 zke-wuhu;板载 1 颗状态指示(暗青常亮,不受灯效影响)+ 外接灯带最多 100 颗;新增 fill 类灯效(中心向两边一次性铺满)与节奏档 pace
|
|
7
|
+
"notes": "v40(zke-wuhu):USB 产品名 zke-wuhu;板载 1 颗状态指示(暗青常亮,不受灯效影响)+ 外接灯带最多 100 颗;新增 fill 类灯效(中心向两边一次性铺满)与节奏档 pace。"
|
|
8
8
|
}
|
|
9
9
|
}
|