操作场景
物模型指将物理空间中的实体数字化,并在云端构建该实体的数据模型。在物联网智能视频服务(消费版)平台中,定义物模型即定义产品功能。完成功能定义后,系统将自动生成该产品的物模型。
定义过程
1. 客户新建产品,生成全局唯一性产品 ID(productId)。
2. 客户修改数据模型定义;可添加、删除、修改自定义数据对象。
3. 客户发布物模型,生成物模型 revision,生成设备端代码(生成的设备端代码会记录 productId/revision 等信息)。
4. 设备端 SDK+ 生成代码+用户开发,客户发布设备固件。
5. App 端 SDK+ 用户开发,客户发布应用 App。
6. 客户版本迭代,功能完善。
说明:
平台会记录每个产品,每次发布的物模型,终端上线时,平台实现数据模型的自动同步及版本兼容处理。
分层设计
设计特点
模板化/规范化的数据模型。
通讯层面,方便实现灵活的按功能约束传输数据对象。
物模型按功能元素、数据对象、数据属性的树状态层次结构进行组织:
树状层级:设备ID(DeviceID)|-- 功能元素(FC)|-- 数据对象(Data)|-- 数据属性(DataAttrib)对象索引:DeviceID.FC.Data.DataAttrib
其中功能元素定义了数据的每个属性的特征,对象索引描述物模型对象的引用,是设备物模型的一个子集。例如:
DeviceID.ProReadonly #设备所有状态类属性DeviceID.ProReadonly._online #设备在线状态DeviceID.ProReadonly._online.stVal #设备在线状态-当前状态值DeviceID.ProReadonly._online.t #设备在线状态-状态改变的时标值
功能元素
序号 | 功能元素 | 说明 | 备注 |
1 | ProConst | properties-const 常量属性(内置模型,不支持用户扩展) | 终端固有的参数信息,运行期间不会发生变化,固件升级可能导致 ProConst 参数变更。 例如:设备版本信息; 设备是否支持某项功能。 设备上电后,主动将 ProConst 参数上送到服务器。 |
2 | ProReadonly | properties-readonly 只读属性(用户可添加自定义数据) | 设备当前状态信息。 例如:在线信息(内置模型),镜头当前状态。 设备状态变更时,主动报告到云端。 |
3 | ProWritable | properties-writable 可写参数(用户可添加自定义数据) | 存储在云端,终端运行时需加载的参数。 例如:云存储开通套餐(内置模型),摄像头预置位。 终端初次启动,主动从云端拉取最新数据。 云端数据变更时,云端主动通知终端。 |
4 | Action | Action 操作(用户可添加自定义控制对象) | 设备接收到控制操作命令,改变当前状态。 例如:打开/关闭镜头,切换预置位. |
5 | Event | Event 事件(内置模型,事件消息体由用户自定义) | 内置通用事件模型,支持应用层触发任意类型的 JSON 格式事件。 |
数据对象
数据对象是物模型的基本数据单元,用于描述设备的一项具体功能或属性。客户通过添加自定义数据对象的方式,实现其对产品的数据建模。添加数据对象时,需指定其对象名称、数据类型、功能约束。
名称 | 说明 |
对象名称 | 对象名称需符合变量命名规范。 同一产品的不同对象名称需要确保唯一性。 约定以下划线开头的对象名为 IoT Video(Consumer Version) 平台的内置对象,客户自定义数据对象不得以下划线开头。 |
数据类型 | 基本数据类型:平台内置的几种基本数据类型。 自定义数据类型:客户通过基本数据类型定义的扩展数据类型。 |
功能约束 | 约定了数据对象的功能特征。 |
数据属性名
数据属性名遵循 IoT Video(Consumer Version) 平台的命名规范,不支持客户扩展。数据属性的命名空间约定如下:
序号 | 属性名 | 说明 |
1 | t | 数据时标,UTC 时标。 |
2 | stVal | 状态值 |
3 | setVal | 设定值 |
4 | ctlVal | 控制值 |
5 | origin | 源发者,描述控制对象的控制来源。 |
基本数据类型
序号 | 数据类型 | 说明 |
1 | int32 | 有符号32位整数。 |
2 | uint32 | 无符号32位整数。 |
3 | float32 | 32位浮点数。 |
4 | float64 | 64位浮点数。 |
5 | string32 | 字符串,最大长度32个字符。 |
6 | string64 | 字符串,最大长度64个字符。 |
7 | stringN | 最大长度为 N 的字符串。 |
扩展数据类型
用户可采用基本数据类型定义“复杂”的扩展类型,扩展数据类型同基本数据类型一样,可用于描述物模型的数据对象。
扩展数据类型定义示例。
{"name": "IntCoordinate","desc": "整形位置坐标","type": [{"type": "int32","name": "x","desc": "x坐标"},{"type": "int32","name": "y","desc": "y坐标"}]}
扩展数据类型值示例。
{"x" : 100,"y" : 100}
ProWritable 数据对象
ProWritable 数据对象结构定义如下:
序号 | 数据对象属性 | 类型 | 字段说明 |
1 | setVal | 用户定义 | 参数设定值,基本类型或用户扩展数据类型。 |
2 | t | int32 | 参数设置的 UTC 时间,由平台填写。 |
示例:
{"setVal" : 0,"t" : 1571275500}
ProWritable 设置流程
说明:
对于可写属性,即使当前设备不在线,设置请求仍会成功,数据会保存在云端,等设备下次上线时,设备会自动更新 ProWritable 属性。
ProReadonly 数据对象
ProReadonly 数据对象结构定义:
序号 | 数据对象属性 | 类型 | 字段说明 |
1 | stVal | 用户定义 | 当前状态值,基本类型或用户扩展数据类型。 |
2 | t | int32 | 状态更新的 UTC 时间,由终端填写。 |
示例:
{"stVal" : 0,"t" : 1571275500}
Action 数据对象
Action 数据对象具备 ProReadonly 的功能,其结构定义为:
序号 | 数据对象属性 | 类型 | 属性说明 |
1 | stVal | 用户定义 | 当前状态值,基本类型或用户扩展数据类型。 |
2 | t | int32 | 状态更新的 UTC 时间,由设备端更新。 |
3 | ctlVal | 用户定义 | 控制下发值,与 stVal 类型一致,此属性仅对设备端可见。 |
4 | origin | string128 | 控制操作来源信息,此属性仅对设备端可见。 |
说明:
Action 对象的 stVal 可写:操作的含义下发控制命令到设备。
云端在接收到对 Action.stVal 的写入请求时,会将该请求转换为对 Action.ctlVal 的控制请求,发送给设备端,并添加控制来源信息。
示例:
//用户在IoT Video(Consumer Version)的AcessId为"134384637"//App端请求关闭镜头,对Action.cameraOn进行控制,写入{"stVal" : 0}//设备端的Action.cameraOn对象会接收到控制命令{"ctlVal" : 0,"origin" : "user/134384637"}
origin 约定及限制
origin 用于描述来源信息可能有以下几种:
关键字 | 格式 | 说明 |
usr | usr/accessId | 来源于用户终端。 |
dev | dev/devId | 来源于设备终端。 |
webapi | webapi | 来源于 webapi 调用。 |
cloud | cloud | 来源于 IoT Video(Consumer Version) 云端。 |
lan | lan/accessId | 来源于局域网用户终端。 |
设备端开发者可通过对 Action 对象的 origin 参数的判断处理,实现具体的业务功能。例如,接收到来源于用户终端的控制请求后,向该用户发送一条定制的消息。
origin 在 Event 数据对象中也有应用,用于描述事件的来源信息。
Action 操作流程
说明:
对于 Action,若当前设备不在线,本次操作不会成功,服务器返回失败。
Event 数据对象
设备在运行过程中,由应用层触发的任意 JSON 数据。
事件结构
关键字 | 格式 | 说明 |
uuid | uuid | 事件的唯一性标志(可用于消息去重处理)。 |
origin | string | 事件的来源信息。 |
t | int32 | 事件的 UTC 时标。 |
topic | string | 主题,由事件发布者指定。 |
data | json | 内容,由事件发布者填写。 |
约束及限定
约定以'$'字符起始的 Topic 为平台保留,开发者不能使用。
origin 的含义与 Action 数据对象相同。
通讯过程
订阅/发布机制
用户绑定设备后,用户终端在接入服务器上线时,会自动订阅相关设备。
接入服务器验证设备临时访问 Token 成功,用户自动订阅该设备。
对于已订阅的设备,用户终端 SDK 将缓存该设备的物模型信息。
设备端状态变更时,云端会将变更信息自动发布到用户端。
IPC 设备物模型示例
序号 | 功能元素 | 对象名 | 类型 | 字段说明 |
1 | ProReadonly | _online | int32 | 在线状态。0:离线,1:在线,2:休眠。 |
2 | ProWritable | _cloudStoreage | struct | 云存储系统配置参数信息。 |
3 | ProWritable | _logLevel | int32 | SDK 日志输出等级。 |
4 | ProWritable | presetPosSetting | sturct | 预置位参数设置。 |
5 | Action | camerOn | int32 | 打开/关闭摄像头。 |
6 | Action | takePhoto | int32 | 拍照。 |
7 | Action | presetPosition | int32 | 预置位相关位置(可控)。 |
物模型定义:
{"iotModel":{"TypeDefs": [{"name": "_ProductInfo","desc": "产品信息","type": [{"name": "productModel","desc": "产品型号","type": "string32"},{"name": "productID","desc": "产品ID","type": "string32"},{"name": "funcCode","desc": "产品可选功能码","type": "uint32"},{"name": "revision","desc": "物模型修订版本","type": "uint32"},{"name": "revisionUtc","desc": "物模型修订时间","type": "uint32"}]},{"name": "_VersionInfo","desc": "固件信息","type": [{"name": "sdkVer","desc": "SDK版本号","type": "uint32"},{"name": "swVer","desc": "应用软件版本号","type": "uint32"},{"name": "hwVer","desc": "硬件版本号","type": "uint32"}]},{"name": "_CloudStorageService","desc": "云存储服务参数","type": [{"name": "serviceType","desc": "云存储服务类型","type": "int32"},{"name": "utcExpire","desc": "云存储服务过期时间(UTC)","type": "int32"},{"name": "pause","desc": "云存储服务暂停,设置为非0时,即使当前存在有效的云存储套餐,设备也不会云存推流","type": "int32"},{"name": "serviceParm","desc": "云存储服务参数信息","type": "string128"}]},{"name": "PlanTimeSection","desc": "计划时间段参数","type": [{"name": "desc","desc": "描述信息","type": "string64"},{"name": "enable","desc": "时间段参数使能","type": "int32"},{"name": "dayOfWeek","desc": "0~6:周日~周六 -1:不指定星期","type": "int32"},{"name": "begin","desc": "每天开始的时间0~86399 -1:无效","type": "int32"},{"name": "end","desc": "每天开始的时间0~86399 -1:无效","type": "int32"}]},{"name": "RecodePlan8","desc": "录像计划,预置8个可设置的时间段,用户可通过启用/设置这些时间段,实现计划录像的功能","type": [{"name": "timeSection1","desc": "预置时间段1","type": "PlanTimeSection"},{"name": "timeSection2","desc": "预置时间段2","type": "PlanTimeSection"},{"name": "timeSection3","desc": "预置时间段3","type": "PlanTimeSection"},{"name": "timeSection4","desc": "预置时间段4","type": "PlanTimeSection"},{"name": "timeSection5","desc": "预置时间段5","type": "PlanTimeSection"},{"name": "timeSection6","desc": "预置时间段6","type": "PlanTimeSection"},{"name": "timeSection7","desc": "预置时间段7","type": "PlanTimeSection"},{"name": "timeSection8","desc": "预置时间段8","type": "PlanTimeSection"}]},{"name": "IntCoordinate","desc": "整形位置坐标","type": [{"type": "int32","name": "x","desc": "x坐标"},{"type": "int32","name": "y","desc": "y坐标"}]},{"name": "PresetPosSetting","desc": "摄像头预置位设定参数","type": [{"name": "pos1","desc": "预置位1坐标","type": "IntCoordinate"},{"name": "pos2","desc": "预置位2坐标","type": "IntCoordinate"},{"name": "pos3","desc": "预置位3坐标","type": "IntCoordinate"},{"name": "pos4","desc": "预置位4坐标","type": "IntCoordinate"},{"name": "pos5","desc": "预置位5坐标","type": "IntCoordinate"},{"name": "pos6","desc": "预置位6坐标","type": "IntCoordinate"}]},{"name": "MyStruct","desc": "自定义数据结构","type": [{"name": "attr1","desc": "aaaa","type": "int32"},{"name": "attr2","desc": "bbbb","type": "string64"},{"name": "attr3","desc": "eeee","type": [{"name": "attr3_1","desc": "cccc","type": "int32"},{"name": "attr3_2","desc": "dddd","type": "int32"}]},{"name": "attr4","desc": "jjjj","type": [{"name": "attr4_1","desc": "aaaa","type": "int32"},{"name": "attr4_2","desc": "bbbb","type": "string64"},{"name": "attr4_3","desc": "eeee","type": [{"name": "attr4_3_1","desc": "cccc","type": "int32"},{"name": "attr4_3_2","desc": "dddd","type": "int32"}]}]}]}],"DataDefs": [{"name": "_productInfo","desc": "产品信息","type": "_ProductInfo","FC": "ProConst"},{"name": "_versionInfo","desc": "版本信息","type": "_VersionInfo","FC": "ProConst"},{"name": "_otaMode","desc": "OTA升级模式(内置对象)","type": "int32","FC": "ProWritable"},{"name": "_otaVersion","desc": "OTA升级版本(内置对象)","type": "string32","FC": "Action"},{"name": "_otaUpgrade","desc": "OTA升级进度(内置对象)","type": "int32","FC": "Action"},{"name": "_logLevel","desc": "日志输出等级设置(内置对象)","type": "int32","FC": "ProWritable"},{"name": "_cloudStoage","desc": "云存储服务参数(内置对象)","type": "_CloudStorageService","FC": "ProWritable"},{"name": "cameraOn","desc": "打开摄像头","type": "int32","FC": "Action"},{"name": "takePhoto","desc": "触发设备拍一张照片","type": "int32","FC": "Action"},{"name": "shootVideo","desc": "触发设备拍一段视频","type": "int32","FC": "Action"},{"name": "recodePlan","desc": "录像计划参数,摄像头按照参数设定的时间范围进行本地录像","type": "RecodePlan8","FC": "ProWritable"},{"name": "presetPosSetting","desc": "摄像头预置位参数(存储用户预设的摄像头位置坐标信息)","type": "PresetPosSetting","FC": "ProWritable"},{"name": "presetPosition","desc": "摄像头预置位(用户可控制摄像头转向预设的某个位置)","type": "int32","FC": "Action"},{"name": "test","desc": "测试数据","type": "MyStruct","FC": "ProReadonly"}]}}