Einstieg: Internals, Attribute, Readings und weitere Anfängerfragen (Ver. 1.2)

Begonnen von andies, 01 Mai 2017, 21:24:31

Vorheriges Thema - Nächstes Thema

andies

Ich merke, nachdem ich nun ein wenig herumgespielt habe, dass mir an einigen Stellen doch ein Grundverständnis fehlt. Hinzu kommt, dass die Ausführungen im Wiki oder der Doku nicht so sind, dass ich sie wirklich verstehe (zwei Beispiele: Das Wort "Internals" kommt in der sehr guten Doku nur zweimal vor - dabei sollte schon wichtig sein zu wissen, was das ist; im Wiki lese ich, dass Readings Anwenderinfos sind, die "für Menschen lesbar sind" - das sind Internals auch usw usf.).

Daher versuche ich mir selbst die Sache klar zu machen und würde mich freuen, wenn ich Tipps und Fehlerhinweise kriege. Danach würde ich versuchen, das in das Wiki einzutragen. Also ich fange mal an und bitte darum mich zu korrigieren.

------------------------------------------------------------------------------------------------



  • Devices sind das Grundgerüst von FHEM. FHEM funktioniert, weil devices miteinander kommunizieren. Typische devices sind beispielsweise Funksteckdosen, Rolladenmotoren, Temperaturmessgeräte, Magnetventile usw. Aber andere Dinge, die man auf den ersten Blick nicht als physisches Gerät bezeichnen würde, sind device: So etwa ist die Benutzeroberfläche von FHEM selbst ein device ("FHEMWEB"), ebenso gibt es devices ohne physische Geräte (dummys genannt), die dazu benutzt werden können, um eine Variable zu speichern.

  • Zuerst einmal muss ein devices einen "Typ" haben, der gleichzeitig die Perl-Befehlsdatei (man spricht präziser vom "Modul") festlegt, in der bestimmte Routinen und Eigenschaften dieses Typs festgehalten sind. Ist etwa ein device vom Typ CALENDAR, so weiß FHEM, dass die Routinen und Eigenschaften im Modul  57_CALENDAR.pm liegen. Die Zahl 57 hatte früher eine Bedeutung, heute ist das nicht mehr der Fall. Aus historischen Gründen wird sie aber immer noch verwendet.

  • Devices haben einen Zustand, der sich im Zeitablauf ändert. So ist beispielsweise ein Fenster offen, ein Rolladenpanzer geschlossen und eine Funksteckdose hat Spannung. Ein Zustand muss dabei nicht exakt eine Variable beinhalten (Tür entweder "offen" oder "geschlossen"), ein Zustand kann auch durch mehrere Variablen beschrieben werden (der Zustand eines Raspberry-Systems, device-type sysmon, umfasst beispielsweise die CPU-Frequenz, die CPU-Temperatur, den load und vieles mehr). Jede einzelne Variable eines Zustands wird durch eine Zeichenkette erfasst.

    Perl ist eine Programmiersprache, bei der zwischen Groß- und Kleinschreibung unterschieden wird. Insofern ist STATE etwas anderes als state. Auch kann es sein, dass Zeichenketten (in Abhängigkeit von der Anwendung) Perlbefehle oder reguläre Ausdrücke enthalten. Für einen Anfänger ist es so etwas nicht immer leicht zu erkennen.

    Wir unterscheiden drei wichtige Elemente, die einen Zustand eines devices beschreiben: Internals, Attribute und Readings. Wenngleich die Unterschiede nicht immer ganz präzise ausgemacht werden können und so mancher Übergang fließend ist, so lässt sich doch folgendes sagen. Alle drei sind natürlich wieder Zeichenketten.

    Internals sind Zeichenketten, die vom Nutzer nicht direkt verändert werden sollen. Oft enthalten sie ganz grundlegende Informationen zu dem device. Irritierend mag sein, dass eine, aber eben auch nur eine wichtige  Größe dabei der STATE genannt wird -- und STATE heißt übersetzt "Zustand". Die anderen Internals charakterisieren unter Umständen auch den Zustand des devices, heißen dann aber nicht mehr STATE. Soll ein Internal eines devices durch Perl ausgelesen werden, so ist die Funktion InternalVal() zu verwenden.

    Attribute sind Zeichenketten, die vom Anwender typischerweise verändert werden können. Sie sollen das Verhalten des Gerätes steuern. Jedes Modul hat eine Reihe von vordefinierten Attributen, so etwa "room" oder "group", die beide festlegen, wie das device in einem Frontend (etwa einer Weboberfläche) dargestellt wird. So kann ein device in mehreren Räume zu "finden" sein, innerhalb eines Raumes wird es dann in einer "Gruppe" erfasst. Kennzeichnend sowohl für Attribute als auch für Internals ist es, keinen Zeitstempel zu besitzen.  Soll ein Attribut eines devices durch Perl ausgelesen werden, so ist die Funktion AttrVal() zu verwenden.

    Zuletzt gibt es Readings. Auch hier handelt es sich um Zeichenketten, die aber mit einem Zeitstempel versehen sind. Reading sollen Messwerte (Zustände) des Gerätes beschreiben. Für Readings ist es gerade typisch, dass sie während der Laufzeit vom Anwender oder FHEM verändert werden. Verwirrend für einen Anfänger kann sein, dass manchmal Internals wie auch Readings mit gleichem Namen (STATE) existieren können -- die bereits erwähnte Berücksichtigung auf die Groß- und Kleinschreibung sorgt aber dafür, dass es sich um verschiedene Objekte handelt. Soll ein Reading eines devices durch Perl ausgelesen werden, so ist die Funktion ReadingsVal() zu verwenden, ReadingsTimestamp() gibt den Zeitstempel zurück.

    STATE ist eine Größe, die in allen Modulen zu finden ist. Es gibt Fälle, in denen STATE ausschließlich die Nachricht 'initialized' enthält. In anderen Fällen stehen Werte (Zahlen, Texte) im STATE. Die Darstellung des Inhaltes von STATE lässt sich verändern. Um dies zu tun, muss das device ein spezielles Attribut besitzen, der Anwender muss es anlegen. Das Attribut lautet 'stateFormat' und muss den Code enthalten, mit dessen Hilfe aus dem Inhalt von STATE die nun neue Anzeige erstellt wird. 

    Halten Sie insbesondere Attribute und Readings auseinander. So sind Fragen der Form "Wieso gelingt es mir nicht, mit ReadingsVal() das Attribut Sowieso auszulesen?" oder "Wieso gibt es eine Fehlermeldung, wenn ich den Timestamp des Attributs beeinflussen will?" oder "Wieso geht 'attr <device> <reading> <wert>' nicht?!" falsch gestellt, weil dort unverträgliche Begriffe in einen Topf geworfen werden.

    Attribute eines devices können direkt in FHEM manipuliert werden. Dazu dient der Befehl "attr <device> <Attributname> <Wert>". Das Gerät <device> muss hierzu natürlich vorab definiert sein. Auch Readings können manipuliert werden, hier ist jetzt allerdings der Befehl "setreading <device> <Readingname> <Wert>" zu verwenden; üblicherweise sollte dies aber nicht bei den Readings geschehen, die durch das Modul von vornherein definiert werden (eine Fehlfunktion könnte die Folge sein). setreading ist insbesondere für Readings gedacht, die vom Anwender "hinzudefiniert" werden. Entsprechend der Philosophie, wonach Internals nicht direkt vom Anwender manipuliert werden sollen, existiert logischerweise keine Funktion "setinternal" oder ähnlich.

    In einigen Fällen sind Objekte eines devices von Interesse, die weder Internal, noch Attribut oder Reading sind. Denken Sie an den Fall eines IP-Kamera-devices und einen Schnappschuss dieser Kamera. Der Schnappschuss selbst ist eine Bilddatei und daher streng genommen keine Zeichenkette, auch findet sich der Inhalt der Datei nicht unter Internals, Readings oder Attributen eines IPCam-devices wieder. Dennoch benötigt man den Schnappschuss, weil dies eines der entscheidenden Anwendungen für IP-Kameras darstellt. Ein ähnlich gelagerter Fall liegt bei einem Feiertagsmodul vor; hier wurde der Name des Feiertages weder unter "Reading" oder "Internal" subsummiert.

    Um daher auf solche weitere Größen eines devices zugreifen zu können, wird ein weiterer Befehl benötigt. Es handelt sich um "get <device> <manchmal_weiteres_Wort>". Im Fall einer IP-Kamera beispielsweise lautet ein entsprechender Schnappschuss "get kamera image", beim Feiertagsmodul schreibt man dagegen "get <device> today". get wird normalerweise nicht zum Auslesen von Readings oder Attributen verwendet.

    Analog kann in einem Modul sein set-Befehl Anwendung finden. Hierbei gibt es, im Gegensatz zu get, aber typischerweise keine Rückmeldung seitens des Moduls. Set-Befehle können weitere interne Größen verändern oder auch vordefinierte Kommandos auslösen. Im Fall eines Schalters beispielsweise wird so der Schalter ein- oder ausgeschaltet.

  • Devices kommunizieren über Events miteinander. Ein device sendet ein Event an FHEM und FHEM verteilt dieses Event an alle devices. Diese wiederum entscheiden dann, ob und wie sie darauf reagieren. Ob ein Event gesendet wird, kann durch die Attribute  event-on-change-reading und event-on-update-reading gesteuert werden.

    Events sind dabei Zeichenketten mit Timestamp, die Internals, Attributen und/oder Readings eines devices verändern.

Haut das ungefähr hin? Fehlt etwas wichtiges? Ist etwas grundsätzlich falsch?
FHEM 6.1 auf RaspPi3 (Raspbian:  6.1.21-v8+; Perl: v5.32.1)
SIGNALduino (433 MHz) und HM-UART (868 MHz), Sonoff, Blitzwolf, Somfy RTS, CAME-Gartentor, Volkszähler, Keyence-Sensor, Homematic-Sensoren und -thermostat, Ferraris-Zähler für Wasseruhr, Openlink-Nachbau Viessmann

Thorsten Pferdekaemper

Zitat von: andies am 01 Mai 2017, 21:24:31ebenso gibt es "leere devices" (auch dummy), die nur dazu da sind, einen Befehl auszulösen.
Daran würde ich bei dummys eher nicht denken. Zumindest kann man mit dummys viel mehr machen, z.B. beliebige Readings setzen und damit sozusagen neue Geräte basteln.

ZitatDie Zahl 57 hatte früher eine Bedeutung, heute ist das nicht mehr der Fall. Aus praktischen Gründen wird sie aber immer noch verwendet.
Ich würde mal eher sagen aus historischen Gründen. Was ist daran "praktisch"?

ZitatZudem gibt es Kommandos, die man einem device zuordnen kann; diese heißen webcmd.
Das steht irgendwie ziemlich unmotiviert mitten in der Beschreibung zu Attributen. Außerdem halte ich webcmd nicht für grundlegend. Ich habe es noch nie gebraucht.

Zitat[Ich habe hier einen Fall, wo es ein Internal STATE und ein Reading state gibt.
Das ist doch sogar meistens so, oder?   

ZitatDas wichtigste Internal dürfte "STATE" sein, das auf der Weboberfläche und in vielen Apps eine besondere Stellung einnimmt. Das Format des STATE wird in allen Modulen vorprogrammiert,
Naja, "ordentliche" Module lassen STATE ganz in Ruhe. Per Default wird es vom Reading state übernommen.

Gruß,
    Thorsten
FUIP

KernSani

@andies: Grundsätzlich finde ich es gut, dass du dieses Thema aufgreifst und im Großen und Ganzen einen vernünftigen Vorschlag erarbeitet hast. Die Kommentare von Thorsten sind aus meiner Sicht durchgehend valide.
Für Internals, Readings und Attribute gibt es ein (technische) Definition im Wiki
Internals sind in weiten Teilen systemweit vorgegeben und sind für das korrekte Funktionieren von FHEM notwendig.
Readings sind Daten, welche von einem Gerät gelesen werden und in FHEM in einer für Menschen verständlichen Form zur Verfügung gestellt werden können. Sie geben den Status des Gerätes wieder und erzeugen Events innerhalb von FHEM auf die andere Geräte reagieren können.
Attribute dienen dazu, dass der Nutzer das Verhalten einer einzelnen Gerätedefinition zur Laufzeit individuell anpassen kann

zu 1.) Warum ausgerechnet Somfy-Motoren?
zu 2.) Um präzise zu sein, definiert das Modul selbst, über welche Events es informiert werden will (meistens sind das alle)
zu 4.) siehe oben und: Readings werden normalerweise nicht vom Anwender verändert, sondern vom physischen Gerät oder als Reaktion auf ein Event. Der Unterschied zwischen Readings und Attributen ist meines Erachtens ziemlich klar (insbesondere mit o.g. Definition)
zu 5.) INTERNAL STATE und reading state spiegeln den internen Status (STATE) und den vom device empfangenen Status (state) des Devices wieder. Wie von Thorsten schon gesagt, sollten diese in der Regel identisch sein, Ausnahmen gibt es z.B. wenn das eventmap Attribut gesetzt is, dann enthält das reading, den "gelesenen" Status umd STATE den gemappten Status.

Grüße,

Oli 
RasPi: RFXTRX, HM, zigbee2mqtt, mySensors, JeeLink, miLight, squeezbox, Alexa, Siri, ...

andies

Vielen Dank für Eure Hinweise. Ich mache das jetzt so, dass ich die in den originalen Post einarbeite, das erscheint mir übersichtlicher. Ich will noch eine grundsätzliche Anmerkung zu folgendem Zitat treffen 

Zitat von: KernSani am 01 Mai 2017, 23:50:48
Für Internals, Readings und Attribute gibt es ein (technische) Definition im Wiki
Internals sind in weiten Teilen systemweit vorgegeben und sind für das korrekte Funktionieren von FHEM notwendig.
Readings sind Daten, welche von einem Gerät gelesen werden und in FHEM in einer für Menschen verständlichen Form zur Verfügung gestellt werden können. Sie geben den Status des Gerätes wieder und erzeugen Events innerhalb von FHEM auf die andere Geräte reagieren können.

Das sind genau die Stellen, an denen ich als Anfänger gestutzt habe (ich weiß noch, dass ich eine halbe Stunde ratlos vor dem Wikieintrag saß). Wenn Readings für Menschen verständlich sind, heißt es dann, dass Internals das nicht sind - denn anderenfalls ergibt die Definition keinen Sinn. Aber Programmierer sind auch Menschen und wieso können die dann die Internals nicht verstehen? Weiter: Internals sind zum korrekten Funktionieren notwendig. Aber Readings doch auch?! Ohne Readings funktionieren die devices nicht, weil sie die Infos nicht weitergeben.

Ich gebe sofort zu, dass meine Fragen und auch meine Ausführungen zu einer speziellen Klientel passen: Keine Programmierer und wenn, dann hobbyhaft (sieht man an meinem grottigen Code); wenig Vorkenntnisse; geringe Fähigkeiten, sich in die Logik eines Servers einzuarbeiten. Denen muss man alles von Anfang an erklären, was zum Teufel heißt "@_[0]"?!?! In einem anderen Thread klang durch, dass es den einen oder anderen gibt, der sich mit diesen Leuten nicht so viel abgeben will. Dafür habe ich Verständnis. Es gibt Gruppen, da will man loslegen und nicht bei jedem neuen schon wieder beim Urschleim anfangen müssen, denn sonst kommt man nie vorwärts (schon mal mit einem Anfänger in einer Gruppe Ski gefahren?).  Dennoch: Hier gilt, dass ich einen Zugang zum Wiki bekommen habe und das mir erlaubt wurde, die Software zu nutzen. Dann muss ich auch den Leuten, die wie ich wenig oder keinen Plan haben, den Gefallen tun und deren Fragen zulassen. Wenn nicht, dann müsst Ihr klar sagen "Wer die folgenden X Perl-Aufgaben nicht lösen kann, darf hier nicht rein". Das aber scheint mir nicht mehrheitsfähig zu sein.

Und wenn ich Euch schon mal "an der Strippe" habe, noch ein paar Fragen.

  • Was genau (formal) sind Events? Sind das auch Zeichenketten mit timestamp und device?
  • Wie werden Zeitbefehle abgearbeitet? Gibt es da ein device, das Zeitgeber ist? Welches ist das und wie oft sendet das?
  • Mir ist nicht ganz klar, wann "get" und "set" verwendet wird. "attr" setzt ein Attribut. Was setzt "set" bzw holt "get" (Reading? Internal?)?
Danke für die Geduld!
FHEM 6.1 auf RaspPi3 (Raspbian:  6.1.21-v8+; Perl: v5.32.1)
SIGNALduino (433 MHz) und HM-UART (868 MHz), Sonoff, Blitzwolf, Somfy RTS, CAME-Gartentor, Volkszähler, Keyence-Sensor, Homematic-Sensoren und -thermostat, Ferraris-Zähler für Wasseruhr, Openlink-Nachbau Viessmann

Wzut

Zitat von: andies am 02 Mai 2017, 09:24:17
Mir ist nicht ganz klar, wann "get" und "set" verwendet wird. "attr" setzt ein Attribut. Was setzt "set" bzw holt "get"
Für den Modul Autor ist da kein Unterschied, er kann mit beiden Befehlen jede Art von Aktion im Modul auslösen.
Es ist aber allgemein üblich das Set im Erfolgsfall nichts (bzw. undef) zurück gibt - also wie bei deinem Chef : Schweigen bedeutet Zustimmung :
set Lampe on -> Reaktion im im Erfolgsfall : nichts , das Licht geht einfach nur an.
Erhält man aber eine Meldung, dann ist es zu 99,9% eine Fehlermeldung.
Bei Get möchte man aber (unbedingt) etwas vom Gerät haben und das wird i.d.R. dann im Webfrontend auch in einem PopUp Fenster angezeigt :
get Radio volume -> PopUp mit z.B. 50%
Maintainer der Module: MAX, MPD, UbiquitiMP, UbiquitiOut, SIP, BEOK, readingsWatcher

Thorsten Pferdekaemper

Zitat von: KernSani am 01 Mai 2017, 23:50:48Internals sind in weiten Teilen systemweit vorgegeben und sind für das korrekte Funktionieren von FHEM notwendig.
Naja, ich bin mir nicht sicher, dass alle Internals für das korrekte Funktionieren notwendig sind. Soweit ich verstehe, soll das eine Dokumentation aus Benutzersicht werden. Für mich z.B. ist ganz einfach zu beantworten, was Internals und was Readings sind. Internals sind "direkte" Felder des Geräte-Hash, die (in der Regel) vom Modul (also vom Geräte-Coding) selbst verwaltet werden und auch (normalerweise) keinen Einfluss nach außen haben. Tja, was davon hilft jetzt einem Benutzer?

ZitatSie geben den Status des Gerätes wieder und erzeugen Events innerhalb von FHEM auf die andere Geräte reagieren können.
(Hier geht's um Readings.) Ich glaube, dass sich im IT-Bereich etabliert hat, dass "Status" etwas ist, was eine (kurze) Werteliste hat, die oft eine Phase im Lebenszyklus eines Objekts beschreibt. Das kann z.B. so etwas wie initialized - opened - connected - disconnected - closed bei einem Netzwerkgerät sein, aber auch so etwas wie open - closed bei einem Fensterkontakt.
Die Gesamtheit der Readings würde man dagegen normalerweise "Zustand" nennen.
Das Blöde ist jetzt, dass "Zustand" auf englisch "state" (zur Abgrenzung von "status") heißt. In FHEM ist aber das Reading "state" oft das, was einem tatsächlichen Status am nächsten kommt.
Meiner Meinung nach ist das etwas verwirrend.   

Zitatzu 2.) Um präzise zu sein, definiert das Modul selbst, über welche Events es informiert werden will (meistens sind das alle)
Meinst Du damit, dass ein Modul normalerweise über alle Events informiert werden will? Das glaube ich eher nicht. Ich denke mal, dass das vielleicht auf notify, DOIF, FileLog und ähnliches zutrifft, aber nicht auf normale Geräte-Module.

Zitatzu 5.) INTERNAL STATE und reading state spiegeln den internen Status (STATE) und den vom device empfangenen Status (state) des Devices wieder.
Siehe oben...

Zitat von: andies am 02 Mai 2017, 09:24:17
Weiter: Internals sind zum korrekten Funktionieren notwendig. Aber Readings doch auch?! Ohne Readings funktionieren die devices nicht, weil sie die Infos nicht weitergeben.
Ich weiß natürlich nicht, was der Verfasser sich dabei gedacht hat, aber ich würde das so interpretieren: Mach Dir über die Internals nicht zu viele Gedanken. Sie werden für das korrekte Funktionieren gebraucht, aber in der Regel nicht für Dich gedacht.
...blöd, dass man durch Klick auf das Internal DEF das ganze Device ändern kann.  :P

ZitatWas genau (formal) sind Events? Sind das auch Zeichenketten mit timestamp und device?
Tja, was genau sind "Events". Eine Definition sollte einfacher zu verstehen sein als das Wort selbst, aber damit kann ich nicht wirklich dienen.
Ein Versuch: Ein Event ist ein Ereignis. Das ist zwar nur eine Übersetzung, aber das trifft's ganz gut. Mehr ist nicht dahinter. In FHEM wird so ein Ereignis durch eine Zeichenkette beschrieben (durch was auch sonst?), die (immer?) mit einem Gerätenamen anfängt. Meistens folgt dann der Name eines Readings und der aktuelle Inhalt des Readings.
Man kann sich ein Event auch als Nachricht vorstellen, die keinen bestimmten Empfänger hat. Vielmehr wird das Event in die Welt hinausgeschrien und wer auch immer mag kann etwas damit machen. 

ZitatWie werden Zeitbefehle abgearbeitet? Gibt es da ein device, das Zeitgeber ist? Welches ist das und wie oft sendet das?
Meinst Du sowas wie ein at? Das ist relativ einfach: Es gibt eine zentrale Schleife in fhem.pl. Die prüft (u.A.), wann der nächste "Zeitbefehl" stattfinden soll. Falls das "jetzt" oder in der Vergangenheit ist, dann wird der Befehl ausgeführt. Liegt der Zeitpunkt in der Zukunft, dann schläft FHEM bis dann, wird aber durch externe Ereignisse aufgeweckt (z.B. jemand klickt auf der Web-Oberfläche oder es kommt was über USB rein).
Unter Windows funktioniert das ganze etwas anders, da dauert der Schlaf immer maximal 5ms.

ZitatMir ist nicht ganz klar, wann "get" und "set" verwendet wird.
Da scheint es keinen 100%igen Konsens zu geben. Wzuts Beschreibung gefällt mir aber und ich versuche das in "meinen" Modulen genau so zu machen.

Gruß,
   Thorsten
FUIP

andies

FHEM 6.1 auf RaspPi3 (Raspbian:  6.1.21-v8+; Perl: v5.32.1)
SIGNALduino (433 MHz) und HM-UART (868 MHz), Sonoff, Blitzwolf, Somfy RTS, CAME-Gartentor, Volkszähler, Keyence-Sensor, Homematic-Sensoren und -thermostat, Ferraris-Zähler für Wasseruhr, Openlink-Nachbau Viessmann

Thorsten Pferdekaemper

Zitat von: andies am 01 Mai 2017, 21:24:31
Eine Zeichenkette kann ein String sein und sie kann auch als Zahl interpretiert werden.
Also "String" ist meiner Meinung nach nur das englische Wort für "Zeichenkette". (Bzw. es ist sogar eine Verallgemeinerung davon.) D.h. eine Zeichenkette ist immer ein String. Was Du schreibst ist also nicht falsch, enthält aber keine Information.

ZitatIn bestimmten Fällen besteht sogar die Möglichkeit, die Zeichenkette als (ausführbaren) Perl-Code aufzufassen! Dann muss die Zeichenkette mit einer geöffneten Klammer { beginnen und einer geschlossenen Klammer } enden; Sonderzeichen wie . und * innerhalb des Codes sind entsprechend zu kennzeichnen ("escapen").
Ist das so? Kannst Du dazu mal ein Beispiel liefern?

ZitatSoll ein Internal eines devices durch Perl ausgelesen werden, so ist die Funktion InternalVal() zu verwenden.
Gehört das hierher? Ich dachte, dass das ein einführender Text werden sollte. Erstens gehört Perl-Programmierung dann nicht wirklich dazu und zweitens muss man i.d.R. keine Internals lesen. (Außer ich bin selbst der Maintainer eines Moduls und dann geht das viel einfacher.)

ZitatVerwirrend für einen Anfänger kann sein, dass manchmal Internals wie auch Readings mit gleichem Namen (STATE) existieren können.
Normalerweise ist das nicht der Fall das Internal heißt STATE und das Reading normalerweise state. Das ist ein Unterschied! Vielleicht wäre es wichtiger, darauf hinzuweisen, dass Groß-/Kleinschreibung zu beachten ist.

ZitatSTATE wird in allen Modulen vorprogrammiert.
Das stimmt so nicht. STATE ist sozusagen in FHEM selbst (also im "Kernel" vorprogrammiert). 

Zitat
Die Art der Darstellung (das Format) des STATE lässt sich verändern. Um dies zu tun, muss das device ein spezielles Attribut besitzen, der Anwender muss es anlegen. Das Attribut lautet 'stateFormat' und muss den Code enthalten, mit dessen Hilfe aus dem ursprünglichen STATE das nun neue Anzeigeformat erstellt wird. 
Ich glaube, es ist nicht die Art der Darstellung, sondern der Inhalt von STATE, der geändert wird. Außerdem wird nicht aus dem ursprünglichen STATE irgend etwas gemacht, sondern in der Regel aus den Readings des Devices. Das "ursprüngliche" STATE steht gar nicht mehr zur Verfügung.

Zitat
Auch Readings können manipuliert werden, hier ist jetzt allerdings der Befehl "setreading <device> <Readingname> <Wert>" zu verwenden.
Man sollte dazu sagen, dass man das bei den Readings, die ein Device mitbringt, nicht machen sollte. Der Befehl ist nützlich, um neue Readings dazuzubauen (insbesondere bei dummys), sollte aber nicht für Readings benutzt werden, die das jeweilige Modul selbst anbietet.

Zitat(Setreading generiert keine Events, siehe dazu unten.)
Doch, tut es. Ich habe es gerade nochmal ausprobiert. Ich finde es etwas seltsam, dass sich diese Ansicht irgendwie verbreitet hat.

Zitatund dieses Event wird an alle devices weitergeleitet.
Das kann man sich so vorstellen, stimmt aber genau genommen nicht. Richtig ist aber, dass das empfangende Device (bzw. Modul) darüber entscheidet.

Zitat
In den Modulen wird festgelegt, auf welche Events ein device reagiert. Dies kann vom Anwender geändert werden. Im Fall von Änderungen der Readings (siehe unten) sind dabei event-on-change-reading und event-on-update-reading entscheidend.
Das klingt so als ob die event-on-Attribute beim Empfänger eines Events entscheiden, ob dieser auf das Event reagiert bzw. daraufhin seine Readings ändert. Das stimmt nicht. Die event-on-Attribute steuern, ob durch das Setzen eines Readings ein Event überhaupt erst ausgelöst (gesendet) wird.

Gruß,
   Thorsten
FUIP

andies

Vielen Dank, das ist allein schon für mich sehr hilfreich. Bevor ich das einbaue und Dich damit erneut nerve, folgende Nachfragen:


  • "In bestimmten Fällen besteht sogar die Möglichkeit, die Zeichenkette als (ausführbaren) Perl-Code aufzufassen! Dann muss die Zeichenkette mit einer geöffneten Klammer { beginnen und einer geschlossenen Klammer } enden; Sonderzeichen wie . und * innerhalb des Codes sind entsprechend zu kennzeichnen ("escapen")." ich dachte an Konstruktionen wie
attr BVG stateFormat {my $zeit = ReadingsTimestamp("$name","Uni1",0) usw. }

    Das wollte ich beschreiben. Unglücklich?[/li]
  • "(Setreading generiert keine Events, siehe dazu unten.) Doch" Dann habe ich das falsch gelesen, https://fhem.de/commandref_DE.html#setreading Das "falls es aus einem notify für Gerät X aufgerufen wurde" scheint hier wesentlich zu sein, kommt aber so unscheinbar am Ende daher. Daher kommt das wahrscheinlich.
    Also gilt "setreading generiert immer Events, es sei denn..."
FHEM 6.1 auf RaspPi3 (Raspbian:  6.1.21-v8+; Perl: v5.32.1)
SIGNALduino (433 MHz) und HM-UART (868 MHz), Sonoff, Blitzwolf, Somfy RTS, CAME-Gartentor, Volkszähler, Keyence-Sensor, Homematic-Sensoren und -thermostat, Ferraris-Zähler für Wasseruhr, Openlink-Nachbau Viessmann

marvin78

Es geht dabei darum, dass es nur dann keine Events erzeugt, wenn es aus im notify für das selbe Gerät verwendet wird, auf dessen Event das notify reagiert hat (aus gutem Grund - bspw. Eventendlosschleife).

justme1968

zur ausführbarkeit von zeichenketten:

das ist werder eine allgemeine eigenart von perl noch von fhem und es gibt auch keine standardisierte syntax die das generell erlauben würde.

in perl ist auch die unterscheidung zwischen zahl, string und zeichenkette nicht ganz so einfach oder sinnvoll. jede zahl ist ein string und eine zeichenkette. jeder string ist eine zeichenkette. weder strings noch zeichenketten müssen zahlen sein.

wenn man versucht solche erklärungen wie in diesem beitrag zu verfassen ist es wichtig syntax und semantik zu unterscheiden und zu trennen. das gleiche gilt für die perl und fhem ebenen.

zu state und STATE git es auch im wiki und einsteiger pdf beschreibungen. falls hier etwas nicht stimmt oder unklar ist sollte man besser dort korrigieren als eventuell missverständliches oder falsches neu zu dokumentieren und vielen nachfolgenden probleme zu machen.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

Thorsten Pferdekaemper

Zitat von: andies am 04 Mai 2017, 12:11:00Sonderzeichen wie . und * innerhalb des Codes sind entsprechend zu kennzeichnen ("escapen")." ich dachte an Konstruktionen wie
attr BVG stateFormat {my $zeit = ReadingsTimestamp("$name","Uni1",0) usw. }

    Das wollte ich beschreiben. Unglücklich?
Ich meinte damit ein Beispiel für das Maskieren. Mir war nicht so ganz klar, wo da gebraucht wird.

ZitatDas "falls es aus einem notify für Gerät X aufgerufen wurde" scheint hier wesentlich zu sein, kommt aber so unscheinbar am Ende daher. Daher kommt das wahrscheinlich.
Also gilt "setreading generiert immer Events, es sei denn..."[/li]
[/list]
Naja, es steht aber am Anfang "generiert aber Ereignisse". Die englische Version ist etwas einfacher zu lessen, da muss man nicht wissen, dass Ereignis = Event.
Es steht ja sogar die Lösung dabei:

sleep 0.1; setreading X Y Z

...wobei inzwischen sogar sleep 0 gehen müsste.
Gruß,
   Thorsten
FUIP

andies

Zitat von: Thorsten Pferdekaemper am 04 Mai 2017, 12:57:54
Ich meinte damit ein Beispiel für das Maskieren. Mir war nicht so ganz klar, wo da gebraucht wird.
Ich dachte dabei an die ;; die da ständig notwendig sind. Ich schreibe das um.
FHEM 6.1 auf RaspPi3 (Raspbian:  6.1.21-v8+; Perl: v5.32.1)
SIGNALduino (433 MHz) und HM-UART (868 MHz), Sonoff, Blitzwolf, Somfy RTS, CAME-Gartentor, Volkszähler, Keyence-Sensor, Homematic-Sensoren und -thermostat, Ferraris-Zähler für Wasseruhr, Openlink-Nachbau Viessmann

doman75

ich habs mir auch mal durchgelesen was mit aufgefallen ist, mit stateformat oder eventmap wird die Darstellung des Internals "STATE" verändert, das Reading "state" bleibt unverändert und kann meines Wissens nur durch setreading verändert werden oder natürlich das Device selber.

andies

Zitat von: justme1968 am 04 Mai 2017, 12:51:25
wenn man versucht solche erklärungen wie in diesem beitrag zu verfassen ist es wichtig syntax und semantik zu unterscheiden und zu trennen. das gleiche gilt für die perl und fhem ebenen.

Da brauche ich, glaube ich, Nachhilfe. Das soll ja für den Einstieg sein. Ich will vorbereiten, dass ein Input sowohl Zahl, Zeichenkette als auch Befehl sein kann. Mehr will ich dann aber auch nicht sagen, weil man den Rest nachlesen kann. Die Frage ist: Ist es in der derzeitigen Fassung formal falsch, dann muss das geändert werden? Ist es irritierend - dann wo und warum? Dann würde ich das umschreiben. In ca 30 minuten lege ich eine neue Fassung hoch, wäre nett, wenn ich dann nochmal eine Kontrolle bekommen könnte.
FHEM 6.1 auf RaspPi3 (Raspbian:  6.1.21-v8+; Perl: v5.32.1)
SIGNALduino (433 MHz) und HM-UART (868 MHz), Sonoff, Blitzwolf, Somfy RTS, CAME-Gartentor, Volkszähler, Keyence-Sensor, Homematic-Sensoren und -thermostat, Ferraris-Zähler für Wasseruhr, Openlink-Nachbau Viessmann