DevelopmentReadingsAPI
Abstract
Diese Seite beschreibt ein Konzept für ein API für Readings in FHEM. Diese Seite dokumentiert den aktuellen Stand der Diskussion.
Ausgangspunkt ist dieser Thread.
Ausgangssituation
In FHEM besitzen Geräte sogenannte Readings (Anzeigewerte). Diese bestehen aus einem Zeitstempel und einem Wert. Die Änderung eines Readings wird in der Regel durch einen Event daran interessierten Geräten über die NotifyFn mitgeteilt. Die Werte von Readings sind Zeichenketten. Sie können beim Herunterfahren in einer eigenen Datei (fhem.save) gesichert und beim Neustarten von FHEM wiederhergestellt werden. Readings sind von der Natur her schnellveränderlich.
Geräte können Attribute besitzen. Attribute besitzen nur einen Werte ohne Zeitstempel. Sie sind in der Regel un- bzw. langsamveränderlich und dienen typischerweise zur Konfiguration. Attribute werden persistent in der Konfiguration abgelegt. Änderungen an Attributen werden auch analog zu Reading-änderungen durch Events distributiert. Auch Attribute sind Zeichenketten.
Geräte besitzen interne Werte (sog. Internals). Auch diese besitzen nur einen Werte ohne Zeitstempel. Internals können perl-skalare oder Referenztypen (z.B. hashes oder Arrays) sein. Änderungen an Internals werden nicht per Event weitergegeben, die Werte werden nicht persistiert.
Readings, Attribute und Internals genügen keiner festgelegten Syntax: es gibt bezüglich der Werte keine Vorgaben zur Standardisierung. Diese können z. B. Zahlenwerte, Kombinationen aus Zahlen und physikalischen Einheiten oder Texte enthalten. Beispielsweise können Readings, die Temperaturen darstellen, die Temperatur in Celsius-Graden oder Kelvin-Graden mit oder ohne Einheitensymbol enthalten. Das erschwert die Weiterverarbeitung. Soll beispielsweise eine Temperatur in einer graphischen Benutzeroberfläche mit einem Thermometer-Widget dargestellt werden, müssen für jede Geräteklasse individuelle Transformationsregeln von der Darstellung im Reading auf den Eingangsparameter im Widget transformiert werden.
Keine Semantik: Es gibt kein API, anhand dessen eine Funktion erkennen kann, was das Reading inhaltlich darstellt. Eine graphische Benutzeroberfläche kann beispielsweise nicht ermitteln, ob für ein bestimmtes Reading ein Thermometer-Widget oder eine Lampe dargestellt werden soll.
Zielsetzung
Es soll ein API eingeführt werden, das einen bzgl. Syntax und Semantik standardisierten Zugriff auf Readings erlaubt.
Frühere Ansätze sind Interfaces und Guidelines und diese Diskussion.
Anforderungen an das API
- Funktionale Anforderungen
- Es soll sich die Bedeutung eines Readings ermitteln lassen (Temperatur, Schaltzustand, Länge, Füllmenge, ...).
- Es sollen sich bei physikalischen Größen Wert und Einheit ermitteln lassen.
- Es soll möglich sein, physikalische Größen in andere Einheitensysteme umrechnen zu können (z.B. K in °C, °C in °F, l im cbm, ...).
- Es sollen Formatierungen unterstützt werden (globaler Default, Default je physikalischer Größe, individuell je Geräteklasse, individuell je Gerät), z.B. Temperaturen grundsätzlich in °C mit einer Nachkommastelle, Uhrzeiten grundsätzlich in 24-Stunden-Notation oder in AM/PM-Schreibweise.
- Es wurde die Anforderung genannt, dass sich der Wertebereich ermitteln lassen sollte. Mir ist nicht klar, ob dies für Readings erforderlich ist (es wäre für Settings erforderlich).
- Nichtfunktionale Anforderungen
- Kein Modul soll das API unterstützen müssen, damit althergebrachte Module ohne Anpassungen weiterfunktionieren.
- Das API soll nur unwesentlichen Overhead bzgl. Speicherverbrauch und Verarbeitungszeiten erzeugen.
- Es soll keine Vereinheitlichung von Readings-Namen erfolgen (temp, temperature) (das war früher einmal eine Forderung).
Erste Überlegungen
- Einheiten alleine genügen nicht, es sollte die physikalische Größe bekannt sein, die von dem Reading repräsentiert wird (Temperatur, Druck, ...).
- Dazu eine Regel, in welcher Einheit diese physikalische Größe vorliegt.
- Es bringt keinen Zusatznutzen, die physikalische Größe am Reading verfügbar zu haben.
- Stattdessen meldet das Device, dass es einem Standard gehorcht (ein Interface implementiert, z.B "temperature").
- Ein GUI weiß dadurch, was es anzuzeigen hat.
- KEINE Einheiten im {readings}{VAL}. Das muß bei wirklich jeder anderen Verwendung außer "Anzeige für Mensch mit selben Locale wie Entwickler." gestrippt werden.
- An jedes Reading werden Metainformationen geklebt. Welche?
- Die Metainformationen könnten Zeiger in eine hierarchische Liste standardisierter Beschreibungen sein. Sind die Interfaces modellhaft?
- Es ist klar, dass die Bedeutung eine Vereinbarung darstellt, die außerhalb des Systems liegt. GGf. kann man die Implementierung aber ihre eigene Dokumentation enthalten lassen.
- Wir brauchen für die Formatierungen einen Speicher für die globalen Defaults und die Geräteklassen- und Geräte- und Readings-spezifischen Überschreibungen.
- Die allgemeinen Zugriffsmethoden können in RTypes.pm eingefügt werden. So was wie RUnit($hash, "desired-temp").
- Wir müssen darüber nachdenken, welche Kunden das API hat und was es denen nutzen soll. FHEMWEB und DBLog sind Kunden.
- Zum Frontend: man kann sich ja viel fürs Backend ausdenken. Aber das richtige Gespür dafür, ob das Design auch wirklich was taugt, bekomme ich erst, wenn ich es einsetze und sehe, wie es sich für den Verwender anfühlt. Daher die Idee für einen Durchstich, ein Proof-of-Concept eben.