@s25g5d4/mi-aqara-sdk

xiaomi & aqara sdk

Usage no npm install needed!

<script type="module">
  import s25g5d4MiAqaraSdk from 'https://cdn.skypack.dev/@s25g5d4/mi-aqara-sdk';
</script>

README

mi-aqara-sdk

作者:jsonzhou 2018/02/10

小米(xiaomi)、绿米(aqara)、米家智能家庭(mijia)开发工具库。

背景

小米IoT开发者平台不支持个人开发者申请,有一些极客的玩法没有API实现不了。通过mi-aqara-sdk可以在Node.js平台实现米家智能家庭的互联互通。

mi-aqara-sdk只在局域网中通讯,使用的协议或机制主要有:udp协议,组播,AES加解密。

基本使用

安装

npm install --save-dev mi-aqara-sdk

使用

const MiAqara = require('mi-aqara-sdk');
MiAqara.create(gateways, opts); // 创建
MiAqara.start(); // 启动

接口

create(gateways, opts) 创建SDK服务

  • gateways 网关列表,支持数组(多个)或对象(单个)
    • sid 网关设备ID (获取方式见文末)
    • password 网关密码 (获取方式见文末)
    • iv [可选]加密初始向量,有默认值
  • opts 服务选项
    • multicastAddress 组播IP,默认:224.0.0.50
    • multicastPort 组播端口,默认:4321
    • serverPort 服务监听端口,默认:9898
    • bindAddress SDK所在设备具有多网络时需要设置
    • onReady 网关及子设备已就绪, 多个网关可能会调用多次
    • onMessage 所有消息回调

示例

    MiAqara.create([{
        sid: '7811dcb28bde',
        password: '**A68343AD********'
    }], {
        onReady (msg) { // 网关及子设备已找到, 多个网关可能会调用多次
            // console.log('onReady', msg);
        },
        onMessage (msg) { // 所有消息类型
            // console.log('onMessage', msg);
        }
    });

事件onReady,onMessage中的msg结构示例

{
    "cmd": "read_ack",
    "model": "switch",
    "sid": "158d0001bf542b",
    "short_id": 2124,
    "data": "{\"voltage\":3012}"
}

cmd枚举列表(消息类型)

  • iam 查找网关时,网关的响应包
  • get_id_list_ack 网关查找子设备列表时消息响应
  • report 网关及子设备状态变化时主动上报
  • read_ack 读设备时消息响应
  • write_ack 写设备时消息响应
  • heartbeat 心跳包,网关每10秒钟发送一次, 主要更新网关token。子设备心跳,插电设备10分钟发送一次,其它1小时发送一次
  • server_ack 通用回复, 如发送报文JSON解析出错,会回复此事件

start() 启动,一般创建完后马上启动

MiAqara.start();

getGatewayBySid(sid) 根据网关设备ID查找网关对象

MiAqara.getGatewayBySid('7811dcb28bde')

getGatewayList() 获取所有网关列表数组

MiAqara.getGatewayList();

controlLight(opts) 控制彩灯

  • opts.sid 网关设备ID
  • opts.power 开关
  • opts.hue 色相
  • opts.saturation 饱和度
  • opts.brightness 亮度

关灯

MiAqara.controlLight({sid:'7811dcb28bde',power:false});

开灯

MiAqara.controlLight({sid:'7811dcb28bde',power:true});

getDeviceBySid(sid) 获取所有子设备(感应器)列表数组

MiAqara.getDeviceBySid('158d0001b8849f');

getDevicesByGatewaySid(gatewaySid) 根据网关ID查找所属子设备列表

MiAqara.getDevicesByGatewaySid('7811dcb28bde');

getDevicesByGatewaySidAndModel(gatewaySid, model) 根据网关ID及子设备型号查找所属子设备列表

获取网关下所有开关子设备

MiAqara.getDevicesByGatewaySidAndModel('7811dcb28bde', 'switch');

子设备型号及中英文名称对照

以下key为model(型号)

const DEVICE_MAP = {
    'gateway': {name:'Gateway', name_cn:'网关'},
    'magnet': {name:'ContactSensor', name_cn:'门窗磁传感器'},
    'motion': {name:'MotionSensor', name_cn:'人体感应'},
    'switch': {name:'Button', name_cn:'按钮'},
    'sensor_ht': {name:'TemperatureAndHumiditySensor', name_cn:'温度湿度传感器'},
    'ctrl_neutral1': {name:'SingleSwitch', name_cn:'单按钮墙壁开关'},
    'ctrl_neutral2': {name:'DuplexSwitch', name_cn:'双按钮墙壁开关'},
    'ctrl_ln1': {name:'SingleSwitchLN', name_cn:'单按钮墙壁开关零火版'},
    'ctrl_ln2': {name:'DuplexSwitchLN', name_cn:'双按钮墙壁开关零火版'},
    '86sw1': {name:'SingleButton86', name_cn:'86型无线单按钮开关'},
    '86sw2': {name:'DuplexButton86', name_cn:'86型无线双按钮开关'},
    'plug': {name:'PlugBase', name_cn:'插座'},
    '86plug': {name:'PlugBase86', name_cn:'86型墙壁插座'},
    'cube': {name:'MagicSquare', name_cn:'魔方'},
    'smoke': {name:'SmokeDetector', name_cn:'烟雾警报器'},
    'natgas': {name:'NatgasDetector', name_cn:'天然气警报器'},
    'curtain': {name:'ElectricCurtain', name_cn:'电动窗帘'},
    'sensor_magnet.aq2': {name:'ContactSensor2', name_cn:'门磁感应 第二代'},
    'sensor_motion.aq2': {name:'MotionSensor2', name_cn:'人体感应 第二代'},
    'sensor_switch.aq2': {name:'Button2', name_cn:'按钮 第二代'},
    'weather.v1': {name:'TemperatureAndHumiditySensor2', name_cn:'温度湿度传感器 第二代'},
    'sensor_wleak.aq1': {name:'WaterDetector', name_cn:'水浸传感器'}
};

getDevicesByModel(model) 根据型号获取所有对应子设备

所有开关设备,包括挂载在不同网关的上子设备

MiAqara.getDevicesByModel('switch')

getDeviceList() 获取所有子设备列表数据

MiAqara.getDeviceList()

change ({sid, gatewaySid, model, data}) 子设备状态变更

  • change({sid,data}) 改变指定设备(子设备ID:sid)的状态
  • change({gatewaySid, model, data}) 改变指定网关下挂载的指定型号的子设备状态
  • change({model, data}) 改变所有指定型号的子设备状态

其它说明

一、设备状态data结构说明 (部份)

门窗磁传感器 (model: magnet)

{
    "status": "close" //close:关闭; open:打开
}

人体感应器 (model: motion)

{
    "status": "motion" //motion:有人移动
}
// 或
{
    "no_motion" "120" //120秒没人移动
}

开关/按钮 (model: switch)

{
    "status": "click" //click:单击; double_click:双击
}

温度湿度传感器 (model: sensor_ht)

{
    "temperature": "1741",
    "humidity": "7593"
}

单按钮墙壁开关 (model: ctrl_neutral1)

{
    "channel_0": "on" //off是关闭
}

双按钮墙壁开关 (model: ctrl_neutral2)

{
    "channel_0": "on",
    "channel_1": "off"
}

单按钮墙壁开关零火版 (model: ctrl_ln1)

{
    "channel_0": "on" //off是关闭
}

双按钮墙壁开关零火版 (model: ctrl_ln2)

{
    "channel_0": "on",
    "channel_1": "off"
}

86型无线单按钮开关 (model: 86sw1)

{
    "channel_0": "click" //click:单击; double_click:双击
}

86型无线双按钮开关 (model: 86sw2)

{
    "channel_0": "click" //click:单击; double_click:双击
    "channel_1": "click" //click:单击; double_click:双击
}

插座 (model: plug)

{
    "status": "on" //off是关闭
}

86型墙壁插座 (model: 86plug)

{
    "status": "on" //off是关闭
}

魔方 (model: cube)

{
    "status": ""
}

status取值:

  • move
  • flip180
  • tap_twice
  • shake_air
  • flip90

烟雾警报器 (model: smoke)

{
    "alarm": "0" // 0,1,2
}

天然气警报器 (model: natgas)

{
    "alarm": "0" // 0,1,2
}

电动窗帘 (model: curtain)

{
    "curtain_level": ""
}

门磁感应 第二代 (model: sensor_magnet.aq2)

{
    "status": "close" //close:关闭; open:打开
}

人体感应器 第二代 (model: sensor_motion.aq2)

{
    "status": "motion" //motion:有人移动
}
// 或
{
    "no_motion" "120" //120秒没人移动
}

按钮/开关 第二代 (model: sensor_switch.aq2)

{
    "status": "click" //click:单击; double_click:双击
}

温度湿度传感器 第二代 (model: weather.v1)

{
    "temperature": "1741",
    "humidity": "7593"
}

水浸传感器 (model: sensor_wleak.aq1)

{
    "status": "leak" //leak:水浸; no_leak:没有水浸
}

二、获取网关sid及密码

1. 打开米家APP - 点击多功能网关 - 点击右上角'...'进入设置 - 关于

2. 在关于页面的下方空白处快速点击,直到隐藏菜单出现

3. 点击-局域网通信协议,开启并复制随机生成密码

4. 点击-网关信息

mac=后面的一串即为网关的SID,去掉“:”,转换成小写使用


趁年底周末折腾了一下,祝大家2018春节快乐!