首页
/ RuView 无线感知接入 Home Assistant 全指南:MQTT 自动发现(HA-DISCO)与 Matter Bridge(HA-FABRIC)双协议架构实战

RuView 无线感知接入 Home Assistant 全指南:MQTT 自动发现(HA-DISCO)与 Matter Bridge(HA-FABRIC)双协议架构实战

2026-09-07 14:51:13作者:温玫谨Lighthearted

RuView 通过 WiFi CSI 感知可输出人体存在、人数、17 关键点姿态、呼吸率/心率、跌倒、动作能量与区域占用等遥测数据。本文以 ADR-115-home-assistant-integration.md 为骨架,结合 docs/integrations/home-assistant.mddocs/integrations/semantic-primitives-metrics.md 以及 v2/crates/wifi-densepose-sensing-server 的源码,完整讲解"MQTT 自动发现为主、Matter 桥接为辅"的双协议 Home Assistant 集成方案。读完本文,你将掌握:实体/主题映射规则、自动发现消息格式、QoS/限速/隐私策略、全部 CLI 配置项、10 个语义自动化原语的触发逻辑,以及可复现的端到端验收方法。


1. 背景:为什么需要一等公民的 Home Assistant 接入

RuView 与底层 WiFi-DensePose 栈已经能通过 Rust 实现的 wifi-densepose-sensing-server(源码位于 v2/crates/wifi-densepose-sensing-server)输出丰富的人体感知遥测。服务器通过 WebSocket 在 /ws/sensing 上广播三类结构化消息,它们是后续所有集成映射的数据源

服务器消息 type 代码位置 负载关键字段
pose_data main.rs 每次检测 17 关键点、confidencetrack_id
edge_vitals 同上 node_idpresencefall_detectedmotionbreathing_rate_bpmheartrate_bpmn_personsmotion_energypresence_scorerssi
sensing_update 同上 聚合检测结果 + 区域命中

运行 Cognitum Seedcognitum-v0 应用,:9000)或独立 ESP32-S3 / ESP32-C6 节点的用户,希望这些遥测直接进入 Home Assistant (HA)——全球部署最广的开源家庭自动化中枢、MQTT 原生支持——以便直接用存在、生命体征、跌倒与动作来构建自动化,而不必手写代码对接 REST/WebSocket API。

ADR-115 指出两个客户侧问题的本质相同(详见 docs/adr/ADR-115-home-assistant-integration.md):

  • #574:用户不想手动粘贴 seed:// URL,期望中枢自动发现节点(mDNS);
  • #760:用户期望"单一仪表盘看到所有传感器"的 HA 式体验,而非被迫使用 RuView 自己的 UI。

两者共同诉求是:RuView 不应是"需要胶水代码才能融入智能家居的黑盒",而应是开箱即用的感知节点。

依据 ADR-115 现状记录:MQTT 主线(P1–P7、P8a、P9、P10)已于 2026-05-23 随 PR #778 落地并标记 Accepted;Matter SDK 接线部分(P8b)按文档延后至 v0.7.1。本文以文档+仓库现状为准进行说明。

1.1 行业对标与本 ADR 的边界

ADR 中对标了 espectre.dev(仅姿态、无生命体征、闭源服务器)、tommysense.com(仅生命体征且强制云)、Aqara FP2(原生 ZigBee、存在+分区)、ESPHome 刷写的 HLK-LD2410 等,行业标杆是"Aqara FP2 的 HA 原生体验 + 低成本即插即用"。RuView 的差异化能力是姿态、心率/呼吸率、跌倒、多房间,因此需要"一等公民"HA 集成来承载这些能力。

同时 ADR 明确了边界:不是 HACS Python 集成(仅作为后续项);不是单向 webhook 推送;不改动 ADR-018 CSI 帧格式或 ADR-039 边缘生命体征报文;不改固件,ESP32-S3 与 ESP32-C6 路径保持字节级不变。


2. 双协议决策:MQTT 主、Matter 次

ADR-115 的核心决策是互补而非互斥的双路径:

  1. 主路径 — MQTT + HA 自动发现(代号 HA-DISCO):在 wifi-densepose-sensing-server 中新增 MQTT 发布器,连接用户提供的 broker(默认 mqtt://localhost:1883),启动时及周期刷新(默认 600 s)时对每个 RuView 节点、每个能力发布一条 HA discovery 消息;把每次 WebSocket 广播(edge_vitals / pose_data / sensing_update)翻译为逐实体的 MQTT 状态消息;并通过 --privacy-mode 在发布前剥离生物特征(HR/BR/姿态关键点)。
  2. 次路径 — Matter Bridge(代号 HA-FABRIC):把 RuView 节点以 Matter Bridged Device 形式暴露到 WiFi 网络上,覆盖 Matter 目前标准化的子集——存在(OccupancySensing)、动作(BooleanState)、跌倒事件(Switch 作为事件)、人数(桥上的数值属性),可被 Apple Home / Google Home / Amazon Alexa / Samsung SmartThings / HA 自身任一 Matter 控制器消费。生物特征(HR/BR)与姿态在 Matter 规范添加可表达的设备类型之前,只走 MQTT。

ADR 给出了四方案对比,核心取舍如下:

准则 A. MQTT 自动发现 D. Matter Bridge B. HACS Python 集成 C. REST webhook
端用户零代码 UX 是(HA 自动建实体) 是(扫码配网) 是(安装后) 否(手工接线)
跨生态覆盖 HA + 任意 MQTT 消费端 Apple/Google/Alexa/SmartThings/HA 仅 HA 仅 HA
分发与维护 既有 crate 一个 Rust feature 一个 Rust feature + Matter SDK 链接 新 Python 仓库 + HACS 审核 极简
实体自动发现 是(homeassistant/ 主题命名空间) 是(Matter commissioning + bridge endpoint) 是(config flow)
双向控制 是(订阅 command topic) 是(Matter commands) 仅单向
承载 HR/BR/姿态 否(无对应 cluster) 是(自定义) 是(自定义)
承载存在/人数/跌倒 是(Matter 1.3+)
无 HA 也能用 任意 MQTT 消费端 任意 Matter 控制器 仅 HA 仅 HA
MVP 工作量 ~2 周 ~4–6 周 ~4–6 周 ~2 天

MQTT 是主路径,因为它能承载 100% 的差异化遥测(姿态、HR、BR),其他路径做不到;Matter 是次路径,因为它覆盖约 30% 的子集(存在/人数/跌倒),却能触及不运行 HA 的另一部分用户。webhook(C)因无实体发现、无控制平面被否决;HACS(B)体验更精致但成本更高,留待 MQTT 落地数据出来后复审。


3. 实体映射与 MQTT 主题结构

3.1 实体映射表

每个 RuView 节点对应 HA 中一个 device,每个能力对应其上一个 entity;ESP32 节点若挂在 Cognitum Seed 之后,通过 via_device 关联,HA 界面即可呈现树状拓扑。

能力 HA 组件 device_class state_class 单位 图标 WS 源字段
Presence binary_sensor occupancy mdi:motion-sensor edge_vitals.presence
Person count sensor measurement persons mdi:account-group edge_vitals.n_persons
Breathing rate sensor measurement bpm mdi:lungs edge_vitals.breathing_rate_bpm
Heart rate sensor measurement bpm mdi:heart-pulse edge_vitals.heartrate_bpm
Motion level sensor measurement % mdi:run edge_vitals.motion(0–1 → ×100)
Motion energy sensor measurement 无量纲 mdi:waveform edge_vitals.motion_energy
Fall detected event mdi:human-fall edge_vitals.fall_detected
Presence score sensor measurement % mdi:gauge edge_vitals.presence_score(×100)
RSSI sensor signal_strength measurement dBm mdi:wifi edge_vitals.rssi
Zone occupancy(每区) binary_sensor occupancy mdi:map-marker sensing_update.zones[*]
Pose keypoints sensor(JSON 属性) mdi:human pose_data.keypoints(opt-in)
Tracked persons(按 ID) binary_sensor(动态) occupancy mdi:account pose_data.track_id

姿态关键点不设为一等实体:HA 没有"17 关键点"原语,因此以 wifi_densepose_<node>_pose 传感器的属性负载暴露,高级用户可对其做 template,而默认 HA UI 保持整洁。

3.2 MQTT 主题结构

遵循 HA 官方 discovery 约定 homeassistant/<component>/<object_id>/<entity>/config;object id 取 wifi_densepose_<node_id> 以与其他设备隔离命名空间:

homeassistant/binary_sensor/wifi_densepose_<node_id>/presence/config       (retained, QoS 1)
homeassistant/binary_sensor/wifi_densepose_<node_id>/presence/state         (not retained, QoS 0)
homeassistant/binary_sensor/wifi_densepose_<node_id>/presence/availability  (retained, QoS 1)

homeassistant/sensor/wifi_densepose_<node_id>/heart_rate/config            (retained, QoS 1)
homeassistant/sensor/wifi_densepose_<node_id>/heart_rate/state              (not retained, QoS 0)

homeassistant/sensor/wifi_densepose_<node_id>/breathing_rate/config
homeassistant/sensor/wifi_densepose_<node_id>/breathing_rate/state

homeassistant/event/wifi_densepose_<node_id>/fall/config                   (retained, QoS 1)
homeassistant/event/wifi_densepose_<node_id>/fall/state                     (not retained, QoS 1)

ruview/<node_id>/raw/pose                                                  (opt-in, not retained, QoS 0)
ruview/<node_id>/raw/sensing_update                                        (opt-in, not retained, QoS 0)

ruview/<node_id>/raw/* 命名空间刻意置于 homeassistant/ 之外:它承载原始 WebSocket JSON,供 Node-RED / Grafana / 自定义脚本直接消费,避免 HA 试图把它解析为实体。

3.3 自动发现负载示例

Presence(binary_sensor) 的 discovery payload:

{
  "name": "Presence",
  "unique_id": "wifi_densepose_aabbccddeeff_presence",
  "object_id": "wifi_densepose_aabbccddeeff_presence",
  "state_topic": "homeassistant/binary_sensor/wifi_densepose_aabbccddeeff/presence/state",
  "availability_topic": "homeassistant/binary_sensor/wifi_densepose_aabbccddeeff/presence/availability",
  "payload_on": "ON",
  "payload_off": "OFF",
  "payload_available": "online",
  "payload_not_available": "offline",
  "device_class": "occupancy",
  "qos": 1,
  "device": {
    "identifiers": ["wifi_densepose_aabbccddeeff"],
    "name": "RuView node aabbccddeeff",
    "manufacturer": "ruvnet",
    "model": "ESP32-S3 CSI node",
    "sw_version": "v0.6.7",
    "via_device": "cognitum_seed_1"
  },
  "origin": {
    "name": "wifi-densepose-sensing-server",
    "sw_version": "0.7.0",
    "support_url": "https://github.com/ruvnet/RuView"
  }
}

Heart rate(sensor) 的 discovery payload:

{
  "name": "Heart rate",
  "unique_id": "wifi_densepose_aabbccddeeff_heart_rate",
  "state_topic": "homeassistant/sensor/wifi_densepose_aabbccddeeff/heart_rate/state",
  "availability_topic": "homeassistant/sensor/wifi_densepose_aabbccddeeff/heart_rate/availability",
  "unit_of_measurement": "bpm",
  "state_class": "measurement",
  "icon": "mdi:heart-pulse",
  "value_template": "{{ value_json.bpm }}",
  "json_attributes_topic": "homeassistant/sensor/wifi_densepose_aabbccddeeff/heart_rate/state",
  "qos": 0,
  "device": { "identifiers": ["wifi_densepose_aabbccddeeff"] }
}

其状态负载形如:{ "bpm": 68.2, "confidence": 0.91, "ts": "2026-05-23T14:00:00Z" }

Fall(event) 的 discovery payload:

{
  "name": "Fall detected",
  "unique_id": "wifi_densepose_aabbccddeeff_fall",
  "state_topic": "homeassistant/event/wifi_densepose_aabbccddeeff/fall/state",
  "event_types": ["fall_detected"],
  "icon": "mdi:human-fall",
  "qos": 1,
  "device": { "identifiers": ["wifi_densepose_aabbccddeeff"] }
}

每次跌倒仅触发一次、不 retained 的事件状态负载:{ "event_type": "fall_detected", "ts": "2026-05-23T14:00:00.123Z", "confidence": 0.87 }

源码佐证:上述结构的实现位于 mqtt/discovery.rs,其中 DiscoveryConfig / DeviceMeta / OriginMeta 均为 Serialize-only 结构体(只发不解析),字段名对齐 HA 官方 discovery schema(当前测试基线为 HA 2025.5)。发现模块的单元测试直接断言 unique_id == "wifi_densepose_aabbccddeeff_presence" 以及状态/可用性主题的路径形态,可作模式参考。

3.4 设备级分组

  • 每个 RuView 节点(ESP32-S3 / S3-Mini / C6,或 mock 模式下的宿主)= 一个 HA device;
  • device.identifiers = ["wifi_densepose_<node_id>"]node_id 取自 edge_vitals.node_id(MAC 派生);
  • Cognitum Seed 之后的子节点设置 device.via_device = "cognitum_seed_<seed_id>",HA 按树状渲染(Seed → 子节点);
  • Seed 本身作为父设备出现,携带自身的诊断实体(uptime、agent health),由 Seed 直接发布而非 sensing-server。

4. QoS、保留、刷新与 LWT 可用性

不同主题的生命周期语义差异决定了 QoS/retain/刷新策略:

主题 QoS Retain 刷新节奏 理由
*/config 1 启动时 + 每 600 s HA 期望 retained discovery;周期重发可在 HA 重启后自愈
*/state(sensor) 0 按 §6 限速 best-effort,HA 容忍偶发丢帧
*/state(binary_sensor) 1 仅变化时 末值重要,新订阅者应看到当前状态
*/state(event) 1 事件发生时 跌倒不可漏报;绝不 retained,避免 HA 重放旧事件
*/availability 1 LWT + 30 s 心跳 离线检测
ruview/*/raw/* 0 随数据发布 原始 firehose,消费端 opt-in

Last Will and Testament (LWT):连接成功时 sensing-server 在每个实体 availability 主题上设置 LWT 为 offline(retained);成功连接后发布 online(retained);随后以 30 s 心跳重发 online,使 HA 能识别僵尸会话。LWT 三元组:主题 .../<entity>/availability、payload offline、QoS 1、retain true。实现见 mqtt/mod.rsmqtt/discovery.rs 中的 AvailabilityPayload::for_entity


5. 带宽控制与限速

姿态关键点以 10 fps × 17 关键点 × 3 浮点约等于每人 4–8 kbit/s,LAN 内可接受,但若用户误路由到计费的蜂窝 MQTT 桥则很危险,因此默认值整体保守:

实体类型 默认速率 可配置 覆盖 flag
Presence(binary) 仅变化时
Person count 1 Hz --mqtt-rate-count=1
BR / HR 0.2 Hz(每 5 s) --mqtt-rate-vitals=0.2
Motion level 1 Hz --mqtt-rate-motion=1
Fall events 事件即时 否(始终即时)
RSSI 0.1 Hz --mqtt-rate-rssi=0.1
Pose keypoints 默认关闭,开启时 1 Hz --mqtt-publish-pose --mqtt-rate-pose=1
Zones 仅变化时

6. 配置:CLI 全量参数与环境变量

wifi-densepose-sensing-server 通过 --mqtt 门控 MQTT 发布器。完整的参数族与默认值(均以 cli.rs 的解析逻辑及 docs/integrations/home-assistant.md 为准):

--mqtt                          Enable MQTT publisher (default off)
--mqtt-host <HOST>              MQTT broker host (default: localhost)
--mqtt-port <PORT>              MQTT broker port (default: 1883, 8883 if --mqtt-tls)
--mqtt-username <USER>          MQTT username
--mqtt-password-env <ENVVAR>    从环境变量读密码 (default: MQTT_PASSWORD)
--mqtt-client-id <ID>           Client ID (default: wifi-densepose-<hostname>)
--mqtt-prefix <PREFIX>          Discovery prefix (default: homeassistant)
--mqtt-tls                      启用 TLS (default off)
--mqtt-ca-file <PATH>           CA bundle (default: system trust)
--mqtt-client-cert <PATH>       mTLS 客户端证书
--mqtt-client-key <PATH>        mTLS 客户端私钥
--mqtt-refresh-secs <N>         Discovery 刷新间隔 (default: 600)
--mqtt-rate-vitals <HZ>         生命体征发布速率 (default: 0.2)
--mqtt-rate-motion <HZ>         Motion 发布速率 (default: 1.0)
--mqtt-rate-count <HZ>         人数发布速率 (default: 1.0)
--mqtt-rate-rssi <HZ>           RSSI 发布速率 (default: 0.1)
--mqtt-publish-pose             发布姿态关键点 (default off)
--mqtt-rate-pose <HZ>           姿态开启时的发布速率 (default: 1.0)
--privacy-mode                  发布前剥离生物特征 (HR/BR/pose)

环境变量等价形式遵循 RUVIEW_MQTT_HOSTRUVIEW_MQTT_USERNAME 等命名,方便 Docker / systemd 用户免于长参数串。配置优先级为 CLI > env > 默认值。语义原语相关参数(--semantic--semantic-thresholds-file--semantic-zones-file--semantic-baseline-window-days、可重复的 --no-semantic <primitive>)与 Matter 参数(--matter--matter-setup-file--matter-reset--matter-vendor-id--matter-product-id)也统一由 cli.rs 声明。

几个值得注意的源码事实(见 Cargo.toml):

  • rumqttc 依赖被门控在 mqtt Cargo feature 之后,未启用 --mqtt 的用户零二进制/运行时成本
  • feature 关闭时 --mqtt-* 参数仍可解析(cli.rs 无条件声明),运行时若启用 --mqtt 则记 WARN、publisher 空转,避免用户误以为参数未生效;
  • mqtt = ["dep:rumqttc"],并带有 mqtt_throughput bench(requires-features mqtt);
  • cli.rs 单测覆盖默认值断言(--mqtt 默认 false、matter_vendor_id 默认 0xFFF1matter_product_id 默认 0x8001semantic 默认 on、semantic_baseline_window_days 默认 14)以及完整参数组合解析和 --no-semantic 可重复性。

状态编码与限速器(mqtt/state.rs)刻意在无 rumqttc 时也能编译,从而可在 --no-default-features 下测试;只有真正持有 rumqttc::AsyncClient 的 publisher(mqtt/publisher.rs)才需要该 feature。

6.1 配置文件格式

区域标签文件(传给 --semantic-zones-file):

# semantic-zones.yaml
zones:
  bathroom: ["zone_3", "zone_7"]
  bedroom:  ["zone_1"]
  kitchen:  ["zone_2"]
  living:   ["zone_5"]
bed_zones: ["zone_1"]

阈值覆盖文件(传给 --semantic-thresholds-file):

# semantic-thresholds.yaml
sleep_dwell_secs: 300
distress_hr_multiple: 1.5
room_active_motion_threshold: 0.10
elderly_anomaly_multiple: 2.0
meeting_min_persons: 2
no_movement_dwell_secs: 1800
fall_risk_event_threshold: 70.0

阈值在 Rust 侧位于各原语模块的 PrimitiveConfig,默认值调校偏保守(保精度舍召回),医疗/商用场景建议保留默认或上调。


7. TLS、认证与隐私模式

7.1 传输安全分级(ADR-115 §3.9)

  • 推荐:专用 VLAN 上的 mTLS,broker 固定到按 Cognitum Seed 逐台签发的 CA;
  • 可接受:TLS 之上的用户名+密码(如用户 HA 内现成的 Mosquitto add-on);
  • 否决:与不可信设备共享网络上的明文。当前版本在非 localhost broker 上启用 --mqtt 而未配 --mqtt-tls 时会记 WARN(v0.7.0 行为);按 ADR,v0.8.0 将升级为硬失败(非零退出),详见 docs/integrations/home-assistant.md 的排障说明。

7.2 --privacy-mode

该开关在任何 MQTT 发布之前剥离生物特征及其可推导通道,无论订阅者是谁;此模式下相关实体的 discovery 消息永不发布(HA 甚至不知道它们存在):

通道 默认 --privacy-mode
Presence published published
Person count published published
Motion level published published
Zone occupancy published published
RSSI published published
Breathing rate published stripped
Heart rate published stripped
Fall events published published(安全 > 隐私)
Pose keypoints 默认关 stripped(不可强制开启)

这落实了 ADR-106 的 primitive-isolation 契约:HR/BR/pose 属生物特征级信号,未经操作者显式 opt-in 不得泄漏给不受约束的 MQTT broker。实现在 mqtt/privacy.rs。非 localhost broker 部署务必把 --privacy-mode--mqtt-tls 组合使用。


8. Matter Bridge(HA-FABRIC)

Matter 路径运行在同一 wifi-densepose-sensing-server 进程内,由 --matter feature flag 独立于 --mqtt 门控(仓库中已有 matter/ 模块:bridge / clusters / commissioning)。桥以 Bridged Devices Aggregator(Matter Core Spec §9.13)身份呈现,为每个 RuView 节点提供一个 Bridged Device endpoint,暴露标准化子集;生物特征与姿态不通过 Matter 暴露——规范中没有对应 cluster,用 Generic Sensor 硬套会让所有控制器渲染成无名数字。

8.1 Matter 设备类型映射

RuView 能力 Matter cluster Endpoint 设备类型 源字段
Presence OccupancySensing (0x0406) OccupancySensor (0x0107) edge_vitals.presence
Motion(布尔、超阈值) OccupancySensing (0x0406) (同一 endpoint) edge_vitals.motion > 0.1
Fall event Switch (0x003B) MultiPressComplete 事件 GenericSwitch (0x000F) edge_vitals.fall_detected(一次瞬时按压 = 一次跌倒)
Person count OccupancySensing 扩展属性(厂商自定义 0xFFF1_0001) (同一 endpoint) edge_vitals.n_persons
Zone occupancy 每区一个 OccupancySensor endpoint (多 endpoint) sensing_update.zones[*]
RSSI / motion energy / presence score / BR / HR / pose 不通过 Matter 暴露 (仅 MQTT)

人数用的厂商自定义属性以 RuView 的 CSA 厂商 ID 命名(开发阶段用 0xFFF1)。不认识厂商扩展的控制器仍会看到标准 OccupancySensing.Occupancy 布尔量——优雅降级

8.2 配网与 fabric 模型

  • WiFi 配网:首次启动时桥打印 Matter setup code(11 位短码 + QR 字符串)到日志及 --matter-setup-file <PATH>;用户用 Apple Home / Google Home / HA Matter 集成扫码。
  • 无需 Thread 射频:sensing-server 运行在拥有 WiFi 但无 802.15.4 的宿主(Pi 5、x86、Cognitum Seed),Matter-over-WiFi 足够;Thread 支持明确排除在范围外,直到 ESP32-C6 固件长出 Matter 协议栈(独立 ADR)。
  • 多 admin / 多 fabric:桥接受多次 commissioning 会话,同一节点可同时配入 Apple Home、Home Assistant 与 Google Home——fabric 隔离由 Matter OperationalCredentials cluster 保证。
  • 重置配网--matter-reset 擦除已存 fabric 凭据,允许针对新控制器重新配对。

8.3 SDK 选型与已知局限

ADR 对比了三类 Rust 路径:纯 Rust 的 matter-rs(无 FFI、契合 Rust-only crate 策略、MIT 许可,但成熟度较低)、project-chip/connectedhomeip 的 Rust FFI(参考实现、可认证但引入 CMake/C++ 工具链)、外部独立 Matter 守护进程(解耦 SDK 变动但多一个进程)。暂定 v0.7.0 走 matter-rs,若 P7 试配对暴露认证阻碍再回退 chip-tool FFI。

文档要求前置声明的有意设计限制(详见 docs/integrations/home-assistant.md):

  • Matter 上无 HR、BR、姿态、RSSI——生物特征/详细遥测请用 MQTT;
  • 跌倒事件是一次性的(一次瞬时按压),控制器须订阅事件;
  • 人数是厂商扩展——Apple Home / Google Home 只显示 occupancy on/off,HA 与 SmartThings(带自定义 handler)才显示数值;
  • 多 fabric 下应选定一个"主控制器"承载自动化逻辑,避免竞争触发;
  • Matter 规范禁止这类设备类型携带视频/图像数据,RuView 本也不会暴露。

8.4 双路径去重

同一节点配入 HA 后会以两种方式出现:HA-DISCO 的完整 MQTT 实体集 + HA Matter 集成下的 Matter 设备。两条路径的 unique_id 都设为 wifi_densepose_<node_id>_<entity>,HA 依据 unique_id 去重,用户看不到幽灵设备;Apple Home / Google Home 则看到同一个物理节点而不重复——这正是"选两条协议而非一条"的架构理由。


9. 语义自动化原语(HA-MIND)

原始信号不是产品。用户不想要"手写 Node-RED 流程去阈值化夜间呼吸率以推断睡眠",而是想要一个能直接接进"有人在睡就把走廊灯调到 10%"自动化的 binary_sensor.bedroom_someone_sleeping。ADR-115 §3.12 定义了把 RuView 从"RF 感知"升级为"环境智能基础设施"的推理层——它必须以一等 HA 实体与 Matter 事件交付,而不是 SDK。

9.1 v1 原语目录

每个原语由一到多个原始通道经小型有限状态机(FSM)融合产生,推理在 wifi-densepose-sensing-server 内运行(与 MQTT 发布同处),由 --semantic 门控(默认开)。每个状态变化携带置信度与 explanation 字段供调试。

原语 输入(raw) 输出形态 默认真值条件 迟滞/不应期
Someone sleeping presence + 低动作(<5% 持续 ≥300 s)+ BR 8–20 bpm + 低 HR 变异性 binary_sensor (occupancy) 全部条件同时成立 5 min 后进入;motion >15% ≥30 s 退出
Possible distress 持续 HR 升高(>1.5× 滚动基线 ≥60 s)+ 躁动动作 + 无跌倒 binary_sensor (problem) + event confidence ≥ 0.75 退出后锁存 5 min
Room active presence + 任意 5 min 窗口内 motion >10% ≥30 s binary_sensor (occupancy) 滚动窗口 空闲 10 min 退出
Elderly inactivity anomaly 无动作 + presence 稳定 > N× 滚动日间中位空闲(默认 2×) binary_sensor (problem) + event 模型个性化 每居民基线;每天最多告警 1 次
Meeting in progress 人数 ≥2 + 持续低幅动作(坐姿)+ 安装 speech_band cog 时叠加语音带微动 binary_sensor (occupancy) ≥2 人 + ≥10 min 人数 <2 持续 2 min 退出
Bathroom occupied 标记 bathroom 的区域内 presence 为真 binary_sensor (occupancy) 区域+presence 隐私模式仍保持开启(非生物特征)
Fall risk elevated 近期近跌倒(无确认跌倒的急剧加速度)或步态不稳得分超阈值 sensor(0–100)+ 越阈时 event 模型推导 24 小时窗口
Bed exit (overnight) "someone sleeping" → presence 在 22:00–06:00 本地时间离开床区 event 边沿触发 每次离床一个事件
No movement (safety check) presence 为真 + motion <1% 持续 ≥N min(默认 30) binary_sensor (problem) + event 时长阈值 出现动作即清除
Multi-room transition 10 s 内 track_id 跨区域连续 eventwho_went_from_to 边沿触发 每 track 一个事件

v2 目录(推迟)包括 child-playing、pet-vs-human、agitation-gradient、circadian-phase,待 v1 有现场数据后由独立 ADR 承接。

仓库现状佐证:推理层已按文档结构落地于 semantic/ —— 每个原语一个文件(sleeping.rsdistress.rsroom_active.rselderly_anomaly.rsmeeting.rsbathroom.rsfall_risk.rsbed_exit.rsno_movement.rsmulti_room.rs),加上共享的 common.rsPrimitiveConfig/PrimitiveState/Reason)、bus.rsSemanticBus 聚合输出并向 MQTT + Matter 广播)。semantic/mod.rs 顶部注释明确了四项契约:服务端推理、单一事实源(新增原语=一个文件改动,无需 MQTT discovery schema 或 Matter cluster 变更)、可解释性(reason 负载)、处处迟滞 + 启动 60 s 暖机抑制。

9.2 三层表面的映射

语义原语如何呈现
MQTT (HA-DISCO) 新主题命名空间 homeassistant/binary_sensor/wifi_densepose_<node>/<primitive>/.../event/.../<primitive>/——完整 discovery 负载,explanation 以 json_attributes 承载
Matter (HA-FABRIC) sleeping/active/meeting/bathroom → OccupancySensing(独立 endpoint);distress/inactivity/no-movement/bed-exit/fall-risk-cross → 专用 GenericSwitch endpoint 上的 Switch.MultiPressComplete 事件;fall-risk 得分 → bridge endpoint 上的厂商扩展属性
HA automations 仓库 examples/ha-blueprints 提供 8 个可直接导入的入门 blueprint:01-notify-on-possible-distress.yaml02-dim-hallway-when-sleeping.yaml03-wake-routine-on-bed-exit.yaml04-alert-elderly-inactivity-anomaly.yaml05-meeting-lights-presence-mode.yaml06-bathroom-fan-while-occupied.yaml07-fall-risk-escalation.yaml08-auto-arm-security-when-not-active.yaml
Apple Home scenes 每个 OccupancySensor endpoint 与每个 GenericSwitch 事件经 Matter 触发 Apple Home 场景——无需 HA

9.3 推理质量契约与可解释性

每个原语随附(详见 docs/integrations/semantic-primitives-metrics.md):

  • 在 ADR-079 配对采集 + 合成压力场景构建的留出测试集上发布 precision/recall/F1 基线(v1:someone_sleeping 0.92/0.78、room_active 0.96/0.94、bathroom_occupied 0.99/0.97、bed_exit 0.94/0.89、no_movement 0.91/0.93,其余见指标文档),并给出复现命令(cargo test ... semantic::--source replay ... --metrics-out);
  • 可解释性负载:每次状态变化带 reason: ["motion<5%", "br=12bpm", "presence=true"] 风格的属性,HA 用户可在自动化模板中引用 state_attr(..., 'reason') 排查触发原因;
  • 置信度阈值:逐原语可用 --semantic-thresholds-file 调节,文档说明默认偏保守;
  • 抑制契约:原语在启动后 60 s 暖机期、以及 csi_calibration_in_progress 状态(ADR-014)期间绝不触发。

9.4 对架构的意义

推理位于 semantic_inference.rs 一类新模块,订阅与 MQTT/Matter 相同的 tokio::broadcast 通道,运行各原语 FSM,产出两个输出流:1)新增 broadcast 通道上的 SemanticState 事件,MQTT 与 Matter publisher 共同订阅(同一推理驱动双表面,不重复实现);2)--data-dir 下 append-only 的 semantic_events.jsonl 日志,供离线分析与 ADR-079 配对监督。


10. 快速上手与验收方法

10.1 启动发布器

# Docker(推荐非开发者)
docker run --rm --net=host \
    ruvnet/wifi-densepose:0.7.0 \
    --source esp32 \
    --mqtt --mqtt-host 192.168.1.10 \
    --mqtt-username homeassistant --mqtt-password-env MQTT_PASSWORD

# 或源码运行(Rust 1.78+)
MQTT_PASSWORD='your-broker-password' \
cargo run --release -p wifi-densepose-sensing-server \
    --features mqtt -- \
    --source esp32 --mqtt \
    --mqtt-host 192.168.1.10 \
    --mqtt-username homeassistant

启动约 5 s 内 HA 应自动创建:每节点一个 device、每设备 17+ entities(含 presence、人数、HR/BR、motion、fall、RSSI、zones 与 10 个语义原语)。优雅退出用 Ctrl-C(发布器会先向所有 availability 主题推 offline);kill -9 由 LWT 兜底,约 30 s 内同样生效。

10.2 验收命令(ADR-115 §8,测试 1–7 覆盖 MQTT,8–10 覆盖 Matter)

# 1. mock 源 + MQTT 启动
cargo run -p wifi-densepose-sensing-server -- \
    --source mock --mqtt --mqtt-host localhost --mqtt-prefix homeassistant

# 2. 观察 discovery + state 消息(应见 presence/heart_rate/breathing_rate/motion/
#    fall/person_count/rssi 每个节点每实体一条 config + 周期性 state)
mosquitto_sub -t 'homeassistant/#' -v

# 3. 全工作区测试套件
cd v2 && cargo test --workspace --no-default-features

# 4. discovery 负载 schema 校验
cargo test -p wifi-densepose-sensing-server --features mqtt mqtt::discovery::schema

# 5. 隐私模式剥离生物特征:订阅日志中不应出现 heart_rate/breathing_rate/pose
cargo run -p wifi-densepose-sensing-server -- --source mock --mqtt --privacy-mode &
mosquitto_sub -t 'homeassistant/#' -v | tee /tmp/privacy.log
grep -E "(heart_rate|breathing_rate|pose)" /tmp/privacy.log   # 期望为空(exit 1)

# 6. HA 端到端(手动,见 docs/integrations/home-assistant.md)
# 7. LWT:运行后见 online;kill -9 后 30 s 内所有 availability 主题变 offline

# 8. Matter Bridge 配对(P7 之后)
cargo run -p wifi-densepose-sensing-server -- \
    --source mock --matter --matter-setup-file /tmp/matter-qr.txt
# 期望:打印 setup code + QR;桥经 mDNS 广播

# 9. Matter 跨控制器:同一 QR 分别配入 Apple Home 与 HA Matter,
#    触发 mock presence 变化,期望两控制器 1 s 内 occupancy 翻转

# 10. Matter 隐私不变量:MQTT 可发布 HR(无 --privacy-mode),
#    Matter 永不暴露 HR cluster(规范无对应 cluster)

仓库侧已有对应集成测试 tests/mqtt_integration.rs(mqtt feature 下运行),discovery 模块内含 schema/路径形态的单元测试。

10.3 排障速查(详见 docs/integrations/home-assistant.md

  • HA 无实体mosquitto_sub -h <broker> -t 'homeassistant/#' -v 看是否有每实体一条 config;有 config 但 HA 无设备,则检查 MQTT 集成是否指向同一 broker;
  • 实体有但状态不更新:确认 sensing-server 实际收到 CSI 帧(日志 [ws] / [edge_vitals] 行),用 wscat -c ws://localhost:8765/ws/sensing 验证广播通道;诊断期可临时 --mqtt-rate-vitals 1.0
  • "Plaintext MQTT on non-localhost broker" WARN:v0.7.0 警告并继续,v0.8.0 将硬失败——要么加 --mqtt-tls + CA,要么把 broker 挪到 localhost;
  • Matter 配对失败:检查 --matter-setup-file 中的 setup code、确认宿主与控制器同一 WiFi 子网;Apple Home 提示未知厂商属预期(开发 VID 0xFFF1),选 "Add anyway"。

11. 风险、收益与备选方案(承接原文档)

收益:HA 用户零代码接入;经 Matter 触达 Apple Home / Google Home / Alexa / SmartThings(把可寻址市场放大到非 HA 用户);与自有 UI 解耦(HA / Grafana / Node-RED 可在同一 MQTT firehose 上自建仪表盘);--privacy-mode 提供合规场景的"一键剥离";Matter fabric 隔离在架构上杜绝控制器窃取生物特征。

成本rumqttc 新运行时依赖(feature 门控、默认关闭);Matter SDK(约 5 MB,仅开启时)与 CSA 规范版本漂移的年审;HA 与 Matter 两侧 schema/版本演进需按发布 pin 版本并在 docs/integrations/home-assistant.md 记录"tested against"矩阵;CI 需 mosquitto 容器 + HA schema 校验 + chip-tool 模拟器;CSA 会员费($3 k/年)仅决定正式厂商 ID,开发期用 0xFFF1

主要风险与缓解(均已在 ADR-115 §7 记录):主题命名空间冲突靠 wifi_densepose_ 前缀 + MAC 派生 id 缓解;HA schema 变更靠 pin 版本 + CI schema 校验;pose 带宽放大靠默认关闭 + 限速;生物特征泄漏靠 --privacy-mode 源头剥离 + 明文 WARN;动态 per-track 实体基数爆炸靠上限 10 + discovery payload="" 删除约定;Matter SDK 不成熟靠 P7 三控制器试配对 + chip-tool FFI 回退。

备选与互补路径HACS Python 集成hass-wifi-densepose,经既有 /ws/sensing WebSocket + /api/* REST 与 config-flow,约 4–6 周,留待 MQTT 落地数据评估);REST webhook 已被否决(单向、无实体发现、无 LWT,不满足即插即用);mDNS/Zeroconf(#574)与 MQTT 正交互补——mDNS 解决"broker 在哪",MQTT auto-discovery 解决"建哪些实体"。


12. 结论

ADR-115 是 RuView 从"又一个感知平台"走向"任何 HA 安装与任何 Matter 控制器家庭均可即插即用升级件"的集成叙事:MQTT 承载丰富且有差异化的遥测(含生物特征与姿态),Matter 以标准簇把存在/人数/跌倒子集带到每个控制器生态;两者由 unique_id 去重、由同一语义推理总线驱动、由 --privacy-mode 在集成边界执行生物特征剥离。从 ADR-115operator guide指标文档mqtt 模块matter 模块semantic 模块blueprint 样例,构成了一条从架构决策到可运行部署的完整证据链。

登录后查看全文
热门项目推荐
相关项目推荐