边缘应用 Link IoT Edge对接
本章主要介绍如何实现 Link IoT Edge平台的API接口调用。物联网边缘计算支持使用边缘端API管理接入到网关的设备,包括获取设备及设备列表、设置设备属性、订阅设备事件等。
1.Link IoT Edge平台概述
Link IoT Edge提供了设备接入和本地计算等能力,当Link IoT Edge被集成到第三方的业务系统中时,需要提供标准的协议接口,来方便其它应用程序访问设备和配置本地计算规则等能力。
MQTT的订阅/发布消息模型,允许应用程序灵活的订阅设备数据,当设备有数据上报时,消息会推送至应用程序,简化了应用程序的实现。
2. Topic定义规范
MQTT协议使用3.1版本,MQTT Broker默认随LE一同部署,应用程序通过访问LE的IP地址+8883端口接入到MQTT Broker。 MQTT客户端连接Broker的用户名和密码由用户在云端控制台配置并部署到边缘网关,目前密码配置露出在边缘分组配置页面。
LE的IP地址获取方法:
当应用程序被LE托管,运行在容器模式时,应用可以通过读取环境变量 “FCBASE_IPADDR“获取LE容器当前的IP地址。
当应用程序被LE托管,运行在进程模式时,使用“127.0.0.1”本机地址即可。
当应用程序为第三方系统组件,没有被LE托管,访问运行LE的宿主机IP地址即可。
从访问对象范围的角度主要分为两类,第一类是访问整个边缘(网关)分组,第二类是访问单个设备/网关。
2.1 MQTT主题格式
{srcApp}/{messageType}/{destApp}/{method}每级字段长度上限为128字节。
2.1.1 {srcApp}
{srcApp}表示发布消息的APP身份。如果消息是由linkedge发布,则对应的{srcApp}为linkedge,如果消息是由其它APP发布的,则{srcApp}是该APP的关键字名称,如ibms。主题中包含消息发布者的身份有以下优点:
隔离广播域,避免应答消息被其它模块接收。
溯源,排查问题时根据主题信息可以定位到请求发起者的身份。
身份验证,{srcApp}字段可用于填写系统颁发的AppID,用于权限验证。
2.1.2 {messageType}
{messageType}表示消息的类型,目前仅支持三种:
request: 表明消息为请求消息。
response:表明消息为响应消息。
notify:表明消息为事件通知消息,此类消息用于广播推送,所有订阅该Topic的APP都可以收到推送信息。
2.1.3 {destApp}
{destApp}表示消息目标,用于指定请求的目标APP。如果请求linkedge的服务,则对应的{destApp}为linkedge,如果请求其它APP服务,则为该APP的关键字名称。当{messageType}为notify时,不需要{destApp}字段。
2.1.4 {method}
{method}表示方法名,例如,可用getDeviceList表示获取设备信息列表。
2.2 分组Topic格式
该类Topic用于访问整个边缘(网关)分组的服务,格式如下:
请求Topic:
{srcApp}/request/linkedge/{method}
应答Topic:
linkedge/response/{srcApp}/{method}
事件通知Topic:
linkedge/notify/{event-name}
样例:
ibms应用程序获取分组中所有的设备列表Topic:
请求Topic:ibms/request/linkedge/getDeviceList
应答Topic:linkedge/response/ibms/getDeviceList
子设备状态变更(下线->上线)Topic:
linkedge/notify/deviceStateChanged
2.3 网关Topic
该类Topic访问单台网关的服务,格式如下:
请求Topic:
{srcApp}/request/linkedge/{pk}/{dn}/{method}
应答Topic:
linkedge/response/{srcApp}/{pk}/{dn}/{method}
事件通知Topic:
linkedge/notify/{pk}/{dn}/{event-name}
{pk}和{dn}为目标网关的ProductKey和DeviceName。
以ibms应用程序获取网关的设备列表为例:
ibms应用程序获取网关的设备列表Topic:
请求Topic:ibms/request/linkedge/{pk}/{dn}/getDeviceList
应答Topic:linkedge/response/ibms/{pk}/{dn}/getDeviceList
某网关下子设备状态变更(下线->上线)Topic:
linkedge/notify/{pk}/{dn}/deviceStateChanged
2.3 基于MQTT的方法调用
2.3.1 订阅应答Topic
基于MQTT的方法调用,通常会定义一对“请求”和“应答”Topic。应用程序需要调用服务方法时,需要先订阅应答Topic,再向请求Topic发送请求,才能正常获取服务应答信息。为了便于代码实现,订阅应答Topic时,设备的PK,DN和方法都可以使用通配符,这样只需订阅一次应答Topic,后续请求设备服务无需再动态订阅应答Topic。下面的样例以读取设备属性为例,应答Topic配置为”thing/response/testApp/+/+/+”,只需订阅一次,后续访问任意设备的任何服务,都可以收到应答消息。
2.3.2 Payload通用字段说明
请求Payload中必填的字段为“requestId”,类型为string,用作消息标识,相同APP源发出的请求消息的requestId应该各不相同,可用UUID、随机数或自增长数值等手段。如果请求消息中没有填写”requestId”,该请求将被丢弃。
请求Payload的可选字段的“timeout”,类型为number,单位为秒,用于标识请求的超时时间,当LE处理请求超过该时间仍未完成,LE会回送TIMEOUT错误信息。默认值为4s,最少1s,最大120s。
请求Payload的可选字段的“timestamp”,类型为number,单位为毫秒,用于标识请求的发起时间。
请求Payload的可选字段的“version”,类型为string,用于标识请求的版本号,目前用作保留字段。
/* 1.先订阅应答Topic,用户接收设备应答数据 */ #./mosquitto_sub --psk-identity linkedge --psk 12345678 -p 8883 -t thing/response/testApp/+/+/+ -v & /* 2.发送设备方法调用get请求 */ #./mosquitto_pub --psk-identity linkedge --psk 12345678 -p 8883 -t testApp/request/thing/a1Mtx4p2fHG/LightSensor/get -m "{\"params\":[\"MeasuredIlluminance\"],\"requestId\":\"ff8db62b-4d75-46c8-bf6a-1600d326a88b\"}" /* 3.mosquitto_sub输出设备应答信息 */ thing/response/testApp/a1Mtx4p2fHG/LightSensor/get {"code":0,"message":"success","params":{"MeasuredIlluminance":1000},"requestId":"ff8db62b-4d75-46c8-bf6a-1600d326a88b"}
3. 云端依赖
3.1 配置MQTT用户名和密码
使用MQTT协议访问LE网关,用户首先要在云端边缘分组页面,配置分组访问的用户名和密码。用户程序中的MQTT客户端使用该用户名和密码访问LE。
3.2 选择分组代理网关
应用程序需要访问边缘分组的信息时,需要有一台网关(分组代理网关)负责查询、收集、汇总分组中所有的网关信息,并返回一条应答消息给应用程序。这时涉及如何选择分组中代理网关的问题,有两个策略:
用户在页面选择“代理网关”。
分组中网关根据一定策略协商出一台代理网关,如选择网关中IP地址最小的作为代理网关。
跟智慧园区产品线同学确认,倾向于让用户指定“代理网关”,原因是“现场会在和外部应用一起在服务器上部署一个LE,最好指定这个LE。”
为了更好的用户体验,当分组中只有一台网关时,该网关默认成为分组代理网关,响应所有分组请求消息。
3.1 边缘网关Topic示例:
该类Topic用于访问整个边缘(网关)分组的服务,格式如下:
请求Topic:
{srcApp}/request/linkedge/{method}
应答Topic:
linkedge/response/{srcApp}/{method}
事件通知Topic:
linkedge/notify/{event-name}
ibms应用程序获取分组中所有的设备列表Topic:
请求Topic:ibms/request/linkedge/getDeviceList
应答Topic:linkedge/response/ibms/getDeviceList
子设备状态变更(下线->上线)Topic:linkedge/notify/deviceStateChanged
3.2 分组Topic格式示例:
该类Topic用于访问整个边缘(网关)分组的服务,格式如下:
请求Topic:
{srcApp}/request/linkedge/{method}
应答Topic:
linkedge/response/{srcApp}/{method}
事件通知Topic:
linkedge/notify/{event-name}
ibms应用程序获取分组中所有的设备列表Topic:
请求Topic:ibms/request/linkedge/getDeviceList
应答Topic:linkedge/response/ibms/getDeviceList
子设备状态变更(下线->上线)Topic:linkedge/notify/deviceStateChanged
4. 接口详细说明
4.1 设备读写
设备读写主要包含设备数据的订阅和设备方法的调用两部分。
4.1.1 设备数据订阅
通过订阅设备数据上报的Topic,应用程序可以监听设备上报的属性值和事件信息。
设备属性上报Topic:
thing/notify/${pk}/${dn}/property
设备事件上报Topic:
thing/notify/${pk}/${dn}/${tsl.event.identifer}
数据发布Payload透传驱动上报数据:
# 示例1-设备属性上报:
Topic:thing/notify/${pk}/${dn}/property
Payload:
{
"key1":{
"value":"value1",
"time":152444872****
},
"key2":{
"value":"value2",
"time":152444872****
}
}
# 示例2-设备事件上报:
Topic:thing/notify/${pk}/${dn}/${tsl.event.identifer}
Payload:
{
"params": {
"value" : {
"key1":"value1",
"key2":"value2"
},
"time" : 152444872****
}
}
4.1.2 设备方法调用
设置设备属性,调用设备set方法Topic:
{srcApp}/request/thing/${pk}/${dn}/set
获取设备属性值,调用设备get方法Topic:
{srcApp}/request/thing/${pk}/${dn}/get
调用设备自定义方法Topic:
{srcApp}/request/thing/${pk}/${dn}/${tsl.service.identifer}
设备配置Payload在驱动请求参数基础上增加了requestId字段,用于标识每次配置请求:
#示例-设置设备属性
Topic:testApp/request/thing/${productKey}/${deviceName}/set
Payload:
{
"requestId":"0bc458b5-47f6-472f-bd88-3624696e9776", #[Required]
"timeout":5,
"params":{ #设备方法调用的参数[Required]
"key1":"value1",
"key2":"value2"
}
}
#示例-获取设备属性
Topic:testApp/request/thing/${productKey}/${deviceName}/get
Payload:
{
"requestId":"ff8db62b-4d75-46c8-bf6a-1600d326a88b", #[Required]
"params":[ #设备方法调用的参数[Required]
"key"
]
}
设置设备属性应答Topic:
thing/response/{srcApp}/${pk}/${dn}/set
获取设备属性应答Topic:
thing/response/{srcApp}/${pk}/${dn}/get
调用设备自定义方法应答Topic:
thing/response/{srcApp}/${pk}/${dn}/${tsl.service.identifer}
配置应答Payload在驱动应答消息基础上增加了requestId字段,用于匹配对应的配置请求:
#示例-设置设备属性应答数据
Topic:thing/response/{srcApp}/${pk}/${dn}/set
Payload:
{
"requestId":"0bc458b5-47f6-472f-bd88-3624696e9776",
"code":0,
"message":"",
"params":{}
}
#示例-获取设备属性应答数据
Topic:thing/response/{srcApp}/${pk}/${dn}/get
Payload:
{
"requestId":"ff8db62b-4d75-46c8-bf6a-1600d326a88b",
"code":0,
"message":"success",
"params":{
"key":"value"
}
}
4.2 设备状态查询
4.2.1 获取设备列表
获取分组设备列表Topic:
{srcApp}/request/linkedge/getDeviceList
获取网关设备列表Topic:
{srcApp}/request/linkedge/{pk}/{dn}/getDeviceList
请求Payload:
{
"requestId": "0bc458b5-47f6-472f-bd88-3624696e9777", # [Required]
"timestamp": 157121985****, #ms [Optional]
"timeout":3, # 最少1s,最多120s [Optional: default 4s]
"version": "1.0" # [Optional]
}
获取分组设备列表应答Topic:
linkedge/response/{srcApp}/getDeviceList
应答Payload
{ "params":[ #数组,包含所有网关下的子设备 { "gwProductKey":"a1PQ9828qvr", #网关的productkey "gwDeviceName":"yinlong_gw_dev1",#网关的devicename "code":0, "message":"success", "deviceList":[ #设备列表 { "productKey":"a1KRepmC2XJ", #设备的productkey "deviceName":"modbus_tcp_dev_1", #设备的devicename "localOnline":"false", #设备与网关的连接状态 "cloudOnline":"false", #设备与云端的连接状态 "activationState":"notActivated",#设备在云端是否被激活 "nickName":"xxx", #设备别名 "tags":[ #设备包含的标签 ] }, { "productKey":"a1ZJTVsqj2y", "deviceName":"lightDevNoSpecial", "localOnline":"true", "cloudOnline":"true", "activationState":"activated", "nickName":"xxx", #设备别名 "tags":[ ] }, { "productKey":"a1ZJTVsqj2y", "deviceName":"LightDev2", "localOnline":"false", "cloudOnline":"false", "activationState":"notActivated", "nickName":"xxx", #设备别名 "tags":[ #设备包含的标签 { "key":"type", #设备标签的key "value":"light" #设备标签的value }, { "key":"owner", "value":"yinlong" }, { "key":"location", "value":"master bedroom" }, { "key":"color", "value":"red" } ] } ] } ], "requestId":"0bc458b5-47f6-472f-bd88-3624696e9777", "version":"1.0", "timestamp":157225013****, "code":0, "message":"success" }
获取网关设备列表应答Topic:
linkedge/response/``{srcApp}``/{pk}/{dn}/getDeviceList
应答Payload:
{ "requestId":"0bc458b5-47f6-472f-bd88-3624696e9777", "timestamp": 157121985****, "version":"1.0", "code":0, "message":"success", "params":[ #设备列表 { "productKey":"a1Mtx4p2fHG", #设备的productkey "deviceName":"device1", #设备的devicename "localOnline":"true", #设备和网关的连接状态 "cloudOnline":"true", #设备和云端的连接状态 "activationState": "activated/notActivated/activationFailed", #设备在云端的激活状态 "tag":[ { "key":"coordinate", "value":"0:0" } ] } ] }
4.2.2 获取设备TSL配置信息
获取设备TSL请求Topic:
{srcApp}/request/thing/{pk}/{dn}/getTsl
如果topic中的pk、dn为网关的,参数中指定设备pk,需要遍历所有网关,查询返回可能会有多个网关下pk的tsl,可能存在不一致的情况,如何选择是个问题。
如果Topic中仅指定设备pk可能有多个网关回复, Topic中pk、dn为设备的,这样可以保证仅有一个网关回复,而且就是你想操作的设备的tsl,更加合理。
请求Payload:
{
"requestId": "0bc458b5-47f6-472f-bd88-3624696e9778",
"version": "1.0",
"timeout":3 # 最少1s,最多120s
}
获取设备TSL应答Topic:
thing/response/{srcApp}/{pk}/{dn}/getTsl
应答Payload:
{
"params":{
"productKey":"a1KRepmC2XJ",
"deviceName":"modbus_tcp_dev_1",
"code":0,
"message":"success",
"tsl":"{"events":[{"desc":"属性上报","identifier":"post","method":"thing.event.property.post","name":"post","outputData":[{"dataType":{"specs":{"max":"2147483647","min":"-2147483648","unit":"Mpa"},"type":"double"},"identifier":"pressure1","name":"pressure1"}],"required":true,"type":"info"}],"profile":{"productKey":"a1KRepmC2XJ"},"properties":[{"accessMode":"rw","dataType":{"specs":{"max":"2147483647","min":"-2147483648","unit":"Mpa"},"type":"double"},"identifier":"pressure1","name":"pressure1","required":true}],"schema":"https://iotx-tsl.oss-ap-southeast-1.aliyuncs.com/schema.json","services":[{"callType":"async","desc":"属性设置","identifier":"set","inputData":[{"dataType":{"specs":{"max":"2147483647","min":"-2147483648","unit":"Mpa"},"type":"double"},"identifier":"pressure1","name":"pressure1"}],"method":"thing.service.property.set","name":"set","outputData":[],"required":true},{"callType":"async","desc":"属性获取","identifier":"get","inputData":["pressure1"],"method":"thing.service.property.get","name":"get","outputData":[{"dataType":{"specs":{"max":"2147483647","min":"-2147483648","unit":"Mpa"},"type":"double"},"identifier":"pressure1","name":"pressure1"}],"required":true}]}", #物模型
"tslConfig":"{"profile":{"productKey":"a1KRepmC2XJ"},"properties":[{"identifier":"pressure1","operateType":"holdingRegister","originalDataType":{"specs":{"registerCount":1,"reverseRegister":0,"swap16":0},"type":"int16"},"pollingTime":1000,"registerAddress":"0x01","scaling":1,"trigger":1,"writeFunctionCode":16}]}" #扩展物模型
},
"requestId":"0bc458b5-47f6-472f-bd88-3624696e9777",
"version":"1.0",
"timestamp":157224857****,
"code":0,
"message":"success"
}
4.3 IFTTT规则配置
4.3.1 获取IFTTT规则列表
获取分组IFTTT规则列表Topic:
{srcApp}/request/linkedge/getSceneList
获取网关IFTTT规则列表Topic:
{srcApp}/request/linkedge/{pk}/{dn}/getSceneList
请求Payload:
{
"requestId": "0bc458b5-47f6-472f-bd88-3624696e9778",
"timestamp": 157121985****, #ms [Optional]
"timeout":3, # 最少1s,最多120s [Optional: default 4s]
"version": "1.0" # [Optional]
}
获取分组IFTTT规则应答Topic:
linkedge/response/{srcApp}/getSceneList
应答Payload:
{
"params":[ #规则列表
{
"gwProductKey":"a1PQ9828qvr", #网关productkey
"gwDeviceName":"alpine_test_gateway",#网关的devicenmae
"code":0,
"message":"success",
"data":[ #包含网关中所有规则的描述
]
},
{
"gwProductKey":"a1PQ9828qvr",
"gwDeviceName":"yinlong_gw_dev1",
"code":0,
"message":"success",
"data":[
{
"times":5,
"failureTimes":5,
"lastState":{
"state":"failure",
"cause":"walk action set: The name iot.device.ida1ZJTVsqj2y_alpine_light_dev1 was not provided by any .service files",
"time":"2019-10-28T19:35:00+08:00",
"duration":1
},
"id":"a08d6c08bc1a440693ba9c9c8166a968",
"name":"ifttt",
"running":true,
"time":"2019-10-28T19:30:47+08:00",
"uptime":259072,
"actions":{
"times":5,
"failureTimes":5,
"lastState":{
"state":"failure",
"cause":"The name iot.device.ida1ZJTVsqj2y_alpine_light_dev1 was not provided by any .service files",
"time":"2019-10-28T19:35:00+08:00",
"duration":1
}
},
"conditions":{
"times":5,
"failureTimes":0,
"lastState":{
"state":"success",
"cause":"",
"time":"2019-10-28T19:35:00+08:00",
"duration":0
}
}
}
]
}
],
"requestId":"0bc458b5-47f6-472f-bd88-3624696e9777",
"version":"1.0",
"timestamp":157226250****,
"code":0,
"message":"success"
}
获取网关IFTTT规则应答Topic:
linkedge/response/{srcApp}/{pk}/{dn}/getSceneList
应答Payload:
{
"params":[ #网关下的规则列表
{
"times":0,
"failureTimes":0,
"lastState":null,
"id":"a08d6c08bc1a440693ba9c9c8166a968",
"name":"ifttt",
"running":true,
"time":"2019-10-28T17:35:35+08:00",
"uptime":5967,
"actions":{
"times":0,
"failureTimes":0,
"lastState":null
},
"conditions":{
"times":0,
"failureTimes":0,
"lastState":null
}
}
],
"requestId":"0bc458b5-47f6-472f-bd88-3624696e9777",
"version":"1.0",
"timestamp":157225534****,
"code":0,
"message":"success"
}
4.3.2 控制IFTTT规则启停
同一个IFTTT规则,部署到不同的网关,ID是相同的。因此IFTTT规则启停,仅支持面向网关的定向操作,不支持分组维度。
使能网关IFTTT规则Topic:
{srcApp}/request/linkedge/{pk}/{dn}/enableScene
关闭网关IFTTT规则Topic:
{srcApp}/request/linkedge/{pk}/{dn}/disableScene
请求Payload:其中params数组中至少包含一个,至多包含32个对象。
{
"requestId": "0bc458b5-47f6-472f-bd88-3624696e9778",
"version": "1.0",
"params": [ #场景规则id数组[Required]
{
"id": "id1"
}
]
}
使能网关IFTTT规则配置应答Topic:
linkedge/response/{srcApp}/{pk}/{dn}/enableScene
关闭网关IFTTT规则配置应答Topic:
linkedge/response/{srcApp}/{pk}/{dn}/disableScene
应答Payload:
{
"params":[
{
"id":"123000000",
"code":1,
"message":"no such scene"
},
{
"id":"a08d6c08bc1a440693ba9c9c8166a968",
"code":0,
"message":"success"
}
],
"requestId":"0bc458b5-47f6-472f-bd88-3624696e9777",
"version":"1.0",
"timestamp":157227690****,
"code":0,
"message":"success"
}
4.4 设备列表和状态变更
4.4.1 设备列表变更
当网关互联中某一网关所拥有的设备列表出现变化时,互联网络将广播一条消息通知给订阅者。
变更Topic:
linkedge/notify/deviceListChanged
内容
{
"timestamp":157225090****,
"version":"1.0",
"params":[
{
"gwProductKey":"a1XqBnyTZLD",
"gwDeviceName":"ModbusTestGW"
}
]
}
4.4.2 设备在线状态变更
当网关互联中某子设备的在线状态出现变化时(包括连接到本地和连接到云端),网关互联网络将广播一条消息给订阅者。
通知Topic:
linkedge/notify/deviceStateChanged
内容
内容格式大体与4.2.1获取设备列表相同。
{
"timestamp": 1572250903307,
"version": "1.0",
"params": [{
"gwProductKey": "a1XqBnyTZLD", #网关的productkey
"gwDeviceName": "ModbusTestGW", #网关的devicename
"deviceList": [{ #网关下的设备列表
"productKey": "a1OSqKKiZLL", #设备的productkey
"deviceName": "DN035", #设备的devicename
"localOnline": "true/false", #设备的本地在线状态
"cloudOnline": "true/false", #设备的云端在线状态
"activationState": "activated/notActivated/activationFailed",#设备在云端的激活状态
}]
}]
}
4.5 网关信息查询
4.5.1 获取网关列表
获取分组网关列表Topic:
{srcApp}/request/linkedge/getGatewayList
请求Payload
{
"requestId": "0bc458b5-47f6-472f-bd88-3624696e9777", # [Required]
"timestamp": 157121985****, #ms [Optional]
"timeout":3, # 最少1s,最多120s [Optional: default 4s]
"version": "1.0" # [Optional]
}
获取分组网关列表应答Topic:
linkedge/response/{srcApp}/getGatewayList
响应Payload
{
"params":[
{
"gwProductKey":"a1phR16zqNZ",
"gwDeviceName":"gateway_01",
"code":0, #此网关接口的服务调用的返回码
"message":"success",
"gatewayInfo":{ #网关信息
"productKey":"a1phR16zqNZ", #网关的productkey
"deviceName":"gateway_01", #网关的devicename
"nickName":"", #网关的别名
"tags":[ #网关的标签
]
}
},
{
"gwProductKey":"a1phR16zqNZ",
"gwDeviceName":"gateway_02",
"code":101572,
"message":"getGateway timeout"
},
{
"gwProductKey":"a1phR16zqNZ",
"gwDeviceName":"gateway_03",
"code":101572,
"message":"ERROR_GWC_REQUEST_TIMEOUT"
}
],
"requestId":"0bc458b5-47f6-472f-bd88-3624696e9777",
"version":"1.0",
"timestamp":158202075****,
"code":10****, #分组接口的调用返回码
"message":"ERROR_GWC_REQUEST_TIMEOUT"
}
5.错误码
应答Payload中的”code”字段代表错误码,成功时返回0,异常时返回下述错误码,错误信息保存到”message”字段:
0: 成功
101571: 参数校验不合法
101572: 请求处理超时
101573: LinkIoTEdge处理失败
101574:设备驱动处理失败
101575: MQTT消息代理处理失败
101576: 设备不存在
101578: 请求的参数个数超出上限
101579: 访问资源不存在
101580: 请求的参数为空
6.自测用例
该部分测试用例中的测试数据,对于MQTT客户端开发具有很好的借鉴价值,结合具体例子的请求和应答便于开发者加深对协议规范的理解。
6.1 部署配置样例
本地部署方法:./casctl deploy gwc_deploy.conf
gwc_deploy.conf配置文件样例:
{
"version":"1.0",
"instanceId":"iid222",
"instanceGroupId":"linkedge",
"instanceGroupPsk":"123456abcdef12345678123456ABCDEF",
"userTlsConfig":[
{
"userId":"customer1",
"psk":"123456"
},
{
"userId":"customer2",
"psk":"12345678"
}
],
"nodesConfig":[
{
"ipAddress":"172.17.0.2",
"productKey":"a1PQ9828qvr",
"deviceName":"yinlong_gw_dev1",
"isGroupAgent":"1" #Mark this gw as groupAgent
},
{
"ipAddress":"172.17.0.3",
"productKey":"a1PQ9828qvr",
"deviceName":"alpine_test_gateway"
}
]
}
6.2 自测用例
订阅所有设备属性、事件上报
/* 订阅设备属性上报Topic,接收设备属性上报数据 */
#./mosquitto_sub --psk-identity linkedge --psk 123456aBcdef12345678123456ABCDEf -p 8883 -t thing/notify/+/+/property -v &
thing/notify/a1Mtx4p2fHG/LightSensor/property {"MeasuredIlluminance":{"value":550,"time":156662262****}}
thing/notify/a1Mtx4p2fHG/LightSensor/property {"MeasuredIlluminance":{"value":600,"time":156662265****}}
thing/notify/a1Mtx4p2fHG/LightSensor/property {"MeasuredIlluminance":{"value":650,"time":156662268****}}
访问外部/本地网关设备方法
/* 1.先订阅应答Topic,用户接收设备应答数据 */
#./mosquitto_sub --psk-identity linkedge --psk 12345678 -p 8883 -t thing/response/testApp/+/+/+ -v &
/* 2.发送设备方法调用get请求 */
#./mosquitto_pub --psk-identity linkedge --psk 12345678 -p 8883 -t testApp/request/thing/a1Mtx4p2fHG/LightSensor/get -m "{\"params\":[\"MeasuredIlluminance\"],\"requestId\":\"ff8db62b-4d75-46c8-bf6a-1600d326a88b\"}"
/* 3.mosquitto_sub输出设备应答信息 */
thing/response/testApp/a1Mtx4p2fHG/LightSensor/get {"code":0,"message":"success","params":{"MeasuredIlluminance":1000},"requestId":"ff8db62b-4d75-46c8-bf6a-1600d326a88b"}
消息路由
配置全部设备数据到FC,配置某个ProductKey下所有设备数据到FC。
获取网关设备列表
./mosquitto_sub --psk-identity linkedge --psk 123456aBcdef12345678123456ABCDEf -p 8883 -t linkedge/response/testApp/a1PQ9828qvr/yinlong_gw_dev1/getDeviceList -v &
./mosquitto_pub --psk-identity linkedge --psk 123456aBcdef12345678123456ABCDEf -p 8883 -t testApp/request/linkedge/a1PQ9828qvr/yinlong_gw_dev1/getDeviceList -m "{\"requestId\": \"0bc458b5-47f6-472f-bd88-3624696e9777\", \"version\":\"1.0\"}"
linkedge/response/testApp/a1PQ9828qvr/yinlong_gw_dev1/getDeviceList {"data":[{"productKey":"a1ZJTVsqj2y","deviceName":"LightDev","localOnline":"true","cloudOnline":"true","activationState":"activated","tags":[{"key":"type","value":"light"},{"key":"owner","value":"yinlong"},{"key":"location","value":"livingroom"},{"key":"color","value":"white"}]},{"productKey":"a1arJcX0Koy","deviceName":"Sensor_device1","localOnline":"true","cloudOnline":"true","activationState":"activated","tags":[{"key":"location","value":"master bedroom"}]},{"productKey":"a1KRepmC2XJ","deviceName":"modbus_tcp_dev_1","localOnline":"false","cloudOnline":"false","activationState":"notActivated","tags":[]},{"productKey":"a1Mtx4p2fHG","deviceName":"LightSensor","localOnline":"true","cloudOnline":"true","activationState":"activated","tags":[]},{"productKey":"a1ZJTVsqj2y","deviceName":"LightDev2","localOnline":"false","cloudOnline":"false","activationState":"notActivated","tags":[{"key":"type","value":"light"},{"key":"owner","value":"yinlong"},{"key":"location","value":"master bedroom"},{"key":"color","value":"red"}]},{"productKey":"a1PQ9828qvr","deviceName":"yinlong_gw_dev1","localOnline":"false","cloudOnline":"false","activationState":"notActivated","tags":[]},{"productKey":"a1ZJTVsqj2y","deviceName":"lightDevNoSpecial","localOnline":"true","cloudOnline":"true","activationState":"activated","tags":[]}],"requestId":"0bc458b5-47f6-472f-bd88-3624696e9777"}
getTsl 测试用例
./mosquitto_sub --psk-identity linkedge --psk 123456aBcdef12345678123456ABCDEf -p 8883 -t thing/response/testApp/+/+/getTsl -v &
./mosquitto_pub --psk-identity linkedge --psk 123456aBcdef12345678123456ABCDEf -p 8883 -t testApp/request/thing/a1arJcX0Koy/alpine_light_sensor/getTsl -m "{\"requestId\": \"0bc458b5-47f6-472f-bd88-3624696e9777\",\"timeout\":5}"
thing/response/testApp/a1arJcX0Koy/alpine_light_sensor/getTsl {"params":{"productKey":"a1arJcX0Koy","deviceName":"alpine_light_sensor","code":0,"message":"success","tsl":"{\"events\":[{\"desc\":\"属性上报\",\"identifier\":\"post\",\"method\":\"thing.event.property.post\",\"name\":\"post\",\"outputData\":[{\"dataType\":{\"specs\":{\"max\":\"65535\",\"min\":\"0\",\"step\":\"0.01\",\"unit\":\"Lux\",\"unitName\":\"照度\"},\"type\":\"double\"},\"identifier\":\"MeasuredIlluminance\",\"name\":\"光照度检测值\"}],\"required\":true,\"type\":\"info\"}],\"profile\":{\"productKey\":\"a1arJcX0Koy\"},\"properties\":[{\"accessMode\":\"r\",\"dataType\":{\"specs\":{\"max\":\"65535\",\"min\":\"0\",\"step\":\"0.01\",\"unit\":\"Lux\",\"unitName\":\"照度\"},\"type\":\"double\"},\"identifier\":\"MeasuredIlluminance\",\"name\":\"光照度检测值\",\"required\":true}],\"schema\":\"https://iotx-tsl.oss-ap-southeast-1.aliyuncs.com/schema.json\",\"services\":[{\"callType\":\"async\",\"desc\":\"属性设置\",\"identifier\":\"set\",\"inputData\":[],\"method\":\"thing.service.property.set\",\"name\":\"set\",\"outputData\":[],\"required\":true},{\"callType\":\"async\",\"desc\":\"属性获取\",\"identifier\":\"get\",\"inputData\":[\"MeasuredIlluminance\"],\"method\":\"thing.service.property.get\",\"name\":\"get\",\"outputData\":[{\"dataType\":{\"specs\":{\"max\":\"65535\",\"min\":\"0\",\"step\":\"0.01\",\"unit\":\"Lux\",\"unitName\":\"照度\"},\"type\":\"double\"},\"identifier\":\"MeasuredIlluminance\",\"name\":\"光照度检测值\"}],\"required\":true}]}","productKey":"a1arJcX0Koy","deviceName":"alpine_light_sensor","code":0,"message":"success","tslConfig":"{\"profile\":{\"productKey\":\"a1arJcX0Koy\"}}"},"requestId":"0bc458b5-47f6-472f-bd88-3624696e9777","version":"1.0","timestamp":1572249171823,"code":0,"message":"success"}
获取分组设备列表
前置条件:修改gwc_deploy.conf,选择一台网关为groupAgent:设置代理网关标志 “isGroupAgent”:”1”
./casctl dep gwc_deploy.conf
测试命令
./mosquitto_sub --psk-identity linkedge --psk 123456aBcdef12345678123456ABCDEf -p 8883 -t linkedge/response/testApp/getDeviceList -v &
./mosquitto_pub --psk-identity linkedge --psk 123456aBcdef12345678123456ABCDEf -p 8883 -t testApp/request/linkedge/getDeviceList -m "{\"requestId\": \"0bc458b5-47f6-472f-bd88-3624696e9777\"}"
linkedge/response/testApp/getDeviceList {"params":[{"gwProductKey":"a1PQ9828qvr","gwDeviceName":"yinlong_gw_dev1","code":0,"message":"success","deviceList":[{"productKey":"a1ZJTVsqj2y","deviceName":"LightDev","localOnline":"true","cloudOnline":"true","activationState":"activated","tags":[{"key":"type","value":"light"},{"key":"owner","value":"yinlong"},{"key":"location","value":"livingroom"},{"key":"color","value":"white"}]},{"productKey":"a1arJcX0Koy","deviceName":"Sensor_device1","localOnline":"true","cloudOnline":"true","activationState":"activated","tags":[{"key":"location","value":"master bedroom"}]},{"productKey":"a1ZJTVsqj2y","deviceName":"LightDev2","localOnline":"false","cloudOnline":"false","activationState":"notActivated","tags":[{"key":"type","value":"light"},{"key":"owner","value":"yinlong"},{"key":"location","value":"master bedroom"},{"key":"color","value":"red"}]},{"productKey":"a1Mtx4p2fHG","deviceName":"LightSensor","localOnline":"true","cloudOnline":"true","activationState":"activated","tags":[]},{"productKey":"a1KRepmC2XJ","deviceName":"modbus_tcp_dev_1","localOnline":"false","cloudOnline":"false","activationState":"notActivated","tags":[]},{"productKey":"a1ZJTVsqj2y","deviceName":"lightDevNoSpecial","localOnline":"true","cloudOnline":"true","activationState":"activated","tags":[]}]},{"gwProductKey":"a1PQ9828qvr","gwDeviceName":"alpine_test_gateway","code":0,"message":"success","deviceList":[{"productKey":"a1fsUodstaA","deviceName":"oil_temperature_dev1","localOnline":"true","cloudOnline":"true","activationState":"activated","tags":[]},{"productKey":"a1arJcX0Koy","deviceName":"alpine_light_sensor","localOnline":"true","cloudOnline":"true","activationState":"activated","tags":[]}]}],"requestId":"0bc458b5-47f6-472f-bd88-3624696e9777","version":"1.0","timestamp":157218682****,"code":0,"message":"success"}
超时情况:linkedge/response/testApp/getDeviceList {"params":[{"gwProductKey":"a1PQ9828qvr","gwDeviceName":"yinlong_gw_dev1","code":101572,"message":"ERROR_GWC_REQUEST_TIMEOUT"},{"gwProductKey":"a1PQ9828qvr","gwDeviceName":"alpine_test_gateway","code":101572,"message":"ERROR_GWC_REQUEST_TIMEOUT"}],"requestId":"0bc458b5-47f6-472f-bd88-3624696e9777","version":"1.0","timestamp":157218540****,"code":101572,"message":"ERROR_GWC_REQUEST_TIMEOUT"}
getSceneList
获取单个网关的规则列表
./mosquitto_sub --psk-identity linkedge --psk 123456aBcdef12345678123456ABCDEf -p 8883 -t linkedge/response/testApp/a1PQ9828qvr/yinlong_gw_dev1/getSceneList -v &
./mosquitto_pub --psk-identity linkedge --psk 123456aBcdef12345678123456ABCDEf -p 8883 -t testApp/request/linkedge/a1PQ9828qvr/yinlong_gw_dev1/getSceneList -m "{\"requestId\": \"0bc458b5-47f6-472f-bd88-3624696e9777\"}"
linkedge/response/testApp/a1PQ9828qvr/yinlong_gw_dev1/getSceneList {"params":{"code":0,"message":"success","data":[{"times":0,"failureTimes":0,"lastState":null,"id":"a08d6c08bc1a440693ba9c9c8166a968","name":"ifttt","running":false,"time":"","uptime":0,"actions":{"times":0,"failureTimes":0,"lastState":null},"conditions":{"times":0,"failureTimes":0,"lastState":null}}]},"requestId":"0bc458b5-47f6-472f-bd88-3624696e9777","version":"1.0","timestamp":157222996****,"code":0,"message":"success"}
dbus-send --bus=unix:path=/tmp/var/run/mbusd/mbusd_socket --dest=iot.gateway.scene --print-reply /iot/gateway/scene iot.gateway.scene.listSceneStats
获取分组的规则列表
./mosquitto_sub --psk-identity linkedge --psk 123456aBcdef12345678123456ABCDEf -p 8883 -t linkedge/response/testApp/getSceneList -v &
./mosquitto_pub --psk-identity linkedge --psk 123456aBcdef12345678123456ABCDEf -p 8883 -t testApp/request/linkedge/getSceneList -m "{\"requestId\": \"0bc458b5-47f6-472f-bd88-3624696e9777\"}"
linkedge/response/testApp/getSceneList {"params":[{"gwProductKey":"a1PQ9828qvr","gwDeviceName":"alpine_test_gateway","code":0,"message":"success","data":[]},{"gwProductKey":"a1PQ9828qvr","gwDeviceName":"yinlong_gw_dev1","code":0,"message":"success","data":[{"times":5,"failureTimes":5,"lastState":{"state":"failure","cause":"walk action set: The name iot.device.ida1ZJTVsqj2y_alpine_light_dev1 was not provided by any .service files","time":"2019-10-28T19:35:00+08:00","duration":1},"id":"a08d6c08bc1a440693ba9c9c8166a968","name":"ifttt","running":true,"time":"2019-10-28T19:30:47+08:00","uptime":273231,"actions":{"times":5,"failureTimes":5,"lastState":{"state":"failure","cause":"The name iot.device.ida1ZJTVsqj2y_alpine_light_dev1 was not provided by any .service files","time":"2019-10-28T19:35:00+08:00","duration":1}},"conditions":{"times":5,"failureTimes":0,"lastState":{"state":"success","cause":"","time":"2019-10-28T19:35:00+08:00","duration":0}}}]}],"requestId":"0bc458b5-47f6-472f-bd88-3624696e9777","version":"1.0","timestamp":157226252****,"code":0,"message":"success"}
enableScene
./mosquitto_sub --psk-identity linkedge --psk 123456aBcdef12345678123456ABCDEf -p 8883 -t linkedge/response/testApp/+/+/enableScene -v &
./mosquitto_pub --psk-identity linkedge --psk 123456aBcdef12345678123456ABCDEf -p 8883 -t testApp/request/linkedge/a1PQ9828qvr/yinlong_gw_dev1/enableScene -m "{\"requestId\": \"0bc458b5-47f6-472f-bd88-3624696e9777\",\"params\":[{\"id\":\"a08d6c08bc1a440693ba9c9c8166a968\"},{\"id\":\"123000000\"}]}"
linkedge/response/testApp/a1PQ9828qvr/yinlong_gw_dev1/enableScene {"params":[{"id":"123000000","code":1,"message":"no such scene"},{"id":"a08d6c08bc1a440693ba9c9c8166a968","code":0,"message":"success"}],"requestId":"0bc458b5-47f6-472f-bd88-3624696e9777","version":"1.0","timestamp":157227690****,"code":0,"message":"success"}
disableScene
./mosquitto_sub --psk-identity linkedge --psk 123456aBcdef12345678123456ABCDEf -p 8883 -t linkedge/response/testApp/+/+/disableScene -v &
./mosquitto_pub --psk-identity linkedge --psk 123456aBcdef12345678123456ABCDEf -p 8883 -t testApp/request/linkedge/a1PQ9828qvr/yinlong_gw_dev1/disableScene -m "{\"requestId\": \"0bc458b5-47f6-472f-bd88-3624696e9777\",\"params\":[{\"id\":\"a08d6c08bc1a440693ba9c9c8166a968\"}]}"
linkedge/response/testApp/a1PQ9828qvr/yinlong_gw_dev1/disableScene {"params":[{"id":"a08d6c08bc1a440693ba9c9c8166a968","code":0,"message":"success"}],"requestId":"0bc458b5-47f6-472f-bd88-3624696e9777","version":"1.0","timestamp":157227715****,"code":0,"message":"success"}
7. 设备端开发
7.1 C版本SDK
本章为您介绍C版本的SDK使用方法及相关API。Link IoT Edge提供C版本的SDK,名称为linkedge-thing-access-sdk-c。C版本开源的SDK源码请参见开源C库。
get_properties_callback
/*
* 获取属性(对应设备产品物模型属性定义)的回调函数,需驱动开发者实现获取属性业务逻辑。
*
* Link IoT Edge需要获取某个设备的属性时,SDK会调用该接口间接获取到数据并封装成固定格式后回传给Link IoT Edge。
* 开发者需要根据设备id和属性名找到设备,将获取到的属性值按照@device_data_t格式填充。
*
* @dev_handle: Link IoT Edge需要获取属性的具体某个设备。
* @properties: 属性值键值结构,驱动开发者需要将根据属性名称获取到的属性值更新到properties中。
* @properties_count: 属性个数。
* @usr_data: 注册设备时,用户传递的私有数据。
* 所有属性均获取成功则返回LE_SUCCESS,其他则返回错误码(参考le_error.h错误码宏定义)。
* */
typedef int (*get_properties_callback)(device_handle_t dev_handle,
leda_device_data_t properties[],
int properties_count,
void *usr_data);
set_properties_callback
/*
* 设置属性(对应设备产品物模型属性定义)的回调函数,需驱动开发者实现设置属性业务逻辑。
*
* Link IoT Edge需要设置某个设备的属性时,SDK会调用该接口将具体的属性值传递给应用程序,开发者需要在本回调
* 函数里将属性设置到设备。
*
* @dev_handle: Link IoT Edge需要设置属性的具体某个设备。
* @properties: Link IoT Edge需要设置的设备的属性名称和值。
* @properties_count: 属性个数。
* @usr_data: 注册设备时,用户传递的私有数据。
*
* 若获取成功则返回LE_SUCCESS,失败则返回错误码(参考le_error.h错误码宏定义)。
* */
typedef int (*set_properties_callback)(device_handle_t dev_handle,
const leda_device_data_t properties[],
int properties_count,
void *usr_data);
call_service_callback
/*
* 服务(对应设备产品物模型服务定义)调用的回调函数,需要驱动开发者实现服务对应业务逻辑。
*
* Link IoT Edge需要调用某个设备的服务时,SDK会调用该接口将具体的服务参数传递给应用程序,开发者需要在本回调
* 函数里调用具体的服务,并将服务返回值按照@device_data_t格式填充到output_data。
*
* @dev_handle: Link IoT Edge需要调用服务的具体某个设备。
* @service_name: Link IoT Edge需要调用的设备的具体某个服务名,名称与设备产品物模型一致。
* @data: Link IoT Edge需要调用的设备的具体某个服务参数,参数与设备产品物模型保持一致。
* @data_count: Link IoT Edge需要调用的设备的具体某个服务参数个数。
* @output_data: 开发者需要将服务调用的返回值,按照设备产品物模型规定的服务格式返回到output中。
* @usr_data: 注册设备时,用户传递的私有数据。
*
* 若获取成功则返回LE_SUCCESS,失败则返回错误码(参考le_error.h错误码宏定义)。
* */
typedef int (*call_service_callback)(device_handle_t dev_handle,
const char *service_name,
const leda_device_data_t data[],
int data_count,
leda_device_data_t output_data[],
void *usr_data);
leda_report_properties
/*
* 上报属性,在设备所属产品物模型中规定了设备的属性上报能力。
*
* 上报属性,可以上报一个,也可以多个一起上报。
*
* dev_handle: 设备在Link IoT Edge本地唯一标识。
* properties: @leda_device_data_t,属性数组。
* properties_count: 本次上报属性个数。
*
* 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。
*
*/
int leda_report_properties(device_handle_t dev_handle, const leda_device_data_t properties[], int properties_count);
leda_report_event
/*
* 上报事件,设备具有的事件上报能力在设备产品物模型有规定。
*
*
* dev_handle: 设备在Link IoT Edge本地唯一标识。
* event_name: 事件名称。
* data: @leda_device_data_t,事件参数数组。
* data_count: 事件参数数组长度。
*
* 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。
*
*/
int leda_report_event(device_handle_t dev_handle, const char *event_name, const leda_device_data_t data[], int data_count);
leda_offline
/*
* 下线设备,假如设备工作在不正常的状态或设备退出前,可以先下线设备,这样Link IoT Edge就不会继续下发消息到设备侧。
*
* dev_handle: 设备在Link IoT Edge本地唯一标识。
*
* 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。
*
*/
int leda_offline(device_handle_t dev_handle);
leda_online
/*
* 上线设备,设备只有上线后,才能被Link IoT Edge识别。
*
* dev_handle: 设备在Link IoT Edge本地唯一标识。
*
* 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。
*/
int leda_online(device_handle_t dev_handle);
leda_register_and_online_by_device_name
/*
* 通过已在阿里云物联网平台创建的设备device_name,注册并上线设备,申请设备唯一标识符。
*
* 若需要注册多个设备,则多次调用该接口即可。
*
* product_key: 在阿里云物联网平台创建的产品ProductKey。
* device_name: 在阿里云物联网平台创建的设备名称DeviceName。
* device_cb: 请求调用设备回调函数结构体,详细描述见@leda_device_callback。
* usr_data: 设备注册时传入私有数据,在回调中会传给设备。
*
* 阻塞接口,返回值设备在Link IoT Edge本地唯一标识,>= 0表示有效,< 0 表示无效。
*
*/
device_handle_t leda_register_and_online_by_device_name(const char *product_key, const char *device_name, leda_device_callback_t *device_cb, void *usr_data);
leda_register_and_online_by_local_name
/*
* 通过本地自定义设备名称,注册并上线设备,申请设备唯一标识符。
*
* 若需要注册多个设备,则多次调用该接口即可。
*
* product_key: 在阿里云物联网平台创建的产品ProductKey。
* local_name: 由设备特征值组成的唯一描述信息,必须保证同一个product_key时,每个设备名称不同。
* device_cb: 请求调用设备回调函数结构体,详细描述见@leda_device_callback。
* usr_data: 设备注册时传入私有数据,在回调中会传给设备。
*
* 阻塞接口,返回值设备在Link IoT Edge本地唯一标识,>= 0表示有效,< 0 表示无效。
*
* 注:在同一产品ProductKey条件设备注册,不允许本接口和leda_register_and_online_by_device_name接口同时使用。
* 即每一个产品ProductKey设备注册必须使用同一接口,否则设备注册会发生不可控行为。
*/
device_handle_t leda_register_and_online_by_local_name(const char *product_key, const char *local_name, leda_device_callback_t *device_cb, void *usr_data);
leda_init
/*
* 驱动模块初始化,模块内部会创建工作线程池,异步执行阿里云物联网平台下发的设备操作请求,工作线程数目通过worker_thread_nums配置。
*
* worker_thread_nums: 线程池工作线程数,该数值根据注册设备数量进行设置。
*
* 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。
*/
int leda_init(int worker_thread_nums);
leda_exit
/*
* 驱动模块退出。
*
* 模块退出前,释放资源。
*
* 阻塞接口。
*/
void leda_exit(void);
leda_get_driver_info_size
/*
* 获取驱动信息长度。
*
* 阻塞接口,成功返回驱动信息长度,失败返回0。
*/
int leda_get_driver_info_size(void);
leda_get_driver_info
/*
* 获取驱动信息(在物联网平台配置的驱动配置)。
*
* driver_info: 驱动信息,需要提前申请好内存传入。
* size: 驱动信息长度,leda_get_driver_info_size,如果传入driver_info比实际配置内容长度短,会返回LE_ERROR_INVAILD_PARAM。
*
* 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。
*
* 配置格式:
{
"json":{
"ip":"127.0.0.1",
"port":54321
},
"kv":[
{
"key":"ip",
"value":"127.0.0.1",
"note":"ip地址"
},
{
"key":"port",
"value":"54321",
"note":"port端口"
}
],
"fileList":[
{
"path":"device_config.json"
}
]
}
*/
int leda_get_driver_info(char *driver_info, int size);
leda_get_device_info_size
/*
* 获取设备信息长度。
*
* 阻塞接口,成功返回设备信息长度,失败返回0。
*/
int leda_get_device_info_size(void);
leda_get_device_info
/*
* 获取设备信息(在物联网平台配置的设备配置)。
*
* device_info: 设备信息,需要提前申请好内存传入。
* size: 设备信息长度,该长度通过leda_get_device_info_size接口获取,如果传入device_info比实际配置内容长度短,会返回LE_ERROR_INVAILD_PARAM。
*
* 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。
*
* 配置格式:
[
{
"custom":{
"port":12345,
"ip":"127.0.0.1"
},
"deviceName":"device1",
"productKey":"a1ccxxeypky"
}
]
*/
int leda_get_device_info(char *device_info, int size);
leda_get_config_size
/*
* 获取驱动配置长度。
*
* 阻塞接口,成功返回驱动配置长度,失败返回0。
*/
int leda_get_config_size(void);
leda_get_config
/*
* 获取驱动所有配置。
*
* config: 驱动配置,需要提前申请好内存传入。
* size: 驱动配置长度,该长度通过leda_get_config_size接口获取,如果传入config比实际配置内容长度短,会返回LE_ERROR_INVAILD_PARAM。
*
* 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。
*
* 配置格式:
{
"config":{
"json":{
"ip":"127.0.0.1",
"port":54321
},
"kv":[
{
"key":"ip",
"value":"127.0.0.1",
"note":"ip地址"
},
{
"key":"port",
"value":"54321",
"note":"port端口"
}
],
"fileList":[
{
"path":"device_config.json"
}
]
},
"deviceList":[
{
"custom":"{"port":12345,"ip":"127.0.0.1"}",
"deviceName":"device1",
"productKey":"a1ccxxeypky"
}
]
}
*/
int leda_get_config(char *config, int size);
config_changed_callback
/*
* 驱动配置变更回调接口。
*
* config: 配置信息。
*
* 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。
*/
typedef int (*config_changed_callback)(const char *config);
leda_register_config_changed_callback
/*
* 订阅驱动配置变更监听回调。
*
* config_cb: 配置变更通知回调接口。
*
* 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。
*/
int leda_register_config_changed_callback(config_changed_callback config_cb);
leda_get_tsl_size
/*
* 获取指定产品ProductKey对应物模型内容长度。
*
* product_key: 产品ProductKey。
*
* 阻塞接口,成功返回product_key对应物模型内容长度,失败返回0。
*/
int leda_get_tsl_size(const char *product_key);
leda_get_tsl
/*
* 获取指定产品ProductKey对应物模型内容。
*
* product_key: 产品ProductKey。
* tsl: 物模型内容,需要提前申请好内存传入。
* size: 物模型内容长度,该长度通过leda_get_tsl_size接口获取,如果传入tsl比实际物模型内容长度短,会返回LE_ERROR_INVAILD_PARAM。
*
* 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。
*/
int leda_get_tsl(const char *product_key, char *tsl, int size);
leda_get_tsl_ext_info_size
/*
* 获取指定产品ProductKey对应物模型扩展信息内容长度。
*
* product_key: 产品ProductKey。
*
* 阻塞接口,成功返回product_key对应物模型扩展信息内容长度,失败返回0。
*/
int leda_get_tsl_ext_info_size(const char *product_key);
leda_get_tsl_ext_info
/*
* 获取指定产品ProductKey对应物模型扩展信息内容。
*
* product_key: 产品ProductKey。
* tsl_ext_info: 物模型扩展信息,需要提前申请好内存传入。
* size: 物模型扩展信息长度,该长度通过leda_get_tsl_ext_info_size接口获取,如果传入tsl_ext_info比实际物模型扩展信息内容长度短,会返回LE_ERROR_INVAILD_PARAM。
*
* 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。
*/
int leda_get_tsl_ext_info(const char *product_key, char *tsl_ext_info, int size);
leda_get_device_handle
/*
* 获取设备句柄。
*
* product_key: 产品ProductKey。
* device_name: 设备名称DeviceName。
*
* 阻塞接口,成功返回device_handle_t,失败返回小于0数值。
*/
device_handle_t leda_get_device_handle(const char *product_key, const char *device_name);
7.2 Java版本SDK
设备接入SDK(Java版本)支持开发者使用Java语言开发设备接入驱动(以下简称驱动)。客户网关环境在安装有Link IoT Edge软件的条件下只要满足Java运行环境即可运行Java驱动。
Java版本开源的SDK源码请参见开源Java库。
LedaConfig
类名全称:
com.aliyun.linkedge.sdk.LedaConfig
类声明:
public class LedaConfig
Java方法说明:| 限定符和类型 | 方法和说明 || :—- | :—- || static String | getDriverConfig()获取驱动配置。 || static String | getDeviceConfig()获取设备配置。 || static String | getTsl(String productKey)获取productKey(产品唯一标识符)对应的物模型(TSL)。 || static String | getTslConfig(String productKey)获取productKey对应的物模型扩展配置。 |
LedaDevice
类名全称:
com.aliyun.linkedge.sdk.LedaDevice
类声明:
public class LedaDevice
构造函数:
LedaDevice(String productKey, String deviceName)
Java方法说明:| 限定符和类型 | 方法和说明 || :—- | :—- || LedaData | getProperties(List propertyNameList)根据指定的属性名称,获取属性值。使用该方法时,需要实现重载(Overload)。 || int | setProperties(HashMap properties)设置属性名称和属性值。使用该方法时,需要实现重载。 || LedaData | callService(String methodName, HashMap params)执行自定义方法。使用该方法时,需要实现重载。 || int | online()上线设备。 || int | offline()下线设备。 || int | reportProperties(HashMap properties)上报设备属性。 || int | reportEvents(String eventName, HashMap outputData)上报设备事件。 |
数据类
类名全称:
com.aliyun.linkedge.sdk.LedaDevice
类声明:
public class LedaData
构造函数:
LedaData(int code, HashMap<String, Object> data)
Java方法说明:| 限定符和类型 | 方法和说明 || :—- | :—- || void | setCode(int code)设置状态码。 || int | getCode()获取状态码。 || void | setData(HashMap data)设置数据内容。 || HashMap | getData()获取数据内容。 |
错误码
类名全称:
com.aliyun.linkedge.sdk.exception.LedaErrorCode
类声明:
public class LedaErrorCode { public static final int LE_SUCCESS = 0; public static final int LE_ERROR_UNKNOWN = 100000; public static final int LE_ERROR_INVALID_PARAM = 100001; public static final int LE_ERROR_TIMEOUT = 100006; public static final int LE_ERROR_PARAM_RANGE_OVERFLOW = 100007; public static final int LE_ERROR_SERVICE_UNREACHABLE = 100008; public static final int LEDA_ERROR_DEVICE_UNREGISTER = 109000; public static final int LEDA_ERROR_DEVICE_OFFLINE = 109001; public static final int LEDA_ERROR_PROPERTY_NOT_EXIST = 109002; public static final int LEDA_ERROR_PROPERTY_READ_ONLY = 109003; public static final int LEDA_ERROR_PROPERTY_WRITE_ONLY = 109004; public static final int LEDA_ERROR_SERVICE_NOT_EXIST = 109005; public static final int LEDA_ERROR_SERVICE_INPUT_PARAM = 109006; public static final int LEDA_ERROR_INVALID_JSON = 109007; public static final int LEDA_ERROR_INVALID_TYPE = 109008; private static final String LE_SUCCESS_MSG = "Success"; /* 请求成功*/ private static final String LE_ERROR_INVALID_PARAM_MSG = "Invalid params"; /* 传入参数为NULL或无效*/ private static final String LE_ERROR_TIMEOUT_MSG = "Tiemout"; /* 超时*/ private static final String LE_ERROR_PARAM_RANGE_OVERFLOW_MSG = "Param range overflow"; /* 参数范围越界*/ private static final String LE_ERROR_SERVICE_UNREACHABLE_MSG = "Service unreachable"; /* 服务不可达*/ private static final String LEDA_ERROR_DEVICE_UNREGISTER_MSG = "Device has't register"; /* 设备未注册*/ private static final String LEDA_ERROR_DEVICE_OFFLINE_MSG = "Device has offline"; /* 设备已下线*/ private static final String LEDA_ERROR_PROPERTY_NOT_EXIST_MSG = "Property no exist"; /* 属性不存在*/ private static final String LEDA_ERROR_PROPERTY_READ_ONLY_MSG = "Property only support read"; /* 属性只读*/ private static final String LEDA_ERROR_PROPERTY_WRITE_ONLY_MSG = "Property only support write"; /* 属性只写*/ private static final String LEDA_ERROR_SERVICE_NOT_EXIST_MSG = "Service no exist"; /* 服务不存在*/ private static final String LEDA_ERROR_SERVICE_INPUT_PARAM_MSG = "Service param invalid"; /* 服务的输入参数不正确错误码*/ private static final String LEDA_ERROR_INVALID_JSON_MSG = "Json format invalid"; /* JSON格式错误*/ private static final String LEDA_ERROR_INVALID_TYPE_MSG = "Param type invalid"; /* 参数类型错误*/ }
Java方法说明:| 限定符和类型 | 方法和说明 || :—- | :—- || String | getMessage(int code)获取错误码对应的消息。 |