Ich habe ein DOIF wie folgt:
define di_Hauslicht DOIF ([swHausLicht:connected] eq "Offline") ({increment("FI_Out","HL_counter")}) DOELSE ( (IF ([swHausLicht:state] eq "ON") (set flagHausLicht on) ELSE (set flagHausLicht off) ))
Bei dem Aufruf des DOIF kommt folgende Fehlermeldung:
ERROR evaluating {if(OFF eq "ON"){fhem('set flagHausLicht on')}else{fhem('set flagHausLicht off')}}: Bareword "OFF" not allowed while "strict subs" in use at (eval 3593918) line 1.
2020.09.21 15:51:09.335 2: di_Hauslicht: IF (OFF eq "ON") (set flagHausLicht on) ELSE (set flagHausLicht off) : Bareword "OFF" not allowed while "strict subs" in use at (eval 3593918) line 1.
Dieses DOIF soll nichts weiter machen als einen Zähler inkrementieren, wenn das MQTT-Device "Offline" ist und wenn nicht, dann für die Steuerung des Icons im Tablet-UI das Flag setzen, das dann die Farbe des Icons bestimmt. Das wurde auf diesem Umweg gemacht, weil noch andere Instanzen auf das Icon einen Einfluss haben. Also nichts "weltbewegendes".
Die Fehlermeldung kann ich nicht nachvollziehen, wahrscheinlich mache ich noch was falsch, wer kann mir auf "die Sprünge" helfen? Vielen Dank schon mal.
"flagHausLicht" ist wie folgt definiert:
Internals:
CFGFN ./FHEM/99_MQTT.cfg
FUUID 5e23af19-f33f-8bda-be4b-d51d9b20ebe12206
NAME flagHausLicht
NR 1790
STATE off
TYPE dummy
READINGS:
2020-09-21 05:35:33 state off
Attributes:
room Home,MQTT,Switches
setList on off
und "swHausLicht" ist ein MQTT-Device (WeMos) und wie folgt definiert:
Internals:
CFGFN ./FHEM/99_MQTT.cfg
FUUID 5ec4618d-f33f-8bda-5141-339fc91afc23eccf
IODev mqtt
NAME swHausLicht
NR 1807
STATE incoming publish received
TYPE MQTT_DEVICE
READINGS:
2020-09-21 18:17:05 connected Online
2020-09-21 05:35:33 state OFF
2020-09-21 18:17:05 transmission-state incoming publish received
message_ids:
publishSets:
:
topic Hauslicht/cmnd/POWER
values:
ON
OFF
sets:
OFF
ON
subscribe:
Hauslicht/tele/LWT
Hauslicht/tele/RESULT
Hauslicht/stat/POWER
Hauslicht/tele/TELEMETRY
subscribeExpr:
^Hauslicht\/tele\/LWT$
^Hauslicht\/tele\/RESULT$
^Hauslicht\/stat\/POWER$
^Hauslicht\/tele\/TELEMETRY$
subscribeQos:
Hauslicht/stat/POWER 0
Hauslicht/tele/LWT 0
Hauslicht/tele/RESULT 0
Hauslicht/tele/TELEMETRY 0
subscribeReadings:
Hauslicht/stat/POWER:
cmd
name state
Hauslicht/tele/LWT:
cmd
name connected
Hauslicht/tele/RESULT:
cmd
name result
Hauslicht/tele/TELEMETRY:
cmd
name telemetry
Attributes:
IODev mqtt
alexaName Hauslicht
alexaRoom Garten
event-on-change-reading .*
eventMap on:ON off:OFF
genericDeviceType switch
publishSet ON OFF Hauslicht/cmnd/POWER
room Alexa,MQTT,Switches
stateFormat transmission-state
subscribeReading_connected Hauslicht/tele/LWT
subscribeReading_result Hauslicht/tele/RESULT
subscribeReading_state Hauslicht/stat/POWER
subscribeReading_telemetry Hauslicht/tele/TELEMETRY
Das kommt von deinen (unnötigen) verdoppelten Klammern im DOELSE (( IF ... ))
Irgendwie verwirrt es den DOIF Interpreter und er glaubt, es wäre etwas anderes.
Mach einfach so und es sollte funktionieren:
define di_Hauslicht DOIF ([swHausLicht:connected] eq "Offline") ({increment("FI_Out","HL_counter")}) DOELSE (IF ([swHausLicht:state] eq "ON") (set flagHausLicht on) ELSE (set flagHausLicht off))
Vielen Dank, aber dass die überflüssige doppelte Klammer eine solchen Wirkung hat, das war mir wirklich unklar und das verstehe ich nicht wirklich, denn ansonsten sind doppelte Klammern zwar unsinnig, aber sind kein Fehler. Aber hier kann es natürlich anders sein. Ich versuche das mal und werde berichten.
Stimmt, es wird ohne Fehlermeldung ausgeführt. Vielen Dank, dann werde ich mal alles durchsuchen und diese Fehler beseitigen, denn ich war der irrigen Ansicht, dass die IFs in Klammern eingeschlossen werden müssen, ich dachte, ich hätte das mal gelesen, war wohl nicht so.
Wenn etwas in einem DOIF Befehl in zusätzlichen Klammern steht, hat es für DOIF eine besondere Bedeutung, und wird z.B. benutzt, um einen Befehl mit Koma so-wie-es-ist zu nehmen, und nicht als mehrere Befehle zu interpretieren (Koma ist ja im DOIF nw das Trennzeichen).
OK vielleicht verwirrend. Ich weiss nicht genau, wie das codiert ist, und vielleicht kann Damian daran schrauben. Irgendein eval() des Befehls anscheinend.
Aber Fakt ist: es funktioniert ohne die zusätzliche Klammern, und es funktioniert nicht wenn die da sind.
Vielen Danke für die Erklärung, wenn man es weiß, dann kann man darauf achten und alles ist okay.
DOIF hat keinen vollständigen Parser, insb. muss DOIF den IF-Befehl als solchen erkennen, um die spezifischen Angaben in eckigen Klammern nicht zu ersetzen, sondern sie dem IF-Befehl zu überlassen (beide benutzen die gleiche Syntax). Hier erkennt DOIF durch die doppelte Klammerung den IF-Befehl nicht und ersetzt vorzeitig die Angabe in eckiger Klammer zu OFF. Der IF-Befehl kann also den Ausdruck nicht mehr korrekt in Perl-if übersetzen, statt dessen bleibt ein OFF übrig, welches wiederum im erzeugten Perl-Ausdruck durch den IF-Befehl zum Fehler führt.
Es sind hier einfach drei Parser beschäftig, die manchmal zu viel des Guten sind.
Im DOIF-Perl-Modus ist die Sache etwas eleganter gelöst, weil DOIF dort direkt in Perl übersetzt.
Vielen Dank für die ausführliche Erklärung, durch die mir nun einiges klarer wurde. Bestimmt ist das mit den doppelten Klammern schon irgendwo - CommandRef oder Wiki - beschrieben worden, ich habe das nur nicht gelesen. In diesem Zusammenhang muss ich mal die sehr ausführliche DOIF-Beschreibungen loben, bei der wohl fast jeder für sein spezielles "Problem" fündig werden kann, sehr gut, was bei anderen Sachen aus verständlichen Gründen oft zu kurz kommt. Besonders die einfachen Programmbeispiele zeigen die Anwendungsfälle sehr deutlich, das müßte generell bei alle Modulen so sein, denn ein "Bild" sagt oft mehr als tausend Worte. Aus früheren Zeiten weiß ich, dass Programmierer erst mal nie mit ihrem Modul so richtig "fertig" werden und die Dokumentation sehr oft mehr als dürftig ist oder sogar ganz ausbleibt. Das ist bei den DOIFs mit der Doku nicht der Fall. Vielen Dank dafür.
Das DOIF im Perl-Modus werden ich bei zukünftigen Erweiterungen - FHEM-Anwendung ist eben eine "Lebensaufgabe" und wird nie so richtig "fertig" - auch versuchen, wobei meine Perl-Kenntnisse eher dürftig sind. Ich programmiere in Perl eher wie in C, was ich fast perfekt kann, und nur für spezielle Dinge suche ich mir die Sachen zusammen. In meinem Alter lerne ich keine weitere Programmiersprache, ich habe mal mit Algol68 und Lochkarten angefangen ...