Integrating Xiaomi S50 vacuum cleaner

Let us get a vacuum cleaner

So my wife wanted a vacuum cleaner. We do not have any pets but we do have children and this means that in spring and summer the apartment is full of sand from the playground.
When you take a look at e.g. Amazon there is a lot of robots which get the job done, but all of them mostly have a specific app for the control the robot and they "call home" to allegedly improve the functionality. Not going to go into it, but I just do not believe that. So I started looking for a vacuum cleaner, that can work in the local network only. This was not an easy task, but then I stumbled upon Valetudo and saw that it supported Xiaomi vacuum cleaners. This gave me the push in the right direction and I got a Xiaomi S50. After some tweaking, right now I could not be happier with my setup.

Big picture

  1. I rooted the S50 and installed Valetudo on it. Then, just to be sure, I blocked all outgoing traffic from the robot in my router. This gives me a nice webinterface to locally control my robot, this is basically 90% of what I wanted.
  2. Now to get the robot integrated with Domoticz, I activated the MQTT integration so that it can communicate with the same MQTT broker as Domoticz. The newer versions of Mosquitto MQTT broker I am using per default do not allow connections from allow connections from external adresses. So make the changes as described in the linked post.
  3. The problem is, that Domoticz per se doesn't understand what the robot is saying on the MQTT bus and vice versa. Domoticz only communicates under domoticz topic and Valetudo is using it's own valetudo topic. Enter NodeRED as a translator between Valetudo and Domoticz. After installing NodeRED we can implement flows to control Valetudo from Domoticz and to show Valetudo information in Domoticz.

NodeRED flow

This is how my Domoticz-Valetudo interface in NodeRED looks like.

nodered.jpg

You can find the JSON flow here. When you import it, you will need to create a couple of Domoticz devices so that you can get the data in and control out. After you created the devices in Domoticz, then just enter the ID on the right places in the flow.

domoticzid.jpg

You need following devices:

  • Virtual sensor, Type Text, for Rockrobo state.
  • Virtual sensor, Type Text, for the date when the last cleaning was made.
  • Virtual sensor, Type Text, for the duration of the last cleaning.
  • Virtual sensor, Type Percentage, for the state of the dust bin. This is calculated by a dzvents script I will explain later.
  • Virtual switch, Type Push On Button, for the reset of the dust bin.
  • Virtual switch, Type Selector, for control commands.
sensorsvaletudo.jpg
controlvaletudo.jpg

With this setup you can get the most important data from Valetudo visible in Domoticz and you can send the commands to the robot. In the next step we will get this automated.

I am not home, so go and clean

Here you will find the script I wrote for the automation of the vacuum cleaner.
Basicaly the title says it all, I want the cleaning to start when nobody is home. There is a couple of exceptions:

  • cleaning can only be done once in 24 hours and between 08:00 and 20:00,
  • no cleaning if nobody was home for the last 24 hours (do not clean when on vacation).

The Rockrobo stops cleaning or doesn't even start if the dust bin is full. The first Valetudo versions didn't figure out which flag the firmware is using for this, so I implemented a simple cumulative function for this.

-- Estimation how full is the dust bin.

if (cleaning_start.compare(domoticz.data.old_cleaning_start).mins > 1) then
   current_dust_bin = math.min(100, (current_dust_bin + math.ceil(100*tonumber(domoticz.devices('Rockrobo_Dauer_letzte_Reinigung_min').state)/cleaning_mins_max))) -- Round up and limit.
   domoticz.devices('Rockrobo_Staubbehaelter').updatePercentage(current_dust_bin)
end


-- Reset the dust bin values.

if (domoticz.devices('Rockrobo_Staubbaehelter_leeren').changed) then
   domoticz.log('Setze die Staubbehälterwartung zurück.')
   current_dust_bin = 0
   domoticz.devices('Rockrobo_Staubbehaelter').updatePercentage(current_dust_bin)
end

-- Send out the dust bin notification.

if (current_dust_bin > lmt_max and domoticz.data.old_dust_bin < lmt_max) then
   domoticz.log('Rockrobo Staubbehälter leeren.', domoticz.LOG_ERROR)
   domoticz.email('Rockrobo', 'Rockrobo Staubbehälter leeren.', 'root@homeserver')
end

The function calculates how full the dust bin is and then sends me an E-Mail. Then I can use the virtual Push On button to reset the calculation after I emptied the bin.

So that is it, have fun and write me if you get in trouble or have questions.

Happy Hacking !!

License: CC BY-SA 4.0 Discuss on Mastodon