-
Notifications
You must be signed in to change notification settings - Fork 15
Daily cleaning with vacuum robot
I have a Xiaomi Roborock S50 cleaning my big single storey house. My objective is to let the vacuum clean the maximum of rooms when we are not at home. But it's not so easy due to the configuration of the house and existing obstacles:
- Curtains (on the floor)
- Furniture blocking access
- Room doors closed
- Children stuff on the ground
- Big carpet with black patterns (yes the vacuum will avoid the black pattern due to fall avoidance logic. Not so smart)
- Small and lite carpets
- Door to access the underground opened
I've tried to launch a simple cleaning and let Rocky (yes my vacuum is called Rocky) clean the whole house, but it's not efficient and regularly the vacuum is trapped somewhere. So I need to put some automation to make it work as the family expect.
The way I've designed it:
- Clean the house every workday starting at 10h00. I currently don't use presence detection to trigger the automation.
- No automatic cleaning during holidays or week-ends.
- Define mandatory zones (done everyday) and optional zones to be cleaned on demand.
- Mandatory zones should be safe for Rocky if we forget to check for potential obstacles before leaving the house.
- If daily cleaning is interrupted by users, it should be resumed avoiding zones already cleaned.
- Battery consumption is optimised to avoid reaching 20% trigger that will make the robot wait to charge up to 80% before resuming the task in progress.
- Need notification at the end of the routine for monitoring and to remind me to clean the dust bin.
Recently, some Home Assistant users have shared how to have a map in your lovelace and select the zones you want to clean by clicking some room on draw rectangles. It's very nice, but for me be the best integration/automation is the one you forget. My approach is really design to be a routine and let it work without thinking about it.
My vacuum robot is a Xiaomi Roborock S50 with latest firmware and registered in the Xiaomi Home app on the European server. So all is standard here. I had to hack the robot due to the patterns of the living room carpet (see below)
The vacuum try to avoid the black zone considering them as void. No way to deactivate the cliff sensors in the software. I've seen 3D printable covers for the previous version of Xiaomi vacuum and the final solution is a white paper taped on the sensor.
In consequence, I can't use the cliff sensors to avoid my vacuum falling in the underground access stairs when someone left the door open. I will in a near future add a vacuum barrier or/and Xiaomi zigbee door sensor to secure Rocky.
- The Xiaomi Vacuum platform is used to manage the vacuum (configured in vacuum.yaml).
- The workday binary sensor platform is used to decide if it's a working day or a day off (configured in workday.yaml).
- The Telegram integration is used to send report at the end of the daily cleaning and send a reminder to clean the dust bin in the evening (configured in integrations/telegram.yaml and entities/notify/telegram.yaml).
- Some input_boolean entities are used for every zones managed by Rocky (configured in
vacuum_can_clean_*.yaml
in input_booleans folder). The optional zones can be set by switching on the related toggle in my Lovelace GUI. - One input_select entity is used to set a
holidays mode
for the house (configured in house_mode.yaml). If activated, the vacuum won't start automatically at 10:00. - I use the Variable custom integration to count zone, surface and duration of the daily cleaning (configured in
variable.yaml
and the filesnb_cleaning_*
in folderentities/variables
). Used in the repport send by Telegram. - I use Google TTS engine on my Google Home to acknoledge zone request done by kids (configured in
google.yaml
) - A lot of scripts:
- scripts for piloting the daily routines
- scripts for launching each zone cleaning (
launch_vacuum_*.yaml
inhouse
andareas
folders) - script for constructing the map
- script for stopping the cleaning
I can launch manually the daily cleaning sequence with the script vacuum_workday_sequence
but as it is a routine, I've an automation (launch_vacuum_each_workday.yaml) to launch the sequence every workday (it's mean binary_sensor.workday_sensor
is on
) at 10:00 if the house in not in holidays
mode.
Currently I don't use presence detection as I didn't invest sufficient time to have a reliable system to be sure people are home or not.
The automation calls a master script (vacuum_workday_sequence.yaml) which schedules all the tasks. To avoid repeating too much code I have a bloc with the following template for each zone to be cleaned:
- service: script.launch_daily_vacuum_in_room
data_template:
room_script: script.launch_vacuum_in_kitchen
room_bool: input_boolean.vacuum_can_clean_the_kitchen
room_name: "kitchen"
room_battery_needed: 13
repetition: 2
- wait_template: "{{ is_state('script.launch_daily_vacuum_in_room', 'off') }}"
As you can see I use the script launch_daily_vacuum_in_room
to package all the actions to be done each time the vacuum starts a zone cleaning. It takes parameters to select the script to be used with the cleaning instructions, the boolean to check if the zone have to be clean today, the name of the zone (the name is used in logbook dedicated entries) and an estimation of the battery needed to do the cleaning (in %). This script is shown below.
alias: Lance le nettoyage quotidient dans une pièce
sequence:
# Test if boolean is 'on' (not yet done today)
- condition: template
value_template: "{{ is_state(room_bool, 'on') }}"
# Test if rocky have enough battery before launching the cleaning.
# To avoid cleaning stopeed and waiting vacuum charge from 20% to 80% before resuming
- wait_template: "{{ states('sensor.vacuum_battery')| float - room_battery_needed | default(0) > 20 }}"
# Launch the cleaning
- service: script.turn_on
data_template:
entity_id: "{{ room_script }}"
variables:
repetition: "{{ repetition }}"
# Test if cleaning have started
# Warning if battery reach low trigger (20%) the vacuum will return to dock for
# charging to 80%. Currently no way to catch that.
- wait_template: "{{ is_state('vacuum.rocky', 'docked') != True}}"
# Test if finished
- wait_template: "{{ is_state('vacuum.rocky', 'docked') }}"
# Change the value of the boolean to make it done
- service: input_boolean.turn_off
data_template:
entity_id: "{{ room_bool }}"
# Add a message in logbook
- service: logbook.log
data_template:
name: Rocky
message: has just finished cleaning the {{ room_name }}
entity_id: vacuum.rocky
domain: vacuum
The script launch_daily_vacuum_in_room
do different things:
- First test if the boolean corresponding to the zone is
on
. - Then check if there is enough battery available to avoid reaching the 20% trigger. If not the vacuum charge on the docking station to have sufficient battery.
- Call the script with the cleaning instructions (see example below).
- Check Rocky as really start the cleaning by leaving the docking station.
- Wait for Rocky to return to the dock. When docked, the cleaning is completed so the boolean is set to
off
and an entry is added in the logbook.
This script is called by the routine but can be called directly in your Home Assistant UI or with a vocal command (I use IFTTT thru a Google Home). The script set the fan speed, define the zone coordinates, add an entry in the logbook and set the input_boolean used to remind to empty the dust bin in the evening.
alias: Lance Rocky dans le salon en évitant les obstacles
sequence:
- service: vacuum.set_fan_speed
data:
entity_id: vacuum.rocky
fan_speed: Standard
- service: xiaomi_miio.vacuum_clean_zone
data_template:
entity_id: vacuum.rocky
repeats: "{{ repetition | default(1) }}"
zone:
# Avoid zone with lot of stuff, curtains, chairs and small carpets
- [25600, 25600, 30000, 29300]
- [25500, 29300, 27800, 32600]
- service: logbook.log
data_template:
name: Rocky
message: starts cleaning the living room (safe mode)
entity_id: vacuum.rocky
domain: vacuum
- service: input_boolean.turn_on
data:
entity_id: input_boolean.vacuum_need_to_be_emptied
There are default values for script parameters to be able to use this script directly.
As you can see, the vacuum_workday_sequence.yaml
is iterating on all the possible zones. The selection of the zone to be cleaned during the next launch is done by managing the input_boolean
linked to each zone.
I have an automation init_vacuum_booleans_daily.yaml
which is reseting all mandatory zones (kitchen, living_room in safe mode, entrance and coordidor) at midnight.
If I need to update the zone to be cleanded before the launch, I use a specific lovelace UI or one Xiaomi wireless dual wall switch to toggle the input_boolean
states.
To ensure usage by the kids, I add this switch to let them the request their room cleaning. Kids check if there is no obstacle in their room, ensure the door is open and click the switch to request the corresponding zone for next routine cleaning. My Google home will then speak to acknoledge the request. The kids found it funy so they are motivated to ask Rocky regularly to clean their room before going to school.
The automation to manage the interactions with the switch and the TTS through Google Home is done in
vacuum_request_kids_cleaning.yaml
]
I add to my lovelace UI some buttons to manage the selection of the zones and the manual launch of the routine. With different action I can launch, pause or stop the routine to ask the vacuum to return on docking station.
You can search my export of lovelace setup to see how it is done.
TO BE COMPLETED & add IFTT in integration list
To be honest I'm not yet satisfied with the error monitoring and reporting. The Xiaomi phone application is spamming me too much for each standard completion of zone. So I remove the notification. I've implemented automation for error monitoring by Home Assistant but it seems some error status are not visible thru the standard Xiaomi RoboRock API. So sometimes I find my vacuum stuck somewhere at the end of the day without any alert. This topic need to be improved in the future. I'm open to any idea.
Current implementation used the automation in vacuum_notify_error.yaml
After each routine, I receive on Telegram a message with the number of rooms cleaned, the corresponding surface and the total time to achieve all the tasks. You can find how it is done by going to the end of vacuum_workday_sequence.yaml.
Everyday at 8:00 PM, if Rocky has clean a room within the day, I receive a notification on Telegram to remind me to empty the dust bin. I have 3 buttons to acknoledge, to snooze or to postponned to ahve a reminder tomorrow.
Tips for zone when room doors can be closed.
Classical errors: string / coordinate order. Vacuum stuck behind a door. Logbook.
How to find coordinates.
How to stop the routine.
Script to refresh the map
- test way to increase state update rate