科沃斯T50 PRO上下水版接入Home Assistant(含地图修复)

目录

前言

HA 自带的 ecovacs 集成可以接入科沃斯扫地机,底层依赖 deebot-client 这个库。但国行 T50 系列的不少新型号库里还没收录,账号能登录、集成能加上,可设备一个实体都没有。

网上现成的做法(什么值得买这篇、瀚思彼岸这帖)都是 docker exec 进 HA 容器,直接改 site-packages 里的文件。这样有两个问题:

  1. HA 一升级就失效:容器镜像换了,改过的文件也跟着没了;
  2. HAOS 用户往往进不去容器 :Advanced SSH & Web Terminal 插件默认开着保护模式,执行 docker 只会提示 PROTECTION MODE ENABLED!。

我的做法是写一个几十行的自定义集成,在 HA 启动时往内存里打补丁 ,不碰任何库文件,升级 HA 后也不用重做。我的机器是 T50 PRO 上下水版 ,还踩到了一个帖子里没提的坑:不同批次的机器上报的型号 ID 不一样。

环境:

  • Home Assistant OS(HA Green),Core 2026.9.3
  • 内置 ecovacs 集成,依赖 deebot-client==18.5.1
  • 设备:DEEBOT T50 PRO 上下水版,国区账号

一、问题原理

1. 设备识别不出来

deebot-client 靠设备上报的 class(硬件 ID) 去加载 deebot_client/hardware/<class>.py,文件里写的是这个型号支持哪些功能。加载逻辑很简单:

python 复制代码
# deebot_client/hardware/__init__.py
full_package_name = f"{__package__}.{class_}"
module = await asyncio.to_thread(importlib.import_module, full_package_name)

找不到对应文件,就会在日志里报:

复制代码
Device class "dur723" not recognized. Please add support for it: {... 'deviceName': ' DEEBOT T50 PRO 上下水版', 'model': 'FARADAYSE_PRO_A_W_CN', ...}
Device " DEEBOT T50 PRO 上下水版" not supported.

重点:先看日志里自己机器上报的 class 是什么,不要照抄别人的。 网上帖子里的 T50 Pro 上报的是 q0n7xe,我这台上下水版(型号 FARADAYSE_PRO_A_W_CN)上报的却是 dur723。只照帖子做 q0n7xe 的映射,对我这台没用。

查看方法:设置 → 系统 → 日志,搜 not recognized。

2. 地图打不开(HTTP 500)

设备识别成功后,地图实体 image.xxx_map 可能一直加载不出来,/api/image_proxy/image.xxx_map 返回 500。原因在 deebot_client/messages/json/map/__init__.py:

python 复制代码
class OnMapInfoV2(MessageBodyDataDict):
    @classmethod
    def _handle_body_data_dict(cls, event_bus, data):
        if (outline_version := data.get("outlineVer")) == "0":
            return HandlingResult.success()
        if outline_version != "1":
            # Unsupported version
            return HandlingResult.analyse()
        event_bus.notify(MapInfoEvent(map_id=data["mid"], info=data["info"]))
        return HandlingResult.success()

新固件回复的地图信息里 outlineVer 是 "2",被当成不支持的版本直接丢掉,MapInfoEvent 永远不会触发,生成 SVG 时就拿不到地图元信息。

截至写这篇文章时(deebot-client 18.6.0),这两个问题上游都还没合并修复,相关 PR:#1835(上下水版 q0n7xe)、#1797(接受 outlineVer 2)。

二、补丁思路

  • 型号映射 :Python 的 importlib.import_module 会先查 sys.modules。只要提前把 deebot_client.hardware.dur723 指到一个已有的相近型号模块上,库就能"找到"配置文件,效果和帖子里建软链接一样。
  • 地图 :把 OnMapInfoV2._handle_body_data_dict 包一层,遇到 outlineVer == "2" 就当成 "1" 交给原逻辑处理。GetMapInfoV2 继承自 OnMapInfoV2,主动拉取和被动推送两条路径都能覆盖。
  • 加载顺序:如果 ecovacs 集成比补丁先启动,设备已经被判成不支持了,所以补丁生效后会自动重载一次 ecovacs 配置项。

映射到哪个型号?

可选的有两个:

配置文件 型号 说明
elrxgb(软链到 c8rj4y) T50 Max Pro Omni 网上帖子用的;上游有个已知问题 #1483:getCleanPreference 返回 20005
nxeux7(软链到 fd60kt) T50 OMNI 上游 PR #1835 给上下水版用的就是这份,作者真机验证过

两者一对比,nxeux7 多了基站状态(GetStationState)、拖布自动清洗频率、GetCleanInfoV2,更贴近上下水版,所以我选了 nxeux7。

三、操作步骤

1. 新建自定义集成

在 HA 配置目录下新建 custom_components/ecovacs_patch/,放两个文件。用 File editor、Samba 或 SSH 都可以,不需要关闭保护模式。

custom_components/ecovacs_patch/manifest.json:

json 复制代码
{
  "domain": "ecovacs_patch",
  "name": "Ecovacs T50 Pro Patch",
  "codeowners": [],
  "dependencies": [],
  "documentation": "https://bbs.hassbian.com/thread-32418-1-1.html",
  "iot_class": "local_push",
  "requirements": [],
  "version": "1.0.0"
}

custom_components/ecovacs_patch/__init__.py:

python 复制代码
"""运行时给 deebot-client 打补丁,让科沃斯 T50 Pro 能在内置 ecovacs 集成里用。

1. 硬件 ID 别名:库里没有对应文件的型号识别不出设备,映射到功能相近的已支持型号。
2. 地图 outlineVer=2:库只认 "1",新固件回 "2" 时被丢弃,导致地图实体 HTTP 500。

上游修好后直接删掉这个集成即可(每个补丁都会先检查是否还需要)。
"""

from __future__ import annotations

import importlib
import logging
import sys

from homeassistant.config_entries import ConfigEntryState
from homeassistant.core import HomeAssistant
from homeassistant.helpers.typing import ConfigType

DOMAIN = "ecovacs_patch"
_LOGGER = logging.getLogger(__name__)

# 设备上报的硬件 ID -> 库里已有的配置模块
# dur723: T50 PRO 上下水版(FARADAYSE_PRO_A_W_CN),按上游 PR #1835 对同款 q0n7xe 的做法映射到 T50 OMNI
HARDWARE_ALIASES = {"q0n7xe": "elrxgb", "dur723": "nxeux7"}
SUPPORTED_OUTLINE_VERSIONS = ("2",)


def _patch_hardware() -> bool:
    from deebot_client import hardware  # noqa: PLC0415

    changed = False
    for alias, source in HARDWARE_ALIASES.items():
        name = f"{hardware.__name__}.{alias}"
        try:
            importlib.import_module(name)
            continue  # 库里已有,不需要补
        except ModuleNotFoundError:
            pass
        sys.modules[name] = importlib.import_module(f"{hardware.__name__}.{source}")
        hardware._NOT_FOUND.discard(alias)  # noqa: SLF001
        changed = True
        _LOGGER.warning("已把硬件 ID %s 映射到 %s", alias, source)
    return changed


def _patch_map_info() -> None:
    from deebot_client.messages.json.map import OnMapInfoV2  # noqa: PLC0415

    if getattr(OnMapInfoV2, "_ecovacs_patch", False):
        return
    original = OnMapInfoV2._handle_body_data_dict.__func__  # noqa: SLF001

    def _handle_body_data_dict(cls, event_bus, data):
        if data.get("outlineVer") in SUPPORTED_OUTLINE_VERSIONS:
            data = {**data, "outlineVer": "1"}
        return original(cls, event_bus, data)

    OnMapInfoV2._handle_body_data_dict = classmethod(_handle_body_data_dict)  # noqa: SLF001
    OnMapInfoV2._ecovacs_patch = True  # noqa: SLF001
    _LOGGER.warning("已让 OnMapInfoV2 接受 outlineVer=%s", SUPPORTED_OUTLINE_VERSIONS)


async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
    hardware_changed = await hass.async_add_executor_job(_patch_hardware)
    await hass.async_add_executor_job(_patch_map_info)

    # ecovacs 可能比本集成先加载完、已经错过了补丁,重载一次让设备重新识别
    if hardware_changed:
        for entry in hass.config_entries.async_entries("ecovacs"):
            if entry.state is ConfigEntryState.LOADED:
                hass.async_create_task(hass.config_entries.async_reload(entry.entry_id))
    return True

如果你的机器上报的是别的 class,在 HARDWARE_ALIASES 里加一行就行,比如 "0gxgac": "nxeux7"。可选的配置文件见 deebot_client/hardware 目录,挑一个同系列的。

2. 在 configuration.yaml 启用

yaml 复制代码
# 科沃斯 T50 Pro 补丁(硬件ID别名 + 地图 outlineVer=2)
ecovacs_patch:

3. 检查配置并重启

开发者工具 → YAML → 检查配置,通过后重启 HA(SSH 里执行 ha core check && ha core restart 也一样)。

日志里看到下面几行,说明补丁已生效:

复制代码
WARNING [custom_components.ecovacs_patch] 已把硬件 ID q0n7xe 映射到 elrxgb
WARNING [custom_components.ecovacs_patch] 已把硬件 ID dur723 映射到 nxeux7
WARNING [custom_components.ecovacs_patch] 已让 OnMapInfoV2 接受 outlineVer=('2',)

(另外会有一条 We found a custom integration ecovacs_patch which has not been tested...,所有自定义集成都会有这条,不用管。)

4. 添加 Ecovacs 集成

设置 → 设备与服务 → 添加集成 → 搜索 Ecovacs,填科沃斯 App 的账号和密码。如果之前已经加过、设备是空的,补丁会自动重载;没反应的话手动重新加载一次这个集成。

四、效果

我这台识别出 42 个实体(其中 14 个诊断/配置类的默认禁用),主要有:

  • vacuum.xxx:开始/暂停/回充、吸力档位
  • 电量、基站状态、本次和累计清扫面积/时长
  • 主刷、边刷、滤网、尘袋、拖布、清洁液等耗材寿命,以及对应的重置按钮
  • 拖布烘干、手动集尘、重定位按钮
  • 自动集尘频率、工作模式、水量档位、当前地图
  • 地图实体 image.xxx_map:通过 /api/image_proxy 返回 200 的 SVG

五、注意事项

  1. 先看自己的 class 再映射 。同样叫 T50 PRO,常见的就有 q0n7xe、dur723、0gxgac 几种,日志里 not recognized 那一行写得很清楚。
  2. 映射的是"相近型号"的配置,上下水版特有的功能(比如自动上下水相关设置)可能没有对应实体,这是正常的。个别命令如果机器不支持,日志里可能会有少量 warning。
  3. 补丁打在内存里,HA 升级后照样生效。等上游正式支持你的型号后,_patch_hardware 会检测到库里已经有对应文件,自动跳过;到时候把 custom_components/ecovacs_patch 和 yaml 里那一行删掉就行。
  4. 补丁依赖 deebot-client 的内部实现(hardware._NOT_FOUND、OnMapInfoV2),哪天库改了结构,补丁可能会失效。升级后记得看一眼日志里那几行补丁提示还在不在。

参考

相关推荐
zxsz_com_cn1 天前
预测性维护中的迁移学习:把A产线的模型搬到B产线
机器学习·工业4.0·iot·设备管理·预测性维护
刚及格的陆拾伍2 天前
Wi-Fi核心知识精要:从频段到帧结构全解析
网络·物联网·网络协议·信息与通信·iot
J_bean3 天前
IOT接入层-阐述物联网四种设备接入方式
mqtt·iot·设备接入·设备直连·网关透传
调试优选官10 天前
IoT物联网系统定制落地实践:从设备接入、协议网关、平台分层到业务应用,如何做技术选型、交付验收、责任边界与长期运维成本评估及迁移安排
物联网·iot·成本分析
K成长日志11 天前
DALI协议-Part209-颜色控制
物联网·网络协议·iot·智能照明·智能建筑·dali
Alsmile11 天前
乐吾乐物联网平台保姆级教程:从设备接入、场景联动到可视化大屏,一篇搞定
物联网·iot
K成长日志12 天前
BLE链路层-隐私保护
网络·物联网·蓝牙·iot·ble
K成长日志12 天前
BLE链路层-Feature Support
网络·嵌入式·无线通信·蓝牙·iot·ble
会周易的程序员13 天前
5 节点边缘冗余方案(上):基于 aiRaft 的物联网高可用控制面设计
c++·分布式·物联网·raft·iot·共识