Homematic: Push-Nachricht versenden

Mit 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!

Die Kommentarfunktion ist derzeit geschlossen.