Hauptmenü

Perl/FHEM-Syntax

Begonnen von Harald, 17 September 2013, 18:13:29

Vorheriges Thema - Nächstes Thema

Harald

Hallo zusammen,

jetzt muss ich mal eine für Perl-Erfahrene eine ganz dumme Frage stellen. Bitte verzeiht mir, aber ich kann keine Erklärung finden.

Ich habe in einem Modul folgende Einträge: my $strStateOld=ReadingsVal($strShutter,"cntStateOld","?");
...
...
if ( $strStateOld eq "?") {

Kann mir jemand erklären, was das ? bedeutet bzw. wofür das steht? Ich würde gerne verstehen, was da abläuft.
Ich interpretiere das so:
Der Wert des Readings "cntStateOld" des Gerätes $strShutter wird geladen und der Variablen $strStateOld zugewiesen. Der Defaultwert ist "?".
In der if-Abfrage wird der geladene Wert im Stringkontext mit "?" auf Gleichheit geprüft. Falls das Ergebnis wahr ist, dann mache {....
Aber was bedeutet "?". In den Readings des Gerätes steht nie ein ?

Bitte verhaut mich nicht. Bin halt Anfänger :-( und die Suche an div. Stellen hat mich nicht erleuchtet.

Viele Grüße und vielen Dank im Voraus für die Erklärung

Harald

Router:AVM7590 1&1 FW:FRITZ!OS 07.56 Anbindung:1&1 50/10 Mb/s, WLAN-Repeater 300E
ELV MAX!Cube, 7xThermostat, ECO, RasPi 4B mit bullseye auf Festplatte,
CUL V 1.67, JeeLink v3_10.1c, nanoCUL, 1xS300TH, 4xHMS100T, 4xELRO, 1xTFA, 2xMAX_FK
ELV MAX!1.4.5, FHEM 5.7 auf RasPi, Kostal PIKO plus

Dietmar63

alles richtig verstanden.
if ( $strStateOld eq "?") {
überprüft, ob der defaultWert gesetzt wurde ... passiert wenn das Gerät in $strShutter nicht gefunden wurde oder das Reading nicht existiert.
Gruß Dietmar
FB7390, CUL, 2 FHT, FS20
modules: 98_WOL.pm, 98_Heating_Control.pm,   98_WeekdayTimer.pm, 98_RandomTimer.pm, 59_Twilight.pm

Harald

Danke für die schnelle Anwort. Aber eine Frage habe ich noch dazu.
Was ist der Defaultwert? Der muss ja auch irgendwo deffiniert werden. Wie und wo kann ich finden, wo dieser Wert festgelegt wird? Oder ist das irgend ein Wert?

Übrigens ist der tatsächliche Wert kein String sondern numerisch (1 bzw. 0). Aber eine Zahl ist ja in Perl auch ein String.

Viele Grüße

Harald
Router:AVM7590 1&1 FW:FRITZ!OS 07.56 Anbindung:1&1 50/10 Mb/s, WLAN-Repeater 300E
ELV MAX!Cube, 7xThermostat, ECO, RasPi 4B mit bullseye auf Festplatte,
CUL V 1.67, JeeLink v3_10.1c, nanoCUL, 1xS300TH, 4xHMS100T, 4xELRO, 1xTFA, 2xMAX_FK
ELV MAX!1.4.5, FHEM 5.7 auf RasPi, Kostal PIKO plus

Gigafix

Hallo Harald

Du hast Dir Deine zweite Frage eigentlich schon in Deiner ersten Anfrage beantwortet:
Der Wert des Readings "cntStateOld" des Gerätes $strShutter wird geladen und der Variablen $strStateOld zugewiesen. Der Defaultwert ist "?".

Hier Dein Eintrag, und darunter die Beschreibung aus der Commandref

ReadingsVal($strShutter,"cntStateOld","?")
ReadingsVal(<devicename>,<reading>,<defaultvalue>)

Also wird dort das Fragezeichen als <defaultvalue> = Defaultwert definiert.

Viele Grüße
Gigafix
VM Synology DS918 | CubieTruck |2x HMLAN | HMUSB | 3x HMWLAN | CCU2 | MAX-Cube | nanoCUL | ZWDongle |

Harald

Hallo Gigafix,

besten Dank für die Aufklärung. Da habe ich wohl zu kompliziert gedacht. Ich hatte vermutet, das das "?" ein Platzhalter für irgend einen besimmten Wert sei. Es ist dann wohl so, dass die if-Abrage tatsächlich prüft, ob der Wert von $strStateOld einen String ? beinhaltet.

Hah - ich glaube jetzt habe ich verstanden: Wenn das Reading leer oder nicht vorhanden ist, wird "?" übernommen und in der if-Abfrage wird geprüft, ob das der Fall ist. Sonst wird der Wert 1 oder 0 (einen anderen gibt es da nicht) in die Variable geschrieben.

Nochmals danke Euch beiden, dass Ihr Euch meiner angenommen habt.

Viele Grüße

Harald
Router:AVM7590 1&1 FW:FRITZ!OS 07.56 Anbindung:1&1 50/10 Mb/s, WLAN-Repeater 300E
ELV MAX!Cube, 7xThermostat, ECO, RasPi 4B mit bullseye auf Festplatte,
CUL V 1.67, JeeLink v3_10.1c, nanoCUL, 1xS300TH, 4xHMS100T, 4xELRO, 1xTFA, 2xMAX_FK
ELV MAX!1.4.5, FHEM 5.7 auf RasPi, Kostal PIKO plus

bugster_de

Hi,

da das Fragezeichen (?) in Perl ja auch andere sematische Bedeutungen hat, sollte man es aus meiner Sicht nicht als Defaultwert verwenden, da es sonst zumindest zu offenen Fragen beim Lesen des Codes kommt. Immer auch mal daran denken, dass FHEM ggf. richtig lange Zeit einfach nur arbeitet und man nach vielen Monaten sich wieder in den Code eindenken soll.

Ich nutze deshalb z.B. immer entweder wirklich sinnvolle Werte, die im weiteren Verlauf der Funktion keinen Schaden anrichten oder halt z.B. das Wort "mydefault" oder so was. Dann wird der Code gleich selbsterklärend.

Viele Grüße
bugster_de

Harald

Hallo zusammen,

ich habe mal wieder eine Frage zur Syntax bzw. zu Perl-Befehlen. Folgende Zeile habe ich in einem Modul:
my $dutycycle = ReadingsVal($IODevName,"dutycycle",0);

In $IODevName steht MAXLAN. MAXLAN hat aber kein Reading = dutycycle. Das steht unter Internals. O.g. Befehl liest aber nicht aus den Internals sondern nur aus den Readings, oder? Jedenfalls bekomme ich keinen gültigen Wert.

Was muss ich schreiben, damit $dutycycle den richtigen Wert bekommt?

Herzlichen Dank schonmal im Voraus für die hilfreichen Antworten.

Viele Grüße

Harald
Router:AVM7590 1&1 FW:FRITZ!OS 07.56 Anbindung:1&1 50/10 Mb/s, WLAN-Repeater 300E
ELV MAX!Cube, 7xThermostat, ECO, RasPi 4B mit bullseye auf Festplatte,
CUL V 1.67, JeeLink v3_10.1c, nanoCUL, 1xS300TH, 4xHMS100T, 4xELRO, 1xTFA, 2xMAX_FK
ELV MAX!1.4.5, FHEM 5.7 auf RasPi, Kostal PIKO plus

betateilchen

#7
Zitat von: Harald am 17 Oktober 2013, 13:24:52O.g. Befehl liest aber nicht aus den Internals sondern nur aus den Readings, oder?

Richtig. Deshalb heißt dieser Befehl ja auch ReadingsVal() und nicht InternalVal(), wie der Befehl, der Dir weiterhelfen könnte :)
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Harald

#8
mni tnx  betateilchen,

das werde ich nachher mal ausprobieren. Diesen Befehl hatte ich nicht gefunden. Aber es gibt ja so viele Perl-Befehle  ;)
Da muss man schon einen ganz fitten Kopf haben oder sich sehr lange damit beschäftigen, dass man das alles weiß.

Schönen Tag noch und viele Grüße

Harald

Nachtrag: Sehr schön, das klappt ausgezeichnet. Nochmals besten Dank für die Hilfe.
Router:AVM7590 1&1 FW:FRITZ!OS 07.56 Anbindung:1&1 50/10 Mb/s, WLAN-Repeater 300E
ELV MAX!Cube, 7xThermostat, ECO, RasPi 4B mit bullseye auf Festplatte,
CUL V 1.67, JeeLink v3_10.1c, nanoCUL, 1xS300TH, 4xHMS100T, 4xELRO, 1xTFA, 2xMAX_FK
ELV MAX!1.4.5, FHEM 5.7 auf RasPi, Kostal PIKO plus

betateilchen

#9
Du machst einen ganz großen Denkfehler:

Zitat von: Harald am 17 Oktober 2013, 13:44:42Aber es gibt ja so viele Perl-Befehle

InternalVal() ist (genau wie ReadingsVal()) überhaupt kein Perl Befehl, sondern eine Funktion, die Rudi in der fhem.pl ausprogrammiert hat und die es somit NUR innerhalb von fhem gibt.

Und die fhem.pl ist immer die erste Anlaufstelle, wenn man sich mit so einer Frage beschäftigt, wie von Dir gestellt. Ich hatte da nur reingeschaut mit der gedanklichen Logik "wenn es ReadingsVal() gibt, könnte es doch auch InternalsVal() geben" - und siehe da, diese beiden Funktionen stehen dort direkt hintereinander.

Man muss also nicht alles wissen, sondern nur wissen, wo man nachschauen kann :)

Warum die eine aber ein s im Namen hat (ReadingsVal) und die andere nicht, kann ich Dir genausowenig beantworten wie die Frage, warum es für diese Funktion keine Vorwärtsdeklaration in der fhem.pl gibt.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Harald

Das ist ein prima Hinweis. Werde ich mir für die Zukunft merken. Da gibt es bestimmt noch vieles nützliches.
Gibt es eigentlich eine Übersicht oder Beschreibung, wie FHEM aufgebaut ist und wie es arbeitet? Ich habe bisher nicht wirklich was passendes gefunden außer Wiki, comref, fhem für Einsteiger usw.

Nochmals Danke und viele Grüße

Harald
Router:AVM7590 1&1 FW:FRITZ!OS 07.56 Anbindung:1&1 50/10 Mb/s, WLAN-Repeater 300E
ELV MAX!Cube, 7xThermostat, ECO, RasPi 4B mit bullseye auf Festplatte,
CUL V 1.67, JeeLink v3_10.1c, nanoCUL, 1xS300TH, 4xHMS100T, 4xELRO, 1xTFA, 2xMAX_FK
ELV MAX!1.4.5, FHEM 5.7 auf RasPi, Kostal PIKO plus

betateilchen

Zitat von: Harald am 17 Oktober 2013, 14:03:01Gibt es eigentlich eine Übersicht oder Beschreibung, wie FHEM aufgebaut ist und wie es arbeitet?

Ganz einfach gesagt, definiert fhem ein Framework mit bestimmten Regeln, an die man sich bei der Entwicklung von eigenen/spezifischen Modulen halten muss. Fhem tut dabei eigenlich selbst nichts anderes, als in einer Endlosschlaufe permanent alle definierten "Geräte" (dazu zählen z.B. auch Logfiles, notify usw.) abzuklappern, um nachzuschauen, ob es irgendwo irgendwas zu tun gibt.

Das ist jetzt wirklich sehr einfach beschrieben, die tatsächliche technische Umsetzung dieses Ablaufs ist natürlich sehr viel komplexer und da steckt schon jede Menge Hirnschmalz und Arbeit drin.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Harald

#12
Besten Dank, so ähnlich habe ich mir das schon gedacht. Und mit dem Gehirnschmalz, das ist schon enorm, so etwas zu entwickeln. Ich glaube, da muss man das schon von der Pike auf gelernt haben. Da kann ich mit meinen Programmierkenntnissen in Assembler auf MC 6202 und Basic (ja, ist schon gefühlte 99 Jahre her) nicht mithalten. Dann kommt noch dazu, dass FHEM und somit Perl ganz neu für mich ist. Da kommen die grauen Zellen ganz schön in's Rotieren. Aber langsam, ganz langsam kommt's. Und wenn man hier fragen kann und so tolle Unterstützung bekommt von den "Wissenden", dann klappt's auch irgendwann mit dem Verstehen.

Nochmals Danke für die Erläuterungen und schönen Tag noch

Harald
Router:AVM7590 1&1 FW:FRITZ!OS 07.56 Anbindung:1&1 50/10 Mb/s, WLAN-Repeater 300E
ELV MAX!Cube, 7xThermostat, ECO, RasPi 4B mit bullseye auf Festplatte,
CUL V 1.67, JeeLink v3_10.1c, nanoCUL, 1xS300TH, 4xHMS100T, 4xELRO, 1xTFA, 2xMAX_FK
ELV MAX!1.4.5, FHEM 5.7 auf RasPi, Kostal PIKO plus

Harald

Hallo zusammen,

ich habe schon wieder so eine Frage: Die Befehlszeile lautetmy $strLastTransmit=ReadingsTimestamp($therm,"msgcnt","");
aber in den Readings des Gerätes gibt es kein "msgcnt" aber in dessen Inernals gibt es "MSGCNT". Muss ich in der FHEM.cfg mittelsattr Computer userReadings msgcnt {InternalVal ("Computer","MSGCNT",0)}mir ein "msgcnt" erzeugen oder gibt es eine Möglichkeit den TimeStamp von "MSGCNT" direkt zu ermitteln?

Vielen Dank in Voraus und viele Grüße

Harald
Router:AVM7590 1&1 FW:FRITZ!OS 07.56 Anbindung:1&1 50/10 Mb/s, WLAN-Repeater 300E
ELV MAX!Cube, 7xThermostat, ECO, RasPi 4B mit bullseye auf Festplatte,
CUL V 1.67, JeeLink v3_10.1c, nanoCUL, 1xS300TH, 4xHMS100T, 4xELRO, 1xTFA, 2xMAX_FK
ELV MAX!1.4.5, FHEM 5.7 auf RasPi, Kostal PIKO plus

betateilchen

Die Internals haben keinen Timestamp, wenn ich mich recht erinnere.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!