<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>小米 on 落日余晖</title><link>https://is-i7.cn/tags/%E5%B0%8F%E7%B1%B3/</link><description>Recent content in 小米 on 落日余晖</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Wed, 12 Aug 2026 20:00:00 +0800</lastBuildDate><atom:link href="https://is-i7.cn/tags/%E5%B0%8F%E7%B1%B3/index.xml" rel="self" type="application/rss+xml"/><item><title>绕过米家云：用 python-miio 本地直连小米设备，秒级拿到传感器数据</title><link>https://is-i7.cn/posts/python-miio-local-mi-device/</link><pubDate>Wed, 12 Aug 2026 20:00:00 +0800</pubDate><guid>https://is-i7.cn/posts/python-miio-local-mi-device/</guid><description>&lt;blockquote>
&lt;p>折腾 Home Assistant + 米家设备时，最让人头疼的就是&amp;quot;数据延迟&amp;quot;。官方集成走米家云，温湿度 2-3 分钟才更新一次，偶尔云端数据还会&amp;quot;抽风&amp;quot;报错。本文记录我用 python-miio 绕过米家云、局域网直连除湿机，把数据采集频率做到秒级、并接入 HA 的完整实战。&lt;/p>&lt;/blockquote>
&lt;hr>
&lt;h2 id="一痛点为什么需要本地直连">一、痛点：为什么需要本地直连&lt;/h2>
&lt;p>先看一张真实对比（同一台除湿机，同一时刻）：&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>数据来源&lt;/th>
&lt;th>当前值&lt;/th>
&lt;th>状态&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>米家云（官方集成）&lt;/td>
&lt;td>30 °F ❌&lt;/td>
&lt;td>云端数据坏了，实际应是 84 °F&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>本地直连（python-miio）&lt;/td>
&lt;td>29.5 °C ✅&lt;/td>
&lt;td>准确&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>官方 HA 米家集成的工作方式是 &lt;strong>MQTT 订阅推送&lt;/strong>：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-plain" data-lang="plain">&lt;span style="display:flex;">&lt;span>设备属性变化 → 设备上报米家云 → 米家云 MQTT 推送 → HA
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>```plain
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>理论上 HA 能&amp;#34;第一时间&amp;#34;收到，但实际依赖两点：
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>1. **设备主动上报**（米家 WiFi 设备为省电，通常 2-3 分钟才上报一次传感器数据）
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>2. **推送可靠性**（官方仓库 Issue 里提到 WiFi 设备推送丢失率接近 30%）
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>结果就是：**延迟大、还不一定准**。
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>而**本地直连**的路径是：
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>```plain
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>你的脚本 → 局域网直连设备（miio 协议）→ 秒级返回
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>```plain
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>不经过米家云，不依赖设备上报节奏，你想读就读，又快又准。
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>---
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>## 二、原理：米家设备的本地通信
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>小米的 WiFi 设备（除湿机、空气净化器、扫地机等）在局域网内会开放一个 **miio 协议**（UDP 54321 端口）。只要你有设备的 **token**（一个 32 位十六进制密钥），就能在局域网内直接和设备通信。
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>```plain
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>┌──────────┐ 局域网 (UDP 54321) ┌──────────┐
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│ 你的脚本 │ ──── miio 协议 ──────▶│ 小米设备 │
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│(python-miio)│ ◀── 加密响应 ────── │ │
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>└──────────┘ └──────────┘
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>```plain
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>关键点：
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>- **token** 是设备配对时生成的密钥，控制设备的&amp;#34;钥匙&amp;#34;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>- miio 协议是加密的，token 用于加解密
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>- [python-miio](https://github.com/rytilahti/python-miio) 是开源的 Python 库，封装了这套协议
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>- MIoT（小米新一代物模型）设备用 `siid/piid`（服务ID/属性ID）寻址属性
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>---
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>## 三、实战：除湿机本地直连全流程
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>### 第 1 步：获取设备 token
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>token 是本地直连的必需品。获取方式有几种：
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>**方法 A：从 Home Assistant 官方集成配置里提取（最省事）**
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>如果你已经在 HA 装了官方米家集成，token 已经明文存在配置里：
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>```plain
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>/config/.storage/xiaomi_home/miot_devices/&amp;lt;你的uid&amp;gt;_cn.dict
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>```plain
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>这个文件是 JSON，里面每个设备都带 `token` 字段。
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>**方法 B：用旧版米家 APP 提取数据库**
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>安卓米家 APP（旧版 5.4.54）的数据库里有 token，用 [mihome-binary-extractor](https://github.com/Maxmudjon/Get_MiHome_devices_token) 提取。
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>**方法 C：在线工具**（不推荐，有账号泄露风险）
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; ⚠️ **token 等于设备控制权**，千万不要提交到公开仓库或发到群里。
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>### 第 2 步：找到设备局域网 IP
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>本地直连需要设备的局域网 IP。几种方式：
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>- 路由器后台看 DHCP 客户端列表
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>- `ip neigh` / `arp -a` 看 ARP 表
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>- python-miio 的发现功能
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>但设备 MAC 可能随机化，最稳的办法是**用 token 遍历候选 IP 试连**：
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>```python
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>from miio import MiotDevice
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>token = &amp;#34;你的token&amp;#34;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>for ip in [&amp;#34;192.168.1.98&amp;#34;, &amp;#34;192.168.1.107&amp;#34;, &amp;#34;192.168.1.89&amp;#34;]:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> try:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> dev = MiotDevice(ip=ip, token=token, mapping={})
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> info = dev.info()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> print(f&amp;#34;✅ {ip}: {info.model}&amp;#34;)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> except Exception:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> print(f&amp;#34;❌ {ip}&amp;#34;)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>```plain
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>哪个 IP 返回了 `model`，就是它（我的除湿机是 `192.168.1.89`，model `xiaomi.derh.13l`）。
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>### 第 3 步：读数据 —— 理解 MIoT 的 siid/piid
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>MIoT 设备用**服务(siid) + 属性(piid)** 来组织功能。比如除湿机：
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>- `siid=3, piid=2` → 温度
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>- `siid=3, piid=1` → 湿度
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>- `siid=2, piid=5` → 目标湿度
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>读取用 `get_property_by(siid, piid)`：
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>```python
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>from miio import MiotDevice
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>dev = MiotDevice(ip=&amp;#34;192.168.1.89&amp;#34;, token=&amp;#34;你的token&amp;#34;, mapping={})
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>temp = dev.get_property_by(3, 2)[0][&amp;#34;value&amp;#34;] # 温度
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>humidity = dev.get_property_by(3, 1)[0][&amp;#34;value&amp;#34;] # 湿度
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>print(f&amp;#34;温度 {temp}°C, 湿度 {humidity}%&amp;#34;)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># 输出: 温度 29.5°C, 湿度 58%
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>```plain
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>**怎么知道哪个 siid/piid 是温度？** —— 扫描：
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>```python
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>for siid in range(1, 9):
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> for piid in range(1, 8):
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> try:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> r = dev.get_property_by(siid, piid)[0]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> if r.get(&amp;#34;code&amp;#34;) == 0 and r.get(&amp;#34;value&amp;#34;) is not None:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> print(f&amp;#34;siid={siid} piid={piid}: {r[&amp;#39;value&amp;#39;]}&amp;#34;)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> except Exception:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> pass
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>```plain
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>看输出里哪个值像温度（20-30）、哪个像湿度（40-70），就能对上号。也可以查设备的 [MIoT Spec](https://home.miot-spec.com/)。
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>### 第 4 步：MQTT 推送到 HA，秒级显示
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>光自己读到数据还不够，要让它进 HA、能在仪表盘显示，最优雅的方式是 **MQTT Discovery**：你的脚本发布一个 discovery 消息，HA 自动创建对应传感器。
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>架构：
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>```plain
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>除湿机 ──python-miio──▶ 采集脚本 ──paho-mqtt──▶ mosquitto ──discovery──▶ HA
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>```plain
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>完整采集脚本：
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>```python
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>import time, json
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>import paho.mqtt.client as mqtt
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>from miio import MiotDevice
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>MQTT_HOST = &amp;#34;127.0.0.1&amp;#34;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>DEV_IP = &amp;#34;192.168.1.89&amp;#34;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>DEV_TOKEN = &amp;#34;你的token&amp;#34;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>INTERVAL = 10 # 每10秒采集一次
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># 连 MQTT
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>client = mqtt.Client()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>client.connect(MQTT_HOST, 1883, 60)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>client.loop_start()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># 发布 discovery，HA 会自动创建传感器
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>discovery = {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;name&amp;#34;: &amp;#34;除湿机温度(本地)&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;state_topic&amp;#34;: &amp;#34;dehumi_local/state&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;value_template&amp;#34;: &amp;#34;{{ value_json.temperature }}&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;unit_of_measurement&amp;#34;: &amp;#34;°C&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;device_class&amp;#34;: &amp;#34;temperature&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;state_class&amp;#34;: &amp;#34;measurement&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;unique_id&amp;#34;: &amp;#34;dehumi_local_temp_001&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>client.publish(&amp;#34;homeassistant/sensor/dehumi_local_temp/config&amp;#34;,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> json.dumps(discovery), retain=True)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># 湿度同理，略
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>dev = MiotDevice(ip=DEV_IP, token=DEV_TOKEN, mapping={})
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>while True:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> try:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> temp = dev.get_property_by(3, 2)[0][&amp;#34;value&amp;#34;]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> humid = dev.get_property_by(3, 1)[0][&amp;#34;value&amp;#34;]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> # 一次发一个 JSON，HA 用 value_template 拆分
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> payload = json.dumps({&amp;#34;temperature&amp;#34;: temp, &amp;#34;humidity&amp;#34;: humid})
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> client.publish(&amp;#34;dehumi_local/state&amp;#34;, payload, retain=True)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> print(f&amp;#34;{time.strftime(&amp;#39;%H:%M:%S&amp;#39;)} 温度={temp}°C 湿度={humid}%&amp;#34;)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> except Exception as e:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> print(f&amp;#34;采集失败: {e}&amp;#34;)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> time.sleep(INTERVAL)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>```plain
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>HA 那边只要装了 MQTT 集成（连同一个 broker），几秒内就会自动出现「除湿机温度(本地)」「除湿机湿度(本地)」两个传感器，**10 秒刷新一次**。
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>---
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>## 四、效果对比
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>| | 官方集成（云端） | 本地直连（python-miio+MQTT） |
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>|--|--|--|
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>| 更新频率 | 2-3 分钟 | **10 秒（可调更短）** |
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>| 数据准确性 | 依赖云端（偶发错误） | **直读设备，准** |
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>| 断网能否工作 | ❌ | ✅ |
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>| 响应延迟 | 分钟级 | **秒级** |
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>| 部署复杂度 | 一键装集成 | 需要写脚本 + broker |
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>---
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>## 五、踩坑记录
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>1. **netifaces 编译失败**：python-miio 依赖 netifaces，在 `python:3-slim` 镜像里没有 gcc 会编译失败。解决：用完整的 `python:3` 镜像，或装 `gcc python3-dev`。
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>2. **新版 python-miio 的 API 变了**：网上的老教程用 `get_properties_by`，新版改成了 `get_property_by(siid, piid)`，而且 `MiotDevice` 创建时必须传 `mapping={}`（否则报 &amp;#34;Neither the class nor the parameter defines the mapping&amp;#34;）。
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>3. **`miiocli` 命令找不到**：pip 装完 python-miio 后，`miiocli` 有时不在这个 PATH。直接用 Python API 调用更稳。
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>4. **MQTT 集成配置方式**：新版 HA 不能在 `configuration.yaml` 里写 `mqtt: broker: ...` 了（会报 invalid option），必须通过「设置 → 集成 → 添加 MQTT」用 UI 配置，或直接写 config_entries。
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>5. **discovery 的 entity_id 是中文名 slugify**：如果 discovery 里 `name` 写中文，HA 生成的 entity_id 会是拼音（如 `chu_shi_ji_wen_du`），自动化里引用要注意。
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>6. **设备 MAC 随机化**：现在很多设备开启了 MAC 随机化，没法靠厂商 OUI 识别。用 token 遍历 IP 试连最靠谱。
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>---
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>## 六、总结
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>本地直连的本质就三件事：**拿到 token → 找到 IP → 用 miio 协议读写**。
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>适合的场景：
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>- 对数据实时性要求高（自动化、监控）
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>- 米家云数据不稳/不准
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>- 想完全本地化、断网可控
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>不适合的场景：
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>- 蓝牙/Zigbee 设备（不是 IP 设备，走不了 miio）
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>- 不想折腾、一键党（直接用官方集成就行）
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>如果你的核心诉求是&amp;#34;数据又快又准&amp;#34;，这套方案值得搞。**我的除湿机从 2-3 分钟更新一次，变成了 10 秒一次，而且云端报错温度时本地依然准确** —— 这就是本地直连的价值。
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>---
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>**参考资料**
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>- [python-miio](https://github.com/rytilahti/python-miio)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>- [MIoT Spec 查询](https://home.miot-spec.com/)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>- [HA MQTT Discovery 文档](https://www.home-assistant.io/docs/mqtt/discovery/)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>- [米家官方 HA 集成](https://github.com/XiaoMi/ha_xiaomi_home)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item></channel></rss>