面向本地日程、提醒、存储、语音和消息渠道的设备端系统
几个模块一起交付:日程负责记录安排,定时任务负责触发,设备运行时负责组装,语音、存储和 IM 通过适配器接入。
Important
当前 main 已完成仓库范围内的功能开发:日程与提醒、持久化存储、语音/Linx、SparkBot 音频与显示、MCP 工具、IM Gateway 以及 Profile 驱动 Runtime 均已接入,并由主机测试、CI 和已有设备验证覆盖。部署到具体硬件或外部服务时,仍需按文档配置凭据并执行现场验证。
VoiceLife 把安排、触发和通知拆开,让它们可以分别演进:
- 日程记录“要做什么”。
- 定时任务记录“什么时候触发哪一次”。
- 存储模块负责原子写入、重启恢复和健康指标。
- 语音与 IM 模块把外部平台转换成稳定的领域事件。
- Runtime 只负责把选定的实现组装起来,不承载业务规则。
这套拆分是为了让不同模块可以并行开发,也让某个外部平台暂时不可用时不影响其他模块的主机测试。
需要 CMake。构建设备固件时还需要 ESP-IDF 6.0.2;Ninja 可选。
# 提交前完整检查,不需要 ESP-IDF
./scripts/run_pre_submit_checks.sh
# 运行指定的主机测试
./scripts/run_host_tests.sh -R schedule_policy_test
# 查看和校验固件 Profile
python3 scripts/firmware.py list
python3 scripts/firmware.py validateIM Gateway 的 PostgreSQL 契约测试使用仓库根目录的 Compose 配置:
docker compose up -d postgres
pnpm --dir services/im-gateway test没有 PostgreSQL 时,相关契约测试会跳过,其余测试仍可运行。
构建设备固件:
source /path/to/esp-idf-v6.0.2/export.sh
python3 scripts/prepare_sqlite.py
python3 scripts/firmware.py build esp32s3-esp-sparkbot
python3 scripts/firmware.py package esp32s3-esp-sparkbotVoiceLife 使用 ESP-IDF 组件化模块单体。核心代码使用 C++,外部 SDK、网络库、平台格式和板卡驱动只能通过 Port 或 Adapter 进入。
| 组件 | 负责什么 | 主要依赖 |
|---|---|---|
voicelife_contracts |
Status、Result、事件和跨模块公共契约 | 无 |
voicelife_schedule |
日程实体、命令、结果和服务接口 | contracts |
voicelife_timing |
定时任务、实例和提醒规则 | contracts |
voicelife_storage_fatfs |
Flash 分区校验、Wear Levelling、FATFS 挂载生命周期和容量 | contracts;ESP 端依赖 fatfs、esp_partition |
voicelife_storage_sqlite |
SQLite 连接、Schema/迁移、完整性检查、业务 SQL 与 Repository | contracts、schedule;设备 Profile 启用时需要 sqlite3、FATFS/WL |
voicelife_im |
平台无关的 IM 事件、上报和传输契约 | contracts |
voicelife_voice |
语音会话、音频/传输 Port 和 Provider Registry | contracts |
voicelife_linx |
Linx/XRobot 协议和 Provider Adapter | contracts、voice |
voicelife_linx_esp |
ESP32-S3 WSS/TLS Transport 和分片重组 | contracts、linx |
voicelife_audio_esp |
ESP32-S3 音频 Profile、探针和设备端 Port | contracts、voice |
voicelife_board_esp |
ESP-SparkBot 板级 Profile、能力矩阵、共享电源仲裁和身份探针 | contracts |
voicelife_mcp |
工具 Schema、注册中心和调用路由 | contracts |
voicelife_runtime |
唯一组装入口,按生命周期启动和回滚基础设施 | contracts、mcp、voice、linx、storage adapters |
依赖方向只有一条:适配器依赖用例,用例依赖领域,领域不认识 ESP-IDF、HTTP 或平台 SDK。CI 会运行 scripts/check_architecture.sh 检查组件清单、命名空间和依赖图。
每个模块先写稳定契约,再接入真实实现。主机测试覆盖状态、错误和跨模块串联;设备测试只验证设备才能证明的内容,例如分区恢复、I2S 生命周期和资源水位。
Profile 描述一次可发布固件选择哪些实现,不保存凭据。默认生产 Profile 是 esp32s3-esp-sparkbot:
{
"schemaVersion": 1,
"id": "esp32s3-esp-sparkbot",
"target": "esp32s3",
"adapters": {
"audio": { "driver": "esp32s3-es8311-duplex", "capabilities": ["es8311-duplex"] },
"speech": { "driver": "xrobot-websocket", "capabilities": ["streaming-asr", "tts", "cancel-generation", "pcm"] },
"storage": { "driver": "fatfs-sqlite", "capabilities": ["persistent-sqlite", "atomic-calendar-write", "durable-calendar"] },
"im": { "driver": "voicelife-gateway", "capabilities": ["https", "secure-credentials"] }
}
}凭据只使用 secret://、nvs:// 或 env:// 引用,不写进 Profile、日志或 Git。新增平台时,实现 Adapter、声明能力、补契约测试,再修改部署配置;业务模块不写平台判断。
功能开发已完成,当前进入维护、发布和部署验证阶段:
| 方向 | 状态 | 说明 |
|---|---|---|
| 组件边界和依赖检查 | 已完成 | 主机与 CI 可验证 |
| 日程与定时提醒 | 已完成 | 日程、周期规则、精确触发、确认/稍后提醒、动作幂等和持久化重放已接入 Runtime |
| SQLite 持久化存储 | 已完成 | FATFS/Wear Levelling、SQLite Schema/迁移、重启恢复和健康检查已接入生产 Profile |
| IM Gateway | 已完成 | PostgreSQL 持久化、Koishi Runtime、微信公众号 Webhook/模板投递、H5 Action UI 和 SSE 动作流已交付 |
| 语音、音频和 Linx 适配器 | 已完成 | ESP32-S3 PCM/I2S、ES8311 双工、Linx WSS/TLS、ASR/TTS、Opus 和会话状态机已接入 |
| SparkBot 显示与板级能力 | 已完成 | GIF 资源分区、表情渲染、按键、电源仲裁和显示状态联动已接入 |
| MCP 工具与跨端契约 | 已完成 | 工具 Schema、调用路由、日程操作和 C++/TypeScript 双端契约测试已固定 |
| Profile 驱动 Runtime | 已完成 | Profile 校验、能力声明、凭据引用和生命周期启动/回滚已接入 |
| 测试与发布门禁 | 已完成 | 主机测试、Python 检查、IM Gateway 契约测试、架构检查和 CI 覆盖率门禁已配置 |
| 真机闭环与用户试用 | 未开始 | 进入对应功能 Issue 后再验收 |
VoiceLife/
├── components/ # C++ 组件
├── config/ # Profile 和 Schema,不放凭据
├── docs/ # 架构、工程、协作文档和展示资源
├── main/ # ESP-IDF app_main
├── scripts/ # 构建、测试、检查和设备恢复工具
├── services/ # 设备外的服务,例如 IM Gateway
├── tests/ # 主机、Python 和必须上板的测试
└── third_party/ # 第三方源码和许可证
README 只保留项目入口和跨模块信息。当前维护文档按文档导航组织;研究、阶段草稿和一次性证据留在对应 Issue、PR 或 Git 历史,避免把某一个模块的过程材料当成整个项目的产品说明。
- 架构与适配器设计规范
- ADR 0001:组件化模块单体与 Ports/Adapters
- ADR 0002:能力驱动的适配器 Profile
- SQLite 实板验证与 Flash 恢复手册
- 硬件调试与串口日志规则
- SparkBot 显示组件说明
- IM Gateway 运行手册
- 协同开发规范
- 提交描述规范
- 参与开发
设备侧部分实现参考了 78/xiaozhi-esp32 的音频、协议和构建经验。具体迁移范围和许可证记录在 THIRD_PARTY.md。

