Frumorn12/vibe99ctl
GitHub: Frumorn12/vibe99ctl
一款用于 Mechlands Vibe99 机械键盘的开源跨平台终端驱动工具,替代官方 Windows GUI,支持通过命令行控制 RGB 灯效、TFT 屏幕和时钟。
Stars: 0 | Forks: 0
# vibe99ctl
**一款用于 Mechlands Vibe99 键盘的开源终端驱动工具 —— 可在 shell 中控制 RGB、内置 TFT 屏幕和时钟。无需专有 GUI。**
[](https://github.com/Frumorn12/vibe99ctl/actions/workflows/ci.yml)
[](LICENSE)
[](https://www.python.org/)
## 概述
Mechlands Vibe99 是一款 96%/1800 布局的无线机械键盘,配备一块
**1.06 英寸 TFT 屏幕**。其官方驱动是一个 **仅限 Windows 的 GUI**,需要通过
**有线** 连接才能配置 RGB 灯效、向屏幕上传图片/GIF 以及同步时钟。
`vibe99ctl` 旨在通过终端完成所有这些操作,以 **Linux 优先**,同时也支持
**Windows**,并提供一个干净、可编写脚本的 CLI。
### 功能说明
| 功能 | 命令 | 状态 |
|---|---|---|
| RGB:纯色 | `vibe99 rgb set` | 🟡 编码器已构建,待验证协议 |
| RGB:特效/预设 | `vibe99 rgb preset` | 🟡 编码器已构建,待验证协议 |
| RGB:亮度 / 关闭 | `vibe99 rgb brightness` / `off` | 🟡 编码器已构建 |
| 屏幕:静态图片 | `vibe99 screen upload-image` | 🟡 处理流水线已构建,待验证协议 |
| 屏幕:动画 (GIF) | `vibe99 screen upload-animation` | 🟡 处理流水线已构建 |
| 屏幕:视频 → 动画 | `vibe99 screen upload-video` | 🟡 **可转换** (不支持原生视频) |
| 时钟同步 | `vibe99 clock sync` | 🟡 编码器已构建 |
| 设备发现 | `vibe99 list-devices` / `info` | 🟢 目前可用 |
| 诊断 | `vibe99 doctor` | 🟢 目前可用 |
| 逆向工程辅助 | `vibe99 protocol ...` / `dump-descriptor` | 🟢 目前可用 |
🟢 = 目前可用 · 🟡 = 已实现,需要通过硬件抓包来确认字节流
### 关于“视频”支持 —— 请注意
Vibe99 **并不播放真正的视频**。其固件仅接受静态图片和
**GIF/动画帧**。因此,`vibe99 screen upload-video` 会将视频**转换**为简短的、低帧率的帧序列,并作为动画上传。
这种结果是刻意为之的卡顿感 —— 这是硬件限制,而不是 bug,我们拒绝掩饰这一点。
## 安装
```
# 从 source 构建(在 alpha 阶段推荐)
git clone https://github.com/Frumorn12/vibe99ctl.git
cd vibe99ctl
python -m venv .venv && source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e .
# 可选:启用真正的视频转换(mp4/webm/...)。GIFs 无需此项即可工作。
pip install -e ".[media]" # imageio + ffmpeg
pip install -e ".[media-full]" # + OpenCV
```
### 依赖要求
**Linux**
- Python 3.10+
- `hidapi` 系统库:`sudo apt install libhidapi-hidraw0` (Debian/Ubuntu),或者在编译 wheel 时安装构建头文件 `libudev-dev libusb-1.0-0-dev`。
- 用于非 root 访问的 udev 规则(参见 [故障排除](#troubleshooting))。
**Windows**
- Python 3.10+
- `hidapi` wheel 已捆绑 DLL;进行 HID 访问无需额外的驱动程序。
- 将键盘置于 **有线** 模式进行配置(与官方工具相同)。
## 用法
```
# 发现硬件
vibe99 info
vibe99 list-devices # only known/candidate devices
vibe99 list-devices --all # every HID interface (use this to find your VID/PID)
vibe99 doctor # environment & connectivity checks
# RGB
vibe99 rgb set "#ff8800" # dry-run preview
vibe99 rgb set red --brightness 60 --apply
vibe99 rgb preset rainbow --speed 80 --apply
vibe99 rgb preset breathing --color "0,128,255" --apply
vibe99 rgb brightness 40 --apply
vibe99 rgb off --apply
# 屏幕
vibe99 screen upload-image logo.png --fit cover --apply
vibe99 screen upload-animation cat.gif --fps 5 --apply
vibe99 screen upload-video clip.mp4 --max-frames 60 --apply # converted, not streamed
# 时钟
vibe99 clock sync --apply
vibe99 clock sync --at 2026-12-31T23:59:00 --apply
# Reverse-engineering 辅助工具
vibe99 dump-descriptor --all
vibe99 protocol sniff-notes
vibe99 protocol checksum "06 01 64 ff"
vibe99 protocol ping --apply
```
指定特定设备(例如自动检测错误时):
```
vibe99 --vid 0x05ac --pid 0x024f rgb set blue --apply
vibe99 --path "/dev/hidraw3" info
```
查看 [`examples/`](examples/) 获取可直接复制粘贴的示例。
## 示例 (CLI)
```
# 半亮度的红色“呼吸”氛围灯
vibe99 rgb preset breathing --color red --brightness 50 --apply
# 将你的 logo 放在屏幕上,裁剪以填满屏幕
vibe99 screen upload-image ~/Pictures/logo.png --fit cover --apply
# 以约 5 fps 循环播放 GIF
vibe99 screen upload-animation ~/Pictures/loading.gif --fps 5 --apply
# 保持屏幕上的时钟准确(例如通过 cron / 登录 hook)
vibe99 clock sync --apply
```
## 故障排除
**`No Mechlands Vibe99 (or compatible) device found`**
- 使用 **USB-C 数据线**(有线模式)连接键盘 —— 无线/2.4G 模式可能会以不同的 PID 枚举,或者不暴露控制接口。
- 运行 `vibe99 list-devices --all` 并查找厂商接口(标有 `*`)。
找到了吗?请显式传入 `--vid/--pid`,并请
[提交一个协议 issue](.github/ISSUE_TEMPLATE/protocol_capture.md)。
**Linux:`open failed / access denied`**
创建一个 udev 规则(将 ID 替换为你从 `list-devices --all` 中获取的 ID):
```
sudo tee /etc/udev/rules.d/99-vibe99.rules >/dev/null <<'EOF'
# Mechlands Vibe99 (SONiX) — 共享 Apple 的 05ac:024f,因此此规则也会
# 放宽具有该 ID 的 Apple 键盘的权限。如果这有影响,请自行调整。
KERNEL=="hidraw*", ATTRS{idVendor}=="05ac", ATTRS{idProduct}=="024f", MODE="0660", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="05ac", ATTRS{idProduct}=="024f", MODE="0660", TAG+="uaccess"
EOF
sudo udevadm control --reload-rules && sudo udevadm trigger
```
然后重新插拔键盘。
**`hidapi` 导入失败**
安装系统库(`libhidapi-hidraw0`)或构建头文件,然后
执行 `pip install --force-reinstall hidapi`。运行 `vibe99 doctor` 进行确认。
**提示“已发送”但没有任何变化**
你可能在运行时没有加 `--apply`(试运行),或者 opcode/校验和的猜测
与你的固件不符。在协议确认之前,后者属于预期情况 ——
抓取数据包正是你能提供的帮助(见下文)。
## 逆向工程说明
确认协议最快的方法是使用该 OEM 系列产品搭载的 **WebHID** Web 驱动:
它是纯 JavaScript 编写的,因此你可以在 Chrome DevTools 中挂钩
`HIDDevice.prototype.sendReport` 并读取每一个数据包。USB
抓包(Wireshark + usbmon/USBPcap)是备选方案。完整、逐步的指南如下:
- [`docs/reverse-engineering.md`](docs/reverse-engineering.md) — 如何进行抓包。
- [`docs/protocol.md`](docs/protocol.md) — 字节级规范(随着我们的研究进行补充)。
- `vibe99 protocol sniff-notes` — 简短版本,直接在你的终端中查看。
如果你拥有一台 Vibe99,对单个操作(例如“设置为红色”)进行一次干净的抓包将
极具价值 —— 请通过协议 issue 模板分享给我们。
## 功能状态
查看 [概述](#what-it-does) 中的实时状态矩阵,以及
[`docs/assumptions-and-limits.md`](docs/assumptions-and-limits.md) 中的详细分析。
## 假设与限制
- **已确认** — 官方/营销材料:1.06 英寸 TFT;显示
日期/时间/电池/连接/锁定指示器;支持由带有文本的 JPG/PNG 构建的 GIF 和动画;通过 **有线** 连接配置;官方驱动仅限 Windows。
- **已确认** — 来自真实设备的 HID 报告描述符:
- USB 标识 **`05ac:024f`**,制造商 **SONiX**,产品名
**"Mechlands Vibe99"**(它复用了 Apple 的 VID:PID,因此我们还会匹配
产品字符串,以避免影响到真正的 Apple 键盘)。
- 两个厂商接口:**控制** = usage page `0xFF13`(64 字节的
out/feature 报告),**屏幕** = usage page `0xFF68`(用于像素数据的 **4096 字节**
output 报告)。无编号的 Report ID。
- 2.4G 模式暴露了不同且更小的厂商报告(`0xFF60`) ——
因此配置必须通过有线方式进行。
- **极有可能**:屏幕为 RGB565,可能是 240×240;由于 USB Full-Speed 带宽限制,设备上的动画仅以
极低的几帧每秒 (fps) 运行。
- **有待在真实硬件上验证**:RGB / 屏幕 / 时钟的命令 opcode、payload 布局和
校验和算法(需要抓取 Windows 或
WebHID 驱动程序的通信数据),以及确切的屏幕分辨率和像素顺序。
所有“极有可能”/“有待验证”的内容都集中放在 `config.py` 和
`protocol/` 编码器中,每一处都标有 `# TO-VERIFY`,因此确认协议
只需修改几个常量 —— 而无需重写整个工具。
## 免责声明与安全
这是一个**非官方**项目。它**不隶属于 Mechlands,也未获得其**
认可或支持**。“Mechlands”和“Vibe99”是其各自所有者的商标;此处使用它们仅是为了描述兼容性。
向 USB 设备写入未经验证的数据会带来一定风险。此工具默认以 dry-run 模式运行以降低此风险,但**使用风险由你自己承担**。对于任何硬件损坏,作者不承担任何责任(参见 [LICENSE](LICENSE))。这里的所有逆向工程都是为了与你所拥有的硬件实现**互操作性**。
## 许可证
[MIT](LICENSE) © 2026 Andrea Brescia
标签:Python, RGB灯效控制, 外设管理, 文档结构分析, 无后门, 机械键盘, 硬件驱动, 逆向工具