[gelöst] Prüfen eines Dummy (ob value defined) funktioniert nicht

Begonnen von Tom Major, 12 Juni 2017, 23:18:39

Vorheriges Thema - Nächstes Thema

Tom Major

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
Früher: FHEM 5.x
Jetzt: RaspberryMatic / ioBroker

DeeSPe

-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
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

Tom Major

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
Früher: FHEM 5.x
Jetzt: RaspberryMatic / ioBroker

CoolTux

Da Du schon so tiefgreifend mit FHEM Funktionen arbeitest, schau Dir doch im SVN wie die Funktion IsDevice() arbeitet  ;)


Grüße
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

DeeSPe

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
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

Tom Major

#5
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
Früher: FHEM 5.x
Jetzt: RaspberryMatic / ioBroker

KernSani

Das heißt, es funktioniert jetzt? Kannst du dann noch [Gelöst] vor das Subject des ersten Posts schreiben?
RasPi: RFXTRX, HM, zigbee2mqtt, mySensors, JeeLink, miLight, squeezbox, Alexa, Siri, ...

Tom Major

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,
Früher: FHEM 5.x
Jetzt: RaspberryMatic / ioBroker

DeeSPe

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
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

Tom Major

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

Früher: FHEM 5.x
Jetzt: RaspberryMatic / ioBroker

DeeSPe

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
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

CoolTux

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.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

Tom Major

#12
@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.
Früher: FHEM 5.x
Jetzt: RaspberryMatic / ioBroker