数字孪生 - 是什么
数字孪生(digital twin) : 是实体设备在云端的映射,是存在于云服务中设备的虚拟表示,又被称作数字分身。
那么为什么会有这个概念,其在实际场景中的作用是什么。
数字孪生 - 怎么用
实际IoT场景下,涉及设备的控制和查看。假设这里控制端是手机,设备是车辆,两者之间通过MQTT服务进行双向通信。手机可以控制车辆,查看车辆信息。
设备在线时,查询和控制都可以满足,但是离线时,考虑下面情况,
- 设备离线时,怎么查询设备状态 。
- 设备离线时,控制端发出的数据怎么处理。
通过数字孪生,可以覆盖上面2个问题 ,
结合上图,通过数字孪生,设备在云端存储了一个分身,控制端不再直接和设备交互,而是和云端的设备分身交互,查看车辆状态,控制设备。
针对上面的问题:
- 查看:设备离线时,由于云端设备分身是一直在线的,可以从云端设备分身上获取设备的最后状态。
- 控制:设备离线时,云端设备分身可以先接收控制指令并且改变状态,等设备再次上线时,再将分身的状态同步给设备。
至此我们对于数字孪生有了初步了解,其是设备在云端上的分身 ,可以用于处理设备离线时的查看或控制请求。下面我们在展开说说具体的设计思路。
数字孪生 - 设计思路
数字孪生里, 有2个基本概念 设备本身 和 设备分身 ,对于这里2个概念,利用如下3个属性 ,可以做巧妙设计 ,
desired status , reported status,actual status
设备本身:actual status,代表设备的真实状态。
设备分身:desired status 和 reported status 是设备分身的属性,分别代表对于设备的预期值 和 设备的上报值。 任何有控制权限的控制端都可以对预期值进行修改,而上报值只能由设备上报更新。
当我们想对设备进行控制时,不是直接向设备发送控制指令,而是先改变分身desired status,当设备发现actual status和分身desired status不一致时,再由设备端触发状态转变,随后再上报自己当前状态actual status。如下图:
1,控制端发出关灯指令,设备分身desired status改变为off
2,desired status同步到设备端,设备改变自身状态 关灯,actual status变为off
3,设备端上报自身状态给 设备分身,reported status为off
额外优势
至此,我们讲解了数字孪生的设计思路 ,仔细看上述的过程,会发现这种设计还有额外的优势
- 事件转换为状态: 分身的存在可以将事件请求,都转换为状态存储起来,这比存储事件,面对多端请求时,更容易处理。
- HTTP接口:控制端不在直接和设备本身交互,而是和分身所在的云端进行交互。这样云端可以设计额外提供http接口,这样对不方便使用mqtt的控制端,多了一种选择。
实现
AWS IoT Core - 影子服务
根据上述的设计思路,我们完全可以自己实现数字孪生。但不得不说,AWS的物联网服务 AWS IoT Core 中的影子服务本身对于数字孪生就是一个很好的实现。
影子服务介绍
摘自官网:
- AWS IoT Device Shadow 服务为 AWS IoT 事物对象添加影子。无论设备是否已连接,Shadows 都可以将设备的状态提供给 AWS IoT 应用程序和其他服务。 AWS IoT 事物对象可以有多个命名的阴影,这样您的物联网解决方案就有更多选项可以将您的设备连接到其他应用程序和服务。
这里事物就是指的设备本身,阴影就是**设备分身,**所以影子服务和我们上面介绍的数字孪生是完全吻合的!
接入影子服务,开干!
影子服务本身的通信机制也是基于MQTT实现的,所以交互上,需要 发布publish / 订阅subscrib 某些topic,以此来进行数据通信。
服务相关topic
这里是影子服务预定义的topic,
/get
/get/accepted
/get/rejected
/update
/update/delta
/update/accepted
/update/documents
/update/rejected
/delete
/delete/accepted
/delete/rejected
由上可知,影子服务的topic接口设计是围绕着 CURD-增删改查实现的。
交互流程
画个流程示例,更好说明下这些topic的使用方法,
- 1 - 订阅
- 设备端订阅这几个topic: /get/accepted , /get/rejected,/update/accepted, /update/rejected, /update/delta 。
- 2 - 查询
- 设备端 - 设备上线后,可以先查询下影子的状态,向
ShadowTopicPrefix/get
发送请求,会触发ShadowTopicPrefix/get/accepted
或ShadowTopicPrefix/get/rejected
(如无权限 则查询请求被拒),当获取ShadowTopicPrefix/get/accepted
中的数据后,设备端即可收到当前影子的数据状态。
- 设备端 - 设备上线后,可以先查询下影子的状态,向
- 3 - 更新
- 影子改变:APP端发送控制命令,比如开车门,先请求改变影子状态,影子服务收到后会改变影子
desired status
。从而触发/update/accepted
和/update/delta
事件。- accepted事件:只要影子上的值有变化,就会触发。
- delta事件: 只有当影子上的
desired status
和reported status
不一致时,才会触发,delta代表desired status
中差异的部分。
- 设备改变:通过订阅接收
/update/accepted
和/update/delta
中的数据,可以获得desired status
,设备可以根据desired status
去改变设备的actual status
。 - 状态上报:设备端通过上报自身状态到影子服务,改变影子服务上设备分身的
reported status
。
- 影子改变:APP端发送控制命令,比如开车门,先请求改变影子状态,影子服务收到后会改变影子
效果,展示!
这里我们用代码在控制台里模拟下 控制端-手机app 和 设备端-车辆,控制端-手机app可以发送控制指令(开门 / 关门) 到影子服务,改变其 desired status
,设备端车辆订阅topic拿到订阅数据后,根据 desired status
改变车辆自身 actual status
,然后再上报给影子服务更新 reported status
。
这里手机作为控制端 ,1-锁车,2-解锁 ,输入锁车或解锁指令后 ,会先改变左侧影子 desired status
状态,随后车辆收到/update/accepted
和 /update/delta
,其中会带有影子desired status
,车端根据其进行相应的锁车或解锁,从而 actual status
会改变,随后再上报给影子服务,更新影子 reported status
。
当控制指令下发,开始执行时,通过上面的动图可看到这个变化的顺序,影子desired status
→ 设备actual status
→ 影子reported status
源码
上述演示,对应的源码