danaghili/ai-doorbell
GitHub: danaghili/ai-doorbell
一个运行在 Reolink 门铃硬件上的 AI 语音对讲系统,通过逆向工程专有协议实现门铃扬声器的任意音频播放,结合本地 Whisper 转录和本地 LLM 回复完成实时访客对话。
Stars: 0 | Forks: 0
# AI 门铃
一个在 Reolink Video Doorbell PoE 内运行的 AI 对讲机。有人按门铃(或出现在门口)时 →
Jarvis 通过门铃麦克风听到他们的声音 → 转录他们说的话 → 撰写回复 → 并通过
门铃扬声器播放出来,从而进行简短的来回对话。它会通过名字问候被识别出的家庭成员
——但仅限在它确信无疑的时候。
最困难的部分是:门铃**没有提供用于播放任意音频的本地 API**,因此
扬声器路径是对 Reolink 专有的 Baichuan 协议进行逆向工程的实现。
## 状态
**已部署并实际运行在一扇真正的大门上。** 完整的循环——按门铃 → 问候 → 听取 →
转录(本地 Whisper)→ 回复(本地 LLM)→ 播放——作为容器运行在家庭服务器上,并且
与真实的访客进行真实的对话。上线的第一天暴露了三个真实的
环境集成缺陷(每一个都通过记录的缺陷通道进行了修复,并优先提交了回归
测试——参见 `docs/BUGS.md` 和 `docs/trails/`),并提供了足够的经验来发布第一个强化
增量(`docs/increments/INC-001.md`):日志中的完整对话可观测性、
本地模型的保活心跳、在核心大脑故障时优雅的语音兜底、
速率限制的所有者警报,以及基于新鲜度控制的按名问候。包含 265 个单元测试;重新部署只需
一条命令(`deploy.sh`)。剩余工作:少量由操作员执行的实机调优检查(对话轮次感知
和触发门控场景),这些已在 `docs/reviews/coverage.md` 中如实记录为延期处理。
## 逆向工程故事(最困难的部分)
Reolink 没有提供用于播放任意音频的本地 API——所有标准路径均告失败(go2rtc backchannel、
RTSP ANNOUNCE、ONVIF Profile T、云端锁定的 customAudio、带有证书锁定的 App)。扬声器输出是
通过逆向工程专有的 **Baichuan 协议**(在端口 9000 上的二进制 TCP,一个
AES-CFB 会话)并确认 ElevenLabs 的声音通过门铃扬声器播放而破解的。
- **经过验证的客户端是 `scripts/baichuan_final.py`** —— 对讲机构建所依赖的 Baichuan 扬声器
客户端(文本 → ElevenLabs → ADPCM → 门铃扬声器)。它已在实机硬件上完成验证。
- `scripts/baichuan_speak.py` 和 `scripts/doorbell_speak.py` 是**已废弃的**突破前
草稿,仅供历史记录保留——请勿使用。
- 完整的攻关故事 + 协议事实:`docs/doorbell-intercom-journey.md`。
## 三条严格的安全规则
该系统的构建经过深思熟虑,确保:
1. **它永远无法采取物理行动。** 没有解锁,没有开栓,没有报警——绝对不行。负责
撰写回复的 AI 没有任何可调用的工具,并且唯一与 Home Assistant 通信的部分只能*读取*
状态并*通知*所有者,没有任何途径可以命令锁或执行器。这是结构性的保证,而
非一句口头承诺(并且已由测试锁定)。
2. **它绝不猜测名字。** 只有在人脸识别确信*且*
无歧义时,家庭成员才会被按名问候;在所有不确定的情况下,都会回退到通用问候。
3. **人脸数据保留在本地。** 人脸/生物识别数据永远不会离开本地硬件。云端(Claude、
ElevenLabs)只会接收到对话文本,并且识别出的名字是在本地应用的,
在回复撰写完成后——因此没有云端模型能将身份与对话关联起来。
## 构建方式
- **`doorbell_ai/`** —— 长期运行的对讲机进程(配置、触发器 + 门控、对话
循环、麦克风捕获 + 语音端点检测、本地 Whisper、回复撰写器、语音播放步骤、
Home Assistant 读取/通知客户端,以及名字名册)。
- **`scripts/baichuan_final.py`** —— 经过验证的 Baichuan 扬声器客户端(作为子进程调用)。
- **`ha/doorbell_ai.yaml``** —— 唯一的 Home Assistant 自动化配置,将按门铃或
门口有人转化为循环监听的 MQTT 触发器。
- **`Dockerfile` + `entrypoint.sh`** —— 容器及其基于 Infisical 的密钥注入。
- **`docs/deployment.md`** —— 如何构建、运行和发布它。
- **`docs/TECHNICAL_SOW.md`** —— 工作范围;**`docs/DECISIONS.md`** —— 构建的决策日志。
## 我可以使用这个吗?
诚实的回答:这是一个**个人展示项目,而非产品**——一个门铃,一扇大门,没有
支持,并且 Baichuan 协议本质上对固件极其敏感(Reolink
更新中的握手更改可能会破坏扬声器路径,直到它被重新逆向工程)。可重用性明确
不是其目标。话虽如此,有三个层次确实值得借鉴:
1. **Baichuan 扬声器客户端 + 协议说明**(`scripts/baichuan_final.py`、
`docs/doorbell-intercom-journey.md`)—— 针对 Reolink 门铃的音频输出文档。如果你拥有
类似的硬件,这就是你要找的部分;即使在你的固件上客户端失效了,
协议笔记也是指引你的地图。
2. **胶水循环,如果你的家庭实验室匹配** —— 所有特定于设置的内部都来自配置,因此一套
由 Reolink + Home Assistant + Mosquitto + Ollama 主机(Frigate 是可选的,用于
按名问候)组成的系统确实可以通过填入 `.env` 格式的值来运行它。除了
“在我的设备上能跑”之外,不作任何承诺。
3. **安全模式** —— 具有零可调用工具的回复撰写 LLM,一个在结构上没有命令接口的
Home Assistant 客户端,一个绝不猜测名字的置信度底线,以及一个
新鲜度校验门槛,确保永远不会播报过时的识别结果。这些可以迁移到任何硬件上的
任何 AI 门口项目,也是最值得复制的部分。
## 运行说明
所有特定于设置的参数(地址、凭据、entity ID、语音)都来自运行时的
Infisical——没有任何内容被硬编码。完整的构建/运行步骤请参见 **`docs/deployment.md`**;
简短版本:创建一次被 git 忽略的 `.deploy.env`,然后每次重新部署只需运行 `./deploy.sh`
(拉取 → 构建 → 镜像内冒烟检查 → 切换 → 验证)。变量名已记录在
`.env.example` 中。
## 更多文档
- `CHANGELOG.md` —— 构建过程、第一个上线日及其暴露的缺陷。
- `docs/increments/INC-001.md` —— 部署后的强化增量(包含其自身的范围规范)。
- `docs/doorbell-intercom-journey.md` —— 逆向工程记录 + 协议事实。
- `docs/doorbell-audio-pipeline-status.md` —— pipeline 状态,包括 QuickReplyPlay HTTP 兜底。
- `docs/doorbell-intercom.md` —— 早期的架构笔记。
- `docs/frigate-doorbell-integration.md` —— Frigate 人员检测集成。
- `docs/doorbell-installation-plan.md` —— 原始硬件安装计划。
- `docs/standards/` —— 编码标准、项目结构和领域词汇表。
标签:AI对话助手, AI风险缓解, 协议逆向工程, 智能门铃, 物联网, 语音交互, 请求拦截, 边缘AI, 逆向工具