Ecovacs in Home Assistant Part10 - extend ecovacs build-in integration for the Ecovacs X5 Pro( )
Ecovacs in Home Assistant Part10 - extend ecovacs build-in integration for the Ecovacs X5 Pro(mxse7w.py )
DEEBOT X5 PRO (China Version - MXSE7W)
This article specifically targets the Chinese Mainland version of the ECOVACS DEEBOT X5 PRO.
Unlike the global models, the Chinese version has several hardware and software differences that are important when integrating it with Home Assistant.
By extending the device capability definition, Home Assistant can access several additional OMNI station features that are already supported by the robot firmware.
The model covered in this article is:
Product: DEEBOT X5 PRO
Model: MXSE7W
Region: China
The capability definition for the Chinese version is located in:
https://github.com/DeebotUniverse/client.py/blob/dev/deebot_client/hardware/mxse7w.py
This file acts as the capability map between Home Assistant and the robot.
It tells Home Assistant:
which commands the robot supports
which settings can be modified
which events should be monitored
which sensors should be exposed
how the OMNI station can be controlled
"""Deebot DEEBOT X5 PRO OMNI Capabilities."""
from __future__ import annotations
# Import various "Capability" base classes and device type definitions from the deebot_client library
from deebot_client.capabilities import (
Capabilities,
CapabilityClean,
CapabilityCleanAction,
CapabilityCustomCommand,
CapabilityEvent,
CapabilityExecute,
CapabilityExecuteTypes,
CapabilityLifeSpan,
CapabilityMap,
CapabilitySet,
CapabilitySetEnable,
CapabilitySettings,
CapabilitySetTypes,
CapabilityStation,
CapabilityStats,
CapabilityWater,
DeviceType,
)
# Import relevant commands for controlling station actions and JSON serialization
from deebot_client.commands import StationAction
from deebot_client.commands.json import station_action
from deebot_client.commands.json.advanced_mode import GetAdvancedMode, SetAdvancedMode
from deebot_client.commands.json.auto_empty import GetAutoEmpty, SetAutoEmpty
from deebot_client.commands.json.battery import GetBattery
from deebot_client.commands.json.carpet import (
GetCarpetAutoFanBoost,
SetCarpetAutoFanBoost,
)
from deebot_client.commands.json.charge import Charge
from deebot_client.commands.json.charge_state import GetChargeState
from deebot_client.commands.json.child_lock import GetChildLock, SetChildLock
from deebot_client.commands.json.clean import CleanAreaV2, CleanV2
from deebot_client.commands.json.clean_count import GetCleanCount, SetCleanCount
from deebot_client.commands.json.clean_logs import GetCleanLogs
from deebot_client.commands.json.clean_preference import (
GetCleanPreference,
SetCleanPreference,
)
from deebot_client.commands.json.continuous_cleaning import (
GetContinuousCleaning,
SetContinuousCleaning,
)
from deebot_client.commands.json.custom import CustomCommand
from deebot_client.commands.json.efficiency import GetEfficiencyMode, SetEfficiencyMode
from deebot_client.commands.json.error import GetError
from deebot_client.commands.json.fan_speed import GetFanSpeed, SetFanSpeed
from deebot_client.commands.json.life_span import GetLifeSpan, ResetLifeSpan
from deebot_client.commands.json.map import (
GetCachedMapInfo,
GetMajorMap,
GetMapInfoV2,
GetMapSetV2,
GetMapTrace,
GetMinorMap,
SetMajorMap,
)
from deebot_client.commands.json.multimap_state import (
GetMultimapState,
SetMultimapState,
)
from deebot_client.commands.json.network import GetNetInfo
from deebot_client.commands.json.ota import GetOta, SetOta
from deebot_client.commands.json.play_sound import PlaySound
from deebot_client.commands.json.pos import GetPos
from deebot_client.commands.json.relocation import SetRelocationState
from deebot_client.commands.json.stats import GetStats, GetTotalStats
from deebot_client.commands.json.sweep_mode import GetSweepMode, SetSweepMode
from deebot_client.commands.json.true_detect import GetTrueDetect, SetTrueDetect
from deebot_client.commands.json.voice_assistant_state import (
GetVoiceAssistantState,
SetVoiceAssistantState,
)
from deebot_client.commands.json.volume import GetVolume, SetVolume
from deebot_client.commands.json.water_info import GetWaterInfo, SetWaterInfo
from deebot_client.commands.json.work_mode import GetWorkMode, SetWorkMode
from deebot_client.commands.json.work_state import GetWorkState
from deebot_client.const import DataType
# Import "Event" and enum definitions used to notify the client when the vacuum state changes
from deebot_client.events import (
AdvancedModeEvent,
AvailabilityEvent,
BatteryEvent,
CachedMapInfoEvent,
CarpetAutoFanBoostEvent,
ChildLockEvent,
CleanCountEvent,
CleanLogEvent,
CleanPreferenceEvent,
ContinuousCleaningEvent,
CustomCommandEvent,
EfficiencyModeEvent,
ErrorEvent,
FanSpeedEvent,
FanSpeedLevel,
LifeSpan,
LifeSpanEvent,
MajorMapEvent,
MapChangedEvent,
MapTraceEvent,
MultimapStateEvent,
NetworkInfoEvent,
OtaEvent,
PositionsEvent,
ReportStatsEvent,
RoomsEvent,
StateEvent,
StationEvent,
StatsEvent,
SweepModeEvent,
TotalStatsEvent,
TrueDetectEvent,
VoiceAssistantStateEvent,
VolumeEvent,
WorkMode,
WorkModeEvent,
auto_empty,
water_info,
)
from deebot_client.events.auto_empty import AutoEmptyEvent
from deebot_client.events.efficiency_mode import EfficiencyMode
from deebot_client.models import StaticDeviceInfo
def get_device_info() -> StaticDeviceInfo:
"""Get all static device information and capability mappings supported by the DEEBOT X5 PRO OMNI model."""
return StaticDeviceInfo(
DataType.JSON, # This model uses JSON data format for communication
Capabilities(
device_type=DeviceType.VACUUM, # Device type: Robotic Vacuum Cleaner
# --- Basic Status Capabilities ---
availability=CapabilityEvent(
AvailabilityEvent, [GetBattery(is_available_check=True)]
), # Availability status (determines if the device is online by checking the battery status)
battery=CapabilityEvent(BatteryEvent, [GetBattery()]), # Battery level status
charge=CapabilityExecute(Charge), # Charging control command (return to dock)
# --- Cleaning Control Capabilities ---
clean=CapabilityClean(
action=CapabilityCleanAction(command=CleanV2, area=CleanAreaV2), # Global cleaning and area cleaning
continuous=CapabilitySetEnable(
ContinuousCleaningEvent,
[GetContinuousCleaning()],
SetContinuousCleaning,
), # Continuous cleaning / Resume cleaning (Get/Set/Event)
count=CapabilitySet(CleanCountEvent, [GetCleanCount()], SetCleanCount), # Cleaning cycle count (e.g., clean 1 or 2 times)
log=CapabilityEvent(CleanLogEvent, [GetCleanLogs()]), # Cleaning logs / historical records
preference=CapabilitySetEnable(
CleanPreferenceEvent, [GetCleanPreference()], SetCleanPreference
), # Cleaning preference settings
work_mode=CapabilitySetTypes(
event=WorkModeEvent,
get=[GetWorkMode()],
set=SetWorkMode,
types=(
WorkMode.MOP, # Mop only
WorkMode.MOP_AFTER_VACUUM, # Mop after vacuum
WorkMode.VACUUM, # Vacuum only
WorkMode.VACUUM_AND_MOP, # Vacuum and mop simultaneously
),
), # Working mode switching
),
# --- Custom Commands & Error Handling ---
custom=CapabilityCustomCommand(
event=CustomCommandEvent, get=[], set=CustomCommand
), # Passthrough / custom low-level command capability
error=CapabilityEvent(ErrorEvent, [GetError()]), # Malfunction and error events
# --- Fan Speed Settings ---
fan_speed=CapabilitySetTypes(
event=FanSpeedEvent,
get=[GetFanSpeed()],
set=SetFanSpeed,
types=(
FanSpeedLevel.QUIET, # Quiet
FanSpeedLevel.NORMAL, # Normal
FanSpeedLevel.MAX, # Max
FanSpeedLevel.MAX_PLUS, # Max Plus
),
),
# --- Consumables & Maintenance Lifecycle ---
life_span=CapabilityLifeSpan(
types=(
LifeSpan.BRUSH, # Main brush
LifeSpan.FILTER, # Dustbin filter
LifeSpan.HAND_FILTER, # Handheld / fine filter
LifeSpan.SIDE_BRUSH, # Side brush
LifeSpan.UNIT_CARE, # Unit maintenance
LifeSpan.CLEANING_SOLUTION, # Cleaning solution
LifeSpan.SEWAGE_BOX, # Wastewater tank maintenance
),
event=LifeSpanEvent,
get=[
GetLifeSpan(
[
LifeSpan.BRUSH,
LifeSpan.FILTER,
LifeSpan.HAND_FILTER,
LifeSpan.SIDE_BRUSH,
LifeSpan.CLEANING_SOLUTION,
LifeSpan.SEWAGE_BOX,
]
)
],
reset=ResetLifeSpan, # Reset consumable lifecycle timer command
),
# --- Map Capabilities ---
map=CapabilityMap(
cached_info=CapabilityEvent(CachedMapInfoEvent, [GetCachedMapInfo()]), # Cached map information
changed=CapabilityEvent(MapChangedEvent, []), # Map update / change events
info=CapabilityExecute(GetMapInfoV2), # Get basic map details
major=CapabilitySet(MajorMapEvent, [GetMajorMap()], SetMajorMap), # Main map management
minor=CapabilityExecute(GetMinorMap), # Secondary / multi-floor map management
multi_state=CapabilitySetEnable(
MultimapStateEvent, [GetMultimapState()], SetMultimapState
), # Multi-map management switch state
position=CapabilityEvent(PositionsEvent, [GetPos()]), # Real-time vacuum coordinates on the map
relocation=CapabilityExecute(SetRelocationState), # Relocation command
rooms=CapabilityEvent(RoomsEvent, [GetCachedMapInfo()]), # Room / zone information on the map
set=CapabilityExecute(GetMapSetV2), # Map configurations and settings
trace=CapabilityEvent(MapTraceEvent, [GetMapTrace()]), # Cleaning path / movement trace
),
# --- Network & Audio ---
network=CapabilityEvent(NetworkInfoEvent, [GetNetInfo()]), # Wi-Fi and network status information
play_sound=CapabilityExecute(PlaySound), # Find my robot / play prompt tone
# --- Advanced Settings ---
settings=CapabilitySettings(
advanced_mode=CapabilitySetEnable(
AdvancedModeEvent, [GetAdvancedMode()], SetAdvancedMode
), # Advanced mode switch
carpet_auto_fan_boost=CapabilitySetEnable(
CarpetAutoFanBoostEvent,
[GetCarpetAutoFanBoost()],
SetCarpetAutoFanBoost,
), # Auto-boost suction on carpets switch
child_lock=CapabilitySetEnable(
ChildLockEvent, [GetChildLock()], SetChildLock
), # Child lock switch
efficiency_mode=CapabilitySetTypes(
event=EfficiencyModeEvent,
get=[GetEfficiencyMode()],
set=SetEfficiencyMode,
types=(
EfficiencyMode.ENERGY_EFFICIENT_MODE, # Energy-saving mode
EfficiencyMode.STANDARD_MODE, # Standard mode
),
), # Cleaning efficiency / power consumption mode
ota=CapabilitySetEnable(OtaEvent, [GetOta()], SetOta), # Firmware OTA update status and settings
sweep_mode=CapabilitySetEnable(
SweepModeEvent, [GetSweepMode()], SetSweepMode
), # Sweeping mode settings
true_detect=CapabilitySetEnable(
TrueDetectEvent, [GetTrueDetect()], SetTrueDetect
), # TrueDetect 3D structured light obstacle avoidance switch
voice_assistant=CapabilitySetEnable(
VoiceAssistantStateEvent,
[GetVoiceAssistantState()],
SetVoiceAssistantState,
), # YIKO voice assistant status and switch
volume=CapabilitySet(VolumeEvent, [GetVolume()], SetVolume), # Voice broadcast volume settings
),
# --- Operation & Station Status Monitoring ---
state=CapabilityEvent(StateEvent, [GetChargeState(), GetWorkState()]), # Vacuum main state (Charging/Working)
station=CapabilityStation(
action=CapabilityExecuteTypes(
station_action.StationAction, types=(StationAction.EMPTY_DUSTBIN,)
), # Control station actions (e.g., manually trigger dust collection)
auto_empty=CapabilitySetTypes(
event=AutoEmptyEvent,
get=[GetAutoEmpty()],
set=SetAutoEmpty,
types=(
auto_empty.Frequency.AUTO, # Automatic dust collection
auto_empty.Frequency.SMART, # Smart dust collection
),
), # Auto-empty frequency settings
state=CapabilityEvent(StationEvent, [GetWorkState()]), # OMNI station's own working state
),
# --- Cleaning Statistics Data ---
stats=CapabilityStats(
clean=CapabilityEvent(StatsEvent, [GetStats()]), # Current / single cleaning session stats (area, time)
report=CapabilityEvent(ReportStatsEvent, []), # Data reporting events
total=CapabilityEvent(TotalStatsEvent, [GetTotalStats()]), # Lifetime cumulative cleaning statistics
),
# --- Water Tank & Mop Module Control ---
water=CapabilityWater(
amount=CapabilitySetTypes(
event=water_info.WaterAmountEvent,
get=[GetWaterInfo()],
set=SetWaterInfo,
types=(
water_info.WaterAmount.LOW, # Low water level
water_info.WaterAmount.MEDIUM, # Medium water level
water_info.WaterAmount.HIGH, # High water level
),
), # Mopping water flow adjustment
mop_attached=CapabilityEvent(
water_info.MopAttachedEvent, [GetWaterInfo()]
), # Detect whether the mopping pad/bracket is installed
),
),
)
Overall Structure
The file follows a simple three-level hierarchy:
StaticDeviceInfo
│
└── Capabilities
│
├── clean
├── map
├── station
├── water
├── settings
├── battery
├── stats
└── ...
1.Root Node —— StaticDeviceInfo
StaticDeviceInfo is the root object.
It defines the robot's communication protocol (JSON) and registers every capability supported by the device.
2.Branch Nodes
Branch Nodes — Capabilities
Each branch groups together a specific category of functionality.
Each branch contains one or more commands, events, and configuration options.
3.Leaf Nodes
Leaf Nodes — Individual Commands
The leaf nodes are the actual commands and events exchanged with the robot.
These commands correspond to the JSON requests sent through the official ECOVACS Open Platform API.
When Home Assistant calls one of these commands, the robot executes the requested action and returns the corresponding status or result.
Extend the Built-in Home Assistant Ecovacs Integration for the DEEBOT X5 PRO (MXSE7W, China Version)
step 1.Copy the original hardware definition from the Home Assistant container.
cd /data/homeassistant202405
docker cp ha:/usr/local/lib/python3.14/site-packages/deebot_client/hardware/mxse7w.py .
This creates a local copy that can be edited safely.
step 2.Add new station actions for StationAction.CLEAN_BASE functionality
Locate the following section:
station=CapabilityStation(
action=CapabilityExecuteTypes(
station_action.StationAction,
types=(
StationAction.EMPTY_DUSTBIN,
),
),
) Replace it with:
station=CapabilityStation(
action=CapabilityExecuteTypes(
station_action.StationAction,
types=(
StationAction.EMPTY_DUSTBIN,
StationAction.DRY_MOP,
StationAction.WASH_MOP,
StationAction.CLEAN_BASE,
) # add StationAction.WASH_MOP, 20260715
), step 3.Replace the Original File
Copy the modified file back into the container.
docker cp mxse7w.py ha:/usr/local/lib/python3.14/site-packages/deebot_client/hardware/
docker restart ha
step 4.Verify in Home Assistant
The newly added station services should now appear in Home Assistant.
output
This approach extends the existing integration without modifying Home Assistant's core logic, making it a simple and maintainable customization for the Chinese Mainland MXSE7W model.
Comments
Comments are closed