Skip to content

设备通信

概述

联网功能组件 是基础通信组件,设备和云端通信,APP 和云端通信,或者 APP 和设备之间相互通信都可以通过这个组件的 API 来实现。

组件功能点:

  • 设备查询所属产品信息
  • 设备和云端建立通道
  • 设备与云端通信
  • 设备发送数据到 APP

说明:本文档是从业务使用场景的角度说明云端提供的各服务接口,方便开发者迅速了解各接口功能点,以及在什么场景下使用哪些接口。

前置条件

设备已经链接互联网,配网方式请开发者自行研发,比如可以通过网口,或者直接固化 WiFi 信息等。

Note

注意使用 websocket 或者 TCP 方式 请求体后末尾添加一个"\n"换行符,否则会得到 timeout 的结果。

getProdInfo

设备真正链接服务器进行数据发送接收之前,需要先通过链接调度服务器查询链接地址,获取到设备当前所处地域最佳链接地址,以达到最佳稳定通信效果,所以不建议设备固件写死下面的地址。 如果使用氦氪固件或氦氪嵌入式SDK,您并不需要关注这些细节,固件和SDK会封装好。

通信链接调度服务地址

地址 功能 协议 数据安全级别 服务区域
info.hekr.me:91 产品信息查询服务 TCP 非SSL 全球

结果说明

  • 从应答里解析出serviceHost和servicePort,得到连接的目标地址。
  • 从应答里解析出connectType,决定建立tcp长连接还是websocket长连接。
  • 从应答里解析出encryptType,决定使用非加密还是加密通道。
  • 确定以上信息后,和云端建立真正的连接。

请求参数说明

请求参数说明

参数 必填 说明
msgId 0-65535 消息 id
action getProdInfo 固定为 getProdInfo
params.devTid 设备地址
params.prodKey 产品密钥 产品密钥 ,可以从 console 的产品管理页面中找到

结果参数说明

参数 说明
msgId 0-65535 对应于请求中的 msgId 的值
action getProdInfoResp 固定为 getProdInfoResp
mid 产品标志
workMode
tokenType 1,2 1:静态,2:动态。 静态 token 就是一旦生成,永久不变,DYNAMI 每次登录都需要更换,已经废弃,用户现在无需关心这个字段,只需要将第一次获取到的 token 永久保存,登录的时候携带即可。
serviceHost 设备发起通信链接的主机地址
servicePort 设备发起通信链接的端口
connectType 通信协议,上面提到的 http,tcp 或者 websocket 中的一种
encryptType 加密类型,None,无加密,SSL则是 ssl 方式加密
code 详见下面错误码 错误说明,200 ok,其他参见下表

错误码

错误码 提示信息 中文释义 可能造成的原因
9200000 Success 调用成功
9400000 Error 未知错误 该行以下所有9400开头的错误码需要单独处理
9400001 Bad param 非法参数
9400002 Action does not exist action不存在
9400003 Product does not exist 产品不存在
9400004 Time out 超时
9400005 Method not support 方法不支持
9500000 Server error 服务错误
9500001 Server response error 服务应答错误

通过TCP协议

请求地址: tcp://info.hekr.me:91

请求体

Note

注意请求体后末尾添加一个"\n"换行符

{
  "msgId": 90,
  "action": "getProdInfo",
  "params": {
    "devTid": "TEST_DEV001",
    "prodKey": "test_prod_key"
  }
}

返回体

{
  "msgId": 90,
  "action": "getProdInfoResp",
  "code": 200,
  "desc": "success",
  "params": {
    "mid": "test_mid",
    "workMode": 1,
    "tokenType": 2,
    "serviceHost": "host",
    "servicePort": 83,
    "encryptType": "None",
    "connectType": "tcp"
  }
}

TCP调试

主流编程语言或者平台(Java、Python、NodeJS、PHP等)都有提供TCP开发包(即Socket开发包),开发者可以在命令行工具中通过“telnet”命令来调试TCP接口。

调试步骤如下:

  1. 在命令行工具输入:telnet info.hekr.me 91
  2. 输入请求参数:{"msgId" : 90,"action" : "getProdInfo","params" : {"devTid" : "TEST_DEV001","prodKey" : "0126736378c6ba606ca72d9"}}
  3. 回车。
  4. 查看服务器返回结果。

通信地址

Info

所有请求消息、返回以换行("\n")分割,文档中为了美观将json以缩进换行表示,实际调用中JSON体内不换行,仅在消息末尾换行。通信数据格式需要根据产品接入协议编写,详细信息参见产品接入协议

地址 功能 协议 数据安全级别 服务区域
hub.hekr.me:83 设备<->云端通道 TCP长连接 非SSL 亚太
hub.hekr.me:183 设备<->云端通道 TCP长连接 SSL 亚太
hub.hekr.me:84 设备<->云端通道 WebSocket长连接 非SSL 亚太
hub.hekr.me:184 设备<->云端通道 WebSocket长连接 SSL 亚太
fra-hub.hekreu.me:83 设备<->云端通道 TCP长连接 非SSL 欧洲
fra-hub.hekreu.me:183 设备<->云端通道 TCP长连接 SSL 欧洲
fra-hub.hekreu.me:84 设备<->云端通道 WebSocket长连接 非SSL 欧洲
fra-hub.hekreu.me:184 设备<->云端通道 WebSocket长连接 SSL 欧洲
va-hub.hekrus.me:83 设备<->云端通道 TCP长连接 非SSL 北美东部+南美
va-hub.hekrus.me:183 设备<->云端通道 TCP长连接 SSL 北美东部+南美
va-hub.hekrus.me:84 设备<->云端通道 WebSocket长连接 非SSL 北美东部+南美
va-hub.hekrus.me:184 设备<->云端通道 WebSocket长连接 SSL 北美东部+南美
ca-hub.hekrus.me:83 设备<->云端通道 TCP长连接 非SSL 北美西部+南美
ca-hub.hekrus.me:183 设备<->云端通道 TCP长连接 SSL 北美西部+南美
ca-hub.hekrus.me:84 设备<->云端通道 WebSocket长连接 非SSL 北美西部+南美
ca-hub.hekrus.me:184 设备<->云端通道 WebSocket长连接 SSL 北美西部+南美

devBind

用户要想控制设备,必须将用户和设备绑定,这样该用户才能拥有该设备的控制权,该用户也被称为设备属主。 设备绑定成功后无需再调用 devLogin 进行设备登录操作。

{
  "msgId" : 123,
  "action" : "devBind",
  "params" : {
      "devTid" : "ESP_34ABE",
      "prodKey" : "0cc175b9c0f1b6a831c399e269772661",
      "PINCode" : "1234",
      "SSID" : "HEKR",
      "token" : "" , //首次配网填空,其他情况填设备端保存的token
      "zoneOffSet":480 // 时区偏移量,比如北京+8*60=480,则填写480,如果该参数不填写,则不会返回下面应答中的timeInfo信息,一般情况下不需要该参数,如果设备需要校准时间可以使用该参数
  }
}

参数说明

参数 必填 说明
action 固定位 devBind
devTid 设备地址
prodKey 可以在console 控制台产品中心查看
PINCode 校验码,用户通过 获取 PINCode 接口获取
SSID 当前 WIFI ssid
token 设备第一次登录或者绑定,填写空,以后必须用云端返回的这个 token 进行登录或者绑定
{
    "msgId": 123,
    "action": "devBindResp",
    "code": 200,
    "desc": "success",
    "params": {
        "devTid": "ESP_34ABE",
        "token": "4a8a08f09d37b737956490",
        "ctrlKey": "20005c97f94aff9d7ff8",
        "bindKey": "92eb5ffee6ae2fec3ad7",
        "timeInfo": { // 如果想要返回该参数,则请求的时候需要带上 zoneOffSet 参数
            "timestamp": 1521467915917,
            "year": 2018,
            "month": 2, // 0开始,1月份是0,以此类推
            "day": 19,
            "hour": 21,// 24小时制
            "minute": 58,
            "second": 35,
            "millisecond": 917,
            "dayOfWeek": 2,
            "dayOfYear": 78,
            "weekOfMonth": 4,
            "weekOfYear": 12,
            "zoneOffSet": 480, // 传入的时区偏移量
            "serverZoneOffSet": 480 // 服务器所在时区偏移量
        }
    }
}

返回体

字段 含义
params.token 新的设备token。设备下次再和云端建立通道时,务必使用这个新token,否则有可能导致设备被锁。
params.ctrlKey 控制码。APP远程控制设备时,必须使用这个key。
params.bindKey 绑定码。APP绑定、解绑设备时,必须使用这个key。

devLogin

该指令用于设备和云端建立连接,支持 tcp 和 websocket 长连接方式,方式的选择在 getProdInfo 接口调用时确定。

{
  "msgId" : 123,
  "action" : "devLogin",
  "params" : {
      "devTid" : "ESP_34ABE",
      "prodKey" : "0cc175b9c0f1b6a831c399e269772661",
      "token" : "4a8a08f09d37b737956490",    // 设备第一次联网时填""
      "zoneOffSet":480 // 时区偏移量,比如北京+8*60=480,则填写480,如果该参数不填写,则不会返回下面应答中的timeInfo信息,一般情况下不需要该参数,如果设备需要校准时间可以使用该参数
  }
}
{
  "msgId" : 123,
  "action" : "devLoginResp",
  "code" : 200,
  "desc" : "success",
  "params" : {
      "devTid" : "ESP_34ABE",
      "token" : "4a8a08f09d37b737956490",   // 新的设备token
      "ctrlKey" : "20005c97f94aff9d7ff8",
      "bindKey" : "92eb5ffee6ae2fec3ad7",
      "forceBind" : true,
      "timeInfo": { // 如果想要返回该参数,则请求的时候需要带上 zoneOffSet 参数
            "timestamp": 1521467915917,
            "year": 2018,
            "month": 2,
            "day": 19,
            "hour": 21,
            "minute": 58,
            "second": 35,
            "millisecond": 917,
            "dayOfWeek": 2,
            "dayOfYear": 78,
            "weekOfMonth": 4,
            "weekOfYear": 12,
            "zoneOffSet": 480,
            "serverZoneOffSet": 480
        }
  }
}

返回体

字段 含义
params.token 新的设备token,设备下次再和云端建立通道时,务必使用这个新token,否则有可能导致设备被锁。
params.ctrlKey 控制码。APP远程控制设备时,必须使用这个key。
params.bindKey 绑定码。APP绑定、解绑设备时,必须使用这个key。

设备第一次和云端建立通道时,token填写空字符串"",表示新设备。

requestVerify

该指令用于网关和云端建立连接并进行初步校验,支持 tcp 和 websocket 长连接方式。

{
  "msgId" : 123,
  "action" : "requestVerify",
  "params" : {
      "devTid" : "ESP_34ABE",
      "prodKey" : "0cc175b9c0f1b6a831c399e269772661",
  }
}
{
  "msgId" : 123,
  "action" : "requestVerifyResp",
  "code" : 200,
  "desc" : "success",
  "params" : {
      "randomKey" : "534a2dfd20e24db2acd548c81449b3e8"
    }
  }
}

返回体

字段 含义
params.randomKey 32字节,用于网关登录校验,参见下面的gatewayLogin指令

gatewayLogin

该指令用于网关登录云端,支持 tcp 和 websocket 长连接方式。该指令有两种数据格式,需要根据产品高级设置中的【二次验证】配置来进行上报数据。

如果开启了二次验证(默认),则第一步需要上面的 requestVerify 指令,拿到 randomKey 后进行编码,得到 authKey,编码方式为:

authKey = MD5(randomKey+devTid+devPrivKey),以 devTid=ESP_34ABE,prodKey=0cc175b9c0f1b6a831c399e269772661,devPrivKey=3e9c0dfeb25b4861b2c9b4f33033fca3为例:

authKey=MD5("ESP_34ABE0cc175b9c0f1b6a831c399e2697726613e9c0dfeb25b4861b2c9b4f33033fca3")(仅引号中间的值参与运算)=34193d9b7924b564c0ba0e5aa1373c58
{
  "msgId" : 123,
  "action" : "gatewayLogin",
  "params" : {
      "devTid" : "ESP_34ABE",
      "prodKey" : "0cc175b9c0f1b6a831c399e269772661",
      "authKey" : "34193d9b7924b564c0ba0e5aa1373c58"
  }
}

如果关闭了二次验证,则 authKey 也相应的去掉,示例如下:

{
  "msgId" : 123,
  "action" : "gatewayLogin",
  "params" : {
      "devTid" : "ESP_34ABE",
      "prodKey" : "0cc175b9c0f1b6a831c399e269772661"
  }
}
{
  "msgId" : 123,
  "action" : "gatewayLoginResp",
  "code" : 200,
  "desc" : "success"
}

设备上报固件 WIFI 等信息

该指令用于设备向云端上报基本设备信息,这些信息包括固件信息,路由器信息的,在设备登录到云端的时候会主动调用此接口上报设备信息。注意 reportDevInfodevSend 的区别。

{
  "msgId" : 291,
  "action" : "reportDevInfo",
  "params" : {                                        // 字段可扩展
      "devTid" : "ESP_4387EF",
      "mid" : "0cc175b9c0f1",
      "workMode" : 0,
      "MAC" : "08EFA809DE6D",                         // 设备MAC地址
      "tokenType" : 2,
      "binVer" : "3.0.61.2",                          // 固件版本
      "binType" : "A",                                // 固件类型
      "SDKVer" : "3.0.61.2",                          // 固件SDK版本
      "serviceHost" : "hub.hekr.me",             // 服务器地址
      "servicePort" : 83,                             // 服务器端口
      "SSID" : "HEKR-TEST"                            // 路由器SSID
  }
}
{
  "msgId" : 291,
  "action" : "reportDevInfoResp",
  "code" : 200,
  "desc" : "success"
}

devSend

该指令是上报设备所属产品在 Console 上配置的协议模板中的命令和参数。当设备状态改变的时候,应该发送 devSend,比如灯泡亮度改变,应该立即发送一个指令消息到云端,这样云端就会将该指令转发给 app,如果 app 在线,会立即更改亮度的数值。

devSend (JSON主控)

{
  "msgId" : 382,
  "action" : "devSend",
  "params" : {
      "devTid" : "ESP_2M_245EC89",
      "appTid" : [],
      "data" : {
          "cmdId" : 9,
          "key1" : "value1",
          "key2" : "value2",
      }
  }
}
{
  "msgId" : 382,
  "action" : "devSendResp",
  "code" : 200,
  "desc" : "success"
}

请求体

字段 是否必须 含义
params.devTid 设备devTid
params.appTid 希望转发的appTid 暂时只支持转发到所有APP,appTid为[]
params.data.cmdId 命令ID
params.data.key1 自定义键值对1
params.data.key2 自定义键值对2

cmdId, key1, key2 这些值可以在 氦氪云控制台-产品管理-产品协议-命令-示例帧 查看它们的使用方法

devSend (JSON透传)

{
  "msgId" : 382,
  "action" : "devSend",
  "params" : {
    "devTid" : "ESP_2M_245EC89",
    "appTid" : [],
    "data" : {
        "raw" : "48EFDFAB"
    }
  }
}
{
    "msgId" : 382,
    "action" : "devSendResp",
    "code" : 200,
    "desc" : "success"
}

请求体

字段 是否必须 含义
params.devTid 设备devTid
params.appTid 希望转发的appTid 暂时只支持转发到所有APP,appTid为[]
params.data.cmdId 命令ID
params.data.raw 透传数据

raw 值可以在 氦氪云控制台-产品管理-产品协议-命令-示例帧 查看它们的使用方法

devSend (48透传)

48EFDFAB

值可以在 氦氪云控制台-产品管理-产品协议-命令-示例帧 查看它们的使用方法

heartbeat

注意

如果30秒内云端没有收到任何数据,则会主动断开连接,所以设备、APP必须定时发送心跳指令来保持连接。

{
  "msgId" : 98,
  "action" : "heartbeat"
}
{
  "msgId" : 98,
  "action" : "heartbeatResp",
  "code" : 200,
  "desc" : "success"
}

appSendResp

该指令用于回复 app 下发的控制指令 appSend。如果设备成功收到消息并且执行成功,那么应该立即发送该指令。参数中应该返回当前设备的状态,期望回应的参数值应该和 appSend 的参数值一样。

{
  "msgId" : 291,
  "action" : "appSendResp",
  "code" : 200,
  "desc" : "success",
  "params" : {
      "devTid" : "ESP_2M_245EC89",
      "ctrlKey" : "123456789123456789",
      "appTid" : "54354353454",
      "data" : {
          "cmdId" : 0,
          "raw":  "0F2CABDEG",
          "customKey" : 0
      }
  }
}

getTimerList

该指令用于设备获取云端的定时任务列表。

指令格式:

{
    "msgId" : 291,
    "action" : " getTimerList",
    "params" : {
        "devTid" : "ESP_245EC89",   //  设备唯一id
        "taskFormat" : "single",     //  定时任务应答格式:single:task数量逐条回复,listtask以数组返回。  默认list
        "timeFormat" : " countdown "   //  定时时间应答格式: cronexpr:cron表达式;countdown倒计时。  默认countdown
    }
}

应答格式: single 任务格式:

// 第一条任务
{
    "msgId": 291,//保持一致
    "action": "getTimerListResp",
    "code": 200,
    "desc": "success",
    "params": {
        "tasksCount": 2,//任务数量
        "taskList": [
            {
                "taskId": 1952511811,   // 预约任务编号,int32
                "delayTime": 248,       // 延时时间,单位秒(s),最大3600s
                "count": 3,           // 循环执行次数,1表示执行一次、n表示执行n次(间隔为looptime)
                "loopTime": 600,         // 循环时间间隔,单位秒(s)
                "task": {
                    "cmdId": 1,
                    "k1": "v1"
                }                       //执行代码,通常为appSend中data部分
            }
        ]
    }
}

// 第二条任务
{
    "msgId": 291,//保持一致
    "action": "getTimerListResp",
    "code": 200,
    "desc": "success",
    "params": {
        "tasksCount": 2,//任务数量
        "taskList": [
            {
                "taskId": 1958890357,//预约任务编号,int32
                "delayTime": 248,//延时时间,单位秒(s),最大3600s
                "count": 3,//循环执行次数,1表示执行一次、n表示执行n次(间隔为looptime)
                "loopTime": 600,//循环时间间隔,单位秒(s)
                "task": {
                    "cmdId": 1,
                    "k1": "v1"
                }//执行代码,通常为appSend中data部分
            }
        ]
    }
}

list 任务格式:

{
    "msgId": 291,
    "action": "getTimerListResp",
    "code": 200,
    "desc": "success",
    "params": {
        "tasksCount": 2,//任务数量
        "taskList": [
            {
                "taskId": 1952511811,//预约任务编号,int32
                "delayTime": 305,//延时时间,单位秒(s),最大3600s
                "count": 3,//循环执行次数,1表示执行一次、n表示执行n次(间隔为looptime)
                "loopTime": 600,//循环时间间隔,单位秒(s)
                "task":  {"raw":"4808020122115533"} //执行代码,根据APP添加,通常为appSend消息体中data部分
            },
            {
                "taskId": 1958890357,
                "delayTime": 1505,
                "count": 1,
                "loopTime": 0,
                "task":  {"raw":"4808020122115533"}
            }
        ]
    }
}

timerReport

定时任务执行完后上报结果 指令格式:

{
    "msgId" : 291,
    "action" : "timerReport",
    "params" : {
    "devTid" : "ESP_245EC89",
        "taskId" : 1,                       //预约任务编号,int32
        "task" : {"raw":"4808020122115533"},  //对应appSendResp中data部分:透传时为MCU应答帧内容。
        "code" : 200                         //表示任务已经触发
    }
}

应答格式:

{
    "msgId" : 291,
    "action" : "timerReportResp",
    "code" : 200,
    "desc" : "success"
}

devSync

该指令用于云端要求设备同步信息,例如同步定时计划任务。设备接收到该指令后会自动调用getTimerList指令同步一次定时计划任务。具体流程参考4.x定时设计方案。

指令格式:

{
    "msgId" : 291,
    "action" : "devSync",
    "params" : {
        "ctrlKey" : "123456789ABCDE" // 设备控制码
    }
}

应答格式

{
    "msgId" : 291,
    "action" : "devSyncResp",
    "code" : 200,
    "desc" : "success"
}

错误码表

错误码 提示信息 中文释义 可能造成的原因
1200000 Success 调用成功
1400000 Error 未知错误 该行以下所有1400开头的错误码需要单独处理
1400001 Json parse error json解析错误 json格式错误
1400002 JWT parse error jwt_token解析错误 jwt token错误
1400003 The field {0} contains a value that is too high 属性值过高 发送报文中某属性的值超过了其上限
1400004 The field {0} contains a value that is too low 属性值过低 发送报文中某属性的值低于了其下限
1400005 The value of the field {0} must be an enumerated value 属性值必须为范围内枚举值 发送报文中某属性值不符合其定义的取值范围
1400006 Field not exist 属性不存在 发送报文中存在了未定义的属性
1400008 devTid not match 设备ID不匹配 报文填写的devTid与登录设备的devTid不一致
1400009 App repeat login APP重复登录 同一个appTid的app重复登录
1400010 User does not exist 用户不存在 用户不存在或者uid填错了
1400011 The device does not have this instruction 设备不具有该指令 设备不具备该指令
1400012 Device does not belong to user 设备不属于该用户 设备不再属于该用户
1400013 Device repeat login 设备重复登录 设备同时登录
1400014 Frame parse error 帧解析错误 报文格式或内容错误
1400015 Device last token can not use 设备上一次token已过期无法使用 使用的旧token已经超过上限
1400016 Action not support 该帧行为不被支持 报文中的action填错了
1400017 Device token can not verification 设备token校验错误 设备token错误
1400018 Device not online 设备不在线 设备离线
1400019 App is not logged in app未登录 app未登录或其他原因导致云端认为app已经离线
1400020 Device is not logged in 设备未登录 设备未登录或其他原因导致云端认为设备已经离线
1400022 The device is not found 找不到指定(devTid)设备 当前产品下不存在该设备
1400023 appTid does not match app设备id不匹配 当前发送报文的appTid与绑定设备时的appTid不一致
1400024 You report info does not match your connect server 上报节点信息与实际不符 上报的内容与当时连接节点信息不一致
1400025 RAW not valid, Please check your protocol template 协议不合法,请参照协议模板 48协议串不合法
1400026 AuthKey can't auth authKey 认证失败 填写了错误的authkey
1400027 Product key not available 不是有效的pk 填写了错误的pk
1400028 PinCode or SSID not available pinCode或者ssid无效 填写了无效的pinCode或者ssid
1400029 Bind failed due to timeout error 绑定设备超时错误 绑定设备超时
1400030 Can not bind other manufacture's device 无法绑定其它厂商的设备 APP绑定了非该厂家的设备
1400039 Device license can not verification 设备license不合法 请填写正确的license
1400031 Can not force bind device 无法强绑设备 设备设定为无法强绑,强绑失败
1400032 Invalid Param 参数不合法 协议参数不合法
1400040 frame payload error 帧内容校验失败 可能帧内容或者求和不对
1500000 Internal error 内部错误 服务内部错误
1500001 Link error 链路错误 链路错误