ARTIFACT / TWINSIA
Twinsia
ACTIVE SYSTEM把居家里的 Zigbee 传感器和智能床垫接进一套系统,统一成设备能力与事件,再用 3D 场景、看板和家属端页面呈现。
◈ System Profile ◈
◈ Access · 访问入口 ◈
◈ Sections · 章节 ◈
◈ README ◈
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
- React 19
- 后端
- Bun
- Elysia
- Eden
- mqtt.js
- Bun.listen
- Elysia
- Bun
- 数据
- PostgreSQL 17
- Drizzle ORM
- drizzle-kit
- Drizzle ORM
- Mosquitto
- PostgreSQL 17
- 契约
- @twinsia/contracts
- @twinsia/shared
- 硬件
- Zigbee 传感器
- Zigbee2MQTT
- 智能床垫
- ESP32
- EFR32
- Zigbee 传感器
- 工程
- 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 - 小程序未开始;窄屏只在桌面常见分辨率验证过
文档索引
- docs/README.md — 文档总索引
- docs/01-指南/开发指南.md — 开发
- docs/02-设计/关系与演进设计.md — 设计
- TODO.md — 当前任务