Roomba

Aus FHEMWiki

Allgemeines

Die Reinigungsroboter Roomba von iRobot können via MQTT an FHEM gekoppelt werden. Dazu werden die Module MQTT2_CLIENT und MQTT2_DEVICE benötigt

Achtung: Work in progress

Produkte

Siehe Produktübersicht

Einbindung in FHEM

Die Roboter haben eine ungewöhnliche Software, diese enthält nämlich einen MQTT-Server (früher MQTT-Broker). Man kann sie also nicht als MQTT-Device bei einem MQTT-Server anmelden, sondern muss ein MQTT-Device schaffen, das sich bei dem internen MQTT-Server anmeldet.

Vorbereitung

Melden Sie den Roboter im WLAN an. Idealerweise lassen Sie ihm eine feste IP-Adresse im WLAN zuweisen. Derzeit ist es noch nicht möglich, den ersten fogenden Schritt innerhalb von FHEM zu tun. Gebraucht wird dazu noch eine externe Anwendung, dafür gibt es nachfolgend zwei Alternativen.

Python

Gehen Sie zur Anwendung Roomba980 . Installieren Sie diese nach dort zu findender Anleitung.
pip install paho-mqtt
pip install pillow
pip install six
pip install git+https://github.com/NickWaterton/Roomba980-Python.git 

Versetzen Sie den Roboter danach in den Anlernzustand. Welche Buttons auf dem Roboter dabei gedrückt werden müssen, entnehmen Sie bitte der Anleitung des Roboters. Während dieser Anlernzustand andauert, starten Sie bitte das Programm

python3 ~/Roomba980-Python/roomba/getpasswd.py

Das Ergebnis ist ein längerer Text ähnlich dem folgenden:

Received: {
"robotname": "Feger", 
"sku": "R981040", 
"nc": 0, 
"ver": "3", 
"proto": "mqtt", 
"ip": "192.168.0.xx", 
"hostname": "Roomba-31xxxxxxxxxx0", 
"sw": "v2.4.8-44", 
"mac": "70:66:xxxxxxxxxxx:6F", 
"cap": {
  "carpetBoost": 1, 
  "pp": 1, 
  "langOta": 1, 
  "binFullDetect": 1, 
  "ota": 2, 
  "maps": 1, 
  "pose": 1, 
  "eco": 1, 
  "multiPass": 2, 
  "edge": 1, 
  "svcConf": 1
}
}
Roomba (Feger) IP address is: 192.168.0.XX
blid is: 3###########0
Password=> :######################A <= Yes, all this string.
Use these credentials in roomba.py

Die fettgedruckten Strings sind IP-Adresse, blid und Passwort und sollten gut aufbewahrt werden.

JavaScript mit node.js

git clone https://github.com/koalazak/dorita980.git
cd dorita980
npm install
npm run getpassword 192.168.0.XX

Die Antwort ist nahezu identisch mit der oben beschriebenen Methode.

Einrichten eines MQTT Client

Definieren Sie in FHEM

define RoombaFegerClient MQTT2_CLIENT 192.168.0.XX:8883
attr RoombaFegerClient 
attr RoombaFegerClient    SSL        1
attr RoombaFegerClient    autocreate no
attr RoombaFegerClient    clientId   3###########0
attr RoombaFegerClient    disconnectAfter 5
attr RoombaFegerClient    mqttVersion 3.1.1
attr RoombaFegerClient    sslargs    SSL_version:SSLv23
attr RoombaFegerClient    username   31###########0

Ersetzen Sie bei den Attributwerten die IP-Adresse die clientId und den username durch den blid-String aus dem vorangehenden Schritt. Führen Sie dann mit dem aus dem vorangehenden Schritt notierten Passwort aus

set RoombaFegerClient password :######################A

Sie sollten jetzt schon in der Lage sein, sich durch

set RoombaFegerClient connect

mit dem Roboter zu verbinden, der Status des Client wechselt dabei für 5 Sekunden auf den Wert "connected". Klappt dies nicht, bitte bei diesem Client das Attribut verbose auf 5 setzen. Wenn Sie im Log eine Nachricht sehen, dass die SSL-Verbindung verweigert wurde, müssen Sie noch in der Datei \etc\ssl\openssl.conf in der passenden Sektion den fett markierten Eintrag vornehmen

 [ssl_default_sect]
   MinProtocol = TLSv1.2
   CipherString = DEFAULT:@SECLEVEL=1

vornehmen.

Einrichten eines MQTT Device

Definieren Sie in FHEM

define RoombaFeger MQTT2_DEVICE 3###########0
attr RoombaFeger IODev RoombaFegerClient
attr RoombaFeger devicetopic 3###########0
attr RoombaFeger readingList $DEVICETOPIC:.* { json2nameValue($EVENT) }
attr RoombaFeger setList start cmd {"command": "start", "time": 1, "initiator": "localApp"} \
 dock cmd  {"command": "dock", "time": 1, "initiator": "localApp"} \
 resume cmd  {"command": "resume", "time": 1, "initiator": "localApp"} \
 pause cmd  {"command": "pause", "time": 1, "initiator": "localApp"}

wobei natürlich wieder die oben erhaltene blid für die fett hervorgehobenen Strings eingesetzt wird. Sie erhalten dadurch ein Device, dass Sie mit FHEM-Kommandos starten und anhalten können. Wenn der Roboter läuft, meldet er eine Vielzahl von Daten an FHEM - und nicht alle davon sind informativ.

Roomba1.png

Komfortfunktionen für Readings

Das so erzeugte MQTT-Device hat eine Vielzahl von Readings, die gar nicht alle benötigt werden. Diese kann man vermeiden und durch eigene Readings ersetzen, indem der Attributwert auf

attr RoombaFeger readingList $DEVICETOPIC:.* {roomba::reading($NAME,$EVENT)}
attr RoombaFeger stateFormat cmPhaseE (battery %)

geändert wird. Dazu muss natürlich in einem Package roomba die Funktion reading() definiert werden, die je nach einlaufenden Daten entsprechende Readings erzeugt. Beispiel:

package roomba;
...
sub reading($$){
 my ($name,$evt) = @_;
 
 if( $evt =~ /state....reported....pose/){
   return pose($name,$evt);
 }else{
   my ($evt) = @_;
   main::Log 1,"[RoombaUtils] uncaught event ".$evt
     if( $evt ne "$name" );
   return
 }
}
...
sub pose($$){
 my ($name,$evt) = @_;
 my $hash = $main::defs{$name};
 
 #-- getting events of the type
 my $dec   = decode_json($evt);
 my $theta = $dec->{'state'}->{'reported'}->{'pose'}->{'theta'};
 my $px    = $dec->{'state'}->{'reported'}->{'pose'}->{'point'}->{'x'};
 my $py    = $dec->{'state'}->{'reported'}->{'pose'}->{'point'}->{'y'};
 ... 
 my %ret   = ("positionTheta",$theta,"position","(".$px.",".$py.")");
 return {%ret};
}

Mit dieser Funktion werden die Readings positionTheta und position erzeugt. Weitere Beispiele dafür, die einen komfortablen Satz von Readings erzeugen, finden Sie in FHEM, und zwar im Ordner fhem/contrib/Roomba in der Datei 99_RoombaUtils.pm. Wenn Sie diese Datei in den Ordner fhem/FHEM kopieren, wird sie beim Systemstart automatisch geladen und stellt dieses Package zur Verfügung.

Komfortfunktionen für set-Befehle

Die Eingabe von Konfigurationsdaten (z.B. ob Kantenreinigung erfolgen soll) oder Zeitplänen ist zwar prinzipiell mit dem "nackten" MQTT-Device auch möglich, aber nicht sehr komfortabel. Mit der Abänderung des Attributwertes auf

attr RoombaFeger setList start:noArg {roomba::command($NAME,"start",$EVENT)} \
 stop:noArg {roomba::command($NAME,"stop",$EVENT)} \ 
 dock:noArg {roomba::command($NAME,"dock",$EVENT)} \
 resume:noArg {roomba::command($NAME,"resume",$EVENT)} \
 pause:noArg {roomba::command($NAME,"pause",$EVENT)} \
 CarpetBoost:true,false {roomba::setting($NAME,"carpetBoost",$EVENT)} \
 TwoPass:true,false {roomba::setting($NAME,"twoPass",$EVENT)} \
 NoAutoPasses:true,false {roomba::setting($NAME,"noAutoPasses",$EVENT)} \
 NoPP:true,false {roomba::setting($NAME,"noPP",$EVENT)} \
 VacHigh:true,false {roomba::setting($NAME,"vacHigh",$EVENT)} \
 BinPause:true,false {roomba::setting($NAME,"binPause",$EVENT)} \
 OpenOnly:true,false {roomba::setting($NAME,"openOnly",$EVENT)} \
 ProgHold:true,false {roomba::setting($NAME,"schedHold",$EVENT)} \
 ProgSun:time {roomba::setsched($NAME,0,$EVENT)} \
 ProgMon:time {roomba::setsched($NAME,1,$EVENT)} \
 ProgTue:time {roomba::setsched($NAME,2,$EVENT)} \
 ProgWed:time {roomba::setsched($NAME,3,$EVENT)} \
 ProgThu:time {roomba::setsched($NAME,4,$EVENT)} \
 ProgFri:time {roomba::setsched($NAME,5,$EVENT)} \
 ProgSat:time {roomba::setsched($NAME,6,$EVENT)} \
 maplist:noArg {roomba::setting($NAME,"local:cmMapList={listmaps('$NAME')}",$EVENT)} \
 mapdel {roomba::setting($NAME,"local:cmMapList={delmap('$NAME','$EVENT')}",$EVENT)} 

und den dazu in 99_RoombaUtils.pm zur Verfügung gestellten Funktionen geht das sehr viel einfacher.

Maps