# 5. 接口文档(v2)

# 5.1 通用说明

# 5.1.1 请求域名

线上请求域名:https://api-prod.smartmidea.net

# 5.1.2 请求说明

请求ID说明:请求ID长度为32位,由数字和字母组成,不能带有#和*等特殊字符

# 5.1.3 返回说明

接口返回值说明: 授权相关接口遵循标准OAuth 2.0授权规范,所有请求返回遵循HTTP请求状态的Http状态编码,在HTTP Status Code不为200的时候才返回相对应的错误提示

HTTP状态码说明

HTTP Status Code 描述
200 OK
409 业务异常
4xx 请求错误,参考http请求返回标准状态码
500 服务器异常

返回结果

字段 类型 说明
error String 错误码
error_description String 错误提示

返回示例

{
    "error": "1000",
    "error_description": "system error"
}

# 5.2 授权相关

# 5.2.1 获取授权页

接口说明: 根据颁发的clientId返回相应的授权登录页面,获取美居标准授权需要用OAuth2授权方式,目前只支持response_type=code

请求协议: HTTPS

请求方式: GET

请求地址: /v2/open/oauth2/authorize

参数格式: query 参数

请求参数

字段 必选 类型 说明
client_id true String 唯一的第三方开发者ID
state true String 请求授权方的校验字段,授权服务透传原值返回
response_type true String 授权类型
code - 授权码方式
redirect_uri true String 重定向 URI,需要与应用创建时回调url保持一致

请求示例

/v2/open/oauth2/authorize?client_id=client_id********************1234&state=1&response_type=code&redirect_uri=************************

返回结果

返回登录页面,让用户输入用户名、密码

返回示例

登录页面

登录返回uri示例

redirect_uri?code=h4GJTCPEb***********************&state=1

错误码说明

error 说明
1000 未知系统错误
1002 参数非法
1009 开发者账号不存在
1100 短信验证码不合法

# 5.2.2 获取令牌

接口说明: 该接口获取或刷新AccessToken,如需要做消息订阅,则调用此接口获取令牌后必须调用文档2.1接口做用户绑定

请求协议: HTTPS

请求方式: POST

请求地址: /v2/open/oauth2/token

参数格式: body 参数

请求参数

字段 必选 类型 说明
client_id true String 唯一的第三方开发者ID
client_secret true String 第三方开发者密钥
grant_type false String 使用的授权模式,获取/刷新AccessToken分别传值如下。
获取:authorization_code
刷新:refresh_token
code false String 文档1.1接口调用后返回的授权码,grant_type为authorization_code时需要
refresh_token false String 上一步获得的refresh_token,grant_type为refresh_token时需要

请求示例

{
  "client_id": "client_id********************1234",
  "client_secret": "client_secret******************abcd",
  "grant_type": "authorization_code",
  "code": "code******************abcd"
}
{
"client_id": "client_id********************1234",
"client_secret": "client_secret******************abcd",
"grant_type": "refresh_token",
"refresh_token": "refresh_token****************abcdd"
}

返回结果

字段 类型 说明
access_token String 访问令牌
expires_in Integer 访问令牌有效期,目前有效期为24小时
单位:秒
refresh_token String 刷新令牌
token_type String 令牌类型,目前只支持bearer类型

返回示例

{
  "access_token": "access_token***************1234",
  "expires_in": 7200,
  "refresh_token": "refresh_token****************abcd",
  "token_type": "bearer"
}

错误码说明

error 说明
1000 未知系统错误
1001 redirect_uri解析失败
1002 参数非法
1003 服务返回解析失败
1004 服务调用失败
2001 非法开发者
2003 授权过程失败

# 5.3 用户相关

# 5.3.1 用户绑定

接口说明: 第三方提供给美的授权凭证与绑定用户,如需要做消息订阅,则此接口必须调用

请求协议: HTTPS

请求方式: POST

请求地址: /v2/open/user/accept

参数格式: body 参数

请求头

字段 必选 类型 说明
Authorization true String Bearer开头的访问令牌
例如:Bearer 0lemRvfLicjkHtno8r6wolAq8V7oLGe6
ClientId true String 唯一的第三方开发者ID
SignatureVersion true String 签名版本,默认值为2.0
Signature true String 签名摘要,签名方式请参照附录

请求参数

字段 必选 类型 说明
reqId true String 请求ID
stamp true String 请求时间戳,毫秒级区分
type false String 授权类型,授权码授权为:OAuth2.AuthorizationCode,客户端授权为:OAuth2.ClientCredentials,不授权为空,为空则不会提前获取令牌
thirdUid true String 第三方开放用户唯一标识
code false String 授权码,type为OAuth2.AuthorizationCode时需要传

请求示例

{
  "reqId": "fe8234bf-e94c-4cdf-8ea9-c3112962ab01",
  "stamp": "20181201160518000",
  "type": "0",
  "thirdUid": "cc225bbb3540f99dedef91eddd789609",
  "code": "code******************abcd"
}

返回结果

字段 类型 说明
reqId String 请求ID
openUid String 用户ID

返回示例

{
  "reqId": "fe8234bf-e94c-4cdf-8ea9-c3112962ab01",
  "openUid": "b3540cc225bbf99dd789609edef91edd"
}

错误码说明

error 说明
1000 未知系统错误
1002 参数非法
1003 ClientId校验失败或服务返回解析失败
1004 服务调用失败
1006 签名或用户验证失败
1009 开发者账号不存在
2001 非法开发者
2005 三方刷新令牌过期,无法刷新访问令牌
2006 无法从三方云平台获取oauth2令牌

# 5.3.2 获取用户基本信息

接口说明: 获取美居开放的用户信息以及家庭信息

请求协议: HTTPS

请求方式: POST

请求地址: /v2/open/user/get

参数格式: body 参数

请求头

字段 必选 类型 说明
Authorization true String Bearer开头的访问令牌
例如:Bearer 0lemRvfLicjkHtno8r6wolAq8V7oLGe6
ClientId true String 唯一的第三方开发者ID
SignatureVersion true String 签名版本,默认值为2.0
Signature true String 签名摘要,签名方式请参照附录

请求参数

字段 必选 类型 说明
reqId true String 请求ID
stamp true String 请求时间戳,毫秒级区分

请求示例

{
  "reqId": "fe8234bf-e94c-4cdf-8ea9-c3112962ab01",
  "stamp": "20181201160518000"
}

返回结果

字段 类型 说明
openUid String 美的用户ID
userName String 用户名称
homegroupList List 用户创建的家庭列表(不包含加入的家庭)
homegroupId Long 用户创建的家庭ID
homegroupName String 用户创建的家庭名字

返回示例

{
  "openUid": "b3540cc225bbf99dd789609edef91edd",
  "userName": "小明",
  "homegroupList": [{
    "homegroupId": 3121311,
    "homegroupName": "我的家1"
  }, {
    "homegroupId": 3121312,
    "homegroupName": "我的家2"
  }]
}

错误码说明

error 说明
1000 未知系统错误
1002 参数非法
1003 ClientId校验失败
1006 签名或用户验证失败
1009 开发者账号不存在
2001 非法开发者

# 5.3.3 用户取消授权

接口说明: 取消当前access token的授权

请求协议: HTTPS

请求方式: POST

请求地址: /v2/open/user/cancel

参数格式: body 参数

请求头

字段 必选 类型 说明
Authorization true String Bearer开头的访问令牌
例如:Bearer 0lemRvfLicjkHtno8r6wolAq8V7oLGe6
ClientId true String 唯一的第三方开发者ID
SignatureVersion true String 签名版本,默认值为2.0
Signature true String 签名摘要,签名方式请参照附录

请求参数

字段 必选 类型 说明
reqId true String 请求ID
stamp true String 请求时间戳,毫秒级区分
thirdUid false String 第三方开放用户唯一标识,文档2.1交换双方用户标识传入的thirdUid,如调用文档2.1用户绑定接口则此项必传

请求示例

{
  "reqId": "fe8234bf-e94c-4cdf-8ea9-c3112962ab01",
  "thirdUid": "b3540cc225bbf99dd789609edef91edd",
  "stamp": "20181201160518000"
}

返回结果

字段 类型 说明
reqId String 请求ID

返回示例

{
  "reqId": "b3540cc225bbf99dd789609edef91edd"
}

错误码说明

error 说明
1000 未知系统错误
1002 参数非法
1003 ClientId校验失败或服务返回解析失败
1004 服务调用失败
1006 签名或用户验证失败
1009 开发者账号不存在
2001 非法开发者
2003 取消授权过程失败

# 5.4 设备配网及确权

# 5.4.1 设备配网指引

接口说明: 该接口用于获取设备的配网指引信息

请求协议: HTTPS

请求方式: POST

请求地址: /v2/open/connect/guide/info

参数格式: body 参数

请求头

字段 必选 类型 说明
Authorization true String Bearer开头的访问令牌
例如:Bearer 0lemRvfLicjkHtno8r6wolAq8V7oLGe6
ClientId true String 唯一的第三方开发者ID
SignatureVersion true String 签名版本,默认值为2.0
Signature true String 签名摘要,签名方式请参照附录

请求参数

字段 必选 类型 说明
reqId true String 请求ID
stamp true String 请求时间戳,毫秒级区分
enterprise true String 企业码,如果接入的是美的牌,则为0000,其他企业码请联系对接人
type true String 设备品类(格式如AC)
sn8 true String 设备型号
modelNumber false String 特殊设备型号(A0),如果存在则必传
mode true String 配网模式 (0:AP,1:快连,2:声波,3:蓝牙,4:零配,5:WIFI,6:ZigBee)

请求示例

{
  "reqId":"fe8234bf-e94c-4cdf-8ea9-c3112962ab01",
  "stamp": "1593740640770",
  "enterprise": "0000",
  "type": "AC",
  "sn8": "010A0307",
  "modelNumber":"1",
  "mode":"0"
}

返回结果

字段 类型 说明
reqId String 请求ID
id String 指引记录Id
enterprise String 企业码
type String 设备品类(格式如AC)
modelCode String 设备型号(SN8)或特殊设备型号(A0)的值
modelType String modelCode类型 0:A0设备型号(SN8),1:特殊设备型号(A0)的值
mode String 配网模式 (0:AP,1:快连,2:声波,3:蓝牙,4:零配,5:WIFI,6:ZigBee)
wifiFrequencyBand String WIFI频段:1:2.4G,2:2.4G/5G
isAutoConnect String 上电默认连接模式(0 不启动,1 AP,2 WIFI零配)
mainConnectTypeUrlList JSONArray 主配网图列表
mainConnectTypeDesc String 配网介绍

返回示例

{
    "reqId": "fe8234bf-e94c-4cdf-8ea9-c3112962ab01",
    "id": "204",
    "enterprise": "0000",
    "type": "CA",
    "modelCode": "010A0307",
    "modelType": "0",
    "mode": "0",
    "wifiFrequencyBand": "1",
    "isAutoConnect": "0",
    "mainConnectTypeUrlList": [
        "http://fcmms.midea.com/zhiyin_new/6be6fbe5032768fc885956cc877418e3.png",
        "http://fcmms.midea.com/zhiyin_new/5ffa25acd859baeabc4e6e70b266187d.jpg"
    ],
    "mainConnectTypeDesc": "① 查看显示板是否已经“解锁”,若已经解锁执行第2步。在锁定状态,长按“锁定/解锁”按键3秒,解锁显示板 \r\n② 长按“智能”按键5秒,直至显示板显示“AP”或“WiFi模块恢复出厂设置”字样 \r\n③ 长按“锁定/解锁”按键3秒,锁定显示板,锁定时冰箱进入配置模式"
}

错误码说明

error 说明
1000 未知系统错误
1002 参数非法
1003 服务返回解析失败
1004 服务调用失败

# 5.4.2 设备后确权

后确权方案说明

交互逻辑说明
部分美的设备的模组上电后默认进入配网模式,配网绑定后需要手动进行后确权操作后,才能对设备进行远程控制。后确权逻辑设计如下:
1、用户配网绑定设备成功后,应先查询设备是否支持后确权以及当前的后确权状态
2、若设备支持后确权,且当前未确权,则需要下发指令给设备模组,让其进入待确权状态
3、此时向用户提示确权操作(线下提供后确权文档)
4、用户按照指引完成设备操作,确权结束
5、设备模组记住确权状态,直至下次重新配网
注意:设备进入待确权状态后,需要在60s内完成确权动作,否则设备会退出待确权状态,重新进入未确权状态。

交互时序图

确权方案

规范要求
综合考虑到设备性能及接口安全性,特规定如下规则:
1、调用文档3.2.2接口返回成功前为第一阶段,调用文档3.2.3接口返回成功前后为第二阶段,第二阶段允许文档3.2.3接口轮询调用
2、在进行相关确权动作之前(第一阶段)需要先明确设备处于未确权状态(返回值为2)后才进行后确权相关接口调用,明确设备确权状态可考虑通过调用文档3.2.3接口进行查询,但该接口此阶段在调用并成功返回的情况下只允许调用一次,如果有失败的情况最多重试不超过3次
3、在调用文档3.2.2接口并收到成功返回后(第二阶段)才允许开始轮询调用文档3.2.3接口进行实时确权状态查询
4、轮询调用文档3.2.3接口(第二阶段)时频率为每5秒一次,即每一次请求成功或失败后5秒才重新发起请求
5、轮询调用文档3.2.3接口(第二阶段)时总次数不超过12次

(1)设备确权指引

接口说明: 该接口用于获取设备的确权指引信息

请求协议: HTTPS

请求方式: POST

请求地址: /v2/open/appliance/auth/guide/info

参数格式: body 参数

请求头

字段 必选 类型 说明
Authorization true String Bearer开头的访问令牌
例如:Bearer 0lemRvfLicjkHtno8r6wolAq8V7oLGe6
ClientId true String 唯一的第三方开发者ID
SignatureVersion true String 签名版本,默认值为2.0
Signature true String 签名摘要,签名方式请参照附录

请求参数

字段 必选 类型 说明
reqId true String 请求ID
stamp true String 请求时间戳,毫秒级区分
enterprise true String 企业码
type true String 设备品类
sn8 false String 设备型号。sn8和modelNumber两者至少传其一
modelNumber false String 特殊设备型号(A0)。sn8和modelNumber两者至少传其一

请求示例

{
  "reqId":"fe8234bf-e94c-4cdf-8ea9-c3112962ab01",
  "stamp": "1593740640770",
  "enterprise": "0000",
  "type": "AC",
  "sn8": "010A0307",
  "modelNumber":"1"
}

返回结果

字段 类型 说明
reqId String 请求ID
id String 指引记录Id
enterprise String 企业码
type String 设备品类(格式如AC)
modelCode String 设备型号(SN8)或特殊设备型号(A0)的值
modelType String modelCode类型 0:A0设备型号(SN8),1:特殊设备型号(A0)的值
confirmImgUrl String 确权指引图片地址
confirmDesc String 确权指引文案

返回示例

{
    "reqId": "fe8234bf-e94c-4cdf-8ea9-c3112962ab01",
    "id": "204",
    "enterprise": "0000",
    "type": "CA",
    "modelCode": "010A0307",
    "modelType": "0",
    "confirmDesc": "长按“WIFI键”5秒,听到“滴”的一声表示验证成功。",
    "confirmImgUrl": "http://oss-cn-foshan.midea.com:17480/userDownload/3348D039BD4B470E8182F486A54F348F/dcpprod/86d98b0b7c6940c286883e986691ff85"
}

错误码说明

error 说明
1000 未知系统错误
1002 参数非法
1003 服务返回解析失败
1004 服务调用失败

# 3.2.2 设备确权

接口说明: 该接口用于支持后确权的设备,使用这个接口让设备进入待确权状态,设备进入待确权状态后,用户在设备上确权

请求协议: HTTPS

请求方式: POST

请求地址: /v2/open/appliance/auth/confirm

参数格式: body 参数

请求头

字段 必选 类型 说明
Authorization true String Bearer开头的访问令牌
例如:Bearer 0lemRvfLicjkHtno8r6wolAq8V7oLGe6
ClientId true String 唯一的第三方开发者ID
SignatureVersion true String 签名版本,默认值为2.0
Signature true String 签名摘要,签名方式请参照附录

请求参数

字段 必选 类型 说明
reqId true String 请求ID
stamp true String 请求时间戳,毫秒级区分
applianceCode true String 设备虚拟ID

请求示例

{
  "reqId":"fe8234bf-e94c-4cdf-8ea9-c3112962ab01",
  "stamp": "1593740640770",
  "applianceCode":"17592186044420"
}

返回结果

字段 类型 说明
reqId String 请求ID

返回示例

{
  "reqId":"fe8234bf-e94c-4cdf-8ea9-c3112962ab01"
}

错误码说明

error 说明
1000 未知系统错误
1002 参数非法
1003 服务返回解析失败
1004 服务调用失败
1105 账户不存在
1300 设备不存在
1304 设备不属于此用户
1305 用户不是设备的管理员
1306 设备超时没响应
1307 设备离线
1393 异常,无法切换

# 3.2.3 确权状态查询

接口说明: 该接口用于获取设备确权状态

请求协议: HTTPS

请求方式: POST

请求地址: /v2/open/appliance/auth/get

参数格式: body 参数

请求头

字段 必选 类型 说明
Authorization true String Bearer开头的访问令牌
例如:Bearer 0lemRvfLicjkHtno8r6wolAq8V7oLGe6
ClientId true String 唯一的第三方开发者ID
SignatureVersion true String 签名版本,默认值为2.0
Signature true String 签名摘要,签名方式请参照附录

请求参数

字段 必选 类型 说明
reqId true String 请求ID
stamp true String 请求时间戳,毫秒级区分
applianceCode true String 设备虚拟ID

请求示例

{
  "reqId":"fe8234bf-e94c-4cdf-8ea9-c3112962ab01",
  "stamp": "1593740640770",
  "applianceCode":"17592186044420"
}

返回结果

字段 类型 说明
status Integer 设备确权状态值
0 已确权
1 待确权
2 未确权
3 不支持确权

返回示例

{
  "status":1
}

错误码说明

error 说明
1000 未知系统错误
1002 参数非法
1003 服务返回解析失败
1004 服务调用失败
1105 账户不存在
1300 设备不存在
1304 设备不属于此用户
1305 用户不是设备的管理员
1306 设备超时没响应
1307 设备离线
1394 获取授权状态出错(支持确权的情况下查询状态出错)

# 5.4.3 获取ADS动态路由地址

接口说明: 该接口用于获取ADS动态路由相关信息,ADS(appliance domain_name service) ,用于提供给设备获取有效登录接入层的域名等信息。接入新版配网SDK需要接入该接口。

请求协议: HTTPS

请求方式: POST

请求地址: /v2/open/connect/ads

参数格式: body 参数

请求头

字段 必选 类型 说明
Authorization true String Bearer开头的访问令牌
例如:Bearer 0lemRvfLicjkHtno8r6wolAq8V7oLGe6
ClientId true String 唯一的第三方开发者ID
SignatureVersion true String 签名版本,默认值为2.0
Signature true String 签名摘要,签名方式请参照附录

请求体

字段 必选 类型 说明
reqId true String 请求ID
stamp true String 请求时间戳,毫秒级区分

请求示例

{
    "reqId": "fe8234bf-e94c-4cdf-8ea9-c3112962ab01",
    "stamp": "20181201160518000"
}

返回结果

字段 类型 说明
字段 类型 说明
reqId String 请求ID
adsId String ADS集群ID,十进制
adsDomain String 域名
adsPort int 端口

返回示例

{
    "reqId": "fe8234bf-e94c-4cdf-8ea9-c3112962ab01",
    "adsId": "65793",
    "adsDomain": "ads.smartmidea.net",
    "adsPort": 28850
}

错误码说明

error 说明
1000 未知系统错误

# 5.5 设备控制相关

# 5.5.1 获取设备列表

接口说明: 该接口用于获取用户名下的设备列表

请求协议: HTTPS

请求方式: POST

请求地址: /v2/open/device/list/get

参数格式: body 参数

请求头

字段 必选 类型 说明
Authorization true String Bearer开头的访问令牌
例如:Bearer 0lemRvfLicjkHtno8r6wolAq8V7oLGe6
ClientId true String 唯一的第三方开发者ID
SignatureVersion true String 签名版本,默认值为2.0
Signature true String 签名摘要,签名方式请参照附录

请求参数

字段 必选 类型 说明
reqId true String 请求ID
stamp true String 请求时间戳,毫秒级区分
homegroupId false String 家庭ID,传入查询指定家庭下的设备

请求示例

{
  "reqId": "fe8234bf-e94c-4cdf-8ea9-c3112962ab01",
  "stamp": "20181201160518000"
}

返回结果

字段 类型 说明
reqId String 请求ID
applianceList JSONArray 设备列表
sn8 String 设备型号
modelNumber String 特殊设备型号(A0)
applianceCode String 设备虚拟ID,用于设备相关操作
type String 设备类型
name String 设备名称
onlineStatus String 设备在线状态,1为在线,0为离线
enterprise String 设备企业码

返回示例

{
  "reqId": "fe8234bf-e94c-4cdf-8ea9-c3112962ab01",
  "applianceList": [{
    "applianceCode": "17592186044420",
    "type": "0xAC",
    "name": "客厅空调",
    "sn8": "1",
    "modelNumber": "",
    "onlineStatus": "1",
    "enterprise": "0000"
  }]
}

错误码说明

error 说明
1000 未知系统错误
1002 参数非法
1003 ClientId校验失败或服务返回解析失败
1004 服务调用失败
1006 签名或用户验证失败
1009 开发者账号不存在
1105 用户不存在
2001 非法开发者

# 5.5.2 获取设备信息

接口说明: 该接口用于获取用户名指定设备信息

请求协议: HTTPS

请求方式: POST

请求地址: /v2/open/device/info/get

参数格式: body 参数

请求头

字段 必选 类型 说明
Authorization true String Bearer开头的访问令牌
例如:Bearer 0lemRvfLicjkHtno8r6wolAq8V7oLGe6
ClientId true String 唯一的第三方开发者ID
SignatureVersion true String 签名版本号,默认值为2.0
Signature true String 签名摘要,签名方式请参照附录

请求参数

字段 必选 类型 说明
reqId true String 请求ID
stamp true String 请求时间戳,毫秒级区分
applianceCode true String 设备虚拟ID

请求示例

{
  "reqId": "fe8234bf-e94c-4cdf-8ea9-c3112962ab01",
  "stamp": "20181201160518000",
  "applianceCode": "1099511629543"
}

返回结果

字段 类型 说明
reqId String 请求ID
sn8 String 设备型号
modelNumber String 特殊设备型号(A0)
applianceCode String 设备虚拟ID,用于设备相关操作
type List 设备类型
name String 设备名称
enterprise String 设备企业码

返回示例

{
  "reqId": "fe8234bf-e94c-4cdf-8ea9-c3112962ab01",
    "applianceCode": "17592186044420",
    "type": "0xAC",
    "name": "客厅空调",
    "sn8": "1",
    "modelNumber": "",
    "enterprise": "0000"
}

错误码说明

error 说明
1000 未知系统错误
1002 参数非法
1003 ClientId校验失败
1006 签名或用户验证失败
1009 开发者账号不存在
1200 该用户不属于设备所在家庭组
1300 设备不存在
1305 该设备不属于该用户
2001 非法开发者
2012 静态密钥错误

# 5.5.3 绑定设备

接口说明: 该接口用于绑定设备,需要结合美居配网用的OpenSDK,返回reqId则接口调用成功

请求协议: HTTPS

请求方式: POST

请求地址: /v2/open/device/bind

参数格式: body 参数

请求头

字段 必选 类型 说明
Authorization true String Bearer开头的访问令牌
例如:Bearer 0lemRvfLicjkHtno8r6wolAq8V7oLGe6
ClientId true String 唯一的第三方开发者ID
SignatureVersion true String 签名版本,默认值为2.0
Signature true String 签名摘要,签名方式请参照附录

请求参数

字段 必选 类型 说明
reqId true String 请求ID
bindType false String 绑定类型,默认AP配网可不传,例如大屏扫码的类型为qrcode
qrcodeToken false String 扫描的二维码字符串,bindType为qrcode时必传
stamp true String 请求时间戳,毫秒级区分
applianceCode true String 设备虚拟ID,用于设备相关操作
verificationCode false String 验证码,bindType不传或者为ap时必传
procotolVersion false String 【固件版本号】 对应 Android/iOS AP配网返回的参数【设备协议版本号】
applianceType false String 【品类码】 对应Android/iOS AP配网返回的参数deviceTpye【设备品类】

请求示例

{
  "reqId": "fe8234bf-e94c-4cdf-8ea9-c3112962ab01",
  "stamp": "20181201160518000",
  "applianceCode": "17592186044420",
  "verificationCode": "000100"
}

返回结果

字段 类型 说明
reqId String 请求ID

返回示例

{
  "reqId": "fe8234bf-e94c-4cdf-8ea9-c3112962ab01"
}

错误码说明

error 说明
1000 未知系统错误
1001 二维码或家电类型格式错误
1002 参数非法
1003 ClientId校验失败或服务返回解析失败
1004 服务调用失败
1006 签名或用户验证失败
1009 开发者账号不存在
1011 设备标识解密失败
1105 用户不存在
1200 该用户不属于设备所在家庭组
1202 不是家庭的主人
1212 房间不属于家庭(如果指定了房间)
1300 设备不存在
1301 验证码验证失败
1307 设备离线
1309 家电型号不存在
1322 缓存中未获取到设备标识
1360 设备注册的绑定消息不存在
1361 设备的随机码的补充字段和设备标识不匹配
1383 绑定超时(设备连接上云端到绑定操作时间间隔不能大于60s)
1384 校验码错误
1501 家电家庭组超过最大上限(150)
2001 非法开发者
2014 此设备不支持绑定

# 5.5.4 解绑设备

接口说明: 该接口用于解绑设备,返回reqId则接口调用成功

请求协议: HTTPS

请求方式: POST

请求地址: /v2/open/device/unbind

参数格式: body 参数

请求头

字段 必选 类型 说明
Authorization true String Bearer开头的访问令牌
例如:Bearer 0lemRvfLicjkHtno8r6wolAq8V7oLGe6
ClientId true String 唯一的第三方开发者ID
SignatureVersion true String 签名版本,默认值为2.0
Signature true String 签名摘要,签名方式请参照附录

请求参数

字段 必选 类型 说明
reqId true String 请求ID
stamp true String 请求时间戳,毫秒级区分
applianceCode true String 设备虚拟ID,用于设备相关操作

请求示例

{
  "reqId": "fe8234bf-e94c-4cdf-8ea9-c3112962ab01",
  "stamp": "20181201160518000",
  "applianceCode": "17592186044420"
}

返回结果

字段 类型 说明
reqId String 请求ID

返回示例

{
  "reqId": "fe8234bf-e94c-4cdf-8ea9-c3112962ab01"
}

错误码说明

error 说明
1000 未知系统错误
1002 参数非法
1003 ClientId校验失败或服务返回解析失败
1004 服务调用失败
1006 签名或用户验证失败
1009 开发者账号不存在
1105 用户不存在
1300 设备不存在
1305 该设备不属于该用户
2001 非法开发者

# 5.5.5 控制设备

接口说明: 该接口用于发送控制设备指令至设备

请求协议: HTTPS

请求方式: POST

请求地址: /v2/open/device/control

参数格式: body 参数

请求头

字段 必选 类型 说明
Authorization true String Bearer开头的访问令牌
例如:Bearer 0lemRvfLicjkHtno8r6wolAq8V7oLGe6
ClientId true String 唯一的第三方开发者ID
SignatureVersion true String 签名版本,默认值为2.0
Signature true String 签名摘要,签名方式请参照附录

请求参数

字段 必选 类型 说明
reqId true String 请求ID
stamp true String 请求时间戳,毫秒级区分
applianceCode true String 设备虚拟ID,用于设备相关操作
command true String 设备控制命令,内容需要进行转义
示例:"{\"control\":{\"power\":\"on\"}}"

注:control为控制设备指令,格式为JSON字符串,具体指令请联系不同品类对接人

请求示例

{
  "reqId":"c1pebi7h-zslx-zslx-zslx-iar8loygqjt7",
  "stamp":"202103161750",
  "applianceCode":"1099511833333",
  "command":"{\"control\":{\"power\":\"off\"}}"
}

返回结果

字段 类型 说明
reqId String 请求ID
status Object 设备状态返回值

返回示例

{
  "status":{
    "show_h":"off",
    "single_wash":"off",
    "efficient":"off",
    "passwater_lowbyte":0,
    "winter":"off",
    "screen_off":"off",
    "cur_rate":0,
    "ali_manager":"off",
    "mom_wash":"off",
    "baby_wash":"off",
    "appoint_power":"off",
    "error_code":0,
    "scroll_hot":"off",
    "elec_warning":"off",
    "sensor_error":"off",
    "sleep":"off",
    "end_time_minute":26,
    "frequency_hot":"off",
    "big_water":"off",
    "top_temp":26,
    "safe":"off",
    "mode":"none",
    "ti_protect":"off",
    "appoint_wash":"off",
    "wash":"off",
    "need_discharge":"off",
    "cloud":"off",
    "sterilization":"off",
    "fast_hot_power":"off",
    "warm_power":"off",
    "protect_show":"off",
    "sterilize_high_temp":"off",
    "always_fell":"off",
    "power":"off",
    "wash_with_temp":"off",
    "cur_temperature":26,
    "temperature":50,
    "heat":"whole",
    "memory":"off",
    "flow":0,
    "bath_person":"off",
    "two_egg":"off",
    "version":25,
    "ele_exception":"off",
    "door_status":"off",
    "bash_end":"0",
    "communication_error":"off",
    "sound_dad":"off",
    "get_temp":"off",
    "smart_sterilize":"off",
    "cloud_appoint":"off",
    "one_egg":"off",
    "people_wash":"off",
    "limit_error":"off",
    "night":"off",
    "whole_heat":"on",
    "wash_temperature":0,
    "machine":"real_machine",
    "top_heat":"off",
    "protect":"off",
    "grea":0,
    "scene":"off",
    "music":"off",
    "t_hot":"off",
    "summer":"off",
    "waterday_highbyte":0,
    "bottom_heat":"on",
    "scene_id":0,
    "fast_wash":"off",
    "dad_wash":"off",
    "clean":"off",
    "auto_off":"off",
    "rate":0,
    "sterilize_left_days":157,
    "water_quality":0,
    "water_flow":"off",
    "volume":50,
    "mg_remain":0,
    "get_time":"off",
    "midea_manager":"on",
    "water_cyclic":"off",
    "discharge_left_time":0,
    "shower":"off",
    "negative_ions":"off",
    "end_time_hour":0,
    "half_heat":"off",
    "discharge_status":0,
    "bath":"off",
    "func_select":"low",
    "type_select":"normal",
    "bottom_temp":"off",
    "hot_power":"on",
    "heat_water_level":0,
    "water_system":0,
    "tech_water":"off",
    "in_temperature":0,
    "eplus":"off",
    "uv_sterilize":"off",
    "now_wash":"on",
    "waterday_lowbyte":0,
    "passwater_highbyte":0
  },
  "code":"0",
  "reqId":"c1pebi7h-zslx-zslx-zslx-iar8loygqjt7"
}

错误码说明

error 说明
1000 未知系统错误
1001 指令格式化错误
1002 参数非法
1003 ClientId校验失败
1006 签名或用户验证失败
1009 开发者账号不存在
1014 lua脚本内部转换错误
1200 该用户不属于设备所在家庭组
1300 设备不存在
1305 该设备不属于该用户
1307 设备离线
1321 设备未确权

# 5.5.6 查询设备

接口说明: 该接口用于查询设备状态

请求协议: HTTPS

请求方式: POST

请求地址: /v2/open/device/status/get

参数格式: body 参数

请求头

字段 必选 类型 说明
Authorization true String Bearer开头的访问令牌
例如:Bearer 0lemRvfLicjkHtno8r6wolAq8V7oLGe6
ClientId true String 唯一的第三方开发者ID
SignatureVersion true String 签名版本,默认值为2.0
Signature true String 签名摘要,签名方式请参照附录

请求参数

字段 必选 类型 说明
reqId true String 请求ID
stamp true String 请求时间戳,毫秒级区分
applianceCode true String 设备虚拟ID
command true String 设备查询,可查询全状态
示例:"{"query":{}}"

注:query为查询设备指令,格式为JSON字符串,具体属性请联系不同品类对接人

请求示例

{
  "reqId":"8ev6pxru-cny4-cny4-cny4-x80jvf46nidg",
  "stamp":"202103161750",
  "applianceCode":"1099511833333",
  "command":"{\"query\":{}}"
}

返回结果

字段 类型 说明
reqId String 请求ID
status Object 设备状态返回值

返回示例

{
  "status":{
    "show_h":"off",
    "single_wash":"off",
    "efficient":"off",
    "passwater_lowbyte":0,
    "winter":"off",
    "screen_off":"off",
    "cur_rate":0,
    "ali_manager":"off",
    "mom_wash":"off",
    "baby_wash":"off",
    "appoint_power":"off",
    "error_code":0,
    "scroll_hot":"off",
    "elec_warning":"off",
    "sensor_error":"off",
    "sleep":"off",
    "end_time_minute":27,
    "frequency_hot":"off",
    "big_water":"off",
    "top_temp":25,
    "safe":"off",
    "mode":"none",
    "ti_protect":"off",
    "appoint_wash":"off",
    "wash":"off",
    "need_discharge":"off",
    "cloud":"off",
    "sterilization":"off",
    "fast_hot_power":"off",
    "warm_power":"off",
    "protect_show":"off",
    "sterilize_high_temp":"off",
    "always_fell":"off",
    "power":"on",
    "wash_with_temp":"off",
    "cur_temperature":25,
    "temperature":50,
    "heat":"whole",
    "memory":"off",
    "flow":0,
    "bath_person":"off",
    "two_egg":"off",
    "version":25,
    "ele_exception":"off",
    "door_status":"off",
    "bash_end":"0",
    "communication_error":"off",
    "sound_dad":"off",
    "get_temp":"off",
    "smart_sterilize":"off",
    "cloud_appoint":"off",
    "one_egg":"off",
    "people_wash":"off",
    "limit_error":"off",
    "night":"off",
    "whole_heat":"on",
    "wash_temperature":0,
    "machine":"real_machine",
    "top_heat":"off",
    "protect":"off",
    "grea":0,
    "scene":"off",
    "music":"off",
    "t_hot":"off",
    "summer":"off",
    "waterday_highbyte":0,
    "bottom_heat":"on",
    "scene_id":0,
    "fast_wash":"off",
    "dad_wash":"off",
    "clean":"off",
    "auto_off":"off",
    "rate":0,
    "sterilize_left_days":157,
    "water_quality":0,
    "water_flow":"off",
    "volume":50,
    "mg_remain":0,
    "get_time":"off",
    "midea_manager":"on",
    "water_cyclic":"off",
    "discharge_left_time":0,
    "shower":"off",
    "negative_ions":"off",
    "end_time_hour":0,
    "half_heat":"off",
    "discharge_status":0,
    "bath":"off",
    "func_select":"low",
    "type_select":"normal",
    "bottom_temp":"off",
    "hot_power":"on",
    "heat_water_level":0,
    "water_system":0,
    "tech_water":"off",
    "in_temperature":0,
    "eplus":"off",
    "uv_sterilize":"off",
    "now_wash":"on",
    "waterday_lowbyte":0,
    "passwater_highbyte":0
  },
  "code":"0",
  "reqId":"8ev6pxru-cny4-cny4-cny4-x80jvf46nidg"
}

错误码说明

error 说明
1000 未知系统错误
1001 指令格式化错误
1002 参数非法
1003 ClientId校验失败
1006 签名或用户验证失败
1009 开发者账号不存在
1200 该用户不属于设备所在家庭组
1300 设备不存在
1305 该设备不属于该用户
1307 设备离线
1321 设备未确权

# 5.6 设备通知相关

# 5.6.1 设备订阅

接口说明: 设备订阅接口,被订阅的设备才会有消息通知,返回reqId则接口调用成功

请求协议: HTTPS

请求方式: POST

请求地址: /v2/open/device/subscribe

参数格式: body 参数

请求头

字段 必选 类型 说明
Authorization true String Bearer开头的访问令牌
例如:Bearer 0lemRvfLicjkHtno8r6wolAq8V7oLGe6
ClientId true String 唯一的第三方开发者ID
SignatureVersion true String 签名版本,默认值为2.0
Signature true String 签名摘要,签名方式请参照附录

请求参数

字段 必选 类型 说明
reqId true String 请求ID
stamp true String 请求时间戳,毫秒级区分
applianceCode true String 设备虚拟ID,以英文分号分隔开

请求示例

{
  "reqId": "fe8234bf-e94c-4cdf-8ea9-c3112962ab01",
  "stamp": "20181201160518000",
  "applianceCode": "17592186044420;1099511824211;1099511824212"
}

返回结果

字段 类型 说明
reqId String 请求ID

返回示例

{
  "reqId": "fe8234bf-e94c-4cdf-8ea9-c3112962ab01"
}

错误码说明

error 说明
1000 未知系统错误
1002 参数非法
1003 ClientId校验失败或服务返回解析失败
1004 服务调用失败
1006 签名或用户验证失败
1009 开发者账号不存在
1300 设备不存在

# 5.6.2 取消设备订阅

接口说明: 取消设备订阅,取消后第三方不会再收到这些设备的通知,返回reqId则接口调用成功

请求协议: HTTPS

请求方式: POST

请求地址: /v2/open/device/subscribe/cancel

参数格式: body 参数

请求头

字段 必选 类型 说明
Authorization true String Bearer开头的访问令牌
例如:Bearer 0lemRvfLicjkHtno8r6wolAq8V7oLGe6
ClientId true String 唯一的第三方开发者ID
SignatureVersion true String 签名版本,默认值为2.0
Signature true String 签名摘要,签名方式请参照附录

请求参数

字段 必选 类型 说明
reqId true String 请求ID
stamp true String 请求时间戳,毫秒级区分
applianceCode true String 设备虚拟ID,以英文分号分隔开

请求示例

{
  "reqId": "fe8234bf-e94c-4cdf-8ea9-c3112962ab01",
  "stamp": "20181201160518000",
  "applianceCode": "17592186044420;1099511824211;1099511824212"
}

返回结果

字段 类型 说明
reqId String 请求ID

返回示例

{
  "reqId": "fe8234bf-e94c-4cdf-8ea9-c3112962ab01"
}

错误码说明

error 说明
1000 未知系统错误
1002 参数非法
1003 ClientId校验失败或服务返回解析失败
1004 服务调用失败
1006 签名或用户验证失败
1009 开发者账号不存在
1300 设备不存在

# 5.6.5 消息通知

接口说明: 此接口由第三方定义及实现,由美的云调用,用于通知设备订阅信息,接口鉴权方式由第三方定义,通知内容基于下面请求体定义

请求协议: HTTPS

请求方式: POST

请求地址: 由第三方定义,并提前注册到美的IoT开发者平台(申请开发者ID时)

参数格式: body 参数

请求头

字段 必选 类型 说明
clientId true String 唯一的第三方开发者ID
signature true String 签名摘要,签名方式请参照附录
Authorization false String 设备订阅通知授权模式选择授权码授权或客户端授权时会传
Bearer开头的访问令牌
例如:Bearer 0lemRvfLicjkHtno8r6wolAq8V7oLGe6

请求参数

字段 必选 类型 说明
header true Object 请求体头部
namespace true String 通知事件类型
ApplianceBind - 设备绑定
ApplianceUnbind - 设备解绑
ApplianceState - 设备状态
reqId true String 请求ID
stamp true String 请求时间戳,毫秒级区分
openUid true String 用户ID
payload true Object 请求体负载,不同namespace时内容不同,下列示例中分别说明

设备绑定通知payload内容及示例

字段 必选 类型 说明
appliance true Object 设备实体
name true String 设备名称
type true String 设备类型
applianceCode true String 设备虚拟ID
modelNumber true String 特殊设备型号(A0)
{
  "header": {
    "namespace": "ApplianceBind",
    "reqId": "1",
    "stamp": "201902251110111",
    "openUid": "123"
  },
  "payload": {
    "appliance": {
      "name": "空调A",
      "type": "0xAC",
      "applianceCode": "1099511824210",
      "modelNumber": "1"
    }
  }
}

设备解绑通知payload内容及示例: ​

字段 必选 类型 说明
applianceCode true String 设备虚拟ID
{
  "header": {
    "namespace": "ApplianceUnbind",
    "reqId": "1",
    "stamp": "201902251110111",
    "openUid": "123"
  },
  "payload": {
    "applianceCode":"1099511824210"
  }
}

设备状态通知payload内容及示例: ​

字段 必选 类型 说明
onlineStatus true String 设备在线状态,0代表离线,1代表在线
applianceCode true String 设备虚拟ID
status true Object 设备状态

设备离线通知

{
  "header": {
    "namespace": "ApplianceState",
    "openUid": "37310c0fa4c179b20b897c4f8c109fdc",
    "reqId": "75fc02e9ce59baf8365ba5f1abb46f4a",
    "stamp": "1599190860000"
  },
  "payload": {
    "onlineStatus": "0",
    "applianceCode": 70368744268027,
    "status": { }
  }
}

设备上线通知

{
  "header": {
    "namespace": "ApplianceState",
    "openUid": "37310c0fa4c179b20b897c4f8c109fdc",
    "reqId": "75fc02e9ce59baf8365ba5f1abb46f4b",
    "stamp": "1599190960147"
  },
  "payload": {
    "onlineStatus": "1",
    "applianceCode": 70368744268027,
    "status": { }
  }
}

设备变化通知

{
  "header": {
    "namespace": "ApplianceState",
    "reqId": "1",
    "stamp": "201902251110111",
    "openUid": "123"
  },
  "payload": {
    "onlineStatus":"1",
    "applianceCode":"1099511824210",
    "status": {
      "power": "on",
      "light": "off",
      "dry": "on"
    }
  }
}

返回结果

美的IoT开发者平台不处理

# 5.7 场景相关

# 5.7.1 获取场景列表

接口说明: 获取美居家庭下的一键场景列表

请求协议: HTTPS

请求方式: POST

请求地址: /v2/open/scene/item/list

参数格式: body 参数

请求头

字段 必选 类型 说明
Authorization true String Bearer开头的访问令牌
例如:Bearer 0lemRvfLicjkHtno8r6wolAq8V7oLGe6
ClientId true String 唯一的第三方开发者ID
SignatureVersion true String 签名版本,默认值为2.0
Signature true String 签名摘要,签名方式请参照附录

请求参数

字段 必选 类型 说明
reqId true String 请求ID
stamp true String 请求时间戳,毫秒级区分
homegroupId true String 家庭ID,从用户信息接口中选择

请求示例

{
  "reqId": "fe8234bf-e94c-4cdf-8ea9-c3112962ab01",
  "stamp": "20181201160518000",
  "homegroupId": "12099672"
}

返回结果

字段 类型 说明
reqId String 请求ID
sceneList List 场景列表
sceneId String 场景ID
sceneType String 场景类型
2 - 一键场景

注:目前云云对接只返回一键场景数据
sceneName String 场景名称
enable String 场景是否禁用
0 - 禁用
1 - 启用
homegroupId String 家庭ID

返回示例

{
  "reqId": "fe8234bf-e94c-4cdf-8ea9-c3112962ab01",
  "sceneList": [{
    "sceneId": "4512121",
    "sceneType": "2",
    "sceneName": "回家",
    "enable": "1",
    "homegroupId": "12099672"
  }]
}

错误码说明

error 说明
1000 未知系统错误
1001 sceneType,homegroupId类型转化异常
1002 参数非法
1003 ClientId校验失败或服务返回解析失败
1004 服务调用失败
1006 签名或用户验证失败
1009 开发者账号不存在
1200 该用户不属于设备所在家庭组
2001 非法开发者

# 5.7.2 获取场景详情

接口说明: 获取美居家庭下的一键场景详情

请求协议: HTTPS

请求方式: POST

请求地址: /v2/open/scene/item/get

参数格式: body 参数

请求头

字段 必选 类型 说明
Authorization true String Bearer开头的访问令牌 例如:Bearer 0lemRvfLicjkHtno8r6wolAq8V7oLGe6
ClientId true String 唯一的第三方开发者ID
SignatureVersion true String 签名版本,默认值为2.0
Signature true String 签名摘要,签名方式请参照附录

请求参数

字段 必选 类型 说明
reqId true String 请求ID
stamp true String 请求时间戳,毫秒级区分
sceneId true String 场景ID,从场景列表接口中选择
homegroupId true String 家庭ID,从用户信息接口中选择

请求示例

{
  "reqId": "fe8234bf-e94c-4cdf-8ea9-c3112962ab01",
  "stamp": "20181201160518000",
  "sceneId": "4512121",
  "homegroupId": "12099672"
}

返回结果

字段 类型 说明
reqId String 请求ID
sceneId String 场景ID
sceneName String 场景名称
enable String 场景是否禁用 0 - 禁用 1 - 启用
homegroupId String 家庭ID
applianceList List 设备列表
applianceCode String 设备虚拟ID
applianceName String 设备名称
applianceType String 设备类型
command JSONObject 设备执行动作
{
  "reqId": "fe8234bf-e94c-4cdf-8ea9-c3112962ab01",
  "sceneId": "4512121",
  "sceneName": "回家",
  "enable": "1",
  "applianceList": [{
    "applianceCode": "4565215",
    "applianceType": "0xAC",
  	"applianceName": "空调",
    "command": {
        "mode": "auto",
        "power": "on"
    }
  }]
}

错误码说明

error 说明
1000 未知系统错误
1001 sceneType,homegroupId,sceneId类型转化异常
1002 参数非法
1003 ClientId校验失败或服务返回解析失败
1004 服务调用失败
1006 签名或用户验证失败
1009 开发者账号不存在
1200 该用户不属于设备所在家庭组
1700 该用户没有操作权限
1701 场景不存在
2001 非法开发者

# 5.7.3 执行场景

接口说明: 执行场景

请求协议: HTTPS

请求方式: POST

请求地址: /v2/open/scene/item/execute

参数格式: body 参数

请求头

字段 必选 类型 说明
Authorization true String Bearer开头的访问令牌
例如:Bearer 0lemRvfLicjkHtno8r6wolAq8V7oLGe6
ClientId true String 唯一的第三方开发者ID
SignatureVersion true String 签名版本,默认值为2.0
Signature true String 签名摘要,签名方式请参照附录

请求参数

字段 必选 类型 说明
reqId true String 请求ID
stamp true String 请求时间戳,毫秒级区分
homegroupId true String 家庭ID,从用户信息接口中选择
sceneId true String 场景ID

请求示例

{
  "reqId": "fe8234bf-e94c-4cdf-8ea9-c3112962ab01",
  "stamp": "20181201160518000",
  "homegroupId": "12099672",
  "sceneId": "4512121"
}

返回结果

字段 类型 说明
reqId String 请求ID
resultId String 执行记录ID

返回示例

{
  "reqId": "fe8234bf-e94c-4cdf-8ea9-c3112962ab01",
  "resultId": "5746727"
}

错误码说明

error 说明
1000 未知系统错误
1001 homegroupId,sceneId类型转化异常
1002 参数非法
1003 ClientId校验失败或服务返回解析失败
1004 服务调用失败
1006 签名或用户验证失败
1009 开发者账号不存在
1200 该用户不属于设备所在家庭组
1202 非主人无法操作
1300 设备不存在
1700 该用户没有操作权限
1701 场景不存在
1702 该场景未启用
1704 此场景不做推送
2001 非法开发者

# 5.8 物模型相关

# 5.8.1 操作(action)调用

接口说明: 触发物模型定义的action,从而控制设备

请求协议: HTTPS

请求方式: POST

请求地址: /v2/open/thing/action

参数格式: body 参数

请求头

字段 必选 类型 说明
Authorization true String Bearer开头的访问令牌
例如:Bearer 0lemRvfLicjkHtno8r6wolAq8V7oLGe6
ClientId true String 唯一的第三方开发者ID
SignatureVersion true String 签名版本,默认值为2.0
Signature true String 签名摘要,签名方式请参照附录

请求参数

字段 必选 类型 说明
reqId true String 请求ID
stamp true String 请求时间戳,毫秒级区分
applianceCode true String 设备虚拟ID,用于设备相关操作
moduleCode true String 物模型模块编码
actionCode true String 物模型动作编码
action true Object 说明:
1、JSON格式的对象类型,单层结构参数
2、由调用的物模型Action中定义的input为准,且接口会对其类型进行校验,因此送入的JSON参数必须符合入参定义(包括参数名、类型、约束范围),具体请联系不同品类对接人
3、如果物模型的入参定义有默认值,则可以不送入参数,接口会将默认使用默认值

请求示例

{
  "reqId":"c1pebi7h-zslx-zslx-zslx-iar8loygqjt7",
  "stamp":"202103161750",
  "applianceCode":"1099511833333",
  "moduleCode":"fans",
  "actionCode":"power",
  "action": {
    "power": true   
  }
}

返回结果

字段 类型 说明
requestId String 请求ID
code String 接口响应码
data Object 物模型定义的返回结果

返回示例

{
    "requestId": "t11122233344",
    "code": "0",
    "data": {
        "prop1": "aaa",
        "prop2": "bbb",
        "prop3": "ccc"
    }
}

错误码说明

error 说明
1000 未知系统错误
1001 指令格式化错误
1002 参数非法
1003 ClientId校验失败
1006 签名或用户验证失败
1009 开发者账号不存在
1014 lua脚本内部转换错误
1200 该用户不属于设备所在家庭组
1300 设备不存在
1305 该设备不属于该用户
1307 设备离线
1321 设备未确权

# 5.8.2 属性(property)查询

接口说明: 用于查询设备的属性,可指定查询属性名称,不指定则返回错误

请求协议: HTTPS

请求方式: POST

请求地址: /v2/open/thing/properties

参数格式: body 参数

请求头

字段 必选 类型 说明
Authorization true String Bearer开头的访问令牌
例如:Bearer 0lemRvfLicjkHtno8r6wolAq8V7oLGe6
ClientId true String 唯一的第三方开发者ID
SignatureVersion true String 签名版本,默认值为2.0
Signature true String 签名摘要,签名方式请参照附录

请求参数

字段 必选 类型 说明
reqId true String 请求ID
stamp true String 请求时间戳,毫秒级区分
applianceCode true String 设备虚拟ID,用于设备相关操作
properties true Array 说明:
1、模块和参数之间展开表示,以简化数据结构,模块和属性之间使用“.”号进行分隔
2、如果只输入模块编码,则查询此模块下所有属性
3、仅支持物模型中op参数包含read属性的查询
disablePropIntegrityCheck false boolean 禁用完整性校验,属性查询时,若设备返回属性存在缺失,将忽略此异常,并将其余属性返回,不传默认false
disablePropLegalityCheck false boolean 禁用合法性校验,属性查询时,若设备返回属性与物模型中定义不一致,将忽略此异常,返回原始值,不传默认false

请求示例

{
  "reqId":"c1pebi7h-zslx-zslx-zslx-iar8loygqjt7",
  "stamp":"202103161750",
  "applianceCode":"1099511833333",
  "properties": [
    "module1.prop1", //模块module1的prop1
    "module1.prop2", //模块module1的prop2
    "module2", //模块module2的所有属性
    ...
   ]
}

返回结果

字段 类型 说明
requestId String 请求ID
code String 接口响应码
data Object 说明:
1、响应的参数也是展开格式,符合请求入参规范,所有响应参数符合物模型中属性的定义
2、对于查询模块所有属性的,默认展开并填充所有的属性结果
3、查询全部属性的也使用模块所有属性的相同规则

返回示例

{
    "requestId": "t1112223334445",
    "code":"0",
    "data": {
        "fan.power": "true",
        "fan.workMode": "natural",
        "fan.speedLevel": "level3",
        "fan.swingType": "leftRight",
        "schdeule.timer": "50 7 * * *"
    }
}

错误码说明

error 说明
1000 未知系统错误
1001 指令格式化错误
1002 参数非法
1003 ClientId校验失败
1006 签名或用户验证失败
1009 开发者账号不存在
1014 lua脚本内部转换错误
1200 该用户不属于设备所在家庭组
1300 设备不存在
1305 该设备不属于该用户
1307 设备离线
1321 设备未确权

# 5.8.3 属性(property)批量查询

接口说明: 用于批量查询设备的属性,可指定查询属性名称,不指定则返回错误

请求协议: HTTPS

请求方式: POST

请求地址: /v2/open/thing/batch/properties

参数格式: body 参数

请求头

字段 必选 类型 说明
Authorization true String Bearer开头的访问令牌
例如:Bearer 0lemRvfLicjkHtno8r6wolAq8V7oLGe6
ClientId true String 唯一的第三方开发者ID
SignatureVersion true String 签名版本,默认值为2.0
Signature true String 签名摘要,签名方式请参照附录

请求参数

字段 必选 类型 说明
reqId true String 请求ID
stamp true String 请求时间戳,毫秒级区分
applianceCode true String 设备虚拟ID,用于设备相关操作
properties true Array 批量查询设备的数组,一次请求查询设备数量不超过20
props true Array 说明:
1、模块和参数之间展开表示,以简化数据结构,模块和属性之间使用“.”号进行分隔
2、如果只输入模块编码,则查询此模块下所有属性
3、仅支持物模型中op参数包含read属性的查询
disablePropIntegrityCheck false boolean 禁用完整性校验,属性查询时,若设备返回属性存在缺失,将忽略此异常,并将其余属性返回,不传默认false
disablePropLegalityCheck false boolean 禁用合法性校验,属性查询时,若设备返回属性与物模型中定义不一致,将忽略此异常,返回原始值,不传默认false

请求示例

{
  "reqId":"c1pebi7h-zslx-zslx-zslx-iar8loygqjt7",
  "stamp":"202103161750",
  "properties": [
    {
        "applianceCode": 1001,
        "props": [
            "module1.prop1", //模块module1的prop1
            "module1.prop2", //模块module1的prop2
            "module2" //模块module2的所有属性
        ],
        "disablePropIntegrityCheck": true,
        "disablePropLegalityCheck": true
    },
    {
        "applianceCode": 1002,
        "props": [
            "module1.prop1", //模块module1的prop1
            "module1.prop2", //模块module1的prop2
            "module2" //模块module2的所有属性
        ]
    }
]
}

返回结果

字段 类型 说明
requestId String 请求ID
code String 接口响应码
data Object 说明:
1、响应的参数也是展开格式,符合请求入参规范,所有响应参数符合物模型中属性的定义
2、对于查询模块所有属性的,默认展开并填充所有的属性结果
3、查询全部属性的也使用模块所有属性的相同规则

返回示例

{
    "requestId": "xxxxx",
    "code": "0",
    "data": [
        {
            "code": "0",
            "applianceCode": 1001,
            "data": {
                "module1.prop1": "value1",
                "module1.prop2": "value2",
                "module2.prop1": "value3",
                "module2.prop2": "value4",
                "module2.prop3": "value5"
            }
        },
        {
            "code": "12345",
            "applianceCode": 1002,
            "msg": "error msg"
        }
    ]
}

错误码说明

error 说明
1000 未知系统错误
1001 指令格式化错误
1002 参数非法
1003 ClientId校验失败
1006 签名或用户验证失败
1009 开发者账号不存在
1014 lua脚本内部转换错误
1200 该用户不属于设备所在家庭组
1300 设备不存在
1305 该设备不属于该用户
1307 设备离线
1321 设备未确权

# 5.8.4 全属性(properties)查询

接口说明: 用于查询设备的所有属性

请求协议: HTTPS

请求方式: POST

请求地址: /v2/open/thing/entire/properties

参数格式: body 参数

请求头

字段 必选 类型 说明
Authorization true String Bearer开头的访问令牌
例如:Bearer 0lemRvfLicjkHtno8r6wolAq8V7oLGe6
ClientId true String 唯一的第三方开发者ID
SignatureVersion true String 签名版本,默认值为2.0
Signature true String 签名摘要,签名方式请参照附录

请求参数

字段 必选 类型 说明
reqId true String 请求ID
stamp true String 请求时间戳,毫秒级区分
applianceCode true String 设备虚拟ID,用于设备相关操作

请求示例

{
  "reqId":"c1pebi7h-zslx-zslx-zslx-iar8loygqjt7",
  "stamp":"202103161750",
  "applianceCode":"123456"
}

返回结果

字段 类型 说明
requestId String 请求ID
code String 接口响应码
data Object 说明:
1、响应的参数也是展开格式,符合请求入参规范,所有响应参数符合物模型中属性的定义
2、模块所有属性默认展开并填充所有的属性结果

返回示例

{
    "requestId": "xxxxx",
    "code": "0",
    "data": {
        "module1.prop1": "value1",
        "module1.prop2": "value2",
        "module2.prop1": "value3",
        "module2.prop2": "value4",
        "module2.prop3": "value5"
    }
}

错误码说明

error 说明
1000 未知系统错误
1001 指令格式化错误
1002 参数非法
1003 ClientId校验失败
1006 签名或用户验证失败
1009 开发者账号不存在
1014 lua脚本内部转换错误
1200 该用户不属于设备所在家庭组
1300 设备不存在
1305 该设备不属于该用户
1307 设备离线
1321 设备未确权

# 5.8.5 属性(properties)设置

接口说明: 用于设置设备属性

请求协议: HTTPS

请求方式: POST

请求地址: /v2/open/thing/properties/modify

参数格式: body 参数

请求头

字段 必选 类型 说明
Authorization true String Bearer开头的访问令牌
例如:Bearer 0lemRvfLicjkHtno8r6wolAq8V7oLGe6
ClientId true String 唯一的第三方开发者ID
SignatureVersion true String 签名版本,默认值为2.0
Signature true String 签名摘要,签名方式请参照附录

请求参数

字段 必选 类型 说明
reqId true String 请求ID
stamp true String 请求时间戳,毫秒级区分
applianceCode true String 设备虚拟ID,用于设备相关操作
properties true Object 说明:
1、模块和参数之间展开表示,以简化数据结构,模块和属性之间使用“.”号进行分隔
2、仅支持物模型属性的op定义中包含“write”枚举的属性
3、属性值需要符合物模型中的类型定义及约束

请求示例

{
  "reqId":"c1pebi7h-zslx-zslx-zslx-iar8loygqjt7",
  "stamp":"202103161750",
  "applianceCode":"123456",
  "properties":{
    "module1.prop1": "value1", //设置模块module1的prop1属性
    "module1.prop2": "value1", //设置模块module1的prop2属性
    "module2.prop3": "value1" //设置模块module2的prop3属性
   }
}

返回结果

字段 类型 说明
requestId String 请求ID
code String 接口响应码
data Object 说明:
1、响应的参数也是展开格式,符合请求入参规范,响应仅包含是否成功
2、响应的属性与请求交互的一致

返回示例

{
    "requestId": "xxxxx",
    "code": "0",
    "data": "success"
}

错误码说明

error 说明
1000 未知系统错误
1001 指令格式化错误
1002 参数非法
1003 ClientId校验失败
1006 签名或用户验证失败
1009 开发者账号不存在
1014 lua脚本内部转换错误
1200 该用户不属于设备所在家庭组
1300 设备不存在
1305 该设备不属于该用户
1307 设备离线
1321 设备未确权

# 5.9 签名摘要规则说明

(1)说明

为保证消息的完整性,防止消息在途中被第三方修改。在请求的参数中增加一个sign参数作为信息摘要值。服务器端与手机端用相同的规则生成sign值,服务器端接收到请求后对比sign值是否正确,如果正确才处理请求,否则视为非法请求。

(2)生成摘要原串

请求信息摘要(即sign值)生成规则:

摘要原串B = Http Method(如POST)+请求URI串(去除URL串host部分,如:/v2/open/device/list/get)+ URL请求参数QueryString + 请求消息体bodyBytes的字符串(utf-8编码)

比如(仅作示例,与原接口请求参数不同):

POST /v2/open/device/list/get?client_id=f6f1ec55481b5dc314bd6555e4d3d3bb&timestamp=1556193552988 HTTP/1.1
Host: xx.com
Content-Type: **/*
{"reqId":"fe8234bf-e94c-4cdf-8ea9-c3112962ab01","applianceList":[{"applianceCode":"17592186044420","type":"0xAC","name":"客厅空调","modelNumber":"1","onlineStatus":"1"}]}

则摘要原串B:

POST/v2/open/device/list/getclient_id=f6f1ec55481b5dc314bd6555e4d3d3bb&timestamp=1556193552988{"reqId":"fe8234bf-e94c-4cdf-8ea9-c3112962ab01","applianceList":[{"applianceCode":"17592186044420","type":"0xAC","name":"客厅空调","modelNumber":"1","onlineStatus":"1"}]}

(3)由摘要原串生成sign值

使用HmacSHA256签名算法对字符串B进行签名,得到对应的签名数组再使用Base64进行编码(除了Base64编码外还需注意所有String <==> byte[]地方显式设置了编码为UTF-8 ) 注:其中密钥使用美的云为三方云分配的clientSecret Signature = Base64(HMAC_SHA_256 (clientSecret, Http Method + RequestURI + QueryString + 请求消息体bodyBytes的字符串(utf-8编码)))

(4)实现示例

JAVA版

package com.midea.smart.iot.open.common.util;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.HmacUtils;
import org.apache.commons.lang3.StringUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URLDecoder;


/**
 * @Description: 签名摘要工具类
 * @Author: musilin
 * @Date: 2019-4-18
 * @Version: 1.0.0
 */
public class SignatureUtil {
    private static Logger LOGGER = LoggerFactory.getLogger(SignatureUtil.class);

    /**
    * 获取消息认证码
    *
    * @param clientSecret 密钥
    * @param requestMethod 请求方法
    * @param requestURI 请求URI
    * @param queryString url中的查询参数
    * @param bodyBytes 消息体
    * @return
    */
    public static String getSignature(final String clientSecret,
        final String requestMethod, final String requestURI,
        final String queryString, final byte[] bodyBytes) {
        try {
            String queryStringAfterDeal = StringUtils.isBlank(queryString) ? ""
                                                                           : URLDecoder.decode(queryString,
                    "utf-8");
            String payload = ((bodyBytes != null) && (bodyBytes.length > 0))
                ? new String(bodyBytes, "utf-8") : "";
            StringBuilder valueToDigest = new StringBuilder();
            valueToDigest.append(requestMethod).append(requestURI)
                         .append(queryStringAfterDeal).append(payload);

            return createSignature(clientSecret, valueToDigest.toString());
        } catch (Exception e) {
            LOGGER.error("createSignature error : {}", e);
        }

        return null;
    }

    /**
    * 生成消息认证码
    *
    * @param clientSecret 密钥
    * @param valueToDigest 待签名字段
    * @return
    */
    public static String createSignature(final String clientSecret,
        final String valueToDigest) {
        LOGGER.info("strValue to digest : {};clientSecret:{}", valueToDigest,
            clientSecret);

        final byte[] digest = HmacUtils.hmacSha256(clientSecret, valueToDigest);

        return Base64.encodeBase64String(digest);
    }

    public static void main(String[] args) {
        try {
            String clientSecret = "o8dk8vm6cbuyxdrl4se4c6i3h4tdea9b";
            String method = "POST";
            String requestURI = "/v1/open/device/list/get";
            String queryString = "client_id=f6f1ec55481b5dc314bd6555e4d3d3bb&timestamp=1556193552988";
            byte[] bodyBytes = "reqId:fe8234bf-e94c-4cdf-8ea9-c3112962ab01".getBytes(
                    "utf-8");
            String signature = SignatureUtil.getSignature(clientSecret, method,
                    requestURI, queryString, bodyBytes);
            System.out.println(signature); //输出结果:v+YGWmfylFSF9rhSPSYJAzo8IY+NZxhOdAhs9ii7Aig=
        } catch (Exception e) {
        }
    }
}

Golang版

package main

import("bytes""crypto/hmac""crypto/sha256""encoding/base64""fmt""net/url")

/**
 * 获取消息认证码
 * @param clientSecret 密钥
 * @param requestMethod 请求方法
 * @param requestURI 请求URI
 * @param queryString url中的查询参数
 * @param bodyBytes 消息体
 * @return
 */
func getSignature(clientSecret string, requestMethod string, requestURI string, queryString string, bodyBytes[] byte) string {
    var buffer bytes.Buffer buffer.WriteString(requestMethod) buffer.WriteString(requestURI) if queryString != "" {
        queryStringAfterDeal,
        _: =url.QueryUnescape(queryString) buffer.WriteString(queryStringAfterDeal)
    }
    buffer.WriteString(string(bodyBytes)) return createSignature(buffer.String(), clientSecret)
}

/**
 * 生成消息认证码
 * @param apiSecret 密钥
 * @param valueToDigest 待签名字段
 * @return
 */
func createSignature(valueToDigest string, clientSecret string) string {
    fmt.Println("valueToDigest=" + valueToDigest) fmt.Println("clientSecret=" + clientSecret) key: =[] byte(clientSecret) h: =hmac.New(sha256.New, key) h.Write([] byte(valueToDigest)) return base64.URLEncoding.EncodeToString(h.Sum(nil))
}

func main() {
    var clientSecret = "o8dk8vm6cbuyxdrl4se4c6i3h4tdea9b"
    var method = "POST"
    var requestURI = "/v1/open/device/list/get"
    var queryString = "client_id=f6f1ec55481b5dc314bd6555e4d3d3bb&timestamp=1556193552988"
    var bodyBytes = [] byte("reqId:fe8234bf-e94c-4cdf-8ea9-c3112962ab01") fmt.Println(getSignature(clientSecret, method, requestURI, queryString, bodyBytes))

}

NodeJs版

const crypto = require('crypto');

const urlencode = require('urlencode');

/**
* 获取消息认证码
* @param clientSecret 密钥
* @param requestMethod 请求方法
* @param requestURI 请求URI
* @param queryString url中的查询参数
* @param bodyBytes 消息体
* @return
*/
function getSignature(clientSecret, requestMethod, requestURI, queryString, bodyBytes) {
    var queryStringAfterDeal = queryString ? urlencode.decode(queryString, 'utf-8') : "";
    var payload = Buffer.from(bodyBytes).toString('utf-8');
    var valueToDigest = requestMethod + requestURI + queryStringAfterDeal + payload;
    return createSignature(valueToDigest, clientSecret);
}

/**
* 生成消息认证码
* @param apiSecret 密钥
* @param valueToDigest 待签名字段
* @return
*/
function createSignature(valueToDigest, clientSecret) {
    console.log("valueToDigest=" + valueToDigest);
    return crypto.createHmac('SHA256', clientSecret).update(valueToDigest).digest('base64');
}

module.exports = getSignature;

var clientSecret = "o8dk8vm6cbuyxdrl4se4c6i3h4tdea9b";
var method = "POST";
var requestURI = "/v1/open/device/list/get";
var queryString = "client_id=f6f1ec55481b5dc314bd6555e4d3d3bb&timestamp=1556193552988";
var bodyBytes = Buffer.from('reqId:fe8234bf-e94c-4cdf-8ea9-c3112962ab01', 'utf-8');
let signature = getSignature(clientSecret, method, requestURI, queryString, bodyBytes);
console.log(signature);

# 5.10 客户端加密说明

(1)说明

客户端对敏感信息加密时约定采用(AES/CBC/PKCS5Padding),其中IV通过伪随机数生成器生成,并且转成十六进制字符串后拼接在加密后的字符串前面,其中加密字符串也采用十六进制,解密的时候云端会把拼接在前面的iv变量截取下来再做解密。 伪代码示例(以clientSecret作为密钥来源数据为例):

byte[] iv=randomBytes(16);//1.生成随机IV值
byte[] key=subArray(SHA256(clientSecret.getBytes()),0,16);//2.处理clientSecret得到密钥字节数组,由clientSecret做SHA256后取字节数组前16字节
String sn;//3.待加密原文,如这里的uuid
return hexString(iv)+hexString(AES128CBC(uuid.getBytes(),key,iv))//4.最后把转成16进制字符串的IV字符串拼接在对称加密后的十六进制密文字符串前面,作为加密后的值

(2)实现示例

JAVA版


import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;


/**
 * @Description: AES对称加密(CBC模式-动态IV)
 * @Author: musilin
 * @Date: 2020-12-25
 * @Version: 1.0.0
*/
public class AESCBCForClient {

  /**
   * 对称加密算法类型
   */
  private static String Algorithm = "AES";
  /**
   * 定义算法/模式/补码方式
   */
  private static final String AES_CBC_ENCRYPTION_ALGORITHM = "AES/CBC/PKCS5Padding";

  /**
   * 默认IV长度
   */
  public static final int DEFAULT_IV_SIZE = 16;

  /**
   * 获取IV Byte
   *
   * @return 初始化向量
   */
  public static byte[] getIvByte() {
    final byte[] iv = new byte[DEFAULT_IV_SIZE];
    new SecureRandom().nextBytes(iv);
    return iv;
  }

  /**
   * 获取IV
   *
   * @return 初始化向量
   */
  public static IvParameterSpec getIv(byte[] iv){
    return new IvParameterSpec(iv);
  }

  /**
   * 加密(CBC模式)
   *
   * @param src 原文
   * @param keyByte 密钥字节数组,由访问令牌做SHA256后取字节数组前16字节
   */
  public static String encryptByCBC(String src, byte[] keyByte) throws NoSuchAlgorithmException, NoSuchPaddingException,
      InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException, InvalidAlgorithmParameterException {
    byte[] ivByte = getIvByte();
    IvParameterSpec ivParameterSpec = getIv(ivByte);
    String ivStr = byteToHexString(ivByte);
    return ivStr+byteToHexString(encrypt(src.getBytes("utf-8"), keyByte, AES_CBC_ENCRYPTION_ALGORITHM, ivParameterSpec));
  }

  /**
   * 加密
   *
   * @param srcByte 原文byte数组
   * @param keyByte 密钥byte数组
   * @param algorithmProvider 对称算法及对应模式
   */
  private static byte[] encrypt(byte[] srcByte, byte[] keyByte, String algorithmProvider, IvParameterSpec ivParameterSpec) throws NoSuchAlgorithmException, NoSuchPaddingException,
      InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException, InvalidAlgorithmParameterException {
    SecretKey secretKey = new SecretKeySpec(keyByte, Algorithm);
    Cipher cipher = Cipher.getInstance(algorithmProvider);
    cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);

    byte[] cipherBytes = cipher.doFinal(srcByte);
    return cipherBytes;
  }
  /**
   * 将byte转换为16进制字符串
   */
  public static String byteToHexString(byte[] src) {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < src.length; i++) {
      int v = src[i] & 0xff;
      String hv = Integer.toHexString(v);
      if (hv.length() < 2) {
        sb.append("0");
      }
      sb.append(hv);
    }
    return sb.toString();
  }

  public static void main(String[] args) {
    try {
      String src = "18826410885";
      String dynamicKey = "1234bafcb5943f67";
      System.out.println("密钥:" + dynamicKey);
      System.out.println("原文:" + src);
      String beforeDecryptStr = encryptByCBC(src, subArray(SHA256(dynamicKey.getBytes()),0,16));
      System.out.println("加密:" + beforeDecryptStr);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

最后修改于: 2025-04-02