Interacting with my Ecovacs Deebot robotic vacuum with Python & Sucks
— Python, Technology — 4 min read
After a month of working from home I noticed an increase in the amount of cleaning that my girlfriend and myself had to do to keep the flat in a decent state.
When a friend of mine told me that the Ecovacs Deebot 500 was only £160 on Amazon, came with a set of spares and worked with my Google Home I bought it without even blinking, I could now just let it run on a schedule and pick everything up.
So far I’ve found it to be an amazing little robot and it’s given us a lot of entertainment as it goes about it’s business, especially when it recently knocked a can of Pringles off the shelf and paraded it around the flat.
There were a few teething problems at the start, the Ecovacs app for instance will not pair with the Deebot unless you enable location access (on iOS at least) but after that’ it’s worked seamlessly — definitely worth the £160.
When I purchased the Deebot I had joked to my friend (who lives down the hallway from me) that we should host a Robot Wars like fight between our machines and a quick search on Github returned a Python library that looked like I might be able to do that.
The library — Sucks
Sucks is a Python library for connecting to your Deebot via API gateway used by the Ecovacs app and sends XMPP messages to the robot in order to start cleaning, stop cleaning, recharge and send it commands to move.
The fact that the Deebot uses XMPP makes me wonder if back in the days when we used Jabber in one my previous employers if we could have had a Deebot as a Jabber bot, that’d be really cool.
In order to set up the library’s CLI you need to create a suck.conf
file which contains the following data:
email
— The email address you use to login to the Ecovacs apppassword_hash
— Amd5
hash of the password you use to login to the Ecovacs appdevice_id
— Amd5
hash of the timestamp used when logging incountry
— The two character code for your countrycontinent
— The two character code for your continent (ww
also available if you can’t get things to work)
There is a sucks login
command that will automatically generate this file for you but there’s currently a bug for UK users where Sucks uses http://ipinfo.io/json to get the country code which returns gb
but Ecovacs expects uk
so I had to create this myself.
Using the sucks CLI you can:
- Use
sucks clean
which will clean similar to the ‘standard mode’ in the Ecovacs app - Use
sucks edge
which will clean similar to the ‘edge mode’ in the Ecovacs app - Use
sucks charge
which will send the robot back to the charger - Use
sucks stop
which will stop the robot at it’s current position
If you want finer control over the Deebot then you’ll need to create a Python script which uses Sucks as a library, as doing so gives access to all the XMPP commands.
Gotchas
I ended up having to use the https://github.com/bmartin5692/sucks fork of sucks to successfully interact with my Deebot 500, the library from PyPi would throw the following error when issuing commands:
1<error type="wait" code="404"><recipient-unavailable xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" /></error>
The sucks.conf
is only necessary for working with the CLI so if you’re having issues with the CLI but know the information you need to send, it might be easier to just write a Python script and keep the config values there.
Using Sucks to send commands to Deebot
Interacting with your Deebot via the API is pretty straightforward, you log into the Ecovacs API, get a list of devices and then create an VacBot
instance for the device you want to control:
Once you’ve got your VacBot
instance you can then use the following methods and properties to get information from the Deebot and send commands to it:
refresh_statuses()
— Get the statuses for cleaning, charging from the serverrefresh_components()
— Get the components lifespan values from the servercharge_status
— Returns the charging status of the Deebot (requiresrefresh_statuses
to be called first)battery_status
— Returns the battery charge status as a float (0–1 range)components
— Returns the lifespan values of the Deebot’s components in days (requiresrefresh_components
to be called first)run()
— Tell the Deebot to execute an action such asClean
,Charge
,Stop
,Move
Actions that can be used with run
The run()
method is a wrapper around the XML payloads that get sent via XMPP, the other properties and methods are calling run()
with preset arguments but there’s a few that you can send that aren’t in that list.
run()
takes an instance of a subclass of VacBotCommand
as it’s argument, the following objects are available:
Clean
— Start cleaning in standard modeEdge
— Start cleaning in edge modeSpot
— Start cleaning in spot modeStop
— Stop the Deebot in it’s current positionCharge
— Send the Deebot back to the chargerMove
— Manually move the Deebot, takes the following options:forward
,left
,right
,turnaround
,stop
PlaySound
— Make the Deebot play a soundGetCleanState
— Get the cleaning statusGetChargeState
— Get the charging statusGetBatteryState
— Get the battery statusGetLifeSpan
— Get the lifespan of a component, takes the following options:side_brush
,main_brush
,filter
SetTime
— Set the time and timezone of the Deebot, takes a timestamp and timezone
An example script of using run()
to start the Deebot cleaning on high in standard mode can be found below:
A failed experiment
My girlfriend acting as hand model
Once I had got past all the issues getting Sucks set up and was able to send commands to the Deebot I had an idea — I could use a Playstation 4 controller and the Move
commands to essentially turn cleaning into a game.
I set up a simple PyGame script to capture the controller’s D-Pad input and then mapped those buttons to forward
, left
, right
and turnaround
but unfortunately it looks like my Deebot 500 doesn’t support the Move
command.
This meant that the premise of holding a Deebot Robot Wars was no longer viable so I instead refactored the script to map the X button to start cleaning, Circle to stop cleaning. Square to play a sound and Triangle to send the Deebot back to charging.
Summary
While my Deebot model only supports the basic commands it was really fun to lose an hour or so hooking up a PS4 controller to send commands to the Deebot.
I’m not sure of how compatible all the models of Deebot are so I can’t say which models support the Move
commands but having that amount of control would open a whole range of cleaning options as you could create routes in code and execute them as a set of scripts.
If I ever get my Linux machine up and running again I’ll most likely also look to create some form of Conky script to display the stats on my desktop as this information would be cool to see.