2024年11月21日星期四 下午7:35:12

米家智能设备miio协议完整具体的分析 (自动发现)

2 年 前
#2317 引用
米家智能设备协议完整具体的分析- Xiaomi Mi Home Binary Protocol

https://awsl.rip/2022/01/07/42988ce3d67b/

背景

米家这种面向消费者的大型项目,数据通行的安全性一定要得到保证。例如米家的摄像头配对后,传输的数据要保证不被第三方从中间手段获取,要有加密后的数据包。



miio.protocol =  Xiaomi Mi Home Binary Protocoll

The Mi Home Binary Protocol is used to configure & control smart home devices made by Xiaomi.

It is an encrypted, binary protocol, based on UDP. The designated port is 54321.

Xiaomi is a manufacturer of smart home devices under the "MiHome" label. These devices use an encrypted, proprietary network protocol to communicate with the official smartphone app. It operates on UDP port 54321.



Xiaomi Mi Home Binary Protocol doc:https://github.com/OpenMiHome/mihome-binary-protocol/blob/master/doc/PROTOCOL.md

    Xiaomi Miio devices miio协议设备

miIO-discovery获取token与控制  port 54321


Packet format

从设计角度来讲,首先构造一个数据包.

首先需要
从数据包内容中识别出智能家居支持米家,所以一定要构造一个数据包头,在米家协议中是0x2131(Magic Number)
,数据包的长度也要提供。
接下来是安全方面的考量,数据包中要包含该设备的唯一识别码、时间戳、密钥、数据包的校验和(Checksum)以及最重要的——数据本身。

根据以上信息,给出米家数据包头的具体格式便很容易理解。

struct miioheader{
    uint16_t magic = 0x2131; // Magic Number
    uint16_t length; // 长度
    uint32_t pad_unk = 0x0; // 目前未知,但具体使用时基本置零
    uint32_t DID; // 设备识别码
    uint32_t stamp; // 数据包时间戳
    union {
        uint8_t token[16]; // 该设备的密钥
        uint8_t chksum[16]; // 校验和
    }
};





握手协议(SmartConnect)

Client → Device

Hello Packet

米家的网络传输协议基于UDP,那么对于设备的识别就会变得容易,因为我们可以<broadcast>地址通过网关(家庭路由器或智能网关)直接向局域网中的全部设备广播一个识别数据包,进行有效回显的设备即为支持米家的设备。

这个数据包的名字叫做称为Hello Packet。

设备给我们的回显包含了设备的基本信息
,当然,对于Hello Packet来讲,数据只包括上文提到的包头。

发送的Hello Packet内容:


发送的Hello Packet内容:

struct miioheader{
    uint16_t magic = 0x2131; // Magic Number
    uint16_t length = 0x20; // 长度
    uint32_t pad_unk = 0x0; // 目前未知,但具体使用时基本置零
    uint32_t DID = 0xFFFFFFFF; // 设备识别码
    uint32_t stamp = 0xFFFFFFFF; // 数据包时间戳
    union {
        uint8_t token[16]; // 该设备的密钥
        uint8_t chksum[16]; // 校验和
        uint128_t hello = 0xffffffffffffffffffffffffffffffff;
    } // 用FF填充
};


Device → Client

回显内容中,DID被替换为设备的识别码,Stamp被替换为当前设备的时间戳,Token字段返回设备的Token。
Example output:



### 192.168.13.2 => 192.168.13.1 (xx:xx:xx:xx:xx:xx => yy:yy:yy:yy:yy:yy)
META: Hello

### 192.168.13.2 <= 192.168.13.1 (xx:xx:xx:xx:xx:xx <= yy:yy:yy:yy:yy:yy)
META: device yy:yy:yy:yy:yy:yy has token: abcdef1234567890abcdef1234567890

### 192.168.13.2 => 192.168.13.1 (xx:xx:xx:xx:xx:xx => yy:yy:yy:yy:yy:yy)
{"id":1234567890,"method":"miIO.config_router",
"params":{"ssid":"WiFi name","passwd":"WiFi password","uid":987654321}}

### 192.168.13.2 <= 192.168.13.1 ( xx:xx:xx:xx:xx:xx  <=yy:yy:yy:yy:yy:yy)
{"result":["ok"],"id":1234567890}




Notes注意

在2017-02-23年后的固件中,只有设备第一次配对才会返回设备的Token,其余的Hello Packet回显中该字段均以FF填充。如果已经配对,可以使用您的米家账户在小米云端直接获取设备Token或重置设备。

The 128-bit token is used to identify the device and, more importantly, to encrypt all further communication.

Update 2017-02-23: Xiaomi updated the device firmwares and only uninitialized devices reveal their token now.

As of 2017-02-10, the initialization process ("SmartConnect") leaks the user's WiFi credentials, due to weak encryption. See PROTOCOL.md for more details. I do not recommended connecting MiHome devices to your main WiFi network.



数据加密

米家的数据加密使用AES-128-CBC算法,使用PKCS7作为数据填充的方式,加密的密钥和IV矢量如下。


Key = MD5(Token);
IV  = MD5(MD5(Key) + Token);

在数据包头部以后,就是我们加密后的数据了,但在填充数据之后还要做一件很关键的事情——修改包头。在米家协议中对数据包头的验证很严格,我们首先需要填写当前数据包生成的时间(相对设备时间戳,但一般应用中为设备时间戳+1)需要用Token填充好Checksum字段(Token字段),然后对整个数据包进行MD5校验,生成的MD5重新写入Checksum字段。

做好这一切后,即可向指定地址的设备发送数据了。

AES加密
填入时间戳和Token
指令数据
校验和
数据头初始化


0
2 年 前
#2318 引用
米家智能设备协议完整具体的分析

https://awsl.rip/2022/01/07/42988ce3d67b/

设备和米家app在同一局域网下使用的加密专有网络协议,这个被称之为miIO协议。该协议基于UDP,使用54321端口进行通信。具体功能见github地址https://github.com/rytilahti/python-miio,这个库的目的是支持所有miIO兼容的设备,将设备类型和控制方法进行了分类,以简化与它们的交互。

miio协议

Xiaomi is a manufacturer of smart home devices under the "MiHome" label. These devices use an encrypted, proprietary network protocol to communicate with the official smartphone app. It operates on UDP port 54321.


https://github.com/OpenMiHome/mihome-binary-protocol

Xiaomi Mi Home Binary Protocol

小米IOT控制流程  local control 本地控制

在同一局域网中,小米设备可以使用专有的加密UDP网络协议进行通信控制。在网络可达的前提下,向小米设备发送hello bytes就可以获得含有token的结构体数据。之后,构造相应的结构体,并且以同样的方式发送给设备即可完成控制。具体流程如下:



Tokens and device management

A few miIO devices send back their token during a handshake and can be used without figuring out the token. Most devices hide their token, such as Yeelights and the Mi Robot Vacuum.


Reset your Mi Home device. This will reset the token and remove the device from the Mi Home app - you will need to readd it later. Check the manual of your device to find out how to perform a reset.








小米云端Token提取器:https://github.com/PiotrMachowski/Xiaomi-cloud-tokens-extractor

笔者的一些项目:

    https://github.com/Socular/Gosund-Plug-Remote-Switch
    https://github.com/Socular/Mihome-Gosund-Plug-API

2017-02-23年后  miio协议?

注意

在2017-02-23年后的固件中,只有设备第一次配对才会返回设备的Token,其余的Hello Packet回显中该字段均以FF填充。

如果已经配对,使用您的米家账户在小米云端直接获取设备Token或重置设备。
0
2 年 前
#2319 引用
[Discovery]This miio devices will execute two types of discovery:
 discovery by handshake  - miio.miioprotocol:Discovery
discovery by mDNS. - miio.discovery:Discovering devices with mDNS


54321/udp is used by miIO protocol  - detail:https://www.msly.cn/boards/topic/7318/1#20141



cli
# miiocli discover




mDNS discovery returns information that can be used to detect the device type which does not work with all devices.

The handshake method works on all MiIO devices and may expose the token needed to communicate with the device, but does not provide device type information.

To be able to communicate with devices their IP address and a device-specific encryption token must be known.

If the returned a token is with characters other than 0s or fs, it is likely a valid token which can be used directly for communication.


https://python-miio.readthedocs.io/en/latest/discovery.html#device-discovery

Nov 9, 2022, netdisco  is deprecated

https://github.com/home-assistant-libs/netdisco

This library is deprecated. We will no longer release new versions, fix bugs or accept pull requests. If you are looking to make your Home Assistant integration discoverable, use the zeroconf and SSDP manifest options.

Netdisco is available on PyPi. Install using .

pip3 install netdisco


Example

From command-line:

python3 -m netdisco
# To see all raw data:
python3 -m netdisco dump



参考信息

协议说明:https://github.com/OpenMiHome/mihome-binary-protocol/blob/master/doc/PROTOCOL.md

基于 IP 的 HomeKit 设备 mDNS 自动发现

对于基于 IP 的 HomeKit 设备,它们将根据 mDNS(多播 DNS,Multicast DNS)协议在局域网中广播自己的 .local 本地域名3和 IP 地址4。mDNS 的原理就好比是在一个随机入住的酒店里,房客可以时不时向所有房间广播自己的名字和房间号,认识他的其他房客会将他当前的房间号保存下来。根据本地缓存的 mDNS 信息,终端设备就可以用固定的域名访问到局域网中的某个 HomeKit 设备,而无需担心其 IP 地址发生变化。

https://community.aqara.com/pc/#/post/postDetail/99

homeassistant.local requires that mDNS

homeassistant.local requires that mDNS is configured and that the host is called homeassitant


https://community.home-assistant.io/t/installing-home-assistant-core-2023-2-2-in-a-python-venv-on-raspberry-pi-3b-step-by-step/529311/15


0
2 年 前
#2320 引用
miio协议

“拿到token之后用miio添加也不成功”:
1. 你这个网关应该使用 Xiaomi Gateway 集成(xiaomi_aqara),而不是xiaomi miio;
2. 以后你还会遇到一种情况,就是很多新上市的设备不再使用miio协议,此时可以使用 https://github.com/ha0y/xiaomi_miot_raw 这个插件接入


miIO

Control Mi Home devices that implement the miIO protocol, such as the Mi Air Purifier, Mi Robot Vacuum and Mi Smart Socket. These devices are commonly part of what Xiaomi calls the Mi Ecosystem which is branded as MiJia.

https://github.com/aholstenson/miio


0
2 年 前
#2322 引用
MIoT 协议

2018 年

MIoT 协议是小米智能家居从 2018 年起推行的智能设备通信协议规范,此后凡是可接入米家的设备均通过此协议进行通信。此插件按照 MIoT 协议规范与设备通信,实现对设备的状态读取及控制。

The Xiaomi IoT platform is fully implementing the MioT-Spec access work. The Xiaomi IoT Device Protocol Specification (MIoT Specification) will replace the original miio profile protocol specification.

i've checked some plugins of new devices and many of them use miot api (cloud only) rather than miio.
for example air purifier 3. i can't say for sure because i don't have device, but from what i saw it's stripped from local miio api.


MIoT

Manufacturing Internet of Things (MIoT)

MIOT - The best IoT solution for your data.

MIOT is a Software application for IoT & Analytics which is an essential component of IoT ecosystem that supports and connects all components within the system. It helps to facilitate device & user management, handle hardware/software communication protocols, data collect, processing, visualization, reporting & Data Analytics.

It enables device connectivity via industry standard IoT protocols – MQTT, CoAP and HTTP and supports both cloud and on-premises deployments. MIOT combines scalability, fault-tolerance and performance so you will never lose your data.

MIOT allows you to create rich IoT Dashboards for data visualization and remote device control in real-time. customizable widgets allow you to build end-user custom dashboards for most IoT use-cases. User can create complex Rule Chains to process data from your devices and match your application specific use cases. MIOT Platform is scalable, fault-tolerant, robust, efficient, customizable and durable.


MIoT-Spec

Xiaomi brought out a new specification named MIoT-Spec. Let's call it MIoT for short.
It is used to communicate with ALL Xiaomi IoT devices. 

Compared with the old miio, this new specification is clear, highly adaptive, and open to all. Thanks to MIoT, nearly all Xiaomi IoT devices can be integrated into HASS in a very easy way.
So I worked out this integration.

https://github.com/ha0y/xiaomi_miot_raw/blob/master/README_en.md

MIoT-Spec 是小米IoT平台根据硬件产品的联网方式、产品功能的特点、用户使用场景的特征和用户对硬件产品使用体验的要求,设计的描述硬件产品功能定义的标准规范。


https://bbs.hassbian.com/thread-11749-1-1.html

MIoT-Spec: The protocol specification for Xiaomi IoT devices, is a standard designed by the Xiaomi IoT platform to describe the function definition of hardware products according to the networking mode of hardware products, the characteristics of product functions, the characteristics of user usage scenarios and the user's requirements for hardware product use experience specification.

See:https://github.com/al-one/hass-xiaomi-miot



miot auto很多可以本地控制,不支持miot协议的设备就老老实实用miio协议本地控制吧

由于部分设备使用的是旧版的miio协议,在局域网环境下无法通过miot-spec协议读写数据,但是却可以在小米云端使用miot-spec协议,因此此类设备需要开启云端模式后才可以正常接入。
0
2 年 前
#2405 引用
miio

在miio中,可以通过
get_prop "['on', 'bright', 'ct']"
方法获取开关、亮度、色温等属性,通过
set_power、set_bright、set_ct
等方法设置开关、亮度、色温属性;但属性名和方法名杂乱无章,没有一个统一的地方查询。

miot

而miot改用了一套更科学的方法管理设备的属性,通过get_properties获取属性、set_properties方法设置属性。

Miot local control

Some gateways (lumi.gateway.mieu01) do not support getting the connected subdevices locally. For those gateways, cloud credentials can be specified during the config flow and the “Use cloud to get connected subdevices” can be enabled in the options flow (after setting up the integration, click Configuration in the sidebar, then click Integrations and then click Options on the already set up Xiaomi Miio Gateway integration). The connected subdevices will then be retrieved from the Xiaomi Miio cloud (internet), control and status updates of those subdevices will then further take place over local network connection. A re-authentication flow may be triggered when no cloud credentials are provided yet and are needed for that particular gateway model.

https://www.home-assistant.io/integrations/xiaomi_miio/#xiaomi-gateway



If the device is following Zigbee standards it is possible it will work with other gateway solutions, it is just not confirmed as working yet!

https://github.com/ha0y/xiaomi_miot_raw

通过本插件,已接入米家的智能设备均可快速高效地接入 Home Assistant,而无关设备的具体型号。

本插件具有本地(局域网)和云端两种工作方式。两种方式结合,可以接入绝大多数米家智能设备(包括蓝牙、蓝牙 Mesh 和 ZigBee 设备)。

Xiaomi Cloud is able to convert MIoT commands to miio commands and send them to the device via Internet. With your Xiaomi account, the integration sends commands - instead of to devices - to Xiaomi Cloud, so that all devices can work properly.

https://github.com/ha0y/xiaomi_miot_raw
0
2 年 前
#2406 引用



xiaomi_miot_raw解释解密从云端获取到的数据的具体方法

https://github.com/ha0y/xiaomi_miot_raw


本插件并无意“伪装”成米家客户端,而是通过标准的miot api进行通信,这些api可能小米官方没有写过文档,但是github上已有很多相关的实现代码可以参考。
例如yeelight的api https://github.com/Yeelight/miot-api (现已不可访问)、以及 https://github.com/squachen/micloud 。

局域网miio协议和云端通信,确实存在差别。

其他设备与局域网内设备通信使用token,其他设备与云端通信使用账号信息。


而云端与设备通信,实现更为复杂,需要key之类的更复杂的信息
,大多数设备除非拆机读芯片无法获取到这个信息,至少目前我没有能力去模拟出一个小米云来让设备直接通信。
0
2 年 前
#9188 引用
使用TCP/UDP工具控制Yeelight灯带

SSDP port 1982

port 55443

创建UDP组播连接
根据文档的搜索命令

M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1982
MAN: “ssdp:discover”
ST: wifi_bulb


https://blog.csdn.net/a10615/article/details/105570293

c++ 源代码

https://rickys.blog.csdn.net/article/details/52085140


Qucik start

小米旗下Yeelight开放了API,按照通信协议,控制Yeelight灯需要如下步骤:

1. App UDP广播特定字符串;

2. 灯收到上述广播后回应字符串,包含IP、ID;

3. App拿到上述灯信息后,建立TCP连接;

4. App按照通信协议中的命令,即可控制灯的开关、亮度、颜色等。



Step 1:搜索自动发现设备

创建UDP组播连接


M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1982
MAN: “ssdp:discover”
ST: wifi_bulb



2、发送组播搜索命令



3、设备响应
发送后,如果有设备在线,一般都能立马接收到响应。接收区就是设备的响应
0
2 年 前
#9209 引用
1
0
2 年 前
#16430 引用
1
0