Homematic: Push-Nachricht versenden
kai am 16. Mai 2019 um 11:16Mit der neuen CCU3 ist auch meine Begeisterung für Homematic wiedererwacht. Es ist einiges in Planung und im ersten Schritt habe ich mich entschieden von einer Benachrichtigung per Mail auf Push-Nachrichten umzusteigen.
Mit einem Dienst wie PushOver ist dies recht einfach und nahezu kostenfrei umsetzbar (lediglich die App kostet nach einer gewissen Zeit einmalig etwas Geld).
Nun sollte es aber die full-featured Lösung sein. Also nicht nur einfach eine Text-Nachricht, sondern die komplette (für mich sinnvolle) API von PushOver sollte unterstützt werden.
„Im Code steht die Wahrheit“, daher legen wir los…
!__Pushover Keys string po_api_user="XXX"; string po_api_token="YYY"; !__Nachricht string po_title= dom.GetObject("PushOver_Subject").Value(); string po_message= dom.GetObject("PushOver_Text").Value();
Die Key’s für den Zugriff auf PushOver bekommt ihr, wenn ihr Euch dort anmeldet. Die speichern wir in je einer Script-Variablen.
Die eigentliche Nachricht lesen wir aus vorher angelegen Systemvariablen aus. Diese sind beide als Zeichenkette angelegt:
- PushOver_Subject
- PushOver_Text
string po_file="-1"; if(dom.GetObject("PushOver_File").IsVar()){ po_file = dom.GetObject("PushOver_File").Value(); }
Nun prüfen wir, ob ein Anhang mitgesendet werden soll. Das muss ein Bild sein, und auch kleiner als 2,5MB (Vergleiche PushOver-API).
Auch dieses müssen wir vorher in eine Systemvariable (Zeichenkette) schreiben. Hier natürlich nur den Pfad zu der Datei, nicht die Daten selbst.
Die Prüfung mittels .IsVar() bietet die (saubere) Möglichkeit, das Script auch zu nutzen, wenn es die Systemvariable nicht gibt. Sie muss also nur angelegt werden, wenn man Bilder verschicken will.
string po_priority = "0"; if(dom.GetObject("PushOver_Priority").IsVar()){ string po_priority= dom.GetObject("PushOver_Priority").Value(); }
Weiter geht es mit der Priorität der Nachricht. Hier haben wir verschiedene Stufen:
- 0=Normal
- 1=High (AudioVibration auch waehrend quiet hour)
- 2=Emergency (Meldung Muss bestätigt werden, solange sound/Vibration)
- -1=Low
- -2=Lowest
Ich verwende nur 0 für alle Informationen und 2, wenn ein Rauchmelder ausgelöst hat.
string po_retry="0"; string po_expires="0"; if(po_priority=="2"){ po_retry = "30"; ! -- alle 30 Sekunden erneute Benachrichtigung po_expires = "3600"; ! -- nach einer Stunde keine neue Benachrichtigung, Message bleibt ungelesen }
Wenn die Prioritär auf „Emergency“ steht, kann man mit weiteren Parameter die Dringlichkeit definieren. Mittels „retry“ ist zu definieren, in welchen Zeitabständen der User erneut eine Benachrichtigung bekommt, bis er diese bestätigt hat. Mit „expires“ definieren, wir wann das Nerven ein Ende hat. Beide Angaben sind in Sekunden zu definieren.
string po_sound = "pushover"; ! -- let it be the default if(dom.GetObject("PushOver_Sound").IsVar()){ string sounds = "pushover;bike;bugle;cashregister;classical;cosmic;falling;gamelan;incoming;intermission;magic;mechanical;pianobar;siren;spacealarm;tugboat;alien;climb;persistent;echo;updown;none"; integer idx = dom.GetObject("PushOver_Sound").Value(); po_sound = sounds.StrValueByIndex(";", idx); }
Nun wird es laut. Ich habe eine Systemvariable „PushOver_Sound“ die eine Werteliste ist. Über diese kann ein „Sound“ auch in einem Programm ausgewählt werden:

Die Systemvariable enthält dann nur den Index, welchem man in den Parameter für PushOver übersetzen muss. Daher die Ermittlung des Listenelements aus „sounds“ (muss mit Inhalt der Systemvariablen übereinstimmen!) per StrValueByIndex.
Nun haben wir alles zusammen, was wir brauchen und können das Kommando zusammenbauen:
string po_request = "/usr/local/addons/cuxd/extra/curl -s -k"; ! --inital command po_request = po_request # " --form-string \"token="#po_api_token#"\" "; po_request = po_request # " --form-string \"user="#po_api_user#"\" "; po_request = po_request # " --form-string \"message="#po_message.ToUTF8()#"\" "; !--Use UriEncode to get the Umlauts running po_request = po_request # " --form-string \"title="#po_title.ToUTF8()#"\" "; po_request = po_request # " --form-string \"sound="#po_sound#"\" "; ! -- Always, default is 0 po_request = po_request # " --form-string \"priority="#po_priority#"\" "; !--Optionals if(po_priority == "2"){ po_request = po_request # " --form-string \"retry="#po_retry#"\" "; po_request = po_request # " --form-string \"expire="#po_expires#"\" "; } if(po_file != "-1"){ !# -- Use -F here for upload function of curl po_request = po_request # " -F \"attachment=@"#po_file#"\" "; } po_request = po_request # " https://api.pushover.net/1/messages.json";
Ich verwende hier das für mehrere Parameter – meiner Ansicht nach – besser lesbare Format mit „form-string“. So kann ich alle Parameter in beliebiger Reihenfolge anhängen. Die optionalen weglassen wenn sie nicht gebraucht werden und auch die spezielle Option für den Upload des Bildes (-F -> FileUpload via curl) nutzen.
Wichtig ist noch, die Freitexte richtig zu encodieren. Hierzu bietet die CCU (seit Version 2.29.22 (September 2017)) die Möglichkeit, „.ToUTF8()“ zu verwenden. Was eine universelle Codierung ist und auch Umlaute und Sonderzeichen erlaubt.
Was bleibt nun noch über …
dom.GetObject("CUxD.CUX2801001:1.CMD_EXEC").State(po_request);
Raus damit!