Allgemeiner (optionaler) Support für Units (Unit.pm)

Begonnen von Loredo, 06 November 2016, 19:22:19

Vorheriges Thema - Nächstes Thema

Loredo

Ich habe im Rahmen von 59_Wunderground und 50_HP1000 die Erzeugung eines multi-value state Readings zusammen mit den jeweiligen Einheiten der verwendeten Ausgangs-Readings gebraucht. Die Funktion getMultiValStatus() im gerade eingecheckten Unit.pm Package tut genau das.


Aus diesem Vorhaben heraus hat es sich entwickelt, dass ich die Unterstützung für Einheiten/Units noch weitergesponnen habe, so dass nun letztendlich eine für alle Module und auch FHEM Benutzer optional einsetzbare Unit Erweiterung für FHEM herausgefallen ist. Dafür wird $defs{$name}{READINGS}{$reading}{U} verwendet.


Der Stand ist nun soweit, dass man als Benutzer vorhandenen Readings entsprechende Units mittels dem Befehl "setunit" zuweisen oder mittels "deleteunit" wieder löschen kann. Dabei wird devspec und readingspec verwendet, so dass die Befehle maximale Flexibilität erlauben. setunit erlaubt es außerdem über den Readingnamen zu versuchen die Unit automatisch zu ermitteln und zuzuweisen, sofern explizit kein anderer Wert angegeben wurde. Das alles funktioniert also komplett unabhängig für jedes bestehende Modul "on top". Der User muss Unit.pm lediglich laden, sofern er kein Modul verwendet, was Unit.pm bereits implementiert hat (siehe auch hier). Aktuell sind das meine Module 50_HP1000 und 59_Wunderground.
Außerdem gibt es zur Anzeige der zugewiesenen Units den Befehl "unit". Standardmäßig werden nur tatsächlich definierte Units angezeigt. Möchte man die Reading-Namen basierte Erkennung per Default einschalten, ohne dass etwas in $defs{$name}{READINGS}{$reading}{U} zugewiesen sein muss, dann kann man das neue User Attribut unitFromReading entweder global oder auch pro Device setzen.


Für Modulentwickler stehen außerdem die an die bestehenden readings Funktionen angelehnten Unit-spezifischen Funktionen bereit:


readingsUnitSingleUpdate()
readingsUnitSingleUpdateIfChanged()
readingsUnitBulkUpdateIfChanged()
readingsUnitBulkUpdate()
readingsUnitBeginUpdate()
readingsUnitEndUpdate()


Eine allgemeine Funktion für DbLog_split ist mit Unit_DbLog_split() ebenfalls enthalten.

Da die readingsUnit-Funktionen zu den normalen, nicht Unit-spezifischen Pendants kompatibel sind, kann man als Modulautor per Suchen+Ersetzen auf Unit-Support umstellen. In diesem Fall werden über die vorhandenen Reading-Namen dann entsprechende Units zugewiesen. Optional kann man dann sein Modul erweitern und explizit eine Unit-Abbreviation als Parameter mitgeben. Eine Liste der bekannten und zuweisbaren Units erhält man übrigens mit "setunit ?" (aktuell noch nicht sehr hübsch nur als Dumper...).


Was macht man nun mit den Unit Angaben außer sie sich per unit-Befehl anzeigen zu lassen?
Für die Verwendung in Automationen etc. gibt es analog zu den bestehenden Funktionen wie ReadingsVal() neue Funktionen, die die Units berücksichtigen:


ReadingsUnit()
ReadingsUnitLong()
ReadingsUnitAbbr()
ReadingsValUnit()
ReadingsValUnitLong()


ReadingsValUnit() und ReadingsValUnitLong() sind soweit mit ReadingsVal() kompatibel, berücksichtigen jedoch zusätzlich die gesetzte Unit, sofern vorhanden.
ReadingsValUnit() zeigt die Kurzform an während ReadingsValUnitLong() eine lange Variante anzeigt, um z.B. in einer Sprachausgabe verwendet werden zu können. Dabei werden natürlich unterschiedliche Sprachen unterstützt (aktuell en, de, fr, nl, pl) und außerdem auch ggf. Unterschiede in der lokalen Schreibweise oder die Reihenfolge Value<>Unit berücksichtigt. Z.B. wird aus dem Reading UV=1 dann in der Kurzschreibweise "1 UVI" oder in der Langschreibweise "UV-Index 1". Selbstverständlich ist auch Singular und Plural berücksichtigt.
Englisch ist die Standardsprache, wirklich übersetzt habe ich bisher nur die deutschen Schreibweisen. Wer helfen mag die anderen Sprachen auch zu übersetzen kann sich dazu den %unitsDB Hash gerne vornehmen und mit schicken  ;)


Was nun abschließend noch fehlt ist natürlich die Unit-Zuweisungen persistent zu halten; aktuell überlebt das ganze natürlich keinen FHEM Neustart und man müsste entsprechende setunit-Befehle per Notify o.ä. nach dem Neustart vorsehen. Für meine 2 aktuellen Module ist das nicht tragisch, weil die zur Laufzeit ohnehin die Units regelmäßig neu setzen. Trotzdem wollte ich fragen, ob das ganze vielleicht so interessant ist, dass man entweder setstate entsprechend mit Unit Support erweiterte oder beim serialisieren der Readings zusätzlich noch setunit-Befehle mit in fhem.save schreiben könnte (analog dazu natürlich gleiche Erweiterungen in configDB).


Wenn es gewollt ist, dann lagere ich die Befehle setunit, deleteunit und unit auch ordnungsgemäß in eigene Dateien aus. Das macht IMHO aber erst Sinn, wenn die Unit-Definitionen den FHEM Neustart überleben und Nutzer die Befehle dann wirklich benutzen wollten. Aktuell sind sie nur zum herumspielen verfügbar, wenn man z.B. das Wunderground Modul verwendet.




Gruß
Julian
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER

justme1968

hallo loredo,

vielleicht magst du dir noch mal diesen vorschlag:  https://forum.fhem.de/index.php/topic,46730.msg384676.html#msg384676 von anfang des jahres anschauen.

hier war die idee über ein zwei attribute zu gehen und somit das persistieren automatisch zu bekommen. die attribute sind auch im frontend direkt sichtbar und änderbar. das ist bei änderungen an {READINGS} ja leider nicht so. auch können frontends direkt ohne klimmzüge auf die daten zugreifen. es sind auch keine zusätzlichen routinen für readings update nötig. das würde auch das sanboxing von modulen das ich immer noch im hinterkopf habe einfacher machen.

auch gab es die möglichkeit global oder device spezifisch die anzeige und skalierung von bestimmten oder allen einheiten zu konfigurieren und auch die konfigurierbare anzeige in telnet und fhemweb gibt es dort schon.

wie wäre es deine übersetzungen und auch die möglichkeit kurze und lange beshribungen mit mit meinem attribut basierten ansatz und den frontend erweiterungen zu kombinieren?

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

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

Loredo

Diese Diskussion ist bei mir vollkommen in Vergessenheit geraten (ganz offensichtlich)  ;)


Die zusätzlichen Funktionen klingen alle sinnvoll. Die Unit Zuweisung ansich über Attribute vorzunehmen finde ich spontan nicht ganz so toll, da es sich dabei eher zu sehr zweckentfremdet anfühlt.


Was ich im Attribut abspeichern würde wäre in erster Linie die Unit-Abkürzung, über die alles referenziert wird. Ich wollte diese Dynamik auch gerne beibehalten und die tatsächliche Einheit auch nicht ins Attribut schreiben. Frontends hätten also davon erstmal wenig und könnten die Einheit nicht direkt abfragen.


Grundsätzlich habe ich nichts dagegen beide Ansätze zu vereinen. Das hier war bisher allerdings schon ein zeitlicher Kraftakt und ich vermute auch bei dir war das der Grund, weshalb es dort stecken geblieben ist, wo es bisher steht.
Die vielen Ansprüche an eine Lösung fordern offenbar soviel Einsatz und Zeit, dass wir dadurch dann offenbar nur schwer zu einer Lösung kommen. Wenn wir den Elefanten aber etwas zerlegt bekämen und nicht alle auf einmal wollten, vielleicht kämen wir dann einfacher zu einem ersten Wurf für alle.
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER

justme1968

naja... attribute sind doch der normale weg etwas persistent und für den anwender konfigurierbar zu machen.

auch das es ohne weitere interne änderungen auskommt und für alle frontends direkt verfügbar ist finde ich einen grossen vorteil. wenn nicht sogar das wichtigste. was nützen einheiten wenn sie im fronend nicht sichtbar sind.

das es damals nicht weiter ging lang vor eher daran das es nicht genügend interesse gab als das der elefant zu gross ist. lass uns mal drüber schlafen und schauen ob sich noch jemand eine meinung dazu hat.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

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

Loredo

#4
Ich habe mir deine Patches jetzt angesehen und darauf basierende Erweiterungen vorgenommen.
Die Formatierungen fehlen derzeit noch, die verschiedenen Orte zur Festlegung der Einheit habe ich übernommen:

1. $def{$name){readingsDesc}
2. $modules{$TYPE){readingsDesc}
3. $attr{$name}{readingsDesc}
4. $attr{global}{readingsDesc}

Dabei habe ich allerdings nicht auf eine "entweder/oder"-Strategie gesetzt, sondern "sowohl als auch". Die Definition kann auf allen Ebenen gemischt und überschrieben werden. Die Befehle setunit und deleteunit wurden darauf angepasst, dass man hierüber einfach Unit Zuweisungen abändern und im Attribut readingsDesc abspeichern kann. Die ReadingsUnit*() Funktionen sind unverändert geblieben.

Ich habe im Unit Hash auch einmal ein paar FHEM Readings-Typen hinterlegt.

Ausschnitt aus "setunit ?":

$VAR1 = {
          'FHEM' => {
                      'onoff' => {
                                   'format' => [
                                                 'off',
                                                 'on'
                                               ],
                                   'suffix' => 'onoff',
                                   'abbr' => 'onoff',
                                   'ref_base' => 900,
                                   'txt_base' => 'FHEM',
                                   'lang' => 'en',
                                   'txt' => 'on/off'
                                 },
                      'oknok' => {
                                   'txt' => 'ok/nok',
                                   'txt_base' => 'FHEM',
                                   'lang' => 'en',
                                   'ref_base' => 900,
                                   'abbr' => 'oknok',
                                   'format' => [
                                                 'nok',
                                                 'ok'
                                               ],
                                   'suffix' => 'oknok'
                                 },
                      'closure' => {
                                     'txt_base' => 'FHEM',
                                     'lang' => 'en',
                                     'txt' => 'open/closed/tilted',
                                     'suffix' => 'lock',
                                     'format' => [
                                                   'closed',
                                                   'open',
                                                   'tilted'
                                                 ],
                                     'abbr' => 'closure',
                                     'ref_base' => 900
                                   },
                      'bool' => {
                                  'lang' => 'en',
                                  'txt_base' => 'FHEM',
                                  'txt' => 'true/false',
                                  'abbr' => 'bool',
                                  'ref_base' => 900,
                                  'suffix' => 'bool',
                                  'format' => [
                                                'false',
                                                'true'
                                              ]
                                },
                      'pct' => {
                                 'symbol' => '%',
                                 'suffix' => 'pct',
                                 'format' => '%i',
                                 'txt' => 'percent',
                                 'lang' => 'en',
                                 'ref_base' => 900,
                                 'abbr' => 'pct',
                                 'tmpl' => '%value% %symbol%',
                                 'txt_base' => 'FHEM'
                               }
                    },
          'luminous flux' => {
                               'lm' => {
                                         'formula_symbol' => 'F',
                                         'txt' => 'Lumen',
                                         'lang' => 'en',
                                         'dimension' => 'J',
                                         'suffix' => 'lm',
                                         'format' => '%i',
                                         'txt_base' => 'luminous flux',
                                         'ref_base' => 17,
                                         'si_base' => 'lm',
                                         'abbr' => 'lm'
                                       }
                             },
          'energy' => {
                        'mw' => {
                                  'ref_base' => 7,
                                  'si_base' => 'j',
                                  'abbr' => 'mw',
                                  'ref' => 'j',
                                  'txt_base' => 'energy',
                                  'scale_txt_m' => 'm',
                                  'format' => '%.1f',
                                  'scale_m' => '1.0e-3',
                                  'suffix' => 'mJ',
                                  'scale_txt_long_m' => 'mili',
                                  'dimension' => 'M L^2 T^−2',
                                  'formula_symbol' => 'E',
                                  'txt' => 'milijoule',
                                  'lang' => 'en'
                                },
                        'uj' => {
                                  'suffix' => 'μJ',
                                  'format' => '%.1f',
                                  'scale_m' => '1.0e-6',
                                  'scale_txt_m' => 'μ',
                                  'scale_txt_long_m' => 'micro',
                                  'dimension' => 'M L^2 T^−2',
                                  'lang' => 'en',
                                  'formula_symbol' => 'E',
                                  'txt' => 'microjoule',
                                  'si_base' => 'j',
                                  'abbr' => 'uj',
                                  'ref_base' => 7,
                                  'ref' => 'j',
                                  'txt_base' => 'energy'
                                },
                        'mj' => {
                                  'scale_txt_long_m' => 'mili',
                                  'scale_txt_m' => 'm',
                                  'suffix' => 'mJ',
                                  'format' => '%.1f',
                                  'scale_m' => '1.0e-3',
                                  'txt' => 'milijoule',
                                  'formula_symbol' => 'E',
                                  'lang' => 'en',
                                  'dimension' => 'M L^2 T^−2',
                                  'ref_base' => 7,
                                  'abbr' => 'mj',
                                  'si_base' => 'j',
                                  'txt_base' => 'energy',
                                  'ref' => 'j'
                                },
                        'j' => {
                                 'format' => '%.1f',
                                 'suffix' => 'J',
                                 'scale_m' => '1.0e0',
                                 'scale_txt_m' => '',
                                 'scale_txt_long_m' => '',
                                 'dimension' => 'M L^2 T^−2',
                                 'lang' => 'en',
                                 'formula_symbol' => 'E',
                                 'txt' => 'Joule',
                                 'si_base' => 'j',
                                 'abbr' => 'j',
                                 'ref_base' => 7,
                                 'txt_base' => 'energy'
                               },
                        'uw' => {
                                  'txt_base' => 'energy',
                                  'ref' => 'j',
                                  'ref_base' => 7,
                                  'si_base' => 'j',
                                  'abbr' => 'uw',
                                  'formula_symbol' => 'E',
                                  'txt' => 'microwatt',
                                  'lang' => 'en',
                                  'dimension' => 'M L^2 T^−2',
                                  'scale_txt_long_m' => 'micro',
                                  'scale_txt_m' => 'μ',
                                  'format' => '%.1f',
                                  'suffix' => 'μW',
                                  'scale_m' => '1.0e-6'
                                }
                      },
          'luminous intensity' => {
                                    'cd' => {
                                              'format' => '%.1f',
                                              'suffix' => 'cd',
                                              'dimension' => 'J',
                                              'lang' => 'en',
                                              'formula_symbol' => 'Iv',
                                              'txt' => 'Candela',
                                              'si_base' => 'cd',
                                              'abbr' => 'cd',
                                              'ref_base' => 6,
                                              'txt_base' => 'luminous intensity'
                                            }
                                  },
          'electric charge' => {
                                 'coul' => {
                                             'txt' => 'Coulomb',
                                             'formula_symbol' => 'C',
                                             'lang' => 'en',
                                             'dimension' => 'I T',
                                             'suffix' => 'C',
                                             'format' => '%.1f',
                                             'txt_base' => 'electric charge',
                                             'ref_base' => 20,
                                             'abbr' => 'coul',
                                             'si_base' => 'coul'
                                           }
                               },
          'amount of substance' => {
                                     'mol' => {
                                                'ref_base' => 5,
                                                'si_base' => 'mol',
                                                'abbr' => 'mol',
                                                'txt_base' => 'amount of substance',
                                                'format' => '%.1f',
                                                'suffix' => 'mol',
                                                'formula_symbol' => 'n',
                                                'lang' => 'en',
                                                'dimension' => 'N'
                                              }
                                   },
          'pressure' => {
                          'hpa' => {
                                     'txt' => 'hectopascal',
                                     'formula_symbol' => 'p',
                                     'lang' => 'en',
                                     'dimension' => 'M L^−1 T^−2',
                                     'scale_txt_long_m' => 'hecto',
                                     'scale_txt_m' => 'h',
                                     'format' => '%i',
                                     'scale_m' => '1.0e2',
                                     'suffix' => 'hPa',
                                     'txt_base' => 'pressure',
                                     'ref' => 'pa',
                                     'ref_base' => 10,
                                     'abbr' => 'hpa',
                                     'si_base' => 'pa'
                                   },
                          'bar' => {
                                     'txt_base' => 'pressure',
                                     'ref_base' => 10,
                                     'si_base' => 'pa',
                                     'abbr' => 'bar',
                                     'txt' => 'Bar',
                                     'formula_symbol' => 'p',
                                     'lang' => 'en',
                                     'dimension' => 'M L^−1 T^−2',
                                     'scale_txt_long_m' => '',
                                     'scale_txt_m' => '',
                                     'scale_m' => '1.0e0',
                                     'format' => '%i',
                                     'suffix' => 'bar'
                                   },
                          'pa' => {
                                    'dimension' => 'M L^−1 T^−2',
                                    'txt' => 'Pascal',
                                    'formula_symbol' => 'p',
                                    'lang' => 'en',
                                    'scale_txt_m' => '',
                                    'format' => '%i',
                                    'suffix' => 'Pa',
                                    'scale_m' => '1.0e0',
                                    'scale_txt_long_m' => '',
                                    'txt_base' => 'pressure',
                                    'ref_base' => 10,
                                    'abbr' => 'pa',
                                    'si_base' => 'pa'
                                  },
                          'mbar' => {
                                      'scale_txt_m' => 'm',
                                      'scale_m' => '1.0e-3',
                                      'format' => '%i',
                                      'suffix' => 'mbar',
                                      'scale_txt_long_m' => 'mili',
                                      'dimension' => 'M L^−1 T^−2',
                                      'formula_symbol' => 'p',
                                      'txt' => 'milibar',
                                      'lang' => 'en',
                                      'ref_base' => 10,
                                      'abbr' => 'mbar',
                                      'si_base' => 'pa',
                                      'ref' => 'bar',
                                      'txt_base' => 'pressure'
                                    }
                    }
        };



Die Verwendung der Dimension oder des Format Symbols für die Kurzform (bei dir in der Funktion &readingsDimension) muss nochmals überdacht werden, weil nicht für jede Maßeinheit ein einzelnes Dimensionszeichen vergeben werden kann und manchmal auf das (dann klein geschriebene) Format Symbols ausgewichen werden müsste. Ich habe das daher noch nicht in getMultiValStatus() integriert und die short-Definition auf Basis des Readingsnamen beibehalten.







TL;DR

Testen ist sehr einfach: Man kann das Wunderground Modul mit einer beliebigen Wetterstation definieren und hat ein Device, mit dem man das komplette Verhalten sehen kann.


define WU Wunderground <APIKEY> IBAYERNM70

(meinen API Key kann ich leider hier nicht mitgeben, es ist aber einfach sich hier einen zu besorgen)
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER

justme1968

das klingt schon mal sehr gut :)

ich schaue es mir gerne noch mal in ruhe an. das wird aber nicht vor dem wochenende gehen.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

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

Loredo

Hallo André,


Ich habe Unit.pm zwischenzeitlich so umgebaut, dass es eigentlich einem RTypes.pm entsprichen müsste (inkl. Sprachunterstützung). Ich habe mich dabei nun auch an deiner Benennung und Aufteilung der Funktionen orientiert.
Anbei der angepasste Patch für fhem.pl, FHEMWEB und TELNET. Er ist minimal-inversiv, so dass man derzeit Unit.pm noch nicht in fhem.pl laden muss. Vielleicht könnte man überlegen, ihn so bereits einmal einzuchecken @Rudi?


Auch habe ich den List-Befehl recht stark erweitert. Der dritte Parameter für Reading-, Internal- oder Attributsname ist jetzt per Regex und Komma separierter Liste möglich, so dass man flexibler bei der Ausgabe ist.
Neu ist auch, dass Internals und Attribute entsprechend markiert werden, um sie besser voneinander unterscheiden zu können.
Ebenfalls neu hinzugekommen ist als vierter Parameter nun Regex-basierte Abfrage der Reading Descriptions. Die angehängte Textdatei zeigt einmal ein "list .* .* .*" in einer fhem.cfg.demo Konfiguration, bei der zusätzlich noch ein HP1000 Device mit RTypes definiert wurde.


Ich bin gespannt auf das Feedback  ;)




Gruß
Julian

Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER

justme1968

#7
schön das du weiter machst. leider bin ich noch nicht zum in ruhe nachschauen gekommen. ich bin aber sehr dafür das es so bald wie möglich (in einem ersten schritt) integriert wird.

das mit dem besser formatierten list output hatte ich auch schon mal ein wenig eingebaut, das problem ist aber das dann list nicht mehr rückwärtskompatibel ist und diverse frontends und andere anwendungen probleme bekommen. ich vermute rudi wird das nicht übernehmen.

das der dritte parameter jetzt auch eine regex sein kann finde ich aber sehr gut.

der neue vierte parameter ist leider wieder nicht rückwärts kompatibel, bis jetzt kann man ja beim list beliebig viele durch leerzeichen getrennten readings/internals/attribute angeben. wie wäre es wenn man die neuen paramter als <param>=<wert> angibt? also z.b. desc=.* dann wäre das potential für einen konflikt nicht mehr gegeben. zum parsen kann man parseParams verwenden.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

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

Loredo

Zitat von: justme1968 am 13 November 2016, 16:01:24
der neue vierte parameter ist leider wieder nicht rückwärts kompatibel, bis jetzt kann man ja beim list beliebig viele durch leerzeichen getrennten readings/internals/attribute angeben. wie wäre es wenn man die neuen paramter als <param>=<wert> angibt? also z.b. desc=.* dann wäre das potential für einen konflikt nicht mehr gegeben. zum parsen kann man parseParams verwenden.


parseParams verwende ich bereits auch in CommandSetreadingdesc(), es macht daher tatsächlich Sinn es auch hier mit einzubauen. Ich schau es mir mal an.


Was derzeit noch ein ungelöstes Problem ist: An irgendeiner Stelle muss für die unterschiedlichen Sprachen noch jeweils ein eigener Hash erzeugt und die Hash-Referenzkette unterbrochen werden. Ansonsten ist es derzeit so, dass in $defs{$name}{readingsDesc} die Werte immer der Sprache entsprechen, die die jeweilige FHEMWEB Instanz hat, über die zuletzt auf den Hash zugegriffen worden ist. Ich wollte eigentlich vermeiden dort einen Hash-of-Hashes abzulegen, bin mir aber nicht im klaren wo es sinnvoll ist die Template Umwandlung letztendlich vorzunehmen. Daher hatte ich gehofft du würdest es beim Studieren des aktuellen Standes ggf. verbessern können.
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER

justme1968

aus dem stegreif habe ich noch keine idee. ich muss erst mal ein bisschen damit spielen.

mir ist auch noch nicht ganz klar ob man die sprache bis auf reading ebene braucht oder ob die device ebene reicht. wobei die reading ebene schon 'richtiger' wäre.

hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

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

rudolfkoenig

ZitatVielleicht könnte man überlegen, ihn so bereits einmal einzuchecken @Rudi?
Ich wurde ganz am Anfang schon abgehaengt, weil ich die Notwendigkeit von Units immer noch nicht sehe. Bin noch auf dem alten Standpunkt, dass Einheiten in FHEM ueberall mitzuschleppen (anstatt "nur" zu dokumentieren) mehr Probleme fuer Entwickler und Benutzer nach sich zieht, als es loest.

Loredo

#11
Daher ist das ganze ja (bisher) auch optional.
Inzwischen reden wir ja von Reading Typen, was eine Reihe von Vorteilen bringt:


- Prinzipiell: jedes Reading kann nun eigene Attribute haben. Für die Zuweisung gibt es das Device-Attribut readingsDesc, welches auch mittels der Befehle setreadingdesc/deletereadingdesc gepflegt werden kann. Module können im Device-Hash ebenfalls einen readingsDesc Hash als Vorgabe hinterlegen.
- ein zentral vordefiniertes Reading Attribut ist "rtype", welches einen Reading Typ zuweist
- Reading Typen können dynamisch zusammengestellt werden und sind eine Art Template für das, was mit einem Reading angefangen werden soll, wenn es angefasst wird (egal ob gelesen oder geschrieben)
- Unit.pm liefert dafür mehrere Hashes mit, die miteinander verknüpft sind. Es fehlt noch auch diese Datenbank vom User auf globaler und Device-Ebene erweitern zu können, um in FHEM so nicht vordefinierte Reading Typen selbst zu erstellen
- neben RTypes für alle möglichen (SI-)Einheiten gibt es auch FHEM RTypes, z.B. oknok, bool, epoch, time, datetime, datetimesec, compasspoint, direction, closure, condition_hum, condition_uvi, pct
- für metrische Werte ist hinterlegbar in welchem Größenverhältnis der Wert einzuordnen ist. Dadurch sind automatische Umrechnungen möglich (z.B. von Milliwatt in Kilowatt, Gramm in Kilogramm etc). inklusive automatischer Generierung des kurzen und langen Suffix
- einheitliche Darstellung von Readings über alle Module hinweg und damit dann auch für alle Frontends
- automatischer Suffix bei Zahlenwerten (inkl. sprachlich abhängiger Langversion z.B. für Sprachausgaben oder einfach zur Beschreibung/Dokumentation)
- automatische Umrechnung von Werten bei der Darstellung
- Unterstützung von Sprachen auch für Text-Values
- durch Erweiterung von readingsBulkUpdate() ist es optional möglich einen Scope festzulegen, der beim Schreiben des Readingwertes überprüft wird. Dadurch wird es auch möglich standardisiert einem Textwert einen Zahlenwert zuzuordnen und umgekehrt. Die Darstellung der Readings lässt sich somit vereinheitlichen.
- Modulautoren können den Zweck eines Readings genau definieren
- gleichwohl können Anwender von Modulen ohne RType Support manuell einen Typ zuweisen, um die Darstellung zu vereinheitlichen und auch automatische Konvertierungen zu erhalten
- man kann endlich verschiedene Readings von unterschiedlichen Modulen logisch vergleichen weil man automatisch ermitteln kann, welche Readings die selbe inhaltliche Bedeutung haben


... achso und der eigentliche Auslöser war, dass André und ich beide bei den Wetter Modulen den STATE/state Wert automatisch und dynamisch zusammensetzen wollten, bei dem zum einen ein Kurzname für ein Reading mit fester Bedeutung (Formel-Symbol) statt des Readingnamen hergenommen wird und zum anderen optional auch die Einheit wie z.B. °C etc mitgeloggt werden kann. Das kann man an makeSTATE() in Unit.pm sehen.


Jedenfalls sind die zentralen Änderungen in fhem.pl so gering, dass es danach jedem Modulautor und auch Anwender offen steht, etwas damit anzufangen oder nicht. Es krempelt nichts um, sondern erweitert nur für diejenigen, die einen Sinn darin sehen (für die anderen wird der Sinn dann mit der Zeit sicherlich erkennbarer werden  ;)
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER

justme1968

und für den anwender hat diese standardisierte meta information unter anderem folgende vorteile:

- ein frontend kann diese abhängig von der art des readings automatisch grafisch anders anzeigen.
- ein frontend anwender kann readings des gleichen typs je nach konkreter anwendung unterschiedlich formatieren
- es ist eine voraussetzung um readings halbwegs automatisch in frontends zu verwenden die nicht text basiert sind. z.b. siri oder alexa.

hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

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

rudolfkoenig

Das man damit eine Schicht an Komplexitaet (== Arbeit fuer Entwickler und/oder Anwender) hinzufuegen kann, verstehe ich.
Ich sehe es noch nicht, dass es Wert ist. Z.Bsp:

Zitat- einheitliche Darstellung von Readings über alle Module hinweg und damit dann auch für alle Frontends
Reading-Value ist ein Text. Warum wird es fuer alle Frontends einheitlicher, wenn man Formatierungsoptionen hinzufuegen kann?

Zitat- automatischer Suffix bei Zahlenwerten
Automatisch ist es nicht (irgendwer muss ja was umbauen) und auch jetzt kann ich nach dem Wert eine Masseinheit dazuschreiben.
Ja, es ist nicht formalisiert, und u.U. kann was schiefgehen. Aber einfach, und funktioniert auch, wenn der Modulautor was falsch gemacht hat.

Zitat- automatische Umrechnung von Werten bei der Darstellung
Warum will man es umrechnen? Und wieso passiert das automatisch?
Der Frontendautor _kann_ sich die Muehe machen, fuer die Amerikaner alles in Fahrenheit/Meilen/ounce/etc umzurechnen, alle anderen rechnen mW mit SI. Haben wir wirklich einen Bedarf dafuer?

Zitat- Unterstützung von Sprachen auch für Text-Values
Das fuehrt an einer bestimmten Stelle eine Moeglichkeit ein, unterschiedliche Sprachen zu unterstuetzen. Aber wo sollen die Uebersetzungen herkommen? XLIFF oder gettext()? Es soll sicher nicht was selbstgebautes sein wo jeder in seinem .pm ein Hash mit dem ihm bekannten Sprachen einbaut, sondern etwas, was man einer Uebersetzungsbuero geben kann.  Der Rest an Log- und Fehlermeldungen, Befehlen, etc wird weiterhin nicht uebersetzt. Mehrere Sprachen zu unterstuetzen will ich sicher nicht durch die Hintertuer mit einem Units-Patch einfuehren.

Zitat- ein frontend anwender kann readings des gleichen typs je nach konkreter anwendung unterschiedlich formatieren
- ein frontend kann diese abhängig von der art des readings automatisch grafisch anders anzeigen.
geht doch auch jetzt.

Zitat- es ist eine voraussetzung um readings halbwegs automatisch in frontends zu verwenden die nicht text basiert sind. z.b. siri oder alexa.
Das haette ich gerne erklaert.

Ein nicht zu unterschaetzender Vorteil von FHEM liegt in der Einfachheit. Bevor ich das opfere, muss ich ueberzeugt sein, dass es Wert ist. Hier bin ich noch nicht ueberzeugt.


Loredo

#14
Es geht hier vor allem darum eine Standardisierungsschicht zu ermöglichen. Und ja, ich reite wieder auf meinem Lieblingswort "Convenience". Glücklicherweise hat André aber auch noch Homebridge und Alexa als Beispiele genannt, die mit einem Wert erst dann wirklich etwas anfangen können (nicht nur Sprachausgabe oder Erkennung), wenn sie den Kontext (!) eines Zahlen- oder Textwertes kennen.


Vereinfacht gesagt: Technisch möchten wir dafür zunächst nur Reading-Attribute haben, genauso wie es für Devices auch Attribute gibt, die man frei verwenden kann. Das alleine sollte eigentlich kein Problem sein, denn es macht ja offenbar auch Sinn ein Device mittels Device-Attributen näher spezifizieren zu können. Grundsätzlich sprechen wir dabei zunächst also von einer reinen Backend-Funktion.


Als nächstes habe ich mit den Mehrinformationen, die man nun für ein Reading hinterlegen kann, etwas angefangen. Ich habe mir dafür als Reading-Attribut "rtype" ausgesucht. Damit verweist man auf eine Liste vordefinierter weiterer Meta-Informationen, die dann schließlich erstmal eine Liste weiterer Zusatzinformationen bringen. Im FHEM Backend Bereich gibt es hier nur eine sinnvolle Anwendung, die man (vornehmlich als Modulautor oder als sehr erfahrener Anwender) definieren können möchte: Eingehende Werte vor dem Schreiben in den Hash umzurechnen oder umzuformatieren. Die Logik dazu ist bereits in Unit.pm vorgesehen, es kommt keine Arbeit auf Modulautoren für bestehende Module zu. Wer aber in seinem Modul selbst solche Umrechnungen vorgenommen hat, kann überlegen sein Modul deutlich zu verschlanken und ggf. doppelte Readings mit der selben Information, die aber nur für die Darstellung in unterschiedlichen Einheiten angelegt werden, zu reduzieren. Das sollte aber eher die Ausnahme sein, denn Ziel ist eigentlich die Daten möglichst "RAW" so wie sie kommen auch zu speichern. Auch mit 100 Nachkommastellen, denn es bekommt sie ja nur jemand zu Gesicht, wenn er es will und in der FHEM Logik kann mit dem genausten Wert gearbeitet werden, der zur Verfügung steht, anstatt ihn ggf. zu verkrüppeln, nur um eine schönere Anzeige zu bekommen (oder allein dafür ein zweites Reading zu erstellen). Beispiel: Die Gradzahl für die Windrichtung reicht eigentlich vollkommen aus, um sie auch in einer Himmelsrichtung anzuzeigen, statt dafür ein weiteres Reading zu erstellen. Hier möchte der eine aber gerne die kurze Schreibweise "NNW" haben, der andere hätte gerne "Nord-Nordwest" und der nächste spricht polnisch und möchte es in seiner Sprache haben. Aber ich schweife ab, zum Frontend komme ich eigentlich unten.
Für die Auswertung als Plott kann man Textwerte automatisch und standardisiert in die dafür notwendigen Zahlenwerte umrechnen. Das entspräche beispielsweise der Definition von Systemvariablen in einer Homematic CCU, bei der ich auch ein ARRAY festlege und die Position des Textwertes dadurch auch automatisch einem Zahlenwert entspricht, mit dem ich etwas anderes anfangen kann als nur mit dem Textwert. Dazu muss ich aber wissen, welche möglichen Werte ein Reading annehmen kann.
Praktischerweise kann ich diese Meta-Informationen aber sogar zur automatischen Generierung der CommandRef Informationen verwenden. Ich weiß von mir selbst, dass ich gerade bei Modulen mit mehr als nur einer Hand voll Readings diese nicht gerne (und oft mit Absicht) nicht dokumentiere und darauf setze, dass sich deren Sinn schon aus dem Namen heraus ergibt. Aber welche Möglichkeit hat ein Anwender den Sinn tatsächlich zu erkennen? Bei meiner HP1000 Wetterstation habe ich irre lange herumprobiert nur um herauszufinden, in welcher Einheit diese mir die Werte liefert. Das muss ich in FHEM bei so vielen Modulen und Readings auch oft tun. Ich muss damit herumspielen und schauen, welche verschiedenen Werte ein Reading wohl annehmen kann, denn wehe es ist nicht dokumentiert oder es wurde schlicht vergessen. Mit Reading-Types würde ein Modulautor, der sich entschließt sich darauf einzulassen, dazu angehalten minimalste Informationen einfach und schnell zu hinterlegen - in der Sprache der Logik, die vielen Entwicklern einfacher fällt, weil sie direkten Quellcodebezug hat statt in "Blümchensprache". Von dem Versuch einer einheitlichen Benennung von Readings und deren einheitliche Dokumentation für alle Module gar nicht zu sprechen... Die Benennung kann uns mit Einführung von Reading-Types aber egal sein, denn sowohl FHEM kann erkennen was genau es ist als auch der Anwender. Ob nun die Celsius-Temperatur in "temp", "temp_c", "temperature" oder "isgradwarmoderkalt" ist dabei vollkommen egal, denn der Sinn und Zweck eines Wertes (Kontext) ist direkt einsehbar und auch programmatisch auswertbar.

Nun wechseln wir ins Frontend. FHEMWEB und FHEM-Telnet sind bekannte Beispiele dafür. Hat ein Reading keine Meta-Informationen, passiert hier genau Null-Komma-Null. Sind Meta-Informationen vorhanden (egal ob durch Unit.pm, durch das Modul, durch das Device ansich oder durch den Anwender vergeben/überschrieben), können diese ausgewertet werden und für eine veränderte Darstellung sorgen, ohne dass auf der Backend- und Logik-Schicht etwas beeinträchtigt wird. Dazu zählen selbstverständlich Sprachanpassungen (ohne eine Sprachdatei aus einem Übersetzungbüro) sowie die dazugehörige Template-Information. Frontends können nun wissen, welchen Informationsgehalt sie von einem Reading erwarten können und können auch sagen:


ZitatIch möchte aber diese Rohdaten nicht direkt haben, sondern ich möchte diese gerne nur mit einer Nachkommastelle und bitte in Kilowatt und nicht in Milliwatt. Außerdem hätte ich gerne noch das wissenschaftlich korrekte Suffix dafür an der richtigen Stelle vor oder hinter der Zahl, so wie es für meine Anzeigesprache Deutsch/Englisch/U-name-it erforderlich ist. Wenn du die Sprache nicht kennt, liefere mir einfach den Standard in englischer Sprache. Außerdem möchte ich meinem Anwender gerne zeigen können, um was für eine wissenschaftliche Größe es sich hier handelt (sind es Temperaturfinformationen? Sind es elektrische Informationen?). Sag mir bitte auch welche Werte ich für dieses Reading erwarten kann, denn ich möchte meine Skala dafür entsprechend einstellen. Oder ein Auswahlfenster anzeigen.


All das geht komplett automatisch, weil ich in FHEM diverse Reading-Typen hinterlegt habe und der Anwender in FHEMWEB sagen kann, was er sehen will und wie er es sehen will. Andere Frontends, die JSON2 verwenden, können automatisch mit diesen Infos versorgt werden, wenn sie damit etwas anfangen können. Falls nicht ist es nicht schlimm, wir können ja weiterhin die Rohdaten so senden wie bisher! Die Mehrarbeit kommt also nur zustande, wenn hier jemand erkennt, dass er sich bei seinem Frontend das Leben deutlich vereinfachen kann, weil er nicht das Rad wie zig andere Frontends neben ihm wieder neu erfinden und definieren muss, wie er die Daten richtig interpretiert. Keine langen Listen mehr mit "im Reading mit dem Namen xxy und der Endung _c erwarte ich, dass die Zahl wohl offenbar einem Celsius Wert entspricht". Das muss das Frontend einfach nicht mehr wissen, es beschränkt sich endlich nur noch auf die Anzeige und wir erhalten eine Trennung von Anzeige- und Datenlogik so wie viele es schon immer haben wollten.


Nun zur Schnittstelle mit anderen Hausautomationslösungen: Wie wir an Apples Homekit (->Homebride) und Amazons Alexa sehen, arbeiten diese Systeme mit deutlich mehr Informationen als FHEM sie derzeit (sinnvoll) bereithalten kann. Ja das ein oder andere geht auch heute, bedeutet in der Regel aber für jeden einzelnen Anwender, dass er genau das gleiche einstellen und konfigurieren muss, wie hunderte/tausende andere Anwender. Warum muss das sein (ich komme nicht um einen Seitenverweis herum, der hier und z.B. bei HMCCU-Definitionen auch Linderung gebracht hätte, den du auch halb blockierst)? Die Reading-Type Erweiterung ist nicht als starres Korsett angelegt, sondern hilft einen FHEM Standard zu etablieren ohne die vorhandenen Modulautoren dazu zu zwingen etwas anpassen zu müssen. Auch Anwender können darauf verzichten oder Bestandsmodule selbstständig durch die Zuweisung von Reading-Typen so für die Anzeige erweitern, ohne die Modullogik zu beeinträchtigen. Es dürfte viele userReadings und userAttribute ersparen und große FHEM Installationen deutlich übersichtlicher und fehlerfreier gestalten (wer kennt es nicht, dass sich durch Nutzerdefinitionen Fehler einschleichen, die dann keiner mehr nachvollziehen kann so schnell). Mittels "setreadingdesc .* rtype=" kann man sogar eine gesamte FHEM-Installation durchgehen und anhand der Readingnamen dazu passende Reading-Typen zuweisen lassen. Anschließend gehe ich nochmals über die Liste durch (list .* .* rtype=.*), um False-Positives zu korrigieren et voila, die Umstellung/Erweiterung ist erledigt. Deletereading hilft mir in analoger Weise eigene Reading-Type Definitionen wieder zu entfernen.


Ja es gibt mehr Komplexität, aber wird jemand dazu gezwungen sich darauf einzulassen? Nein. Bleibt alles altbewährte wie gehabt erhalten? Ja.
Welche zentralen Fragen neben diesen beiden (für mich entscheidenden) stellst du dir dabei noch?








Edit:
Ich hätte einen Wunsch:
Lies hier nicht so viel in der Theorie, sondern installier einfach mal den Patch, mach ein "use Unit.pm" und schau, was sich für dich wirklich verändert und was du praktisch mit "setreadingdesc" und "list" anfangen kannst, um die Auswirkungen zu sehen. Ich kann hier so viel schreiben wie ich will, aber solange du nicht bereit bist entweder den (wirklich kleinen) Patch anzuschauen oder dessen Auswirkungen zusammen mit Unit.pm einfach einmal eine viertel Stunde auszuprobieren, kommen wir wohl nicht weiter.
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER

rudolfkoenig

Hmm. Ich habe das gelesen, und ich sehe aber keine neuen Argumente. Man kann was machen, was man teilweise auch jetzt machen kann. Warum das Wert ist, dafuer die zusaetzliche Komplexitaet in Kauf zu nehmen, erschliesst sich mir nicht. Nicht falsch verstehen: ich sperre mich nicht prinzipiell gegen Aenderungen. Ich will nur wissen, ob irgendein Aufwand es Wert ist.

Btw. der Patch ist mit 100k (Unit.pm kommt ja ploetzlich mit) gross genug, dass ich nicht alle Nebenwirkungen verstehe. Und die, die ich verstehe (z.Bsp. wie $lang eingebaut ist, neue Abhaengigkeit in fhem.pl von JSON.pm, die readingsDesc Implementierung), ist mir die Vorteile (noch) nicht Wert.

Loredo

#16
Ich habe den list-Befehl nun so umgeändert, dass er mit parseParams() arbeitet. Die Regex-Funktion für den 3. Parameter funktioniert jetzt abwärtskompatibel zur bisherigen Version.
Außerdem habe ich den Language Support nun so abgekapselt, dass der Device-Hash nicht mehr verändert wird. Dafür wird in replaceTemplate() eine Deep-Kopie von $defs{$name}{readingDesc} mittel Perl::Clone angefertigt und dann entsprechend für die Anzeige aufbereitet. Im readingDesc Hash sieht man deshalb nun auch vollständig alle Inhalte.


Die Sprache wird dabei ganz einfach so gewählt, dass bei Vorhandensein eines Hashes der Form {key}{sprache} ein {key} umgewandelt wird, bevor die Ausgabe verarbeitet wird und schließlich die beiden Template Vorlage "tmpl" und "tmpl_long" durch ihre Werte ersetzt werden. In diesen Templates wird alles, was mit %% umgeben ist, durch entsprechende Werte aus dem readingsDesc Hash ersetzt, sofern es einen entsprechend benannten Scalar-Key gibt. Das ist auch schon die ganze Magie, nichts großartiges.


Eine gute Idee davon wie das alles gemeint ist gibt eine Ansicht auf den aktuellen ReadingsType Hash:



setreadingdesc rtype=?
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER

Loredo

#17
Zitat von: rudolfkoenig am 13 November 2016, 19:22:18
Btw. der Patch ist mit 100k (Unit.pm kommt ja ploetzlich mit) gross genug, dass ich nicht alle Nebenwirkungen verstehe. Und die, die ich verstehe (z.Bsp. wie $lang eingebaut ist, neue Abhaengigkeit in fhem.pl von JSON.pm, die readingsDesc Implementierung), ist mir die Vorteile (noch) nicht Wert.


Eigentlich greift alles aus Unit.pm ja erst, wenn man showUnits=1 gesetzt hat und zusätzlich ein Modul tatsächlich den Support dafür eingebaut hat oder ein Benutzer anfängt entsprechende Attribute manuell zu setzen.
Ist denn ein vollständiges Verständnis dafür notwendig, solange die Schnittstelle bzw. der Übergang genau bekannt ist? Es wird kein zusätzlicher Code ausgeführt, solange showUnits=0 steht.




@André: Ich finde wir brauchen readingsFormat nicht. Stattdessen würde ich ein Device-Attribut "readingsTypes" haben wollen, um Readings-Typen auf Globaler und Device-Ebene als Anwender definieren zu können.
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER

klaus.schauer

Beim EnOcean-Modul sehe ich durchaus Bedarf für ein möglichst universelle Reading-Funktionen einschl. der Unit-Ausgabe.

Ich möchte kurz beschreiben, wie die Daten im Modul in drei Varianten empfangen und aufbereitet werden:

# Kanalbeschreibung mit Hilfe der in den Profildefinitionen vorab festgelegten Werte und Wertebereiche

I. d. R. wird dabei nur der Wert auf die Variablengenauigkeit gerundet ausgegeben. Die Einheit ist dann der commandref zu entnehmen.

# Kanalbeschreibung, über das Datentelegramm selbst, mit Angaben zum Wertebereich, zu Einheiten und der Genauigkeit

Hier wird die Ausgabeformatierung und Rundung zur Laufzeit berechnet. Zusätzlich gibt es in den meisten Fällen ein zusätzliches Reading, das die Einheit beschreibt z. B. temperatureUnit zu temperature

# Kanäle, die während des Anlernvorgangs beschrieben werden

Jeder Kanal wird über folgende Parameter definiert:
1. Kanaltyp: Data, Flag, Enumertion
2. Signaltyp: abhängig vom Kanaltyp z. B. on/off, auto/cooling/heating, power (W)/ frequency (Hz)/ time (s)
3. Wertetyp: Current value, set point absolute, set point relative

Weiterhin werden Parameter für die Umsetzung und Formatierung der Daten selbst beschrieben:

1. Auflösung: 2 bit - 32 bit
2. Skalierung min: x 1, ..., x 10.00.000, x 0.1, ..., x 0.000000001
3. Skalierung max: x 1, ..., x 10.00.000, x 0.1, ..., x 0.000000001
4. Engineering min: -128 ... 127
5. Engineering max: -128 ... 127

Für diesen Kanaltyp werden neben dem formatierten Wert zusätzliche Readings xUnit, xChannelType, xValueType je Kanal ausgegeben.

Für das EnOcean-Modul wäre es deshalb ideal und notwendig, dass diese o. a. Parameter zur Laufzeit an die readingsUnitBulkUpdate() oder readingsUnitSingleUpdate() übergeben werden könnten.

Vielleicht gibt es ja auch einen anderen gleichwertigen Ansatz.

Mir würde es insgesamt helfen, wenn die vorgestellten neuen Funktionen mit Hilfe eines Programmbeispiels zur Werteübergabe beschrieben würde.

Loredo

#19
Einfacher wäre es, wenn du es dir selbst ansiehst, Klaus, und Feedback gibst, was ggf. noch fehlen würde. Ich kann mich selbst nicht in die EnOcean Welt eindenken.
Das Wunderground Modul gibt ein extrem gutes Beispiel darüber ab, wie die Zuweisung von Reading-Typen funktioniert. Bisher ist es vornehmlich mit dem Hintergrund von Wettermodulen definiert. Die Builtin-Readingtypen sollten aber eigentlich bereits mehr als ausreichend für die allermeisten FHEM-Readings sein.


Zentraler Ansatz ist allerdings nicht zwangsläufig die eingehenden Werte, die mit readingsBulkUpdate() geschrieben werden vorher umzuwandeln und den formatierten Wert in fhem.save abzuspeichern. Vielmehr sollen die Daten, wann immer möglich, als Rohdaten erhalten bleiben, um dann für die Anzeige umformatiert und ggf. auch konvertiert zu werden. Aktuell kann man noch nicht von einer Einheit in die andere umrechnen lassen, da mein Ansatz anders ist als der von André. Es gibt Reading-Typ-Gruppen und innerhalb einer dieser Gruppen soll es dann möglich sein von einer in die andere Einheit umzurechnen. Für die metrischen Angaben fehlt dazu nicht viel, aber auf gleiche Weise wird man dann auch von Fahrenheit in Celsius etc. umrechnen lassen können. Das Readings-Attribut "rtype" zu setzen bedeutet also in erster Linie zu sagen, in welchem Format der aktuelle Readings-Wert einzuordnen ist. Später ist ein Readings-Attribut "convert" vorgesehen, welches dann ebenfalls einen rtype enthält. Die Formatierungsfunktion soll dann automatisch anhand der unterschiedlichen Readings-Attribute ermitteln, ob und wie in das gewünschte Anzeigeformat umgewandelt werden kann. Dafür gibt es auch schon eine Menge Definitionen in UConv.pm, die ich als Hilfsfunktionen dafür vorgesehen habe.
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER