iRobot Roomba i7+ Configuration using Rest980

Hm… It is interesting. Now, I have tried with only holding the dock button. After 2 seconds the roomba behaves the same way. It Beeps and the wifi icon flashes.

On my mikrotik I created a new firewall rule to block internet access from my roomba. But got the same issue.

Any other tip? :confused:

PS Roomba980-Python-master> ping 192.168.10.240

Pinging 192.168.10.240 with 32 bytes of data:
Reply from 192.168.10.240: bytes=32 time=4ms TTL=255
Reply from 192.168.10.240: bytes=32 time=2ms TTL=255
Reply from 192.168.10.240: bytes=32 time=2ms TTL=255
Reply from 192.168.10.240: bytes=32 time=4ms TTL=255

Ping statistics for 192.168.10.240:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 2ms, Maximum = 4ms, Average = 3ms
PS Roomba980-Python-master> python .\roomba\getpassword.py -R 192.168.10.240
CV or numpy module not found, falling back to PIL
waiting on port: 5678 for data
found 1 Roomba(s)
Make sure your robot (Roomba) at IP 192.168.10.240 is on the Home Base and powered on (green lights on). Then press and hold the HOME button on your robot until it plays a series of tones (about 2 seconds). Release the button and your robot will flash WIFI light.
Press Enter to continue…
Received: {
“ver”: “3”,
“hostname”: “Roomba-31750xxxxxxxx500”,
“robotname”: “Roomba”,
“ip”: “192.168.10.240”,
“mac”: “D0:C5:D3:E4:28:FF”,
“sw”: “3.3.47”,
“sku”: “R676040”,
“nc”: 0,
“proto”: “mqtt”,
“cap”: {
“ota”: 1,
“eco”: 1,
“svcConf”: 1
}
}
Roomba (Roomba) IP address is: 192.168.10.240
Connection Error timed out
Traceback (most recent call last):
File “.\roomba\getpassword.py”, line 39, in
main()
File “.\roomba\getpassword.py”, line 36, in main
Password(arg.roombaIP,file=arg.configfile)
File “D:\Users\user\Downloads\Roomba980-Python-master\Roomba980-Python-master\roomba\password.py”, line 41, in init
self.get_password()
File “D:\Users\user\Downloads\Roomba980-Python-master\Roomba980-Python-master\roomba\password.py”, line 138, in get_password
wrappedSocket.send(packet)
File “C:\Users\user\AppData\Local\Programs\Python\Python38-32\lib\ssl.py”, line 1175, in send
return super().send(data, flags)
socket.timeout: timed out

@medaK git clone https://github.com/koalazak/dorita980.git
cd dorita980
npm install (assume you have node installed on your machine)
npm run getpassword 192.168.10.240
-> then press and hold home icon button on your roomba for 2 seconds until the wifi icon start flashing and roomba beeps

if error occurs, paste it back in here, i can see you using some python script, but i am not familiar with that method

During the process, but before the error message the roomba said the “Now you are connected to roomba blabla…”

events.js:183
throw er; // Unhandled ‘error’ event
^

Error: connect ETIMEDOUT 192.168.10.240:8883
at Object._errnoException (util.js:1022:11)
at _exceptionWithHostPort (util.js:1044:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1198:14)

npm ERR! Linux 5.4.34-1-pve
npm ERR! argv “/usr/bin/node” “/usr/bin/npm” “run” “getpassword” “192.168.10.240”
npm ERR! node v8.10.0
npm ERR! npm v3.5.2
npm ERR! code ELIFECYCLE
npm ERR! [email protected] getpassword: node ./bin/getpassword.js "192.168.10.240"
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] getpassword script ‘node ./bin/getpassword.js “192.168.10.240”’.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the dorita980 package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! node ./bin/getpassword.js “192.168.10.240”
npm ERR! You can get information on how to open an issue for this project with:
npm ERR! npm bugs dorita980
npm ERR! Or if that isn’t available, you can get their info via:
npm ERR! npm owner ls dorita980
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR! /root/repos/dorita980/npm-debug.log

I am having issues running Rest980 docker image in Hassio. I can successfully run roombaAPW to get the credentials. When I start the Rest980 docker image I get the following when I set the firmware to 3 in the configuration.

> [email protected] start /usr/src/app
> node ./bin/www

/usr/src/app/node_modules/dorita980/lib/v2/cloud.js:7
  throw new Error('Not implemented.');
  ^

Error: Not implemented.
    at dorita980 (/usr/src/app/node_modules/dorita980/lib/v2/cloud.js:7:9)
    at new cloud (/usr/src/app/node_modules/dorita980/index.js:12:10)
    at /usr/src/app/routes/api.js:33:46
    at handleIP (/usr/src/app/routes/api.js:26:68)
    at Object.<anonymous> (/usr/src/app/routes/api.js:27:1)
    at Module._compile (module.js:577:32)
    at Object.Module._extensions..js (module.js:586:10)
    at Module.load (module.js:494:32)
    at tryModuleLoad (module.js:453:12)
    at Function.Module._load (module.js:445:3)
    at Module.require (module.js:504:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/usr/src/app/app.js:11:16)
    at Module._compile (module.js:577:32)
    at Object.Module._extensions..js (module.js:586:10)
    at Module.load (module.js:494:32)
    at tryModuleLoad (module.js:453:12)
    at Function.Module._load (module.js:445:3)
    at Module.require (module.js:504:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/usr/src/app/bin/www:7:11)
    at Module._compile (module.js:577:32)

npm ERR! Linux 4.15.0-99-generic
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "start"
npm ERR! node v6.17.1
npm ERR! npm  v3.10.10
npm ERR! code ELIFECYCLE
npm ERR! [email protected] start: `node ./bin/www`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] start script 'node ./bin/www'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the rest980 package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     node ./bin/www
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs rest980
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!     npm owner ls rest980
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /usr/src/app/npm-debug.log

So, you got your credentials? Or?

Dont set firmware to 3 btw, every firmrware >= 2, has number 2 in configuration.

You should read rest980 documentation. From the documentation: " Set to 1 or 2 depends of your robot firmware version. Use 2 for any firmware >=2 (yes, use 2 if you have firmware version 3). Default to 1 for firmware 1.6.6"

Even though it said that I am now connected, I did not get the credentials. And I didn’t set the firmware to 3.

@medaK from where you starting that script? (npm ERR! Linux 5.4.34-1-pve) from server or you host machine? And do you have NodeJS installed on that machine?

The part about firmware version was meant to be for @PixelAlarm

actually that runs inside an LXC container on my NUC. Of cource nodejs is installed

apt-get update
apt-get upgrade
apt-get install nodejs
apt-get install npm

If it is a problem factor, then I will install nodejs locally on my windows 10 pc and try there.

@medaK I would definitely try that from local machine instead of LXC server container, let me know if that works or not

@pasleto no success. I am so confused.

PS dorita980-master> npm run getpassword 192.168.10.240

[email protected] getpassword dorita980-master
node ./bin/getpassword.js “192.168.10.240”

Make sure your robot is on the Home Base and powered on (green lights on). Then press and hold the HOME button on your robot until it plays a series of tones (about 2 seconds). Release the button and your robot will flash WIFI light.
Then press any key here…
(node:1492) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.
events.js:287
throw er; // Unhandled ‘error’ event
^

Error: connect ETIMEDOUT 192.168.10.240:8883
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1141:16)
Emitted ‘error’ event on TLSSocket instance at:
at emitErrorNT (internal/streams/destroy.js:92:8)
at emitErrorAndCloseNT (internal/streams/destroy.js:60:3)
at processTicksAndRejections (internal/process/task_queues.js:84:21) {
errno: ‘ETIMEDOUT’,
code: ‘ETIMEDOUT’,
syscall: ‘connect’,
address: ‘192.168.10.240’,
port: 8883
}
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] getpassword: node ./bin/getpassword.js "192.168.10.240"
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] getpassword script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\user\AppData\Roaming\npm-cache_logs\2020-05-17T14_16_44_037Z-debug.log

@medaK hmm strange, can you ping to your roomba from host machine? If so, there might be a problem in your network, maybe some proxy blocking communication from roomba

The strangest thing that, when I reboot the roomba, it immediatly want to communicate with the cloud and after the https connection is established it got tcp packets from 8883 from the internet.

it’s strange because I have uninstalled my application and I unlinked the irobot account in google home.

OFC, yes i can. I dont undestand this behaviour. :confused:

Maybe if i turn off my firewall. (but there isn’t any setup for this type of blocking…)

If no success, i will fire my roomba from my home :smiley:

try to make separate network (maybe hostspot from your phone) to make connection between your roomba and host machine, you would need to connect roomba to that network for credectials recovery process and then setup roomba back to your home network, but from the log it seems something on your network blocking roomba to communicate with your host machine

that part about cloud connection is strange and might be the reason around connection timeout

Thanks I missed that. This may be another basic question but I am not seeing what needs to be placed into: lovelace.yaml and vacuum.yaml as called out in the instructions. I see in the faq the format of the rooms in secrets.yaml.

if you have Roomba i7 just copy and paste this config into yours, if you dont use some kind of packaging, just paste things from vacuum.yaml into configuration.yaml, based on its domain (sensor, automation, …)

about the frontend, things from lovelace.yaml paste into your lovelace in your intended view

Hi Peter,

Give this a shot…

NOTE! I havent tested this - just put it together this morning so it might have a couple of mistakes :wink:

Let me know how you go :+1:

If its all good, ill add it to the FAQ as a guide for adding a second level.

Cheers :beers:

Changes

secrets.yaml

#replace existing map with map0
vacuum_map_0: http://<ip or fqdn of docker host>:<nginxphpport>/image0.php
vacuum_map_1: http://<ip or fqdn of docker host>:<nginxphpport>/image1.php

vacuum.yaml

###################################
# Sensor
###################################

sensor:
        #... EXISTING...
  - platform: template
    sensors:
      vacuum:
        #... EXISTING...
        attribute_templates:
        #... EXISTING...
        
          # pmap1_id I7/S9 Models - Level 1 (represented by the second pmap list entry)
          pmap1_id: >-
            {% if state_attr('sensor.rest980', 'pmaps')[1] is defined %}
              {{ state_attr('sensor.rest980', 'pmaps')[1] | regex_findall_index("{'([\w\-]+)': '\w+'}") }}
            {% else %}
              n-a
            {% endif %}
          # pmap1_timestamp I7/S9 Models
          pmap1_timestamp: >-
            {% if state_attr('sensor.rest980', 'pmaps')[1] is defined %}
              {{ state_attr('sensor.rest980', 'pmaps')[1] | regex_findall_index("{'[\w\-]+': '(\w+)'}") }}
            {% else %}
              n-a
            {% endif %}

###################################
# Input Boolean
###################################

input_boolean:
 # existing room entries, add "_0_" between clean and name
  vacuum_clean_0_kitchen:
    name: Kitchen
    icon: mdi:silverware-fork-knife
 # new map entries, add "_1_" before between clean and name
  vacuum_clean_1_bedroom:
    name: Second Floor Bedroom
    icon: mdi:bed-empty

###################################
# Input Text
###################################

input_text:
 # existing room entries, add "_0_" between clean and name
  vacuum_clean_0_kitchen:
    name: Kitchen
    initial: !secret vacuum_kitchen   
 # new map entries, add "_1_" before between clean and name
  vacuum_clean_1_bedroom:
    name: Second Floor Bedroom
    initial: !secret vacuum_second_floor_bedroom    
    
###################################
# Group
###################################

group:
  vacuum_rooms_0:  #renamed from existing group
  # existing room entries, add "_0_" between clean and name
    
  vacuum_rooms_1:
 # new map entries, add "_1_" before between clean and name
    
###################################
# Input Select
###################################

input_select:
  vacuum_map_selection:
    name: Vacuum Map Selection
    options:
      - 'Ground'
      - 'Level 1'
    
###################################
# Automation
###################################

automation:
  # Initiate Selective Room Clean Map 0
  - alias: Vacuum Clean Rooms 0 #renamed from existing, adds extra action for level selection (camera)
    trigger:
    - platform: event
      event_type: initiate_vacuum_clean_0
    action:
      - service: input_select.select_option
        data:
          entity_id: input_select.vacuum_map_selection
          option: "Ground"
      - service: rest_command.vacuum_clean
        data_template:
          payload: >
            {
              "ordered": 0,
              "pmap_id": "{{ state_attr('sensor.vacuum', 'pmap0_id') | string }}",
              "regions": [{% for boolean in states.input_boolean if 'vacuum_clean_0_' in boolean.entity_id and is_state(boolean.entity_id, 'on') %}
                {% set room = 'input_text.' + boolean.entity_id.split('.')[1] %} {{ states(room) | string }} {%- if not loop.last %},{%- endif %}
                {%- endfor %}
              ],
              "user_pmapv_id": "{{ state_attr('sensor.vacuum', 'pmap0_timestamp') | string }}"
            }
      - service: input_boolean.turn_off
        data:
          entity_id: group.vacuum_rooms_0
          
  # Initiate Selective Room Clean Map 1
  - alias: Vacuum Clean Rooms 1
    trigger:
    - platform: event
      event_type: initiate_vacuum_clean_1
    action:
      - service: input_select.select_option
        data:
          entity_id: input_select.vacuum_map_selection
          option: "Level 1"
      - service: rest_command.vacuum_clean
        data_template:
          payload: >
            {
              "ordered": 0,
              "pmap_id": "{{ state_attr('sensor.vacuum', 'pmap1_id') | string }}",
              "regions": [{% for boolean in states.input_boolean if 'vacuum_clean_1_' in boolean.entity_id and is_state(boolean.entity_id, 'on') %}
                {% set room = 'input_text.' + boolean.entity_id.split('.')[1] %} {{ states(room) | string }} {%- if not loop.last %},{%- endif %}
                {%- endfor %}
              ],
              "user_pmapv_id": "{{ state_attr('sensor.vacuum', 'pmap1_timestamp') | string }}"
            }
      - service: input_boolean.turn_off
        data:
          entity_id: group.vacuum_rooms_1
         
         
###################################
# Camera
###################################

camera:
  - platform: generic
    still_image_url: !secret vacuum_map_0
    content_type: image/png
    name: Roomba_Ground
camera:
  - platform: generic
    still_image_url: !secret vacuum_map_1
    content_type: image/png
    name: Roomba_Level_1

lovelace.yaml

### VERTICAL STACK CARD ###
cards:
  - entity: sensor.vacuum
    type: 'custom:roomba-vacuum-card'
  - entities:
      # existing room entries, add "_0_" between clean and name
      - input_boolean.vacuum_clean_0_kitchen
      - entity: automation.vacuum_clean_rooms_0
        lock:
          enabled: |
            [[[
              if ((states['group.vacuum_rooms_0'].state == "on") && (states['sensor.vacuum'].state == "Ready"))
                return false;
              return true;
            ]]]
          exemptions: []
        name: Clean Rooms
        styles:
          card:
            - height: 50px
        tap_action:
          action: call-service
          service: automation.trigger
          service_data:
            entity_id: automation.vacuum_clean_rooms_0
        type: 'custom:button-card'
    head:
      label: Ground Floor Cleaning
      type: section
    type: 'custom:fold-entity-row'
  - entities:
      # new map entries, add "_1_" before between clean and name
      - input_boolean.vacuum_clean_1_bedroom
      - entity: automation.vacuum_clean_rooms_1
        lock:
          enabled: |
            [[[
              if ((states['group.vacuum_rooms_1'].state == "on") && (states['sensor.vacuum'].state == "Ready"))
                return false;
              return true;
            ]]]
          exemptions: []
        name: Clean Rooms
        styles:
          card:
            - height: 50px
        tap_action:
          action: call-service
          service: automation.trigger
          service_data:
            entity_id: automation.vacuum_clean_rooms_1
        type: 'custom:button-card'
    head:
      label: Level 1 Floor Cleaning
      type: section
    type: 'custom:fold-entity-row'
   

### PICTURE GLANCE CARD >> INSIDE STATE-SWITCH ###   


type: custom:state-switch
entity: input_select.coffee_time
states:
  Ground:
    aspect_ratio: 0%
    camera_image: camera.roomba_0
    entities: []
    type: picture-glance
  Level 1:
    aspect_ratio: 0%
    camera_image: camera.roomba_1
    entities: []
    type: picture-glance

image.php -> rename to image0.php

create second copy as image1.php and update to reflect your second level

This is covered in Step 6. I use packages so you should be able to copy in vacuum.yaml into your packages directory (and/or create one in your config section and refer here to configure packages in HA

With lovelace.yaml, you can create a manual card and copy the content from this file in (note there is two cards a vertical stack, and picture glace which will need to be created seperately)

The relevent input_booleans/input_texts/secrets room details will need to be updated to reflect you home

Ill update the FAQ, you dont need to include the room details, only the room ID

Thanks I didn’t realize you were pointing to the vacuum.yaml in your git repository.

Thanks for your help!

1 Like

Thanks, I’ve moved these to links in the README :beers: