APP通信
说明¶
所有请求消息、返回以换行("\n")分割,文档中为了美观将json以缩进换行表示,实际调用中JSON体内不换行,仅在消息末尾换行。
获取API主域名地址¶
hekr云支持全球化访问和控制设备,为了获得良好的网络体验,在使用api之前必须先获取app(用户)最近的服务中心信息,并由此调用对应数据中心的api。
获取数据中心信息的服务由 info.hekr.me:91
统一提供服务,同时也提供了设备查询信息,都是通过 tcp
方式获取的。建立tcp连接后发送如下信息:
{"action":"getAppDomain"}
会返回如下相应信息:
{"dcInfo":{"opTimestamp":1519440536598,"fromDC":"gz","dc":"gz","area":"asia","fromArea":"asia","domain":"hekr.me"},"msgId":0,"action":"getAppDomainResp","code":200,"desc":"success"}
参数 | 说明 |
---|---|
dc | 开发者无需关心 |
fromDC | 开发者无需关心 |
area | 开发者无需关心 |
fromArea | 开发者无需关心 |
domain | 调用api应该使用的域名,国内:hekr.me,美洲:hekrus.me,欧洲:hekreu.me |
code | 错误码,200正常 |
desc | 错误描述 |
用户在调用api的时候只需要关心 domain
参数,以登录接口为例,如果调用 info.hekr.me
返回的 domain
是 hekrus.me
,则说明是北美的(app/手机检测到是在北美),那么应该调用接口 https://uaa-openapi.hekrus.me/login
,而不是 https://uaa-openapi.hekr.me/login
,注意域名的区别。同理,其他api也要这样动态拼接。
如果您不需要全球化,只服务一个地方,也可以固定域名,但是为了方便扩展,推荐使用上述方式来调用api。
服务地址¶
全球化的hekr提供了多数据中心服务(其他正在建设中),以下是现有数据中心app连接地址。当app要控制设备的时候,app需要连接到设备所在数据中心的地址,不能随便选一个地址连接。
那么怎么知道设备在哪个数据中心呢?在设备列表中会有一个 dcInfo
字段,这个字段的结构如下:
{
"opTimestamp": 1517930387464,
"fromDC": "gz",
"dc": "gz",
"area": "asia",
"fromArea": "asia",
"connectHost": "hub.hekr.me"
}
字段说明
参数 | 说明 |
---|---|
opTimestamp | 用户无需关心 |
dc | 用户无需关心 |
fromDC | 用户无需关心 |
area | 用户无需关心 |
fromArea | 用户无需关心 |
connectHost | app 如果要控制设备,应该域名(注意没有端口,需要根据下面表格中的协议选择对应端口) |
app控制设备的时候,真正用到的只是 connectHost
这个字段,其余作为参考和日志调试即可。比如拉取设备列表,点击这个设备要进行控制的时候,发现 connectHost
是 ca-hub.hekrus.me
,则说明app应该连接 ca-hub.hekrus.me
这个地址,端口根据对应的连接方式选择。
地址 | 功能 | 协议 | 数据安全级别 | 服务区域 |
---|---|---|---|---|
hub.hekr.me:85 | APP<->云端通道 | TCP长连接 | 非SSL | 亚太 |
hub.hekr.me:185 | APP<->云端通道 | TCP长连接 | SSL | 亚太 |
hub.hekr.me:86 | APP<->云端通道 | WebSocket长连接 | 非SSL | 亚太 |
hub.hekr.me:186 | APP<->云端通道 | WebSocket长连接 | SSL | 亚太 |
fra-hub.hekreu.me:85 | APP<->云端通道 | TCP长连接 | 非SSL | 欧洲 |
fra-hub.hekreu.me:185 | APP<->云端通道 | TCP长连接 | SSL | 欧洲 |
fra-hub.hekreu.me:86 | APP<->云端通道 | WebSocket长连接 | 非SSL | 欧洲 |
fra-hub.hekreu.me:186 | APP<->云端通道 | WebSocket长连接 | SSL | 欧洲 |
va-hub.hekrus.me:85 | APP<->云端通道 | TCP长连接 | 非SSL | 北美东部+南美 |
va-hub.hekrus.me:185 | APP<->云端通道 | TCP长连接 | SSL | 北美东部+南美 |
va-hub.hekrus.me:86 | APP<->云端通道 | WebSocket长连接 | 非SSL | 北美东部+南美 |
va-hub.hekrus.me:186 | APP<->云端通道 | WebSocket长连接 | SSL | 北美东部+南美 |
ca-hub.hekrus.me:85 | APP<->云端通道 | TCP长连接 | 非SSL | 北美西部+南美 |
ca-hub.hekrus.me:185 | APP<->云端通道 | TCP长连接 | SSL | 北美西部+南美 |
ca-hub.hekrus.me:86 | APP<->云端通道 | WebSocket长连接 | 非SSL | 北美西部+南美 |
ca-hub.hekrus.me:186 | APP<->云端通道 | WebSocket长连接 | SSL | 北美西部+南美 |
appLogin¶
用户使用已注册账号调用云端 login 接口登录 APP 后会返回一个 token,APP 会使用这个 token 主动调用云端提供的 appLogin 接口建立通道, 云端获取到 appTid 之后可以知道 app 在线状态。
注:token 有效期为12小时。如果APP和云端建立通道前 token 已过期,云端会提示 token 无效; 如果联网之后连接不断,即使 token 过期,APP 还能继续控制设备。
请求¶
{
"msgId" : 240,
"action" : "appLogin",
"params" : {
"appTid" : "35897387434734",
"token" : "eyJhbGc..."
}
}
参数¶
字段 | 是否必须 | 含义 |
---|---|---|
params.token | 是 | 新的设备token,设备下次再和云端建立通道时,务必使用这个新token,否则有可能导致设备被锁。 |
appTid | 是 | app唯一标识,建议使用 UUID |
响应¶
{
"msgId" : 240,
"action" : "appLoginResp",
"code" : 200,
"desc" : "success"
}
指令格式中的参数token,是APP调用登录接口,如果APP和云端建立通道前token已过期,云端会提示token无效;如果联网之后连接不断,即使token过期,APP还能继续控制设备。
heartbeat¶
由于云端30秒没有收到数据会主动和 APP 断开连接,所以 App 为了保持和云端的长连接,需要周期性的发送心跳请求。
指令格式:
{
"msgId" : 98,
"action" : "heartbeat"
}
{
"msgId" : 98,
"action" : "heartbeatResp",
"code" : 200,
"desc" : "success"
}
appSend¶
该指令用于控制设备。如果设备成功接收消息,那么设备会进行回应,app 会收到 action 为 appSendResp
的指令,除了 action 和发送时候不一样中外,其余参数和发送的指令的参数一样。 appSendResp
仅仅代表设备成功接收消息,并且理解这个消息的内容,至于设备有没有动作,这个要看 appSend 之后设备的当前状态,如果和预期一样则说明控制成功,否则失败。所以成功与否在于设备的执行,而不是云端。
appSend (JSON主控)¶
{
"msgId" : 291,
"action" : "appSend",
"params" : {
"devTid" : "ESP_2M_245EC89",
"ctrlKey" : "123456789123456789",
"appTid" : "54354353454",
"data" : {
"cmdId" : 0,
"customKey" : 0
}
}
}
{
"msgId" : 291,
"action" : "appSendResp",
"code" : 200,
"desc" : "success",
"params" : {
"devTid" : "ESP_2M_245EC89",
"ctrlKey" : "123456789123456789",
"appTid" : "54354353454",
"data" : {
"cmdId" : 0,
"raw": "0F2CABDEG",
"customKey" : 0
}
}
}
请求体¶
字段 | 是否必须 | 含义 |
---|---|---|
params.devTid | 是 | 设备devTid |
params.ctrlKey | 是 | 设备ctrlKey |
params.subDevTid | 是 | 子设备subDevTid,子设备控制时使用 |
params.appTid | 是 | app唯一标识 |
params.data.cmdId | 是 | 命令ID |
params.data.customKey | 否 | 自定义key,可以指定多个键值对 |
cmdId, customKey这些值可在氦氪云控制台-产品管理-产品协议-命令上查看它们的具体定义。 指令和应答里的customKey不一定是完全一致的,因为下发指令值是期望值,应答里的值设备的实际返回,可能会因为溢出等原因导致不一致。
发送数据到设备(JSON透传)¶
{
"msgId" : 291,
"action" : "appSend",
"params" : {
"devTid" : "ESP_2M_245EC89",
"ctrlKey" : "123456789123456789",
"appTid" : "358974675345",
"data" : {
"raw" : "48EF4DFA"
}
}
}
{
"msgId" : 291,
"action" : "appSendResp",
"code" : 200,
"desc" : "success",
"params" : {
"devTid" : "ESP_2M_245EC89",
"ctrlKey" : "123456789123456789",
"appTid" : "358974675345",
"data" : {
"raw" : "48EF4DFA"
}
}
}
发送数据到设备(网关JSON主控)¶
{
"msgId" : 291,
"action" : "appSend",
"params" : {
"devTid" : "ESP_2M_245EC89",
"ctrlKey" : "123456789123456789",
"subDevTid" : "sub_dev_tid",
"appTid" : "358974675345",
"data" : {
"cmdId" : 1,
"power" : 2
}
}
}
{
"msgId" : 291,
"action" : "appSendResp",
"code" : 200,
"desc" : "success",
"params" : {
"devTid" : "ESP_2M_245EC89",
"ctrlKey" : "123456789123456789",
"appTid" : "358974675345",
"data" : {
"raw" : "48EF4DFA"
}
}
}
请求体¶
字段 | 是否必须 | 含义 |
---|---|---|
params.devTid | 是 | 设备devTid |
params.ctrlKey | 是 | 设备ctrlKey |
params.subDevTid | 是 | 子设备subDevTid,子设备控制时使用 |
params.appTid | 是 | app唯一标识 |
params.data.raw | 是 | 透传数据 |
raw的具体格式,可参考氦氪云控制台-产品管理-产品协议-命令-示例帧。
错误码表¶
错误码 | 提示信息 | 中文释义 | 可能造成的原因 |
---|---|---|---|
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 | 链路错误 | 链路错误 |