全部产品

边缘应用 Link IoT Edge对接

更新时间:2020-06-30 18:51:05

本章主要介绍如何实现 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}

样例:

  1. ibms应用程序获取分组中所有的设备列表Topic
  2. 请求Topicibms/request/linkedge/getDeviceList
  3. 应答Topiclinkedge/response/ibms/getDeviceList
  4. 子设备状态变更(下线->上线)Topic
  5. 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应用程序获取网关的设备列表为例:

  1. ibms应用程序获取网关的设备列表Topic
  2. 请求Topicibms/request/linkedge/{pk}/{dn}/getDeviceList
  3. 应答Topiclinkedge/response/ibms/{pk}/{dn}/getDeviceList
  4. 某网关下子设备状态变更(下线->上线)Topic
  5. 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. /* 1.先订阅应答Topic,用户接收设备应答数据 */
    2. #./mosquitto_sub --psk-identity linkedge --psk 12345678 -p 8883 -t thing/response/testApp/+/+/+ -v &
    3. /* 2.发送设备方法调用get请求 */
    4. #./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\"}"
    5. /* 3.mosquitto_sub输出设备应答信息 */
    6. 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. # 示例1-设备属性上报:
  2. Topic:thing/notify/${pk}/${dn}/property
  3. Payload:
  4. {
  5. "key1":{
  6. "value":"value1",
  7. "time":152444872****
  8. },
  9. "key2":{
  10. "value":"value2",
  11. "time":152444872****
  12. }
  13. }
  14. # 示例2-设备事件上报:
  15. Topic:thing/notify/${pk}/${dn}/${tsl.event.identifer}
  16. Payload:
  17. {
  18. "params": {
  19. "value" : {
  20. "key1":"value1",
  21. "key2":"value2"
  22. },
  23. "time" : 152444872****
  24. }
  25. }

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}

设备驱动接口规范链接http://gitlab.alibaba-inc.com/iot-gateway/gateway/wikis/cmp_interface
设备配置Payload在驱动请求参数基础上增加了requestId字段,用于标识每次配置请求:

  1. #示例-设置设备属性
  2. Topic:testApp/request/thing/${productKey}/${deviceName}/set
  3. Payload:
  4. {
  5. "requestId":"0bc458b5-47f6-472f-bd88-3624696e9776", #[Required]
  6. "timeout":5,
  7. "params":{ #设备方法调用的参数[Required]
  8. "key1":"value1",
  9. "key2":"value2"
  10. }
  11. }
  12. #示例-获取设备属性
  13. Topic:testApp/request/thing/${productKey}/${deviceName}/get
  14. Payload:
  15. {
  16. "requestId":"ff8db62b-4d75-46c8-bf6a-1600d326a88b", #[Required]
  17. "params":[ #设备方法调用的参数[Required]
  18. "key"
  19. ]
  20. }
  • 设置设备属性应答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字段,用于匹配对应的配置请求:

  1. #示例-设置设备属性应答数据
  2. Topic:thing/response/{srcApp}/${pk}/${dn}/set
  3. Payload:
  4. {
  5. "requestId":"0bc458b5-47f6-472f-bd88-3624696e9776",
  6. "code":0,
  7. "message":"",
  8. "params":{}
  9. }
  10. #示例-获取设备属性应答数据
  11. Topic:thing/response/{srcApp}/${pk}/${dn}/get
  12. Payload:
  13. {
  14. "requestId":"ff8db62b-4d75-46c8-bf6a-1600d326a88b",
  15. "code":0,
  16. "message":"success",
  17. "params":{
  18. "key":"value"
  19. }
  20. }

4.2 设备状态查询

4.2.1 获取设备列表

  • 获取分组设备列表Topic:{srcApp}/request/linkedge/getDeviceList
  • 获取网关设备列表Topic:{srcApp}/request/linkedge/{pk}/{dn}/getDeviceList
  • 请求Payload:
  1. {
  2. "requestId": "0bc458b5-47f6-472f-bd88-3624696e9777", # [Required]
  3. "timestamp": 157121985****, #ms [Optional]
  4. "timeout":3, # 最少1s,最多120s [Optional: default 4s]
  5. "version": "1.0" # [Optional]
  6. }
  • 获取分组设备列表应答Topic:linkedge/response/{srcApp}/getDeviceList
  • 应答Payload

    1. {
    2. "params":[ #数组,包含所有网关下的子设备
    3. {
    4. "gwProductKey":"a1PQ9828qvr", #网关的productkey
    5. "gwDeviceName":"yinlong_gw_dev1",#网关的devicename
    6. "code":0,
    7. "message":"success",
    8. "deviceList":[ #设备列表
    9. {
    10. "productKey":"a1KRepmC2XJ", #设备的productkey
    11. "deviceName":"modbus_tcp_dev_1", #设备的devicename
    12. "localOnline":"false", #设备与网关的连接状态
    13. "cloudOnline":"false", #设备与云端的连接状态
    14. "activationState":"notActivated",#设备在云端是否被激活
    15. "nickName":"xxx", #设备别名
    16. "tags":[ #设备包含的标签
    17. ]
    18. },
    19. {
    20. "productKey":"a1ZJTVsqj2y",
    21. "deviceName":"lightDevNoSpecial",
    22. "localOnline":"true",
    23. "cloudOnline":"true",
    24. "activationState":"activated",
    25. "nickName":"xxx", #设备别名
    26. "tags":[
    27. ]
    28. },
    29. {
    30. "productKey":"a1ZJTVsqj2y",
    31. "deviceName":"LightDev2",
    32. "localOnline":"false",
    33. "cloudOnline":"false",
    34. "activationState":"notActivated",
    35. "nickName":"xxx", #设备别名
    36. "tags":[ #设备包含的标签
    37. {
    38. "key":"type", #设备标签的key
    39. "value":"light" #设备标签的value
    40. },
    41. {
    42. "key":"owner",
    43. "value":"yinlong"
    44. },
    45. {
    46. "key":"location",
    47. "value":"master bedroom"
    48. },
    49. {
    50. "key":"color",
    51. "value":"red"
    52. }
    53. ]
    54. }
    55. ]
    56. }
    57. ],
    58. "requestId":"0bc458b5-47f6-472f-bd88-3624696e9777",
    59. "version":"1.0",
    60. "timestamp":157225013****,
    61. "code":0,
    62. "message":"success"
    63. }
  • 获取网关设备列表应答Topic:linkedge/response/``{srcApp}``/{pk}/{dn}/getDeviceList

  • 应答Payload:
    1. {
    2. "requestId":"0bc458b5-47f6-472f-bd88-3624696e9777",
    3. "timestamp": 157121985****,
    4. "version":"1.0",
    5. "code":0,
    6. "message":"success",
    7. "params":[ #设备列表
    8. {
    9. "productKey":"a1Mtx4p2fHG", #设备的productkey
    10. "deviceName":"device1", #设备的devicename
    11. "localOnline":"true", #设备和网关的连接状态
    12. "cloudOnline":"true", #设备和云端的连接状态
    13. "activationState": "activated/notActivated/activationFailed", #设备在云端的激活状态
    14. "tag":[
    15. {
    16. "key":"coordinate",
    17. "value":"0:0"
    18. }
    19. ]
    20. }
    21. ]
    22. }

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:
  1. {
  2. "requestId": "0bc458b5-47f6-472f-bd88-3624696e9778",
  3. "version": "1.0",
  4. "timeout":3 # 最少1s,最多120s
  5. }
  • 获取设备TSL应答Topic:thing/response/{srcApp}/{pk}/{dn}/getTsl
  • 应答Payload:
  1. {
  2. "params":{
  3. "productKey":"a1KRepmC2XJ",
  4. "deviceName":"modbus_tcp_dev_1",
  5. "code":0,
  6. "message":"success",
  7. "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}]}", #物模型
  8. "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}]}" #扩展物模型
  9. },
  10. "requestId":"0bc458b5-47f6-472f-bd88-3624696e9777",
  11. "version":"1.0",
  12. "timestamp":157224857****,
  13. "code":0,
  14. "message":"success"
  15. }

4.3 IFTTT规则配置

4.3.1 获取IFTTT规则列表

  • 获取分组IFTTT规则列表Topic:{srcApp}/request/linkedge/getSceneList
  • 获取网关IFTTT规则列表Topic:{srcApp}/request/linkedge/{pk}/{dn}/getSceneList
  • 请求Payload:
  1. {
  2. "requestId": "0bc458b5-47f6-472f-bd88-3624696e9778",
  3. "timestamp": 157121985****, #ms [Optional]
  4. "timeout":3, # 最少1s,最多120s [Optional: default 4s]
  5. "version": "1.0" # [Optional]
  6. }
  • 获取分组IFTTT规则应答Topic:linkedge/response/{srcApp}/getSceneList
  • 应答Payload:
  1. {
  2. "params":[ #规则列表
  3. {
  4. "gwProductKey":"a1PQ9828qvr", #网关productkey
  5. "gwDeviceName":"alpine_test_gateway",#网关的devicenmae
  6. "code":0,
  7. "message":"success",
  8. "data":[ #包含网关中所有规则的描述
  9. ]
  10. },
  11. {
  12. "gwProductKey":"a1PQ9828qvr",
  13. "gwDeviceName":"yinlong_gw_dev1",
  14. "code":0,
  15. "message":"success",
  16. "data":[
  17. {
  18. "times":5,
  19. "failureTimes":5,
  20. "lastState":{
  21. "state":"failure",
  22. "cause":"walk action set: The name iot.device.ida1ZJTVsqj2y_alpine_light_dev1 was not provided by any .service files",
  23. "time":"2019-10-28T19:35:00+08:00",
  24. "duration":1
  25. },
  26. "id":"a08d6c08bc1a440693ba9c9c8166a968",
  27. "name":"ifttt",
  28. "running":true,
  29. "time":"2019-10-28T19:30:47+08:00",
  30. "uptime":259072,
  31. "actions":{
  32. "times":5,
  33. "failureTimes":5,
  34. "lastState":{
  35. "state":"failure",
  36. "cause":"The name iot.device.ida1ZJTVsqj2y_alpine_light_dev1 was not provided by any .service files",
  37. "time":"2019-10-28T19:35:00+08:00",
  38. "duration":1
  39. }
  40. },
  41. "conditions":{
  42. "times":5,
  43. "failureTimes":0,
  44. "lastState":{
  45. "state":"success",
  46. "cause":"",
  47. "time":"2019-10-28T19:35:00+08:00",
  48. "duration":0
  49. }
  50. }
  51. }
  52. ]
  53. }
  54. ],
  55. "requestId":"0bc458b5-47f6-472f-bd88-3624696e9777",
  56. "version":"1.0",
  57. "timestamp":157226250****,
  58. "code":0,
  59. "message":"success"
  60. }
  • 获取网关IFTTT规则应答Topic:linkedge/response/{srcApp}/{pk}/{dn}/getSceneList
  • 应答Payload:
  1. {
  2. "params":[ #网关下的规则列表
  3. {
  4. "times":0,
  5. "failureTimes":0,
  6. "lastState":null,
  7. "id":"a08d6c08bc1a440693ba9c9c8166a968",
  8. "name":"ifttt",
  9. "running":true,
  10. "time":"2019-10-28T17:35:35+08:00",
  11. "uptime":5967,
  12. "actions":{
  13. "times":0,
  14. "failureTimes":0,
  15. "lastState":null
  16. },
  17. "conditions":{
  18. "times":0,
  19. "failureTimes":0,
  20. "lastState":null
  21. }
  22. }
  23. ],
  24. "requestId":"0bc458b5-47f6-472f-bd88-3624696e9777",
  25. "version":"1.0",
  26. "timestamp":157225534****,
  27. "code":0,
  28. "message":"success"
  29. }

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个对象。
  1. {
  2. "requestId": "0bc458b5-47f6-472f-bd88-3624696e9778",
  3. "version": "1.0",
  4. "params": [ #场景规则id数组[Required]
  5. {
  6. "id": "id1"
  7. }
  8. ]
  9. }
  • 使能网关IFTTT规则配置应答Topic:linkedge/response/{srcApp}/{pk}/{dn}/enableScene
  • 关闭网关IFTTT规则配置应答Topic:linkedge/response/{srcApp}/{pk}/{dn}/disableScene
  • 应答Payload:
  1. {
  2. "params":[
  3. {
  4. "id":"123000000",
  5. "code":1,
  6. "message":"no such scene"
  7. },
  8. {
  9. "id":"a08d6c08bc1a440693ba9c9c8166a968",
  10. "code":0,
  11. "message":"success"
  12. }
  13. ],
  14. "requestId":"0bc458b5-47f6-472f-bd88-3624696e9777",
  15. "version":"1.0",
  16. "timestamp":157227690****,
  17. "code":0,
  18. "message":"success"
  19. }

4.4 设备列表和状态变更

4.4.1 设备列表变更

当网关互联中某一网关所拥有的设备列表出现变化时,互联网络将广播一条消息通知给订阅者。

  • 变更Topic: linkedge/notify/deviceListChanged
  • 内容
  1. {
  2. "timestamp":157225090****,
  3. "version":"1.0",
  4. "params":[
  5. {
  6. "gwProductKey":"a1XqBnyTZLD",
  7. "gwDeviceName":"ModbusTestGW"
  8. }
  9. ]
  10. }

4.4.2 设备在线状态变更

当网关互联中某子设备的在线状态出现变化时(包括连接到本地和连接到云端),网关互联网络将广播一条消息给订阅者

  • 通知Topic: linkedge/notify/deviceStateChanged
  • 内容

内容格式大体与4.2.1获取设备列表相同。

  1. {
  2. "timestamp": 1572250903307,
  3. "version": "1.0",
  4. "params": [{
  5. "gwProductKey": "a1XqBnyTZLD", #网关的productkey
  6. "gwDeviceName": "ModbusTestGW", #网关的devicename
  7. "deviceList": [{ #网关下的设备列表
  8. "productKey": "a1OSqKKiZLL", #设备的productkey
  9. "deviceName": "DN035", #设备的devicename
  10. "localOnline": "true/false", #设备的本地在线状态
  11. "cloudOnline": "true/false", #设备的云端在线状态
  12. "activationState": "activated/notActivated/activationFailed",#设备在云端的激活状态
  13. }]
  14. }]
  15. }

4.5 网关信息查询

4.5.1 获取网关列表

  • 获取分组网关列表Topic:{srcApp}/request/linkedge/getGatewayList
  • 请求Payload
  1. {
  2. "requestId": "0bc458b5-47f6-472f-bd88-3624696e9777", # [Required]
  3. "timestamp": 157121985****, #ms [Optional]
  4. "timeout":3, # 最少1s,最多120s [Optional: default 4s]
  5. "version": "1.0" # [Optional]
  6. }
  • 获取分组网关列表应答Topic:linkedge/response/{srcApp}/getGatewayList
  • 响应Payload
  1. {
  2. "params":[
  3. {
  4. "gwProductKey":"a1phR16zqNZ",
  5. "gwDeviceName":"gateway_01",
  6. "code":0, #此网关接口的服务调用的返回码
  7. "message":"success",
  8. "gatewayInfo":{ #网关信息
  9. "productKey":"a1phR16zqNZ", #网关的productkey
  10. "deviceName":"gateway_01", #网关的devicename
  11. "nickName":"", #网关的别名
  12. "tags":[ #网关的标签
  13. ]
  14. }
  15. },
  16. {
  17. "gwProductKey":"a1phR16zqNZ",
  18. "gwDeviceName":"gateway_02",
  19. "code":101572,
  20. "message":"getGateway timeout"
  21. },
  22. {
  23. "gwProductKey":"a1phR16zqNZ",
  24. "gwDeviceName":"gateway_03",
  25. "code":101572,
  26. "message":"ERROR_GWC_REQUEST_TIMEOUT"
  27. }
  28. ],
  29. "requestId":"0bc458b5-47f6-472f-bd88-3624696e9777",
  30. "version":"1.0",
  31. "timestamp":158202075****,
  32. "code":10****, #分组接口的调用返回码
  33. "message":"ERROR_GWC_REQUEST_TIMEOUT"
  34. }

5.错误码

应答Payload中的”code”字段代表错误码,成功时返回0,异常时返回下述错误码,错误信息保存到”message”字段:

  1. 0: 成功
  2. 101571: 参数校验不合法
  3. 101572: 请求处理超时
  4. 101573: LinkIoTEdge处理失败
  5. 101574:设备驱动处理失败
  6. 101575: MQTT消息代理处理失败
  7. 101576: 设备不存在
  8. 101578: 请求的参数个数超出上限
  9. 101579: 访问资源不存在
  10. 101580: 请求的参数为空

6.自测用例

该部分测试用例中的测试数据,对于MQTT客户端开发具有很好的借鉴价值,结合具体例子的请求和应答便于开发者加深对协议规范的理解。

6.1 部署配置样例

  • 本地部署方法:./casctl deploy gwc_deploy.conf
  • gwc_deploy.conf配置文件样例:
  1. {
  2. "version":"1.0",
  3. "instanceId":"iid222",
  4. "instanceGroupId":"linkedge",
  5. "instanceGroupPsk":"123456abcdef12345678123456ABCDEF",
  6. "userTlsConfig":[
  7. {
  8. "userId":"customer1",
  9. "psk":"123456"
  10. },
  11. {
  12. "userId":"customer2",
  13. "psk":"12345678"
  14. }
  15. ],
  16. "nodesConfig":[
  17. {
  18. "ipAddress":"172.17.0.2",
  19. "productKey":"a1PQ9828qvr",
  20. "deviceName":"yinlong_gw_dev1",
  21. "isGroupAgent":"1" #Mark this gw as groupAgent
  22. },
  23. {
  24. "ipAddress":"172.17.0.3",
  25. "productKey":"a1PQ9828qvr",
  26. "deviceName":"alpine_test_gateway"
  27. }
  28. ]
  29. }

6.2 自测用例

1.订阅所有设备属性、事件上报

  1. /* 订阅设备属性上报Topic,接收设备属性上报数据 */
  2. #./mosquitto_sub --psk-identity linkedge --psk 123456aBcdef12345678123456ABCDEf -p 8883 -t thing/notify/+/+/property -v &
  3. thing/notify/a1Mtx4p2fHG/LightSensor/property {"MeasuredIlluminance":{"value":550,"time":156662262****}}
  4. thing/notify/a1Mtx4p2fHG/LightSensor/property {"MeasuredIlluminance":{"value":600,"time":156662265****}}
  5. thing/notify/a1Mtx4p2fHG/LightSensor/property {"MeasuredIlluminance":{"value":650,"time":156662268****}}

2.访问外部/本地网关设备方法

  1. /* 1.先订阅应答Topic,用户接收设备应答数据 */
  2. #./mosquitto_sub --psk-identity linkedge --psk 12345678 -p 8883 -t thing/response/testApp/+/+/+ -v &
  3. /* 2.发送设备方法调用get请求 */
  4. #./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\"}"
  5. /* 3.mosquitto_sub输出设备应答信息 */
  6. thing/response/testApp/a1Mtx4p2fHG/LightSensor/get {"code":0,"message":"success","params":{"MeasuredIlluminance":1000},"requestId":"ff8db62b-4d75-46c8-bf6a-1600d326a88b"}

3.消息路由:
配置全部设备数据到FC,配置某个ProductKey下所有设备数据到FC。

4.获取网关设备列表

  1. ./mosquitto_sub --psk-identity linkedge --psk 123456aBcdef12345678123456ABCDEf -p 8883 -t linkedge/response/testApp/a1PQ9828qvr/yinlong_gw_dev1/getDeviceList -v &
  2. ./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\"}"
  3. 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"}

5.getTsl 测试用例:

  1. ./mosquitto_sub --psk-identity linkedge --psk 123456aBcdef12345678123456ABCDEf -p 8883 -t thing/response/testApp/+/+/getTsl -v &
  2. ./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}"
  3. 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"}

6.获取分组设备列表

  • 前置条件:修改gwc_deploy.conf,选择一台网关为groupAgent:设置代理网关标志 “isGroupAgent”:”1”
  1. ./casctl dep gwc_deploy.conf
  • 测试命令
  1. ./mosquitto_sub --psk-identity linkedge --psk 123456aBcdef12345678123456ABCDEf -p 8883 -t linkedge/response/testApp/getDeviceList -v &
  2. ./mosquitto_pub --psk-identity linkedge --psk 123456aBcdef12345678123456ABCDEf -p 8883 -t testApp/request/linkedge/getDeviceList -m "{\"requestId\": \"0bc458b5-47f6-472f-bd88-3624696e9777\"}"
  3. 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"}
  4. 超时情况: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"}

7.getSceneList

  • 获取单个网关的规则列表
  1. ./mosquitto_sub --psk-identity linkedge --psk 123456aBcdef12345678123456ABCDEf -p 8883 -t linkedge/response/testApp/a1PQ9828qvr/yinlong_gw_dev1/getSceneList -v &
  2. ./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\"}"
  3. 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"}
  4. dbus-send --bus=unix:path=/tmp/var/run/mbusd/mbusd_socket --dest=iot.gateway.scene --print-reply /iot/gateway/scene iot.gateway.scene.listSceneStats
  • 获取分组的规则列表
  1. ./mosquitto_sub --psk-identity linkedge --psk 123456aBcdef12345678123456ABCDEf -p 8883 -t linkedge/response/testApp/getSceneList -v &
  2. ./mosquitto_pub --psk-identity linkedge --psk 123456aBcdef12345678123456ABCDEf -p 8883 -t testApp/request/linkedge/getSceneList -m "{\"requestId\": \"0bc458b5-47f6-472f-bd88-3624696e9777\"}"
  3. 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"}

8.enableScene

  1. ./mosquitto_sub --psk-identity linkedge --psk 123456aBcdef12345678123456ABCDEf -p 8883 -t linkedge/response/testApp/+/+/enableScene -v &
  2. ./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\"}]}"
  3. 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"}

9.disableScene

  1. ./mosquitto_sub --psk-identity linkedge --psk 123456aBcdef12345678123456ABCDEf -p 8883 -t linkedge/response/testApp/+/+/disableScene -v &
  2. ./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\"}]}"
  3. 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

  1. /*
  2. * 获取属性(对应设备产品物模型属性定义)的回调函数,需驱动开发者实现获取属性业务逻辑。
  3. *
  4. * Link IoT Edge需要获取某个设备的属性时,SDK会调用该接口间接获取到数据并封装成固定格式后回传给Link IoT Edge。
  5. * 开发者需要根据设备id和属性名找到设备,将获取到的属性值按照@device_data_t格式填充。
  6. *
  7. * @dev_handle: Link IoT Edge需要获取属性的具体某个设备。
  8. * @properties: 属性值键值结构,驱动开发者需要将根据属性名称获取到的属性值更新到properties中。
  9. * @properties_count: 属性个数。
  10. * @usr_data: 注册设备时,用户传递的私有数据。
  11. * 所有属性均获取成功则返回LE_SUCCESS,其他则返回错误码(参考le_error.h错误码宏定义)。
  12. * */
  13. typedef int (*get_properties_callback)(device_handle_t dev_handle,
  14. leda_device_data_t properties[],
  15. int properties_count,
  16. void *usr_data);

set_properties_callback

  1. /*
  2. * 设置属性(对应设备产品物模型属性定义)的回调函数,需驱动开发者实现设置属性业务逻辑。
  3. *
  4. * Link IoT Edge需要设置某个设备的属性时,SDK会调用该接口将具体的属性值传递给应用程序,开发者需要在本回调
  5. * 函数里将属性设置到设备。
  6. *
  7. * @dev_handle: Link IoT Edge需要设置属性的具体某个设备。
  8. * @properties: Link IoT Edge需要设置的设备的属性名称和值。
  9. * @properties_count: 属性个数。
  10. * @usr_data: 注册设备时,用户传递的私有数据。
  11. *
  12. * 若获取成功则返回LE_SUCCESS,失败则返回错误码(参考le_error.h错误码宏定义)。
  13. * */
  14. typedef int (*set_properties_callback)(device_handle_t dev_handle,
  15. const leda_device_data_t properties[],
  16. int properties_count,
  17. void *usr_data);

call_service_callback

  1. /*
  2. * 服务(对应设备产品物模型服务定义)调用的回调函数,需要驱动开发者实现服务对应业务逻辑。
  3. *
  4. * Link IoT Edge需要调用某个设备的服务时,SDK会调用该接口将具体的服务参数传递给应用程序,开发者需要在本回调
  5. * 函数里调用具体的服务,并将服务返回值按照@device_data_t格式填充到output_data。
  6. *
  7. * @dev_handle: Link IoT Edge需要调用服务的具体某个设备。
  8. * @service_name: Link IoT Edge需要调用的设备的具体某个服务名,名称与设备产品物模型一致。
  9. * @data: Link IoT Edge需要调用的设备的具体某个服务参数,参数与设备产品物模型保持一致。
  10. * @data_count: Link IoT Edge需要调用的设备的具体某个服务参数个数。
  11. * @output_data: 开发者需要将服务调用的返回值,按照设备产品物模型规定的服务格式返回到output中。
  12. * @usr_data: 注册设备时,用户传递的私有数据。
  13. *
  14. * 若获取成功则返回LE_SUCCESS,失败则返回错误码(参考le_error.h错误码宏定义)。
  15. * */
  16. typedef int (*call_service_callback)(device_handle_t dev_handle,
  17. const char *service_name,
  18. const leda_device_data_t data[],
  19. int data_count,
  20. leda_device_data_t output_data[],
  21. void *usr_data);

leda_report_properties

  1. /*
  2. * 上报属性,在设备所属产品物模型中规定了设备的属性上报能力。
  3. *
  4. * 上报属性,可以上报一个,也可以多个一起上报。
  5. *
  6. * dev_handle: 设备在Link IoT Edge本地唯一标识。
  7. * properties: @leda_device_data_t,属性数组。
  8. * properties_count: 本次上报属性个数。
  9. *
  10. * 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。
  11. *
  12. */
  13. int leda_report_properties(device_handle_t dev_handle, const leda_device_data_t properties[], int properties_count);

leda_report_event

  1. /*
  2. * 上报事件,设备具有的事件上报能力在设备产品物模型有规定。
  3. *
  4. *
  5. * dev_handle: 设备在Link IoT Edge本地唯一标识。
  6. * event_name: 事件名称。
  7. * data: @leda_device_data_t,事件参数数组。
  8. * data_count: 事件参数数组长度。
  9. *
  10. * 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。
  11. *
  12. */
  13. int leda_report_event(device_handle_t dev_handle, const char *event_name, const leda_device_data_t data[], int data_count);

leda_offline

  1. /*
  2. * 下线设备,假如设备工作在不正常的状态或设备退出前,可以先下线设备,这样Link IoT Edge就不会继续下发消息到设备侧。
  3. *
  4. * dev_handle: 设备在Link IoT Edge本地唯一标识。
  5. *
  6. * 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。
  7. *
  8. */
  9. int leda_offline(device_handle_t dev_handle);

leda_online

  1. /*
  2. * 上线设备,设备只有上线后,才能被Link IoT Edge识别。
  3. *
  4. * dev_handle: 设备在Link IoT Edge本地唯一标识。
  5. *
  6. * 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。
  7. */
  8. int leda_online(device_handle_t dev_handle);

leda_register_and_online_by_device_name

  1. /*
  2. * 通过已在阿里云物联网平台创建的设备device_name,注册并上线设备,申请设备唯一标识符。
  3. *
  4. * 若需要注册多个设备,则多次调用该接口即可。
  5. *
  6. * product_key: 在阿里云物联网平台创建的产品ProductKey。
  7. * device_name: 在阿里云物联网平台创建的设备名称DeviceName。
  8. * device_cb: 请求调用设备回调函数结构体,详细描述见@leda_device_callback。
  9. * usr_data: 设备注册时传入私有数据,在回调中会传给设备。
  10. *
  11. * 阻塞接口,返回值设备在Link IoT Edge本地唯一标识,>= 0表示有效,< 0 表示无效。
  12. *
  13. */
  14. 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

  1. /*
  2. * 通过本地自定义设备名称,注册并上线设备,申请设备唯一标识符。
  3. *
  4. * 若需要注册多个设备,则多次调用该接口即可。
  5. *
  6. * product_key: 在阿里云物联网平台创建的产品ProductKey。
  7. * local_name: 由设备特征值组成的唯一描述信息,必须保证同一个product_key时,每个设备名称不同。
  8. * device_cb: 请求调用设备回调函数结构体,详细描述见@leda_device_callback。
  9. * usr_data: 设备注册时传入私有数据,在回调中会传给设备。
  10. *
  11. * 阻塞接口,返回值设备在Link IoT Edge本地唯一标识,>= 0表示有效,< 0 表示无效。
  12. *
  13. * 注:在同一产品ProductKey条件设备注册,不允许本接口和leda_register_and_online_by_device_name接口同时使用。
  14. * 即每一个产品ProductKey设备注册必须使用同一接口,否则设备注册会发生不可控行为。
  15. */
  16. 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

  1. /*
  2. * 驱动模块初始化,模块内部会创建工作线程池,异步执行阿里云物联网平台下发的设备操作请求,工作线程数目通过worker_thread_nums配置。
  3. *
  4. * worker_thread_nums: 线程池工作线程数,该数值根据注册设备数量进行设置。
  5. *
  6. * 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。
  7. */
  8. int leda_init(int worker_thread_nums);

leda_exit

  1. /*
  2. * 驱动模块退出。
  3. *
  4. * 模块退出前,释放资源。
  5. *
  6. * 阻塞接口。
  7. */
  8. void leda_exit(void);

leda_get_driver_info_size

  1. /*
  2. * 获取驱动信息长度。
  3. *
  4. * 阻塞接口,成功返回驱动信息长度,失败返回0。
  5. */
  6. int leda_get_driver_info_size(void);

leda_get_driver_info

  1. /*
  2. * 获取驱动信息(在物联网平台配置的驱动配置)。
  3. *
  4. * driver_info: 驱动信息,需要提前申请好内存传入。
  5. * size: 驱动信息长度,leda_get_driver_info_size,如果传入driver_info比实际配置内容长度短,会返回LE_ERROR_INVAILD_PARAM。
  6. *
  7. * 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。
  8. *
  9. * 配置格式:
  10. {
  11. "json":{
  12. "ip":"127.0.0.1",
  13. "port":54321
  14. },
  15. "kv":[
  16. {
  17. "key":"ip",
  18. "value":"127.0.0.1",
  19. "note":"ip地址"
  20. },
  21. {
  22. "key":"port",
  23. "value":"54321",
  24. "note":"port端口"
  25. }
  26. ],
  27. "fileList":[
  28. {
  29. "path":"device_config.json"
  30. }
  31. ]
  32. }
  33. */
  34. int leda_get_driver_info(char *driver_info, int size);

leda_get_device_info_size

  1. /*
  2. * 获取设备信息长度。
  3. *
  4. * 阻塞接口,成功返回设备信息长度,失败返回0。
  5. */
  6. int leda_get_device_info_size(void);

leda_get_device_info

  1. /*
  2. * 获取设备信息(在物联网平台配置的设备配置)。
  3. *
  4. * device_info: 设备信息,需要提前申请好内存传入。
  5. * size: 设备信息长度,该长度通过leda_get_device_info_size接口获取,如果传入device_info比实际配置内容长度短,会返回LE_ERROR_INVAILD_PARAM。
  6. *
  7. * 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。
  8. *
  9. * 配置格式:
  10. [
  11. {
  12. "custom":{
  13. "port":12345,
  14. "ip":"127.0.0.1"
  15. },
  16. "deviceName":"device1",
  17. "productKey":"a1ccxxeypky"
  18. }
  19. ]
  20. */
  21. int leda_get_device_info(char *device_info, int size);

leda_get_config_size

  1. /*
  2. * 获取驱动配置长度。
  3. *
  4. * 阻塞接口,成功返回驱动配置长度,失败返回0。
  5. */
  6. int leda_get_config_size(void);

leda_get_config

  1. /*
  2. * 获取驱动所有配置。
  3. *
  4. * config: 驱动配置,需要提前申请好内存传入。
  5. * size: 驱动配置长度,该长度通过leda_get_config_size接口获取,如果传入config比实际配置内容长度短,会返回LE_ERROR_INVAILD_PARAM。
  6. *
  7. * 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。
  8. *
  9. * 配置格式:
  10. {
  11. "config":{
  12. "json":{
  13. "ip":"127.0.0.1",
  14. "port":54321
  15. },
  16. "kv":[
  17. {
  18. "key":"ip",
  19. "value":"127.0.0.1",
  20. "note":"ip地址"
  21. },
  22. {
  23. "key":"port",
  24. "value":"54321",
  25. "note":"port端口"
  26. }
  27. ],
  28. "fileList":[
  29. {
  30. "path":"device_config.json"
  31. }
  32. ]
  33. },
  34. "deviceList":[
  35. {
  36. "custom":"{"port":12345,"ip":"127.0.0.1"}",
  37. "deviceName":"device1",
  38. "productKey":"a1ccxxeypky"
  39. }
  40. ]
  41. }
  42. */
  43. int leda_get_config(char *config, int size);

config_changed_callback

  1. /*
  2. * 驱动配置变更回调接口。
  3. *
  4. * config: 配置信息。
  5. *
  6. * 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。
  7. */
  8. typedef int (*config_changed_callback)(const char *config);

leda_register_config_changed_callback

  1. /*
  2. * 订阅驱动配置变更监听回调。
  3. *
  4. * config_cb: 配置变更通知回调接口。
  5. *
  6. * 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。
  7. */
  8. int leda_register_config_changed_callback(config_changed_callback config_cb);

leda_get_tsl_size

  1. /*
  2. * 获取指定产品ProductKey对应物模型内容长度。
  3. *
  4. * product_key: 产品ProductKey。
  5. *
  6. * 阻塞接口,成功返回product_key对应物模型内容长度,失败返回0。
  7. */
  8. int leda_get_tsl_size(const char *product_key);

leda_get_tsl

  1. /*
  2. * 获取指定产品ProductKey对应物模型内容。
  3. *
  4. * product_key: 产品ProductKey。
  5. * tsl: 物模型内容,需要提前申请好内存传入。
  6. * size: 物模型内容长度,该长度通过leda_get_tsl_size接口获取,如果传入tsl比实际物模型内容长度短,会返回LE_ERROR_INVAILD_PARAM。
  7. *
  8. * 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。
  9. */
  10. int leda_get_tsl(const char *product_key, char *tsl, int size);

leda_get_tsl_ext_info_size

  1. /*
  2. * 获取指定产品ProductKey对应物模型扩展信息内容长度。
  3. *
  4. * product_key: 产品ProductKey。
  5. *
  6. * 阻塞接口,成功返回product_key对应物模型扩展信息内容长度,失败返回0。
  7. */
  8. int leda_get_tsl_ext_info_size(const char *product_key);

leda_get_tsl_ext_info

  1. /*
  2. * 获取指定产品ProductKey对应物模型扩展信息内容。
  3. *
  4. * product_key: 产品ProductKey。
  5. * tsl_ext_info: 物模型扩展信息,需要提前申请好内存传入。
  6. * size: 物模型扩展信息长度,该长度通过leda_get_tsl_ext_info_size接口获取,如果传入tsl_ext_info比实际物模型扩展信息内容长度短,会返回LE_ERROR_INVAILD_PARAM。
  7. *
  8. * 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。
  9. */
  10. int leda_get_tsl_ext_info(const char *product_key, char *tsl_ext_info, int size);

leda_get_device_handle

  1. /*
  2. * 获取设备句柄。
  3. *
  4. * product_key: 产品ProductKey。
  5. * device_name: 设备名称DeviceName。
  6. *
  7. * 阻塞接口,成功返回device_handle_t,失败返回小于0数值。
  8. */
  9. 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
  • 类声明:

    1. 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
  • 类声明:

    1. public class LedaDevice
  • 构造函数:

    1. 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
  • 类声明:

    1. public class LedaData
  • 构造函数:

    1. 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
  • 类声明:

    1. public class LedaErrorCode {
    2. public static final int LE_SUCCESS = 0;
    3. public static final int LE_ERROR_UNKNOWN = 100000;
    4. public static final int LE_ERROR_INVALID_PARAM = 100001;
    5. public static final int LE_ERROR_TIMEOUT = 100006;
    6. public static final int LE_ERROR_PARAM_RANGE_OVERFLOW = 100007;
    7. public static final int LE_ERROR_SERVICE_UNREACHABLE = 100008;
    8. public static final int LEDA_ERROR_DEVICE_UNREGISTER = 109000;
    9. public static final int LEDA_ERROR_DEVICE_OFFLINE = 109001;
    10. public static final int LEDA_ERROR_PROPERTY_NOT_EXIST = 109002;
    11. public static final int LEDA_ERROR_PROPERTY_READ_ONLY = 109003;
    12. public static final int LEDA_ERROR_PROPERTY_WRITE_ONLY = 109004;
    13. public static final int LEDA_ERROR_SERVICE_NOT_EXIST = 109005;
    14. public static final int LEDA_ERROR_SERVICE_INPUT_PARAM = 109006;
    15. public static final int LEDA_ERROR_INVALID_JSON = 109007;
    16. public static final int LEDA_ERROR_INVALID_TYPE = 109008;
    17. private static final String LE_SUCCESS_MSG = "Success"; /* 请求成功*/
    18. private static final String LE_ERROR_INVALID_PARAM_MSG = "Invalid params"; /* 传入参数为NULL或无效*/
    19. private static final String LE_ERROR_TIMEOUT_MSG = "Tiemout"; /* 超时*/
    20. private static final String LE_ERROR_PARAM_RANGE_OVERFLOW_MSG = "Param range overflow"; /* 参数范围越界*/
    21. private static final String LE_ERROR_SERVICE_UNREACHABLE_MSG = "Service unreachable"; /* 服务不可达*/
    22. private static final String LEDA_ERROR_DEVICE_UNREGISTER_MSG = "Device has't register"; /* 设备未注册*/
    23. private static final String LEDA_ERROR_DEVICE_OFFLINE_MSG = "Device has offline"; /* 设备已下线*/
    24. private static final String LEDA_ERROR_PROPERTY_NOT_EXIST_MSG = "Property no exist"; /* 属性不存在*/
    25. private static final String LEDA_ERROR_PROPERTY_READ_ONLY_MSG = "Property only support read"; /* 属性只读*/
    26. private static final String LEDA_ERROR_PROPERTY_WRITE_ONLY_MSG = "Property only support write"; /* 属性只写*/
    27. private static final String LEDA_ERROR_SERVICE_NOT_EXIST_MSG = "Service no exist"; /* 服务不存在*/
    28. private static final String LEDA_ERROR_SERVICE_INPUT_PARAM_MSG = "Service param invalid"; /* 服务的输入参数不正确错误码*/
    29. private static final String LEDA_ERROR_INVALID_JSON_MSG = "Json format invalid"; /* JSON格式错误*/
    30. private static final String LEDA_ERROR_INVALID_TYPE_MSG = "Param type invalid"; /* 参数类型错误*/
    31. }
  • Java方法说明:| 限定符和类型 | 方法和说明 || :—- | :—- || String | getMessage(int code)获取错误码对应的消息。 |