Add sensor entities for Roborock q10 s5+#166120
Conversation
Add new sensor entities for Roborock Q10 devices: - main_brush_life, side_brush_life, filter_life, sensor_life (remaining %) - total_cleaning_area, total_cleaning_time, total_cleaning_count - clean_percent (current cleaning progress) Also wait for the first MQTT push during coordinator setup so that sensor state is populated immediately after async_config_entry_first_refresh, consistent with V1/Q7 coordinator behavior. A 10s timeout handles the offline case gracefully. Update conftest mock to trigger status listeners on refresh() so tests resolve instantly without timeout.
|
Hey there @Lash-L, @allenporter, mind taking a look at this pull request as it has been labeled with an integration ( Code owner commandsCode owners of
|
There was a problem hiding this comment.
Pull request overview
Expands the Roborock integration’s Q10 (B01 protocol) support by adding additional diagnostic sensor entities backed by python-roborock’s newly exposed Q10 status fields, and adjusts the Q10 coordinator’s first refresh behavior to wait for an initial MQTT push so entities can start with populated status where possible.
Changes:
- Add Q10-specific sensor descriptions/entities for consumables life and cleaning totals/progress.
- Update the Q10 coordinator to wait (with timeout) for the first push update during the initial refresh.
- Extend translations and test fixtures/snapshots to cover the new Q10 sensors.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
homeassistant/components/roborock/coordinator.py |
Waits for initial Q10 MQTT push on first refresh (with timeout) to improve startup state population. |
homeassistant/components/roborock/sensor.py |
Introduces Q10 sensor entity definitions and registers them for Q10 coordinators. |
homeassistant/components/roborock/strings.json |
Adds translation strings for new Q10 sensor names and additional Q10 status enum values. |
tests/components/roborock/conftest.py |
Adjusts Q10 trait mocking to simulate an immediate push update during refresh in tests. |
tests/components/roborock/test_init.py |
Updates expected device entity sets to include Q10 sensor entities. |
tests/components/roborock/snapshots/test_sensor.ambr |
Updates sensor registry/state snapshots to include the new Q10 sensors. |
Adds icons for the following entities: - battery: Battery level indicator - cleaning_time: Current cleaning time - mop_clean_remaining: Remaining mop drying time - brush_remaining: Remaining brush time (DYAD) - main_brush_life: Main brush life percentage (Q10) - side_brush_life: Side brush life percentage (Q10) - filter_life: Filter life percentage (Q10) - sensor_life: Sensor life percentage (Q10) - mop_life_time_left: Mop lifetime remaining (B01) - times_after_clean: Total cleaning count (ZEO) - q7_status: Q7 device status (B01)
Stop waiting for an arbitrary first MQTT status message in the Q10 coordinator initial refresh path, and keep Q10 sensors registered unconditionally with push-based updates as values arrive.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
homeassistant/components/roborock/coordinator.py:631
- The first-refresh wait uses a hard-coded 10 second timeout. Please replace this with a named constant (ideally alongside the existing interval constants) so it’s easier to tune and understand, and so the same value can be reused consistently in tests/docs.
"""Get the unique id of the device as specified by Roborock."""
return self._device.duid
@cached_property
def duid_slug(self) -> str:
"""Get the slug of the duid."""
return slugify(self.duid)
homeassistant/components/roborock/coordinator.py:621
- This comment mentions waiting so that “sensor value_fn filters work correctly at setup time”, but Q10 sensors are now registered unconditionally (no value_fn filtering). Consider updating the comment to reflect the current motivation (e.g., ensuring the initial Q10 status is populated for entities like the vacuum/status enum), to avoid future confusion.
translation_domain=DOMAIN,
translation_key="request_fail",
) from ex
| "default": "mdi:brush" | ||
| }, | ||
| "cleaning_time": { | ||
| "default": "mdi:clock-outline" |
There was a problem hiding this comment.
how do you decide between mdi:brush vs mdi:clock-outline here?
There was a problem hiding this comment.
The duration of the last cleaning depends on the vacuum cleaner as a whole, not just the brush.
The previous refresh_side_effect did a circular DPS round-trip (reading existing properties, converting to DPS, then re-applying the same values) that served no purpose — no test asserted any state change from it.
All Q10 status states are a subset of those already defined in the `status` translation key, so there's no need for a separate `q10_status` key in strings.json and icons.json.
The *_life sensors (main_brush_life, side_brush_life, filter_life, sensor_life) report hours of usage, not a percentage. Update units to UnitOfTime.HOURS with device_class DURATION, fix misleading names in strings.json, and remove explicit icons so HA uses the DURATION default (mdi:timer) to visually distinguish them from *_time_left sensors.
Add realistic mock values (in hours) for main_brush_life, side_brush_life, filter_life and sensor_life matching real device data, so tests validate actual sensor states instead of unknown.
CLEAN_TIME is reported in seconds by the device (1812 = ~30 min). Update native unit to seconds with suggested display in minutes. Update mock value to 1800 s (30 min) to match real device data.
Proposed change
Expands sensor coverage for Roborock Q10 devices (B01 protocol) by exposing all status fields available in python-roborock 4.26.3.
New sensor entities per Q10 device:
statuscleaning_timecleaning_areamain_brush_lifeside_brush_lifefilter_lifesensor_lifetotal_cleaning_areatotal_cleaning_timetotal_cleaning_countclean_percentImplementation notes:
RoborockB01Q10UpdateCoordinator._async_update_datasimply callsawait self.api.refresh()(fire-and-forget). Q10 is push-based: entities are registered unconditionally and their state is populated as MQTT push updates arrive.statustranslation key — allYXDeviceStatevalues produced by the Q10 are a subset of the states already defined there, so no dedicated key is needed.*_life): The device reports hours of usage (e.g.dpMainBrushLife: 81= 81 h used), not a remaining-life percentage. These sensors are modelled asSensorDeviceClass.DURATIONwithnative_unit_of_measurement=UnitOfTime.HOURS.Type of change
Additional information
Checklist
ruff format homeassistant tests)