userReading - Perl Warning im Log

Begonnen von ekur, 07 Januar 2018, 19:44:06

Vorheriges Thema - Nächstes Thema

ekur

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?
FHEM 5.8 auf Intel NUC, Visualisierung TabletUI auf Lenovo Tab10, Datenlogging MySQL
CUL_HM  HM-CC-RT-DN, HM-RC, HM-LC-BL1-FM, HM-PBI-4-FM, HM-SEC-SD, HM-SEC-SCo
ZWave
OWDevice:DS1420,DS18B20 an Intel NUC

MadMax-FHEM

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
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

rudolfkoenig

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.

ekur

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
FHEM 5.8 auf Intel NUC, Visualisierung TabletUI auf Lenovo Tab10, Datenlogging MySQL
CUL_HM  HM-CC-RT-DN, HM-RC, HM-LC-BL1-FM, HM-PBI-4-FM, HM-SEC-SD, HM-SEC-SCo
ZWave
OWDevice:DS1420,DS18B20 an Intel NUC

viegener

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.

Kein Support über PM - Anfragen gerne im Forum - Damit auch andere profitieren und helfen können

ekur

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.
FHEM 5.8 auf Intel NUC, Visualisierung TabletUI auf Lenovo Tab10, Datenlogging MySQL
CUL_HM  HM-CC-RT-DN, HM-RC, HM-LC-BL1-FM, HM-PBI-4-FM, HM-SEC-SD, HM-SEC-SCo
ZWave
OWDevice:DS1420,DS18B20 an Intel NUC

viegener

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
Kein Support über PM - Anfragen gerne im Forum - Damit auch andere profitieren und helfen können

ekur

Ja, das hat auf jeden Fall geholfen. Danke Dir.
FHEM 5.8 auf Intel NUC, Visualisierung TabletUI auf Lenovo Tab10, Datenlogging MySQL
CUL_HM  HM-CC-RT-DN, HM-RC, HM-LC-BL1-FM, HM-PBI-4-FM, HM-SEC-SD, HM-SEC-SCo
ZWave
OWDevice:DS1420,DS18B20 an Intel NUC