Kennlinie / Lookup table in Perl umsetzen

Begonnen von der_oBi, 21 September 2016, 21:13:29

Vorheriges Thema - Nächstes Thema

der_oBi

Hi zusammen,

ich stehe gerade vor folgendem Problem:
Ich würde gerne in einem Reading eine Kennlinie (also x=>y) hinterlegen. Wird diese Kennlinie mit einem Eingangswert (x) "gefüttert", soll ein innerhalb der Kennlinie interpolierter Ausgangswert (y) rauskommen.
Beispiel:
x | 1 | 2
----------
y | 0 | 1

für x=1,5 sollte als Ergebnis demnach y=0,5 ausgegeben werden.

Gibt es hierfür bereits eine Funktion in Perl? Ich könnte es mit Sicherheit auch (mit viel Aufwand) mit einer selbstgebauten Routine umsetzen, hoffe aber, dass es eine einfachere Lösung gibt.

Sorry, wenn ich mich vielleicht ein wenig umständlich ausgedrückt habe. Ich kann weder im Forum noch sonstwo im Netz irgendwas finden. Vielleicht auch einfach nur weil mir der richtige Suchbegriff fehlt?!   ???

Ich hoffe jemand hat eine Idee :)

KernSani

Ich bin mir nicht sicher, ob ich verstehe was du meinst.... Möchtest du ein Funktion (im von dir genannten Beispiel y = x-1) in einem Reading hinterlegen? Wie soll diese dann "gefüttert" werden?
Vielleicht kannst du den Anwendungsfall etwas konkreter darstellen...

Grüße,

Oli

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

Ellert

Vielleicht könntest userReadings benutzen und in den Kennlinienabschnitten linear interpolieren.

der_oBi

Kannst Du Deine Idee etwas genauer beschreiben?

Ellert

Zitat von: der_oBi am 24 September 2016, 06:56:50
Kannst Du Deine Idee etwas genauer beschreiben?
In das Gerät, in dem x entsteht baust Du ein userReading, das den zugehörigen y-Wert berechnet, s. userReadings

Mit Kennlinienabschnitt meine ich den Bereich zwischen zwei nebeneinander liegenden Wertepaaren. Dein Beispiel hat 2 Wertepaare, also nur einen Kennlinienabschnitt. Den  Wert berechnest Du so, wie Du auf 0,5 gekommen bist oder durch lineare Interpolation.

der_oBi

Was lineare Interpolation ist, weiß ich von Berufs wegen leider nur zu genau  ;)

Ich habe eben das Problem, dass meine Kennlinie nicht (wie in meinem Beispiel oben) durch eine einfache mathematische Funktion abzubilden wäre. Wenn ich Deine Idee richtig verstanden habe, müsste ich aber in dem userReading eine Funktion hinterlegen, die mir das Ergebnis berechnet, oder?

Ich habe nun nach langem Bemühen von Google doch noch etwas gefunden, was meine Anforderungen erfüllen sollte:

Math::Interpolate

Wenn ich heute Abend dazu komme, werde ich mal mein Glück damit versuchen.
Vielleicht kennt/nutzt ja jemand diese Lib schon?

Ajuba

Hallo oBi

Konntest du dein Problem lösen?
Ich muss auch Messwerte eines nicht-linearen Thermometers umrechnen. Eine lange Tabelle mit x mA entspricht y °C 

Bei den Readings fehlt mir noch der Durchblick und ich wäre dankbar wenn du deine Lösung hier posten könntest.
FHEM auf RPi3, Homematic CCU3 mit Cuxd und CUL 868 für FS20, Siemens S7 über CP343-1,
DbLog zu MySQL auf NAS QNAP TS-253D,
Yeelight

igami

Guck dir mal das powerMap Modul an, ist zwar eigentlich für Leistung und Energie gedacht, aber funktioniert ja trotzdem.
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal im April 2020.

MAINTAINER: archetype, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap
ToDo: AVScene, FluxLED

Ajuba

Danke für den Tip mit powerMap. Das könnte tatsächlich sein, was ich brauche.
Ich durchschaue nur noch nicht wie ich meinen Input "reinbringe" und wie ich das Ergebnis "auslese".
Ich habe mir mal zum Üben einen Dummy namens IN angelegt und möchte abhängig von dessen Wert Ausgaben auf OUT sehen.
Außerdem habe ich versucht dem IN das Attribut Powermap zuzuweisen (habe ich wahrscheinlich falsch gemacht). Was muss ich beim Attribut setzten in das leere Feld eintragen? 1 oder .* oder sonst was ?
Meine Powermap habe ich "Kennlinie" getauft.

Set assign gibt mir nur "Kennlinie" als Auswahl
Get devices liefert ebenfalls nur "Kennlinie"

Leider bin ich mit Perl Code auch noch auf Kriegsfuß.
Wenn ich unter attr Powermap folgendes eingebe
{
          'IN' => {
            '1' => <10>,
            '2' => <20>,
            '3' => <30>,
          },

sieht meine config folgendermaßen aus

define Kennlinie powerMap
attr Kennlinie powerMap {\
          'IN' => {\
            '1' => <10>,\
            '2' => <20>,\
            '3' => <30>,\
          },
define IN dummy
attr IN powerMap .*
define OUT dummy


Wie ist das überhaupt gemeint?
{
          '<reading>' => {
            '<value>' => <power>,
            '<value>' => <power>,
             ...
          },

Was ist reading, value und power?
Welche Sonderzeichen '<>' müssen stehen bleiben und was durch was ersetzt?
Und wie weise ich das meinen Variablen IN und OUT zu?

Sorry für die vielen hilflosen Fragen.
FHEM auf RPi3, Homematic CCU3 mit Cuxd und CUL 868 für FS20, Siemens S7 über CP343-1,
DbLog zu MySQL auf NAS QNAP TS-253D,
Yeelight

igami

Zitat von: Ajuba am 31 Januar 2017, 22:05:59
Ich habe mir mal zum Üben einen Dummy namens IN angelegt und möchte abhängig von dessen Wert Ausgaben auf OUT sehen.
Das wird so nicht funktionieren, powermap erzeugt neue Readings im bestehenden Device.
Du könntest das so machen:
Ein Dummy mit Namen Kennlinie und den Readings IN und OUT.
Ein powerMap mit Namen Powermap.

Zitat von: Ajuba am 31 Januar 2017, 22:05:59
Außerdem habe ich versucht dem IN das Attribut Powermap zuzuweisen (habe ich wahrscheinlich falsch gemacht). Was muss ich beim Attribut setzten in das leere Feld eintragen? 1 oder .* oder sonst was ?
In das Attribut poweMap musst du deine Kennlinie eintragen.

Zitat von: Ajuba am 31 Januar 2017, 22:05:59
Set assign gibt mir nur "Kennlinie" als Auswahl
powerMap verfügt über eine Datenbank in der schon Werte fur Hue Leuchten und Sonos Lautsprecher stehen. Würde dein Thermometer in dieser Datenbank stehen würde das powerMap Attribut darüber auch gefüllt werden um es manuell zu bearbeiten. Da dies aber nicht der Fall ist passiert nichts ;)

Zitat von: Ajuba am 31 Januar 2017, 22:05:59
Get devices liefert ebenfalls nur "Kennlinie"
Da zeigt dir powerMap für welche devices es Berechnungen anstellt, scheinbar bisher nur Kennline.

Zitat von: Ajuba am 31 Januar 2017, 22:05:59
Wie ist das überhaupt gemeint?
{
          '<reading>' => {
            '<value>' => <power>,
            '<value>' => <power>,
             ...
          },
Ein device kann verschiedene Readings haben. Ich hatte gehofft, dass es durch das Beispiel für die HUE white besser zu verstehen ist:

          'pct' => {
            '0' => 0.4,
            '10' => 1.2,
            '20' => 1.7,
            '30' => 1.9,
            '40' => 2.3,
            '50' => 2.7,
            '60' => 3.4,
            '70' => 4.7,
            '80' => 5.9,
            '90' => 7.5,
            '100' => 9.2,
          },
          'state' => {
            'unreachable' => 0,
            '*' => 'pct',
          },

Zitat von: Ajuba am 31 Januar 2017, 22:05:59
Was ist reading, value und power?
reading ist der Name des Readings, value ist der Wert des Readings und power ist die Leistungsaufnahme.
Bei der HUE wird bei einem pct, also Dimmwert, von 60 % eine Leistung von 3.4 Watt aufgenommen.

Zitat von: Ajuba am 31 Januar 2017, 22:05:59
Welche Sonderzeichen '<>' müssen stehen bleiben und was durch was ersetzt?
Ich weiß nicht ob das irgendwo ofiziell steht, aber ich habe es so verstanden, dass das was in <> steht ein Bezeichner ist und die <> entfallen dabei. Aus '<reading>' wird 'pct'. Sollten noch eckige Klammern vorkommen [] so handelt es sich um ein optionales Element.

Hier ein Beispiel für dei Umsetzung als Raw definition

defmod powerMap powerMap

defmod Kennlinie dummy
attr Kennlinie powerMap {'IN' => {\
   '1' => 10,\
   '2' => 20,\
   '3' => 30,\
},\
}
attr Kennlinie powerMap_noEnergy 1
attr Kennlinie powerMap_rname_P OUT
attr Kennlinie readingList IN
attr Kennlinie setList IN

Du bekommst einen Dummy mit Namen Kennlinie, welche zwei Readings besitzt: IN und OUT.
Durch das Attribut powerMap_noEnergy wird festgelegt, dass kein Energieverbrauch berechnet wird. Mit dem Attribut powerMap_rname_P wird festgelegt, dass das Ausgabe Reading OUT heißt.

Ich hoffe ich konnte dir deine Fragen verständlich beantworten und würde mich freuen wenn es klappt. In jedem Fall aber bitte Feedback geben :)

Grüße
igami
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal im April 2020.

MAINTAINER: archetype, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap
ToDo: AVScene, FluxLED

Ajuba

Ahhh. Schön langsam dämmert es bei mir.
Vor allem die Raw definition hat geholfen.

Kann es erst am Abend ausprobieren und werde dann berichten.
Danke
FHEM auf RPi3, Homematic CCU3 mit Cuxd und CUL 868 für FS20, Siemens S7 über CP343-1,
DbLog zu MySQL auf NAS QNAP TS-253D,
Yeelight

Ajuba

OK, das wäre geschafft. Aber ohne dein Beispiel hätte es nicht geklappt. DANKE

Ich kann jetzt innerhalb von Kennlinie mit "set Kennlinie IN" Werte setzen und gleich unterhalb die Readings IN und OUT korrekt ablesen.  :)

Jetzt noch folgende Fragen:

  • Wie kann ich den OUT Wert nun einer Variable (z.B. dem dummy Temperatur) zuweisen?
  • Der STATE von Kennlinie bleibt dabei immer "? ? ?". Ich nehme an, das ist normal
  • In Fhem werden Kommazahlen offensichtlich im englischen Format (2.9) und nicht im deutschen Format (2,9) akzeptiert. Hab ich was falsch eingestellt, oder ist das so gewollt. Mein Excel akzeptiert das deutsche Format (2,9) als Zahl.
  • Nur aus Interesse: Warum heißt es in der raw definition defmod, im config aber trotzdem define?


FHEM auf RPi3, Homematic CCU3 mit Cuxd und CUL 868 für FS20, Siemens S7 über CP343-1,
DbLog zu MySQL auf NAS QNAP TS-253D,
Yeelight

igami

Zitat von: Ajuba am 01 Februar 2017, 23:21:14
Wie kann ich den OUT Wert nun einer Variable (z.B. dem dummy Temperatur) zuweisen?
Warum möchtest du das tun? Das ist möglich mit readingsProxy, notify oder DOIF, aber dann hättest du den Wert ja doppelt in fhem. Du kannst ja auch einfach das Reading statt OUT temperature nennen.

Zitat von: Ajuba am 01 Februar 2017, 23:21:14
Der STATE von Kennlinie bleibt dabei immer "? ? ?". Ich nehme an, das ist normal
STATE zeigt standardmäßig den Wert vom Readings state. Dies gibt es hier jedoch nicht. Es lässt sich aber über das Attribut stateFormat beeinflussen, sodass dann der Wert von OUT angezeigt wird. Wie das geht steht in der commandref unter readingFnAttributes. Beispiele lassen sich finden indem man in der commandref nach stateFormat sucht.

Zitat von: Ajuba am 01 Februar 2017, 23:21:14
In Fhem werden Kommazahlen offensichtlich im englischen Format (2.9) und nicht im deutschen Format (2,9) akzeptiert. Hab ich was falsch eingestellt, oder ist das so gewollt. Mein Excel akzeptiert das deutsche Format (2,9) als Zahl.
Mir ist nicht bekannt, dass man das ändern kann, auch nicht in einer anderen Programmiersprache als perl.

Zitat von: Ajuba am 01 Februar 2017, 23:21:14
Nur aus Interesse: Warum heißt es in der raw definition defmod, im config aber trotzdem define?
wirf mal einen Blick in die commandref, dort sind beide Befehle erklärt. Auch kannst du mal die Befehle "define Kennlinie dummy" und "defmod Kennlinie dummy" ausführen und gucken was passiert ;)
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal im April 2020.

MAINTAINER: archetype, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap
ToDo: AVScene, FluxLED

der_oBi

Hey,

ja ich konnte mein Problem lösen, allerdings nicht in FHEM sondern in Perl.
Es gibt ein Perl-Modul Math::Interpolate (einfach mal googlen).
Darin ist genau das umgesetzt, was ich brauchte und nicht selbst programmieren wollte ;)

igami

Zitat von: der_oBi am 02 Februar 2017, 19:39:03
ja ich konnte mein Problem lösen, allerdings nicht in FHEM sondern in Perl.
Es gibt ein Perl-Modul Math::Interpolate (einfach mal googlen).
Darin ist genau das umgesetzt, was ich brauchte und nicht selbst programmieren wollte ;)
Würdest du auch deine Lösung mitteilen?
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal im April 2020.

MAINTAINER: archetype, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap
ToDo: AVScene, FluxLED