LOG · 日志

twinsia

DATE 日期
2026-10-23
SOURCE 源码
开发/twinsia.md
READ 阅读
~6 min

Twinsia

把居家里的 Zigbee 传感器和智能床垫接进一套系统,统一成设备能力与事件,再用 3D 场景、看板和家属端页面呈现。

状态:管理端可用;家属端与照护员工作区待生产验收(只读,无下行控制);入口:https://twinsia.205716.xyz(单镜像 + nginx 反代);仓库:本仓库

本质

把 Zigbee 与床垫数据统一成设备能力与事件、再供三端查看的 IoT 数字孪生。

选型

基于 Bun + Elysia 的单体应用,前端 React + Mantine + R3F,数据 PostgreSQL + Drizzle,硬件 Zigbee2MQTT + TCP 床垫,部署单镜像 Compose。

  • 前端
    • React 19
      • Vite
      • react-router-dom
      • TanStack Query
      • Zustand
      • Mantine 9
      • Tabler Icons
      • ECharts
      • React Three Fiber
      • Drei
      • three
  • 后端
    • Bun
      • Elysia
        • Eden
        • mqtt.js
        • Bun.listen
  • 数据
    • PostgreSQL 17
      • Drizzle ORM
        • drizzle-kit
    • Mosquitto
  • 契约
    • @twinsia/contracts
    • @twinsia/shared
  • 硬件
    • Zigbee 传感器
      • Zigbee2MQTT
    • 智能床垫
    • ESP32
    • EFR32
  • 工程
    • Biome
    • husky
    • commitlint
  • 部署
    • Docker Compose
    • Nginx

功能

  • 四个设备包(床垫、门窗、温湿度、人体感应)带 matcher 与事件派生器;未知数据源进 unknown_sources,可在 Discovery 页认领
  • 床垫 TCP:HT MsgPack 帧(0xABCD + CRC8),按首包魔数探测协议,未知协议直接断开
  • 存储:telemetry 原始样本(幂等键 + upsert)、telemetry_buckets(5m/1h/1d)、events;保留窗 14/30/400 天,1d 与安全事件永久
  • 告警四类:数值越界、离床、未翻身、失联;可用性 stale/offline 与缺口检测独立扫描
  • 路由:entities / sources / health(诊断 v2)/ family / caregiver / simulator,另有告警、分析、设备模块
  • 实时:/ws 需 devices.read,/api/family/ws 按授权设备过滤并在心跳时刷新
  • 管理端 14 个 feature:工作区、人员、设备、2D 平面与 3D 总览、场景编辑与家具工坊、时间线、事件、告警、分析、模拟器、IoT 调试、运维
  • 家属端 /family/:近况、设备、事件、场景预览、健康趋势、认知关怀、照护计划、档案、通知中心、求助;照护员在 /caregiver 接收、处置、升级、接手、完成
  • 门禁 14 步、78 个测试文件;迁移链 39 个 SQL

启动流程

bun install
bun run dev        # server 3000 + 管理端 5173 + 家属端 5174
curl http://localhost:3000/api/health

bun run dev:server       # 也可分开起
bun run check            # 14 步门禁
bun run db:smoke         # 临时库重放迁移链
bun run todo             # 打印当前协作方向

需要 Bun 1.3.14 与本机 PostgreSQL(默认库名 twinsia);首次启动自动迁移,SEED_DEMO_DATA=true 写入模拟床垫、一个地点三间房和 24h 历史。环境变量以 apps/server/src/config.ts 为唯一权威;本地接 MQTT 前需按 docs/01-指南/开发指南.md 生成 infra/mosquitto/passwd。管理员初始口令只是本机开发默认值,生产必须用 AUTH_ADMIN_PASSWORD 覆盖。

边界与已知问题

  • 家属端受护人查询曾因迁移 0036 被追改返回 500,本地 0038 补列,待发布复验
  • 家属端跨 app import apps/web/src 却没声明 @twinsia/web 依赖,也没有错误边界,chunk 失败会整页白屏
  • 保留窗只到脚本:宿主 cron 与滚动重算未实现,遥测仍靠人工裁剪
  • 回滚只回镜像,不回 schema;备份产物校验不等于恢复演练
  • 虚拟人只有程序化人形与行走/坐躺/过门,presence、sleep_state、bed_in/out、turn_over 未接入状态机
  • 3D 无自动化测试;演示场景按固定 9×6 摆位,在 6×4 / 5×5 房间里家具会落到房外
  • 空间模型只有矩形房间 + 隔墙,异形轮廓与门洞语义待排期
  • 文档比代码旧:adapters/ 目录不存在(实际在 modules/ingestion/protocols 与 modules/device-packs);设计文档写 TanStack Router,代码用 react-router-dom;接入设计把 zigbee_* 记为骨架,实际已实现
  • 依赖变更必须用 Bun 1.3.14 刷新锁文件;pre-push 只在迁移或 schema 变动时跑 db:smoke
  • 小程序未开始;窄屏只在桌面常见分辨率验证过

文档索引