设备影子

物联网核心套件 IoTCore

  • 旧版文档
  • 产品定价
  • 功能发布记录
  • 产品描述
    • 产品概述
    • 产品优势
    • 核心概念
    • 系统限制
  • 快速入门
    • 使用规则引擎将设备消息流转到业务服务器
    • 创建设备
    • 操作演示
    • 获取连接信息
    • 快速入门流程
    • 创建 IoT Core 实例
    • 使用 MQTT 模拟器连接及收发消息
  • 典型实践
    • 数据转发到函数计算服务CFC
    • 数据转发到用户 Kafka
    • 设备状态数据存储到时序数据库TSDB
    • 数据转发到百度消息服务BMS
  • 服务等级协议SLA
    • 服务等级协议SLA(V2.0)
  • API参考
    • 设备管理
    • 概述
  • 常见问题
    • MQTT客户端及设备SDK相关问题
    • 使用选择
  • 开发者指南
    • 设备侧
      • 通过 IoT Core 官方 SDK 接入
      • 通过开源MQTT Client SDK接入
    • 服务侧
      • IoT Core 日志 SDK (Java)
      • 概述
  • 操作指南
    • 设备接入与管理
      • 应用权限
      • 创建设备
      • 设备影子
      • 管理模板
      • 共享订阅
      • 设备预配
      • 管理设备
      • 通过开放协议接入
        • 使用证书鉴权建立MQTT连接
        • 通过CoAP发布消息
        • 通过MQTT连接及收发消息
        • 通过HTTP发布消息
    • 实例管理
      • 修改实例
      • 创建实例
      • 停止及启动实例
      • 删除实例
    • 运维管理
      • 日志服务
    • 规则引擎
      • 常用查询语句示例
      • 数据目的地管理
      • 数据查询语法和函数
      • 操作步骤
      • 数据目的地
      • 数据筛选
      • 概述
所有文档
menu
没有找到结果,请重新输入

物联网核心套件 IoTCore

  • 旧版文档
  • 产品定价
  • 功能发布记录
  • 产品描述
    • 产品概述
    • 产品优势
    • 核心概念
    • 系统限制
  • 快速入门
    • 使用规则引擎将设备消息流转到业务服务器
    • 创建设备
    • 操作演示
    • 获取连接信息
    • 快速入门流程
    • 创建 IoT Core 实例
    • 使用 MQTT 模拟器连接及收发消息
  • 典型实践
    • 数据转发到函数计算服务CFC
    • 数据转发到用户 Kafka
    • 设备状态数据存储到时序数据库TSDB
    • 数据转发到百度消息服务BMS
  • 服务等级协议SLA
    • 服务等级协议SLA(V2.0)
  • API参考
    • 设备管理
    • 概述
  • 常见问题
    • MQTT客户端及设备SDK相关问题
    • 使用选择
  • 开发者指南
    • 设备侧
      • 通过 IoT Core 官方 SDK 接入
      • 通过开源MQTT Client SDK接入
    • 服务侧
      • IoT Core 日志 SDK (Java)
      • 概述
  • 操作指南
    • 设备接入与管理
      • 应用权限
      • 创建设备
      • 设备影子
      • 管理模板
      • 共享订阅
      • 设备预配
      • 管理设备
      • 通过开放协议接入
        • 使用证书鉴权建立MQTT连接
        • 通过CoAP发布消息
        • 通过MQTT连接及收发消息
        • 通过HTTP发布消息
    • 实例管理
      • 修改实例
      • 创建实例
      • 停止及启动实例
      • 删除实例
    • 运维管理
      • 日志服务
    • 规则引擎
      • 常用查询语句示例
      • 数据目的地管理
      • 数据查询语法和函数
      • 操作步骤
      • 数据目的地
      • 数据筛选
      • 概述
  • 文档中心
  • arrow
  • 物联网核心套件IoTCore
  • arrow
  • 操作指南
  • arrow
  • 设备接入与管理
  • arrow
  • 设备影子
本页目录
  • 定义
  • 使用场景
  • 场景1:网络不稳定,设备频繁上下线。
  • 场景2:多程序同时请求获取设备状态。
  • 场景3:设备掉线。
  • 场景4:设备状态比对通知
  • 场景5:设备初始配置信息获取
  • 整体架构
  • 创建影子模板
  • 创建设备
  • 创建应用
  • 两端交互
  • 资源创建
  • 创建影子模板
  • 创建设备(灯泡设备端使用)和应用(app端使用)
  • 状态上报

设备影子

更新时间:2025-08-21

定义

设备影子是设备在云端的虚拟映射(可以理解为一个json文档),用来记录设备的最近状态和预期状态,通过设备影子可以轻松实现云端对设备状态的管控。

使用场景

场景1:网络不稳定,设备频繁上下线。

由于网络不稳定,设备频繁上下线。应用程序发出需要获取当前的设备状态请求时,设备掉线,无法获取设备状态,但下一秒设备又连接成功,应用程序无法正确发起请求。

使用设备影子机制存储设备最新状态,一旦设备状态产生变化,设备会将状态同步到设备影子。应用程序只需要请求或订阅推送方式获取影子中的状态即可,不需要关心设备是否在线。

场景2:多程序同时请求获取设备状态。

如果设备网络稳定,很多应用程序请求获取设备状态,设备需要根据请求响应多次,即使响应的结果是一样的,设备本身处理能力有限,无法负载被请求多次的情况。

使用设备影子机制,设备只需要主动同步状态给设备影子一次,多个应用程序请求或订阅推送方式,获取设备影子中存储的设备状态,即可获取设备最新状态,做到应用程序和设备的解耦。

场景3:设备掉线。

设备网络不稳定,导致设备频繁上下线,应用程序发送控制指令给设备时,设备掉线,指令无法下达到设备。通过QoS=1或者2实现,但是该方法对于服务端的压力比较大,一般不建议使用。

使用设备影子机制,应用程序发送控制指令,指令携带时间戳保存在设备影子中。当设备掉线重连时,获取指令并根据时间戳确定是否执行。

设备连接掉线,指令发送失败。设备再上线时,设备影子功能通过指令加时间戳的模式,保证设备不会执行过期指令。

场景4:设备状态比对通知

设备上报状态时,仅需报告变更的部分;此时应用对发生变化的属性值更为关心。反之应用对设备亦然。

应用或设备更新属性(desired/reported)后,设备或应用可获取差异推送delta。

场景5:设备初始配置信息获取

设备首次连接时,需要一些配置项或参数作为初始化配置,一般可将配置信息写入固件,但具有差异化的配置就较难处理。

使用设备影子机制,可以将一般性的配置写入影子模板,以此模板创建设备时模板内容将作为设备初始版本的影子。若针对特定设备变更初始配置,也可以针对性更新其影子,设备首次连接时进行 get 获取影子,即可获取期望配置。

整体架构

我们将使用设备影子的实体分为设备端和控制端:前者代表常见的物联网设备,例如网关,智能开关等。后者代表具有控制能力的实体,例如应用服务端,手机app等。

整体架构.png

设备和应用是百度抽象出的一组概念,分属于上图中的设备端和控制端。

创建影子模板

参考 https://cloud.baidu.com/doc/IoTCore/s/2k7o8yf4k

影子模版属于模板的一部分,包含了设备要上报的属性以及其初始值,采用json格式定义。

其限制条件如下:

  • 最外层只能包含三个字段,分别是tags,reported和desired
  • 属性名称不能以@开头,且其中不能包含dollar($),dot(.),space( ),以及comma(,)符号,<=64bytes
  • 属性值支持bool、int32、int64、float、double、string,不支持null和array,对于string类型<=512bytes
  • 对于tags,reported,desired每个存储体嵌套层级<=5
  • 每个JsonObject层级中key值<=50

image2021-9-13_14-57-21.png

创建设备

参考 https://cloud.baidu.com/doc/IoTCore/s/ek7o8yepa

设备创建完成后,百度云会自动生成其对应的影子,因此新建的设备可以直接使用影子服务。

设备可以设定自己的权限组key(默认为设备名),这个key用来决定控制端能否控制(更新设备desired,并接收设备reported delta,详见下文两端交互)该设备,下文会做介绍。

image2021-2-2_11-26-17.png

创建应用

参考 https://cloud.baidu.com/doc/IoTCore/s/Gkfeuwrpr

注意,在创建时,需要选择设备影子的使用方式,并填写权限组key(可以填写多个)。

这里的权限组key和上面设备的权限组key一致,只有设备和应用的权限组key相同时,该应用才能控制该设备。

image2021-2-2_11-27-50.png

两端交互

设备和应用创建完成后,即可通过相应的连接方式连接到百度云,并通过设备影子进行状态上报、控制指令下发等操作。

为了方便用户使用,我们提供了java sdk https://github.com/baidu/iotcore-sdk-java(其他语言的 SDK 开发中,亦可参考 Java 版本自行实现交互逻辑)。

我们以智能家居中常见的“灯泡”场景作为示例,来演示设备影子的使用方式。

设想卧室里的智能灯,用户可以通过手机app查看或者控制灯泡的开关、亮度、颜色等属性。

资源创建

创建影子模板

影子模板包含了设备要上报的属性以及其初始值。当前场景我们定义如下:

Plain Text
1{
2    "tags": {
3        "name": "智慧灯泡"
4    },
5    "reported": {
6        "env_brightness": -1,
7        "status": "unknown",
8        "color": "unknown",
9        "brightness_percent": -1
10    },
11    "desired": {
12      "status": "closed",
13      "color": "white",
14      "brightness_percent": 50
15    }
16}

影子模板里包含了三部分:

  • tags里包含了灯泡的元信息。示例里只包含了name,实际使用还可以包含批次、型号等等信息。
  • desired里包含了定义的灯泡可以改变的属性。示例里包含了状态、颜色、亮度几个信息。
  • reported代表灯泡上报的信息。由于这里只是模板,因此只定义了属性名,各个值都设置为了“unknown”,表示设备还未上线初始化过。此外,可以看到这里还包含了只读(指desired中不包含,因此无法通过下发控制指令来修改)属性"env_brightness"(环境亮度)。设备影子允许reported和desired不完全同构。

创建设备(灯泡设备端使用)和应用(app端使用)

根据上文中的操作指南创建两端使用设备和应用(注意,两者要配置相同的groupKey),获取到对应连接信息,并连接到 IoT Core(连接方式参考 https://cloud.baidu.com/doc/IoTCore/s/Akck4811r)。

设备端推荐使用mqtt协议,其更适合小型物联网设备。

app端可以采用mqtt或者http等协议。mqtt协议优势在于可以通过sub相关主题,来实时监听设备的状态变化。http的优势在于开发人员相对更加熟悉,并且无状态,但无法做到实时监听。

状态上报

灯泡在上电联网并接入到iotcore之后,就可以开始上报自身的状态。

上报方式为向$iot/${deviceName}/shadow/update/reported主题发布一条自身的状态消息(${deviceName}用实际的iotcore中注册的灯泡的设备名替换)。

初始化或者每当有状态信息变化时,都可以向该主题发布消息。

在这个场景里,上报的信息如下:

Plain Text
1{
2    "reported": {
3        "env_brightness": "0,
4        "status": "closed",
5        "color": "white",
6        "brightness_percent": 50
7        "@version": 1
8    }
9}

这里为了方便展示,将上报信息(还有后文指令下发信息)直接用 json表示出来 。实际使用过程需要调用SDK 的上报接口。

可以看到,这里多了一个“@version”字段,用来表示当前信息的版本号,每次上报需要严格加一。

指令下发

当用户想要修改灯泡状态时,例如打开灯泡,则可以通过app下发一条指令。

下发指令的方式为向$iot/${deviceName}/shadow/update/desired主题发布一条指令信息(${deviceName}用实际的iotcore中注册的灯泡的设备名替换)。

例如打开灯泡的信息如下:

Plain Text
1{
2    "desired": {
3        "status": "open"
4    }
5}

设备端(灯泡)需要预先定义订阅主题$iot/${avatarId}/shadow/delta/desired。

这样,app在发布完消息后,设备端就可以实时的接收到这条指令,再通过本地程序(例如实际的硬件处理程序)处理这条指令即可。处理完成后,再通过上报状态的方式将自身状态通知到app端即可。

上一篇
创建设备
下一篇
管理模板