实体与设备接口
这五条都在读组:认 Bearer 或面板会话 cookie(分界见总览)。 自己写面板的话主要就用它们,怎么把页面传上去见自建面板。
先分清设备和实体
Section titled “先分清设备和实体”设备是一台物理东西(一个插座、一台扫地机);实体是它的一项能力(开关、
功率、温度)。实体 id 形如 设备名.能力名,两段都是 snake_case。
一台小米插座能有二十多个实体,其中大部分(上电默认状态、充电保护功率、超用电量
告警阈值)你多半用不上。/api/devices 给你设备这一层,/api/entities 给你能力
这一层,两者用 entity_ids 关联。
# 看全部实体的当前值curl -s -H "Authorization: Bearer $RHA_TOKEN" \ http://127.0.0.1:8420/api/entities | jq '.data[] | {id, value, stale}'
# 开一个开关curl -s -X POST -H "Authorization: Bearer $RHA_TOKEN" \ -H 'Content-Type: application/json' -d '{"value": true}' \ http://127.0.0.1:8420/api/entities/fan.power/set | jq .data三个容易混的字段
Section titled “三个容易混的字段”读到一个值的时候,有三个字段答的是三个不同问题,互不替代:
available—— 设备现在联不联得上stale—— 这个值是不是重启后从存储恢复的旧值poll_tier—— 这个值刷得勤不勤(字段缺席 = 不轮询,广播型设备就是这样)
只看有没有数字会被骗:一台断电的插座,value 里可能还留着最后一次读数,
available 是 false、stale 是 true。面板上该把这种值画成“未确认”的样子。
/api/entities认证:Bearer token 或 面板会话 cookie
按实体 id 字典序返回。
stale = true 的值是重启后从存储恢复的旧值, 不是设备刚报上来的 —— 看到它别当成实时读数。available 答的是另一个问题(设备在不在线), poll_tier 答的是第三个(这值刷得勤不勤; 字段缺席 = 不轮询, 广播型设备就是这样)。三个字段互不替代。
返回
成功时 data 字段的形状:
| 字段 | 类型 | 说明 |
|---|---|---|
available* | boolean | 设备现在联不联得上。 |
class | string | 语义类, 见
这让本字段的引入成本接近零: 没配 bridge 的用户全 一个实体承载的语义。 刻意窄 —— 封闭枚举加一项就要动 core 和所有 bridge, 宁可少。刻意不照抄 HomeKit
的 Service 列表: |
domain | any | 数值实体的取值域, 见 北向 bridge 拿它把设备刻度换算成协议刻度 —— 一台风扇的档位可能是 1-4 档 枚举、也可能是 1-100 无级, 而 HomeKit 的转速滑条固定是 0-100 的百分比。 不知道原始域就无从换算。 一个数值实体的合法取值。 |
id* | string | 实体 id, 形如 |
kind* | string | 这个实体能被怎么用: |
last_updated | string | 这个值是什么时候收到的。缺席 = 本次启动以来没收到过。 |
poll_tier | string | 轮询节奏: null 是广播、推送型设备(BLE 温湿度计、reolink 事件流): 值是设备自己送上来的, 没有"问"这个动作, 对它说"轮询得慢"是错的。用 bool 表达不了这第三种情况。 与 一个实体的轮询节奏。 |
stale* | boolean | 这个值是重启后从存储恢复的旧值, 不是设备报上来的。 面板上该给它一个"未确认"的样子: 值看着有, 但没人保证设备现在真是这样。
收到第一次真实上报后它就变回 |
unit | string | 单位, 由 adapter 给, 如 三套 adapter 各有各的词汇, 这里不做归一 —— 它是给人看的标签,
不是换算依据。要换算看 |
value | any | 当前值, 类型见 |
value_type* | string | 值的类型: |
/api/entities/{id}认证:Bearer token 或 面板会话 cookie
字段含义与 /api/entities 完全一致, 只是单条。
参数
| 参数 | 位置 | 类型 | 说明 |
|---|---|---|---|
id* | 路径 | string | 实体 id, 形如 |
返回
成功时 data 字段的形状:
| 字段 | 类型 | 说明 |
|---|---|---|
available* | boolean | 设备现在联不联得上。 |
class | string | 语义类, 见
这让本字段的引入成本接近零: 没配 bridge 的用户全 一个实体承载的语义。 刻意窄 —— 封闭枚举加一项就要动 core 和所有 bridge, 宁可少。刻意不照抄 HomeKit
的 Service 列表: |
domain | any | 数值实体的取值域, 见 北向 bridge 拿它把设备刻度换算成协议刻度 —— 一台风扇的档位可能是 1-4 档 枚举、也可能是 1-100 无级, 而 HomeKit 的转速滑条固定是 0-100 的百分比。 不知道原始域就无从换算。 一个数值实体的合法取值。 |
id* | string | 实体 id, 形如 |
kind* | string | 这个实体能被怎么用: |
last_updated | string | 这个值是什么时候收到的。缺席 = 本次启动以来没收到过。 |
poll_tier | string | 轮询节奏: null 是广播、推送型设备(BLE 温湿度计、reolink 事件流): 值是设备自己送上来的, 没有"问"这个动作, 对它说"轮询得慢"是错的。用 bool 表达不了这第三种情况。 与 一个实体的轮询节奏。 |
stale* | boolean | 这个值是重启后从存储恢复的旧值, 不是设备报上来的。 面板上该给它一个"未确认"的样子: 值看着有, 但没人保证设备现在真是这样。
收到第一次真实上报后它就变回 |
unit | string | 单位, 由 adapter 给, 如 三套 adapter 各有各的词汇, 这里不做归一 —— 它是给人看的标签,
不是换算依据。要换算看 |
value | any | 当前值, 类型见 |
value_type* | string | 值的类型: |
错误
400—— 实体 id 格式不合法404—— 没有这个实体
/api/devices认证:Bearer token 或 面板会话 cookie
比实体高一层: 一台设备下挂若干实体。返回里的 entity_ids 是该设备的实体 id 列表, 省得前端自己按 id 前缀去 /api/entities 里筛一遍。
manufacturer / model 缺席表示那个 adapter 答不上来, 不是设备没有型号。
返回
成功时 data 字段的形状:
| 字段 | 类型 | 说明 |
|---|---|---|
entity_ids* | array | — |
label | string | 用户在 |
manufacturer | string | 厂商与型号, 由 adapter 提供(见 刻意不在这里回落: HomeKit 回落成 |
model | string | — |
name* | string | 设备 id, 也是它所有实体 id 的前缀( |
/api/entities/{id}/set认证:Bearer token 或 面板会话 cookie
只有 kind = switch 的实体可写。
这个接口是同步等结局的: 派发命令后最多等 6 秒, outcome 为 ok / failed / timeout 三者之一。timeout 不代表没生效, 只代表这 6 秒内没收到确认。
它在读组里 —— 一张泄漏的面板 cookie 是能开关设备的。这是有意的取舍(面板必须能按开关), 不是漏洞。
参数
| 参数 | 位置 | 类型 | 说明 |
|---|---|---|---|
id* | 路径 | string | 实体 id, 形如 |
请求体
| 字段 | 类型 | 说明 |
|---|---|---|
value* | any | — |
返回
成功时 data 字段的形状:
| 字段 | 类型 | 说明 |
|---|---|---|
command_id* | integer | — |
detail | string | — |
outcome* | string | — |
错误
400—— id 不合法 / 实体不可写 / 值的类型对不上404—— 没有这个实体
/api/entities/{id}/history认证:Bearer token 或 面板会话 cookie
需要开着历史记录(rha.toml 的 [storage]), 关着时返回 503。
hourly = true 时按小时聚合, 返回形状变成聚合点(avg / min / max / count), 且只对数值实体有效。缺省返回原始采样点。
limit 缺省 500, 上限 5000(超了按 5000 截)。时间窗缺省是「到现在为止的 24 小时」。
参数
| 参数 | 位置 | 类型 | 说明 |
|---|---|---|---|
id* | 路径 | string | 实体 id |
from | 查询串 | string | 起点, RFC 3339 时间戳。缺省为 |
to | 查询串 | string | 终点, RFC 3339 时间戳。缺省为现在 |
limit | 查询串 | integer | 最多返回多少条。缺省 500, 上限 5000 |
hourly | 查询串 | boolean | 按小时聚合。仅数值实体可用 |
返回
成功时 data 字段的形状 —— 有 2 种,看参数怎么传:
缺省: 原始采样点
| 字段 | 类型 | 说明 |
|---|---|---|
ts* | string | — |
value* | any | — |
hourly=true: 按小时聚合
| 字段 | 类型 | 说明 |
|---|---|---|
avg* | number | — |
bucket* | string | — |
count* | integer | — |
max* | number | — |
min* | number | — |
错误
400—— id 不合法 / 查询参数格式错 / 对非数值实体请求 hourly404—— 没有这个实体503—— 没开历史记录