Warnung aus readingsBulkUpdate

Begonnen von Elektrolurch, 31 Oktober 2014, 12:26:10

Vorheriges Thema - Nächstes Thema

Elektrolurch

Hallo,

leider ist "Fehlermeldungen" ja geschlossen, daher hoffe ich, dass jemand den kleinen Bugfix einschecken kann:

2014.10.31 09:43:44 1: ReadingsBulkUpdate: value: 0.0336111111111111 name: Ku_Deckenlampe reading: power-hourly - value or rd->val not defined
2014.10.31 09:43:44 1: PERL WARNING: Use of uninitialized value in string ne at fhem.pl line 3678.
Das tritt immer dann auf, wenn das reading keinen Wert hat oder noch nicht existiert:

fhem.pl:
Log(1,"ReadingsBulkUpdate: value: $value name: $hash->{NAME} reading: $reading - value or rd->val not defined") if(!defined($value) || !defined($readings->{VAL}));
    $changed= !($attreocr || $attreour)
              || $eour 
              || ($eocr && ($value ne $readings->{VAL}) && $threshold_reached);


($value ne $readings->{VAL})
müste ersetzt werden durch:

defined($readings->{VAL) && ($value ne $readings->{VAL})

Gruß

Elektrolurch

configDB und Windows befreite Zone!

rudolfkoenig

Deine Aenderung wuerde die Meldung in der Tat vermeiden, allerdings bin ich noch nicht sicher, ob das sinnvoll ist. Readings ohne VAL finde ich nicht in Ordnung, und sollte mAn gefixt werden. Oder mir erklaert jemand, warum man hier eine Ausnahme machen sollte.

Elektrolurch

Ich muss es noch Mal gegenchecken, aber ich glaube, die Meldung kommt auch, wenn das reading nicht existiert und nicht nur der val.
configDB und Windows befreite Zone!

betateilchen

Zitat von: rudolfkoenig am 01 November 2014, 00:21:57
Readings ohne VAL finde ich nicht in Ordnung, und sollte mAn gefixt werden. Oder mir erklaert jemand, warum man hier eine Ausnahme machen sollte.

Hm... ich kann Dir schon erklären, wie es zu Readings ohne VAL kommen kann:

Wenn man ein Modul hat, das eine bestimmte "Liste" von möglicherweise vorhandenen Readings füllen möchte und dazu diese Liste abarbeitet, ohne im Vorfeld zu wissen, ob es für das jeweilige Reading überhaupt einen Wert geben kann.

Als Beispiel passiert sowas beispielsweise in meinem GDS Modul, in dem ein Array von Hashes sämtlicher eventuell vorhandener Wetterdaten in einer Schleife abgearbeitet wird, und an ReadingsBulkUpdate jeweils ein ReadingName und ein ReadingValue übergeben wird, unabhängig davon, ob ein ReadingValue existiert.

Je nach verwendeter Wetterstation sind nämlich nicht immer alle möglichen Wetterwerte vorhanden, sondern nur eine Teilmenge davon.

Bisher habe ich mich immer auf die bestehende und sehr zuverlässige "Logik" gestützt, dass BulkUpdate einfach keine Readings ohne Wert anlegt.

Es wäre natürlich nicht schwer, dies  in meinem Modul abzufangen. Aber man würde damit auf ein Stück liebgewonnener Logik in Deiner fhem.pl verzichten müssen. Bin mir auch nicht ganz sicher, ob ich der einzige bin, der sich bisher in seinem Modul auf diese schöne Logik verläßt.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

rudolfkoenig

Zitatich kann Dir schon erklären, wie es zu Readings ohne VAL kommen kann:
Dann musst du das so machen, dass ich es verstehe, am besten mit Code. Ich will nicht mit Raten anfangen.

betateilchen

Das hab ich doch lang und breit erklärt? Welchen Teil hast Du nicht verstanden, sodass Du raten musst?



-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Joachim

Moin Rudi,
siehe z.B. hier:
http://forum.fhem.de/index.php/topic,28047.0.html
In Antwort 3 habe ich für OWMULTI den Ablauf beschrieben.
Da ist das Problen deshalb aufgetaucht, weil der "Container" für $hash->{READINGS} angelegt wird für weitere Informationen, bevor das erste Reading existiert.

Gruß Joachim
FHEM aktuellste Version auf FB 7570 und 7390 mit Zebradem Toolbox Freetz
FHEM auf Raspberry
1-Wire mit LinkUSBi und Rs-Pi ds2482-800  1-Wire-9 Board; Max mit Cube, HMLAN
div. 1-Wire Sensoren; MAX-Thermostaten; Homematic-Komponenten, Zehnder KWL über RS-232

betateilchen

Hier sammle ich die (möglicherweise vorhandenen) Daten aus dem XML File nach %readings


my (%readings, @dummy, $i, $k, $n, $v, $t);

# topLevel informations
@dummy = split(/\./, $alertsXml->{identifier});

$readings{a_identifier} = $alertsXml->{identifier} if($_gdsAll || $_gdsDebug);
$readings{a_idPublisher} = $dummy[5] if($_gdsAll);
$readings{a_idSysten} = $dummy[6] if($_gdsAll);
$readings{a_idTimeStamp} = $dummy[7] if($_gdsAll);
$readings{a_idIndex} = $dummy[8] if($_gdsAll);
$readings{a_sent} = $alertsXml->{sent};
$readings{a_status} = $alertsXml->{status};
$readings{a_msgType} = $alertsXml->{msgType};

# infoSet informations
$readings{a_language} = $alertsXml->{info}[$info]{language} if($_gdsAll);
$readings{a_category} = $alertsXml->{info}[$info]{category};
$readings{a_event} = $alertsXml->{info}[$info]{event};
$readings{a_responseType} = $alertsXml->{info}[$info]{responseType};
$readings{a_urgency} = $alertsXml->{info}[$info]{urgency} if($_gdsAll);
$readings{a_severity} = $alertsXml->{info}[$info]{severity} if($_gdsAll);
$readings{a_certainty} = $alertsXml->{info}[$info]{certainty} if($_gdsAll);

# eventCode informations
# loop through array
$i = 0;
while(1){
($n, $v) = (undef, undef);
$n = $alertsXml->{info}[$info]{eventCode}[$i]{valueName};
if(!$n) {last;}
$n = "a_eventCode_".$n;
$v = $alertsXml->{info}[$info]{eventCode}[$i]{value};
$readings{$n} .= $v." " if($v);
$i++;
}

# time/validity informations
$readings{a_effective} = $alertsXml->{info}[$info]{effective} if($_gdsAll);
$readings{a_onset} = $alertsXml->{info}[$info]{onset};
$readings{a_expires} = $alertsXml->{info}[$info]{expires};
$readings{a_valid} = checkCAPValid($readings{a_expires});
$readings{a_onset_local} = capTrans($readings{a_onset});
$readings{a_expires_local} = capTrans($readings{a_expires});
$readings{a_sent_local} = capTrans($readings{a_sent});

# text informations
$readings{a_headline} = $alertsXml->{info}[$info]{headline};
$readings{a_description} = $alertsXml->{info}[$info]{description} if($_gdsAll || $_gdsLong);
$readings{a_instruction} = $alertsXml->{info}[$info]{instruction} if($readings{a_responseType} eq "Prepare"
&& ($_gdsAll || $_gdsLong));

# area informations
$readings{a_areaDesc} =  $alertsXml->{info}[$info]{area}[$area]{areaDesc};
$readings{a_areaPolygon} =  $alertsXml->{info}[$info]{area}[$area]{polygon} if($_gdsAll || $_gdsPolygon);

# area geocode informations
# loop through array
$i = 0;
while(1){
($n, $v) = (undef, undef);
$n = $alertsXml->{info}[$info]{area}[$area]{geocode}[$i]{valueName};
if(!$n) {last;}
$n = "a_geoCode_".$n;
$v = $alertsXml->{info}[$info]{area}[$area]{geocode}[$i]{value};
$readings{$n} .= $v." " if($v);
$i++;
}

$readings{a_altitude} = $alertsXml->{info}[$info]{area}[$area]{altitude} if($_gdsAll);
$readings{a_ceiling} = $alertsXml->{info}[$info]{area}[$area]{ceiling} if($_gdsAll);


Hier gehe ich in einer Schleife über %readings und übergebe Namen und Werte an readingsBulkUpdate.
Zu diesem Zeitpunkt existiert noch KEINES der möglichen Readings.


readingsBeginUpdate($hash);
while(($k, $v) = each %readings){
readingsBulkUpdate($hash, $k, $v); }
readingsEndUpdate($hash, 1);

-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

rudolfkoenig

@Joachim: $hash->{READINGS} ist nicht das Problem, sondern dass jemand $hash->{READINGS}{"power-hourly"} angelegt hat, ohne $hash->{READINGS}{"power-hourly "}{VAL} zu fuellen.
@betateilchen: in deinem Fall sollte es auch kein Problem geben, da am Anfang $hash->{READINGS}{$v} nicht angelegt ist.

Entweder gibts ein Reading nicht, oder es ist richtig angelegt. Ich wehre mich nur gegen halb-angelegte Readings.

Elektrolurch

Hallo Rudi,

siehe oben, das reading existierte in meinem Beispiel nicht mehr, da mit delete gelöscht.
Außerdem kann val auch ein "undef" enthalten, warum auch immer.
Was ist der Sinn der Abfrage in der fhem.pl / readingsBulkUpdate?
Das Update soll nur dann u.a. erfolgen, wenn der Wert nicht gleich dem neuen Wert ist.
Das heißt doch umgekehrt: Wenn das reading und/oder der Wert nicht existiert, dann update machen.

Gruß

Elektrolurch
configDB und Windows befreite Zone!

Joachim

@ Rudi,
In OWMULTI ist es ja jetzt auch gelöst, das "Problem" entsteht dann, wenn man bei der Initialisierung des Moduls, z.B. Einheiten oder variable weitere Bezeichnungen erzeugt.
Bei OWMULTI z.B.:

$hash->{READINGS}{$owg_channel}{TYPE} = $cnama[1];
$hash->{READINGS}{$owg_channel}{UNIT} = $unarr[0];
$hash->{READINGS}{$owg_channel}{UNITABBR} = $unarr[1];

Dann existiert Der "Container" $hash->{READINGS}{"power-hourly"} schon für TYPE, UNIT, UNITABBR aber noch nicht für VAL, da das erst beim readingsBulkUpdate angelegt wird.
Abfangen kann man das entweder im Modul bei der Initialisierung, oder in der fhem.pl.
Was nun der "saubere" Weg ist, weiß ich nicht.

Gruß Joachim
FHEM aktuellste Version auf FB 7570 und 7390 mit Zebradem Toolbox Freetz
FHEM auf Raspberry
1-Wire mit LinkUSBi und Rs-Pi ds2482-800  1-Wire-9 Board; Max mit Cube, HMLAN
div. 1-Wire Sensoren; MAX-Thermostaten; Homematic-Komponenten, Zehnder KWL über RS-232

rudolfkoenig

@Joachim:
solche Eintraege (TYPE/UNIT/etc) werden nicht unterstuetzt, z.Bsp. nicht gespeichert.
Wenn du sie unbedingt haben willst, dann bitte sicherstellen, dass die notwendigen Werte VAL und TIME gesetzt werden, z.Bsp. readingsBulkUpdate vorher aufrufen.
Falls man unsicher ist, sollte man $hash->{READINGS} nicht direkt anfassen, sondern nur ueber die angebotenen Routinen.

@Elektrolurch:
VAL kann kein undef enthalten, wenn es ueber readingsBulkUpdate gesetzt wird.
Falls man ein reading entfernt, dann sollte man es komplett entfernen.

-> Ich finde die Fehlermeldung immer noch ok.

Joachim

Zitatsolche Eintraege (TYPE/UNIT/etc) werden nicht unterstuetzt, z.Bsp. nicht gespeichert.
Wenn du sie unbedingt haben willst,
War mir klar, und OWMULTI ist nicht meins, fand das nur als Beispiel recht gut.

Gruß Joachim
FHEM aktuellste Version auf FB 7570 und 7390 mit Zebradem Toolbox Freetz
FHEM auf Raspberry
1-Wire mit LinkUSBi und Rs-Pi ds2482-800  1-Wire-9 Board; Max mit Cube, HMLAN
div. 1-Wire Sensoren; MAX-Thermostaten; Homematic-Komponenten, Zehnder KWL über RS-232

betateilchen

Zitat von: rudolfkoenig am 02 November 2014, 11:33:37

@betateilchen: in deinem Fall sollte es auch kein Problem geben, da am Anfang $hash->{READINGS}{$v} nicht angelegt ist.


Dann bin ich ja beruhigt. Nichtsdestotrotz werde ich das GDS bei Gelegenheit dahingehend ändern, dass readingsBulkUpdate nur dann aufgerufen wird, wenn es überhaupt einen Wert für das Reading gibt.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Elektrolurch

delete($hash->{READINGS}{'min-Laststellung'});

ist doch sauber entfernt?
Und auch dann kommt die Warnung aus readingsBulkUpdate,
aber das hatte ich ja schon oben geschrieben....
configDB und Windows befreite Zone!