I would like to add some functionality to the Roomba integration, but I want to see if something is possible first, because right now my solution is a bit janky.
I’ve got a Roomba at home and I’ve been able to get it to clean specific rooms. It’s not elegant, but there are three pieces of information required: the map ID, the map revision number, and the numerical representations of the rooms (e.g. 1,2,3, etc). I was able to find this information using the debug logs for the Roomba integration, which passes along the command that gets sent to the Roomba. Here is an example:
{
"state": {
"reported": {
"lastCommand": {
"command": "start",
"initiator": "rmtApp",
"time": 1709864701,
"ordered": 1,
"pmap_id": "redacted_map_id",
"user_pmapv_id": "redacted_map_revision_timestamp"
"regions": [
{
"params": { "noAutoPasses": true, "twoPass": false },
"region_id": "1",
"type": "rid"
},
{
"params": { "noAutoPasses": true, "twoPass": false },
"region_id": "2",
"type": "rid"
}
],
}
}
}
}
So I’m able to pull the data from pmap_id
and user_pmapv_id
and put them into a SensorEntity
inside the Roomba integration’s files:
# Added to irobot_base.py list of properties of roomba entity:
@property
def last_reported_map_id(self):
"""Return the reported command stats."""
return self.vacuum_state.get("lastCommand", {}).get("pmap_id", {})
@property
def last_reported_map_revision(self):
"""Return the reported command stats."""
return self.vacuum_state.get("lastCommand", {}).get("user_pmapv_id", {})
# Added to sensor.py list of sensor entities that get set up:
RoombaSensorEntityDescription(
key="last_map_id",
translation_key="last_map_id",
icon="mdi:map",
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False,
value_fn=lambda self: self.last_reported_map_id,
),
RoombaSensorEntityDescription(
key="last_map_version",
translation_key="last_map_version",
icon="mdi:map",
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False,
value_fn=lambda self: self.last_reported_map_revision,
),
So basically, when a command comes in, the entities will update. The map revision does occasionally change, as you ‘teach’ the roomba through the app what is and isn’t an obstacle, and then you have to just start and cancel a job to get the map ID updated in Home Assistant again. The problem is that not every command sent to the roomba contains the map ID/revision properties, so the sensors go to Unknown quite frequently. To solve this, I’ve created some template sensors that just watch the entity sensors and grab the last good value:
template:
- sensor:
- name: "Roomba 1 Latest Map ID"
state: '{{ states("sensor.roomba_1_last_map_id") }}'
trigger:
- platform: state
entity_id: sensor.roomba_1_last_map_id
not_to:
- unknown
- unavailable
- sensor:
- name: "Roomba 1 Latest Map Version"
state: '{{ states("sensor.roomba_1_last_map_version") }}'
trigger:
- platform: state
entity_id: sensor.roomba_1_last_map_version
not_to:
- unknown
- unavailable
Using these, I can set up my job scripts that contain all the information I need (like room lists, number of passes, etc). (Sidebar: As far as I can tell, there’s no way for me to pull this data directly into a template trigger sensor because the map info is normally discarded by the integration instead of updated with the state of the Roomba entity. If there is a way to do this directly, I would love to know.)
What I was hoping to find out is: is there a way I can get the SensorEntity to report its last good state if the value of the lambda function is null? I can figure out the if/then within the lambda, but the problem is I don’t know how to pull the current state of the entity in Python without just creating a recursive loop where the entity is asking itself what its state is. If I can get this accomplished, I can remove the template sensors and just directly reference the Map IDs.