这是用户在 2025-3-20 23:45 为 https://iot.mi.com/v2/new/doc/plugin/other/connection-wifi 保存的双语快照页面,由 沉浸式翻译 提供双语支持。了解如何保存?

控制 Wi-Fi 设备

更新时间:2025/02/18

小米 IoT 平台设备功能都是基于 Spec 模型来进行开发的。其连接与控制设备都是通过 Spec 功能定义中的属性(Properties)、事件(Event)或者方法(Action)来进行处理的。在 IoT 后台 - 产品 - 功能定义处可看到对应产品的具体功能定义。

也可以通过如下代码获取产品 Spec 功能定义的 JSON String:

javascript
Service.spec
  .getSpecString(Device.deviceID)
  .then((res) => {
  logger.i('spec string: ', res);
  })
  .catch((error) => {
  logger.e('getSpecString error', error);
  });

在开发者平台修改功能定义后,需要 2 小时才会同步更新。

连接与控制流程

Wi-Fi 设备连接与控制

在照明类产品中,以控制灯开启/关闭的属性是 siid = 2, piid = 1 为例。

在用户点击扩展程序关灯按钮后:

  1. 插件调用 setPropertiesValue 将 siid = 2, piid = 1 的属性值修改为 true;
  2. 请求发送到 IoT 平台服务端后,服务端发送下行 RPC 指令到设备;
  3. 这条指令(set_properties 2 1 true)最终由模组回复到 mcu 的 get_down 的轮询请求中;
  4. 当设备正确处理请求后,mcu 回复 result 2 1 0 给模组告知请求已成功处理;
  5. 最后一个数字 0 用于设备告知插件该请求的处理状态码:code
  6. 0 代表请求处理成功;
  7. 1 代表请求已经发送给设备,具体的处理结果需要等待设备发送 properties_changed 指令,一般只有网关才可能回复此 code
  8. 其他代表失败。
  9. 服务端得知 code = 0,将此 code 回复到插件 setPropertiesValue 请求的 then 回调内;
  10. 插件判断 code = 0,可以认为操作已经成功,展示灯已打开;

插件订阅相关属性/事件后,可以在 deviceReceivedMessages 回调中收到设备主动发出的属性/事件变更:

  1. 设备上报 properties_changed 2 1 true 之后,平台服务端发送推送给插件(如果插件已经订阅的话);
  2. 插件收到属性变更的回调后,在界面上展示灯已打开。

获取属性值

扩展程序可通过以下代码获取设备的各个属性值:

javascript
/**
 * 这里的 siid 和 piid 的获取,可以通过解析 getSpecString 获取的 spec 信息。
 * 也可以通过开发者平台上功能定义处查询该设备对应的设备属性 siid 和 piid 值。
 */

const params = [
  { did: Device.deviceID, siid: 1, piid: 1 },
  { did: Device.deviceID, siid: 2, piid: 1 }
];

Service.spec
  .getPropertiesValue(params)
  .then((res) => {
  logger.i('getPropertiesValue success ', res);
  // 注意判断 res 数组中每一个对象里面是否有 code
  // 如果有 code 说明数据获取失败了
  if (res?.length) {
  res.forEach((item) => {
  if (item.code) {
  // 具体错误码见下文 **Spec 请求错误码**
  logger.e('getPropertiesValue spec error: ', item);
  }
  });
  }
  })
  .catch((error) => {
  // 一般是网络原因或者请求参数问题
  logger.e('getPropertiesValue error ', error);
  });

监听属性/事件变化

获取设备属性值是一次网络请求,一般用于初始化属性值。

设备还会由于遥控器控制、其他用户操作等原因,使得其属性值发生改变。由于设备属性值发生变化,设备会上报 properties_changed。扩展程序可以监听属性值的变化,这样就不需要不断轮询 getPropertiesValue 来获取属性值。在属性值发生变化后,小米 IoT 平台会通过推送透传给扩展程序。

javascript
import { Component } from 'react';
import { Device, DeviceEvent } from 'miot';
import Service from 'miot/Service';

class SwitchSub extends Component {
  constructor(props) {
  super(props);
  // 第 1 步:初始化 state 数据
  // 这里以开关 prop.2.1 为例
  this.state = {
  switch: false
  };
  }

  componentDidMount() {
  // 第 2 步:使用网络请求初始化属性值
  Service.spec
  .getPropertiesValue([{ did: Device.deviceID, siid: 2, piid: 1 }])
  .then((res) => {
  this.onReceiveData(res);
  logger.i('Initial value: ', res);
  })
  .catch((err) => {
  logger.e("Init prop's value error: ", err);
  });

  // 第 3 步:订阅属性值变化
  Device.getDeviceWifi()
  .subscribeMessages('prop.2.1')
  .then((sub) => {
  logger.i('Sub props successfully');
  this.subscription = sub;
  })
  .catch((err) => {
  logger.e('Sub props failed: ', err);
  });

  // 第 4 步:接受属性值变化回调
  this.event = DeviceEvent.deviceReceivedMessages.addListener(
  (device, map, data) => {
  this.onReceiveData(data);
  }
  );
  }

  onReceiveData(data) {
  // 在此格式化 data 数据并 setState
  // 注意:初始化属性值请求(getPropertiesValue)和订阅的属性值变化(deviceReceivedMessages)
  // 返回的数据格式不同
  // 第 5 步:格式化数据并 setState
  if (!data || !data.length) return;
  for (let d of data) {
  if (d.key === 'prop.2.1' || (d.siid === 2 && d.piid === 1)) {
  let value = d.value;
  if (Array.isArray(value)) {
  value = value[0];
  }
  if (
  value !== undefined &&
  typeof value === 'boolean' &&
  this.state.switch.value !== value
  ) {
  this.setState({
  switch: value
  });
  }
  break;
  }
  }
  }

  componentWillUnmount() {
  // 第 6 步:在 componentWillUnmount 中移除监听
  this.subscription && this.subscription.remove();
  this.event && this.event.remove();
  }
}

设备上报事件(event_occured)和 properties_changed 一样也是可以被扩展程序订阅的。事件订阅具体用法和 properties_changed 保持一致。

比如 siid = 2, eiid = 1020 的事件,只需要将上述 prop.2.1 替换成 event.2.1020 即可。

第二步初始化时,事件不像属性一样可以获取到具体的 value 值,不过可以获取事件上报的历史记录(SDS)。

具体使用参考属性/事件历史记录

控制设备

控制设备一般来说是修改设备的属性值(set_properties)或者执行设备功能定义中的方法(action)。

修改设备的属性值

javascript
const params = [
  {
  did: Device.deviceID,
  siid: 2,
  piid: 1,
  value: true
  }
];

Service.spec
  .setPropertiesValue(params)
  .then((result) => {
  if (result instanceof Array && result.length >= 1) {
  const res = result[0];
  if (res.code === 0) {
  // code === 0 说明设置成功,可直接 setState
  logger.i('setPropertiesValue success: ', res);
  } else {
  // 其他 code 可等待订阅返回结果
  // 具体错误码见下文 **Spec 请求错误码**
  logger.i('setPropertiesValue with code: ' + res);
  }
  } else {
  // 其他异常
  logger.w('setPropertiesValue unknown error: ' + res);
  }
  })
  .catch((err) => {
  logger.e('setPropertiesValue error: ' + err);
  });

执行设备功能定义中的方法

javascript
Service.spec
  .doAction({
  did: Device.deviceID,
  siid: 2,
  aiid: 1,
  in: [true, 'shanghai'] // 在 in 数组内按顺序填入功能定义中需要的参数值
  })
  .then((res) => {
  if (res?.length && res[0].code) {
  // 具体错误码见下文 **Spec 请求错误码**
  logger.e('doAction error: ', res);
  } else {
  logger.i('doAction success: ', res);
  }
  })
  .catch((err) => {
  logger.e('doAction error: ', err);
  });

云端缓存与 RPC

扩展程序获取设备属性值的时候,为减小设备压力,默认会直接读取云端缓存值,而不是直接下发请求到设备获取。云端缓存值仅在设备上报 properties_changed 的时候会更新。某些执行设备方法(doAction)的产品逻辑上,设备内部会更新属性值,但是没上报 properties_changed。这种情况缓存值也不会更新。

如果没有缓存值,IoT 云端会下发请求到设备(RPC 请求)获取属性值,然后将设备返回的值透传给扩展程序。

开发者在 getPropertiesValue 获取属性值的时候。如果不想使用 SDK 默认的获取策略,可以修改 getPropertiesValue 函数第二个参数 datasource

javascript
// 自行构造参数
const params = [];
/**
 *
 * datasource=1 优先从服务器缓存读取,没有读取到下发 rpc;不能保证取到的一定是最新值。(默认)
 * datasource=2 直接下发 rpc,每次都是设备返回的最新值。会增加上报量和设备压力。
 * datasource=3 直接读缓存;没有缓存的 code 是 -70xxxx;可能取不到值。
 * 建议 datasource=1 或 datasource=3,以减轻后台服务的压力。
 *
 */

const datasource = 1;

Service.spec
  .getPropertiesValue(params, datasource)
  .then((res) => logger.i('res: ', res))
  .catch((err) => logger.e('err: ', err));

Spec 问题排查

  1. 插件网络请求数据可以在插件控制台打印,抓包查看请求数据等;
  2. 插件 Spec 请求报错可以查看下文 Spec 请求错误码 进行排查;
  3. 如果碰到 Spec 报错,且根据错误码也排查不出问题的情况,请检查是否使用了非白名单用户测试白名单固件;
  4. 开发者平台是否发送 RPC 请求到设备以及设备是否正确回复可以在开发者平台查询通信日志数据;
  5. 日志数据可能会延迟一个小时左右;
  6. 下行日志指的是 IoT 服务端(插件)发送给设备的请求;
  7. 上行日志指的是设备上报给 IoT 服务端的请求。
  8. 排查固件日志是否正常。

Spec 请求错误码

调用接口后,若开发者收到扩展程序返回的错误码(-70xxxyzzz),开发者可按照如下内容排查问题。

错误码格式:

  • xxx:HTTP 标准状态码
  • y:出现错误的位置
  • zzz:错误码
出错的位置出错的位置
0插件1开放平台
2设备云3设备
4MIOT-SPEC
出错位置
错误码说明故障解决
-705001000开放平台服务器内部错误可能的原因:
  1. 请检查 Spec 操作时参数是否正确。
  2. 请检查是否是非白名单用户测试白名单固件。
  3. 请检查当前用户是否有权使用设备的固件版本。
-706012000三方云服务器内部错误云对云特有原因:

请检查三方云的回应是否正常。

  1. 比如 siid 和 piid 等数据应该为数字,不能是字符串。
  2. type 应该填写 Spec urn,而不能是 model 等信息。
-705004000MIoT Spec 服务器内部错误可能的原因:
  1. 请检查 Spec 操作时参数是否正确。
  2. 请检查是否是非白名单用户测试白名单固件。
  3. 请检查当前用户是否有权使用设备的固件版本。
-705005000订阅 ID(subscriptionId) 编码错误-
-705006000notify error-
-704002000设备错误(通用)
三方云请求参数不正确
此错误一般是设备对扩展程序的 Spec 操作返回了错误码导致。请自行在控制台 - 运营 - 通信日志查看设备的原始错误码。

可能的原因:
  1. 扩展程序操作 Spec 太频繁导致设备/网关没法处理进而报错。
  2. 设备/网关网络不好或设备/网关自身原因导致未及时回复扩展程序的 Spec 请求。

    如果是需要网关的设备,且回复的 description 字段为 get rpc invalid code:-9。请尝试重启网关后再试。

  3. 如果是获取属性值,网关没有当前属性的缓存值。

    需要扩展程序等待网关获取到缓存值后再试。

  4. 操作了功能定义中没有的属性或者方法导致设备报错。
  5. 设置的属性值/执行方法携带的属性值无法被设备处理导致设备报错。
BLE/BLE Mesh 设备特有的原因:
  1. 设备没有 properties_changed 上报,扩展程序就去获取属性导致网关报错。

    具体原理请参考米家 BLE Mesh 支持的功能

  2. 固件侧的模板没有跟平台功能定义侧选择的一样导致网关无法正常处理。

    请将固件侧的模板正确修改后,重新绑定设备。

  3. 修改功能定义后立即开始测试 Spec 功能。

    修改功能定义后,请等待 30 分钟后重启网关再进行测试。

小爱语控特有的原因:
    当前控制依赖的智能场景被用户删除导致无法控制。
云对云接入特有原因:

  1. 请求参数不正确。
  2. 云应用没有权限。
-702000000OK-
-702010000accept-
-704010000未认证BLE 设备特有原因:
  1. 扩展程序获取属性时,设备还未通过 properties_changed 上报属性值。

    请扩展程序等待设备上报属性值后重试,或排查设备属性上报流程是否正确。

  2. 设备已经上报过属性值,但是由于老网关上报规则的限制,导致上报不成功。

    请使用新网关进行测试,或等待第二天再进行测试。

  3. BLE 设备不支持通过网关下发 RPC 指令。
    1. 可能是扩展程序通过 getPropertiesValue(params, 2) 接口获取属性值,将第二个参数设置成 2。即仅通过向设备下发 RPC 指令获取属性值。请将第二个参数设置成 3 或不设置第二个参数。
    2. 或者通过网关对 BLE 设备进行了执行方法操作。BLE 设备不支持通过网关发送下行指令。请通过蓝牙直连操作,不要通过网关执行方法。
灯组特有原因:
    当前灯(或者子灯组)在灯组内,不能由小爱进行控制。设计上,小爱只能控制最上层的灯组。
网关子设备特有原因:
    将子设备共享给其他用户,但是没有共享网关,导致其他用户无法控制设备。请将网关也共享给其他用户。
云对云/独立 App 特有原因:
  1. 应用未注册,无权限控制。
  2. 应用刚获取审批,需要时间才能同步。

    请等待半小时后再试。

  3. 请求参数错误。
小爱语控特有原因:
    特定的老设备不支持被小爱语控控制
可能的原因:
  1. 设备已经被解绑,无法执行 Spec 指令。

    请检查设备绑定状态。

  2. 子状态码为:-40121111 时请提交工单检查设备后台配置是否被标记为 不支持 Spec
-704000000错误的请求云对云/独立 App 特有原因:
  1. 应用未注册,无权限控制。
  2. 应用刚获取审批,需要时间才能同步。

    请等待半小时后再试。

  3. 请求参数错误。
-704000001错误的请求体可能的原因:
    请求参数或请求体错误。
-704001000定时只支持小米设备-
-702022036操作正在处理中可能的原因:
  1. 当前写入的属性值或者执行方法正在操作中。

    可能是操作太频繁导致上一次写入操作还在进行中。

  2. 获取设备列表时间太长。

    可能是用户的设备太多,请稍候再试。

云对云特有原因:
    上一次的写入操作,三方云服务超时未回应。
-704042010
  1. 触发场景异常。
  2. 获取设备列表失败。
-
-704042009未找到场景-
-704042012场景无权限-
-704090001未找到设备可能的原因:
  1. 白名单权限问题,请规范测试流程。
    1. 非白名单用户使用白名单固件,请使用白名单账户进行测试。
    2. 将用户添加到白名单让用户绑定设备后,再次将用户白名单权限移除。
    3. 白名单用户将设备共享给非白名单用户使用。
    4. 用户刚被加入到白名单,添加完白名单后请等待半小时后再试。
云对云特有原因:
    三方云告知米家设备不存在。
-704042001未找到设备-
-704042011设备离线可能的原因:
    设备已经离线,请检查设备网络。
-704012901token 不存在或过期-
-704012902token 非法-
-704012903授权过期-
-704012904设备未授权控制能力给小爱可能的原因:
  1. 白名单权限问题,非白名单用户测试白名单产品导致小爱无法控制设备。
  2. 设备未授权控制能力给小爱。

    请在「米家 App - 我的 - 语音控制 - 语音控制授权管理」中打开控制权限。

  3. 操作的设备已经被解绑。
-704012905设备未绑定可能的原因:
    设备已经被解绑,无法执行 Spec 指令。请检查设备绑定状态。
-704012906认证失败-
-704040002服务不存在可能的原因:
  1. 服务(Service)不存在,请对照功能定义检查 siid 是否存在。
  2. 如果功能定义有多个版本,请检查当前固件关联的功能定义版本是否包含操作的服务。
  3. 如果操作的服务刚添加,请等待半小时后再操作。
-706010002远程服务异常可能的原因:
    设备对于控制指令不能正确处理。请在控制台 - 运营 - 通信日志查询设备对于此控制返回的状态码。
-706010004MIoT 错误-
-706010005属性缓存失败-
-704040003属性不存在可能的原因:
  1. 属性(Property)不存在,请对照功能定义检查 siidpiid 是否存在。
  2. 如果功能定义有多个版本,请检查当前固件关联的功能定义版本是否包含操作的服务。
  3. 如果操作的属性刚添加,请等待半小时后再操作。
-704030013属性不可读可能的原因:
  1. 功能定义中设置了该属性(Property)没有读(read)权限,请对照功能定义检查属性权限。
  2. 设备告知读取属性失败。

    设备在 RPC 指令的回复中,回复了错误码 -4001。请在控制台 - 运营 - 通信日志查询设备通信日志并结合固件日志排查问题。

-704030023属性不可写可能的原因:
  1. 功能定义中设置了该属性(Property)没有写(write)权限,请对照功能定义检查属性权限。
  2. 设备告知写属性失败。

    设备在 RPC 指令的回复中,回复了错误码 -4002。请在控制台 - 运营 - 通信日志查询设备通信日志并结合固件日志排查问题。

-704030033属性不可上报可能的原因:
    功能定义中设置了该属性(Property)没有上报(notify)权限,请对照功能定义检查属性权限。
-704030992请求过于频繁,本次请求被拒绝可能的原因:
    请求太频繁,请降低请求频率。
-704220043属性值不正确可能的原因:
  1. 扩展程序或三方云 set_properties 时,传递的 value 值不符合功能定义的要求。

    比如功能定义设置该属性格式为 int32,但是传入的是 string

  2. 设备或三方云 get_properties 的返回结果,传递的 value 值不符合功能定义的要求。

    比如功能定义设置该属性格式为 int32,但是传入的是 string。请自行获取固件日志排查。

  3. 设备对于控制指令没有响应,导致模组向云端回复 user ack timeout(如果是 Android OT 或 Linux OT,会向云端回复 busy)。

    请结合固件日志排查固件业务逻辑问题。

  4. 设备对于控制指令不能正确处理。

    请在控制台 - 运营 - 通信日志查询设备对于此控制返回的状态码并结合固件日志排查问题。

灯组特有原因:
    暂时无法控制未上线设备组成的灯组,请查看帮助中心进行解决。
-705201013读属性失败-
-706012013读属性失败云对云特有原因:
  1. 三方云对 set_properties 请求回复了错误码导致设置失败。
  2. 无法从三方云获取到属性值,请检查三方云返回数据是否正确。
-706012014读属性失败-
-705201023写属性失败-
-706012023写属性失败云对云特有原因:
    无法从三方云返回结果中获取到设定的属性值,请检查三方云返回数据是否正确。
红外设备特有原因:
    不支持的红外码库,请提交工单进行人工排查更新。
-705201033上报属性失败-
-706012033上报属性失败-
-706012043订阅失败-
-704040004事件不存在可能的原因:
  1. 事件(Event)不存在,请对照功能定义检查 siideiid 是否存在。
  2. 如果功能定义有多个版本,请检查当前固件关联的功能定义版本是否包含操作的事件。
  3. 如果操作的事件刚添加,请等待半小时后再操作。
-704222034事件参数数量不匹配可能的原因:
  1. 设备上报事件( event_ocured )时,携带的参数数量和功能定义中的数量不一致。
  2. 如果功能定义有多个版本,请检查当前固件关联的功能定义版本中的事件参数数量。
  3. 如果操作的事件刚修改,请等待半小时后再操作。
-704040005方法不存在可能的原因:
  1. 方法(Action)不存在,请对照功能定义检查 siidaiid 是否存在。
  2. 如果功能定义有多个版本,请检查当前固件关联的功能定义版本是否包含操作的方法。
  3. 如果操作的方法刚添加,请等待半小时后再操作。
-705201015方法执行失败-
-706012015方法执行失败可能的原因:
    设备告知方法执行失败。设备在 RPC 指令的回复中,回复了非 0 code,请在控制台 - 运营 - 通信日志查询设备通信日志并结合固件日志排查问题。
-704220035方法输入参数错误可能的原因:
  1. 方法输入参数值错误。请检查功能定义中输入参数值的格式要求。

    比如功能定义设置某个属性格式为 int32,但是传入的是 string

  2. 设备告知方法输入参数错误。

    设备在 RPC 指令的回复中,回复了错误码 -4006。请在控制台 - 运营 - 通信日志查询设备通信日志并结合固件日志排查问题。

-704220025方法输入参数数量不匹配可能的原因:
  1. 扩展程序或三方云 doAction / action 时,输入的参数数量和功能定义中的输入参数数量不匹配。

    请对比功能定义检查参数中 in 数组的内容。

  2. 如果功能定义有多个版本,请检查当前固件关联的功能定义版本中的方法输入参数数量。
  3. 如果操作的方法刚修改,请等待半小时后再操作。
BLE Mesh 设备特有原因:
    BLE Mesh 设备通过网关执行方法时,最多只支持一个参数。请修改功能定义或使用蓝牙直连执行此方法。
-704222035方法输出参数数量不匹配或参数错误可能的原因:
  1. 设备对于 action 操作的回复中,输出的参数数量和功能定义中的输出参数数量不匹配或参数值错误。

    请对比功能定义检查参数中 out 数组的内容。

  2. 如果功能定义有多个版本,请检查当前固件关联的功能定义版本中的方法输出参数数量以及参数值格式。
  3. 如果操作的方法刚修改,请等待半小时后再操作。
-704044006未找到功能定义可能的原因:
  1. 此设备还未初始化功能定义,请初始化后等待半小时后再试。
  2. 功能定义刚初始化,请等待半小时后再试。
-705204006非法的功能定义可能的原因:
    功能定义中,某些属性的范围超过了属性格式的范围。比如属性格式为 int32,其数值范围最大值不能大于 2147483648,最小值不能小于 -2147483647
-705204007实例未加载-
-704041007cloud not found-
-704220008非法的 ID(SIID、PIID、EIID、AIID)可能的原因:
  1. 设备告知属性/方法/事件不存在。

    设备在 RPC 指令的回复中,回复了错误码 -4003。请在控制台 - 运营 - 通信日志查询设备通信日志并结合固件日志排查问题。

  2. 服务、属性、事件或方法不存在。

    请对照功能定义检查 siidpiideiid 以及 aiid 是否存在。

  3. 如果功能定义有多个版本,请检查当前固件关联的功能定义版本是否包含操作的服务。
  4. 如果操作的服务、属性、事件或方法刚添加,请等待半小时后再操作。
  5. 设备当前固件版本没有在开发者平台开启测试。
-704220009非法的 uid-
-704220010非法的订阅 ID(subscriptionId)-
-704053100无法执行此操作可能的原因:
    设备告知执行操作失败。

    设备在 RPC 指令的回复中,回复了非 0 code。请在控制台 - 运营 - 通信日志查询设备通信日志并结合固件日志排查问题。

-704083036操作超时可能的原因:
  1. 设备告知操作超时。

    设备在 RPC 指令的回复中,回复了错误码 -3。请在控制台 - 运营 - 通信日志查询设备通信日志并结合固件日志排查问题。

  2. 设备固件对于 Spec 请求没进行回复,导致模组/OT 自动回复 -3 超时,请结合固件日志排查问题。
-704040999功能未上线-
-704013101红外设备不支持此操作-
-704053101摄像机休眠中-
错误码
点评文档,助力小编更优秀!
意见反馈