Skip to content

v1.11.0

Choose a tag to compare

@jeppesens jeppesens released this 22 Jun 12:27
c722a24

Eufy Robovac MQTT — v1.11.0

This is a big feature release: live map rendering, off-peak charging schedules, error notifications, voice/language selection, plus new buttons, new sensors, and a batch of UI bug fixes.

Most of this landed in #136 by @smcneece — their first contribution. 🎉

Tested on: C28 Omni (T211A). Other novel-protocol X/L/C-series devices should benefit from the same features; scalar (Tuya) models like the G50 are unaffected where features don't apply.


✨ Highlights

🗺️ Live map rendering (new camera entity)

Your robot's floor map is now available as a Home Assistant camera entity ("Map"), rendered as a live PNG you can drop straight onto a dashboard.

  • How it works: map data streams in over the MQTT biz/ channel (protocol-41). It's parsed into room outlines and a pixel grid (api/map_stream.py), then rendered to PNG with Pillow.
  • What's drawn: room boundaries with per-room colors and labels, the dock, and the robot's live position.
  • Robot marker styles: choose Googly Eyes (default) or a plain Dot.
  • Smart re-rendering: the map re-renders when the robot moves (throttled to once every ~2s), on cleaning/dock state changes, and when the battery hits 100% (to clear the charging badge). Rendering runs in a thread executor so PIL never blocks the event loop, and in-flight renders are cancelled when superseded.
  • Configurable resolution: pick the map image size — 256 / 512 / 1024 / 2048 px (default 512). Higher = more detail, more memory and bandwidth.

⚠️ New dependency: this adds Pillow>=10.0.0, installed automatically by HACS/Home Assistant on upgrade.

🔋 Off-peak charging schedules (new time entities)

Two new time entities — Off-Peak Charging Begin and Off-Peak Charging End — let you read and write the robot's off-peak charging window directly from HA (DPS 176 / UnisettingRequest). Set it once and the robot charges in your cheap-tariff window.

The existing Do-Not-Disturb entity was relabeled "Do Not Disturb Begin" (was "Do Not Disturb Start") for consistency with the new Begin/End naming.

🔔 Error notifications (desktop + mobile)

When the vacuum reports an error, the integration now alerts you:

  • Desktop: a persistent Home Assistant notification (the bell icon). On by default; toggle in options.
  • Mobile: a push via your phone's mobile_app_* notify service. The options flow auto-discovers installed mobile-app services and lets you pick from a dropdown (or type a custom service name). Leave blank to skip mobile alerts.
  • Notifications clear automatically when the error resolves.

🗣️ Voice / language selection (new select entity)

A new "Voice" select entity lets you switch the robot's voice/language pack (DPS 162) across 17 languages — English (Male/Female), German, French, Spanish, Italian, Japanese, Korean, Chinese, Portuguese (BR), Turkish, Russian, Arabic, Dutch, Polish, Thai, Vietnamese.

The "Voice Volume" number entity now works on novel-protocol devices too (DPS 161, 0–100), where it was previously limited to scalar (Tuya) models.


🧩 New entities at a glance

Platform Entity Notes
camera Map Live rendered floor map (PNG)
time Off-Peak Charging Begin / End Read/write off-peak charging window
select Voice 17-language voice pack selection
button Start Cleaning, Pause, Return to Base Mirrors the Eufy app's main controls
sensor Total Cleaning Area Lifetime cleaned area
sensor Total Cleaning Time Lifetime cleaning time (auto h)
sensor Total Cleaning Count Lifetime number of cleans
sensor Dock Firmware Version Diagnostic

🐛 Bug fixes

  • Select entities no longer show "unknown" when idle. The Scene/Task and Room selects now return a "None" placeholder option instead of Python None, fixing the "unknown" state that appeared in the UI while the robot was idle. The placeholder is also injected as the first option so HA stops logging "current option not in list" warnings.
  • Room select active-match is now ID-based. Detecting which room is actively being cleaned now compares room IDs instead of doing a fragile string-substring search on room names.
  • Login now verifies a real device exists. The config flow logs in via the full EufyLogin flow and checks that at least one MQTT-capable device is present, surfacing a clear "No supported devices found" error instead of a generic failure.
  • Config entry is titled by device name. New entries (and reconfigured ones) are named after the discovered device(s) — e.g. "C28 Omni" — rather than your email address.

⚙️ Config & options

  • New Options flow (Settings → Devices → Eufy Robovac → Configure):
    • Map image size (256 / 512 / 1024 / 2048 px)
    • Robot marker style (Googly Eyes / Dot)
    • Desktop notification toggle
    • Mobile notification service (auto-discovered mobile_app_* dropdown, custom values allowed)
  • Reconfigure now updates the entry title alongside the password.
  • New translation/strings entries for the login, reconfigure, and options steps.

🛠️ Internal & dev

  • New module api/map_stream.py (~530 lines): biz/ protocol-41 parser + render_map_png().
  • New camera.py platform wired into setup.
  • Coordinator gained the map render pipeline, biz-message handling, and error-notification lifecycle.
  • New protobuf command builders: set_off_peak_charging, set_voice, novel-protocol set_volume.
  • DPS map additions: VOLUME (161), VOICE_LANGUAGE (162); removed from the "unprocessed" set now that they're handled.
  • Test suite expanded (test_map_stream.py, plus parser/commands/config-flow/select coverage); added run_tests.py helper.
  • CI/lint housekeeping: flake8, mypy, hassfest, and pre-commit fixes; removed CHANGELOG.md; README substantially rewritten.

⬆️ Upgrade notes

  • Pillow (Pillow>=10.0.0) is a new requirement and will be installed automatically. No manual action needed in a standard HACS/Home Assistant setup.
  • New entities will appear after the upgrade and a restart; the map camera populates once the robot streams map data.
  • No breaking changes to existing entity IDs.

🙌 New contributors

Full Changelog: v1.10.0...v1.11.0