fordragon88/web-rnet-configurator
GitHub: fordragon88/web-rnet-configurator
开源的 R-Net 电动轮椅 Web 配置工具,通过 Raspberry Pi + CAN 总线让用户自主调整轮椅驱动参数,实现辅助技术领域的维修权。
Stars: 0 | Forks: 0
# web-rnet-configurator
一个用于 R-Net 电动轮椅的基于 Web 的配置工具。允许任何 R-Net 轮椅的所有者在浏览器中调整他们自己的配置文件参数、expert/OBP 参数,以及(最终实现)JSM/PM 固件,实际的更改通过轮椅上的 Raspberry Pi + PiCAN2 模块进行应用。
这是一个全新的项目。它是团队在 R-Net 协议上所做研究的产品化成果;关于 `d:\Canbus\` 中的基础工作,请参阅下方的[研究与参考资料](#research-and-reference-materials)。
## 状态
MVP 已经完成了 Offline_Mode 以及 Online_Mode 云端部分的功能。真实轮椅的 OBP 和固件写入将通过显式的 `--allow-unconfirmed` 标志来控制,直到 [`docs/CAPTURE_PROCEDURE.md`](docs/CAPTURE_PROCEDURE.md) 中有更多的抓取记录——这关乎的是底层传输字节的确定性,而不是权限问题。
| 里程碑 | 范围 | 状态 |
|---|---|---|
| M0 | 项目引导 | 完成 |
| M1 | 编解码器(Python + TS,S-Record,共享测试夹具) | 完成 |
| M2 | 轮椅检测(banner,XOR,插槽,匹配器) | 完成 |
| M3 | 应用 pipeline 核心(POP-Quick,快照,审计,验证) | 完成 |
| M4 | OBP 和固件(POP-Segmented,进入/退出,回读验证,dry-run) | 完成;轮椅写入路径受限于更多抓取记录 |
| M5 | Web_App MVP(Offline_Mode UI) | 完成 |
| M6 | Agent CLI(`rnet-apply`、`rnet-rollback`、`rnet-audit`、`rnet-pair`、`rnet-import-rnet`、`rnet-export`、`rnet-inspect`、`rnet-honk`、`rnet-lights`、`rnet-agent-daemon`) | 完成 |
| M7 | Cloud_Relay(FastAPI + argon2id + JWT + authz) | 完成 |
| M8 | Online_Mode Agent(MQTT,三通道确认,retry/backoff) | 完成 |
| M9 | 真实轮椅抓取,更多轮椅型号 | 开放贡献 |
| M10 | 文档,Pi 镜像,上游 PR | 完成 |
| M11 | UX 优化(拖放区,配置文件按钮选择器,锁定/重置,等效经销商提示,运行时 CLI + 云通道,Flask 确认服务器,布尔/枚举字段类型,.rnetpkg 检查模式拖放区,报告选项卡,带有红/黄/绿胶囊标志的安全分类器) | 完成 |
| M12 | `.R-net` 往返(重命名配置文件,启用/禁用,速度/加速补丁,从 `.rnetpkg` 以编辑为起点,经销商百分比 UI 缩放) | 完成 |
| M13 | UX 迭代(报告筛选 + 分页,浏览器内带文本导出的 `.R-net` diff 查看器,术语清理) | 完成 |
| M14 | 测试模式切换 + 紧凑型轮椅型号选择器(已验证/占位符 optgroups,针对占位符目标在确认时的 CLI 提示横幅) | 完成 |
| M15 | UX 强化(多插槽脏标记,diff 查看器文件持久化,确认时的按插槽写入摘要,整合 seed 处理效果以修复多导入时的 RHF 状态竞争) | 完成 |
| M16 | 轮椅型号归因准确性检查:在贡献者确认这些轮椅为 Permobil M3 之后,将 chair_model_id 从 `permobil-m300-pcbk` 重命名为 `permobil-m3-old`,并将 `permobil-c500-stander` 重命名为 `permobil-m3-new`,完整的证据链记录在 `docs/PROVENANCE.md` 中 | 完成 |
测试:共 764 个(415 个 Python agent + 54 个 Python relay + 295 个 TypeScript)。
所有 22 个设计属性都至少有一个带标记的测试。mypy 0 个警告,ruff 0 个警告,TS 严格模式。
完整的功能规格说明位于
[`.kiro/specs/web-rnet-configurator/`](.kiro/specs/web-rnet-configurator/):
- [`requirements.md`](.kiro/specs/web-rnet-configurator/requirements.md)
- [`design.md`](.kiro/specs/web-rnet-configurator/design.md)
- [`tasks.md`](.kiro/specs/web-rnet-configurator/tasks.md)
## 仓库结构
```
web-rnet-configurator/
web/ # Web_App SPA (TypeScript, React, Vite, Zod)
src/
tests/
agent/ # On-chair daemon and CLI (Python 3.11+)
rnet_agent/
tests/
relay/ # Cloud_Relay (Python, FastAPI + Mosquitto + Postgres)
rnet_relay/
tests/
chair_models/ # Per-chair-model TOML data files
# (loaded by both Web_App and Agent)
fixtures/
codec_vectors/ # Shared parser test vectors (TS + Python parity)
captures/ # Recorded CAN traces used as test fixtures
tools/ # Build, capture, and CI tooling
docs/ # User and operator documentation
.kiro/ # Spec documents (requirements / design / tasks)
```
## 三大组件,同一仓库
| 组件 | 运行位置 | 功能描述 |
|---|---|---|
| **Web_App** | 浏览器 | 根据每种轮椅型号的 schema 构建 Config_Packages。验证字段,显示确认屏幕,下载或发布包。 |
| **Cloud_Relay** | 小型服务器 | 可选。存储账户,通过 MQTT 中继 Config_Packages,保留 Apply_Reports。该系统在没有它的情况下也能工作(Offline_Mode)。 |
| **Agent** | 轮椅上的 Raspberry Pi + PiCAN2 | 检测已连接的轮椅,捕获 Recovery_Snapshot,使用与 OEM 经销商编程器相同的网络协议应用 Config_Package,验证每一次写入,并写入 Apply_Report。 |
有关部署图和应用 pipeline 状态机,请参阅 `design.md`。
## 基于属性的测试
规格说明列出了 22 个支撑测试套件的正确性属性。
每个属性测试都使用如下格式的规范注释行进行标记
```
Feature: web-rnet-configurator, Property N:
```
如果 `design.md` 中编号的任何属性没有匹配的标记测试,CI 就会失败。属性编号到任务的映射位于 `tasks.md` 的底部。
## 研究与参考资料
本项目建立在两个基础之上:
1. **[openassistivetech/open-rnet](https://github.com/openassistivetech/open-rnet)** —
Stephen Chavez 和 Specter 历时 10 年的 R-Net 逆向工程项目(2016 年 DEFCON24 演讲,2026 年完全开源)。他们记录了 590 多个数据帧,逆向工程了 OBP 参数空间(手册 SK78571/4)、来自经销商加密狗 DLL 的 POP 编程器协议,以及 HCS08 固件加密。我们的 `chair_models/permobil-m3-old.toml` 中确认的参数地址直接来自于他们的 `tools/rnet_obp_mode.py` 的 `OBP_MENU` 表。我们从该项目向上游发送的任何内容都将针对他们的仓库。原作者的镜像位于 [redragonx/open-rnet](https://github.com/redragonx/open-rnet);这两个仓库在字节上是完全相同的。
2. **团队自己的抓取记录**,来自一辆实体轮椅(JSM 序列号 B68021AE;轮椅型号归因是外部元数据,而不是协议推导出来的——请参阅 [`docs/PROVENANCE.md`](docs/PROVENANCE.md)),这为我们提供了对启动 banner、XOR 表和一次编程器会话的第二次独立观察。
| 路径 | 内容 |
|---|---|
| `../RNET_FRAME_DICTIONARY.md` | 规范的数据帧参考。已更新并与上游 [open-rnet](https://github.com/openassistivetech/open-rnet) 项目同步。 |
| `../CAPABILITIES.md` / `_RU.md` | 我们可以在轮椅上读取和更改的内容,以及风险等级。 |
| `../PROTOCOL_DEEPDIVE.md` / `_RU.md` | 带注释的启动跟踪,POP-Quick 剖析,方向分类的迟滞现象,安全观察。 |
| `../POP_DECODE_REPORT.md` / `_RU.md` | 从真实编程器会话中解码出的 POP-Segmented 传输。 |
| `../ANALYSIS_REPORT.md` / `_RU.md` | 对 2026-05-21 最初三次抓取的初步分析。 |
| `../new/ANALYSIS_REPORT.md` / `_RU.md` | 2026-05-22 的操纵杆校准抓取。确认了 X/Y 轴极性。 |
| `../full-dump-2026-05-21-*.log` | 原始 `candump` 跟踪。`1H00M` 抓取是参考编程器会话,也是编解码器重放测试的基础。 |
| `../new/full-dump-*-between-beeps.log` | 定向操纵杆校准抓取。 |
| `../scripts/` | 声音反馈原型(`chair_beeper.py`、`direction_beeper_v3.py`、`light_beeper.py`)。它们演示了读取路径、喇叭输出路径和受运动限制的方向分类器。其中的状态机和协议模式是 `agent/rnet_agent/` 的基础。 |
一旦项目完善,适合上游的部分(编解码器、`chair_models/`、Agent CLI、测试夹具)将作为一个 PR 提交到 [open-rnet](https://github.com/openassistivetech/open-rnet)。
Cloud_Relay 保留在此仓库中。
## 快速开始
面向轮椅所有者和操作员:
- [`docs/QUICKSTART.md`](docs/QUICKSTART.md) - 首次使用的单页备忘录
([俄语翻译](docs/QUICKSTART_RU.md))。
- [`docs/USER_GUIDE.md`](docs/USER_GUIDE.md) - 端到端操作指南。
- [`docs/HARDWARE.md`](docs/HARDWARE.md) - 物料清单和接线。
- [`docs/FIRST_REAL_APPLY.md`](docs/FIRST_REAL_APPLY.md) - 首次对真实轮椅进行写入的
分步运行手册(快照,
dry-run,单一安全参数,回滚验证)。
- [`docs/TEST_PLAN.md`](docs/TEST_PLAN.md) - 测试的内容,以何种
顺序,从“即时 CI”到“真实轮椅上的实际连接”,并
标明了依赖关系,以便贡献者知道什么阻碍了什么。
对于处理 `.R-net` 经销商文件的人员:
- [`docs/RNET_FILE_FORMAT.md`](docs/RNET_FILE_FORMAT.md) - 来自我们
逆向工程工作的字节级布局说明,包括
三个布局系列(较新型 / 短型 / Quickie),
Profile Enable 字节位置,以及如何安全地扩展解析器以支持新
字段。
- [`docs/PROMOTE_PLACEHOLDER_CHAIR.md`](docs/PROMOTE_PLACEHOLDER_CHAIR.md) -
单轮椅运行手册,用于通过一次 CAN 抓取将占位符 chair_model(Quickie,
Permobil F3 / C400 / Omni)从“Web_App 能读取其文件”提升为
“Agent 将通过连线对其进行写入”。
- [`docs/UPSTREAM_DOCS_INDEX.md`](docs/UPSTREAM_DOCS_INDEX.md) -
我们在 `fixtures/upstream-docs/` 下保留的上游 open-rnet 文档快照索引,
并附带差距分析,展示
我们项目深入到了哪里,以及上游仍然有哪些
我们尚未涉及的内容。
- [`docs/VERIFICATION_GUIDE.md`](docs/VERIFICATION_GUIDE.md) -
任何拥有真实轮椅 + 经销商编程器的人员都可以运行的
基准检查,以确定 slot ↔ subindex 映射以及其他
剩余的假设。
面向开发者:
- [`CONTRIBUTING.md`](CONTRIBUTING.md) - 一小时入职指南:环境设置,
CI 结构,文件布局映射,跨平台编解码器规则,提交
规范,以及遇到问题时去哪里寻找答案。
```
make ci # run all linters + tests
make test # just the tests (Python + TypeScript)
make web-dev # run the Web_App locally (Vite dev server)
make agent-dev # run the agent test suite
make relay-dev # run the Cloud_Relay locally (in-memory store)
```
对于拥有设备并能收集真实轮椅抓取记录的任何人:
- [`docs/CAPTURE_PROCEDURE.md`](docs/CAPTURE_PROCEDURE.md) - 按优先级
和风险排序的五次抓取会话;每次都会解锁一个或
多个 milestone-9 任务。始终欢迎提供新轮椅和新固件版本。
## 许可证
GPLv3。完整文本请见 [LICENSE](LICENSE)。源代码、测试夹具、
抓取记录和设计说明全部开放。如果你修改了某些内容,
GPL 要求你也必须公开这些更改。
## 本项目代表的理念
它的存在是因为电动轮椅的所有者不应该为了 30 秒钟的最高时速微调而向经销商付费。这是一个关于维修权利的项目。我们不以资质为门槛,也不假装你需要任何人的许可来维护你自己的出行设备。
话虽如此,有两个物理风险是真实存在且值得注意的:
1. **变砖。** JSM 和 PM 模块上的 R-Net 固件是未签名的。
一次错误的固件写入可能会导致轮椅无法启动,
并且恢复需要 PCB 级别的工作。本项目中的固件写入
受显式选择加入和字节级回读
验证的限制;参数写入不存在此风险。Web_App 和
CLI 都会在各自的通知中明确指出这一点。
2. **意外移动。** 速度和加速度参数会改变
轮椅对操纵杆的响应方式。在进行任何更改后
首次运行时,请确保车轮离地或在
开阔平坦的区域。在最初几次
尝试新配置时,有另一个人在场是明智的。
除了这两点之外,Agent 本身还强制执行:
- 电机电流安全闸门(属性 14):除非轮椅
在完整的 1.5 秒内*持续*报告零电机电流,否则无法进入 Config_Mode
(仅仅一个新的零采样是不够的)。
- 每次应用前进行 Recovery_Snapshot(回滚只需一条命令)。
- 对每次参数写入进行回读验证。
- 在出现 chair 不匹配、schema 违规或指纹
漂移时拒绝执行。
标签:CAN总线, 嵌入式系统, 开源修复, 测试用例, 物联网配置, 辅助技术, 逆向工具