iRobot 9xx on openHAB

looks like you are missing opencv-python from your install. Try install this manually.

Just wondering if anyone has had an issue with the map? Iā€™ve tried everything, but the ā€œsizeā€ of the map does not allow the Roomba to map my entire floor. Is there a way to make the map size bigger (not the image size - if i make the image size bigger, it just stretched the map).

hi

i am blocked at ā€œWARNING: PIL version is 4.0.0, this is not the latest! you can get bad memory leaks with old versions of PILā€

in spite of sudo pip install Pillow
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Requirement already satisfied: Pillow in /usr/lib/python2.7/dist-packages (4.0.0)

Someone ???

CV or numpy module not found, falling back to PIL

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