Hallo,
ich möchte gern für ein paar Dummies aus meiner Konfiguration prüfen, ob sie einen def. Wert haben.
z.B. habe ich das im screenshot gezeigte Dummy momentan mit dem Wert ??? belegt.
Das ist undefined, korrekt?
Folgender Testcode funktioniert nicht so wie ich dachte:
sub func_Test2
{
if (exists($defs{'dy_HZG_Time_LastDay'})) { Log 1, "exists dy_HZG_Time_LastDay"; }
if (defined($defs{'dy_HZG_Time_LastDay'})) { Log 1, "defined dy_HZG_Time_LastDay"; }
my $check = ReadingsVal("dy_HZG_Time_LastDay", "state", -99);
Log 1, "<$check>";
if (!defined($check)) { Log 1, "WARNING, undefined dummy value dy_HZG_Time_LastDay"; }
}
Ausgabe
2017.06.12 23:04:53 1: exists dy_HZG_Time_LastDay
2017.06.12 23:04:53 1: defined dy_HZG_Time_LastDay
2017.06.12 23:04:53 1: <???>
1. Warum kommt in $check nicht -99 zurück?
2. Wenn $check also den Wert ??? hat, warum funktioniert dann die letzte Zeile <if (!defined($check))...> nicht?
3. Was wäre eine saubere Lösung um in Perl den Dummy auf undefined zu prüfen?
Vielen Dank,
Tom
-99 ist nur der Defaulwert der zurückgeliefert wird wenn das Reading nicht gesetzt ist.
Das Reading state ist aber gesetzt denn ???
ist ein gültiger String.
Noch einfacher ist es auf:
if (IsDevice("dy_HZG_Time_LastDay")) {...............}
zu prüfen.
Gruß
Dan
Hallo Dan,
danke für die Ausführungen.
Meine Frage 1. habe ich damit glaub ich verstanden, die -99 kommen nicht zurück da "state" ein vorhandenes reading ist, nur wenn das nicht vorhanden wäre bekäme ich die -99.
Für IsDevice() finde ich einen thread, wo dieses erst im April diesen Jahres eingecheckt wurde für Developer, mein FHEM 5.8. vom Februar hat das wohl nicht (und bringt einen undefined Fehler für diese Funktion auf der Kommandozeile.
Gibt es noch einen anderen Weg?
Und meine 2. Frage
2. Wenn $check also den Wert ??? hat, warum funktioniert dann die letzte Zeile <if (!defined($check))...> nicht?
Vielen Dank,
Tom
Da Du schon so tiefgreifend mit FHEM Funktionen arbeitest, schau Dir doch im SVN wie die Funktion IsDevice() arbeitet ;)
Grüße
Zitat von: Tom Major am 13 Juni 2017, 00:03:14
Für IsDevice() finde ich einen thread, wo dieses erst im April diesen Jahres eingecheckt wurde für Developer, mein FHEM 5.8. vom Februar hat das wohl nicht (und bringt einen undefined Fehler für diese Funktion auf der Kommandozeile.
Gibt es noch einen anderen Weg?
Was spricht gegen Update machen?
Zitat von: Tom Major am 13 Juni 2017, 00:03:14
Und meine 2. Frage
2. Wenn $check also den Wert ??? hat, warum funktioniert dann die letzte Zeile <if (!defined($check))...> nicht?
Was heißt "funktioniert nicht"?
Mit diesem Wert ist $check defined. Du gibst aber nur aus wenn $check nicht defined ist.
Gruß
Dan
Ok, habe IsDevice() testweise in 99_myUtils.pm kopiert.
Damit geht es auch nicht, bei diesem Dummy kommt für diese Funktion auch 1 zurück, 0 wollte ich wegen dem ??? Wert.
Dann noch etwas weiter experimentiert und festgestellt, das der Wert ??? vom Dummy dy_HZG_Time_LastDay tatsächlich ein String mit 3 Fragezeichen ist, ein string compare führt zum Erfolg. Das beantwortet auch meine Frage warum
if (!defined($check)) { Log 1, "WARNING, undefined dummy value dy_HZG_Time_LastDay"; }
nicht zum gewünschten Resultat führte, der Wert ist nicht undef sondern ein echter ??? String.
Irgendwie dachte ich bisher, die ??? stehen nur bei der Ausgabe für ein undef value, ist aber kein echter String, aber zumindest in diesem Fall ist das nicht so. Muss irgendwie mit dem Einlesen des Dummy aus fhem.save zusammenhängen, glaube ich.
Ich habe jetzt meine Check Funktion so geschrieben und decke damit sowohl ein undef als auch den String ??? ab, falls mal jemand auch sowas braucht:
sub func_CheckDummiesForUndefined
{
# array über alle zu prüfenden Dummies
my @Dummy = ( "dy_HZG_Time_LastDay", ... );
my $warnStr = "";
foreach my $i (0 .. $#Dummy) {
my $dummy = $Dummy[$i];
#Log 1, "checking $dummy";
# Check 1
# Mit exists prüft man die reine Existenz eines Hash-Elementes, sein Wert ist egal.
# Mit defined prüft man, ob ein Hash-Element einen Wert anders als "undef" hat. Also neben Existenz des Hash-Elements auch den (Fehler-)wert "undef".
if (!defined($defs{$dummy})) {
my $str = "### WARNING(1) ###, undefined dummy value: $dummy";
Log 1, $str;
$warnStr = $warnStr . $str . "\n";
}
# Check 2
# check auf String "???", wenn das aus fhem.save kommt ist es anscheinend nicht undefined sonder ein echter "???" String, deswegen hier dieser 2. check
if (Value($dummy) eq "???") {
my $str = "### WARNING(2) ###, undefined dummy value: $dummy";
Log 1, $str;
$warnStr = $warnStr . $str . "\n";
}
}
return $warnStr;
}
Grüße Tom
Das heißt, es funktioniert jetzt? Kannst du dann noch [Gelöst] vor das Subject des ersten Posts schreiben?
Hallo KernSani,
ich setze gern den thread auf gelöst, ich würde nur damit noch etwas warten, da mir immer noch nicht klar ist warum der check auf undef nicht funktioniert bzw. warum das value als defined angesehen wird obwohl da ??? steht.
Vielleicht kommt ja noch eine erhellende Antwort, sonst setzte ich den thread bald auf gelöst.
Danke,
Zitat von: DeeSPe am 12 Juni 2017, 23:27:20
Das Reading state ist aber gesetzt denn ???
ist ein gültiger String.
Die erklärende Antwort kam doch schon!
Reicht Dir das nicht? Oder einfach nicht verstanden?
Gruß
Dan
Zitat von: DeeSPe am 15 Juni 2017, 00:03:34
Die erklärende Antwort kam doch schon!
Reicht Dir das nicht? Oder einfach nicht verstanden?
Gruß
Dan
Leider nicht ganz verstanden obwohl mein workaround funktioniert. Meine Frage dazu ist eventuell nicht gut formuliert, ich versuche es noch mal anders:
Da man den code
if (defined($defs{$XXX}))
# Mit defined prüft man, ob ein Hash-Element einen Wert anders als "undef" hat. Also neben Existenz des Hash-Elements auch den (Fehler-)wert "undef".
an verschiedenen Stellen im Forum findet, denke ich das er eine Daseinsberechtigung hat, um auf
undef zu prüfen.
Warum klappt das nicht in meinem Bsp. für mein
undef dummy mit Namen dy_HZG_Time_LastDay? Warum bekomme ich dort nur den
undef Status mit
if (Value($dummy) eq "???") {
raus?
Gibt es zwei Arten von
undef, ein echtes und ein Pseudo, bei dem das Value mir "???" belegt ist, also in Wirklichkeit
defined ist?
Und wenn es in Wirklichkeit defined ist, wo kommt der Wert "???" dann her?
Sorry wenn das eine blöde Frage ist, aber wir sind ja bei Anfängerfragen :)
Grüße Tom
Zitat von: Tom Major am 20 Juni 2017, 22:57:46
Leider nicht ganz verstanden obwohl mein workaround funktioniert. Meine Frage dazu ist eventuell nicht gut formuliert, ich versuche es noch mal anders:
Da man den code
if (defined($defs{$XXX}))
# Mit defined prüft man, ob ein Hash-Element einen Wert anders als "undef" hat. Also neben Existenz des Hash-Elements auch den (Fehler-)wert "undef".
an verschiedenen Stellen im Forum findet, denke ich das er eine Daseinsberechtigung hat, um auf undef zu prüfen.
Warum klappt das nicht in meinem Bsp. für mein undef dummy mit Namen dy_HZG_Time_LastDay? Warum bekomme ich dort nur den undef Status mit
if (Value($dummy) eq "???") {
raus?
Gibt es zwei Arten von undef, ein echtes und ein Pseudo, bei dem das Value mir "???" belegt ist, also in Wirklichkeit defined ist?
Und wenn es in Wirklichkeit defined ist, wo kommt der Wert "???" dann her?
Sorry wenn das eine blöde Frage ist, aber wir sind ja bei Anfängerfragen :)
Grüße Tom
Du verwechselst da wohl was!
if (defined($defs{foo}))
prüft ob überhaupt ein Device mit Namen foo existiert.
Value("foo")
gibt Dir den Wert von STATE vom Device foo zurück.
???
in STATE bedeutet eigentlich nur dass noch kein STATE gesetzt wurde. Da die drei Fragezeichen ein gültiger String sind ist das damit nicht undef.
Gruß
Dan
Kleine Vereinfachung. Der STATE ist schon gesetzt. Es ist nichts weiter wie ein dummy Default Wert. Der eigentlich Zustand ist halt nicht bekannt. Sobald Du einen anderen Wert setzt, zum Beispiel durch set dummy on , wird auch das STATE Value entsprechend gesetzt.
@DeeSPe und @CoolTux, Danke für Eure Erklärungen, STATE ist der Schlüssel, jetzt habe ich es verstanden.
Grüße Tom
Edit: Thread auf [gelöst] gesetzt.