Hallo zusammen,
ich habe mir im Modul HM ein userReading erstellt, dass auf das Reading "ERR_battery" des Moduls reagieren soll und die Anzahl der low Einheiten in das userReading schreiben soll. Das Userreading habe ich wie folgt angelegt:
Bat_Warn {return (split ':',ReadingsVal("HM","ERR_battery", ""))[1] if (split ':',ReadingsVal("HM","ERR_battery", ""))[1]>="1"; return "0"}
Das mit der Abfrage größer gleich 1 habe ich gewählt da das Reading "ERR_battery" nur vorhanden ist wenn eine Einheit den Status battery low meldet und ansonsten nicht vorhanden ist.
Das userReading an sich arbeitet einwandfrei (Bat_Warn gleich 0 wenn alles ok und Anzahl von Low Warnungen wenn vorhanden), aber ich habe jetzt das Problem dass das Log durch den Autoupdate von HM mit folgender Zeile voll geschrieben wird:
PERL WARNING: Use of uninitialized value in numeric ge (>=) at (eval 77364) line 1
Hat jemand einen Ansatz für mich wie ich das userReading umschreiben kann damit ich die Perl Warnung nicht bekomme?
Ich bin mir ja nicht sicher aber:
du nimmst einen Vergleich für Zahlen und vergleichst mit einem String...
also entweder:
if (split ':',ReadingsVal("HM","ERR_battery", ""))[1]ge"1"; return "0"}
oder
if (split ':',ReadingsVal("HM","ERR_battery", ""))[1]>=1; return "0"}
Gruß, Joachim
Perl versucht ein String nach Zahl zu konvertieren, wenn es mit >= vergleicht, und erst wenn das schiefgeht, meckert es.
Vermutlich steht im ersten Wort kein Zahl.
Ich wuerde "attr global stacktrace" setzen, um sicher zu sein, um welchen Perl-Code es geht.
Hallo zusammen,
danke für die schnellen Antworten
@rudolfkönig: Im Reading "ERR_battery" von HM steht "low:1" wenn z.B ein Device eine schlechte Batterie meldet.
@MadMax-FHEM: Leider bringen beide Varianten auch keine Besserung, obwohl ich zuerst dachte das der Stringverlgeich "ge" es wäre.
Mit dem stacktrace gibt es folgendes im Logfile (beide Varianten):
2018.01.07 19:58:48.112 1: PERL WARNING: Use of uninitialized value in string ge at (eval 77727) line 1.
2018.01.07 19:58:48.113 1: eval: {return (split ':',ReadingsVal("HM","ERR_battery", ""))[1] if (split ':',ReadingsVal("HM","ERR_battery", ""))[1]ge"1"; return "0"}
2018.01.07 19:58:48.113 1: stacktrace:
2018.01.07 19:58:48.113 1: main::__ANON__ called by (eval 77727) (1)
2018.01.07 19:58:48.113 1: (eval) called by fhem.pl (4319)
2018.01.07 19:58:48.113 1: main::readingsEndUpdate called by ./FHEM/98_HMinfo.pm (390)
2018.01.07 19:58:48.114 1: main::HMinfo_status called by ./FHEM/98_HMinfo.pm (1582)
2018.01.07 19:58:48.114 1: main::HMinfo_SetFn called by ./FHEM/98_HMinfo.pm (396)
2018.01.07 19:58:48.114 1: main::HMinfo_autoUpdate called by fhem.pl (3063)
2018.01.07 19:58:48.114 1: main::HandleTimeout called by fhem.pl (613)
2018.01.07 20:00:10.418 1: PERL WARNING: Use of uninitialized value in numeric ge (>=) at (eval 77756) line 1.
2018.01.07 20:00:10.418 1: eval: {return (split ':',ReadingsVal("HM","ERR_battery", ""))[1] if (split ':',ReadingsVal("HM","ERR_battery", ""))[1]>=1; return "0"}
2018.01.07 20:00:10.418 1: stacktrace:
2018.01.07 20:00:10.419 1: main::__ANON__ called by (eval 77756) (1)
2018.01.07 20:00:10.419 1: (eval) called by fhem.pl (4319)
2018.01.07 20:00:10.419 1: main::readingsEndUpdate called by ./FHEM/98_HMinfo.pm (390)
2018.01.07 20:00:10.419 1: main::HMinfo_status called by ./FHEM/98_HMinfo.pm (1582)
2018.01.07 20:00:10.420 1: main::HMinfo_SetFn called by fhem.pl (3482)
2018.01.07 20:00:10.420 1: main::CallFn called by fhem.pl (1751)
2018.01.07 20:00:10.420 1: main::DoSet called by fhem.pl (1783)
2018.01.07 20:00:10.420 1: main::CommandSet called by fhem.pl (1167)
2018.01.07 20:00:10.420 1: main::AnalyzeCommand called by ./FHEM/01_FHEMWEB.pm (2463)
2018.01.07 20:00:10.421 1: main::FW_fC called by ./FHEM/01_FHEMWEB.pm (876)
2018.01.07 20:00:10.421 1: main::FW_answerCall called by ./FHEM/01_FHEMWEB.pm (518)
2018.01.07 20:00:10.421 1: main::FW_Read called by fhem.pl (3487)
2018.01.07 20:00:10.421 1: main::CallFn called by fhem.pl (685)
Ich muss leider zugeben, ich werde damit auch nicht schlauer
Die Fehlermeldung sagt, dass der Wert uninitialisiert ist. Da der Wert aus einem split stammt ist entweder im String kein Doppelpunkt vorhanden oder der String ist sogar ganz leer. --> In etwas längerer Form, was Rudi bereits sagte.
Im Prinzip wäre es wohl sinnvoll in das userReading ein Debug einzubauen, dann siehst Du im log-file welcher Wert darinsteht.
Alternativ kannst Du es einfach fehlertolerant machen:
Bat_Warn {my $r = ReadingsVal("HM","ERR_battery", ""); Debug "value :$r:"; return 0 if ( ! $r ); return $1 if ( $r =~ /:\s*(\d+)/ ) }
Ohne das jetzt getestet zu haben und den debug kannst Du entfernen, wenn alles geht.
Hallo viegener,
Danke für die Erklärungen, und ja der String ist ganz leer wenn keine Warnung vorhanden ist.
Dürfte ich Dich noch um ein, zwei Erklärungen oder auch Hinweise bitte damit ich evtl auch verstehe was Du in Deiner Codezeile geschrieben hast, die natürlich funktioniert, danke dafür.
Klar ist mir das Du im ersten Teil den String in eine Variable gesetzt hast und dass das Debug im zweiten Teil für die Anzeige des Originalstrings zwischen zwei : im Log ist.
Jetzt zu den Fragen/Hinweisen:
Im dritten Teil gibst Du Null zurück wenn !$r, ich denke dass das eine Abfrage ist ob der String leer ist, richtig?
Im vierten Teil definierst Du die Rückgabe des Teils 1 ($1) wenn der Vergleich zwischen $r und dem Teil "/:\s*(\d+)/" wahr ist. Aber, kannst Du mir kurz erklären was genau da in dem Teil passiert? Da sind die regexp für Leerzeichen und Zahlen drin, aber ich komme nicht dahinter wie das genau zu interpretieren ist.
Zitat von: ekur am 07 Januar 2018, 22:47:57
Hallo viegener,
Danke für die Erklärungen, und ja der String ist ganz leer wenn keine Warnung vorhanden ist.
Dürfte ich Dich noch um ein, zwei Erklärungen oder auch Hinweise bitte damit ich evtl auch verstehe was Du in Deiner Codezeile geschrieben hast, die natürlich funktioniert, danke dafür.
Klar ist mir das Du im ersten Teil den String in eine Variable gesetzt hast und dass das Debug im zweiten Teil für die Anzeige des Originalstrings zwischen zwei : im Log ist.
Jetzt zu den Fragen/Hinweisen:
Im dritten Teil gibst Du Null zurück wenn !$r, ich denke dass das eine Abfrage ist ob der String leer ist, richtig?
Im vierten Teil definierst Du die Rückgabe des Teils 1 ($1) wenn der Vergleich zwischen $r und dem Teil "/:\s*(\d+)/" wahr ist. Aber, kannst Du mir kurz erklären was genau da in dem Teil passiert? Da sind die regexp für Leerzeichen und Zahlen drin, aber ich komme nicht dahinter wie das genau zu interpretieren ist.
Schön, dass es funktioniert!
Im dritten Teil wird 0 zurückgegeben wenn undefiniert, leerer String oder auch beim Wert 0 - alles dass gilt als logisch falsch und in Deinem Fall auch als keine low-bat
Im vierten Teil mache ich quasi dass, was Du im split gemacht hast ich trenne den Teil abdem Doppelpunkt ab. Allerdings mit dem Regexp genauer auf:
1) Den Doppelpunkt :
2) \s* mögliche TRennzeichen, die zu ignorieren sind (Leerzeichen / Tag etc)
3) Eeine Folge von Ziffern (\d+). Dieser Teil wird durch die Klammern in $1 abgelegt, wenn der regexp auf $r passt. Hier vertraue ich auf die Regel, dass perl bei \d+ soviele Ziffern wie möglich zu erfassen versucht also alle Ziffern in $1 packt
Hoffe das hilft
Ja, das hat auf jeden Fall geholfen. Danke Dir.