米家 MIOT React Native 插件 SDK — 项目架构与插件设计说明
·
米家 MIOT React Native 插件 SDK — 项目架构与插件设计说明
SDK API_LEVEL: 10117 | 框架: React Native 0.61.0 + React 16.9.0 + React Navigation 2.x
米家开发者平台:https://iot.mi.com/
一、项目整体架构
miot-plugin-sdk/ ← 工作空间根目录(不允许修改根 package.json)
├── miot-sdk/ ← 核心 SDK(只读引用,不修改)
│ ├── Device.js ← 设备入口(WifiDevice / BluetoothLE)
│ ├── Service.js ← 服务层聚合(spec / scene / smarthome / storage...)
│ ├── Package.js ← 插件包管理(entry / entrance / exit)
│ ├── Host.js ← 宿主能力(文件系统、系统信息、语言)
│ ├── device/ ← 设备抽象
│ │ ├── BasicDevice.js ← 通用设备基类
│ │ ├── WifiDevice.js ← WiFi 设备(subscribeMessages / loadProperties / callMethod)
│ │ └── bluetooth/ ← 蓝牙设备(connect / discoverServices / write / setNotify)
│ ├── service/
│ │ ├── spec.js ← Spec 协议读写(getPropertiesValue / setPropertiesValue / doAction)
│ │ ├── scene.js ← 场景/定时
│ │ ├── smarthome.js ← 智能家居通用接口
│ │ └── storage.js ← 本地存储
│ ├── ui/ ← 通用 UI 组件库
│ │ ├── NavigationBar ← 导航栏
│ │ ├── CommonSetting/ ← 通用设置(分享、固件升级、更多)
│ │ ├── ListItem, Card, Dialog, ColorPicker... ← 可复用 UI 原子
│ │ └── ...
│ ├── resources/ ← SDK 内置多语言和样式
│ ├── hooks/ ← 内置 hooks
│ └── utils/ ← 工具函数
│
├── projects/ ← 所有设备插件项目(每个独立 npm 包,互不引用)
│ └── com.xiaomi.fan/ ← 风扇(示例)
│
├── bin/ ← CLI 工具
│ ├── createProject.js ← 创建项目
│ ├── runProject.js ← 启动调试
│ └── template/ ← 项目模板(empty / common / wifi / ble)
├── doc-md/ ← SDK 文档(设备管理、蓝牙、功能接口、UI 组件)
└── eslint-mihome-plugin/ ← 自定义 ESLint 规则
核心约束
| 规则 | 说明 |
|---|---|
根 package.json 不可修改 |
修改会导致在线打包失败 |
第三方库只能装在 projects/xxx/ 下 |
cd projects/xxx && npm install --save xxx |
| 项目间不互相引用 | 每个 projects/ 下的项目是独立沙箱 |
二、设备通信协议
2.1 Spec vs Profile
| Profile(旧协议) | Spec / miot-spec(新协议) | |
|---|---|---|
| 年代 | 2019 年前的设备 | 现在的主流设备 |
| 属性标识 | 字符串名 "power" |
数字索引 siid:2, piid:1 |
| 读属性 | loadProperties('power', 'temperature') |
getPropertiesValue([{did, siid, piid}]) |
| 写属性 | callMethod('set_power', ['on']) |
setPropertiesValue([{did, siid, piid, value}]) |
| 订阅格式 | prop.power |
prop.2.1 |
| 方法调用 | callMethod('button_pressed') |
doAction({did, siid, aiid, in:[]}) |
新设备统一用 Spec 协议,Profile 仅作历史兼容。
2.2 WiFi vs BLE 通信链路
WiFi 设备 — 服务端中转:
插件下发请求
→ setPropertiesValue([{did, siid, piid, value}])
→ 云端 → 设备 → 设备上报属性变更
→ DeviceEvent.deviceReceivedMessages 回调
→ 插件更新 UI
BLE 设备 — 直连蓝牙:
插件主动发起
→ checkBluetooth → startScan → connect
→ discoverServices → discoverCharacteristics
→ setNotify(读特征) / write(写特征)
→ BluetoothEvent 各类事件回调
→ 插件更新 UI
三、插件项目的三层分层设计
每个设备插件项目内部,推荐拆为三层:
各层职责边界:
| 层 | 只管什么 | 不管什么 |
|---|---|---|
| 通信层 | spec 协议读写、订阅/取消订阅、pending 防回退、错误码处理 | UI 长什么样 |
| UI 组件层 | 渲染、手势、动画、局部交互 | 数据从哪来、怎么发给设备 |
| 调度层 | 持有全局 state、组合通信层和 UI 层、处理跨组件逻辑(模式切换缓存、禁启用联动) | 具体某个属性的协议细节 |
四、项目入口与路由
4.1 标准入口链
index.js
→ 配置 Package.disableAutoCheckUpgrade(WiFi 自动检测固件升级)
→ 监听 PackageEvent.packageAuthorizationCancel(用户撤销授权 → 清缓存 + 退出)
→ Package.entry(App)
App(class 组件)
→ 根据 Package.entrance 决定初始路由
• Entrance.Main → MainPage(从设备列表点击进入)
• Entrance.Scene → ScenePage(从场景/自动化进入)
→ createStackNavigator 注册所有页面
→ 统一 NavigationBar 配置(title/left/right)
→ 配置页面切换动画(interpolator)
4.2 典型页面路由
MainPage ─→ SettingPage (设置)
─→ ScenePage (场景)
─→ XiaoAiPage (小爱训练)
SettingPage
└── CommonSettingPage(分享、固件升级、更多设置)
五、国际化(i18n)方案
推荐方案(简洁,适合多数项目)
// utils/Strings.js
import Host from 'miot/Host';
const LANGUAGE = Host.locale.language; // 'zh' | 'en'
const getStrings = (strings) => strings[LANGUAGE] || strings.en;
const Strings = getStrings({
zh: { power: '开关', setting: '设置', ... },
en: { power: 'Power', setting: 'Settings', ... },
});
export default Strings;
// 使用
<Text>{Strings.power}</Text>
支持占位符:'电量 {level}%' → formatString(Strings.battery, {level: 80}) → 电量 80%
模板方案(多语言,15种)
// resources/strings/index.js
import { Resources } from 'miot';
import { Language } from 'miot/resources';
// switch-case 按语言加载对应 .js 文件
六、新设备插件开发流程
Step 1 — 创建项目
npm run create com.xxx.yyy.zzz -type wifi # WiFi 设备
npm run create com.xxx.yyy.zzz -type ble # BLE 设备
npm run create com.xxx.yyy.zzz -type common # 通用模板
Step 2 — 定义 spec 属性映射
在 utils/constant.ts 中定义:
// 1. ValueType 枚举
export const ValueType = { bool: 0, uint8: 1, uint16: 3, uint32: 5, ... };
// 2. AttrKey — 属性映射(从设备 spec 文档获取 siid/piid/type)
export const AttrKey = {
power: { key: 'power', siid: 2, piid: 1, type: ValueType.bool },
// ... 按设备 spec 逐个添加
};
// 3. FormatPropsKey — 上报格式转换
export const FormatPropsKey = {
"prop.2.1": AttrKey.power.key,
// ...
};
// 4. Attr — 属性枚举值
export const Attr = {
light: { off: 0, on: 1, ... },
// ...
};
Step 3 — 搭建 MainPage(调度层)
复用自定义通信层骨架
Step 4 — 开发 UI 组件
按设备功能拆分 Presentational 组件,每个组件:
- 只接收 props(数据 + 回调)
- 不 import AttrKey 或 Service.spec
- 可复用 SDK 内置 UI(ListItem, Card, ColorPicker…)
Step 5 — 配置路由和入口
project.json— 设置min_sdk_api_levelindex.js—Package.entry(App)App— 注册路由、配置入口分发SettingPage— 配置 CommonSetting(分享、固件升级等)
Step 6 — 国际化
utils/Strings.js— 中英文文案- 所有用户可见文字通过
Strings.xxx引用,不硬编码中文
Step 7 — 调试与发布
npm start com.xxx.yyy.zzz # 启动调试(米家 APP 扫码)
npm run publish com.xxx.yyy.zzz # 发布构建
七、快速参考
常用 SDK API
import { Package, Device, Service, Host, DeviceEvent } from 'miot';
import { PackageEvent, BluetoothEvent } from 'miot';
import { NavigationBar, CommonSettingPage, SETTING_KEYS } from 'miot/ui';
import { Resources, Styles } from 'miot/resources';
常用设备操作
// WiFi Spec 设备
Service.spec.getPropertiesValue([{did, siid, piid}])
Service.spec.setPropertiesValue([{did, siid, piid, value}])
Device.getDeviceWifi().subscribeMessages('prop.2.1', 'prop.3.1')
// BLE 设备
Bluetooth.checkBluetoothIsEnabled()
Bluetooth.startScan(timeout, ...serviceUUIDs)
Device.getBluetoothLE(peripheralUUID).connect()
bleDevice.getService(uuid).getCharacteristic(uuid).setNotify(true)
bleDevice.getService(uuid).getCharacteristic(uuid).write(value)
// 通用
Device.name / Device.model / Device.deviceID / Device.isOnline / Device.isOwner
Host.locale.language
Package.exit()
更多推荐


所有评论(0)