Warum kein readingsSingleUpdateIfChanged() ?

Begonnen von mumpitzstuff, 11 Januar 2018, 22:44:11

Vorheriges Thema - Nächstes Thema

mumpitzstuff

Ich habe mich gefragt weshalb es die oben genannte Funktion nicht gibt? readingsBulkUpdateIfChanged() gibt es ja auch. Ich fände es konsequenter beides zu haben. Müsste in etwa so aussehen (nur kurz zusammen kopiert):

sub
readingsSingleUpdateIfChanged($$$$)
{
  my ($hash,$reading,$value,$dotrigger)= @_;
  if($value eq ReadingsVal($hash->{NAME},$reading,"")) {
    return undef;
  } else {
    readingsBeginUpdate($hash);
    my $rv = readingsBulkUpdate($hash,$reading,$value);
    readingsEndUpdate($hash,$dotrigger);
    return $rv;
  }
}


Macht es vielleicht dem einen oder anderen Entwickler etwas leichter...

Sidey

Zitat von: mumpitzstuff am 11 Januar 2018, 22:44:11
Ich habe mich gefragt weshalb es die oben genannte Funktion nicht gibt? readingsBulkUpdateIfChanged() gibt es ja auch. Ich fände es konsequenter beides zu haben. Müsste in etwa so aussehen (nur kurz zusammen kopiert):


Macht es vielleicht dem einen oder anderen Entwickler etwas leichter...

Warum sollte ein Entwickler diese Funktion verwenden?

Grüße Sidey
Signalduino, Homematic, Raspberry Pi, Mysensors, MQTT, Alexa, Docker, AlexaFhem

Maintainer von: SIGNALduino, fhem-docker, alexa-fhem-docker, fhempy-docker

mumpitzstuff

Wenn er ein einzelnes Reading schreiben möchte aber nur wenn sich dieses verändert hat. Wäre das Äquivalent zu readingsBulkUpdateIfChanged() oder habe ich was übersehen. Ich habs neulich jedenfalls mal gesucht und mich gewundert, dass es das nicht gibt.

Sidey

Das habe ich verstanden, aber wieso will ein Entwickler ein Reading nur bei Änderungen schreiben?
Signalduino, Homematic, Raspberry Pi, Mysensors, MQTT, Alexa, Docker, AlexaFhem

Maintainer von: SIGNALduino, fhem-docker, alexa-fhem-docker, fhempy-docker

herrmannj

Zitat von: Sidey am 11 Januar 2018, 23:50:08
Das habe ich verstanden, aber wieso will ein Entwickler ein Reading nur bei Änderungen schreiben?
na macht schon Sinn wenn die Anwendung da ist. Gerät meldet sich an -> ONLINE, meldet sich ab -> OFFLINE. Muss man ja nicht jedes mal das reading aktualisieren nur weil 'ne message reinkommt aus der man online offline entnimmt / ableitet. - oder? Ob das allerdings vom framework gemacht werden muss aber mal im Vorbei-laufen vom Modul selbst ist 'ne andere Frage.

Gerade bei single sollte man das auch so hinbekommen ..

mumpitzstuff

Ob man die ...IfChanged() Funktionen braucht sei mal dahingestellt, Fakt ist aber, für die Block Funktion gibt es sie bereits und wird auch des Öfteren in diversen Modulen verwendet. Mein Vorschlag sollte nur dazu dienen, die Sache rund zu machen. Im Moment empfinde ich das noch nicht so an dieser Stelle.

Sidey

Okay, ich verstehe dass es schon eine Implementierung gibt und hier eine Konsistenz hergestellt werden soll.

Ich betrachte jetzt allerdings die Situation aus einer anderen Perspektive.
Aus Anwendersicht.

Wenn ich jetzt event-on-change-reading und event-on-update Reading als Anwender verstanden habe und einsetze,
dann wäre ich doch sehr überrascht, dass ein Reading nur bei einer Änderung des Inhaltes geändert wird.
Das müsste man dann ja jetzt dem Anwender für jedes Reading mitgeben, wie es aktualisiert wird.

Schon das einfache Beispiel mit online - Offline aufgegriffen:
Wenn online nicht mehr periodisch gesetzt wird , dann könnte ein Anwender nicht durch prüfung des Timestamp darauf schließen, ob es noch online ist. Er wäre darauf angewiesen den Status offline auszuwerten.
Klar, alles machbar aber genau da sehe ich eines der größten Probleme in FHEM.
Es gibt oft 3 oder 4 Möglichkeiten eine Aktion zu definieren.
Jedes Modul hat seine Eigenheiten.
Als Endanwender ist das verdammt schwer zu verstehen.

Mir stellt sich halt die Frage, wozu es gut ist, dem Modul eine Entscheidung zu geben, ob es ein Reading aktualisiert.
Der Vergleich des Wertes dürfte in der Regel die gleiche Anzahl an CPU Zyklen verbrauchen, wie es einfach zu setzen.
Da spart man meiner Meinung nach nichts.

Als Anwender habe ich ja noch immer die Option zu bestimmen, ob der Timestamp immer oder nur bei einer Änderung aktualisiert wird.

Wenn man das jetzt noch rund machen wollte, dann würde man die genannten Attribute in der Funktion auch noch auswerten.
Führt wieder zu Komplexität, gibt dem Endanwender aber wieder die Kontrolle.


Bitte versteht mich nicht falsch.
Konsistenz ist schon gut, aber die sollte sich nicht nur auf die API beschränken, sondern auch hin zum Anwender betrachtet werden.

So als Idee, sollte man vielleicht prüfen, wie man dieses Verhalten in der Commandref beschreiben kann.
Damit bekommen wir meiner Meinung nach, schon einen groben Überblick wie komplex eine solche Änderungen für die Anwender wird.

Grüße Sidey

Gesendet von meinem XT1650 mit Tapatalk

Signalduino, Homematic, Raspberry Pi, Mysensors, MQTT, Alexa, Docker, AlexaFhem

Maintainer von: SIGNALduino, fhem-docker, alexa-fhem-docker, fhempy-docker

Reinerlein

Hi Sidey,

ZitatDer Vergleich des Wertes dürfte in der Regel die gleiche Anzahl an CPU Zyklen verbrauchen, wie es einfach zu setzen.
Da spart man meiner Meinung nach nichts.
und genau diese Annahme ist falsch. Es wird bei jedem Setzen eines Readings zunächst mal immer die komplette Event-Notify-Liste abgearbeitet (es sei denn, das Reading soll niemals ein Event auslösen, was aber für die wenigsten gelten wird).
Also alle Devices, die gerne Aktualisierungen mitbekommen wollen (und sich entsprechend angemeldet haben) werden durchlaufen...
Das kann mal so einiges werden.

Ich habe das in meinem Sonos-Modul z.B. nur so umgesetzt. Die Player liefern jedesmal einen kompletten Satz an Informationen, auch wenn sich z.B. nur der Abspielzustand (Play/Pause) geändert hat.
Da reden wir von ca. 20-30 Readingswerten, die dann sinnlos in einer Eventverarbeitung landen.
Außerdem ist der Timestamp der letzten Lieferung doch gegenüber dem Timestamp der letzten echten Änderung eher unwichtig (es sei denn, man möchte darüber ein Lebenszeichen abbilden, oder Sensorwerte speichern, die sich im letzten Zyklus halt zufällig nicht im Wert verändert haben, dann kann man das als Modulentwickler ja für das dafür vorgesehene Reading anders handhaben)...

Ich habe dafür in meinem Modul eine eigene Implementierung (weil es diesen Mechanismus bei mir schon lange vor der Umsetzung in fhem.pl gab), sehe aber durchaus einen echten Bedarf in einer solchen Update-Routine...
Es gibt halt solche und solche Anwendungsfälle :)

Grüße
Reinerlein

Sidey

Zitat von: Reinerlein am 16 Januar 2018, 23:00:31
und genau diese Annahme ist falsch. Es wird bei jedem Setzen eines Readings zunächst mal immer die komplette Event-Notify-Liste abgearbeitet (es sei denn, das Reading soll niemals ein Event auslösen, was aber für die wenigsten gelten wird).
Also alle Devices, die gerne Aktualisierungen mitbekommen wollen (und sich entsprechend angemeldet haben) werden durchlaufen...
Das kann mal so einiges werden.

Durch Setzen eines Readings werden keine Notifys durchlaufen. Das wird erst durch das Generieren von Events verursacht. Das man hier ein bisschen was an CPU Zeit verbrauchen kann weiss ich. Vor einiger Zeit hatte ich mir das auch viel schlimmer vorgestellt, als es tatsächlich ist.

Um das zu generieren von Events zu verhindern gibt es event-on-change . Das kannst Du als Modul Autor auch beim Erstellen einer Instanz vorbelegen. Der Anwender kann es auch anpassen, ja nach belieben.


Zitat von: Reinerlein am 16 Januar 2018, 23:00:31
Ich habe das in meinem Sonos-Modul z.B. nur so umgesetzt. Die Player liefern jedesmal einen kompletten Satz an Informationen, auch wenn sich z.B. nur der Abspielzustand (Play/Pause) geändert hat.
Da reden wir von ca. 20-30 Readingswerten, die dann sinnlos in einer Eventverarbeitung landen.

Und was spricht gegen die Nutzung der vorhandenen Attribute? Damit kann es der Anwender auch noch anpassen. Wie er es halt benötigt.

Grüße Sidey
Signalduino, Homematic, Raspberry Pi, Mysensors, MQTT, Alexa, Docker, AlexaFhem

Maintainer von: SIGNALduino, fhem-docker, alexa-fhem-docker, fhempy-docker

herrmannj

die Unsitte "event-on-" wurde ja erst eingeführt weil eben (einige) Module ständig events generieren obwohl sich der Zustand nicht ändert.

Daraus jetzt rückwärts abzuleiten das man möglichst oft events erzeugt (der Anwender kann es ja richten) ist doch Unsinn.

Beispiel "online/offline".
ZitatWenn online nicht mehr periodisch gesetzt wird , dann könnte ein Anwender nicht durch prüfung des Timestamp darauf schließen, ob es noch online ist.
Von hinten durchs Auge in die Brust geschossen ...
Warum, um Himmels willen, den timestamp prüfen. ?

Wenn ich wissen möchte on das device online ist prüfe ich das reading. Wenn ich eine Aktion beim "online" werden durchführen möchte erstelle ich ein notify welches das event "online" auswertet. Analog "offline".

Da benötigt man kein eben genau kein "event-on" !

Dieser "event-on" ... Murks ... wurde geschaffen damit Log Einträge gesteuert werden (nur wenn sich was ändert, nur alle 10min usw) was ich sowieso für falsch halte. Das muss im Empfänger passieren.

Sonderfälle gibt es natürlich: Lichtschalter als Taster. Sendet events auch mehrfach ("on" ... "on" ... ). Der hat dann aber konsequenterweise auch keinen Zustand (reading) - weil er eben ein Taster ist.

vg
joerg