Neues Modul cmdRouter zur zentralen Verwaltung von FHEM-Kommandos

Begonnen von peterk_de, 28 Juni 2017, 15:17:17

Vorheriges Thema - Nächstes Thema

peterk_de

Ich habe mich endlich einmal dazu durchgerungen, mich in die FHEM-Modul-API einzuarbeiten und mein erstes FHEM-Modul zu schreiben. Was es tut? Sowas hier:

Definition:

defmod router cmdRouter
attr router cmd_SEND set pushoverDevice msg Hallo Welt! device='empfaenger'


Benutzung (im DOIF, Notify, ...):

set router exec cmd_SEND empfaenger='iPhone_Peter'

Ergebnis (wird durch FHEM ausgeführt):

set pushoverDevice msg Hallo Welt! device='iPhone_Peter'

Das ist das (einfache) Grundprinzip. Und damit geht noch einiges mehr ...




Allgemeine Beschreibung

Das Modul erlaubt es, beliebige vordefinierte Kommandos (FHEM oder Perlcode) an zentraler Stelle zu speichern und später über einen selbstgewählten Shortcut auszuführen. Die Nutzungsmöglichkeiten gehen dabei in Richtung des msg-Befehls, allerdings ist das Modul nicht auf das Versenden von Messages beschränkt und verfolgt in der Konfiguration einen völlig anderen Ansatz:


  • Das Modul ist zunächst einmal für das einfache Wegspeichern z.B. längerer fertiger Kommandozeilen geeignet, die man häufig in Notifies, DOIFs etc. verwendet und an zentraler Stelle pflegen möchte, falls man sie einmal ändern möchte. Besonders gut geeignet ist es dadurch natürlich für Benachrichtigungen jeder Art (Lampe blinken lassen, Pushnachricht, ...).
  • Es erlaubt dabei Ersetzungen in diesen Kommandos (also sozusagen das Speichern von Kommando-Templates mit selbstgewählten Platzhaltern, die man beim Aufruf mit Werten/Texten etc. ergänzt). Damit können den gespeicherten Kommandos Parameter übergeben werden (z.B. bei jedem Aufruf verschiedene Texte, Werte aktueller Readings etc.)
  • Zudem kann man mit einfachen Regeln (,,Routen") definieren, ob/wann/mit welchen Ersetzungen ein Kommando ausgeführt wird - oder kann sogar über Perl-Code die erwähnten Template-Ersetzungen von äußeren Umständen (Zeit, Readings, ...) abhängig machen.
  • Befehl-Templates für Geräte, die vom MSG-Befehl unterstützt werden (das sind viele), können sogar einfach per Mausklick angelegt (und dann ggf. angepasst) werden.

Das ganze skaliert von ,,super simpel" wie das Beispiel oben bis hin zur Verwaltung von dutzenden Befehlen, die von 100+ DOIFs/Notifies genutzt werden.

Meine Motivation: Der msg-Befehl

Zu viele Notifies, DOIFs und sonstige Regeln, die alle irgendwie irgendwelche FHEM-Kommandos aufrufen - hauptsächlich Benachrichtigungen über Push-Nachrichten, oder ein blinkendes Deckenlicht, eine Einblendung in Kodi (aber nur, wenn der TV läuft bitte!), auf den Wand-Tablets (aber nur, wenn die Alarmanlage nicht scharf ist), Sprachdurchsagen (nur wenn jemand zu Hause ist, außer nachts) usw.

Nun gibt es dafür ja den msg-Befehl, aber mit dem bin ich nicht warm geworden, u.a. weil er mir durch die vielen speziellen(Syntax-)Konstrukte für vordefinierte Devicetypen/Benachrichtigungsarten/Routingregeln/FollowMe/Wasweißich einfach zu undurchsichtig ist und ich RESIDENTS und Co. nicht nutze...  Ich wollte aber lieber etwas schlankes, allgemeineres, anpassbareres, was nicht mit diversen Parametern und Optionen überladen ist, die ich nicht nutzen will - und andere dafür vielleicht fehlen (bzw. ich zu faul war, zu suchen, wie es geht ;-).

Das Modul ist im fortgeschrittenen Beta-Stadium - vielleicht kann es ja jemand gebrauchen:-) Bei mir tut es aber schon eine Weile seinen Dienst zufriedenstellend.




Doku und Tutorial anhand von Beispielen

Alle Beispiele sind so ,,fertig" - copy und paste und los! Tipp: oben anfangen, mit jedem Schritt wirds schwerer  ^^. Ab Schritt 11 sind Perl-Grundkenntnisse nötig.

0. Definition

Das cmdRouter-Device wird zunächst einmal ohne weitere Parameter definiert:

defmod myCmdRouter cmdRouter

Basics 1 - Speicherung und Ausführung von Kommandos

Im simpelsten Fall speichert man im Device einfach vollständige FHEM-Commandos als Attribute (der Attributname muss mit cmd_ anfangen).

defmod myCmdRouter cmdRouter
attr myCmdRouter cmd_BlinkOben set lampeOben an;;sleep 2;;set lampeOben aus
attr myCmdRouter cmd_BlinkUnten set lampeUnten an;;sleep 1;;set lampeUnten aus


Hier im Beispiel sind gleich 3 Befehle mit Semikolon verkettet, um eine Sequenz zu erzeugen. Die verdoppelten Semikolon (ohne Leerzeichen dahinter) sind hier wichtig, damit FHEM beim ausführen des attr-Befehs weiß, dass das alles zu dem attr-Befehl gehört. Ausführen kann man die Kommandos dann z.B. mit :

set myCmdRouter exec cmd_BlinkOben

Das ist jetzt noch nicht sonderlich beeindruckend und lässt sich auch gut mit Notifies lösen. Aber damit nutzt man auch nur einen Bruchteil der vorhandenen Funktionalität

Basics 2 - ,,Template"-Ersetzungen in gespeicherten Kommandos: Parameter

Man kann beim Aufruf den Kommandos (beliebig viele) Parameter mitgeben - diese werden dann im gespeicherten Befehl ersetzt. Im Beispiel von eben z.B. die Dauer des Einschaltens der Lampe. Parameter können zur besseren Lesbarkeit in Prozentzeichen eingeschlossen werden (sowohl beim Aufruf als auch im gespeicherten Kommando), müssen sie aber nicht:

defmod myCmdRouter cmdRouter
attr myCmdRouter cmd_BlinkOben set lampeOben an;;sleep %sleepDuration%;;set lampeOben aus


Ausführung dann folgendermaßen (getrennt werden die Kommandos und Parameter jeweils mit Leerzeichen):

set myCmdRouter exec cmd_BlinkOben sleepDuration='3'

Ergebnis:

set lampeOben an;sleep 3;set lampeOben aus

Setzt man den Parameter im gespeicherten Kommando in %-Zeichen, hat man einen Vorteil: cmdRouter löscht den Platzhalter dann nämlich heraus, wenn man ihn beim Aufruf nicht mit irgendeinem Wert füllt. Sonst bleibt er so wie er ist einfach drin:

defmod myCmdRouter cmdRouter
attr myCmdRouter cmd_Dim1 set lampeOben pct %percent% %ramptime%
attr myCmdRouter cmd_Dim2 set lampeUnten pct percent ramptime

set myCmdRouter exec cmd_Dim1 percent='50'
set myCmdRouter exec cmd_Dim2 percent='60'


Ergebnis:

set lampeOben pct 50
set lampeUnten pct 60 ramptime


Basics 3 - Ausführung mehrerer gespeicherter Kommandos auf einmal

Nach dem ,,exec" können beliebig viele Kommandos auf einmal ausgeführt werden. Das ganze kann auch mit beliebig vielen Parametern kombiniert werden. Die Parameter, die man beim Aufruf mit einem Wert versieht, werden in allen Kommandos ersetzt, in denen sie enthalten sind:

defmod myCmdRouter cmdRouter
attr myCmdRouter cmd_BlinkOben set lampeOben an;;sleep %sleepDuration%;;set lampeOben aus
attr myCmdRouter cmd_BlinkUnten set lampeUnten an;;sleep %sleepDuration%;;set lampeUnten aus


Ausführung dann folgendermaßen. Die Reihenfolge beim Aufruf ist dabei prinzipiell egal:

set myCmdRouter exec cmd_BlinkOben cmd_BlinkUnten sleepDuration='3'

Ergebnis:

set lampeUnten an;sleep 3;set lampeUnten aus
set lampeOben an;sleep 3;set lampeOben aus


Noch ein Hinweis zur Reihenfolge der Ausführung: Diese lässt sich nicht definieren und kann von Aufruf zu Aufruf variieren - das Modul ist also NICHT geeignet, um mehrere Kommandos in einer definierten Reihenfolge abzuarbeiten! Auch wartet ein Befehl nicht auf den Abschluss des nächsten, im Beispiel werden sich die Lampen also (fast) gleichzeitig für 3 Sekunden einschalten - mal lampeOben einen Sekundenbruchteil früher, mal lampeUnten. Umgehen lässt sich das dadurch, dass Kommandosequenzen ggf. mit sleep als ein Kommando gespeichert werden (wie im Beispiel).

4. Ein gespeichertes Kommando automatisch mit verschiedenen Parametern ausführen lassen: ,,Multi-Parameter"

Der cmdRouter kann automatisch mehrere Aufrufe für ein gespeichertes Kommando erzeugen und für jeden Aufruf eine andere Parameter-Ersetzung vornehmen. Dazu hängt man an einen Parameter (oder an mehrere, aber Achtung!) beim Aufruf einfach _1, _2 usw. an. Damit kann man in unserem Beispiel einfach verschiedene Lampen blinken lassen:

defmod myCmdRouter cmdRouter
attr myCmdRouter cmd_Blink set %lampenName% an;;sleep %sleepDuration%;;set %lampenName% aus


Ausführung dann folgendermaßen: Die Nummer, die angehängt wird, ist prinzipiell egal, muss aber jeweils eine andere positive Ganzzahl sein. Wichtig ist der Unterstrich davor. Parameter ohne Nummer am Ende werden wie bei Basics 3 überall mit dem gleichen Wert ersetzt.

set myCmdRouter exec cmd_Blink sleepDuration='3' lampenName_1='lampeKueche' lampenName_2='lampeFlur'

Ergebnis:

set lampeKueche an;sleep 3;set lampeKueche aus
set lampeOben an;sleep 3;set lampeFlur aus


Dies ist z.B. auch nützlich, wenn man für das Versenden von Push-Nachrichten über ein und dasselbe Komando mehrere Empfänger angeben möchte.

5. Aufrufe von Kommandos mitsamt Parametern speichern: Routen

Um die Flexibilität vom cmdRouter extrem zu steigern, kann man das, was wir vorher als ,,Aufruf" von set ... exec ausgeführt haben (also Kommando-Kürzel und Parameter-Werte zur Ersetzung), ebenfalls als Attribut speichern. Das nennt sich dann ,,Route" - entsprechende Attributnamen müssen mit route_ beginnen:

defmod myCmdRouter cmdRouter
attr myCmdRouter cmd_Blink set %lampenName% an;; sleep %sleepDuration%;; set %lampenName% aus
attr myCmdRouter route_BlinkAll cmd_Blink lampenName_1='lampeKueche' lampenName_2='lampeFlur'


In diesem Beispiel ,,setzt" die route_BlinkAll Werte für den Parameter %lampenName% (und zwar wie unter 4. beschrieben, als Multi-Parameter), nicht jedoch %sleepDuration%. Dieser kann (muss) dann direkt beim Aufruf gesetzt werden, damit er auch ersetzt wird:

set myCmdRouter exec route_BlinkAll sleepDuration='5'

Ergebnis:

set lampeKueche an;sleep 5;set lampeKueche aus
set lampeOben an;sleep 5;set lampeFlur aus


6. a) Verschachtelung von Routen

Die Routen aus 5. können selbst wieder Routen ,,aufrufen". Dies ist nützlich, um sich selbst beliebige Abstraktionsebenen zu schaffen. So können z.B. bei vielen Kommandos oder Parametern verschiedene Kombinationen aus diesen zusammengestellt und später sehr einfach angepasst werden. Ein einfaches Beispiel (Erweiterung von 5.):

defmod myCmdRouter cmdRouter
attr myCmdRouter cmd_Blink set %lampenName% an;;sleep %sleepDuration%;;set %lampenName% aus
attr myCmdRouter route_BlinkAll cmd_Blink lampenName_1='lampeKueche' lampenName_2='lampeFlur'
attr myCmdRouter route_BlinkAllShort route_BlinkAll sleepDuration='1'


In diesem Beispiel ,,inkludiert" route_BlinkAllShort die Route ,,route_BlinkAll" und ergänzt den Parameter für die Einschaltdauer. Die Ausführung ist dann ganz einfach:

set myCmdRouter exec route_BlinkAllShort

Ergebnis:

set lampeKueche an;sleep 1;set lampeKueche aus
set lampeOben an;sleep 1;set lampeFlur aus


Man kann prinzipiell beliebig tief verschachteln, also eine Route definieren, die eine Route enthält, die wieder eine Route enthält, ... . Da man damit aber theoretisch eine Endlosschleife erzeugen kann, wird standardmäßig nach 10 Verschachtelungen abgebrochen und das Reading lastError entsprechend gesetzt. Über das Attribut maxRouteDepth kann man dieses Limit bei Bedarf erhöhen.

6. b) Standardwerte für Parameter per Verschachtelung von Routen definieren

Parameter können mit einem Defaultwert ,,vorbelegt" werden - das funktioniert über Routen, da sich gleichnamige Parameter in einer definierten Reihenfolge überschreiben:

defmod myCmdRouter cmdRouter
attr myCmdRouter cmd_Blink set lampeOben an;; sleep %sleepDuration%;; set lampeOben aus
attr myCmdRouter route_Blinker1 cmd_Blink sleepDuration='1'
attr myCmdRouter route_Blinker2 route_Blinker1 sleepDuration='3'


Aufruf 1:
set myCmdRouter exec route_Blinker1 sleepDuration='5'
—> 5 Sekunden sleep, 5 überschreibt 1

Aufruf 2:
set myCmdRouter exec route_Blinker2
—> 3 Sekunden pause, also wie in route_Blinker2  angegeben (kommt in der Aufrufreihenfolge vor route_Blinker1 dran) definiert

Es gilt also immer der Parameter-Wert, der ,,am nächsten" beim getätigten set ... exec-Aufruf ist. Im Zweifelsfall also der, den man beim set direkt mitgibt.

7. Debugging: Routen vor der eigentlichen Ausführung testen / Debug-Readings erzeugen

Über die Verschachtelung von Routen (6.) und die Multi-Parameter (4.) kann man schon sehr komplexe Regelwerke bauen (Vorwarnung: es wird noch besser ;-)). Verwendet man beim set-Aufruf statt ,,exec" das Wort ,,test", so arbeitet der cmdRouter die Route ab, führt die generierten Kommandos dann aber nicht aus:

set myCmdRouter test route_BlinkAllShort

Stattdessen werden die Kommandos, die ausgeführt werden würden, in das Reading lastTestCmds geschrieben. Außerdem werden die Readings lastTestCall (der getätigte Aufruf) und lastTestRoute (die ,,aufgelöste" Route) erzeugt. Über das Attribut createDebugReadings kann man entsprechende Readings aber auch für alle exec-Aufrufe erzeugen (per default aus).

8. Kommandos und Routen für diverse Geräte automatisch erzeugen

Zu allen vom MSG-Befehl unterstützten Devicetypen kann ein Kommando bzw. eine Route per Mausklick in FHEM-Web (oder per Set-Befehl) angelegt werden. Dazu einfach oben auf der Detailseite des cmdRouter-Devices "generateMessageRoutes" wählen. Daneben erscheint ein DropDown-Menü mit allen bei sich selbst definierten FHEM-Devices, die unterstützt werden. Wenn das Device mehrere Benachrichtigungsarten unterstützt (z.B. Bildschirmnachricht und Audio-Mitteilung beim AMAD-Modul), kann man hier auch auswählen, wofür ein Befehl angelegt werden soll.

Es wird dann immer ein Kommando und eine Route angelegt. Ruft man die Route auf, sind alle Default-Parameter des Message-Befehls schon hinterlegt.

Achtung, dieses Feature ist das "frischeste" des Moduls. Es wird nur der MSG-Prioritätstyp "Normal" unterstützt.

9. Default-Route: route_Default

Stößt der cmdRouter auf eine unbekannte Routenbezeichnung, so wird ein Fehler ins FHEM-Log geschrieben und stattdessen die Default-Route mit dem Namen route_Default verwendet. Diese hat als vordefinierten Inhalt wiederum das Kommando cmd_Default (siehe 10.).

Über das Attribut route_Default kann man dieses Standardverhalten ändern, was extrem sinnvoll sein kann:

defmod myCmdRouter cmdRouter
attr myCmdRouter cmd_Pushover set pushoverDevice msg msgtext device='pushOverDevice'
attr myCmdRouter route_PushPeter cmd_Pushover pushOverDevice_1='iPhone_Peter'
attr myCmdRouter route_Default route_PushPeter


Ab jetzt kann man beliebige nicht vorhandene Routen in seinen Notifies, DOIF-Skripten etc. verwenden - Peter bekommt trotzdem immer eine Push-Nachricht:

set myCmdRouter exec route_BackofenFertig msgtext='Der Backofen ist vorgeheizt!'

Hat man zudem das Attribut createMissingRouteAttrs auf 1 gesetzt, so ist nach dem Aufruf das Attribut route_BackofenFertig zudem automatisch angelegt worden, d.h.

attr myCmdRouter route_BackofenFertig route_PushPeter

wurde automatisch ausgeführt und kann nun ggf. bequem über die Weboberfäche von FHEM angepasst werden.

10. Fortgeschrittene Nutzung: Anpassung des Default-Kommandos cmd_Default

Enthält die Route nach vollständigem Durchlaufen kein Kommando, so wird automatisch das Kommando cmd_Default zur Route hinzugefügt. Dieses erzeugt standardmäßig das Reading ,,lastError" mit einer entsprechenden Fehlermeldung. Das kann man über das Attribut cmd_Default ändern und selbst ein Kommando für diesen Fall festlegen (z.B. eine Pushnachricht mit der Fehlermeldung versenden).

Stößt der cmdRouter auf ein unbekanntes Kommando, so verwendet er stattdessen ebenfalls den Befehl, der in cmd_Default hinterlegt ist (zusätzlich zu evtl. sonst noch vorhandenen cmd_...-Angaben), so dass man die Chance hat, z.B. Schreibfehler zu bemerken. Zudem wird das cmd_Default automatisch für nicht vorhandene Routen benutzt, was man aber ändern kann (siehe 9.).

Setzt man das Attribut createMissingCmdAttrs auf 1, werden unbekannte Kommandos automatisch als Attribut angelegt und mit dem Inhalt von cmd_Default befüllt. Auf diese Weise kann man z.B. gezielt neue Kommandos ,,sammeln" und später auf sinnvolle Werte setzen. Besser (da flexibler) ist es jedoch, das Sammeln neuer Aufrufe über die Default-Route zu erledigen (siehe 9.).

11. Fortgeschrittene Nutzung: Perl-Statements als Route

Statt in eine Route direkt deren Namen einzubetten, kann man ein Perl-Statement verwenden - in geschweiften Klammern. Dieses muss einen Routennamen zurückgeben, der dann entsprechend verwendet wird. Beispiel:

defmod myCmdRouter cmdRouter
attr myCmdRouter cmd_Pushover set pushoverDevice msg msgtext device='pushOverDevice'
attr myCmdRouter route_PushPeter cmd_Pushover pushOverDevice_1='iPhone_Peter'
attr myCmdRouter route_PushPeterAtHome {(ReadingsVal("anwesend.peter","state","") eq "Zu Hause"?"route_PushPeter":"")}


Aufruf:

set myCmdRouter exec route_PushPeterAtHome msgtext='Der Backofen ist vorgeheizt!'

Ergebnis:

route_PushPeter wird nur ausgewertet, wenn das state-Reading vom Device anwesend.peter den Wert ,,Zu Hause" hat. Nur dann bekommt Peter also eine entsprechende Pushover-Nachricht.

12. Fortgeschrittene Nutzung: Perl-Statements als Parameter

Parameter dürfen als Ersetzungswert Perl-Code enthalten. Ersetzt wird der Platzhalter im Kommando dann mit dem Rückgabewert des Perl-Ausdrucks. Dies ist z.B. nützlich, um dynamische Werte in den Kommandos zu ergänzen:

defmod myCmdRouter cmdRouter
attr myCmdRouter cmd_Pushover set pushoverDevice msg msgtext device='pushOverDevice' sound='sound'
attr myCmdRouter route_PushPeter cmd_Pushover pushOverDevice_1='iPhone_Peter' sound={(myUtils_isNight()?"silent":"rising")}


Aufruf:

set myCmdRouter exec route_PushPeter msgtext='Der Backofen ist vorgeheizt!'

Ergebnis (wenn myUtils_isNight() == 1):

set pushoverDevice msg Der Backofen ist vorgeheizt! device='iPhone_Peter' sound='silent'

13. Fortgeschrittene Nutzung: Rekursive Auswertung von Parametern

Enthält das, wodurch ein Parameter-Platzhalter ersetzt werden soll, wiederum einen Platzhalter für einen Parameter, so wird dieser ebenfalls ersetzt. Das ist z.B. wenn man Perlcode als Parameterwert verwendet, sinnvoll.

Folgende Route für den Telegrambot (der im Gegensatz zu Pushover keinen Nachrichtentitel unterstützt) kombiniert Titel und Nachrichtentext zu einer Textnachricht, wenn beides da ist:


defmod myCmdRouter cmdRouter
attr myCmdRouter cmd_TelegramBot set system.telegrambot msg tgReceiver tgMsgtext
attr myCmdRouter route_PushPeter route_Telegram tgReceiver_1='@Peter_K'
attr myCmdRouter route_Telegram cmd_TelegramBot tgMsgtext={("msgtitle"?"msgtitle - msgtext":"msgtext")}
FHEM auf Ubuntu-VM / 2xNUC Proxmox Cluster
UI: HomeKit, TabletUI, Grafana
IOdevs: 2xHueBridge, RaspiMatic-CCU, CUL868, 2xHarmonyHub, 6xRaspi-Roomnode mit CO2, VOC und lepresenced
Devices: 107xHomematic(IP), 96xPhilips Hue, 17xTECHEM, 12xBTLE, 8xSONOS, 2xHomeConnect, 1xShelly 3em, 1xNanoleaf ...

rudolfkoenig


peterk_de

Hi Rudi,

ja kenne ich und nutze ich auch. Allerdings für andere Use-Cases - das beides ergänzt sich prima. Der cmdRouter ist von der Idee her eher eine Alternative zum msg-Befehl als zu cmdalias, auch wenn es zu beidem Überschneidungen gibt. Kernunterschied ist, dass ich im cmdRouter mir sehr bequem beliebige Abstraktionsschichten zu den FHEM-Befehlen anlegen kann. Bei cmdalias geht das auch, aber nicht so "galant".

Vielleicht mal ein Beispiel, wie ich es nutze. In meinen ganzen Notifies steht nur noch sowas wie das hier (Notify für den ActionDetector von Homematic):

fhem("set myCmdRouter exec route_mt_HomeMaticOffline msgtitle='$deviceAlias offline' msgtext='Seit $interval min keine Daten mehr gesendet.' device='$deviceName' room='$devRoom'");

Die "Route" mit der ID route_mt_HomeMaticOffline verwende ich nur in diesem einen Notify (mt_ steht bei mir für "Message Typ"), andere Notifys kriegen nen anderen selbstsprechenden Routennamen.

Mein commandRouter sieht dann auszugsweise so aus:

attr myCmdRouter route_mt_HomeMaticOffline route_mt_DeviceOffline

Da wird die Route also an eine andere Route "weitergeleitet" - nämlich an route_mt_DeviceOffline. Diese Route wiederum - wie diverse andere Routen auch - leitet es dann an die Route "Pushnachricht für Peter" weiter:

attr myCmdRouter route_mt_DeviceOffline route_PushPeter

Und so mach ich das mit allen Benachrichtigungen:

attr myCmdRouter route_mt_Anruf route_PushPeter route_PushSusann route_KodiPopupWZ cmd_PauseTV
attr myCmdRouter route_mt_BackofenVorgeheizt route_PushPeterAtHome route_PushSusannAtHome
attr myCmdRouter route_mt_Briefkasten route_PushPeter route_PushSusann
attr myCmdRouter route_mt_FensterSchließen route_PushPeterAtHome route_PushSusannAtHome

attr myCmdRouter route_mt_KatzeVerstopft route_mt_Katzenklo
attr myCmdRouter route_mt_Katzenklo route_PushPeter route_PushSusann pushoverType='katze'

attr myCmdRouter route_mt_KuehlschrankWarm route_PushPeter route_PushSusannAtHome
attr myCmdRouter route_mt_LuftentfeuchterFehler route_PushPeter route_PushSusannAtHome
attr myCmdRouter route_mt_NiederschlagFensterOffen route_PushPeter route_PushSusannAtHome
attr myCmdRouter route_mt_Tuerklingel route_PushPeter route_PushSusann
attr myCmdRouter route_mt_WaescheFertig route_PushPeterAtHome route_PushSusann

attr myCmdRouter route_Default route_PushPeter


Das ist also erstmal immer noch überwiegend Abstrakt - ich ordne erstmal meist nur jeder dieser Routen eine oder weitere abstrakte Routen zu, die dann abgearbeitet werden. In dem Beispiel repräsentieren sie meist Benachrichtigungswege zu mir, meiner Frau oder eine Kombination daraus. Ab und an ist auch mal ein konkreter Befehl dabei (wie z.B. Kodi pausieren bei Anrufen).

Das ganze wird dann weiter zu konkreten Device-Routen aufgelöst:

attr myCmdRouter route_PushPeter route_Telegram tgReceiver_1='@Peter_K' pushoverType='default' {(ReadingsVal("anwesend.peter","state","") eq "Zu Hause"?"route_iPad":"")}
attr myCmdRouter route_PushPeterAtHome {(ReadingsVal("anwesend.peter","state","") eq "Zu Hause"?"route_PushPeter":"")}

attr myCmdRouter route_PushSusann cmd_Pushover pushOverDevice_1='iPhone_Susann' pushoverType='default' {(ReadingsVal("anwesend.susann","state","") eq "Zu Hause"?"route_iPad":"")}
attr myCmdRouter route_PushSusannAtHome {(ReadingsVal("anwesend.susann","state","") eq "Zu Hause"?"route_PushSusann":"")}

attr myCmdRouter route_iPad cmd_Pushover pushOverDevice_1='iPad'

attr myCmdRouter route_KodiPopupWZ {(ReadingsVal("stube.mediapc.xbmc","state","") eq "opened"?"cmd_KodiPopupWZ":"")} kodiMsgtext={("msgtitle"?"msgtitle - msgtext":"msgtext")}
attr myCmdRouter route_Telegram cmd_TelegramBot tgMsgtext={("msgtitle"?"msgtitle - msgtext":"msgtext")}


Und zum Schluss dann in tatsächliche FHEM-Befehle umgesetzt:

attr myCmdRouter cmd_KodiPopupWZ set stube.mediapc.xbmc msg "kodiMsgtext" 10000 info
attr myCmdRouter cmd_PauseTV {pause_tv()}
attr myCmdRouter cmd_Pushover set system.pushover.pushoverType msg msgtext title='msgtitle' device='pushOverDevice'
attr myCmdRouter cmd_TelegramBot set system.telegrambot msg tgReceiver tgMsgtext



Möchte jetzt meine Frau künftig auch per Telegram statt Pushover ihre Nachrichten bekommen, ist das eine minimale Änderung am Attribut "route_PushSusann" ... genauso wie die Anforderung "Ich möchte aber nur zu Hause wissen wenn der Spüler fertig ist" in 10 Sekunden umgesetzt ist ... etc ;-)
FHEM auf Ubuntu-VM / 2xNUC Proxmox Cluster
UI: HomeKit, TabletUI, Grafana
IOdevs: 2xHueBridge, RaspiMatic-CCU, CUL868, 2xHarmonyHub, 6xRaspi-Roomnode mit CO2, VOC und lepresenced
Devices: 107xHomematic(IP), 96xPhilips Hue, 17xTECHEM, 12xBTLE, 8xSONOS, 2xHomeConnect, 1xShelly 3em, 1xNanoleaf ...

PatrickR

Um ehrlich zu sein erkenne ich auf den ersten Blick nicht den Vorteil zu ggf. mehreren aufeinander aufbauenden myUtils-Funktionen bzw. Trigger-Notifys.

Patrick


Von unterwegs gesendet.
lepresenced - Tracking von Bluetooth-LE-Tags (Gigaset G-Tag) mittels PRESENCE

"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning." - Rich Cook

peterk_de

#4
Jo, per Funktionskaskade in der myUtils geht das  - so hatte ich es auch sehr lange, bis es mich zu sehr genervt hat. Das Modul ist aber tatsächlich genau aus diesem Ansatz heraus bei mir entstanden - irgendwann wurde mir der zu umfangreich und zu klumpig (hier noch ein if, da noch n Spezialfall ...)  da hab ich das dann mal generalisiert und mit ein paar netten Features weiterentwickelt.

Wie z.B.:

Template: set myPushDevice msg "Hallo!" to='Empfaenger'

Aufruf mit den Parametern:
Empfaenger_1='Herrmann'
Empfaenger_2='Gustav'

--> Führt das Kommando-Template automatisch doppelt aus, da zwei Empfänger. Und so. Das braucht als myUtils-Funktionen dann schon recht viel Schreiberei bzw. viel Hirnschmalz im Vorfeld.
FHEM auf Ubuntu-VM / 2xNUC Proxmox Cluster
UI: HomeKit, TabletUI, Grafana
IOdevs: 2xHueBridge, RaspiMatic-CCU, CUL868, 2xHarmonyHub, 6xRaspi-Roomnode mit CO2, VOC und lepresenced
Devices: 107xHomematic(IP), 96xPhilips Hue, 17xTECHEM, 12xBTLE, 8xSONOS, 2xHomeConnect, 1xShelly 3em, 1xNanoleaf ...