v3.0.0
Roomba+ v3.0.0 — Technical Cleanup Release
Config entry version: 22 → 24 (two automatic migration steps, no user action required)
Minimum Home Assistant: 2025.5.0
Breaking changes: none for end users
Overview
v3.0.0 is a pure technical cleanup release with no user-facing behavior changes.
It removes deprecated sensor infrastructure introduced in v2.0, adds two new diagnostic
sensors, and significantly restructures the integration's internal architecture for
long-term maintainability.
What's new
New sensors
consecutive_mission_anomalies (disabled by default)
Exposes the number of consecutive most-recent missions classified as anomalous
(stuck, error, or significantly below the robot's baseline performance). Disabled
by default — consumed by the companion Card's C5-ANOMALY banner (threshold ≥ 3) and
available for custom automations. Activate in the entity registry when needed.
Observed obstacle zone overlay
The map image now overlays robot-detected obstacle zones (from UMF
observed_zones) as semi-transparent orange circles when the UMF aligner is active.
These represent positions where the robot has repeatedly detected obstacles over time,
supplementing the existing red keep-out zone overlay.
Bug fixes and resilience hardening
This release also folds in a round of real-field-data bug-hunting and hardening:
- Vacuum state fix: a freshly-connected or sparsely-reporting robot could be
shown as Paused instead of Idle/Docked. WhencleanMissionStatuswas
missing acycle, the valueNonewas treated as an active cycle. Fixed so a
missing cycle correctly reads as idle. - Store corruption resilience: five storage loaders (
robot_profile,grid,
mission_archive,outline, and related) could raise on a corrupted or
hand-edited.storagefile instead of degrading gracefully. They now reset
cleanly and never propagate the error, so a bad store can't block setup. - Sensor-platform null safety:
roomba_reported_stateis hardened against an
explicit{"state": null}frame that previously could take down the entire
sensor platform. Verified by running every sensor's filter against the real 980
diagnostic plus degraded (all-null, empty, missing-subdict) variants. clean_roomedge case: an emptyroom_passeslist raised anIndexError;
it now returns a clear validation error (no_rooms_resolved).- Dead-code cleanup: removed unreachable calls and unused imports surfaced
during the audit (no behavior change).
Test suite grew from 2867 to 2946 over this hardening pass, all passing.
Removed (deprecated sensors from v2.0)
The following 13 sensors introduced in v2.0 as raw cloud data exposers are
permanently deactivated. They were superseded by their consolidated replacements
in v2.7–v2.9 and have been disabled by default since v2.7.0:
| Removed sensor | Consolidated replacement |
|---|---|
recent_completion_rate |
cleaning_analytics_30d → recharge_pct attribute |
recent_recharges |
event_counts_30d |
recent_evacuations |
event_counts_30d |
recent_dirt_events |
event_counts_30d |
recent_error_code |
event_counts_30d |
recent_error_time |
event_counts_30d |
recent_wifi_floor |
wifi_health |
recent_wifi_stability |
wifi_health |
recent_cleaning_speed |
cleaning_performance |
recent_dirt_density |
cleaning_analytics_30d → dirt_density attribute |
recent_recharge_fraction |
cleaning_analytics_30d → recharge_pct attribute |
cleaning_speed_trend |
cleaning_performance → trend attribute |
recent_coverage_pct |
cleaning_performance → coverage_pct attribute |
If any of these are referenced in your dashboards or automations, replace them with
the corresponding consolidated sensor or attribute listed above.
The F6a (performance degradation) and F6b (battery recharge) Repair Issues continue
to work — the data they depend on is now computed by the consolidated sensors.
Internal architecture changes
These changes have no effect on runtime behavior but significantly improve code
structure and long-term maintainability:
SETUP-SPLIT: async_setup_entry reduced from 657 lines to a 35-line orchestrator
by extracting six named phase functions (_phase_connect, _phase_spatial,
_phase_data, _phase_cloud, _build_runtime_data, _phase_finalize) and a
_SetupContext accumulator dataclass. Each phase is independently readable and
documented.
Cloud refresh callback extracted: The _on_cloud_refresh_complete callback
closure (analytics merge, Repair Issue checks, UMF realignment trigger) is now a
proper named factory function make_cloud_refresh_callback() in callbacks.py,
consistent with the other make_*_callback functions.
Select descriptor pattern: The four simple select entities
(CleaningPassesSelect, DisposablePadWetnessSelect, ReusablePadWetnessSelect,
CarpetBoostSelect) are now driven by frozen RoombaPlusSelectDescription
dataclass descriptors via a single generic SimpleRoombaSelect class, eliminating
~180 lines of duplicated boilerplate.
Dead code removed: MissionArchive.missions_by_room() and
MissionArchive.dirt_series() — identified as structurally unreliable for 900-series
robots via field data analysis — have been removed along with their tests.
Upgrade notes
- Two automatic migrations run on first load (config entry 22 → 23 → 24).
No user action is required; both are non-destructive.- 22 → 23: stabilises FavoriteButton entity_ids. Buttons previously got
locale-dependent ids derived from the iRobot routine name
(e.g.button.roomba_980_og_montag_morgen); they are renamed to stable,
discoverable ids so the companion Card can find them after upgrade. - 23 → 24: disables sensors that are permanently unavailable for most
robots and have no UI path to become available, clearing them out of the
entity list instead of leaving them as "unavailable".
- 22 → 23: stabilises FavoriteButton entity_ids. Buttons previously got
- Deprecated sensors that were already disabled (default since v2.7) are simply gone.
HA will remove their entity registry entries automatically on first load. - If you had manually re-enabled any deprecated sensor, re-enable the corresponding
consolidated sensor or attribute instead. - The
hacs.jsonminimum HA version is now 2025.5.0.
Contributor notes
- Test suite: 2946 tests, 0 failures (baseline: 2872 before v3.0.0 cleanup)
__init__.pynet line delta: −660 lines (1942 → 1282 in the setup/teardown shell)callbacks.pynet delta: +310 lines (cloud helpers + refresh callback)select.pynet delta: −132 lines (descriptor pattern)sensor.pynet delta: −215 lines (deprecated descriptors + helpers removed)