基于阿里云iot平台的简化版设计方案
抽象概念
产品(Product):使用相同连接方式+相同物模型的一类设备。基本字段:
唯一标识:平台生成的产品唯一标识,一般是uuid;
名称;
描述;
节点类型:直连设备、网关设备和网关子设备;
联网方式:WiFi、蜂窝、以太网,以及lora,lora需要填入一些参数(前期先不支持);
连接协议:指的是数据到上一级节点的通信协议。我们暂时不使用阿里云那种自定义topic+脚本转换的方式,而是选择已经对接好的协议:
- 对于直连设备和网关设备:
- 标准MQTT协议:使用规定好的topic进行pub/sub,格式可以参考阿里云;
- 标准HTTP(S)协议:使用规定好的url进行上报;如果想要下控,需要对端host地址;或者参考阿里云,不支持通过HTTP协议下控;
- 其他协议:手动对接的各类协议。所有协议都有唯一编码;
- 对于网关子设备,可以实现一些常见的硬件协议,如:
- modbus协议;
- opc ua协议;
- ZigBee协议;
- 蓝牙协议;
- 未知协议:这里的网关还包括云云对接的情况,此时网关产品下挂载的设备实际是一种虚拟设备;此时设备如何上第三方云平台我们是不必知晓的,此时标记为未知协议即可,该协议不需要任何参数;
- 无论哪种设备,这里选择的协议都是设备与拓扑模型中的上一层通信的协议,协议需要的参数一般是配置在设备层的。
物模型:暂不允许自定义物模型,只能从预置的物模型里面筛选;
- 属性:属性其实是一种综合了事件+命令的抽象,自动生成对应的get/set命令,以及post属性的event;
事件:设备上报的信息,使用json schema定义;
- 命令:即服务,为了重构简单,仍然叫命令。也是json schema定义。
注:
- 物模型和连接协议都是通过使用场景+设备类型进行筛选的,移除以前设计的设备品牌+设备型号的抽象,更便于维护;
- 与以前的设计不同,属性、事件和命令的标识符,只需要保证在同一设备类型下唯一即可。
- 参考阿里云的设计,属性上报的事件都固定叫
EVENT_POST_ATTR
,设置属性的命令叫CMD_SET_ATTR
,获取属性的命令叫EVENT_GET_ATTR
。实际上大部分设备都是定时上报属性,并不支持主动询问。所以属性应该分为:1:可读,2:可设置,4:可询问,这三种的位运算组合; - 非标准协议一般选择了协议就自动绑定了物模型,不再需要手动绑定;
- 选择了标准协议,但是没有绑定物模型,那就默认支持所有物模型。
校验类型:不可选,目前都是强校验,数据不符合要求的,塞入异常数据的kafka topic里;
协议参数:某些协议参数可能需要在产品级别确定;
注意:除了名称和描述,其他字段都是禁止编辑的,想改的话,就删除产品后重新添加;如果产品下面挂载的有设备,禁止删除产品;
设备(Device)。设备是挂在产品下面的,继承产品的所有信息。由于大部分信息都定义在产品里了,设备这边的字段就很少:
- ID:平台对设备的唯一标识;
- 名称;
- 设备本身的标识:一般是硬件本身的序列号,但是也可以是别的,阿里这里用了deviceName;productKey+deviceName构成唯一索引;
- 状态:启用、禁用设备;
- 在线状态:只读数据;
- 对于网关子设备,还需要选择实际对接的网关设备(不考虑集群场景);
- secretKey:可以沿用以前的accessToken;
- 协议参数:如设备的内外网host地址,设备自身访问密钥等;阿里云无此类参数的原因是其要求子设备与网关的通信自行协商。
- 注意:设备的大部分信息也禁止编辑,要改的话也是删除后重新添加;
设备分类:参考阿里云的设计,分为领域-场景-设备类型三层。不同场景可以包含统一设备类型;
TAG: 产品和设备都可以增加自定义的kv字段作为tag,主要用于搜索。之前设计的设备品牌、型号,都可以迁移到tag中,不影响接口返回值。可以沿用以前ext的json设计,也可以单独开表,为了节省时间可暂时沿用ext设计;
初期暂时不需要实现的功能:
- 设备影子。该设计主要是为了解决设备网络情况不佳收不到下发命令的情况,以及主动索取设备属性导致请求过于频繁到设备压力较大的情况。后者可以使用事件/属性缓存完成,前者暂时让用户手动重发;
- 设备分组。该功能放在应用层做即可,只是为了方便管理;
- 任务(Job)功能:后期根据情况添加,可以和规则引擎融合;
- 证书相关功能:暂不需要;
- 通过脚本解析协议:优先级靠后,目前在代码层实现(脚本的性能较低,只是灵活度更高);
与阿里云平台的区别
阿里云添加设备的流程是:
- 添加产品;
- 添加设备;
- 设备/网关使用sdk主动连接阿里云平台,激活设备;
- 仅支持固定的云云对接场景;
注意第3步是要求设备/或者设备网关适配阿里云平台,所以如果设备采用我们自研的MQTT软网关,可以使用同样的对接流程。但是我们要考虑更广泛的云云对接的场景,所以我们需要更多的参数。
例子
这里拿个人曾经对接过的一些设备类型作为例子,说明添加流程。
标准协议设备直连
任意设备使用标准协议,步骤都类似。
先新建一个产品,对应该类设备。然后选择标准协议,绑定物模型。
标准协议网关连接
创建一个网关产品,然后选择标准协议。
理论上,网关会根据实际连接的网关子设备来决定物模型,所以网关无须绑定物模型。
创建一个网关设备。
创建网关子设备产品,然后选择子设备连接网关的协议(一般是非标协议,物模型自动绑定)。
创建网关子设备,然后将其挂到网关设备管理之下。
非标协议直连
新普惠环境监测仪,采用自定义的modbus over tcp协议,蜂窝通信。在设备上设定服务器地址后,设备会主动连接服务器。但是上报数据需要服务器主动发送请求索取。
建立产品:节点选择直连设备,协议选择“智慧工地-环境监测-新普惠环境监测仪“
产品协议参数:采样间隔
添加设备:正常添加序列号即可
非标协议边缘网关连接
宇泛人脸检测设备离线版,采用以太网通信,http+ftp协议(限局域网)。必须经过边缘网关转换才能正常与云端通信。
首先建立网关产品:假设这里是自研网关,采用标准MQTT协议(无须产品参数);
然后在网关产品下面添加实际的网关设备,需要参数:
- ip地址;
- 其他协议通信地址;
然后建立网关子设备产品:通信方式选择”智慧园区-人脸识别-宇泛设备离线版“;
网关子设备产品协议参数:
上报地址:当有人通过考勤机时,上报到哪里。该参数也可以在实施的时候一次性设置好;
心跳间隔:该参数需要设置给设备,然后设备主动发起心跳与网关通信;
然后添加网关子设备,关联到上文中网关产品下的设备,设备协议参数:
- 局域网ip地址;
- 通信端口;
- 通信密钥;
注意:如果仅仅需要设备上报考勤信息,而无需人员、照片下发功能,也可以作为云端直连设备接入。此时所有参数都已经预先设置好,云端其实不需要任何参数。这种情况可以单独设置一个简化版协议。
同样,大部分直连设备都可以通过自研的边缘网关中转。
非标协议云云对接
宇泛人脸检测设备wo平台版,采用以太网通信,直连宇泛自家的wo平台,属于云云对接。
首先建立网关产品:通信协议选择”智慧园区-人脸识别-宇泛设备wo平台版”,产品本身不需要协议参数;
在网关产品下面增加网关设备,填入参数:
- wo平台appId;
- wo平台appKey;
- wo平台appSecret;
增加网关子设备产品,通信协议选未知协议,不需要任何参数。
在网关子设备产品下,录入真正的人脸识别设备,也不需要额外参数。
MySQL schema设计
1 | create table if not exists device |
- 具有相同物模型的设备应被归类为同一设备类型;
- 设备分类引用的都是系统字典里面的value_str;
- 物模型最终是由product中的字段确定的;
- 如果按着阿里云的设计,选择标准品类之后,物模型仍然是可以编辑的;也就是说,product里面保存的是数据的copy而非引用;
- protocol表里关联的物模型,是私有协议对应的物模型,是schema_meta表里id的数组;举个例子:
- 人类识别上传考勤信息时,体温信息是一个标准物模型里“考勤上传”这个事件的可选字段;定义在schema_meta里;
- 私有协议里的schema_events里面含有该事件;
- 产品在选择该私有协议后,自动绑定了该事件的副本。用户可以编辑物模型,将体温参数删除。
物模型数据结构设计
阿里云是自定义了一套json来描述schema,我们这里直接用json schema标准,并进行扩展。
属性
1 | { |
其他的细节可以参考阿里云进行扩展
事件和命令
其实与属性类似,但是标识符需要分别手动设置。
此外:
- 事件有个优先级设置(0-低,1-一般,2-高);
- 命令有个同步、异步的设置,不过目前所有命令都是异步设计;
- 命令的回复也有一个schema;