Kennlinie / Lookup table in Perl umsetzen

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

Vorheriges Thema - Nächstes Thema

der_oBi

Habe ich doch. Die Lösung für mein Interpolationsproblem an sich.
Die individuelle Umsetzung kommt natürlich auf die Problemstellung an. Einfach mal bei cpan nachlesen:
https://www.google.de/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0ahUKEwjoueWEl_LRAhWE7xQKHVyoB9AQFggcMAA&url=http%3A%2F%2Fsearch.cpan.org%2F~bzajac%2FMath-Interpolate-1.05%2Flib%2FMath%2FInterpolate.pm&usg=AFQjCNGD0O3eWnNuak-YRo_3-e38kNIgew&sig2=4q_AJbqLs2pWccqO_pEWiw

In meinem speziellen Fall habe ich es so gemacht:
Interpolate braucht jeweils ein Array mit den x-Werten und eines mit den y-Werten. In meiner Sub habe ich die dann aus einem FHEM-Reading ausgelesen. Dort hatte ich die Wertepaare in folgender Form hinterlegt: "x1:y1,x2:y2,x3:y3". Das Ganze eingelesen und mit split() zerlegt und die beiden Arrays (@x und @y) gefüttert.
Dann kann ich meiner Sub einen x-Wert übergeben und diese gibt mir den interpolierten y-Wert zurück.

Ajuba

Also für mich funktioniert die powermap im Prinzip perfekt. Mit stateFormat klappt auch die Anzeige gut.

Nur bei der Berechnung zickt powermap irgendwie.
Ich habe es nun mit meinen echten Readings von der PLC befüllt.
Das Analog-Thermometer geht von +80°C bis -30°C entsprechend liefert der Analogeingang der PLC Werte von 1793 bis 15501.
Somit sieht mein Powermap attribut folgendermaßen aus (ich spare mir hier die Auflistung aller Werte.

{'IN' => {
'1793' => 80,
'1847' => 79,
'1898' => 78,
'1949' => 77,
'2003' => 76,
'2058' => 75,
.....
'15037' => -24,
'15122' => -25,
'15203' => -26,
'15282' => -27,
'15358' => -28,
'15431' => -29,
'15501' => -30,
},
}


NUN ZUM PROBLEM:
Genaue Werte werden perfekt umgesetzt.
ABER die interpolierten Zwischenwerte !!!
Werte unterhalb dem einstelligen positiven Temperaturbereich scheinen auch zu passen.
Aber oberhalb:
Während 1949 perfekt die 77°C ergibt kommt bei  1848 2.11990502572221948°C heraus. Es sind immer einstellige Falsch-Ergebnisse.
Ich blicke nicht dahinter wo das Problem liegt.  ???
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 02 Februar 2017, 21:53:32
NUN ZUM PROBLEM:
Genaue Werte werden perfekt umgesetzt.
ABER die interpolierten Zwischenwerte !!!
Werte unterhalb dem einstelligen positiven Temperaturbereich scheinen auch zu passen.
Aber oberhalb:
Während 1949 perfekt die 77°C ergibt kommt bei  1848 2.11990502572221948°C heraus. Es sind immer einstellige Falsch-Ergebnisse.
Ich blicke nicht dahinter wo das Problem liegt.  ???
Was meinst du mit einstellig Falsche-Ergebnisse?

Das Problem liegt glaube ich im Modul selbst, ich bin nie davon ausgegangen, dass negative bzw. Absteigende Werte berücksichtigt werden müssen.
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

Sorry, da habe ich mich unklar ausgedrückt. Und sehe gerade, dass ich mich bei einem Wert auch noch vertippt habe.
Ich meinte, dass im Fall einer falschen Interpolations-Berechnung die Zahl vor der Kommastelle einstellig (2.xxx) ist selbst wenn die Lösung im zweistelligen Bereich (55.xxx oder 78.xxx) sein sollte.
Also 1949 ergibt korrekt die 77°C.
Aber 1948 ergibt  2.1199050257222194 °C statt 77.06xxx °C.

Die negativen Werte scheinen für powermap kein Problem darzustellen und die absteigenden Werte grundsätzlich auch nicht.
Die absteigenden Werte könnte ich zur Not auch beheben indem ich das in der PLC invertiere. Nur an den negative Werten kann ich bei der Temperatur naturgemäß nichts ändern wie man aktuell im Freien ja gerade merkt :D.

Also meiner Meinung nach geht es perfekt für alles unter ca. 10°C und darüber fängt es beim Interpolieren zu spinnen an.
Kann es sein, dass es zu viele Werte sind? Gibt es eine Limitierung?
Was kann ich überprüfen oder versuchen um zur Lösung beizutragen?
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

der_oBi

Wie schon erwähnt: wenn Du sowieso schon in Perl zugange bist, probier einfach mal Math::Interpolate. Da ist mit Sicherheit auch für Dich die richtige Funktion dabei.

Prof. Dr. Peter Henning

Diese Ansätze sind alle grenzwertig. Math::Interpolate beispielsweise bewirkt einen ziemlichen Rechenaufwand.

Es ist viel sinnvoller, sich aus den bekannten Werten mit einem Computeralgebraprogramm (sagen wir Wolfram Alpha) eine interpolierende Funktion zu bauen und diese direkt in Perl umzusetzen.

LG

pah

Ajuba

Also das Problem von Powermap habe ich vermutlich herausgefunden.
Es sind Inputwerte >1000

Wenn die Inputwerte unter 1000 bleiben geht es mit negativen sowie absteigenden Werten korrekt um und weist korrekt die interpolierten Ergebnisse zu (Soweit ich es halt empirisch feststellen konnte).

Für mich wäre in work arround, meinen PLC Input immer durch 20 zu dividieren. Dadurch verliere ich zwar an Auflösung, sollte aber am Ergebnis hoffentlich nichts ändern.
Ich scheitere dabei nur wieder an Fhem Grundlagen.
Kann man diese Division gleich als userReading durchführen?
define Temperatur S7_ARead db 209 20 u32
attr Temperatur IODev PLC
attr Temperatur userReadings Temp { ReadingsVal("Temperatur")/20;; }

Mein jämmerlicher Versuch entsprechend CommandRef bringt folgende Fehlermeldung:
<pre>Error evaluating Temperatur userReading Temp: Not enough arguments for main::ReadingsVal at (eval 2582) line 1, near ""Temperatur")" </pre>

Sehe ich das überhaupt richtig, dass ich den Wert als UserReading unter "Temperatur" gleich dividieren kann und wie macht man das korrekt?
Wenn ja, kann ich dann die PowerMap Aufrufe auch gleich mit einbauen?
Oder muss ich das über Zwischenvariablen machen und wenn ja, wie?
Ich hatte beim ersten Einlesen in Fhem mal was gefunden über rechnen mit Variablen finde es aber leider nicht mehr. :-[
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

Loredo

Ich möchte noch darauf hinweisen, dass man das Modul zwar augenscheinlich dafür zweckentfremden kann, diese Spezialfälle aber in der möglichen Weiterentwicklung keine sonderliche Beachtung finden werden und können.
Ein gutes Beispiel ist die Unit Integration. Die Typen der Readings werden bereits als "Wh/Watt pro Stunde" bzw. "W/Watt" deklariert und das Modul arbeitet intern auch bereits damit, es ist lediglich aufgrund der fehlenden Unterstützung in FHEMWEB nicht sichtbar (und es steht in den Sternen, ob wir Rudi davon jemals überzeugen können). Wenn man es also zweckentfremdet, muss man die Einheiten (später) auch entsprechend abändern. Das funktioniert aktuell aber noch nicht unbedingt zuverlässig über das Attribut readingsDesc.
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

Ajuba

Ich, als Anfänger, folge diesem Weg auch nur weil es anscheinend kein anderes Modul gibt, das Kennlinien einfach ohne externe Tools umsetzen kann .
Soweit dürfte es für mich auch funktionieren.
Nun habe ich endlich auch das Dividieren mit notify geschafft und habe und somit Inputwerte unter 1000 für die Powermap korrekte Ergebnisse liefern sollte.

Leider scheitere ich als nächstes daran, dass meine Kennlinie automatisch bei Wertänderung updated.  :-\
Mein Input Wert heisst nun "dum3" und ich habe das ehemalige "IN" durch "dum3" ersetzt.
Schaue ich zum vom PLC Wert errechneten "dum3" werden dort fleissig die PLC Werte errechnet und ändern sich.
ABER bei "Kennlinie" ändert sich absolut nichts
Ich kann (komischerweise) mit "SET Kennlinie dum3" den Eingabe-Wert sogar verändern und Powermap rechnet das Ergebnis korrekt aus.

Hier meine Raw definition
defmod Kennlinie dummy
attr Kennlinie powerMap {'dum3' => {\
'90' => 80,\
'92' => 79,\
'95' => 78,\
.....
'768' => -28,\
'772' => -29,\
'775' => -30,\
},\
}
attr Kennlinie powerMap_noEnergy 1
attr Kennlinie powerMap_rname_P OUT
attr Kennlinie readingList dum3
attr Kennlinie room Wetter
attr Kennlinie setList dum3
attr Kennlinie stateFormat OUT

setstate Kennlinie 0
setstate Kennlinie 2017-02-04 13:30:18 IN 720
setstate Kennlinie 2017-02-05 20:06:12 OUT 0
setstate Kennlinie 2017-02-05 20:06:12 dum3 600


Was fehlt für ein automatisches Update?
Muss ich die Fhem Variable anders nennen (Klammer, Hochkomma, etc.)?
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

Loredo

Warte mal das Update von powerMap morgen ab, da ist die Sortierreihenfolge gefixt.


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

Ajuba

Also wegen mir brauchst du nichts ändern.
Es scheint doch korrekt zu funktionieren.  Mein einziges Problem waren Inputs > 1000 und selbst das kann ich durch dividieren lösen.

Oder habe ich da was übersehen?

Momentan frage ich mich wie ich bei Wert Änderungen automatisch berechnete Ergebnisse bekomme. Siehe mein letzter Post. Ist sicher eine absolut dumme Anfängerfrage. Sorry.

Gesendet von meinem SM-G920F mit Tapatalk

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

Loredo

Das Modul arbeitetet Event basiert und du hast bei dir das Reading dum3 genannt. Es findet somit nur eine neue Berechnung des Readings mit dem Namen aus powerMap_rname_P statt, wenn dum3 ein Event auslöst.


Wenn du das Reading IN als Eingangswert nutzen willst, musst du das auch entsprechend so definieren.
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

Ajuba

Das hatte ich mir schon gedacht und schon vorher folgendes ausprobiert

attr Kennlinie event-on-change-reading dum3

Aber obwohl dum3 fröhlich seine Werte ändert tut sich in der Detailansicht gar nichts?
Das muss ich doch bei Kennlinie reinschreiben, oder?
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

Loredo

event-on-* muss nicht gesetzt sein. Das schränkt Events ein, es definiert sie nicht explizit.


Die Detailansicht ändert sich nur sofort, wenn du Longpoll in FHEMWEB aktiviert hast. Ansonsten musst du die Seite manuell im Browser neu laden, um geänderte Werte zu sehen.
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

Ajuba

Browserupdate und Longpoll bringt nichts.
Abgesehen davon sehe ich jede andere Wertänderung auf anderen Devices auch sofort.

Wie löse ich nun das erwähnte Event mit dum3 aus? Muss ich da beim Notify mit reinpacken?
ZitatEs findet somit nur eine neue Berechnung des Readings mit dem Namen aus powerMap_rname_P statt, wenn dum3 ein Event auslöst.

Hier noch mal die aktuelle Config (nur die wesentlichen Teile aller Beteiligten)
Bei Kennlinie lasse ich die mittleren Werte weg und ersetzte sie durch .....
define Powermap powerMap
define Kennlinie dummy
attr Kennlinie powerMap {'dum3' => {\
'90' => 80,\
'92' => 79,\
'95' => 78,\
.....
'768' => -28,\
'772' => -29,\
'775' => -30,\
},\
}
attr Kennlinie powerMap_noEnergy 1
attr Kennlinie powerMap_rname_P OUT
attr Kennlinie readingList dum3
attr Kennlinie room Wetter
attr Kennlinie setList dum3
attr Kennlinie stateFormat OUT
define Temperatur S7_ARead db 209 20 u32
attr Temperatur IODev PLC
attr Temperatur room Wetter
define dum3 dummy
attr dum3 room Dummys
define dumNot notify Temperatur {fhem("set dum3 " . (Value("Temperatur") /20))}
attr dumNot room Dummys
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