Home Assistant 米家集成:开启智能家居新体验
一、引言
在智能家居蓬勃发展的当下,如何将不同品牌、不同类型的智能设备整合到一个统一的平台进行管理,成为了众多用户关注的焦点。Home Assistant 作为一款开源的智能家居平台,以其强大的扩展性和高度的自定义性,受到了广大智能家居爱好者的青睐。而小米作为智能家居领域的巨头,拥有丰富多样的 IoT 智能设备,其设备以高性价比和广泛的兼容性在市场上占据了重要地位。小米官方支持的 Home Assistant 米家集成,为用户提供了一个将小米智能设备无缝接入 Home Assistant 平台的解决方案,让用户能够更加便捷地实现智能家居的集中控制和自动化管理。本文将深入介绍该集成的各个方面,包括其工作原理、安装配置方法、代码实现分析以及使用过程中的注意事项等,帮助读者全面了解并掌握这一实用的智能家居集成方案。
二、集成介绍
2.1 概述
小米 Home 集成是 Home Assistant 的一个重要集成组件,由小米官方提供支持。它的主要作用是允许用户在 Home Assistant 平台中直接使用小米的各类 IoT 智能设备,实现对这些设备的集中控制和管理。通过该集成,用户可以在 Home Assistant 的界面上方便地查看小米设备的状态信息,并对设备进行远程控制,无需在多个应用之间切换,大大提高了智能家居的使用体验。
2.2 消息收发原理
云端控制
该集成采用了高效的消息收发机制,主要通过向小米云 MQTT Broker 订阅关注的设备消息来实现对设备状态的实时监控。当小米设备的属性发生改变(例如智能灯泡的亮度、颜色变化)或者产生设备事件(如门窗传感器检测到门窗打开)时,设备会主动向小米云发送上行消息。MQTT Broker 接收到这些消息后,会立即向米家集成推送订阅的设备消息。这样,米家集成无需向云端进行频繁的轮询操作,就能第一时间获知设备属性的变化或事件的发生,从而及时更新 Home Assistant 界面上的设备状态信息。
当用户需要对设备进行控制时,例如打开智能插座、调节空调温度等,米家集成会通过小米云 HTTP 接口向设备发送控制消息。设备接收到这些消息后,会根据消息内容做出相应的响应,完成用户的控制指令。
三、安装方法
3.1 版本要求
在安装小米 Home 集成之前,需要确保 Home Assistant 的版本符合要求,具体如下:
- Core ≥ 2024.4.4
- Operating System ≥ 13.0
3.2 具体安装方式
3.2.1 Git clone from GitHub
这种安装方法适合对 Git 操作比较熟悉的用户,通过从 GitHub 仓库克隆代码并执行安装脚本,可以方便地将集成安装到 Home Assistant 中。具体步骤如下:
# 进入 Home Assistant 的配置目录
cd config
# 从 GitHub 克隆 ha_xiaomi_home 仓库
git clone https://github.com/XiaoMi/ha_xiaomi_home.git
# 进入克隆后的仓库目录
cd ha_xiaomi_home
# 执行安装脚本,将集成安装到 Home Assistant 的配置目录
./install.sh /config
如果需要更新 xiaomi_home
到特定版本,可以使用以下命令切换标签:
# 进入 ha_xiaomi_home 仓库目录
cd config/ha_xiaomi_home
# 从远程仓库获取最新的标签信息
git fetch
# 切换到指定版本的标签,例如 v1.0.0
git checkout v1.0.0
# 再次执行安装脚本,更新集成到指定版本
./install.sh /config
3.2.2 HACS
HACS(Home Assistant Community Store)是 Home Assistant 的一个社区商店,提供了丰富的集成和插件供用户选择。使用 HACS 安装小米 Home 集成的步骤如下:
- 打开 HACS,点击溢出菜单(通常是三个点的图标),选择 Custom repositories。
- 在 Repository 字段中输入
https://github.com/XiaoMi/ha_xiaomi_home.git
,在 Category or Type 字段中选择 Integration,然后点击 ADD。 - 在 HACS 的 New or Available for download 部分找到 Xiaomi Home,点击 DOWNLOAD 进行下载安装。
需要注意的是,小米 Home 尚未默认添加到 HACS 商店,不过很快就会上线。
3.2.3 手动安装 via Samba / FTPS
这种方法适合无法使用上述两种方式的用户,通过手动下载并复制文件来完成安装。具体步骤如下:
- 从 GitHub 仓库下载
custom_components/xiaomi_home
文件夹。 - 使用 Samba 或 FTPS 等工具将下载的
custom_components/xiaomi_home
文件夹复制到 Home Assistant 的config/custom_components
文件夹中。
四、配置步骤
4.1 登录
配置小米 Home 集成的第一步是登录小米账户,具体操作如下:
- 打开 Home Assistant 的设置页面,点击 Devices & services。
- 点击 ADD INTEGRATION,在搜索框中输入
Xiaomi Home
,然后点击 NEXT。 - 点击 “Click here to login” 链接,使用小米账户进行登录。
4.2 添加 MIoT 设备
登录成功后,会弹出一个名为 “Select Home and Devices” 的对话框。在这个对话框中,您可以选择要导入到 Home Assistant 中的设备所在的家庭。选择完成后,点击相应的确认按钮,即可将所选家庭中的小米设备添加到 Home Assistant 中。
4.3 多用户登录
在一个小米账户登录并完成用户配置后,如果您需要添加其他小米账户的设备,可以在已配置的小米 Home 集成页面继续添加。具体操作如下:
- 打开 Home Assistant 的设置页面,点击 Devices & services。
- 找到已配置的 Xiaomi Home 集成,点击进入其配置页面。
- 点击 ADD HUB,然后点击 NEXT。
- 点击 “Click here to login” 链接,使用另一个小米账户进行登录。
4.4 更新配置
如果您需要更改小米 Home 集成的配置,例如更新用户昵称、从小米 Home APP 导入的设备列表等,可以在 “Configuration Options” 对话框中进行操作。具体步骤如下:
- 打开 Home Assistant 的设置页面,点击 Devices & services。
- 找到已配置的 Xiaomi Home 集成,点击进入其配置页面。
- 点击 CONFIGURE,在弹出的对话框中选择要更新的选项,按照提示进行操作即可。
4.5 Action 调试模式
当 Action 调试模式激活时,您可以手动向设备发送带有参数的 Action 命令消息。发送带有参数的 Action 命令的用户界面显示为一个 Text 实体。启用该模式的步骤如下:
- 打开 Home Assistant 的设置页面,点击 Devices & services。
- 找到已配置的 Xiaomi Home 集成,点击进入其配置页面。
- 点击 CONFIGURE,在配置选项中找到 Debug mode for action 并启用它。
五、代码分析
5.1 设备实体设置
在 custom_components/xiaomi_home
目录下,有多个文件用于设置不同类型的设备实体,例如 light.py
、switch.py
等。下面以 light.py
中的代码为例,详细分析灯光设备实体的设置过程:
"""Set up a config entry."""
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up a config entry."""
# 从 hass.data 中获取当前配置条目的设备列表
device_list: list[MIoTDevice] = hass.data[DOMAIN]['devices'][
config_entry.entry_id]
new_entities = []
# 遍历设备列表
for miot_device in device_list:
# 遍历设备的灯光实体列表
for data in miot_device.entity_list.get('light', []):
# 创建灯光实体对象并添加到新实体列表中
new_entities.append(
Light(miot_device=miot_device, entity_data=data))
if new_entities:
# 将新实体添加到 Home Assistant 中
async_add_entities(new_entities)
这段代码的主要功能是将小米灯光设备的实体添加到 Home Assistant 中。具体步骤如下:
- 从
hass.data
中获取当前配置条目的设备列表。 - 遍历设备列表,对于每个设备,检查其是否包含灯光实体。
- 如果包含灯光实体,则创建一个
Light
实体对象,并将其添加到new_entities
列表中。 - 最后,通过
async_add_entities
方法将new_entities
列表中的实体添加到 Home Assistant 中。
5.2 设备制造商信息获取
在 custom_components/xiaomi_home/miot/miot_storage.py
文件中,有一个 DeviceManufacturer
类用于获取设备制造商信息。下面是该类的详细代码及分析:
"""Device manufacturer."""
class DeviceManufacturer:
"""Device manufacturer."""
DOMAIN: str = 'miot_specs'
_main_loop: asyncio.AbstractEventLoop
_storage: MIoTStorage
_data: dict
def __init__(
self, storage: MIoTStorage,
loop: Optional[asyncio.AbstractEventLoop] = None
) -> None:
# 初始化事件循环和存储对象
self._main_loop = loop or asyncio.get_event_loop()
self._storage = storage
self._data = {}
async def init_async(self) -> None:
"""初始化设备制造商信息"""
if self._data:
return
# 从本地存储中加载设备制造商信息
data_cache = await self._storage.load_async(
domain=self.DOMAIN, name='manufacturer', type_=dict)
if (
isinstance(data_cache, dict)
and 'data' in data_cache
and 'ts' in data_cache
and (int(time.time()) - data_cache['ts']) <
MANUFACTURER_EFFECTIVE_TIME
):
# 如果本地缓存有效,则使用缓存数据
self._data = data_cache['data']
_LOGGER.debug('load manufacturer data success')
return
data_cloud = None
try:
# 从云端获取设备制造商信息
data_cloud = await MIoTHttp.get_json_async(
url='https://cdn.cnbj1.fds.api.mi-img.com/res-conf/xiaomi-home/'
'manufacturer.json',
loop=self._main_loop)
except Exception as err: # pylint: disable=broad-exception-caught
# 记录获取信息失败的错误日志
_LOGGER.error('get manufacturer info failed, %s', err)
if data_cloud:
# 如果从云端获取信息成功,则保存到本地存储并更新数据
await self._storage.save_async(
domain=self.DOMAIN, name='manufacturer',
data={'data': data_cloud, 'ts': int(time.time())})
self._data = data_cloud
_LOGGER.debug('update manufacturer data success')
else:
if isinstance(data_cache, dict):
# 如果云端获取失败,尝试使用本地缓存数据
self._data = data_cache.get('data', {})
_LOGGER.error('load manufacturer data failed, use local data')
else:
# 本地缓存和云端获取都失败,记录错误日志
_LOGGER.error('load manufacturer data failed')
async def deinit_async(self) -> None:
"""清理设备制造商信息"""
self._data.clear()
def get_name(self, short_name: str) -> str:
"""根据简称获取制造商名称"""
if not self._data or not short_name or short_name not in self._data:
return short_name
return self._data[short_name].get('name', None) or short_name
这个类的主要功能是管理设备制造商信息,具体步骤如下:
- 初始化:在
__init__
方法中,初始化事件循环和存储对象,并将数据字典初始化为空。 - 初始化数据:在
init_async
方法中,首先检查数据是否已经加载。如果没有加载,则尝试从本地存储中加载设备制造商信息。如果本地缓存有效,则使用缓存数据;否则,尝试从云端获取信息。如果从云端获取信息成功,则保存到本地存储并更新数据;如果云端获取失败,则尝试使用本地缓存数据。 - 清理数据:在
deinit_async
方法中,清空数据字典,释放内存。 - 获取制造商名称:在
get_name
方法中,根据设备制造商的简称获取其全称。如果数据字典为空、简称不存在或简称不在数据字典中,则返回简称;否则,返回全称。
5.3 设备信息解析与转换
在 custom_components/xiaomi_home/miot/miot_device.py
文件中,spec_transform
方法用于解析设备的服务、属性、事件和动作,并将其转换为 Home Assistant 可以识别的实体。下面是该方法的详细代码及分析:
"""Parse service, property, event, action from device spec."""
def spec_transform(self) -> None:
"""Parse service, property, event, action from device spec."""
# STEP 1: device conversion
# 解析设备实体信息
device_entity = self.parse_miot_device_entity(
spec_instance=self.spec_instance)
if device_entity:
# 将设备实体添加到实体列表中
self.append_entity(entity_data=device_entity)
# STEP 2: service conversion
# 遍历设备的服务列表
for service in self.spec_instance.services:
# 解析服务实体信息
service_entity = self.parse_miot_service_entity(
miot_service=service)
if service_entity:
# 将服务实体添加到实体列表中
self.append_entity(entity_data=service_entity)
# STEP 3.1: property conversion
# 遍历服务的属性列表
for prop in service.properties:
if prop.platform or not prop.access:
continue
if prop.unit:
# 进行单位转换
prop.external_unit = self.unit_convert(prop.unit)
if not prop.icon:
# 根据单位转换图标
prop.icon = self.icon_convert(prop.unit)
# 特殊转换
self.parse_miot_property_entity(miot_prop=prop)
# 一般转换
if not prop.platform:
if prop.writable:
if prop.format_ == str:
prop.platform = 'text'
elif prop.format_ == bool:
prop.platform = 'switch'
prop.device_class = SwitchDeviceClass.SWITCH
elif prop.value_list:
prop.platform = 'select'
elif prop.value_range:
prop.platform = 'number'
else:
# 不规则属性不进行转换
continue
elif prop.readable or prop.notifiable:
if prop.format_ == bool:
prop.platform = 'binary_sensor'
else:
prop.platform = 'sensor'
# 将属性添加到属性列表中
self.append_prop(prop=prop)
# STEP 3.2: event conversion
# 遍历服务的事件列表
for event in service.events:
if event.platform:
continue
event.platform = 'event'
if event.name in SPEC_EVENT_TRANS_MAP:
event.device_class = SPEC_EVENT_TRANS_MAP[event.name]
# 将事件添加到事件列表中
self.append_event(event=event)
# STEP 3.3: action conversion
# 遍历服务的动作列表
for action in service.actions:
if action.platform:
continue
if action.in_:
action.platform = 'notify'
else:
action.platform = 'button'
# 将动作添加到动作列表中
self.append_action(action=action)
这个方法的主要功能是将设备的规格信息解析并转换为 Home Assistant 可以识别的实体,具体步骤如下:
- 设备转换:调用
parse_miot_device_entity
方法解析设备实体信息,并将其添加到实体列表中。 - 服务转换:遍历设备的服务列表,调用
parse_miot_service_entity
方法解析服务实体信息,并将其添加到实体列表中。 - 属性转换:遍历服务的属性列表,进行单位转换和图标转换。根据属性的读写性和数据类型,将属性转换为不同的平台实体,如文本、开关、选择器、数字等,并将其添加到属性列表中。
- 事件转换:遍历服务的事件列表,将事件转换为
event
平台实体,并根据事件名称设置设备类别,然后将其添加到事件列表中。 - 动作转换:遍历服务的动作列表,根据动作是否有输入参数,将动作转换为
notify
或button
平台实体,并将其添加到动作列表中。
六、安全注意事项
6.1 信息存储
小米 Home 集成实现了 OAuth 2.0 登录流程,不会在 Home Assistant 应用中保存您的账户密码。但是,由于 Home Assistant 平台的限制,登录成功后,您的小米账户的用户信息(包括设备信息、证书、令牌等)将以明文形式保存在 Home Assistant 配置文件中。因此,您需要确保 Home Assistant 配置文件得到妥善存储,避免配置文件泄露导致他人以您的身份登录。建议您采取以下措施来保护配置文件的安全:
- 对 Home Assistant 所在的服务器进行严格的访问控制,设置强密码并定期更换。
- 定期备份配置文件,并将备份文件存储在安全的位置。
- 避免在不安全的网络环境中访问 Home Assistant。
6.2 令牌泄露处理
如果您怀疑您的 OAuth 2.0 令牌已泄露,可以通过以下步骤撤销小米账户的登录授权:
- 打开 Xiaomi Home APP。
- 点击个人资料图标,进入个人资料页面。
- 点击您的用户名,进入小米账户管理页面。
- 在基本信息中,点击 Apps。
- 找到 Xiaomi Home (Home Assistant Integration),点击 Remove。
七、常见问题解答
7.1 小米 Home 集成是否支持所有小米 Home 设备?
目前,小米 Home 集成支持大多数类别为 Home 的设备,只有少数类别不支持,包括蓝牙设备、红外设备和虚拟设备。对于不支持的设备,您可能需要使用其他方式进行控制或等待后续的更新支持。
7.2 小米 Home 集成是否支持多个小米账户?
支持。小米 Home 集成允许将不同账户的设备添加到同一区域。您可以按照上述的多用户登录步骤,将多个小米账户的设备添加到 Home Assistant 中,实现对不同账户下设备的集中管理。
7.3 小米 Home 集成是否支持本地控制?
本地控制可以通过 Xiaomi Central Hub Gateway(固件版本 3.4.0_0000 以上)或内置中央枢纽网关的小米家庭设备(软件版本 0.8.0 以上)实现。如果您没有小米中央枢纽网关或其他具有中央枢纽网关功能的设备,所有控制命令将通过小米云发送。支持 Home Assistant 本地控制功能的小米中央枢纽网关(包括内置中央枢纽网关)的固件尚未发布,请参考 MIoT 团队的升级计划通知。
此外,小米 Home 集成还可以通过启用小米 LAN 控制功能实现部分本地控制。该功能只能控制与 Home Assistant 位于同一局域网中的 IP 设备(通过 WiFi 或以太网电缆连接到路由器的设备),无法控制 BLE Mesh、ZigBee 等设备,且可能会导致一些异常,因此不建议使用。该功能可以通过 Settings > Devices & services > Configured > Xiaomi Home > CONFIGURE > Update LAN control configuration 启用。小米 LAN 控制功能不受地区限制,在所有地区都可用。但如果 Home Assistant 所在的局域网中有中央网关,即使在集成中启用了小米 LAN 控制功能,也不会生效。
八、总结
小米 Home 集成极大地丰富了 Home Assistant 的设备支持范围,让用户能够更加便捷地管理和控制小米的 IoT 智能设备。通过本文的介绍,您应该对该集成的安装、配置、使用方法以及相关的代码实现有了更深入的了解。在使用过程中,务必注意信息安全,避免因配置文件泄露导致的安全风险。希望您能在智能家居的世界中享受更加智能、便捷的生活体验。同时,如果您在使用过程中遇到问题或有任何建议,欢迎通过 GitHub 讨论区或联系 ha_xiaomi_home@xiaomi.com 寻求帮助和反馈。