iRobot 9xx on openHAB

I’m running into the same issue, that the opencv-python is not found in the distribution.
Do you know how to install opencv-python manually on a openhabian install?

I’m a bit blocked with the python installation. :blush:
Hope that somebody can help me out.

What I’ve done to install it (ran it 2 times to be sure):

pip install paho-mqtt                            
   Requirement already satisfied: paho-mqtt in /usr/local/lib/python2.7/dist-packages

pip install paho-mqtt
   Requirement already satisfied: paho-mqtt in /usr/local/lib/python2.7/dist-packages

pip install pillow
   Requirement already satisfied: pillow in /usr/local/lib/python2.7/dist-packages

pip install six
   Requirement already satisfied: six in /usr/lib/python2.7/dist-packages

pip install numpy
   Requirement already satisfied: numpy in /usr/local/lib/python2.7/dist-packages

pip install git+https://github.com/NickWaterton/Roomba980-Python.git  
   Collecting git+https://github.com/NickWaterton/Roomba980-Python.git
   Clocateloning https://github.com/NickWaterton/Roomba980-Python.git to /tmp/pip-QGhZT7-build
   Requirement already satisfied u se --upgrade to upgrade: Roomba980-Python==1.2.3 from git+https://github.com/NickWaterton/Roomba980-Python.git in /usr/local/lib/python2.7/dist-packages
   Requirement already satisfied: numpy in /usr/local/lib/python2.7/dist-packages (from Roomba980-Python==1.2.3)
   Requirement already satisfied: opencv-python in /usr/local/lib/python2.7/dist-packages (from Roomba980-Python==1.2.3)
   Requirement already satisfied: paho-mqtt in /usr/local/lib/python2.7/dist-packages (from Roomba980-Python==1.2.3)
   Requirement already satisfied: pillow in /usr/local/lib/python2.7/dist-packages (from Roomba980-Python==1.2.3)
   Requirement already satisfied: six in /usr/lib/python2.7/dist-packages (from Roomba980-Python==1.2.3)




A bit weird to me, by my path to roomba wasn’t know? So I had to add the path manually:

export PATH=$PATH:/usr/local/bin




And when I know run the command, I’m getting an error?

roomba                                           
   CV or numpy module not found, falling back to PIL                    
   /usr/bin/python: Relink /usr/local/lib/python2.7/dist-packages/PIL/.libs/./liblzma-6cd627ed.so.5.2.4 with /lib/x86_64-linux-gnu/librt.so.1 for IFUNC symbol `clock_gettime
   Segmentatiefout (geheugendump gemaakt)   

python /usr/local/lib/python2.7/dist-packages/roomba/roomba.py
   Traceback (most recent call last):
      File /usr/local/lib/python2.7/dist-packages/roomba/roomba.py, line 25, in <module>
         from roomba.password import Password
      File /usr/local/lib/python2.7/dist-packages/roomba/roomba.py, line 25, in <module>
         from roomba.password import Password                                     
    ImportError: No module named password




Maybe some additional info?

  • Ubuntu 18.04.1 LTS
  • Python 2.7.15rc1
  • OpenHAB 2.4.0.M7

Any hints to resolve this?

Nevermind, seems to be an issue with the opencv.
After reinstalling this packages, I can run the command roomba…

apt install python3-opencv

For the moment, I’m running the script on the background, and it’s been triggered by a startup rule in OH. I couldn’t find in the manual what is the correct way to start the python script. :blush:

My solution:

// rule
    rule "Start roomba communicatie"
    when  
        System started
    then 
        createTimer(now.plusSeconds(60), [|
           executeCommandLine("sudo /etc/openhab2/scripts/roomba_start.sh &")
         ])
    end

// Script  (/etc/openhab2/scripts/roomba_start.sh)

    roomba -R '192.168.111.26' -u '316442109688590' -w ':1:154958722:MVYh0s3OKeiyzj11' -b 'localhost' -U 'MQTTUSER' -P 'MQTTPWD'  -l '/openhab2/log/roomba.log' -M '/openhab2/html' -I '/openhab2/icons/roomba/' -s '(800,1650,0,0,2,180)'                  



@Franco_Pellicciotti, or others,

Did you manage to produce a nice drawing?
It’s not clear to me what is been drawn. Except the path he followed (I think).
Is it fe possible to give it a background? Would say a lot more…

I have a similar task for term paper, I use opencv and openapi. And it`s hard((
But what can I say Roomba 980 is probably the best model at the moment

1 Like

Hello everybody,

based on koalazak and NickWaterton work i figured out how openHAB can natively speak with Roomba via MQTT2 binding. May be it’s of interest.

First the hard part of the job or how the things must be defined:

Bridge mqtt:broker:roomba "Roomba" @ "Cleaner" [ clientID="<blid>", host="<ip>", port=8883, secure=true,
                                                 username="<blid>", password="<pwd>",
                                                 certificatepin=true, publickeypin=true ]
{
  Thing topic state "Roomba state" @ "Cleaner" {
    Channels:
      Type string : wifistat "WiFi"    [ stateTopic="wifistat" ]
      Type string : shadow   "Status"  [ stateTopic="$aws/things/<blid>/shadow/#" ]
  }
}

Now the things are easy:

String RoombaWifistatJSON "Roomba WiFi [%s]"   { channel="mqtt:topic:roomba:state:wifistat" }
String RoombaShadowJSON   "Roomba State [%s]" { channel="mqtt:topic:roomba:state:shadow" }

and we have JSON reply from Roomba broker. There are a lot of messages Roomba send back. Therefore i wrote some rules to get the stuff sorted:

rule "RoombaWifistatJSONReceivedUpdate"
when
  Item RoombaWifistatJSON received update
then
  val String json = RoombaWifistatJSON.state.toString
  if(json !== null) {
    for(String key: transform("JS", "roomba.js", json).split(",")) {
      if(key == "localtimeoffset") {
      } else if(key == "mac") {
      } else if(key == "netinfo") {
      } else if(key == "signal") {
      } else if(key == "pose") {
      } else if(key == "utctime") {
      } else if(key == "wifistat") {
      } else if(key == "wlcfg") {
      } else {
        logInfo("RoombaWifistatJSON", "JSON: " + json + " Key: " + key)
      }
    }
  }
end

rule "RoombaShadowJSONReceivedUpdate"
when
  Item RoombaShadowJSON received update
then
  val String json = RoombaShadowJSON.state.toString
  if(json !== null) {
    for(String key: transform("JS", "roomba.js", json).split(",")) {
      if(key == "audio") {
      } else if(key == "batPct") {
      } else if(key == "batteryType") {
      } else if(key == "bbchg") {
      } else if(key == "bbmssn") {
      } else if(key == "bbrstinfo") {
      } else if(key == "bbchg3") {
      } else if(key == "bbnav") {
      } else if(key == "bbpanic") {
      } else if(key == "bbpause") {
      } else if(key == "bbrun") {
      } else if(key == "bbswitch") {
      } else if(key == "bbsys") {
      } else if(key == "bin") {
      } else if(key == "binPause") {
      } else if(key == "bootloaderVer") {
      } else if(key == "cap") {
      } else if(key == "carpetBoost") {
      } else if(key == "cleanMissionStatus") {
      } else if(key == "cleanSchedule") {
      } else if(key == "cloudEnv") {
      } else if(key == "country") {
      } else if(key == "connected") {
      } else if(key == "dock") {
      } else if(key == "ecoCharge") {
      } else if(key == "hardwareRev") {
      } else if(key == "langs") {
      } else if(key == "language") {
      } else if(key == "lastCommand") {
      } else if(key == "name") {
      } else if(key == "navSwVer") {
      } else if(key == "noAutoPasses") {
      } else if(key == "noPP") {
      } else if(key == "mapUploadAllowed") {
      } else if(key == "mobilityVer") {
      } else if(key == "openOnly") {
      } else if(key == "schedHold") {
      } else if(key == "sku") {
      } else if(key == "softwareVer") {
      } else if(key == "soundVer") {
      } else if(key == "svcEndpoints") {
      } else if(key == "timezone") {
      } else if(key == "twoPass") {
      } else if(key == "tz") {
      } else if(key == "uiSwVer") {
      } else if(key == "umiVer") {
      } else if(key == "vacHigh") {
      } else if(key == "wifiSwVer") {
      } else {
        logInfo("RoombaShadowJSON", "JSON: " + json + " Key: " + key)
      }
    }
  }
end

And as last roomba.js script used as transform:

(function(json){
  var result = "";
  try {
    var buffer = JSON.parse(json).state.reported;
    result = Object.keys(buffer).toString()
  }
  catch(error) {
    result = error;
  }
  finally {
    return result;
  }
})(input)

Sending of commands is done via

val RoombaActions = getActions("mqtt", "mqtt:broker:roomba")

// Commands: "start", "stop", "pause", "resume", "dock"
val GetCommandJSON = [ String command |
  String::format("{\"command\":\"%s\",\"time\":%d,\"initiator\":\"localApp\"}", command, now.millis / 1000)
]

// Settings; Send on "delta",
// carpetBoost true/false, vacHigh true/false, binPause true
//           openOnly true this is edge clean - set to false to enable edge cleaning
//           noAutoPasses true/false twoPass true/false
val GetSettingJSON = [ String command |
  String::format("{\"state\":\"%s\"}")
]

For example to send Roomba home, follow rule can be used:

rule "RoombaDockReceivedCommand"
when
  Item RoombaDock received command ON
then
  RoombaActions.publishMQTT("cmd", GetCommandJSON.apply("dock"))
end

mainly that’s all. To draw a map, i use currently influxdb/grafana.

Kind regards,

Alexander

7 Likes

Thanks a lot @falkena !
I’m not that advance with mqtt as I wish. So, please can you post there also some of your items configuration?
I would like to see in sitemap, info about battery, bin and actual status, bud don’t know how to create items for it.
Thanks

Hi @YogiBB

well, it has nothing with mqtt. For example for bin state use follow:

roomba.items

String RoombaWifistatJSON "Roomba WiFi [%s]"  { channel="mqtt:topic:roomba:state:wifistat" }
String RoombaShadowJSON   "Roomba State [%s]" { channel="mqtt:topic:roomba:state:shadow" }

String RoombaBinPresent "Bin present [%s]"
String RoombaBinFull    "Bin full [%s]" <cistern>

roomba.rules

rule "RoombaShadowJSONReceivedUpdate"
when
  Item RoombaShadowJSON received update
then
  val String json = RoombaShadowJSON.state.toString
  if(json !== null) {
    for(String key: transform("JS", "roomba.js", json).split(",")) {
      if(key == "audio") {
      } else if(key == "batPct") {
      } else if(key == "batteryType") {
      } else if(key == "bbchg") {
      } else if(key == "bbmssn") {
      } else if(key == "bbrstinfo") {
      } else if(key == "bbchg3") {
      } else if(key == "bbnav") {
      } else if(key == "bbpanic") {
      } else if(key == "bbpause") {
      } else if(key == "bbrun") {
      } else if(key == "bbswitch") {
      } else if(key == "bbsys") {
      } else if(key == "bin") {
        RoombaBinFull.postUpdate(transform("JSONPATH", "$..bin.full", json))
        RoombaBinPresent.postUpdate(transform("JSONPATH", "$..bin.present", json))
      } else if(key == "binPause") {
      } else if(key == "bootloaderVer") {
      } else if(key == "cap") {
      } else if(key == "carpetBoost") {
      } else if(key == "cleanMissionStatus") {
      } else if(key == "cleanSchedule") {
      } else if(key == "cloudEnv") {
      } else if(key == "country") {
      } else if(key == "connected") {
      } else if(key == "dock") {
      } else if(key == "ecoCharge") {
      } else if(key == "hardwareRev") {
      } else if(key == "langs") {
      } else if(key == "language") {
      } else if(key == "lastCommand") {
      } else if(key == "name") {
      } else if(key == "navSwVer") {
      } else if(key == "noAutoPasses") {
      } else if(key == "noPP") {
      } else if(key == "mapUploadAllowed") {
      } else if(key == "mobilityVer") {
      } else if(key == "openOnly") {
      } else if(key == "schedHold") {
      } else if(key == "sku") {
      } else if(key == "softwareVer") {
      } else if(key == "soundVer") {
      } else if(key == "svcEndpoints") {
      } else if(key == "timezone") {
      } else if(key == "twoPass") {
      } else if(key == "tz") {
      } else if(key == "uiSwVer") {
      } else if(key == "umiVer") {
      } else if(key == "vacHigh") {
      } else if(key == "wifiSwVer") {
      } else {
        logInfo("RoombaShadowJSON", "JSON: " + json + " Key: " + key)
      }
    }
  }
end

See above source code for roomba.js

Kind regards,

Alexander

Hi Alexander,

I’ve been waiting since June 2018 for this code for the Roomba. I’m not a MQTT user, my first question is which binding do I need use (or both)?

org.openhab.binding.mqtt-2.5.0-SNAPSHOT.jar
org.openhab.binding.mqtt.generic-2.5.0-SNAPSHOT.jar

Best, Jay

@falkena It doesn’t work for me.
It’s going trough RoombaShadowJSON and here is my json:
{"state":{"reported":{"bbrun":{"hr":286,"min":18,"sqft":1147,"nStuck":85,"nScrubs":165,"nPicks":2504,"nPanics":513,"nCliffsF":28074,"nCliffsR":2287,"nMBStll":6,"nWStll":6,"nCBump":0},"bbsys":{"hr":12752,"min":20}}}}

I don’t know if there is another channel for those information in roomba idle state, or I need to send some command to ask for it, or how it works?

Hi @jwiseman

sorry, i’m not PaperUI user, but in addons.cfg I’ve added

binding = mqtt

and

misc = mqttbroker

If you install via jar copy, then both are need.

@YogiBB

You are too quick for roomba :slight_smile: Simply wait. Roomba reports it state from time to time. JSON you posted contains information about (last?) run. I haven’t figured out what the meaning of bbsys is.
There is a lot of information roomba send…

Kind regards,

Alexander.

Hi Alexander,

Here’s my next issue - it’s not getting the password from the unit. My unit is running firmware version 3 and this article only shows version 2 support.

Robot Data:
{ ver: ‘3’,
hostname: ‘Roomba-3164420C5022XXXX’,
robotname: ‘Main Floor’,
ip: ‘192.168.0.143’,
mac: ‘80:C5:F2:72:XX:XX’,
sw: ‘3.2.40’,
sku: ‘R899020’,
nc: 0,
proto: ‘mqtt’,
cap: { ota: 1, eco: 1, svcConf: 1 },
blid: ‘3164420C50000000’ }
Error getting password. Follow the instructions and try again.

Any advise?

Best, Jay

Hi @jwiseman,

it seems, you robot is 890 and not 980. I took a look into koalazak’s source code: There is an if-clause leads in message you posted. Commenting out may help.

Kind regards,

Alexander.

Thanks for the MQTT2 setup post @falkena, I was able to get it running with no problems.

The post however with the example to parse the “key” and update an item is not working for me. I made some wifi items and added a statement to the RoombaWifistatJSON rule to update “signal” wifi items (as this is constantly updating and will allow me to learn how to set this up).


} else if(key == “signal”) {
RoombaSignalSNR.postUpdate(transform(“JSONPATH”, “$…signal.snr”, json))

From the logInfo statement in the rule, here is an example of the output:

JSON: {“state”:{“reported”:{“signal”:{“rssi”:-28,“snr”:59}}}} Key: “snr”:59}}}}

I have added a logInfo statement to the very end of the rule below your logInfo one to just display the just the key:

“snr”:59}}}}

So with the above, the “else if” statement won’t make a match. It is looking for “signal” but the key is “snr”:59}}}}

Any suggestions or hints?

Not sure if i am missing something, as i have little experience with js and transforms…

Thanks for your help.
Craig

Hi @Craigers,
Is roomba.js (see above) script in your transform folder? And, please, change

RoombaSignalSNR.postUpdate(transform(“JSONPATH”, “$…signal.snr”, json))

to

RoombaSignalSNR.postUpdate(transform("JSONPATH", "$..signal.snr", json))

There should be 2 points and not 3.

Kind regards,

Alexander

roomba.js in Transform folder was the “Key” to solving it, I had it in the Scripts folder.

The triple points in my previous post seems to be some sort of formatting when i pasted the statement on this page, as my rule statement only contains 2. Even now if i type 2 points it shows as three.

Thanks so much for your help!

Craig

Thanks Alexander seeing this clause; unfortunately commenting it out did NOT fix it. The password being returned is NULL/Blank. I called and tried chatting with them also and they will NOT give the password to you either.

Any other ideas in getting the password from the unit? I did get everything else except the password.

Best, Jay

Hi @jwiseman,

sadly no. One thing i know, that Roomba accepts only one connection a time. May be you try to connect twice.

Kind regards,

Alexander

I finally figured it out the issue I was having; the instructions in the dorita980 script says to press and hold the clean button for 2 seconds; this isn’t valid for model 899 running firmware v3.x.x.

How to get the blink wifi on the 800 series units is to press the buttons above and below the Clean buttons which are Home and Spot.

Press and hold Home and SPOT Clean simultaneously for 2 seconds. Roomba will generate a tone and flash a green Wi-Fi icon

Hope this helps someone else . . .

Best, Jay

1 Like

Hi Alexander,

Now that I got the password for my 899 iRobot; I need to get MQTT setup correctly.

I’m new to MQTT and was wondering if could you share your mqtt.cfg and mqtt-eventbus.cfg with me?

I have no clue how I should configure these two?

Best, Jay