开发者中心

SmartREST 2.0

概述

本节介绍可与QuarkIoE MQTT实现一起使用的SmartREST 2.0有效载荷格式。

SmartREST 2.0旨在利用MQTT协议,因此可以减少有效负载,甚至超过通过HTTP传输的SmartREST 1.0。 SmartREST 2.0仅可通过MQTT提供。

SmartREST 2.0为主通信提供以下MQTT主题 :

发布消息:


  s/uc/<X-ID>
                      

订阅应答:

s/dc/<X-ID>
                      

创建模板的主题参照此章节。

对比SmartREST 1.0的改变

SmartREST 2.0的基础很像以前版本的CSV有效载荷格式,支持以前创建的模板,最终创建目标JSON结构。

功能上的几个变化:

  • 模板不再包含对象的ID(而ID将由例如MQTT ClientId解析)
  • 可以使用外部ID直接创建和检索托管对象
  • 创建请求模板现在使用JSON Path(正如应答模板)
  • 应答支持列表
  • 如果只找到部分模式,应答也会返回
  • 为连接声明默认X-Id

支持的模板

SmartREST 2.0允许您为以下匹配的HTTP方法创建模板:

API GET POST PUT
设备清单 x x x
报警 x x
事件 x
测量值 x
操作 x

此外,您可以创建模板以从应答和操作返回某些值。

模板集合

模板集合是指定设备通信协议的一组请求和应答模板。 每个集合由唯一ID(称为X-Id)引用。

通过MQTT创建模板

就像SmartREST 1.0,你需要在一个消息中传递集合中的所有模板。 创建模板集合后,将无法再通过MQTT进行修改。 创建模板时,客户端需要发布到以下主题。


  s/ut/<X-ID>
                      

要验证模板集合是否存在,客户端可以订阅主题


  s/dt
                      

当订阅时,客户端可以向创建主题发送空消息,该消息将触发关于该X-ID的创建状态的新 消息。

示例: 发布空消息到 s/ut/myExistingTemplateCollection


  20,myExistingTemplateCollection,<集合ID>
                      

发布空消息到 s/ut/myNotExistingTemplateCollection


  41,myNotExistingTemplateCollection
                      
请求模板

请求模板包含以下基本字段:

字段 数据类型 可能取值 必选 描述
messageId String 引用集合中模板的唯一ID
method String GET
PUT
POST
是否获取,更新或创建数据
api String INVENTORY
MEASUREMENT
ALARM
EVENT
OPERATION
使用的QuarkIoE API
response boolean true
false
请求是否应触发应答模板。 对于GET模板默认为true否则默认为false
mandatoryValues List<String> API上的必填字段的值。 值取决于模板使用的API和方法
customValues List<CustomValue> 应该添加到对象的自定义值

请求模板列出在创建或更新数据时应添加的对象结构(必选和自定义)中的所有片段。 它可以在模板中设置固定值,然后由服务器替换。 如果未在模板中设置值,则该值需要包含在发布消息中(包括必选值)。

示例: 我们创建一个模板来创建一个这样的测量值(测量值有两个必需的值:类型和时间):


// 10,msgId,api,method,response,type,time,custom1.path,custom1.type,custom1.value
   10,999,POST,MEASUREMENT,,c8y_MyMeasurment,,c8y_MyMeasurement.M.value,NUMBER,
                      

此模板为测量值声明了一个附加的自定义属性。 它在模板声明中留下两个字段为空( 时间和自定义属性),以便客户端使用模板发送这两个值


999,2016-06-22T17:03:14.000+02:00,25
// We can also use server time by leaving the time empty
999,,25
                      

以下部分将详细介绍如何创建和使用不同的模板

GET模板

设备清单的GET模板不需要任何必选或自定义值。 相反,他们使用两个不同的字段。 使用SmartREST 2.0,您可以选择通过其ID或直接用externalId从设备清单获取对象。

字段 数据类型 可能取值 必选 描述
byId boolean true
false
GET是否应该由QuarkIoE ID(= true)或externalId(= false)执行
externalIdType String 如果模板由externalId调用,则设置固定的externalIdType

这使您能够以3种不同的方式查询设备清单:

使用QuarkIoE ID


  // Creation:
  10,999,GET,INVENTORY,,true
  // Usage:
  999,123456
                      

在模板中使用固定类型的外部ID


// Creation:
10,999,GET,INVENTORY,,false,c8y_Serial
// Usage:
999,myDeviceImei
                      

在模板中使用没有固定类型的外部ID


// Creation:
10,999,GET,INVENTORY,,false
// Usage:
999,c8y_Serial,myDeviceImei
                      
POST模板

POST模板需要基于API的一组不同的必选值:

API 必选值
测量值 type,time
事件 type,text,time
报警 type,text,status,severity,time
设备清单 externalIdType

以下为最小的模板创建:


  // Creation:
  10,100,POST,MEASUREMENT,false,c8y_CustomMeasurement,,
  10,101,POST,EVENT,,c8y_CustomEvent,mytext,,
  10,102,POST,ALARM,,c8y_CustomAlarm,mytext,ACTIVE,MAJOR,
  // Usage:
  100
  101
  102
                      

在设备清单上创建数据包括为该对象创建一个externalId。 这由必选值externalIdType控制。

重要: 所有POST设备清单模板以msgId之后的externalId值开始。 将此列留空将导致不创建外部ID。


  // Creation:
  10,100,POST,INVENTORY,,c8y_MySerial
  10,101,POST,INVENTORY,,
  // Usage:
  // Create object with externalId c8y_MySerial/myImei
  100,myImei
  // Create object with externalId c8y_MySerial/myImei
  101,myImei,c8y_MySerial
  // This message will result in not creating an external ID
  101,,c8y_MySerial
                      
PUT模板

设备清单的PUT模板遵循与GET模板相同的逻辑,您还可以为PUT使用自定义值。


  // Creation:
  // 10,msgId,method,api,response,byId,externalIdTyoe,custom1.path,custom1.type,custom1.value
  10,999,PUT,INVENTORY,,false,c8y_Serial,c8y_MyCustomValue,STRING,
  // Usage:
  999,myDeviceImei,myValue
                      

报警的PUT模板使用报警的类型来查找要更新的报警。 它将首先检查活跃报警,如果没有活跃报警,它将检查已确认报警。


  // Creation:
  // 10,msgId,method,api,response,type,custom1.path,custom1.type,custom1.value
  10,999,PUT,ALARM,,c8y_MyCustomAlarm,status,ALARMSTATUS
  // Usage:
  999,FAILED
                      

操作的PUT模板使用操作的片段来查找操作。 它将首先检查执行操作,如果没有执行操作,它将检查待处理操作。


  // Creation:
  // 10,msgId,method,api,response,fragment,custom1.path,custom1.type,custom1.value
  10,999,PUT,OPERATION,,c8y_MyOperation,status,OPERATIONSTATUS,SUCCESSFUL,c8y_Fragment.val,NUMBER,
  // Usage:
  999,24
                      
增加定制属性

所有POST和PUT值使您能够将自定义属性添加到模板的结果中。 单个自定义属性要求您在模板创建中添加以下三个值

字段 描述
path 应设置值的JsonPath
type 值的可选数据类型。 默认值: STRING
value 要设置的值。 将此字段留空需要客户端在使用模板时发送值
类型 描述
STRING 默认类型。 无需额外验证值
DATE ISO 8601格式的时间戳。 使用日期时不发送时间戳将使用服务器时间
NUMBER 带小数位的整数或数字
INTEGER 整数
UNSIGNED 整数 (正数)
FLAG 空白映射(例如c8y_IsDevice: {})。 客户端不需要为此值发送任何内容
SEVERITY 报警的严重级别。 用于更新告警的严重级别字段
ALARMSTATUS 报警的状态。 用于更新报警的状态字段
OPERATIONSTATUS 操作的状态。 用于更新操作的状态字段

示例:

带有自定义属性的清除报警模板。


  // Creation:
  10,999,PUT,ALARM,,c8y_MyCustomALarm,status,ALARMSTATUS,CLEARED,c8y_CustomFragment.reason,STRING,
  // Usage:
  999,Device resolved alarm on its own
                        

用于创建自定义测量值的模板。


  // Creation:
  10,999,POST,MEASUREMENT,,c8y_CustomMeasurement,,c8y_CustomMeasurement.custom.value,NUMBER,,c8y_CustomMeasurement.custom.unit,STRING,X
  // Usage:
  999,30.6
                        

用于更新设备中属性的模板。


  // Creation:
  10,999,PUT,INVENTORY,,false,c8y_Serial,c8y_MyCustomValue,STRING,
  // Usage:
  999,myDeviceImei,updatedValue
                        
应答模板

SmartREST 2.0应答模板使用与SmartREST 1.0中相同的结构。

字段 数据类型 必选 描述
messageId String 引用集合中模板的唯一ID
base String 所有模式将使用的JsonPath前缀
condition String 需要存在于对象中以使用模式的JsonPath
pattern List<String> 将从对象中提取并返回到设备的JsonPath列表

应答将用于每个操作以及将应答字段定义为true的任何请求模板。 在每种情况下,服务器将尝试每个注册的应答模板,因此对于单个操作或请求可能有多个应答行。

如果条件为真(或没有定义条件),SmartREST 2.0将始终返回应答模板。 未解析的模式将作为空字符串返回。 您应该使用condition字段来控制何时应返回应答模板。

示例:

从设备对象查询数据

设备对象:


 {
    "id": "12345",
    "type": "myMqttDevice",
    "c8y_IsDevice": {},
    "c8y_Configuration": "val1=1\nval2=2"
  }
                        

模板创建:


  10,999,GET,INVENTORY,,true
  11,888,,c8y_IsDevice,type,c8y_Test,c8y_Configuration
                        

客户端发布:


  999,12345
                        

客户端接收:


  888,myMqttDevice,,"val1=1\nval2=2"
                        

解析自定义操作

操作对象:


{
    "id": "12345",
    "deviceId": "67890",
    "agentId": "67890",
    "status": "PENDING",
    "c8y_CustomConfiguration": {
    "val1": "1",
    "val2": "2",
    "customValues": ["a", "b", "c"]
  },
  "description": "Send custom configuration"
}
                      

模板创建:


11,111,c8y_CustomConfiguration,deviceId,val1,val2,customValues[*]
11,222,,deviceId,c8y_CustomConfiguration.val1,c8y_CustomConfiguration.val2
11,333,,deviceId,val1,val2,customValues[*]
11,444,c8y_CustomConfiguration,c8y_CustomConfiguration.val3,val1,val2,customValues[*]
                      

客户端接收 (假设ClientId是"myMqttTestDevice"):


111,myMqttTestDevice,1,2,a,b,c
222,myMqttTestDevice,1,2
333,myMqttTestDevice,,,
                      

由于条件不匹配操作,因此不返回模板444。

使用缺省集合

将X-ID作为主题的一部分,您可以轻松使用多个模板集合,但为每个消息添加额外的字节。 如果设备多数情况下使用单个集合,那么将此集合指定缺省集合是有意义的。 使用指定的缺省集合,客户端可以使用不需要X-ID的特定主题,而且服务器将使用先前指定的X-ID。

您可以在MQTT ClientID中指定一个X-ID。 您的MQTT ClientID可能如下所示 :

d:myDeviceSerial:myDefaultTemplateXID
                      

注意:

如果在ClientId中使用缺省X-ID,则需要在开头加"d:",以指定客户端是设备。

不需要在建立MQTT连接时存在缺省模板(一旦客户端使用,就会进行验证)。