Skip to content

Repository files navigation

Vacuum Agent

A phoenix rising from the wreck of a robot vacuum

HACS Default Release Home Assistant Tests Validate License: MIT

A custom Home Assistant integration that adds a whole control-and-intelligence layer on top of your robot vacuum — room-level cleaning, a live map you can actually drive from, a learning/ETA system, saved zones, battery-health tracking, a themeable dashboard, eighteen languages, and automation events — for Eufy, Roborock and Dreame. It uses an adapter pattern, so more brands can follow.

Vacuum Agent — a real home's map with every room painted in its own floor material, robot mid-clean

Every room painted with its real floor material — wood, marble, granite, tile, carpet — rendered live over your robot's actual map.

It doesn't replace your vacuum integration, it builds on it: for Eufy that's eufy-clean by jeppesens; for Roborock, Home Assistant's built-in Roborock integration; for Dreame, dreame-vacuum by Tasshack. Vacuum Agent consumes whatever they already expose and adds everything the stock integrations don't.


The map is the centerpiece

Put your robot's live map on the dashboard, then actually work from it:

  • Tap a room to queue it.
  • Draw a box to clean just that spot — no rooms to set up first — and save those boxes as named zones you reuse later (see Saved zones).
  • Rotate the map to match how your home is actually oriented, and mask sensor noise with hide-areas.
  • Floor textures — paint every room with its real material (wood planks, tile + grout, carpet, marble, concrete, granite) as one continuous, themeable floor. It reads like a floor plan of your house, and every material's colours and a Map Texture Rotation are tunable in the theme editor.
  • Custom room colours — give any room its own fill colour, or recolour the whole room palette from the theme editor.
  • Furnished render — trace your real rooms, drop in a to-scale drawing of your home, and align it once so the robot, dock, and cleaning path drive across your actual furniture (Live / Blend / Art view modes).

Per-room control that learns

Per-room cards with profile, learned ETA, and floor type

  • Room-level control — select individual rooms by name and send targeted clean jobs, rather than cleaning the whole floor.
  • Queue management — build, inspect, and reorder a cleaning queue before the job starts.
  • Run profiles and room profiles — save vacuum settings (suction, mop, passes) per-room or as named run profiles you trigger from the UI or an automation.
  • Room rules — attach per-room rules (e.g. mop-only, skip when occupied) that apply automatically when a job is built, driven by any Home Assistant entity.
  • Learning system and ETA — records how long each room actually takes and uses that to estimate completion; estimates improve with every run. Cleans you start from the vendor app are captured and folded into learning too.
  • Stall detection — fires a Home Assistant event when the vacuum has been in a room significantly longer than its learned average.
  • Room drift detection — watches for new rooms the vacuum reports after setup, and for configured rooms that stop being reported, surfacing both for one-click review; permanently suppresses phantom rooms so they never become managed entities.

Saved zones

Beyond one-off box-cleaning, draw a zone, name it, and file it under a room — then re-clean it any time. A collapsible Saved Zones panel lets you multi-select several, apply shared suction/mop settings, and clean the whole selection at once (e.g. a stove area filed under the Kitchen). Six services back it for automations: create_saved_zone, rename_saved_zone, delete_saved_zone, set_saved_zone_room, clean_saved_zone, and clean_saved_zones.

Battery health you can trend

Cumulative cycle counter, zone-aware charge-rate tracking (low / high / mid-job), CC/CV charge-speed indices, per-job drain rates (%/min, %/hour, %/m²), and a baseline-relative health proxy — built to spot degradation trends 6–12 months before they impact cleaning.

Metrics — Battery sub-tab

Make it yours — themes & languages

A built-in theme editor for the panel card, with three layers: ready-made presets, a high-level palette editor, and full token-level control with live previews (including every floor material). Export/import via clipboard or file to share themes or migrate between installs. There's a validated colorblind-safe theme, and a faulted run carries a warning triangle on its errors badge so it can be spotted without relying on colour. The language menu also holds a per-user typeface pickerOpenDyslexic ships built in, and you can drop your own .woff2 fonts into config/eufy_vacuum/fonts/ and they appear in the picker after a restart.

Themes — presets

The card speaks eighteen languages out of the box — English plus seventeen translations: German, French, Spanish, Dutch, Italian, Portuguese, Russian, Polish, Czech, Turkish, Indonesian, Arabic, Hebrew, Japanese, Korean, and Chinese (Simplified & Traditional), including right-to-left Arabic & Hebrew — via a per-user language globe in the header, plus drop-in support for your own locale. A pack follows your Home Assistant language automatically once it's promoted to stable (after native review); until then, pick it from the globe. Anything untranslated falls back to English. (Native reviewers very welcome — see the translations discussion.)

The proof is the everyday surfaces themselves — a room's own controls and a saved routine's step-by-step plan — rendered across the shipped languages:

The Room card's cleaning controls — mode, suction, path, passes and Start — in English, Indonesian, Czech, German, Spanish and French

A saved routine's step-by-step plan and its Run button — in English, Indonesian, Czech, German, Spanish and French

Six of the eighteen. The other twelve — including right-to-left Arabic and Hebrew — are below.

All eighteen languages — the room card, a saved routine, and the whole dashboard card with its map

The room card

The room card in Italian, Dutch, Polish, Portuguese, Turkish and Russian

The room card in Hebrew, Arabic, Korean, Japanese, Simplified Chinese and Traditional Chinese — Hebrew and Arabic are fully mirrored, with the controls right-aligned and Start moved to the left

The routine card

A saved routine in Italian, Dutch, Polish, Portuguese, Turkish and Russian

A saved routine in Hebrew, Arabic, Korean, Japanese, Simplified Chinese and Traditional Chinese — in Hebrew and Arabic the step numbers sit on the right and Run moves to the left

The dashboard card — map, layers and all

Room names stay as you named them; everything the integration supplies is translated.

The dashboard card with its rendered map and map-layer list, in English, Indonesian and Czech

The same card in German, Spanish and French

The same card in Italian, Dutch and Polish

The same card in Portuguese, Turkish and Russian

The same card in Hebrew, Arabic and Korean — in Hebrew and Arabic the whole card mirrors: layer checkboxes move to the right of their labels, the zoom controls reverse, and Dock and Start move to the left, while the floor plan itself keeps its orientation

The same card in Japanese, Simplified Chinese and Traditional Chinese

Fault names are translated too — 237 of them across both brands, so a base-station error reads as "Base station dust duct blocked" in your language rather than as code 6112.

So are the maintenance guides — the ordered care steps and warnings for each part, not just their labels. Turkish even gets its percent sign on the correct side of the number (%100, not 100%), and the hour unit follows the language rather than the string around it. The filter's guide in all eighteen languages →

Also on Roborock

The Roborock adapter (tested on the S6) brings the stock integration up to parity with Eufy: the same per-room rendered map, floor textures, tap-to-queue, draggable room-name labels, and draw-a-zone — plus native per-room live rollover and per-room fan speed. Where a brand doesn't expose a fan-speed select entity, suction is still settable right in the zone/clean panel.

Wash docks surface their two consumables — Dock Cleaning Brush and Dock Strainer. They live on the dock, which Roborock exposes as a second device, so they were previously invisible. Whether a dock can wash, dry or empty is read from the dock itself rather than guessed, and a bare charger produces no rows and no buttons.

Also on Dreame

Dreame arrives through dreame-vacuum by Tasshack, and the map is the part that works differently. Eufy's rooms are inferred from map screenshots and Roborock's arrive as vendor rooms; Dreame's arrive as encoded map data on a camera attribute, which Vacuum Agent decodes itself — so you get true per-room areas, furniture, and live robot heading rather than an approximation.

Dreame L10s Ultra Gen2 — a decoded map with true per-room areas, furniture and floor materials, room names drawn by Vacuum Agent

Dreame's map, decoded rather than screenshotted: true per-room areas, furniture, and live robot heading — with room labels drawn by Vacuum Agent and the baked-in ones switched off upstream.

Maintenance comes from Dreame's own manuals. 700 models are routed to a maintenance profile built from the manufacturer's published care instructions rather than guessed at, and the guidance is translated into all eighteen languages.

Set your map up in the Dreame integration first. A Dreame that has no saved map yet is the one case that misbehaves during first setup; a mapped device is unaffected. Run a mapping pass, let it save, then add the vacuum here — or if you hit it, finish mapping and reload the integration.

Two renderers, one backdrop — and you choose which draws what. The dreame-vacuum integration bakes labels and overlays into the camera image it produces, and Vacuum Agent draws its own on top of that image. Where both are switched on you see the same thing twice — most visibly room names, each appearing once as a baked-in label and once as a Vacuum Agent name pill.

Nothing is broken when that happens; it is two sets of switches that don't know about each other. Fix it from whichever side you prefer:

  • In dreame-vacuum: Configure → Options → Hidden Map objects, and tick Room Names, Room Icons and Room Name Background. That list also covers the path, no-go and no-mop zones, virtual walls, the robot and charger icons, furniture, carpet and floor material — so if you would rather Vacuum Agent drew an overlay, hide it there.
  • In Vacuum Agent: the Rooms map has a Hide room labels toggle, which turns off our name pills and leaves the baked-in ones.

Either change takes effect straight away — dreame-vacuum reloads itself and redraws, with no Home Assistant restart needed. Worth a minute during setup, because the default is both on.

Go-to and zone clean are per-model. A drawn box has to be inverted into the robot's own coordinate frame, and getting that wrong sends the robot to the wrong place — so both controls start switched off on any model whose geometry hasn't been checked against real hardware. Today that means the L10s Ultra Gen2. Every other Dreame gets rooms, map, maintenance and history, and simply doesn't show those two controls. Open an issue if you'd like yours verified.

Two ways to override how a Roborock cleans

Path-optimising vacuums re-route whatever you send them. You pick five rooms in a sensible order, the robot takes them as one batch, and it cleans them in whatever order its own planner prefers. There are two ways to override that, and they are different tools with different reach.

Strict order is per-run. Turn it on and Vacuum Agent stops sending one batch — it dispatches one room per phase, so your queue order is the cleaning order. It costs a dock trip between rooms, which is why it is opt-in and says so. It governs the runs you start, and does nothing on brands that already honour order.

Override Order is persistent, and it reaches past Home Assistant. It writes a saved cleaning sequence into your Roborock app's own settings, so every start afterwards follows it — including a run you begin from the Roborock app itself, days later, with Home Assistant asleep.

Because it edits something that lives in your vendor app, the row is built to be blunt about it:

  • The switch declares intent and writes nothing. Apply and Clear are separate, explicit actions.
  • Turning the switch off is not an undo. The device keeps its saved order — switching off never wipes a sequence you may have set yourself in the Roborock app. Clear is the destructive one, and it asks first. There is a service too: eufy_vacuum.clear_clean_sequence.
  • The row shows the device's real order whatever the switch says, so "off" can never quietly hide a sequence that is still in force.
  • Three states, never two. Green — the device matches your queue. Amber — it differs; Apply writes yours. Grey — the order could not be read. Grey never blocks Start, and Apply is how you find out: you write, the device acknowledges, and now you know.

The Rooms view on a phone: the advisory with "Force this exact order" for a single run, and below it the Override Order row showing the device sequence differing from the queue

Both controls, one screen. "Force this exact order" is the per-run one; the amber row below it is the persistent sequence saved in the Roborock app.

The row tells you which of the three states you are in before you touch anything:

The row in green, reading "Sequence matches your queue"

The row in amber, reading "Sequence differs from your queue", listing the device order and the queue order side by side

Green: the robot already agrees with your queue. Amber: it does not, and the row names both orders so you can see exactly what Apply would change.

Where the row appears: only on vacuums whose adapter declares a device-side clean order — today that means Roborock V1 models (S6, Q5 Pro / a72, S7 / a15, S8 / a70). Newer Qrevo and B01 units use a different transport, and Eufy has no equivalent concept at all. On anything else the row simply does not render — so if you own a Eufy, this control is not hiding somewhere, it does not exist for your robot.

On a phone

The panel is not a desktop layout that survives a small screen. Held upright it reflows to a bottom tab bar with an overflow sheet; turned sideways the status pane and bottom navigation get out of the way, because in landscape they were taking a quarter of the screen for information you were not looking at — and they only yield where something can actually be scrolled, so a short view can never lose its navigation with no gesture left to bring it back.

The theme editor comes with it: the token and palette editors lay out on a phone, the search row collapses, and the colour hint is stated once at the top instead of on every row. Phone widths are part of the automated layout gate on every view, so a change that pushes something off a 390px screen fails the build rather than the user.

Battery stats in portrait: charge rates as stacked label-and-value blocks

The same battery stats in landscape: the charge rates become a real table with zone, rate and notes columns

The same data, twice. Portrait stacks each rate into its own block; landscape has the width for a real table, so it uses one. Neither is the other one squeezed.

The theme token editor on a phone in OpenDyslexic, editing the marble vein colour with a live textured room preview

The token editor on a phone — here in OpenDyslexic, with the floor-texture preview updating live as the vein colour changes.

Automation events

Wire the vacuum into the rest of your home. Vacuum Agent fires eufy_vacuum_job_finished, eufy_vacuum_room_started, eufy_vacuum_room_finished, eufy_vacuum_run_incomplete, eufy_vacuum_path_blocked and eufy_vacuum_stall_captured for use in automations. Two more — eufy_vacuum_room_skipped and eufy_vacuum_stall_detected — depend on the robot reporting which room it is in mid-run, so they fire on brands that track position reliably and stay quiet on those that do not (Roborock's own path optimisation ignores the dispatched room order, so neither fires there). Run/room profiles and zone cleans are triggerable straight from automations and scripts too.

Where it lives

  • Built-in Lovelace panel card — the integration registers its own sidebar dashboard panel. No separate card repository or manual resource registration needed.
  • Drop-in dashboard cards — three compact cards you add to your own dashboards from the card picker (no resources to register): Vacuum Agent — Dashboard Mode (vacuum-agent-dashboard), a multi-room control card (pick rooms + settings, run a saved profile or app scene, embedded map, Start / Dock); the Eufy Room Card (eufy-room-card), one card per room; and the Vacuum Agent Profile Card (vacuum-agent-profile-card), one card per saved run profile, showing the routine's step sequence and a Run button. All three carry the language globe, and the Dashboard card's embedded map pins its pan/zoom across reloads and lets you drag room-name labels. See Dashboard & Room cards.

Tested hardware

Brand Model Status
Eufy X10 Pro Omni Tested — Eufy adapter reference
Eufy Other models Untested — may work, not supported
Roborock S6 Tested — Roborock adapter reference
Roborock Q5 Pro (a72) Tested by a contributor — catalogued as mop-unsettable and dockless
Roborock Other models Untested — may work, not supported
Dreame L10s Ultra Gen2 Tested — Dreame adapter reference
Dreame Other models Untested — may work, not supported

Each brand's adapter was built and validated against one reference model — the Eufy X10 Pro Omni, the Roborock S6 and the Dreame L10s Ultra Gen2. Those are the devices the adapter's behavior is tested against; other models of the same brand reuse that adapter and frequently work, but aren't individually verified.

If you run this on another model, please open an issue with the model name and what worked or didn't — the table grows from there.

Eufy: which models Vacuum Agent can drive

Vacuum Agent's value — per-room cleaning, the live map, room rollover, and the learning/ETA system — all depend on the robot building a room map with per-room segments, delivered over Eufy's MQTT transport. If your robot doesn't map rooms, Vacuum Agent has nothing to add.

Not supported — basic navigation robots (no map, no rooms). These bump-and-go and gyroscopic-navigation models never build a room map, so per-room cleaning, the map view, and learning simply don't apply. They work fine in eufy-clean on their own for start/stop, suction and status — use it directly:

  • RoboVac C-series — 11C, 11S, 15C / 15C MAX, 25C, 30C / 30C MAX, 35C
  • RoboVac G-series — G10 Hybrid, G20 / G20 Hybrid, G30 (incl. Verge / Hybrid / +SES), G32, G35 / G35+, G40 (incl. Hybrid / Hybrid+), G50

Transport-dependent — may not work. The mapping robots — the X-series (X8, X9 Pro, X10 Pro Omni), S1 / S1 Pro, L-series (L60, L70), LR-series (LR20 / LR30 / LR35), Omni C20 and AE C10 — build a map and should drive Vacuum Agent, but only when eufy-clean talks to them over MQTT. eufy-clean v1.12 added a legacy Tuya transport (cloud / local) for older robots; on that path the live map and the room list are never sent, so the map and per-room features go dark even on a robot that can map. Only the X10 Pro Omni is verified. The rest are unconfirmed — feel free to test and report back via an issue and this list will be updated.

Prerequisites

Vacuum Agent is a supervisory control layer — it consumes whatever your provider integration already exposes. The only hard requirement is one supported vacuum provider; everything else is capability-dependent.

Required

  • Home Assistant 2025.6.0 or later — that is the minimum HACS enforces. Development and testing happen on 2026.8+; older cores are permitted and expected to work, but are not exercised, so reports from them are welcome.
  • A working vacuum.* entity for your robot, from your brand's upstream integration: eufy-clean by jeppesens for Eufy, Home Assistant's built-in Roborock integration for Roborock, or dreame-vacuum by Tasshack for Dreame. Vacuum Agent builds on top of it — it doesn't replace it.

Optional (Vacuum Agent works without these — they unlock extra capabilities)

  • A provider map / camera / image entity for the live-map backdrop and richer map views (including the rendered floor-texture map). On Eufy this comes from eufy-cleancamera.<device>_map first appeared in v1.11.1, and running the current release is almost always better; on Roborock it's the built-in integration's map image; on Dreame it's the map camera the dreame-vacuum integration exposes, which Vacuum Agent decodes into true per-room areas and furniture. Without it, room control, queues, and profiles still work — you just don't get the live backdrop or the map-based tools.
  • The Python science stack (numpy, Pillow, scipy) for Auto (CV) map segmentation — bundled in Home Assistant OS, but not always present on Container / Core / Supervised installs. Without it, Auto (CV) is hidden and you set rooms up manually (draw bounds with primitive shapes, or compose over a live/custom map — a few minutes in the editor). Manual setup is fully supported and is the source of truth; it is never required to install or load the integration.
  • Brand-specific companion entities (dock, station, etc.) for richer controls and status.

Installation via HACS

  1. In Home Assistant, open HACS and search for Vacuum Agent.
  2. Install it.
  3. Restart Home Assistant.
  4. Go to Settings → Devices & Services → Add Integration and search for Vacuum Agent.
  5. In the setup form, pick your vacuum entity from the Vacuum dropdown. This is the vacuum.* entity provided by your brand's upstream integration (eufy-clean for Eufy, the built-in Roborock integration for Roborock, dreame-vacuum for Dreame) — you need that integration installed and working first. The Vacuum field is optional during setup; you can leave it blank now and fill it in later via Configure.
  6. A Vacuum Agent item appears in your sidebar (the default panel title; rename it per-vacuum later). The panel card is registered automatically — no manual dashboard editing required.

If you submitted setup without picking a vacuum, the sidebar entry still appears but shows a "setup needed" placeholder pointing you back to Settings → Devices & Services → Vacuum Agent → Configure to add it.

Configuration

Setup form (initial install)

Field Required Description
Vacuum Optional The vacuum.* entity from your brand's upstream integration (eufy-clean for Eufy; the built-in Roborock integration for Roborock). Leave blank to skip for now and set it later via Configure.
Tested model Required A label for your own reference — it does not affect behaviour. The adapter and its capability flags are detected automatically. Defaults to the Eufy X10 Pro Omni.
Notes Optional Free-form text for your own reference. Stored on the config entry and shown again when you reopen Configure; it is not displayed on the integrations page, and it is redacted from diagnostics downloads.

Options flow (Configure button)

After the initial install, open Settings → Devices & Services → Vacuum Agent → Configure to update:

Field Description
Vacuum Change which vacuum.* entity the integration manages.
Notes Update your notes.

Removing the integration

Go to Settings → Devices & Services, find Vacuum Agent, and delete it. The integration's stored settings go with the entry. Map images, learning history, battery logs and any stall captures are files under <config>/eufy_vacuum/ and are deliberately left in place, so re-adding the same vacuum recovers them — delete that folder by hand if you want a clean wipe.

Remove a single vacuum (keeping the others): open Settings → Devices & Services → Vacuum Agent, click that vacuum's device, and choose Delete. Its sidebar panel, entities, and stored data are removed and the other managed vacuums are left untouched. Its learning history and saved map images stay on disk, so re-adding the same vacuum restores them.

Note: this integration sits on top of your provider integration (e.g. eufy-clean), which provides the underlying vacuum.* entity. Removing Vacuum Agent does not remove it; remove that separately if you no longer need it.

What's included

  • The eufy_vacuum custom integration (services, events, data layer).
  • A Lovelace panel card served directly from the integration. No separate HACS frontend repository and no manual resource registration needed.

Screenshots

Live site — kingchddg901.github.io/Vacuum_Agent: the project's hub. A theme gallery renders the real card under every community-submitted theme (each tab, the External Jobs subtab, the review wizard); an animal gallery shows the map companions you can submit — or dedicate to a pet at Rainbow Bridge; and the full docs live there too. The galleries are rebuilt by the render harness on every push to master, so they never go stale — the static tour below is just a quick offline glance.

Click to expand the full panel tour

Maintenance

Track filter, brush, mop, and dock-water status against the integration's maintenance intervals — plus, on devices that report them, lifetime usage totals (area, time, cleans) and the dock firmware version.

Maintenance tab

Base Station

Live dock state, water reservoir projection, and gated dock actions (wash mop, dry mop, empty dust).

Base Station tab

Metrics

Aggregates across the learning dataset in six sub-tabs — Learning, Rooms, Profiles, Water, Dock and Battery — filtered by room, profile, status, or learning use.

Metrics tab

Metrics — Battery

Cycle count, zone-aware charge rates (low / high / mid-job), per-job drain rates (%/min, %/hour, %/m²), and per-mode aggregates from single-bucket jobs. Pointer to the raw CSV / JSONL files for long-term review.

Metrics — Battery sub-tab

Learning Review

Inspect every recorded run, exclude outliers (test runs, false completions, bad room attribution), and see which profiles match the current settings. Open any run for a Run summary — per-room results, elapsed vs cleaning time, area covered, battery used, mid-run recharges, and every fault with its hardware attribution and whether it cleared.

Learning Review tab

External Jobs review

Runs you start from the vendor app (not just HA-dispatched jobs) are captured and surface here for review — confirm the room count (split or merge the detected cuts), name each room, and correct its settings — so app-started cleans feed learning too.

External Jobs subtab — app-started runs awaiting review Review wizard step 1 — confirm the room count Review wizard step 2 — name each room and correct settings

Room Rules

Per-room blocker and modifier rules driven by any Home Assistant entity — skip a room when a door is open, switch profiles when occupancy changes, etc.

Room Rules tab

Themes

Built-in theme editor with three layers: ready-made presets, a palette editor for high-level colors, and full token-level control with live previews.

Themes — presets Themes — palette Themes — tokens

Setup

Register the vacuum, import maps, and configure each room — exclude ghost rooms, set floor type per room (drives the cleaning profile system and the floor-texture map). The Setup tab stays useful after the initial wizard: it watches for new rooms the vacuum reports later and for configured rooms that disappear, surfacing both for one-click review.

Setup tab

Interactive room map (optional)

Tap a room on a live floor-plan view to queue it; double-tap to configure. The map view is off by default — flip the list/map toggle in the Rooms tab. With a provider map entity it works straight away; without one, or to draw your own room shapes (which is what double-tap-to-configure needs), you upload and segment a map once — see Map Configuration.

Interactive room map

Feature summary

  • Floor-texture map — each room painted in its real material (wood, tile, marble, concrete, granite, carpet), themeable, on all three brands
  • Room selection and targeted clean jobs
  • Cleaning queue — build, reorder, inspect before starting
  • Zone cleaning — draw boxes on the live map and clean just those areas
  • Saved zones — named, reusable clean zones filed under a room, with per-zone services
  • Live map — live backdrop, tap-to-queue rooms, map rotation, hide-areas, and a to-scale furnished-render overlay
  • Custom room colours — per-room fill colour and a themeable room-fill palette
  • Room profiles — per-room suction, mop, and pass settings
  • Run profiles — named full-run configurations, triggerable from automations
  • Room rules — conditional per-room behavior
  • Learning system — records per-room timing, improves ETA estimates over time
  • ETA display — estimated completion time shown in the panel
  • Stall detection — event fired when a room takes significantly longer than learned average
  • Battery health — cycle counter, zone-aware charge rates, per-job drain efficiency, baseline-relative health proxy
  • Automation events — job, room, stall, path-blocked, and incomplete-run events
  • Dock actions — wash mop, dry mop, empty dust bin (model-dependent)
  • Maintenance tracking — reset maintenance counters from the UI; lifetime usage totals and dock firmware where the device reports them
  • Room drift detection — auto-surfaces new rooms for review, suppresses phantoms
  • Theme system — full theme editor with clipboard and file-based import/export
  • Multi-language card — per-user language picker, 17 built-in translations + drop-in locales (English fallback)
  • Accessibility — a validated colorblind-safe theme, a shape-coded warning badge on faulted runs, and a per-user typeface picker with OpenDyslexic built in
  • Accessible typefaces — drop your own .woff2 fonts into config/eufy_vacuum/fonts/ and they appear in the picker; coverage is verified against each language's actual characters
  • Stall capture — when a run stalls, save a rendered picture of the room it stopped in, raise a notification, and fire an event carrying the file path (opt-in, per vacuum)
  • Named faults — 237 fault names across both brands, translated in every shipped language, with hardware attribution (dock or robot) and whether the fault cleared
  • Override Order — write a saved cleaning sequence into your Roborock app, so every start follows it (Roborock V1 only); strict order for a single run
  • Setup → System — every value Vacuum Agent reads from your vacuum, where it came from, and what happened when two candidates disagreed
  • Entity overrides — point Vacuum Agent at the right entity by hand when detection gets it wrong (set_entity_override)
  • Mobile layout — the panel reflows to a bottom tab bar and an overflow sheet on phones; the chrome yields in landscape, and the theme token and palette editors lay out on a phone too (verified at 390px and at 720×344 held sideways)

Documentation

Full docs live at kingchddg901.github.io/Vacuum_Agent/docs — part of the project site alongside the theme and animal galleries.

Using it

  • User guide — a walk-through of every panel tab
  • Setup — the initial wizard and ongoing room-drift review
  • Battery health — what's tracked, the twelve sensors, charting, raw CSV/JSONL access
  • Accessibility — the colorblind-safe theme and the shape-coded warning badge
  • Fonts — OpenDyslexic, and adding your own typefaces

Automations

Contributing & internals

For developers and porters

Under the hood the integration is adapter-driven: every brand-specific fact (entity IDs, vocabulary, dispatch payload shape, dropdown option lists, maintenance components, water-tank measurements, upkeep guides) lives in one per-vacuum adapter config dict. The framework reads from this registry at runtime; core never branches on brand — brand-specific dispatch and decode engines live in core registries but are selected only by the name the adapter declares. (One legacy exception: a vacuum with no adapter config registered falls back to the Eufy dispatch payload shape.)

The Eufy adapter at custom_components/eufy_vacuum/adapters/eufy/ is the reference implementation. Adding support for a different vacuum brand is a config-only change: write a parallel adapters/<brand>/ folder, declare what your brand exposes, register the adapter at integration setup. The framework, the card, the learning system, and the dispatch path all consume whatever the adapter declares.

See the porting guide for the vacuum-specific workflow including a four-brand catalog (Eufy, Roborock, Dreame, Narwal) of sample dispatch configs. For the general pattern as a reusable architecture — applicable to any multi-vendor HA integration — see ha-adapter-pattern.

Contributors

Built and maintained by @kingchddg901, with contributions from the community:

  • @Nebr88 (Andrey Dmitriyev) — Roborock adapter fixes: clean-duration and live-room tracking (#19) and unnamed-map imports (#18).
  • @loryanstrant (Loryan Strant) — catalogued the Q5 Pro (a72) as mop-unsettable and dockless, verified on his own hardware (#53).
  • @fhteaglehonorary contributor. One simple question about the staged run (#41) got me over the edge on what the stepped-profile engine needed — the foundation the whole Profile Cookbook stands on — plus the report of a bug that would have quietly killed the profile buttons (#42).

Translations. The seventeen built-in language packs — German, French, Spanish, Dutch, Italian, Portuguese, Russian, Polish, Czech, Turkish, Indonesian, Arabic, Hebrew, Japanese, Korean, and Chinese (Simplified & Traditional) — are AI-drafted and ship as draft until a native speaker reviews them (a draft pack never auto-activates from your Home Assistant language; you pick it from the globe). Corrections, promotions to stable, and brand-new locales are all welcome — start in the translation discussion or follow the Translate the card guide (a translation is data, not code). Community translators are credited here.

Acknowledgements

This integration would not exist without eufy-clean by jeppesens and its contributors. Their work reverse-engineering the Eufy protocol and maintaining the HA integration that bridges the vacuum to Home Assistant is the foundation everything here is built on. If you find this useful, go give their repo a star too.

Vacuum Agent's Roborock support builds on Home Assistant's built-in Roborock integration and its maintainers — their work bringing Roborock's maps, rooms, and cleaning controls into Home Assistant core is what the Roborock adapter stands on.

Licence

MIT — fork it, adapt it, ship it commercially. You don't need my permission and you don't owe this repository a credit line in your README. MIT's one requirement is that you keep the copyright notice and licence text with the code you reuse. See LICENSE for full terms.

The MIT licence covers this project's own code, not everything in the package. The install also bundles the OpenDyslexic typeface under the SIL Open Font License 1.1, which carries its own requirements: the licence file must travel with the font, "OpenDyslexic" is a Reserved Font Name (a modified font may not use it), and the font may not be sold on its own. If you redistribute this integration you are redistributing that font too — keep frontend/fonts/OFL.txt in place. Full attribution in NOTICE.

Beyond the licence, one ask: this project is a top-level addition built on eufy-clean. Please keep acknowledging that dependency in anything you build from this.

Issues

Please report bugs and feature requests at: https://github.com/kingchddg901/Vacuum_Agent/issues

About

Eufy, Roborock & Dreame vacuums in Home Assistant — room-by-room cleaning, live map, learning ETAs, saved zones and a custom card

Topics

Resources

Stars

11 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages