[gelöst] NOTIFY vs. IF/ELSE Syntax

Begonnen von zife, 21 März 2020, 13:49:28

Vorheriges Thema - Nächstes Thema

zife

Hallo Profis,

ich bin in Sachen Syntax trotz oder wegen endloser Lektüre diverser Foreneinträge und Commandref-Abschnitte verloren.

Ich möchte 2 URL mit einer kurzen zeitlichen Pause dazwischen aufrufen, damit ein Gerät Zeit hat, auf dem Standby zu erwachen. Dafür wollte ich "nur" ein Sleep zwischen den beiden GetFileFromURL einbauen.


In meinem NOTIFY mit IF/ELSE-Bedingungen funktioniert das hier:
ELSE ({GetFileFromURL ("http://192.168.178.50:8080/raumserver/controller/leaveStandby?id=WC",5)},{sleep 1},{GetFileFromURL ("http://192.168.178.50:8080/raumserver/controller/loadPlaylist?id=WC&value=Radio1",5)})

In einem NOTIFY ohne IF/ELSE-Bedingungen funktioniert es aber nicht:
define MusikBZAn2 notify MusikBZSeq:partial_2 {GetFileFromURL ("http://192.168.178.50:8080/raumserver/controller/leaveStandby?id=Bad",5)},{sleep 1},{GetFileFromURL ("http://192.168.178.50:8080/raumserver/controller/loadPlaylist?id=Bad&value=Radio1",5)}


Ich habe gefühlt sämtliche Varianten mit Klammern, Kommas und Semikolons probiert, aber nix will funktionieren... welches Brett hab ich vor'm Kopf?
Oder konkreter:
- Wie lautet die korrekte Syntax?
- Darf ich keine Perl- und fhem-Aufrufe mischen? Im oberen Code hatte ich erst das sleep 1 ohne geschweifte Klammern gesetzt - ohne Erfolg.

Danke für Hinweise!
fhem mit EnOcean, Gardena, Vorwerk, Miele und Teufel/Raumfeld-Integration... nur meine Kinder wollen sich damit nicht anständig steuern lassen. Wer weiß Rat?

Zrrronggg!

#1
(editiert)
Hm. Ich sehe mehrere Problem:

1. Man kann FHEM und PERL mischen

2. Soweit ich das sehe machst du das aber nicht. Geschweifte Klammern sagen FHEM: Das in den geschweiften Klammern an PERL übergeben. D.H. auch der sleep Befehl wird an Perl übergeben!

2.1 Ich weiss gerade nicht, ob die Syntax so für ein PERL Sleep ganz richtig ist. Wenn nein, passiert nix.

2.2 Wenn aber ja, macht PERL eine Pause. D.h. du pausierste das komplette FHEM, da FHEM eine Perl Application ist!. Daher raten viele von der Nutzung von sleep ab, denn wenn man es falsch benutzt (so wie vermutlich bei dir), bleib FHEM für die Pausenzeit stehen. Bei einer Sekunde vermutlich egal, aber "{sleep 30}" hält mal munter FHEM komplett an für 30 Sekunden.

3. Keine Kommas zum Aufzählen der Befehle, sondern Semikolons. Ausserdem sind die nicht escaped (verdoppelt).
Zum Thema Escapen:
Folgendes
define MusikBZAn2 notify MusikBZSeq:partial_2 {GetFileFromURL ("http://192.168.178.50:8080/raumserver/controller/leaveStandby?id=Bad",5)};{sleep 1};{GetFileFromURL ("http://192.168.178.50:8080/raumserver/controller/loadPlaylist?id=Bad&value=Radio1",5)} 
bedeutet, dass FHEM, wenn es an der Zeile im Prozessing ankommt folgendes macht:

3.1
erzeuge das define define  MusikBZAn2 notify MusikBZSeq:partial_2 {GetFileFromURL ("http://192.168.178.50:8080/raumserver/controller/leaveStandby?id=Bad",5)} (das wird auslösen wenn MusikBZSeq:partial_2)

3.2 Halte PERLprozessing und damit FHEM für eine Sekunde an

3.3 {GetFileFromURL ("http://192.168.178.50:8080/raumserver/controller/loadPlaylist?id=Bad&value=Radio1",5)}

Und zwar alles zugleich, denn das sind - durch das Seimikolons separiert - alles auszuführenden Befehle, die in einer Zeile stehen.

In jedem Fall enthhält das define nur EINEN Befehl zum aurufen der Seite, der andere wird irgendwann beim Einlesen der Konfig ausgeführt.

4. Was du machen willst ist (ohne Test nur so aus dem Bauch raus hingeschrieben)

define MusikBZAn2 notify MusikBZSeq:partial_2 {GetFileFromURL ("http://192.168.178.50:8080/raumserver/controller/leaveStandby?id=Bad",5)};;sleep 1;;{GetFileFromURL ("http://192.168.178.50:8080/raumserver/controller/loadPlaylist?id=Bad&value=Radio1",5)}

Mich wundert das dein erstes Beispiel gehen soll, allerdings ist hier noch der FHEM DOIF beteiligt (ELSE= DOIF, else = PERL) den ich aus historischen Gründen nicht verwende und dessen Verhalten ich nicht genau kenne.

FHEM auf Linkstation Mini, CUL 868 SlowRF, 2xCUL 868 RFR, CUL 433 für IT, 2xHMLAN-Configurator mit VCCU, ITV-100 Repeater, Sender und Aktoren von FHT, FS20, S300, HM, IT, RSL

Zrrronggg!

#2
Ganz allgemein:

define act_on_Terrassen_Licht notify Terrassen_LS:ob set Terrassen_Licht on; set Flur_Licht on

Ist das gleiche wie:
define act_on_Terrassen_Licht notify Terrassen_LS:ob set Terrassen_Licht on
Zitatset Flur_Licht on

Macht also folgendes: Beim Start von FHEM oder dem neueinlesen der Konfig  wird diese Zeile irgendwann gelesen und es wird
a) define act_on_Terrassen_Licht notify Terrassen_LS:ob set Terrassen_Licht on
erzeugt und ausserdem sofort
b) das Flur_Licht angeschaltet, also nur 1x beim Neustart.


hingegen


[code]define act_on_Terrassen_Licht notify Terrassen_LS:on set Terrassen_Licht on;; set Flur_Licht on[/code]

wir beim Starten oder Neueinlesen eine define act_on_Terrassen_Licht anlegen, das bei notify Terrassen_Licht:ob beide Lichter einschaltet.


Das Escapen verdoppelt KSemikolons immer und man muss auch machmal doppelt escapen Beispiel:

define act_on_Terrassen_Licht notify Terrassen_LS:on set Terrassen_Licht on;; set Flur_Licht on;; define Licht_aus at at +00:20:00 set Terrassen_Licht off;;;; set Flur_Licht off
macht bei Terrassen_Licht:on beide Lichter an und erzeugt ein define, das 20 Minuten später beide Lichter wieder aus macht.

Alles was per Semikolon getrennt in einer Zeile steht wird (mehr oder weniger) zugleich gemacht. Es gibt nicht mal eine gesicherte Reihenfolge, weil da noch die Funkschnittstelle etc zwischenfummelt, sodass

define act_on_Terrassen_Licht notify Terrassen_LS:on set Terrassen_Licht on;; set Flur_Licht on;; define Licht_aus at at +00:20:00 set Terrassen_Licht off;; set Flur_Licht off

(es fehlen hier nur 2 Semikolons) sich vermutlich total anders verhält als intendiert:
Im falle des notify Terrassen_LS:on wird nämlich das Terassen_Licht eingeschaltet, ZUGLEICH das Flur_Licht eingeschaltet, ZUGLEICH das define
define Licht_aus at at +00:20:00 set Terrassen_Licht off angelegt und ZUGLEICH das Flur_Licht  AUSgeschaltet.

In der Praxis wird man beim Betätigen des Lichtschalters Terrassen_LS als mal erleben, dass das Flur Licht angeht, dann wieder auch nicht, oder wenn der Host langsam ist auch mal, dass das Licht angehe und sofort wieder aus. Und wenn das Flur_Licht schon an ist wird es auch oft AUSgehen.

Kurzum: Escapen verstehen ist wichtig.
FHEM auf Linkstation Mini, CUL 868 SlowRF, 2xCUL 868 RFR, CUL 433 für IT, 2xHMLAN-Configurator mit VCCU, ITV-100 Repeater, Sender und Aktoren von FHT, FS20, S300, HM, IT, RSL

zife

#3
Ohje ohje... was hab ich da angefangen  8)
Danke für die ausführliche(n) Erklärung(en).

Verstehe ich es richtig, dass meine Idee so gar nicht klappt - also gar kein bzw. nicht nur ein Syntax-Problem vorliegt, sondern dass ich die Pause zwischen den beiden URL-Aufrufen ganz anders machen muss? Könnt Ihr mich kurz auf den richtigen Weg weisen, bitte?

Und... wo wir schon dabei sind:
define TA_KU_Ost_AlleZu notify TA_KU_Ost_FT55:BI set RO_KU_Ost_FSB61 down,RO_KU_Sued1_FSB61 down,RO_KU_Sued2_FSB61 down
macht aber alle 3 Rollos beim Tastendruck BI runter, richtig? Der Unterschied zu Zrrronggg!'s Beispiel ist, dass ich kein Leerzeichen nach dem Komma habe, richtig?

Zum Thema Escapen werde ich wohl noch ein paar Abende investieren müssen... da hilft das Stichwort schon mal.


Edit: Wäre das Beispiel mit dem
define Licht_aus at at +00:20:00 set Terrassen_Licht off,,,, set Flur_Licht off
dann die beste Lösung für mein Problem?

Noch'n Edit:
Das o.g. vermutete Stück Code klappt leider nicht - es passiert... nix
{GetFileFromURL ("http://192.168.178.50:8080/raumserver/controller/leaveStandby?id=Bad",5)},,sleep 1,,{GetFileFromURL ("http://192.168.178.50:8080/raumserver/controller/loadPlaylist?id=Bad&value=Radio1",5)}
fhem mit EnOcean, Gardena, Vorwerk, Miele und Teufel/Raumfeld-Integration... nur meine Kinder wollen sich damit nicht anständig steuern lassen. Wer weiß Rat?

Otto123

#4
Hi,

Kommas als Trenner ?!? Ich würde halbe Punkte verwenden ;) um Befehle zu trennen.

Wie hast Du den Code eingegeben? Das muss doch Fehler werfen?

Korrigiertes Beispiel:
define Licht_aus at +00:20:00 set Terrassen_Licht off;;set Flur_Licht off

Die Mischung von unterschiedlichen Kommandotypen (FHEM, Perl, Shell) ist nicht offiziell unterstützt! Kann zwar gehen, muss aber nicht. Siehe Doku: https://commandref.fhem.de/#command

Dieser Perl Code kann funktionieren (nicht getestet) aber würde als FHEM Befehl FHEM blockieren!
{GetFileFromURL ("http://192.168.178.50:8080/raumserver/controller/leaveStandby?id=Bad",5);sleep 1; GetFileFromURL ("http://192.168.178.50:8080/raumserver/controller/loadPlaylist?id=Bad&value=Radio1",5)}

Gruß Otto
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

zife

Zitat
Wie hast Du den Code eingegeben? Das muss doch Fehler werfen?

Ist Teil eines längeren NOTIFY, siehe Idee von Zrrronggg! oben. Hab ich nur verkürzt zitiert.

Eingabe über DEF bzw. direkt in der fhem.cfg (ja, ich weiss, ist böse, aber ich hänge aus alten Zeiten noch dran, direkt im Code zu arbeiten).

Gibt jedenfalls in beiden Versionen als vollständiges NOTIFY keine Fehlermeldung, aber es passiert eben auch nix.

Hm, wie ich meinen Plan umsetzen könnte, das hab ich noch nicht begriffen. Brett vorm Kopf? Wie wär denn ein Weg, quasi "coderein" zu bleiben und nichts zu mischen?
fhem mit EnOcean, Gardena, Vorwerk, Miele und Teufel/Raumfeld-Integration... nur meine Kinder wollen sich damit nicht anständig steuern lassen. Wer weiß Rat?

Otto123

Zitat von: zife am 21 März 2020, 18:02:29
Gibt jedenfalls in beiden Versionen als vollständiges NOTIFY keine Fehlermeldung, aber es passiert eben auch nix.
Meine Varianten oder Deine?

Poste doch mal alles und nicht bloß Fragmente.
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

Zrrronggg!

#7
Otto hat recht ich habe oben Kommas anstatt Semikolons verwendet ... du auch. Das ist sowieso falsch, bestimmt Betäubung bei mir wegen Corinna.
Das du Kommas verwendet hast, ist also der DRITTE Grund warum es nicht geht, denn meine sonstigen Ausführungen sind trotzdem richtig.

(damit Leute die den Thread späterlesen nicht verwirrst werden, habe ich den ersten Post jetzt korrigiert)


Nun zu deinen Fragen.

Sleep geht schon (ich würde es so nicht machen, geht aber)
aber:
a) keine geschweiften Klammern ums Sleep, denn dann ist es ein PERL Sleep, das ist evil, weil es FHEM mit anhält
b) alle Kommandos müssen per Semikolon abgetrennt werden. Die in das Define sollen müssen per doppeltem Semikolon "escaped" werden.


Gehen müsste also
define MusikBZAn2 notify MusikBZSeq:partial_2 {GetFileFromURL ("http://192.168.178.50:8080/raumserver/controller/leaveStandby?id=Bad",5)};;sleep 1;;{GetFileFromURL ("http://192.168.178.50:8080/raumserver/controller/loadPlaylist?id=Bad&value=Radio1",5)}
FHEM auf Linkstation Mini, CUL 868 SlowRF, 2xCUL 868 RFR, CUL 433 für IT, 2xHMLAN-Configurator mit VCCU, ITV-100 Repeater, Sender und Aktoren von FHT, FS20, S300, HM, IT, RSL

Otto123

#8
Ich will es nochmal hervorheben:
ZitatDie Mischung von unterschiedlichen Kommandotypen (FHEM, Perl, Shell) ist nicht offiziell unterstützt! Kann zwar gehen, muss aber nicht. Siehe Doku: https://commandref.fhem.de/#command
Ein netter Kollege von mir, hat mal gesagt: Es besteht kein Rechtsanspruch auf die Beibehaltung von Fehlern! ;)
In dem Sinne ist - dass es jetzt geht, obwohl dokumentiert ist, dass es nicht geht - ein Fehler!

Vorschlag: Schreib alles in ein Script (Script.sh) und führe das Script aus!

get url
sleep 1
get url

define willi notify bla:bla "bash Script.sh"
Erfüllt den Zweck und blockiert nicht. Und ist Pflegeleichter ;)

Gruß Otto
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

Zrrronggg!

#9
Zitat von: zife am 21 März 2020, 16:39:05



Und... wo wir schon dabei sind:
define TA_KU_Ost_AlleZu notify TA_KU_Ost_FT55:BI set RO_KU_Ost_FSB61 down,RO_KU_Sued1_FSB61 down,RO_KU_Sued2_FSB61 down
macht aber alle 3 Rollos beim Tastendruck BI runter, richtig?


Nein. der Code ist funktionslos und wird Fehlermeldungen abwerfen.

Entweder:

define TA_KU_Ost_AlleZu notify TA_KU_Ost_FT55:BI set RO_KU_Ost_FSB61 down;; set RO_KU_Sued1_FSB61 down;; set RO_KU_Sued2_FSB61 down

oder

define TA_KU_Ost_AlleZu notify TA_KU_Ost_FT55:BI set RO_KU_Ost_FSB61, RO_KU_Sued1_FSB61,RO_KU_Sued2_FSB61 down

Hier ist das Komma mal richtig eingesetzt  ;D, nämlich als Aufzählung aller Geräte für die der down Befehl gelten soll.

Die Leerzeichen sind egal.




ZitatNoch'n Edit:
Das o.g. vermutete Stück Code klappt leider nicht - es passiert... nix
{GetFileFromURL ("http://192.168.178.50:8080/raumserver/controller/leaveStandby?id=Bad",5)},,sleep 1,,{GetFileFromURL ("http://192.168.178.50:8080/raumserver/controller/loadPlaylist?id=Bad&value=Radio1",5)}

Das ist mein Fehler. SEMIKOLON, da hat Otto recht.

Wo ich aber nicht so pessimistisch wie  Otto wäre ist die Mischung von PERL und FHEM Code. Das geht und zwar gut. ABER man muss sehr sorgfältig sein, was Klammern und Escapen betrifft. Ferner:
Ottos letztes Beispiel:

{GetFileFromURL ("http://192.168.178.50:8080/raumserver/controller/leaveStandby?id=Bad",5);sleep 1; GetFileFromURL ("http://192.168.178.50:8080/raumserver/controller/loadPlaylist?id=Bad&value=Radio1",5)}


Stimmt so zwar, wird aber in deinem Umfeld nicht gehen, weil du es in einem define verwenden wirst und dann escapen muss, also Semikolons verdoppeln. Siehe mein Beispiel ein Post zuvor.





FHEM auf Linkstation Mini, CUL 868 SlowRF, 2xCUL 868 RFR, CUL 433 für IT, 2xHMLAN-Configurator mit VCCU, ITV-100 Repeater, Sender und Aktoren von FHT, FS20, S300, HM, IT, RSL

Zrrronggg!

#10
Zitat von: Otto123 am 21 März 2020, 19:17:10
Ich will es nochmal hervorheben:Ein netter Kollege von mir, hat mal gesagt: Es besteht kein Rechtsanspruch auf die Beibehaltung von Fehlern! ;)
In dem Sinne ist - dass es jetzt geht, obwohl dokumentiert ist, dass es nicht geht - ein Fehler!

Aus der von dir zitierten commandref geht nicht hervor, das man das nicht machen darf. Ich kann nicht nachvollziehen, dass das ein Fehler sein soll. Es wird explizit drauf hingewiesen:

There are three types of commands: "FHEM" commands (described in this document), shell commands (they must be enclosed in double quotes ") and perl expressions (enclosed in curly brackets {})

D.H. Perl expressions sind ausdrücklich erlaubt. Oder was verstehe ich da nicht?

Jedenfalls: das, was threadowner machen will geht, wenn er Klammern richtig setzt und Semikolons escaped.

Ich würde zugegeben insbesondere "sleep" in so gemischten Konstrukten vermeiden, weil man "aus versehen" was falsch machen kann, aber gehen tut's wenn richtig angewendet, und so wie ich die Commanref interpretiere ist das ausdrücklich erlaubt. Alle Leute die vor DOIF angefangen haben, nutzen idR das Perl-if und haben - so wie ich - kiloweise gemischten Code.

Vielleicht verstehe ich die Commandref nicht richtig oder überlese was?
FHEM auf Linkstation Mini, CUL 868 SlowRF, 2xCUL 868 RFR, CUL 433 für IT, 2xHMLAN-Configurator mit VCCU, ITV-100 Repeater, Sender und Aktoren von FHT, FS20, S300, HM, IT, RSL

Otto123

Zitat von: Zrrronggg! am 21 März 2020, 19:35:14
Vielleicht verstehe ich die Commandref nicht richtig oder überlese was?
Es ist immer wichtig den ganzen Text zu lesen: jeden Satz, jedes Wort :)
Also auch den Letzten
ZitatNote: mixing command types (FHEM/shell/perl) on one line is not supported, even if it might work in some cases.
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

zife

Also erst einmal großes Danke für die engagierte Hilfe!

In der Tat funktioniert der zuletzt genannte Code für mein Aufweck-Problem.  8)
Ich hatte ihn zwar zwischendurch schon genau so probiert (neben all den falschen Varianten), aber wie Murphy es so will, hat der sleep 1 manchmal nicht gereicht, mit sleep 2 läuft es bestens und sicher.

Ich mach es jetzt erstmal so:
Ich benutze diese Variante für den Moment, damit zuhause Friede herrscht (WAF!) - zu viel fhem ist ja nicht sonderlich ehetauglich.

Das mit dem Skript werde ich ausprobieren - ich bin zwar eigentlich Pragmatiker, aber am Ende möchte ich schon sauberen, gut dokumentierten Code. Und da hab ich grad auch was dazugelernt.

@Zrrronggg!: Wie würdest Du das denn lösen, so rein konzeptionell? Wenn ich Dich richtig verstanden habe, würdest Du weder mit sleep noch mit dem bash Skript arbeiten?

Auch das mit dem Rollo-Code werde ich nochmal überarbeiten - blöder Fehler, das hatte ich mir eigentlich schon richtig angelesen.
fhem mit EnOcean, Gardena, Vorwerk, Miele und Teufel/Raumfeld-Integration... nur meine Kinder wollen sich damit nicht anständig steuern lassen. Wer weiß Rat?

Zrrronggg!

Vielleicht reden wir irgendwie aneinander vorbei.

Immerhin steht da ja:
Zitatshell commands or perl expressions are needed for complex at or notify arguments
Um das machen zu können MUSS man ja FHEM und Perl commandos mischen.

Ferner gibts in der Command ref ja auch dies:
https://commandref.fhem.de/#perl
Und da es ja immer wichtig ist,  ganzen Text zu lesen: jeden Satz, jedes Wort  hab ich das auch mal gemacht.

Da sind explizit gemischte oneliner aufgeführt als Beispiel, wie man das einsetzen kann, z.b.

define n2 notify piri:on { if($hour > 18 || $hour < 5) { fhem "set light on" } }

Die Command ref sagt also: Man kann PERL Commandos verwenden, hier ein paar Beispiele um bestimmte Dinge zu tun, darf man aber so nicht machen?

Vielleicht meinst du das aber gar nicht, sondern z.b. konkret die Verwendung von FHEM sleep zwischen zwei PERL Expressions vom Threadowner?


Da wäre es in der Tat besser, mal das komplette Konstrukt zu sehen, denn so machen würde ich es auch nicht, schon weil ich sleep eher vermeide. Ohne das gesamte Umfeld fällt's mir aber auch schwer, was vorzuschalgen, was besser ist.

FHEM auf Linkstation Mini, CUL 868 SlowRF, 2xCUL 868 RFR, CUL 433 für IT, 2xHMLAN-Configurator mit VCCU, ITV-100 Repeater, Sender und Aktoren von FHT, FS20, S300, HM, IT, RSL

Otto123

#14
Das Beispiel was Du anführst ist aber nur perl! Mit Verwendung der Perl Funktion fhem()!
Das ist etwas völlig anderes.

Glaub mir, ich habe erst letzten mit Anderen genau dies diskutiert. Rudi hat daraufhin die commandref ergänzt. Mal sehen ob ich den Thread noch finde.
Gefunden:
https://forum.fhem.de/index.php/topic,108970.msg1029531.html#msg1029531

Und hier was ähnliches https://forum.fhem.de/index.php/topic,108994.15.html

Gruß Otto
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz