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