HTTP-Steuerung per Hausautomation

skippa1978

Active member
Da MQTT am Alfred noch nicht wirklich brauchbar ist, suche ich nach alternativen Wegen, die Steuerung in meine Hausautomation (in dem Fall FHEM mit HTTPMOD einzubinden). Es gibt auch die Möglichkeit, Befehle per HTTP abzusetzen, soviel ist mir schon bekannt. Ich poste das hier im Übrigen nicht im Alfred-Forum, da die HTTP Befehle nicht auf Alfred beschränkt sind.

Wie kann man per HTTP folgendes machen?

  • Starten
  • Stoppen
  • Dock
  • gehen auch get-Abfragen wichtiger Status, wie:
    • Position​
    • aktueller Status (charge, mow, dock, error, idle)​
    • Solution (fix, float, invalid)​
  • Perfekt wäre, wenn man auch Kartenwechsel per HTTP vornehmen könnte...aber das ist schon ein großer Aufwand.


Danke!
 
Wobei das mittelfristig ja mal auf dem Roboter (= in dem Fall Alfred) passieren soll, wie ich an anderer Stelle gelesen habe. Also alle Karten auf dem Alfred und ein Wechsel geht dort per Knopfdruck. Sinnvoll wäre es jedenfalls.
 
Hallo Skippa,

grundsätzlich kann man fast alles mit den HTTP Requests machen. Warum fast, dass was in der App intern gemacht wird, kann auch nicht mittels HTTP Requests realiesiert werden.

Die Sunray App kommuniziert mit dem Ardumower/Alfred mittels POST-Requests. Diese werden in FHEM vom HTTPMOD-Modul unterstützt, so dass die Steuerung und Statusabfrage (das was in der Sunray angezeigt wird) funktioniert. Um sich viel Arbeit zu ersparen emfehle ich dir in der config.h vom Alfred folgende Einstellung:
Code:
//#define ENABLE_PASS   1
Also Passwortabfrage zu deaktivieren, dann kommuniziert Alfred mit der Sunray App/FHEM in Klartext. Wenn du dir Sorgen wegen der Sicherheit machst, sind diese unbegründet, da die Kommunikation in deinem lokalen Netz stattfindet und dieses ist hoffentlich mit Wifi Sicherheitsstandarts abgesichert.
Also ab jetzt die Vorgehensweise mit deaktivierten Passwortabfrage.

Leg dir in FHEM ein HTTPMOD-Device an:
Code:
define Alfred HTTPMOD none 0
Aktiviere für Fehlersuche folgende Attribute:
Code:
showBody 1
showError 1
Diese kannst du später, wenn alles läuft wieder auf 0 setzen

Als erstes versuchen wir den Status des Mähers abzufragen (Das macht Sunray App ca. alle 2s).
Lege dir folgende Attribute an:
Code:
get01Data  AT+S,0x13
get01Name  http_summary
get01URL   http://192.168.IP-vom-Alfred/

Jetzt zur Erklärung. AT+S ist eigentlicher Befehl an Alfred, sende mir deinen Status. 0x13 ist die Checksumme über den AT+S String, da es immer AT+S ist, müssen wir diesen nicht immer wieder neueberechnen, die Checksumme ist in diesem Fall immer gleich. Wenn du jetzt get http_summary aufruffst, müsste im Body irgendwas mit S,und vielen Zahlen dahinter kommen. Wenn nichts kommt, versuche in dem Attribut get01Data hinter 13 einen Leerzeichen zu setzen (ich hatte hier Probleme mit der Botschaftslänge.)

Wenn das klappt, dann können wir, wie folgt weiter
In dem empfangenen S-String stecken diverse Informationen, die dem enzelnen Reading zugeordnet werden können. An der ersten Stelle steht Batteriespannung, an der zweiten Position (x-Achse), an der dritten Position (y-Achse) usw. Um diese in FHEM dem richtigen Reading zuzuordnen, muss man mit regulären Ausdrucken arbeiten, hier empfehle ich dir folgende Seite, dort kann man seinen Ausdruck ganz gut testen bevor du ihn produktiv schaltest:
https://regex101.com/

So fangen wir mit Batteriespannung an, lege folgende Attribute an:
Code:
reading01Name batteryVoltage
reading01Regex S,([\d\.]+)

reading01Name ist natürlich frei wählbar. reaading01Regex ist der regulärer Ausdruck (quasi an welcher Stelle im zurückgeliefrtem String die Spannung zu suchen ist).
Um die Größe regelmäßig abzufragen (wie gesagt Sunray App macht es ca. alle 2s) müsstest du deine Definition von ganz oben etwas anpassen, ändere die 0 auf die Zeit die du gerne als Intervall Abfrage haben möchtest (z.B. alle 10s):
Code:
define Alfred HTTPMOD none 10
und ergänzte noch ein folgendes Attribut:
Code:
get01Poll 1

Da ich für die AT+S Abfrage damals schon alles an regulären Ausdrücken angelegt habe, ist das für dich ein leichtes Spiel die zu übernehmen, hier ist meine damalige Dfinition:
Code:
   reading01Name batteryVoltage
   reading01Regex S,([\d\.]+),
   reading02Name stateX
   reading02Regex S,[\d\.]+,(-?[\d\.]+)
   reading03Name stateY
   reading03Regex S,[\d\.]+,-?[\d\.]+,(-?[\d\.]+)
   reading04Name stateDelta
   reading04Regex S,[\d\.]+,-?[\d\.]+,-?[\d\.]+,(-?[\d\.]+)
   reading05Name gps.solution
   reading05Regex S,[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,(-?[\d\.]+)
   reading06Name stateOp
   reading06Regex S,[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,(-?[\d\.]+)
   reading07Name mowPointsIdx
   reading07Regex S,[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,(-?[\d\.]+)
   reading08Name dgpsAge
   reading08Regex S,[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,(-?[\d\.]+)
   reading09Name stateSensor
   reading09Regex S,[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,(-?[\d\.]+)
   reading10Name targetPoint.x
   reading10Regex S,[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,(-?[\d\.]+)
   reading11Name targetPoint.y
   reading11Regex S,[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,(-?[\d\.]+)
   reading12Name gps.accuracy
   reading12Regex S,[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,(-?[\d\.]+)
   reading13Name gps.numSV
   reading13Regex S,[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,(-?[\d\.]+)
   reading14Name batteryCurrent
   reading14Regex S,[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,(-?[\d\.]+)
   reading15Name gps.numSVdgps
   reading15Regex S,[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,(-?[\d\.]+)
   reading16Name mapCRC
   reading16Regex S,[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,(-?[\d\.]+)
   reading17Name lateralError
   reading17Regex S,[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,-?[\d\.]+,(-?[\d\.]+)

Wenn es bis dahin alles klappt, kann man versuchen weitere Werte aus dem Mower auszulesen. Hierzu gibt es noch zwei Befehle.
Code:
AT+V
AT+T

Über AT+V bekommt man einige Informationen, die über Laufzeit sich nicht ändern (FW Version etc). Über AT+T bekommt man die Statistikdaten. Die Befehle muss man analog dem AT+S in die get Attribute verpacken.
Code:
get02Data  AT+T,0x14
get01Name  http_statistic
get02URL   http://192.168.IP-vom-Alfred/
[/CODE]

Der Antwortstring für AT+T fängt mit T an, also müssen die Regex entsprechend angepasst werden. Die Checksumme hat sich auch geändert, da wir einen anderen String Richtung Alfred schicken. Hier empfehle ich diese Seite:
https://www.scadacore.com/tools/programming-calculators/online-checksum-calculator/

Dort unter ASII Input unseren String eingeben (z.B. AT+T) und dann AnalyzeDataAscii. Für uns die richtige Checksumme steht unter CheckSum8 Modulo 256.

Jetzt haben wir alles an Daten aus dem Alfred geholt was die comm.cpp unterstützt.

Im nächsten Schritt kann man ein Paar Befehle absetzen. Hierzu legt man im HTTPMOD-Modul folgende Attribute:
Code:
[CODE]set01Data  AT+C,-1,1,0.2,100,0,-1,-1,1,0x30
set01Name  start
set01URL   http://192.168.IP-vom-Alfred/
[/CODE]

Erläterung:
AT+C: Befehl an Alfred tue was
1 Stelle: Mow Motor an (1) oder aus (0) (Wir übergeben -1, also keine manuelle Steuerung)
2 Stelle: Was getan werden soll (0:Stop, 1: Mow, 4:dock) (Wir übergeben 1)
3 Stelle: Mit Welcher Geschwindigkeit gemäht werden soll (0.2m/s)
4 Stelle: fix timeout (nach 100s ohne fix wird timeout gesetzt)
5 Stelle: finish and restart (ja oder nein, den Sinn dieser Funktion verstehe ich nicht, mit -1 wir ein ngültiger Wert übergeben, also es wird gemacht was in der config definiert ist)
6: Stelle: Set mowing Point in percent (wenn hier etwas zwischen 0 und 100 übergeben wird, wird der Mow-Vorgang abgebrochen, hiermit kann man gezielt die Stelle einstellen ab wo gemäht werden soll, danach muss der Mow Vorgang gestartet werden)
7 Stelle: Skip next mow point (wenn 1 wird Mow Vorgang gestopt, es muss neuegestartet werden)
8 Stelle: Sonar enable (1 oder 0, beim Alfred sielt keine Role was übergeben wird)

Ein deutlicher Vorteil gegenüber dem Start über MQTT ist zum Beispiel die Geschwindigkeit, die individuell angepasst werden kann. Beim MQTT Start wird die Geschwindigkeit übernommen, die MQTT Programmierer in den Start Befehl hinterlegt hat. Hier kann alles frei in dem set Attribut angepasst werden.

Daraus ergeben sich folgende AT+C Kombinationen:
stop: AT+C,-1,0,-1,-1,-1,-1,-1,-1
dock: AT+C,-1,4,-1,-1,-1,-1,-1,-1
Die Checksummen müssen natürlich hier neue berechnet werden

Abschliessend betrachtet kann man sagen der Alfred/Ardumower lässt sich wunderbar über HTTP steuern. Hierzu werden POST-Requests genutzt. Das Steuerbefehl wird mit im Header übergeben. Zu beachten wäre, man muss zusammen mit den Daten die Checksumme übergeben (CheckSum8 Modulo 256).

Hier noch mal die weiteren Befehle die von comm.cpp unterstützt werden:
AT+Y: Reboot robot
AT+Y2: Reboot GPS
AT+Y3: Shutdown robot
AT+M,lateral_Speed,angular_Speed: manual control (Joystik)
AT+E: Motor test (Rover aufbocken, Die Räder machen 10 Umdrehungen, letzte halbe Umdrehung langsam)
AT+Q: Motor test + plot (ACHTUNG!! Mähmotor wird mit angesteuert, Rover aufbocken!). Der Test macht nur sinn in Verbindung mit dem seriellen Plot, damit die Verläufe der Odometrie mit ausgewertet werden können.
AT+F: Sensor test (Dauer 60s). In dieser Zeit kann Bumper, Lift und Sonar Sensor von Hand (Karosse anheben etc.) getriggert werden (In der seriellen Konsole, bzw. beim Alfred im journal kann geschaut werden, ob der Sensor auch ausgelöst hat)
AT+W,idx,30xmap_points: Upload map_points (Alle Map-Punkte hintereinander weg an den Rover übertragen, 30 Wertepaare (x,y) pro Post Request, idx wächst um 30 an: 0,30,60,90usw. Abfolge: Perimeter, Exclusion, Dock, Waypoints)
AT+N,perimeter,exclusion,docking,waypoints,0: Folgt unmittelbar nach AT+W, und übergibt die Anzahl der Perimeterponts, Exclusionen, Dockpoints, Waypoints und gefolgt von 0
AT+X,first_exclusion,second_exclusion...: Folgt unmittelbar nach AT+N und enthält die Anzahl an Punkten für die jeweilige Exclusion
....

Sollte mir noch was einfallen, ergänze ich es hier


...
to be contuned...
 
Zuletzt bearbeitet:
Das klappt gut. Es gibt hin und wieder empty response aber das liegt am fehlerhaften WLAN bei Alfred. Danke erstmal bis dahin. RegExe könnte man sicher noch ein wenig vereinfachen aber erstmal ist das gut so
 
Oben