[DBRep] maxvalue Reading (und evtl userReading) Frage

Begonnen von Kai-Alfonso, 30 September 2019, 16:46:19

Vorheriges Thema - Nächstes Thema

Kai-Alfonso

Hallo,

ich habe mal eine Frage zu maxvalue und dem Readingname. Ich lasse mir von einem Temperatur-Device die Höchsttemperatur des aktuellen Jahres ausgeben. Das Reading bekommt (wie in der Doku beschrieben) den Namen:

2019-07-25_16-38-16__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__no_aggregation

jetzt würde ich aber gerne (weil ich es in meiner SmartVisu Visu gerne darstellen möchte) das Reading nach zb. MaxTemp12M ändern. Normalerweise würde ich das ja mit userReadings machen, allerdings kann sich der Readingsname auch ändern, ja nachdem ob ein höhererer Wert in der DB ist oder nicht.

Jetzt meine Fragen:

- kann man den Readingsname evtl konfigurierbar machen?
- wenn nein, unterstützt  userReading im Readingsval in der Angabe des Readings auch regex?
- Bonusfrage: Kann ich den Timestamp-Anteil des Readings als Timestamp des Readings setzen?
- Alternativ dann halt wieder ein neues Reading mit userreading (Problem mit dem variablen Anteil des Readingsnamens wie vorher)

oder hat jemand eine andere Lösung? In Smartvisu bzw Fronthem brauche ich zur Darstellung eine eindeutige DeviceName/Readings/Timestamp Kombination
Raspi2|nanoCul433|nanoCul868|CCU2
Energie-USBZähler|homebrew HM Devices
DBLog|DBRep|Homematic|Baumarktsteckdosen
Hue|Webcams mit DS-Station (Synology)|Bewegungsmelder|Rollladen|Schalter (IT|HM)

DS_Starter

Hallo Kai-Alfonso,

Zitatkann man den Readingsname evtl konfigurierbar machen?
Ja, ist bereits möglich mit dem Attribut readingNameMap. Allerdings geht das nicht für das komplette Reading, sondern für einen Teil des Strings. Hintergrund ist, wenn ein Reading immer komplett gleich heißt, würde es in der Anzeige
überschrieben, d.h es würde nur eins dargestellt obwohl es 10 gibt.
Als Beispiel mit readingNameMap = MaxVal:

    2019-09-29_19-01-25__MaxVal__2019-09-29  8.1900  2019-09-30 18:36:28

Zitatunterstützt  userReading im Readingsval in der Angabe des Readings auch regex?
Readingsval ünterstützt kein Regex in der Angabe des Readings.

ZitatBonusfrage: Kann ich den Timestamp-Anteil des Readings als Timestamp des Readings setzen?
Nein, ist nicht vorgesehen.

Aber es gibt natürlich Lösungen. Eine davon ist die eingebaute Schnittstelle für den User mit dem Attribut userExitFn.
Damit ist so ziemlich alles machbar, vorausgesetzt man kann ein bisschen Perl.
Wenn du es damit angehen möchtest, würde ich dir helfen. Man müßte nur genau wissen wie die benötigte Darstellung  der  DeviceName/Readings/Timestamp Kombination aussehen soll, als Userreading (Nachbildung mit Rgex) oder Werte in drei Readings eines Dummies oder anders ?

Grüße,
Heiko


ESXi@NUC+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

Kai-Alfonso

Zitat von: DS_Starter am 30 September 2019, 19:10:57

Aber es gibt natürlich Lösungen. Eine davon ist die eingebaute Schnittstelle für den User mit dem Attribut userExitFn.
Damit ist so ziemlich alles machbar, vorausgesetzt man kann ein bisschen Perl.
Wenn du es damit angehen möchtest, würde ich dir helfen. Man müßte nur genau wissen wie die benötigte Darstellung  der  DeviceName/Readings/Timestamp Kombination aussehen soll, als Userreading (Nachbildung mit Rgex) oder Werte in drei Readings eines Dummies oder anders ?

Grüße,
Heiko

Guten Morgen Heiko,

danke das Du mir Deine Hilfe anbietest. Ich überlege, ob es nicht sogar sinnvoll ist, maxvalue direkt im Temperatur-Device als Reading zu schreiben. Ich brauche auch nicht wirklich einen ganzen Timestamp für maxvalue, Datum als extra Reading würde reichen, je nachdem was leichter zu machen ist.

Also gibt es 2 Möglichkeiten:

1. Im Temperaturdevice ein Reading   maxTemp12M mit dem Wert maxValue. Der Timestamp vom Reading soll den Timestamp des DB Eintrags bekommen.

oder

2.  Im Temperaturdevice 2 Readings: ein Reading maxTemp12M mit dem Wert maxValue; ein Reading maxTemp12MDate mit dem Datum als Reading, wann maxValue geloggt wurde.

Ich hoffe, man kann verstehen, was ich meine  8)
Raspi2|nanoCul433|nanoCul868|CCU2
Energie-USBZähler|homebrew HM Devices
DBLog|DBRep|Homematic|Baumarktsteckdosen
Hue|Webcams mit DS-Station (Synology)|Bewegungsmelder|Rollladen|Schalter (IT|HM)

DS_Starter

Moin Kai again  :),

Zitat1. Im Temperaturdevice ein Reading   maxTemp12M mit dem Wert maxValue. Der Timestamp vom Reading soll den Timestamp des DB Eintrags bekommen.

Das würde ich als erstes mal machen. So etwas ähnliches mache ich mit Max-Power Ermittlungen des laufenden und vorherigen Monats. Also welche max. Leistung (Peak) hat die PV gebracht. Das setzt ein Reading in einem Device.


############################################################################################################
########           power_max in Rep.total_pac.currmonth / Rep.total_pac.prevmonth setzen   
############################################################################################################
sub calcpomax {
my ($name,$reading,$value) = @_;
my $hash = $defs{$name};

if($reading =~ /^.*total_pac__MAX.*$/) {
     $reading =~ /^(\d+)-(\d+)-(\d+)_(\d+)-(\d+)-(\d+)_.*$/;
     my $pmts = "$3.$2.$1 $4:$5:$6";
     my $fmtDateTime = FmtDateTime(gettimeofday());
     setReadingsVal($hash,"power_max",$value,$fmtDateTime);
     setReadingsVal($hash,"power_max_ts",$pmts,$fmtDateTime);
}
return;
}


Kannst schonmal schauen. Heute Abend würde ich dir ein Beispiel für deinen Einsatzfall erstellen wenn du bis dahin noch nicht klargekommen sein solltest.

Grüße,
Heiko
ESXi@NUC+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

Kai-Alfonso

Hallo Heiko,

ich denke, ich werde da ein wenig Hilfe brauchen. Mir ist klar, das ich eine myUtils Prozedur anlegen muss, ich dann mit attr userExitFn Prozedur aufrufen kann.

So wie ich das verstehe, wird die Prozedur mit jedem neuen Event, den ich durch die Attribute device  und reading im DBRep Device definiere, aufgerufen - oder nur, wenn ich set maxvalue display mache?

Raspi2|nanoCul433|nanoCul868|CCU2
Energie-USBZähler|homebrew HM Devices
DBLog|DBRep|Homematic|Baumarktsteckdosen
Hue|Webcams mit DS-Station (Synology)|Bewegungsmelder|Rollladen|Schalter (IT|HM)

DS_Starter

#5
Fast richtig.
Die Prozedur wird mit jedem erstellten Reading durchlaufen, also bei jedem Run des DbRep devices (also bei jedem set maxvalue display) und für jedes Ergebnisreading. In der Prozedur muss man dann filtern wann was bei welchem Readinginhalt passieren soll.
Heute Abend kann ich ein konkretes Beispiel liefern.

Lg
ESXi@NUC+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

Kai-Alfonso

Raspi2|nanoCul433|nanoCul868|CCU2
Energie-USBZähler|homebrew HM Devices
DBLog|DBRep|Homematic|Baumarktsteckdosen
Hue|Webcams mit DS-Station (Synology)|Bewegungsmelder|Rollladen|Schalter (IT|HM)

DS_Starter

#7
Hallo Kai,

hier nun dein Beispiel. Ich habe es  getestet und funktioniert so wie du es möchtest.
Im Beispiel werte ich die Datensätze eines SMA Energymeters (Device SMA_Energymeter) aus und will ermitteln wann innerhalb der letzten 24h der Spitzenwert der Einspeisung (Einspeisung_Wirkleistung) war und wie hoch er war.
Damit soll dann das Reading "maxTemp12M" im Ursprungsdevice gesetzt werden und als Besonderheit den Timestamp des ermittelten Datensatzes bekommen. Im Normalfall würde man deine Variante 2 wählen. Das neu erzeugte Reading mit Variante 1 erzeugt keinen Event !

Erstmal das DbRep anlegen und im Attribut

userExitFn = setmax

setzen. setmax ist der Name der Routine in 99_myUtils.pm.
Die anderen Parameter im DbRep zur Eingrenzung kennst du ja. "timeDiffToNow = d:1" setzen um die letzten 24h dynamisch zu berechnen und auszuwerten.

Das ganze DbRep ist nun so definiert:


defmod Rep.SMAMeter DbRep LogDB
attr Rep.SMAMeter aggregation no
attr Rep.SMAMeter device SMA_Energymeter
attr Rep.SMAMeter fastStart 1
attr Rep.SMAMeter reading Einspeisung_Wirkleistung
attr Rep.SMAMeter room DbLog
attr Rep.SMAMeter showproctime 1
attr Rep.SMAMeter timeDiffToNow d:1
attr Rep.SMAMeter userExitFn setmax


Jetzt legst du dir diese kleine Routine in 99_myUtils.pm an. Ich habe es kommentiert, damit die Funktion und vor allem auch die "Sonderlocke" klar wird, die im Normalfall nicht zur Anwendung kommt.


############################################################################################################
##        Reading maxTemp12M in Ursprung-Device aus maxValue setzen   
##        $name    = Name des DbRep-Devices
##        $reading = das übergebene Reading vom DbRep-Device in der Form:
##                   2019-10-01_11-44-45__SMA_Energymeter__Einspeisung_Wirkleistung__MAX__no_aggregation
##        $value   = der Wert des übergebenen Readings
############################################################################################################
sub setmax {
my ($name,$reading,$value) = @_;
my $resr = "maxTemp12M";                                                       # so soll das Ergebnisreading heißen
my $dev  = "SMA_Energymeter";                                                  # Device in dem ds Reading erstellt wird

if($reading =~ /^.*__SMA_Energymeter__Einspeisung_Wirkleistung__MAX__.*$/) {   # es ist das Ergebnis aus MAX / SMA_Energymeter / Einspeisung_Wirkleistung
     $reading =~ /^(\d+)-(\d+)-(\d+)_(\d+)-(\d+)-(\d+)__.*$/;                   # Extraktion Timestamp
     my $pmts = "$1-$2-$3 $4:$5:$6";
     my $hash = $defs{$dev};                                                    # hash des Zieldevices
     # readingsSingleUpdate($hash, $resr, $value, 1);                           # wenn man den aktuellen Timestamp setzt (Normalfall)
     setReadingsVal($hash,$resr,$value,$pmts);                                  # !!! Spezialfall !!! abweichenden Timestamp setzen
}
return;
}


Wenn man nun "set ... maxValue" in DbRep ausführt wird das Reading im Device SMA_Energymeter angelegt und hat den Timestamp des Datensatzes aus der Datenbank, d.h. den Zeitpunkt des Maximalwertes.
Ich weiß jetzt nicht genau wozu du es eigentlich genau in dieser Form brauchst, sonst würde ich zwei Readings anlegen und den einen den Max-Wert und dem anderen den Zeitwert zuweisen so wie du es in deinem 2. Fall beschrieben hast.

Grüße,
Heiko
ESXi@NUC+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

Kai-Alfonso

#8
Zitat von: DS_Starter am 01 Oktober 2019, 19:27:57


Wenn man nun "set ... maxValue" in DbRep ausführt wird das Reading im Device SMA_Energymeter angelegt und hat den Timestamp des Datensatzes aus der Datenbank, d.h. den Zeitpunkt des Maximalwertes.
Ich weiß jetzt nicht genau wozu du es eigentlich genau in dieser Form brauchst, sonst würde ich zwei Readings anlegen und den einen den Max-Wert und dem anderen den Zeitwert zuweisen so wie du es in deinem 2. Fall beschrieben hast.

Grüße,
Heiko

Hey Heiko

10000 Dank - ich werde mir das morgen früh spätestens mal anschauen und mich dann melden. 2 Readings würden natürlich auch gehen - ich kann in Smartvisu mir ein Reading ausgeben als Text und den Timestamp des Readings auch als Text (Variante 1) oder halt jedes Reading einzeln. Hab mal ein Screenshot angehangen, was ich ungefähr will. Ich weiß nicht, ob Du schon mal was mit Smartvisu gemacht hast, aber man kann relativ vieles damit machen



Raspi2|nanoCul433|nanoCul868|CCU2
Energie-USBZähler|homebrew HM Devices
DBLog|DBRep|Homematic|Baumarktsteckdosen
Hue|Webcams mit DS-Station (Synology)|Bewegungsmelder|Rollladen|Schalter (IT|HM)

DS_Starter

Smartvisu sagt mir was, aber ich habe kaum Zeit um mich um eigene Grafik zu kümmern.  ;)
ESXi@NUC+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

Kai-Alfonso

Zitat von: DS_Starter am 01 Oktober 2019, 19:54:11
Smartvisu sagt mir was, aber ich habe kaum Zeit um mich um eigene Grafik zu kümmern.  ;)

Verständlich ;-) habs auch nur gemacht, weil ich da auf der Arbeit die Zeit dazu habe, das nebenbei zu machen ;-)

Perl nebenbei zu lernen leider nicht :-(

Was mir bei deiner Prozedur auffällt: der Selekt geschieht über das Reading. Ich brauche hier nicht zusätzlich ein && $device = oder so ähnlich, weil ich das entsprechende Device schon über das Attribut device im Dbrep Device selektiere?
Raspi2|nanoCul433|nanoCul868|CCU2
Energie-USBZähler|homebrew HM Devices
DBLog|DBRep|Homematic|Baumarktsteckdosen
Hue|Webcams mit DS-Station (Synology)|Bewegungsmelder|Rollladen|Schalter (IT|HM)

DS_Starter

ZitatIch brauche hier nicht zusätzlich ein && $device = oder so ähnlich, weil ich das entsprechende Device schon über das Attribut device im Dbrep Device selektiere?
Ja genau, das Ergebnisreading was ausgewertet wird, ist schon hinreichend genau in der if-Bedingung bestimmt.
Man kann den Regex im if natürlich noch ausbauen und z.B. auch das Zieldevice mit extrahieren weil es ja im Reading von DbRep mitgeliefert wird.
Der Möglichkeiten sind viele.  ;)
ESXi@NUC+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

DS_Starter

Ich habe dir noch ein Beispiel erstellt wie man aus dem von DbRep gelieferten Reading gleich das Ursprungdevice extrahieren kann um das Reading dort zu setzen.
Das sieht dann so aus:


############################################################################################################
##        Reading maxTemp12M im Ursprungdevice aus maxValue setzen   
##        $name    = Name des DbRep-Devices
##        $reading = das übergebene Reading vom DbRep-Device in der Form:
##                   2019-10-01_11-44-45__SMA_Energymeter__Einspeisung_Wirkleistung__MAX__no_aggregation
##        $value   = der Wert des übergebenen Readings
############################################################################################################
sub setmax {
my ($name,$reading,$value) = @_;
my $resr = "maxTemp12M";                                                       # so soll das Ergebnisreading heißen

if($reading =~ /^.*__SMA_Energymeter__Einspeisung_Wirkleistung__MAX__.*$/) {   # es ist das Ergebnis aus  Ursprungdevice / ausgewertetes Reading / MAX
     my ($ts,$dev,undef) = split("__",$reading,3);                              # Extraktion Timestamp, Ursprungdevice = Device in dem das Reading erstellt wird
     $ts      =~ /^(\d+)-(\d+)-(\d+)_(\d+)-(\d+)-(\d+)$/;                       # Aufteilung Timestamp
     my $pmts = "$1-$2-$3 $4:$5:$6";                                            # Neuzusammenstellung des Timestamp
     my $hash = $defs{$dev};                                                    # hash des Zieldevices
     # readingsSingleUpdate($hash, $resr, $value, 1);                           # wenn man den aktuellen Timestamp setzt (Normalfall)
     setReadingsVal($hash,$resr,$value,$pmts);                                  # !!! Spezialfall !!! abweichenden Timestamp setzen
}
return;
}
ESXi@NUC+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

Kai-Alfonso

Noch mal Moin  8)

Vielen Dank für deine Geduld und Mühe - ich setz mich gleich mal hin und teste das. Erstmal ein Kaffee  8)
Raspi2|nanoCul433|nanoCul868|CCU2
Energie-USBZähler|homebrew HM Devices
DBLog|DBRep|Homematic|Baumarktsteckdosen
Hue|Webcams mit DS-Station (Synology)|Bewegungsmelder|Rollladen|Schalter (IT|HM)

Kai-Alfonso

So, hat einwandfrei geklappt :-) Vielen Dank noch mal

Wenn ich das richtig verstehe, dann wertet er alle DB-Einträge aus, wenn ich nicht mit timeolderThan/timeDiffToNow etc die Selection einschränke, oder?

So wie ich es jetzt gemacht habe = historisch maxValue

mit attr timestamp_begin current_year_begin  kann ich dann ja das maxValue für das laufende Jahr bestimmen, oder? timestamp_end muss ich nicht zwingend setzen? Er nimm dann automatisch das aktuelle Datum?
Raspi2|nanoCul433|nanoCul868|CCU2
Energie-USBZähler|homebrew HM Devices
DBLog|DBRep|Homematic|Baumarktsteckdosen
Hue|Webcams mit DS-Station (Synology)|Bewegungsmelder|Rollladen|Schalter (IT|HM)