设备 RPC(下行指令)
平台支持向在线设备下发指令(远程控制、参数设置)。当前为 one-way(单向) 模式:平台发出后不等待、不校验设备回执,也不排队重发——这决定了它的适用边界与设备端实现方式。
一、谁发起、怎么发起
指令由平台侧发起:在设备台账的操作列对设备点击 下发指令。指令内容为:
| 要素 | 说明 |
|---|---|
| method | 方法名,如 reboot、setThreshold,由设备端约定实现 |
| params | 参数,JSON 对象,透传给设备端 |
| 目标 | 一台设备(普通设备、网关或子设备) |
二、路由规则(平台侧行为)
平台按目标设备的形态自动选择下发路径,设备端需要按对应形态订阅:
目标设备 下发主题(QoS 1)
──────────────────────── ─────────────────────────────────────
独立直连设备 v1/devices/{令牌}/rpc/request/{requestId}
有直连连接的子设备 同上(优先直连,更快)
无直连连接的子设备 v1/gateway/rpc/{网关令牌} ← 由网关转发
网关(转发给其子设备) v1/gateway/rpc/{网关令牌}子设备的兜底逻辑:有直连连接就走直连;没有则回退到父网关转发,避免"设备离线就完全发不出"。
三、设备端实现
直连设备
订阅自己的 RPC 主题(每次请求的 requestId 不同,用通配符一次订好):
v1/devices/{你的令牌}/rpc/request/+收到的报文:
json
{ "method": "reboot", "params": { "delay": 5 } }设备端按 method 分发执行即可。requestId 位于主题末段,one-way 模式下无需用它回复。
网关
订阅:
v1/gateway/rpc/{网关令牌}收到的报文:
json
{
"device": "Device A",
"data": {
"id": "3f2a…",
"method": "setThreshold",
"params": { "temperature": 60 }
}
}网关的职责是边缘转交:按 device(子设备外部 ID)找到现场设备,把 data 中的指令送达,并完成平台侧约定不了的本地协议转换。
报文规则速查
| 场景 | 主题 | 报文 |
|---|---|---|
| 直连设备接收 | v1/devices/{令牌}/rpc/request/{requestId} | { "method": …, "params": … } |
| 网关接收(发给子设备) | v1/gateway/rpc/{网关令牌} | { "device": "外部ID", "data": { "id", "method", "params" } } |
| 网关自己作为目标 | 不支持独立目标 | 下发给网关必须指定子设备外部 ID |
主题中的
{令牌}就是设备的 Access Token——以令牌作为主题隔离密钥,天然保证一台设备只能收到属于自己的指令。
四、失败行为(重要)
one-way 模式的失败是即时、显式的,平台侧发起人会直接收到错误:
| 情况 | 结果 |
|---|---|
| 设备(或网关)离线 | 下发失败,提示"设备不在线"——不排队、不缓存 |
| 目标是网关但未指定子设备 | 参数错误 |
| 设备在线但没实现该 method | 平台发送成功,设备端静默忽略——平台无法感知 |
因此设备端设计请遵循:
- 幂等:同一条指令可能因边缘重发而到达多次,执行逻辑要能重复执行;
- 关键动作要有设备侧确认闭环:例如下发重启后,设备重新上线并上报一个"已重启"属性,供平台侧确认;
- 离线指令不能依赖 RPC:需要"设备下次上线再执行"的语义,请改用属性通道(设备上线后拉取/接收属性变更)自行实现。
五、常见问题
| 现象 | 排查方向 |
|---|---|
| 提示设备不在线 | 设备未连上平台;或目标子设备无直连且父网关离线 |
| 下发成功但设备没反应 | 设备端未订阅正确主题(检查令牌与通配符);method 未实现;报文格式不符 |
| 子设备收不到指令 | 子设备无直连时应由网关转发——确认网关在线且边缘侧能按外部 ID 找到子设备 |
| 想下发后拿到返回值 | 当前仅支持 one-way 无回执,需回执请用属性/遥测通道上报执行结果 |
下一步:完整可运行的接入示例代码,请看《示例代码》。