首页
/ RuView 酒店住客幸福度评分:WiFi CSI 与 Cognitum Seed 向量桥接实现解析(ADR-065)

RuView 酒店住客幸福度评分:WiFi CSI 与 Cognitum Seed 向量桥接实现解析(ADR-065)

2026-09-07 10:53:50作者:秋泉律Samson

导读

本篇文章完整解读 RuView 仓库中的 ADR-065(Hotel Guest Happiness Scoring — WiFi CSI + Cognitum Seed Bridge):如何在不使用摄像头、不接触住客的前提下,仅凭 ESP32-S3 采集的 WiFi CSI 信号,在边缘 WASM 模块中推算一条 8 维「幸福度向量」,再经 UDP 链路桥接到局域网内的 Cognitum Seed 边缘智能设备,完成 kNN 检索、概念漂移监测与 Ed25519 见证链审计。读完本文,你将掌握该方案从 8 维向量定义、加权合成公式、事件注册表(690–694)、Seed API 对接,到 4MB Flash 构建与隐私合规设计的完整脉络,并能借助仓库中的 schema、查询脚本与启动器立即动手复现。


一、背景:酒店满意度测量为何需要 RF 感知

ADR-065 首先点出行业痛点:酒店缺少一种客观、实时、且保护隐私的住客满意度测量手段。传统的离店问卷与 NPS(净推荐值)调查存在三重缺陷:

  • 时滞严重:只能事后回收,无法在入住期间实时干预;
  • 样本偏差:答卷者偏向极端情绪群体;
  • 覆盖率低:通常只能触达不到 10% 的住客。

相比之下,环境射频(Ambient RF)感知可以从 CSI 信号中推断与舒适度、幸福感相关的行为线索(步态、呼吸、停留模式等),全程无需摄像头、可穿戴设备或任何住客配合。这正是 RuView 一贯的"以 WiFi 为传感器"路线的垂直行业应用,与仓库顶层描述(把普通 WiFi 信号转化为空间智能、生命体征与存在感知)一脉相承。

方案技术前提:你已有的设备资产

ADR-065 的方案并非从零搭建,而是建立在 RuView 既有的两层资产之上:

1)ESP32-S3 CSI 传感节点(Tier 2 DSP 固件)

文档部署了两种变体:

设备 Flash PSRAM MAC 端口 说明
ESP32-S3(QFN56 rev 0.2) 4 MB 2 MB 1C:DB:D4:83:D2:40 COM5 低成本节点,使用 sdkconfig.defaults.4mb + partitions_4mb.csv
ESP32-S3 8 MB 8 MB -- COM7 全功能节点,已有部署

两款均运行 Tier 2 DSP 固件,具备存在检测、生命体征提取、跌倒检测与步态分析能力。对应固件工程位于 firmware/esp32-csi-node,其中 provision.py 负责将 WiFi 凭证、node-id、区域与 Seed 地址写入设备。

2)Cognitum Seed 边缘智能设备

同一网段内部署了一台 Cognitum Seed 作为向量聚合与审计节点:

属性
地址 169.254.42.1(link-local)
硬件 Raspberry Pi Zero 2 W
固件 0.7.0
向量库 398 条向量,dim=8
API 端点 98 个(REST,完整文档化)
传感器 PIR、门磁(reed switch)、振动、ADS1115 ADC(4 通道模拟)、BME280(温/湿/气压)
安全 Ed25519 托管链 + 防篡改见证日志

Seed 的 8 维向量库与漂移检测引擎,使它天然适合充当从 CSI 数据提取出的行为特征向量的汇聚点——ADR-065 的核心主张正是:"不用改 Seed 的 schema,因为幸福度向量设计为正好 dim=8"。

已就位的 WASM 边缘模块(融合输入源)

ADR 特别强调,幸福度评分模块是"融合层(fusion layer)而非重写":它消费以下四个已经运行在设备上的模块的输出:

模块 事件 ID 输出
exo_emotion_detect.rs 610–613 唤醒水平(arousal)、压力指数(stress index)
med_gait_analysis.rs 130–134 步频(cadence)、步幅(stride length)、规律性(regularity)
ret_customer_flow.rs 410–413 进入/离开计数、方向
ret_dwell_heatmap.rs 420–423 各区域停留时间

v2/crates/wifi-densepose-wasm-edge/src 中可以逐一核对这些模块:exo_emotion_detect.rs 中确实定义了 EVENT_AROUSAL_LEVEL = 610EVENT_STRESS_INDEX = 611 等常量,med_gait_analysis.rs 定义了 EVENT_STEP_CADENCE = 130,两个零售模块 ret_dwell_heatmap.rs(410–413)与 ret_customer_flow.rs(420–423)也在同一目录。也就是说,ADR 表格对应的源代码是真实存在、可检索的(个别模块的实际事件 ID 常量号与 ADR 表格存在互换,详见下文"实现层核对")。


二、核心设计决策

ADR-065 将决策拆成九个层次,下面逐层展开并与源码印证。

决策 1:新 WASM 模块 exo_happiness_score.rs

方案新建一个 WASM 边缘模块,把上述既有模块的输出融合为一条 8 维幸福度向量,与 Seed 的向量维度(dim=8)严格对齐。

事件注册表(690–694) 按 ADR 规划:

事件 ID 名称 说明
690 HAPPINESS_VECTOR 每个评分窗口输出的完整 8 维幸福度向量
691 HAPPINESS_TREND 最近 N 条向量的窗口趋势(上升/下降/平稳)
692 HAPPINESS_ALERT 评分越过配置阈值(低满意度)告警
693 HAPPINESS_GROUP 多人区域的聚合评分
694 HAPPINESS_CALIBRATION 基线重校准事件(新住客入住时)

实现层核对:在 exo_happiness_score.rs 中,690–694 五个常量(EVENT_HAPPINESS_SCORE=690EVENT_GAIT_ENERGY=691EVENT_AFFECT_VALENCE=692EVENT_SOCIAL_ENERGY=693EVENT_TRANSIT_DIRECTION=694)确实存在,但命名与 ADR 表格的描述语义不同:实现层把 690 定义为逐帧复合评分、691–694 定义为步态能量/情感效价/社交能量/进出方向,每 4 帧(约 5 Hz)以降低 75% UDP 包率的方式节流发送。这说明 ADR 给出的是注册语义的顶层规划,源码则落地为可量化的具体事件常量,两者编号范围一致。

模块的 DSP 部分使用滚动环形缓冲与在线统计(CircularBufferEmaWelfordStats,来自同目录 vendor_common.rs),并对多组窗口长度做了注释化的资源预算(如步频窗 16 帧≈0.8s、呼吸窗 16 样本≈16s、停留窗 32 帧≈1.6s),所有中间统计均内存常驻、无浮点库依赖以外的开销。

决策 2:8 维幸福度向量 Schema

每一维都被归一化到 [0.0, 1.0],1.0 代表最大正向信号。ADR 给出的维度定义:

名称 来源 推导逻辑
0 gait_speed med_gait_analysis(130) 归一化步行速度,步伐轻快=正向
1 stride_regularity med_gait_analysis(131) 步间方差小=步态放松
2 movement_fluidity CSI 相位加加速度(d³/dt³) 加加速度低=动作流畅、不急促
3 breathing_calm 生命体征 BR 提取 静息 BR 12–18 为平静,偏离则扣分
4 posture_openness CSI 子载波扩散 子载波间相位扩散宽=姿态舒展
5 dwell_comfort ret_dwell_heatmap(420) 在便利设施区域适度停留=参与度
6 direction_entropy ret_customer_flow(410) 低熵=移动有目的性;徘徊扣分
7 group_energy 多目标 CSI 聚类 2 人以上同步移动=社交参与

复合标量为加权归一化结果(ADR 原文写作 weighted L2 norm,公式实为加权平均):

score = sum(w[i] * v[i] for i in 0..7) / sum(w[i])

默认权重均匀(全 1.0),可通过 NVS 或 Seed API 配置。

实现层核对:实际 Rust 实现把权重做成了常量 W_GAIT_SPEED=0.25W_STRIDE_REG=0.15W_FLUIDITY=0.20W_BREATH_CALM=0.20W_POSTURE=0.10W_DWELL=0.10(六项和恰为 1.0,即凸组合),并在复合评分后套一层 HAPPINESS_ALPHA=0.10 的 EMA 平滑。8 维向量在结构体中以 happiness_vector: [f32; 8] 落地,其排列顺序与 ADR 表格不同[0]=happiness_score(复合评分本身),[1]..[6] 对应步速、步态规律、流畅度、呼吸平静、姿态、停留,[7]=social_energy。JSON Schema 文件 happiness_vector_schema.json 与该排列一致(dim0 为复合分,权重注明 gait=0.25、fluidity=0.20、calm=0.20、stride=0.15、posture=0.10、dwell=0.10)。若你要直接解析或写入 Seed 向量,务必以 schema 顺序为准,而不要照搬 ADR 的纯语义编号。

决策 3:ESP32 → Seed 桥接(UDP + REST 双通道)

ADR 给出了清晰的数据流框图:

ESP32-S3 (CSI)                    Cognitum Seed (169.254.42.1)
+------------------+              +----------------------------+
| Tier 2 DSP       |              |                            |
| + WASM modules   |  UDP 5555   | /api/v1/store/ingest       |
| exo_happiness    |──────────────| (POST, 8-dim vector)       |
|   _score.rs      |              |                            |
|                  |              | /api/v1/drift/check        |
|                  |◄─────────────| (drift alerts via webhook) |
|                  |              |                            |
|                  |              | /api/v1/witness/append     |
|                  |              | (Ed25519 audit trail)      |
+------------------+              +----------------------------+

数据流六个步骤

  1. ESP32 以 20+ Hz 采集 CSI,把子载波数据送入既有的 WASM 模块;
  2. exo_happiness_score.rs 在每个评分窗口(默认 30 秒)内汇聚情绪、步态、客流、停留模块的输出;
  3. 8 维向量被打包为 32 字节负载(8 × float32),经 UDP 发往 169.254.42.1 的 5555 端口;
  4. Seed 上一个轻量桥接任务收到 UDP 包后,附带元数据(room ID、时间戳、MAC)POST 到 /api/v1/store/ingest
  5. Seed 的漂移检测引擎监控向量流,标记异常(突然下跌、持续低分);
  6. 每条向量追加进 Ed25519 见证链,形成防篡改审计记录。

examples/ruview_live.py 中可以看到同一桥接协议的 Python 参考实现:CognitumSeedBridge 类把向量 POST 到 ${base}/api/v1/store/ingest(后台线程、5 秒超时、静默忽略连接错误),并从 ${base}/api/v1/sensor/drift/status 拉取漂移状态。这为不具备完整固件的场景提供了一条可直接运行的桥接捷径。

决策 4:Seed 端漂移检测与幸福度趋势

Seed 内置的漂移检测引擎将新向量与滚动基线比较:

  • 入住校准:新住客入住触发事件 694,重置基线;
  • 漂移阈值:可配置,默认余弦距离 > 0.3 触发告警;
  • 趋势窗口:最近 20 条向量(30s 间隔下约 10 分钟);
  • 告警路由:幸福度趋势下滑时,Seed 的 webhook 通知酒店管理系统。

seed_query.py 的命令 report 把这条逻辑做成可读输出——它用 [1.0]*7+[0.5] 的"理想开心参照向量"与 [0.0]*7+[0.5] 的"沮丧参照向量"各做一次 kNN 检索,打印最开心/最焦虑的时刻,再叠加漂移分数给出"mood stable / WARNING: Mood drift detected"的结论,是全流程最直观的落地样例。

决策 5:RuView Live 仪表盘的 --seed 模式

ruview_live.py 增加 --mode happiness--seed 参数。ADR 给出的命令为:

python ruview_live.py --port COM5 --seed 169.254.42.1 --mode happiness

仓库当前版本把端口参数统一为 --csi(缺省时 happiness 模式自动回落 COM5、vitals 模式回落 COM7),--seed 接受完整 HTTP base URL:

python examples/ruview_live.py --mode happiness --csi COM5 \
  --seed http://169.254.42.1 --duration 300

在 happiness 模式下仪表盘显示:

  • 8 维幸福度向量的实时雷达图;
  • 标量幸福度评分(0–100,红/黄/绿三色编码);
  • 最近一小时的趋势迷你图(sparkline);
  • Seed 见证链状态(最近哈希、链长度);
  • 多 ESP32 节点上报时的房间级聚合。

实现上,examples/ruview_live.pyHappinessScorer 类融合步态、呼吸、社交信号做加权评分(happiness = clamp01(...)),随后把 happinessgait_energyaffect_valencesocial_energyvector 一并塞入每轮显示字典,再交由 _happiness_bar() 与终端表格渲染。README 中的示例输出如下(来自 examples/happiness-vector/README.md):

#    s             Happy   Gait   Calm  Social  Pres   RSSI    Seed   CSI#
#   2s  [====------] 0.43   0.00   0.64    0.00    no    -59      OK   1800
#  10s  [=======---] 0.72   0.65   0.80    0.45   YES    -55      OK   4200

决策 6:整体架构

                    +------------------------------------------+
                    |              Hotel Room                   |
                    |                                           |
                    |  [ESP32-S3]         [Cognitum Seed]       |
                    |  COM5 or COM7       169.254.42.1          |
                    |  4MB or 8MB flash   Pi Zero 2 W           |
                    |       |                    |               |
                    |       | WiFi CSI           | PIR, reed,   |
                    |       | 20+ Hz             | BME280,      |
                    |       v                    | vibration    |
                    |  +-----------+             |               |
                    |  | Tier 2 DSP|             v               |
                    |  | presence  |      +-------------+       |
                    |  | vitals    |      | Seed API    |       |
                    |  | gait      |      | 98 endpoints|       |
                    |  | fall det  |      | 398 vectors |       |
                    |  +-----------+      | dim=8       |       |
                    |       |             +-------------+       |
                    |       v                    ^               |
                    |  +-----------+   UDP 5555  |              |
                    |  | WASM edge |─────────────┘              |
                    |  | happiness |                            |
                    |  | score     |   Drift alerts             |
                    |  | (690-694) |◄──────────────             |
                    |  +-----------+   /api/v1/drift/check      |
                    |                                           |
                    +------------------------------------------+
                              |
                              | MQTT / HTTP
                              v
                    +------------------+
                    | Hotel Management |
                    | System / RuView  |
                    | Live Dashboard   |
                    +------------------+

从架构图可以提炼出该方案的关键拓扑特性:处理完全本地化(ESP32 边缘 + Seed link-local 网络),无云端依赖;感知链路(RF)与语义链路(向量)解耦,酒店管理系统只通过 MQTT/HTTP 消费语义结果。

决策 7:4MB Flash 变体支持

ADR 明确将 4MB 的 COM5 节点(约合每房间 ~$8 的文档估算成本)列为幸福度评分的官方支持对象。仓库中确实存在配套的 partitions_4mb.csvsdkconfig.defaults.4mb。双 OTA 槽各 1.856 MB,足够承载完整 Tier 2 DSP 固件加上估算 <40 KB 的 exo_happiness_score.wasm

4MB 变体构建方式:

cp sdkconfig.defaults.4mb sdkconfig.defaults
idf.py build

WASM 模块加载器会依据可用堆大小决定实例化哪些模块;在 4MB/2MB PSRAM 变体上,幸福度评分以缩减的评分窗口运行(60s 代替 30s)以节约内存。这也直接呼应了文档 Consequences 部分对"低评分频率(60s vs 30s)"的坦诚声明。

决策 8:隐私合规设计

ADR-065 把隐私作为第一类约束,逐条论证:

  • 无摄像头:全部感知基于 RF(WiFi 子载波幅度/相位);
  • 无面部识别:幸福度由运动模式推断,不看表情;
  • 无音频采集:呼吸率来自 RF 反射的胸廓位移,而非麦克风;
  • 设备端不存 PII:向量匿名,房间↔住客映射只存在于酒店 PMS;
  • 见证链审计:Ed25519 见证链提供"采集了什么、何时采集"的可审计证据,满足 GDPR 第 30 条记录保存义务;
  • 住客退出机制:ESP32 节点上有 GPIO 连接的物理开关,可完全关闭 CSI 采集;Seed 的门磁还可用作"隐私模式"触发(移除门上的磁铁即暂停感知);
  • 保留期限:向量在 Seed 上仅保留整个入住周期再加 24 小时,随后清除;见证链无限期仅保留哈希(非向量)供审计。

仓库侧对隐私承诺的佐证还包括顶层 ADR-160(edge-skill-library-honest-labeling)以及源码中对"幸福度仅为代理信号、不得用于情绪决策"的强声明(见下文局限章节)。

决策 9:Seed API 集成面

ADR 列出方案实际用到的 Seed REST 端点:

端点 方法 用途
/api/v1/store/ingest POST 摄入 8 维幸福度向量
/api/v1/store/query POST 按房间/时间段检索向量
/api/v1/drift/check GET 检查当前向量是否偏离基线
/api/v1/drift/configure PUT 设置漂移阈值与窗口大小
/api/v1/witness/append POST 向 Ed25519 托管链追加事件
/api/v1/witness/verify GET 校验链完整性
/api/v1/sensors/bme280 GET 房间温湿度(舒适度相关性分析)
/api/v1/sensors/pir GET PIR 存在状态(与 CSI 交叉验证)

seed_query.py 中可以看到这些端点在客户端侧的实际拼装:status/api/v1/status + /api/v1/sensor/drift/statussearchPOST /api/v1/store/search(body 为 {vector, k});witness/api/v1/custody/epoch + /api/v1/cognitive/status。注意该脚本对端点的使用与 ADR 表格表述略存差异(如查询用 /store/search 而非 /store/query),实际调用时应以脚本与 Seed 固件文档为准。


三、仓库落地:examples/happiness-vector 快速上手

ADR 对应的配套工程集中在 examples/happiness-vector 目录,包含四个文件:

文件 说明
README.md 方案总览 + 快速开始
seed_query.py 纯标准库 CLI:status / search / witness / monitor / report
provision_swarm.sh 多节点批量配网脚本
happiness_vector_schema.json 8 维向量格式的 JSON Schema

1. 刷写并配置单个 ESP32 节点

# 构建固件(仓库根目录执行)
cd firmware/esp32-csi-node
idf.py build

# 烧录
idf.py -p COM5 flash

# 写入 WiFi 与 Seed 凭证
python provision.py \
  --port COM5 \
  --ssid "YourWiFi" \
  --password "yourpassword" \
  --node-id 1 \
  --seed-url "http://10.1.10.236" \
  --seed-token "YOUR_SEED_TOKEN" \
  --zone "lobby"

注意:provision.py 位于固件工程内;而示例工程中的批量脚本 provision_swarm.sh 通过相对路径 ../../firmware/esp32-csi-node/provision.py 复用同一配网器,并对 COM5/COM6/COM8/COM9/COM10 五个端口依次写入 lobby/hallway/restaurant/pool/conference 五个区域。它要求先设置 SWARM_WIFI_SSIDSWARM_WIFI_PASSWORDSWARM_SEED_URLSWARM_SEED_TOKEN 四个环境变量,并预置 ESP-IDF Python venv。

2. 首次配对 Seed(仅一次)

# 通过 USB link-local 配对(免 token)
curl -X POST http://169.254.42.1/api/v1/pair/window
curl -X POST http://169.254.42.1/api/v1/pair -H "Content-Type: application/json" \
  -d '{"name":"esp32-swarm"}'
# 从响应中保存 token

3. 查询与监控 Seed

# 状态(向量数、epoch、见证链长度、漂移状态)
python examples/happiness-vector/seed_query.py \
  --seed http://10.1.10.236 --token YOUR_TOKEN status

# 实时监控流入向量
python examples/happiness-vector/seed_query.py \
  --seed http://10.1.10.236 --token YOUR_TOKEN monitor

# 幸福度报告(基于 kNN 参考向量)
python examples/happiness-vector/seed_query.py \
  --seed http://10.1.10.236 --token YOUR_TOKEN report

# 见证链审计
python examples/happiness-vector/seed_query.py \
  --seed http://10.1.10.236 --token YOUR_TOKEN witness

# 按情绪检索(happy/neutral/stressed)
python examples/happiness-vector/seed_query.py \
  --seed http://169.254.42.1 search --mood happy --k 5

seed_query.py 依赖仅为 Python 3.7+ 标准库(urllib),无需安装第三方包;不传 --seed 时默认走 USB link-local(http://169.254.42.1,无需 token)。

4. 8 维向量的线上格式

happiness_vector_schema.json 把摄入负载定义为 {vectors: [[id, 8维数组], ...]}。其 $defs 部分包含三条关键约定:

  • 向量 ID 编码node_id * 1000000 + type_offset + timestamp_component,其中 type_offset 为 0(注册)、100000(心跳)、200000(幸福度)。例如节点 1 的注册向量 ID 为 1000000,幸福度向量 ID 约为 12xxxxx;
  • 维度语义:dim0 复合分、dim1 步速、dim2 步态规律、dim3 流畅度、dim4 呼吸平静、dim5 姿态、dim6 停留、dim7 社交能量,每维限制在 minimum: 0, maximum: 1,数组严格 minItems=8/maxItems=8
  • 权重:gait=0.25, stride=0.15, fluidity=0.20, calm=0.20, posture=0.10, dwell=0.10。

5. 幸福度 WASM 的独立构建路径

如果你不想走完整固件链路,也可以单独编译幸福度评分模块:

cd v2/crates/wifi-densepose-wasm-edge
cargo build --target wasm32-unknown-unknown --release

该模块的单元测试(内嵌在 exo_happiness_score.rs#[cfg(test)] 段)覆盖了关键行为:无 presence 时不产出任何事件、快而规律的步态给出中等偏上的步速分、10 BPM 平静呼吸下呼吸平静分 > 0.7、极端输入下评分与向量各维始终落在 [0,1]、向量维数恒为 8、事件 ID 的节流发射逻辑、进出方向推断与 reset()。这些测试既是行为契约,也是你验证对算法理解的最快入口。


四、影响评估(Consequences)

正向收益

  • 无需问卷/可穿戴即可获得实时、客观的满意度测量;
  • 复用四个既有 WASM 模块——幸福度模块只是融合层,不是重写;
  • Seed 8 维向量库天然契合,无需 schema 变更;
  • Ed25519 见证链满足酒店业审计要求与 GDPR 记录保存义务;
  • 4MB 与 8MB 两种变体都支持,便于以低成本规模部署;
  • Seed 的环境传感器(BME280、PIR)可补充温度/湿度等上下文,与幸福度做相关性分析;
  • 无云依赖,全部在 ESP32 边缘 + Seed link-local 网络内完成。

负面与边界

  • 从运动模式推断幸福度只是代理测量,与真实满意度的相关性必须做实证校验;
  • 4MB 变体因内存限制把评分频率降到 60s(vs 30s);
  • ESP32 ↔ Seed 的 UDP 传输不可靠,可能丢包——缓解手段是序号 + ESP32 端的小型重试缓冲;
  • link-local(169.254.x.x)把 Seed 限制在同一网段;多房间部署需要每子网一台 Seed 或做路由桥接;
  • 漂移阈值需要按物业调参(豪华度假村与快捷酒店的运动模式差异显著);
  • 多住客房间内无法区分个体,除非引入实验性的多目标 CSI 聚类(关联 ADR-064,Tier 3)。

科学诚实性声明(重要)

ADR-065 是一份 2026-03-20 提出、状态为 Proposed 的架构决策记录。需要特别指出的是,其对应实现模块在源码头部明确标注:

"SPECULATIVE, UNVALIDATED AFFECT HEURISTIC……HAPPINESS_SCORE 是步态能量/运动代理信号,而非经过验证的情绪度量;它从未与自我报告、面部情绪或任何参照标准做过相关性验证(见 ADR-160 §A2),不得用于情绪推断、筛查或任何针对个人情绪状态的决策。DSP(滚动统计 + 加权评分)是真实的;其输出被解释为"情绪"这一环是未经验证的。"

因此,阅读和使用本方案时应把"幸福度向量"理解为行为/生理代理特征向量,它的工程链路(采集 → 融合 → 向量化 → 漂移监测 → 见证审计)是完整可复现的,而语义解读端仍需研究验证——这一克制表述与 ADR-160(边缘技能库诚实标注)的原则一脉相承,也是评估该 ADR 是否值得进入生产的关键前提。


五、延伸阅读

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