libingtong/nd104-panel
GitHub: libingtong/nd104-panel
逆向 ND104 键盘内置屏幕的 HID 协议,将 Claude Code 额度与天气信息渲染为多帧面板定时推送到屏幕显示。
Stars: 0 | Forks: 0
# ND104 屏幕信息面板
逆向 **[ND104 键盘](https://chilkey.com/products/nd104-keyboard)** 内置屏幕(320×172)的 HID 传输协议,并实现一个常驻程序,把
**Claude Code 用量额度 + 实时天气 + 降雨预警**渲染成多帧面板,定时推送到屏幕,由设备端自动循环轮播。
完整的字节级协议规格见 [`protocol-spec.md`](./protocol-spec.md)。
## 效果
设备端循环播放的三类帧(深色主题,大字):
- **额度帧** —— Claude Code 真实 5H / 周 剩余额度%(来自 `api.anthropic.com` 限额响应头,与状态栏同源)。
- **天气帧** —— 当前温度、天气、最高/最低、体感、湿度、风、AQI + 一行预报摘要,配矢量天气图标。
- **降雨预警帧** —— 仅当未来 2 小时内可能降雨时自动追加,显示预计转雨时刻与概率。
## 原理简述
- 屏幕是键盘的一个 HID 子设备(`0x5542/0x0001`,usagePage `0xFF60`),用 64 字节报文传输。
- 图片走自定义封装:`55 42 | 宽 | 高 | 帧数N | 每帧延时 | 每帧JPEG长度 | JPEG…`,`BA 3E` 分片发送。
- 多帧即"帧数 N>1",设备端自动循环。每帧延时字节封顶 255(≈2 秒),更长停留用重复帧实现。
- 实测:设备**不要求**块校验帧(发错误 CRC 反而会损坏码流),故发送端不发。
细节、抓包证据与字段判定(实测 vs 推测)全部记录在 [`protocol-spec.md`](./protocol-spec.md)。
## 环境要求
- macOS(额度读取依赖 Keychain 里的 Claude Code OAuth 令牌;launchd 常驻为 macOS 专有)。
- Node.js 18+。
- 一把 ND104 键盘,USB 连接,且关闭官方网页(官方页会独占设备)。
- 一个彩云天气 token(免费):https://dashboard.caiyunapp.com
## 安装
npm install
## 配置(环境变量)
| 变量 | 必填 | 说明 |
|---|---|---|
| `CAIYUN_TOKEN` | 是 | 彩云天气 token |
| `WEATHER_COORD` | 否 | `"经度,纬度"`,默认北京 `116.4074,39.9042` |
| `WEATHER_CITY` | 否 | 城市名,默认 `北京` |
| `ND_INTERVAL_MIN` | 否 | 推送间隔(分钟),默认 30 |
| `ND_DWELL_SEC` | 否 | 每帧停留秒数,默认 6 |
| `ND_ACTIVE_DAYS` | 否 | 活跃星期(0=周日),默认 `1,2,3,4,5` |
| `ND_ACTIVE_RANGES` | 否 | 活跃时段,默认 `9-12,14-19` |
| `RAIN_PROB` | 否 | 降雨判定概率阈值(%),默认 30 |
额度数据来自本机 Keychain 中 Claude Code 的 OAuth 令牌(`security find-generic-password -s "Claude Code-credentials"`),
仅在本机使用,不会离开设备。
## 使用
# 只渲染各帧到 panel-*.jpg 预览,不连硬件
CAIYUN_TOKEN=xxx node push-daemon.js --once --dry-run
# 连接硬件推送一次
CAIYUN_TOKEN=xxx node push-daemon.js --once
# 常驻(默认 30 分钟一次,仅工作日 9–12 / 14–19 点推送,省 flash)
CAIYUN_TOKEN=xxx node push-daemon.js
# 临时调整每帧停留
CAIYUN_TOKEN=xxx node push-daemon.js --once --dwell 8
其它工具:
node nd104-push.js # 推一张静态图片(自动缩放/转码为 320×172 JPEG)
node push-gif.js # 推一段动画(抽帧打包成多帧容器,设备端循环)
## 开机自启(launchd)
`nd104-panel.plist` 是模板。替换其中的占位符(`__NODE__` / `__PROJECT_DIR__` / `__CAIYUN_TOKEN__` / `__COORD__` / `__CITY__`),然后:
cp nd104-panel.plist ~/Library/LaunchAgents/com..nd104-panel.plist
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com..nd104-panel.plist
# 重载: launchctl kickstart -k gui/$(id -u)/com..nd104-panel
日志在项目目录 `nd104.log`。
## 目录结构
lib/nd104.js 协议核心(帧构造 / 传输 / 多帧容器 / pushJpeg / pushFrames)
lib/quota.js Claude Code 真实额度(api.anthropic.com 限额响应头)
lib/weather.js 彩云天气取数 + 归一化 + 未来2小时降雨检测
lib/render.js SVG→JPEG 渲染额度 / 天气 / 预警帧
lib/icons.js 纯 SVG 矢量天气图标
push-daemon.js 常驻主程序
nd104-push.js 单图推送 CLI
push-gif.js 动画推送 CLI
protocol-spec.md 字节级协议规格
## 免责声明
本项目为对自有硬件的互操作性研究与个人使用,与键盘厂商、Anthropic、彩云天气均无隶属关系。
使用风险自负:向设备 flash 频繁写入可能影响寿命,默认配置已尽量降低写入频率。
## License
MIT
标签:GNU通用公共许可证, HID协议, MITM代理, Node.js, 云资产清单, 桌面组件, 硬件交互, 自定义脚本, 逆向工程