iRobot Roomba i7+ Configuration using Rest980

Essentially yes.

The Roomba has status and mode, (which internally is called cycle and phase).

The automations for mapping occur for Ready to Clean or Train and like you said, from Clean/Train back to Ready.

Stuck is actually a mode, so if it does get stuck the automations continue to run - as the cycle hasn’t finished unless you stop or send the robot home.

If you did pickup and move the Roomba (more than just into a flat surface) it will likely mess with the map coordinates until it rediscovered its location and continued the cycle.

Hope this helps and your welcome :blush: glad it’s working :+1:

Great stuff -

I am struggling with the Map. Can anyone explain or point to how to figure out how to adjust the x / y off sets, flips and rotates? Also image size adjustment? Width, height . Lastly floor png dimensions. 300x300?

A lot I know… i’ve been adjusting like crazy. Only result has been increase blood pressure.

Paul

it took me a bit of fussing with it. But eventually I got it to work. building a floorplan and scaling it to fit the map is by far the most difficult. I’ve found, that if you set the dimensions and such in the php first. refreshing after every change to figure out what direction you need to go, then once you have a good map, then save that image, make a new image in paint.net or photoshop or something that has layers. Make the map the top layer, then draw your floor plan around it. This works best if you have some exposed WALL in each room of the house. This allows you to draw your floorplan the exact size of your house. I snapshotted the smart map, then cropped the two halves of my long house together, then layed that map, under the drawn line map, resized and refreshed for about 30 minutes. then I ended up with something… acceptable. Not clean, not pretty, but it’s enough that I can look at it and say, “Yes, the kitchen has been cleaned” , or, “Don’t go in there mom, Rosie is hard at work”

1 Like

Thanks @austech360 - That helped - I think a key learning… adjust the image.php while the remote is in full clean mode. Start with x / y off set… then size as it complete the job. Really have to check it every 5 mins to adjust. I’ve now got a good base blank image. Will now work with layers.

1 Like

Hi @Syrius
I found some minor issue with one of the automation scripts.

i’m getting this in my log only i noticed it when i was running the vacuum and looking at the vacuum camera in lovelace just happened to be looking at the home-automation.log file. I can also go to Automation Editor and invoke it there, I get the same log error.

2020-02-14 12:00:00 ERROR (MainThread) [homeassistant.components.automation] Error while executing automation automation.vacuum_maintenance_check. Unknown error for call_service at pos 1:
Traceback (most recent call last):
File “/usr/src/homeassistant/homeassistant/components/automation/init.py”, line 449, in action
await script_obj.async_run(variables, context)
File “/usr/src/homeassistant/homeassistant/helpers/script.py”, line 189, in async_run
await self._handle_action(action, variables, context)
File “/usr/src/homeassistant/homeassistant/helpers/script.py”, line 272, in _handle_action
await self._actions[_determine_action(action)](action, variables, context)
File “/usr/src/homeassistant/homeassistant/helpers/script.py”, line 354, in _async_call_service
context=context,
File “/usr/src/homeassistant/homeassistant/helpers/service.py”, line 66, in async_call_from_config
domain_service = config[CONF_SERVICE_TEMPLATE].async_render(variables)
File “/usr/src/homeassistant/homeassistant/helpers/template.py”, line 221, in async_render
return compiled.render(kwargs).strip()
File “/usr/local/lib/python3.7/site-packages/jinja2/asyncsupport.py”, line 76, in render
return original_render(self, *args, **kwargs)
File “/usr/local/lib/python3.7/site-packages/jinja2/environment.py”, line 1008, in render
return self.environment.handle_exception(exc_info, True)
File “/usr/local/lib/python3.7/site-packages/jinja2/environment.py”, line 780, in handle_exception
reraise(exc_type, exc_value, tb)
File “/usr/local/lib/python3.7/site-packages/jinja2/_compat.py”, line 37, in reraise
raise value.with_traceback(tb)
File “”, line 1, in top-level template code
File “/usr/local/lib/python3.7/site-packages/jinja2/runtime.py”, line 430, in init
self._after = self._safe_next()
File “/usr/local/lib/python3.7/site-packages/jinja2/runtime.py”, line 450, in _safe_next
return next(self._iterator)
File “”, line 22, in t_1
TypeError: ‘<’ not supported between instances of ‘NoneType’ and ‘float’

i think the problem is from this line
{% for item in states.sensor if ‘vacuum_maint’ in item.entity_id and (state_attr(item.entity_id, ‘visibility_timestamp’) < as_timestamp(now())) %}
{% set ns.count = loop.index %}
{% endfor %}

the 7 entities don’t have visibility_timestamp in my HA, instead they have just timestamp or visibility_timeout closest matching names, looking at Developer Tools.states.

i went back to github for the ckeck-button card tree branch e80ef56 download again
this file, copy/paste in raw mode.

https://github.com/jeremywillans/check-button-card/blob/e80ef5647f042f78aa06df50d2d6014a417fb0ab/check-button-card.js

replaced my check-button-card.js restarted hassio, i still don’t have attribute visibility_timestamp that the automation script expects. am I missing some other configuration to get the attribute name visibility_timestamp?
do I need to declare visibility_timestamp in the lovelace button-card entities section like visibility_timeout was declared?

for now I edited visibility_timestamp to -> timestamp which the 7 entities do have.
state_attr(item.entity_id, ‘timestamp’)

running the automation script vacuum maintenance check manually from Automation Editor throws no errors after this workaround.

/Pierre

Hi @pnakashian,

If you have replaced the check-button-card, you will need to update the sensors to “recreate” the attributes. Simply click on the sensor and it will update, you can then hit the undo button to restore it back to your previous date. (So this process will re write the attributes twice)

You can also press hold on the sensors to manually set a time in the past :+1:

Is it possible to increase mapping accuracy by reducing the polling time?
Is it possible to make it actually “fill in” the area that it’s cleaned? Maybe make the lines thicker so it creates a “path” so to speak?

I used to have a Robart vacuum and REALLY liked the cleaning map it would give in live time.

Any way to get something along these lines? Thoughts? Also. Maybe a way to adjust fan speed, and “cleaning passes” Also, Is it possible to set the order of rooms cleaned? Like, at 8:30 I want the master bedroom cleaned because my grandpa goes to bed around 9, but I want it to finish the rest of the house afterward. I don’t want to have to set schedules like 8:30 - Master bedroom then at 9:00 - Rest of the house.

Just some features I’d like to see. You’re doing a GREAT job with this. It looks FANTASTIC and I’m loving having all my eggs in one basket, If I can uninstall the iRobot app and never have to use it again, that would be AMAZING!

Hi @Syrius,
that didn’t work, but I finally got it working, and maybe removed some unnecessary config in my configuration.yaml

my current setup in configuration.yaml , my external mqtt broker can handle
multiple discovery prefixes, I didn’t need the discovery_prefix so i removed it.

mqtt:
broker: 127.0.0.1
port: 1884
client_id: hass
discovery: true
protocol: 3.1
keepalive: 60

here’s the gotcha when trying to install a plugin that the HACS doesn’t have a way of installing the specific commit. I installed from HACS 1st, then I overwrote the file /config/www/community/check-button-card/check-button-card.js from the tree branch e80ef56.

But Homeassistant ignored this overwritten file, it somehow used the original version that I installed from HACS. In the same directory /config/www/community/check-button-card/ there was another file that I ignored check-button-card.js.gz. Home assistant or some component either checked the 2 files were not in sync or it just uses check-button-card.js.gz instead.

so anybody that copies check-button-card.js to the folder /config/www/community/check-button-card/ from another location they will also need to run gzip check-button-card.js , and copy check-button-card.js.gz into /config/www/community/check-button-card/.

Now I have visibility_timestamp which I never did. makes the calculations in my previous posted script unnessary.

{% set cleanDate=as_timestamp(state_attr(‘sensor.vacuum_maint_clean_brushes’,‘visibility_timestamp’)|timestamp_local)|timestamp_custom(’%m/%d/%Y’) %}
{{ state_attr(‘sensor.vacuum_maint_clean_brushes’, ‘friendly_name’) }}->
…Clean date {{cleanDate}}…{{ state_attr(‘sensor.vacuum_maint_clean_brushes’, ‘visibility_timeout’) }} togo

{% set cleanDate=as_timestamp(state_attr(‘sensor.vacuum_maint_clean_contacts’,‘visibility_timestamp’)|timestamp_local)|timestamp_custom(’%m/%d/%Y’) %}
{{ state_attr(‘sensor.vacuum_maint_clean_contacts’, ‘friendly_name’) }}->
…Clean date {{cleanDate}}…{{ state_attr(‘sensor.vacuum_maint_clean_contacts’, ‘visibility_timeout’) }} togo

{% set cleanDate=as_timestamp(state_attr(‘sensor.vacuum_maint_clean_filter’,‘visibility_timestamp’)|timestamp_local)|timestamp_custom(’%m/%d/%Y’) %}
{{ state_attr(‘sensor.vacuum_maint_clean_filter’, ‘friendly_name’) }}->
…Clean date {{cleanDate}}…{{ state_attr(‘sensor.vacuum_maint_clean_filter’, ‘visibility_timeout’) }} togo

{% set cleanDate=as_timestamp(state_attr(‘sensor.vacuum_maint_clean_wheel’,‘visibility_timestamp’)|timestamp_local)|timestamp_custom(’%m/%d/%Y’) %}
{{ state_attr(‘sensor.vacuum_maint_clean_wheel’, ‘friendly_name’) }}->
…Clean date {{cleanDate}}…{{ state_attr(‘sensor.vacuum_maint_clean_wheel’, ‘visibility_timeout’) }} togo

{% set replaceDate=as_timestamp(state_attr(‘sensor.vacuum_maint_replace_brushes’,‘visibility_timestamp’)|timestamp_local)|timestamp_custom(’%m/%d/%Y’) %}
{{ state_attr(‘sensor.vacuum_maint_replace_brushes’, ‘friendly_name’) }}->
…Replace date {{replaceDate}}…{{ state_attr(‘sensor.vacuum_maint_replace_brushes’, ‘visibility_timeout’) }} togo

{% set replaceDate=as_timestamp(state_attr(‘sensor.vacuum_maint_replace_filter’,‘visibility_timestamp’)|timestamp_local)|timestamp_custom(’%m/%d/%Y’) %}
{{ state_attr(‘sensor.vacuum_maint_replace_filter’, ‘friendly_name’) }}->
…Replace date {{replaceDate}}…{{ state_attr(‘sensor.vacuum_maint_replace_filter’, ‘visibility_timeout’) }} togo

{% set replaceDate=as_timestamp(state_attr(‘sensor.vacuum_maint_replace_wheel’,‘visibility_timestamp’)|timestamp_local)|timestamp_custom(’%m/%d/%Y’) %}
{{ state_attr(‘sensor.vacuum_maint_replace_wheel’, ‘friendly_name’) }}->
…Replace date {{replaceDate}}…{{ state_attr(‘sensor.vacuum_maint_replace_wheel’, ‘visibility_timeout’) }} togo

Last Mission: {{ state_attr(‘sensor.rest980’, ‘cleanMissionStatus’)[“sqft”] }} sqft

Yes you need to delete this file for it to use the js version.

I have the check-button-card forked so you can actually specify this as a custom HACS repository rather than copying the files manually. Same with the Roomba card.

The dev has merged my PR but has not yet issues a new release (so it’s not updated in HACS yet) once it’s offical I’ll submit a PR to get Roomba vacuum card added to the default repo also

I spoke to the developer about adding an option to show the due date (based on visibility time / timestamp) rather than last done - so watch this space :+1:

Thanks @Syrius,
when I saw commit value my brain just went into “git checkout …”
different git repos having the same commit value didn’t cross my mind.

I’ve uninstalled the check-button-card, and added your repos check-button-card
and re-installed it.

Humbly learned a lot from this experience.

-MQTT explorer is a great free tool to troubleshoot mqtt messages.
-never assume anything.
-mqtt entities are very resilient from being deleted
until you find they were published with RETAINED.

I look forward for the visibility_time (due date) being displayed.

thanks for all the help.
/Pierre

1 Like

In case anyone else is interested in aligning vacuum cleaning path with floor plan of your home.
I went to wikipedia for rotation of axes formula, found x’ and y’ equations.
my roomba consistently gives x,y data that is about 2.5 degrees rotated clockwise, don’t know why.
the formula from wikipedia is for counter-clockwise, hence I used -2.5.


snippet from wikipedia
“rotates the xy axes counterclockwise through an angle θ into the x’y’ axes”

here’s an image of vacuum cleaning path with original data

here’s the same vacuum.log data with just these 3 lines of code.

$rot_angle_in_degrees = -2.5;
$x=($x*cos(deg2rad($rot_angle_in_degrees))+$y*sin(deg2rad($rot_angle_in_degrees)));
$y=(-1*$x*sin(deg2rad($rot_angle_in_degrees))+$y*cos(deg2rad($rot_angle_in_degrees)));

for myself I tweaked scale of x’ and y’ calculated values and added another x’ and y’ offset

$rot_angle_in_degrees = -2.5;
$scale=0.97;
$xp_offset=35;
$yp_offset=0;
$x=$xp_offset+($x*cos(deg2rad($rot_angle_in_degrees))+$y*sin(deg2rad($rot_angle_in_degrees)))*$scale;
$y=$yp_offset+(-1*$x*sin(deg2rad($rot_angle_in_degrees))+$y*cos(deg2rad($rot_angle_in_degrees)))*$scale;

I put the new calculated $x, $y code after ($theta = $split[2]) in image.php, around line 112

$x = $split[1]+$x_offset;
$y = $split[0]+$y_offset;
$theta = $split[2];

you can put the setup values near the top.

1 Like

Thanks @pnakashian great work… Finally I manage to align vacuum cleaning path with floor plan.
Before, with original image.php:

After, with your code and parameter adjustment;

I have also one question. For Roomba 980 hence it doesn’t have individual Room cleaning feature is it possible somehow within Frontend setting the type of cleaning (All, kitchen, bedroom…) and then after placing Roomba to the specific location and pressing CLEAN on the robot to have vacuum map aligned to specific room with different parameter setup (x,y, scale,offset) depending on boolean value which represents a specific room.

I’ll try to answer this question as best as I can.

if you were planning to put the roomba 980 into a room press clean then close the door behind it.
I suppose you can pass a flag to image.php I don’t code PHP, but I’ve seen Jeremy’s code in configuration.yaml shell_command

vacuum_clear_image: curl -X GET -s -O /dev/null '{{ states("input_text.vacuum_map") }}?clear=true'
vacuum_generate_image: curl -X GET -s -O /dev/null '{{ states("input_text.vacuum_map") }}?last=true'

he passes clear=true, and last=true into image.php

inside the image.php he uses isset($_GET['clear']) and isset($_GET['last']) to get values
you can do something similar without having to get room Xprime, Yprime boundary min/max values.

Another way is to obtain X prime, Y prime boundary values as the roomba enters a specific room using the wikipedia formula. Because of the rotation on the original X,Y data, you can’t use the original X,Y data to obtain a pair of X boundary min/max values or a pair of Y boundary min/max values when entering a room.

You can do this watching in home assistant gui X prime, Y prime value as roomba crosses into that room.

add the following script below into lovelace markdown card
you’ll see in realtime the transformed Xprime, Yprime values

{% set x = state_attr('sensor.rest980', 'pose')['point']['x'] %},
{% set y = state_attr('sensor.rest980', 'pose')['point']['y'] %},
{% set rot_angle_in_degrees = -2.5 %}
{% set scale=0.97 %}
{% set xp_offset=35 %}
{% set yp_offset=0 %}
{% set xp=xp_offset+(x*cos(rot_angle_in_degrees*pi/180)+y*sin(rot_angle_in_degrees*pi/180))*scale %}
{% set yp=yp_offset+(-1*x*sin(rot_angle_in_degrees*pi/180)+y*cos(rot_angle_in_degrees*pi/180))*scale %}

origX, origY {{ x, y }}

Xprime,Yprime {{ xp, yp }}

once you get room boundary Xprime, Yprime values you can put in
if -else if logic inside image.php around line 112, after my previous code snippet where x,y values were recalculated.

your top left room for instance would have php if else like this

if ($x>=$x_room1_boundary_min && $x<=$x_room1_boundary_max
&& $y>=$y_room1_boundary_min && $y<=$y_room1_boundary_max) {
//here you can fine tune and add room specifix X_offset, Y_offset, scale
}

1 Like

Thank you for your suggestions. But, after removing Roomba 980 from Dock and placing it to desired Room for cleaning the coordinates are (0,0,0) at the beginning so comparing to X-Y boundary values for specific room identifications will not work. I think I will somehow use input_booleans to set the “flag” which Room I plan to clean so the cleaning map should be placed correctly to my floorplan after using correct set of parameters (angle, offset, scale…)

Just got software update 3.2.9… Everything still appears to be working but can’t see any release notes for it yet :thinking:

Hi @Syrius
I think your repo
jeremywillans/check-button-card has visibility_timestamp broken, there have been a few commits since e80ef56, latest commit now is 68e4549. When I switched to your repo I had already created the entities and didn’t single click the check-button entity until I had to perform maintenance today.
The entities already created from commit e80ef56 will still have visibility_timestamp attribute even after upgrading the code.

Only after single clicking the check-buttons the attribute visibility_timestamp goes away with latest code. Since the HACS plugin install for jeremywilans/check-button-card doesn’t let you choose version or commits, I reverted it manually downloading the e80ef56 .js and creating .js.gz from it in the /config/www/community/check-button-card folder. I got visibility_timestamp back now.

I’m at HA version 0.105.5 in case you don’t see an issue in your config.

/Pierre

1 Like

Try using master for the version in my repo, however dont touch it if you have a workaround :rofl:

I’m in the process of updating my repo to use the new timeout_timestamp option which the proper check-button-card now uses - just waiting for one last PR to be merged to fix an outstanding issue

Got some new updates coming also… Watch this space!! :partying_face:

First off, thank you for all the hard work.
I am trying to get this to work and having issues. I am trying to do this without docker so everything is manually installed downloaded and configured.
I have the robot-vacuum-card working. It updates with information and I can start and stop my roomba (s9+)
My issues is that the clean individual rooms is not working.
This is the contents of my secrets.yaml (maps are not working either but I will focus on that later)

vacuum_state:  http://192.###.#.###:3000/api/local/info/state
vacuum_action: http://192.###.#.###:3000/api/local/action/
vacuum_verify_ssl: false
vacuum_map: http://192.###.#.###:4123/image.php
vacuum_pmap_id: 2F8WoQ#######QyOE9UA
vacuum_user_pmapv_id: 200####222327
vacuum_family:  '{"region_id": "1","region_name": "Family Room","region_type": "family_room", "type": "rid"}'
vacuum_dining:  '{"region_id": "9","region_name": "Dining Room","region_type": "dining_room", "type": "rid"}'
vacuum_kitchen: '{"region_id": "7","region_name": "Kitchen","region_type": "kitchen", "type": "rid"}'
vacuum_foyer:   '{"region_id": "12","region_name": "Foyer","region_type": "foyer", "type": "rid"}'
vacuum_hallway: '{"region_id": "15","region_name": "Hallway","region_type": "hallway", "type": "rid"}'
vacuum_living:  '{"region_id": "11","region_name": "Living Room","region_type": "living_room", "type": "rid"}'
vacuum_utility: '{"region_id": "16","region_name": "Utility","region_type": "laundry_room", "type": "rid"}'
vacuum_breakfast: '{"region_id": "17","region_name": "Breakfast Room","region_type": "breakfast_room", "type": "rid"}'

I am running rest980 and getting output that status is being run but I never see the

GET /api/local/info/state 200 100.559 ms - 3420
GET /api/local/info/state 200 100.511 ms - 3420
GET /api/local/info/state 200 100.519 ms - 3420
GET /api/local/info/state 200 100.521 ms - 3420
GET /api/local/info/state 200 100.541 ms - 3420
GET /api/local/info/state 200 100.541 ms - 3420
GET /api/local/info/state 200 100.709 ms - 3420
GET /api/local/info/state 200 100.541 ms - 3420
GET /api/local/info/state 200 100.523 ms - 3420
GET /api/local/info/state 200 100.529 ms - 3420
GET /api/local/info/state 200 100.653 ms - 3420

But I never see the /api/local/action

I have looked through the vacuum.yaml file and changed all of the section in there that refer to the different rooms. I think it comes down to the automation not firing
In looking through the code I cannot find where initiate_vacuum_clean event gets notified. What am I missing?


automation:
  # Initiate Selective Room Clean
  - alias: Vacuum Clean Rooms
    hide_entity: true
    trigger:
    - platform: event
      event_type: initiate_vacuum_clean       
    action:
      - service: rest_command.vacuum_clean
        data_template:
          payload: >

Hi @batlin, thanks :blush:

In the Lovelace.yaml file the button card calls the Automation. Can you please check/verify that is configured correctly?

Hi there!

Very nice write up!

I have a Roomba 960 and running home assistant on a Raspberry pi 3B.
The built in Roomba component works, but I’m missing some features I would like to play with.
If I am correct this addon should work for my 960 as well right? (except room cleaning and other not supported features). I see in the readme that this is for amd64 systems only, but the following is mentioned:

Would be nice if I can get the map to work.

Furthermore, I looked into the code on github, but I cannot find if it is possible to send Raw commands?
I would like to play around with some RAW commands, because of multiple reasons:

  • My base is located under a closet. I would like to get the Roomba to drive from underneath when the bin is full, so it is easier to empy. I tried using the original component with clean, but that doesn’t work as the Roomba doesn’t accept new missions when the bin in full.
  • I would like to create my own “room cleaning” feature like SuperMario wants, but for that to work the Roomba needs to be able to drive said room first

I have found some commands here, I think the are for a iRobot Create 2. But it might give some pointers to additional commands?
With the original Roomba component I seem to be unable to send Raw commands (see my post here, no answers yet though)

Thanks in advance!