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
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
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)
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
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?
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
Zitat von: DS_Starter am 01 Oktober 2019, 13:02:52
Heute Abend kann ich ein konkretes Beispiel liefern.
Lg
ich freue mich drauf 8)
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
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
Smartvisu sagt mir was, aber ich habe kaum Zeit um mich um eigene Grafik zu kümmern. ;)
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?
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. ;)
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;
}
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)
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?
Moin Kai,
du hast alle deine Fragen schon korrekt selbst beantwortet. :)
Alles ist so wie du sagst.
Super :D
Zitat von: DS_Starter am 02 Oktober 2019, 08:01:58
Moin Kai,
du hast alle deine Fragen schon korrekt selbst beantwortet. :)
Alles ist so wie du sagst.
Super :D
8) Die Doku ist ja auch recht gut - wenn ich mal was nicht verstehe, liegt es nur an mir und nicht am fehlender/schlechter Doku
Aber ich habe (mal wieder) eine Bonusfrage 8)
Bekommt die Prozedur mit, welchen set Befehl (set maxValue/minValue/averageValue) ich zum Aufruf des userExitFn genutzt habe?
Weil dann bräuchte ich nur ein DbRep Device, um zum Beispiel historisch die maxValue und minValue in ein Reading schreiben zu lassen.
tl;dr
my $resr = "maxTemp"; # wenn set maxValue
my $resr = "minTemp"; # wenn set minValue
Dann bräuchte ich nur eine Prozedur/ein DbRep Device für die historischen min/max Daten anstatt jeweils eine Prozedur/ein DbRep Device für jeweils min/max
ZitatBekommt die Prozedur mit, welchen set Befehl (set maxValue/minValue/averageValue) ich zum Aufruf des userExitFn genutzt habe?
Ja, das Reading im DbRep hat hinten dann MIN, AVG oder sowas. Muss man dann in der Sub berücksichtigen.
Vielleicht noch eine Ergänzung.
Wenn du mit aggregation=X die Auswertung über mehrere Perioden deines Auswertungszeitraumes durchführst, werden ja mehrere Readings im DbRep erstellt, für jede Periode eins. Also 12 Readings für eine Jahresauswertung mit monatlichen Perioden.
Diese Readings kannst du auch mit der Prozedur auswerten, musst nur den Regex und die Logik anpassen damit das auch sauber auseinandergenommen wird um die Ergebnisreadings in deinem Zieldevice zu erstellen.
Grüße,
Heiko
Zitat von: DS_Starter am 02 Oktober 2019, 08:32:24
Ja, das Reading im DbRep hat hinten dann MIN, AVG oder sowas. Muss man dann in der Sub berücksichtigen.
Vielleicht noch eine Ergänzung.
Wenn du mit aggregation=X die Auswertung über mehrere Perioden deines Auswertungszeitraumes durchführst, werden ja mehrere Readings im DbRep erstellt, für jede Periode eins. Also 12 Readings für eine Jahresauswertung mit monatlichen Perioden.
Diese Readings kannst du auch mit der Prozedur auswerten, musst nur den Regex und die Logik anpassen damit das auch sauber auseinandergenommen wird um die Ergebnisreadings in deinem Zieldevice zu erstellen.
Grüße,
Heiko
Hey - jetzt habe ich verstanden, das die userExitFn auf das Reading zugreift und ich darauf dann den Regex mache. Das war mir vorher nicht so klar. aggregation hatte ich noch gar nicht auf dem Schirm, ist aber eine tolle Sache. Jetzt muss ich mir nur noch klar werden, was ich genau will. 8)
Hab grade gesehen: aggregation = month liefert mir auch solche Werte:
2019-10-01 08:39:10 .associatedWith Umgebungssensor_Fassade_SuedSeite
2019-10-02 08:57:10 2014-11-08__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2014-11 0.0000
2019-10-02 08:57:10 2014-12-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2014-12 0.0000
2019-10-02 08:57:10 2015-01-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2015-01 0.0000
2019-10-02 08:57:10 2015-02-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2015-02 0.0000
2019-10-02 08:57:10 2015-03-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2015-03 0.0000
2019-10-02 08:57:10 2015-04-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2015-04 0.0000
2019-10-02 08:57:10 2015-05-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2015-05 0.0000
2019-10-02 08:57:10 2015-06-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2015-06 0.0000
2019-10-02 08:57:10 2015-07-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2015-07 0.0000
2019-10-02 08:57:10 2015-08-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2015-08 0.0000
2019-10-02 08:57:10 2015-09-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2015-09 0.0000
2019-10-02 08:57:10 2015-10-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2015-10 0.0000
2019-10-02 08:57:10 2015-11-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2015-11 0.0000
2019-10-02 08:57:10 2015-12-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2015-12 0.0000
2019-10-02 08:57:10 2016-01-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2016-01 0.0000
2019-10-02 08:57:10 2016-02-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2016-02 0.0000
2019-10-02 08:57:10 2016-03-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2016-03 0.0000
2019-10-02 08:57:10 2016-04-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2016-04 0.0000
2019-10-02 08:57:10 2016-05-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2016-05 0.0000
2019-10-02 08:57:10 2016-06-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2016-06 0.0000
2019-10-02 08:57:10 2016-07-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2016-07 0.0000
2019-10-02 08:57:10 2016-08-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2016-08 0.0000
2019-10-02 08:57:10 2016-09-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2016-09 0.0000
2019-10-02 08:57:10 2016-10-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2016-10 0.0000
2019-10-02 08:57:10 2016-11-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2016-11 0.0000
2019-10-02 08:57:10 2016-12-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2016-12 0.0000
2019-10-02 08:57:10 2017-01-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2017-01 0.0000
2019-10-02 08:57:10 2017-02-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2017-02 0.0000
2019-10-02 08:57:10 2017-03-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2017-03 0.0000
2019-10-02 08:57:10 2017-04-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2017-04 0.0000
2019-10-02 08:57:10 2017-05-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2017-05 0.0000
2019-10-02 08:57:10 2017-06-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2017-06 0.0000
2019-10-02 08:57:10 2017-07-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2017-07 0.0000
2019-10-02 08:57:10 2017-08-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2017-08 0.0000
2019-10-02 08:57:10 2017-09-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2017-09 0.0000
2019-10-02 08:57:10 2017-10-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2017-10 0.0000
2019-10-02 08:57:10 2017-11-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2017-11 0.0000
2019-10-02 08:57:10 2017-12-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2017-12 0.0000
2019-10-02 08:57:10 2018-01-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2018-01 0.0000
2019-10-02 08:57:10 2018-02-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2018-02 0.0000
2019-10-02 08:57:10 2018-03-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2018-03 0.0000
2019-10-02 08:57:10 2018-04-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2018-04 0.0000
2019-10-02 08:57:10 2018-05-01__Umgebungssensor_Fassade_SuedSeite__temperature__MAX__2018-05 0.0000
Also Monatswerte vom November 2014 bis Mai 2018 mit 0 Werten - in den Monaten gibt es keine DB Einträge mit dem Device (das kam erst im Juni 2018). Allerdings sind in der DB Einträge am 2014 von anderen Devices...was vielleicht erklärt, wieso er auf 2014 kommt. Kann man das irgendwie unterdrücken?
ZitatAllerdings sind in der DB Einträge am 2014 von anderen Devices...was vielleicht erklärt, wieso er auf 2014 kommt. Kann man das irgendwie unterdrücken?
Hmm, eigentlich nur über die time* Attribute momentan. Also erst mit der Auswertung beginnen wenn es die DS gibt.
Ich hab das jetzt mal so deine Prozedur abgewandelt, damit ich für min/max nicht 2 Dbrep Devices brauche. Geht bestimmt eleganter/besser, funktioniert aber so erstmal 8)
############################################################################################################
## 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 TempHist {
my ($name,$reading,$value) = @_;
my $resr;
if($reading =~ /^.*__MAX.*$/) {
$resr = "MaxTempHist";
}
if($reading =~ /^.*__MIN.*$/) {
$resr = "MinTempHist";
}
if($reading =~ /^.*__temperature.*$/) { # 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;
}
Das Ergebnis zählt. Prima :)
Hi Heiko,
vielleicht könntest Du mir noch mal kurz behilflich sein? 8) :o :o
Ich habe das Perl-Script ein wenig angepasst:
sub TempStatistik {
my ($name,$reading,$value) = @_;
my $resr;
$resr = $reading =~ /(?<=__)(.*)(?=__)/;
if($reading =~ /^.*Temp.*$/) { # 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;
}
Hintergrund ist, das ich dann nicht für die verschiedenen Statistiken keine unterschiedlichen Subs und DBRep Devices brauche, weil ich die entsprechenden Attribute vor der Erstellung der Statistiken entsprechend ändere.
Ein typisches Reading sieht wie folgt aus
2019-10-31_07-13-39__MinTempDay__no_aggregation
MinTempDay ist mit readingNameMap gemappt und wird je nach Art der Auswertung geändert (in zb. MaxTempDay etc.)
Mit $resr = $reading =~ /(?<=__)(.*)(?=__)/;
sollte ich ja eigentlich aus dem Reading den Mittelpart selektieren und später dann als Zielreading nutzen können.
Leider funktioniert das nicht - es kommen auch keine Fehler oder ähnliches. Wo habe ich da einen (Denk-) Fehler gemacht?
Das List des DBRep-Devices
Internals:
.FhemMetaInternals 1
DATABASE fhem
DEF DBLog
FUUID 5d97397e-f33f-ce3b-b1d6-3954147b01fee5e9
FVERSION 93_DbRep.pm:v8.28.2-s20379/2019-10-18
LASTCMD minValue display
MODEL Client
NAME DbRep.Statistik
NOTIFYDEV global,DbRep.TempDay_SuedSeite
NR 237
NTFY_ORDER 50-DbRep.TempDay_SuedSeite
ROLE Client
STATE done
TYPE DbRep
UTF8 0
.attraggr:
.attreour:
state
.attrminint:
HELPER:
DBLOGDEVICE DBLog
IDRETRIES 3
MINTS 2014-11-08 09:27:00
PACKAGE main
SQLHIST
UEFN_REGEXP attr DbRep.Statistik readingNameMap MinTempDay
USEREXITFN TempStatistik
VERSION 8.28.2
CV:
aggregation no
aggsec 1
destr 2019-10-31
dsstr 2019-10-31
epoch_seconds_end 1572521183
mestr 10
msstr 10
testr 12:26:23
tsstr 00:00:00
wdadd 345600
yestr 2019
ysstr 2019
DBREPCOL:
COLSET 1
DEVICE 64
EVENT 512
READING 64
TYPE 64
UNIT 32
VALUE 128
OLDREADINGS:
READINGS:
2019-10-31 12:26:23 .associatedWith Umgebungssensor_Fassade_SuedSeite
2019-10-31 12:26:24 2019-10-31_07-13-39__MinTempDay__no_aggregation -3.0000
2019-10-31 12:26:24 background_processing_time 0.0833
2019-10-31 12:26:24 sql_processing_time 0.0411
2019-10-31 12:26:24 state done
Attributes:
allowDeletion 1
device Umgebungssensor_Fassade_SuedSeite
event-on-update-reading state
reading temperature
readingNameMap MinTempDay
room Datenbank
showproctime 1
timestamp_begin current_day_begin
userExitFn TempStatistik
BonusFrage: Habe mit Log versucht, mir die Variable ins Log schreiben zu lassen, aber selbst mit
Log 1, "Test";
erscheint nix im Log (ich nehm an Fhemlog?)
wo ist denn da der Fehler?
10000 Dank :-)
Hallo Kai,
bin zur Zeit im Kurzurlaub und kann dich gerade nur rudimentär unterstützen.
Dieser Teil
$resr = $reading =~ /(?<=__)(.*)(?=__)/;
ist so nicht richtig. So könnte es funktionieren
$reading =~ /^.*__(.*)__.*$/;
$resr = $1;
...
Ich empfehle dir den Regextester https://regex101.com/ um deine Regex vorher zu testen und durchzuspielen.
Damit kommt man sehr gut zum Ziel.
Montag kann ich wieder mehr unterstützen.
Grüße,
Heiko
Zitat von: DS_Starter am 31 Oktober 2019, 19:25:58
Hallo Kai,
bin zur Zeit im Kurzurlaub und kann dich gerade nur rudimentär unterstützen.
Dieser Teil
$resr = $reading =~ /(?<=__)(.*)(?=__)/;
ist so nicht richtig. So könnte es funktionieren
$reading =~ /^.*__(.*)__.*$/;
$resr = $1;
...
Ich empfehle dir den Regextester https://regex101.com/ um deine Regex vorher zu testen und durchzuspielen.
Damit kommt man sehr gut zum Ziel.
Montag kann ich wieder mehr unterstützen.
Grüße,
Heiko
Hey Heiko,
kein Streß - eilt nicht. Regex teste ich generell erstmal gegen regex101 oder ähnliche Seiten, der müsste eigentlich passen.
Leider geht es durch deine Änderung auch nicht - schauen wir mal zusammen nächste Woche drauf. Schönen Kurzurlaub 8)
Danke :)
Habe doch etwas Zeit gefunden und auch ausprobiert. So funktioniert es
sub TempStatistik {
my ($name,$reading,$value) = @_;
my $resr;
if($reading =~ /^.*Temp.*$/) { # es ist das Ergebnis aus Ursprungdevice / ausgewertetes Reading / MAX
my ($ts,$read,undef) = split("__",$reading,3); # Extraktion Timestamp, read = Reading Name zum Erstellen, Extract aus readingNameMap
$ts =~ /^(\d+)-(\d+)-(\d+)_(\d+)-(\d+)-(\d+)$/; # Aufteilung Timestamp
my $pmts = "$1-$2-$3 $4:$5:$6"; # Neuzusammenstellung des Timestamp
my $hash = $defs{$name}; # hash des Zieldevices
# readingsSingleUpdate($hash, $resr, $value, 1); # wenn man den aktuellen Timestamp setzt (Normalfall)
setReadingsVal($hash,$read,$value,$pmts); # !!! Spezialfall !!! abweichenden Timestamp setzen
}
return;
}
Das Reading wird im ausführenden DbRep Device erstellt. Ansonsten könntest du $name auch auf ein beliebiges Device setzen.
Grüße,
Heiko
Zitat von: DS_Starter am 01 November 2019, 10:21:18
Danke :)
Habe doch etwas Zeit gefunden und auch ausprobiert. So funktioniert es
sub TempStatistik {
my ($name,$reading,$value) = @_;
my $resr;
if($reading =~ /^.*Temp.*$/) { # es ist das Ergebnis aus Ursprungdevice / ausgewertetes Reading / MAX
my ($ts,$read,undef) = split("__",$reading,3); # Extraktion Timestamp, read = Reading Name zum Erstellen, Extract aus readingNameMap
$ts =~ /^(\d+)-(\d+)-(\d+)_(\d+)-(\d+)-(\d+)$/; # Aufteilung Timestamp
my $pmts = "$1-$2-$3 $4:$5:$6"; # Neuzusammenstellung des Timestamp
my $hash = $defs{$name}; # hash des Zieldevices
# readingsSingleUpdate($hash, $resr, $value, 1); # wenn man den aktuellen Timestamp setzt (Normalfall)
setReadingsVal($hash,$read,$value,$pmts); # !!! Spezialfall !!! abweichenden Timestamp setzen
}
return;
}
Das Reading wird im ausführenden DbRep Device erstellt. Ansonsten könntest du $name auch auf ein beliebiges Device setzen.
Grüße,
Heiko
Cool - vielen Dank. Ich würde gerne noch das $name auf das Device zeigt was in dem Reading device in dem DbRep Device zeigt 8) 8) Vielleicht könntest mir noch mal kurz unter die Arme greifen? ;)
Gerne ...
Du meintest sicherlich nicht Reading sondern Attribut device.
So sollte es funktionieren:
sub TempStatistik {
my ($name,$reading,$value) = @_;
my $resr;
if($reading =~ /^.*Temp.*$/) { # es ist das Ergebnis aus Ursprungdevice / ausgewertetes Reading / MAX
my ($ts,$read,undef) = split("__",$reading,3); # Extraktion Timestamp, read = Reading Name zum Erstellen, Extract aus readingNameMap
$ts =~ /^(\d+)-(\d+)-(\d+)_(\d+)-(\d+)-(\d+)$/; # Aufteilung Timestamp
my $pmts = "$1-$2-$3 $4:$5:$6"; # Neuzusammenstellung des Timestamp
my $dest = AttrVal($name, "device", ""); # device Attribut dbrep auslesen
my $hash = $defs{$dest}; # hash des Zieldevices
# readingsSingleUpdate($hash, $resr, $value, 1); # wenn man den aktuellen Timestamp setzt (Normalfall)
setReadingsVal($hash,$read,$value,$pmts); # !!! Spezialfall !!! abweichenden Timestamp setzen
}
return;
}
Du kannst dir die Syntax von AttrVal im Wiki anschauen https://wiki.fhem.de/wiki/DevelopmentModuleAPI#AttrVal
Probier mal,
lg
Zitat von: DS_Starter am 01 November 2019, 19:30:19
Gerne ...
Du meintest sicherlich nicht Reading sondern Attribut device.
So sollte es funktionieren:
sub TempStatistik {
my ($name,$reading,$value) = @_;
my $resr;
if($reading =~ /^.*Temp.*$/) { # es ist das Ergebnis aus Ursprungdevice / ausgewertetes Reading / MAX
my ($ts,$read,undef) = split("__",$reading,3); # Extraktion Timestamp, read = Reading Name zum Erstellen, Extract aus readingNameMap
$ts =~ /^(\d+)-(\d+)-(\d+)_(\d+)-(\d+)-(\d+)$/; # Aufteilung Timestamp
my $pmts = "$1-$2-$3 $4:$5:$6"; # Neuzusammenstellung des Timestamp
my $dest = AttrVal($name, "device", ""); # device Attribut dbrep auslesen
my $hash = $defs{$dest}; # hash des Zieldevices
# readingsSingleUpdate($hash, $resr, $value, 1); # wenn man den aktuellen Timestamp setzt (Normalfall)
setReadingsVal($hash,$read,$value,$pmts); # !!! Spezialfall !!! abweichenden Timestamp setzen
}
return;
}
Du kannst dir die Syntax von AttrVal im Wiki anschauen https://wiki.fhem.de/wiki/DevelopmentModuleAPI#AttrVal
Probier mal,
lg
Super, vielen Dank. Das hat geklappt. AttrVal kenne ich, bei hapert es eher mit der genauen syntaktischen Umsetzung. Warum zum Beispiel brauche ich ein Hash des Ziel-Device und kann nicht $dest nehmen?
ZitatWarum zum Beispiel brauche ich ein Hash des Ziel-Device und kann nicht $dest nehmen?
Es kommt darauf an welche Variablen der nachfolgenden Funktion, hier ist es setReadingsVal, übergeben werden müssen.
setReadingsVal verlangt einen Hash des Zieldevices. Bei manch anderen Funktionen kann man den $name oder sogar entweder den Hash oder den Namen übergeben. Es kommt darauf an was der Programmierer der Funktion implementiert hat.
Da hilft nur ein Blick in die Doku oder direkt in die fhem.pl (bzw. wo die benutzte Funktion lokalisiert ist)
Eigentlich müsste man auch noch prüfen, ob es einen Hash des übergebenen Devices gibt, also ob das Device überhaupt existiert. So könnte man ergänzen:
.....
my $hash = $defs{$dest}; # hash des Zieldevices
# readingsSingleUpdate($hash, $resr, $value, 1); # wenn man den aktuellen Timestamp setzt (Normalfall)
return if(!$hash); # Absprung falls kein Hash vorhanden
setReadingsVal($hash,$read,$value,$pmts); # !!! Spezialfall !!! abweichenden Timestamp setzen
.....
oder hier noch einen entsprechenden Logeintrag vornehmen.
ah ok,
jetzt verstehe ich das - weil das war mir nicht klar, weil ich mal das eine, mal das andere gesehen habe und ich beim ausprobieren von Sachen oft nicht zum Ergebnis gekommen bin, weil die Beispiele für meinen Anwendungsfall falsch waren, die ich mir rausgesucht habe.
Noch ne kurze Frage:
Ich erstelle mit zB. set maxValue Display ein Reading (wie vorher besprochen) mit dem Timestamp in dem Device laut Attribut Device. Dieses Reading will ich in die DB schreiben. DBincludeMode ist aktiviert, das Reading steht im Attribut DbLogInclude und bei event-on-change/update-reading ist es auch drin. DB Einträge werden aber nicht erzeugt.
Moin Kai,
Zitat
Ich erstelle mit zB. set maxValue Display ein Reading (wie vorher besprochen) mit dem Timestamp in dem Device laut Attribut Device. Dieses Reading will ich in die DB schreiben. DBincludeMode ist aktiviert, das Reading steht im Attribut DbLogInclude und bei event-on-change/update-reading ist es auch drin. DB Einträge werden aber nicht erzeugt.
Naja, wir verwenden hier einen "Trick" und verwenden die Funktion setReadingsVal aus fhem.pl weil du den bestimmten Timestamp haben möchtest (Erinnerung !!! Sonderfall!!! ). Diese Funktion wird keinen Event erzeugen. Kontrollier mal bitte im Eventmonitor. Ich gehe davon aus, dass kein Event generiert wird.
Wenn das so ist, kann natürlich kein DB-Eintrag erzeugt werden.
Aber auch dafür gibt es eine Lösung. Man kann sich einen Event in der subroutine erzeugen. Schau dir mal den Befehl "trigger" an. Den könntest du einbauen. Wenn du nicht klarkommst, können wir heute Abend nochmal gemeinsam schauen.
EDIT: Du kannst natürlich auch direkt in die DB schreiben ohne Event. Siehe "set ... insert" im DbRep.
LG,
Heiko
Zitat von: DS_Starter am 04 November 2019, 07:56:45
Moin Kai,
Naja, wir verwenden hier einen "Trick" und verwenden die Funktion setReadingsVal aus fhem.pl weil du den bestimmten Timestamp haben möchtest (Erinnerung !!! Sonderfall!!! ). Diese Funktion wird keinen Event erzeugen. Kontrollier mal bitte im Eventmonitor. Ich gehe davon aus, dass kein Event generiert wird.
Wenn das so ist, kann natürlich kein DB-Eintrag erzeugt werden.
Aber auch dafür gibt es eine Lösung. Man kann sich einen Event in der subroutine erzeugen. Schau dir mal den Befehl "trigger" an. Den könntest du einbauen. Wenn du nicht klarkommst, können wir heute Abend nochmal gemeinsam schauen.
EDIT: Du kannst natürlich auch direkt in die DB schreiben ohne Event. Siehe "set ... insert" im DbRep.
LG,
Heiko
Hey 8)
Trigger kenn ich - ich versuche mich erst selber an einer Lösung. Auch wenn es nicht immer so aussieht, ich versuche immer erst selbst mein Glück, auch wenn ich nicht alles verstehe und wenn ich nicht weiterkomme, dann frage ich 8)
Du hattest recht - es wurden keine Events erzeugt.
Dan habe ich die untere Zeile so ergänzt:
[...]
# readingsSingleUpdate($hash, $resr, $value, 1); # wenn man den aktuellen Timestamp setzt (Normalfall)
setReadingsVal($hash,$read,$value,$pmts); # !!! Spezialfall !!! abweichenden Timestamp setzen
fhem ("trigger $dest $read:$value");
was dann beim Ausführen ein Event erzeugt:
2019-11-04 11:12:12.844 CUL_HM Umgebungssensor_Fassade_SuedSeite MinTempDay:9.4000
komischerweise wird aber trotzdem nix in die DB geschrieben.
Also habe ich das mal mit set insert probiert. Da ja der Timestamp ein wenig anders formatiert sein muss laut commandref (Datum,Uhrzeit), habe ich erstmal das in eine neue Variable geschrieben:
$ts =~ /^(\d+)-(\d+)-(\d+)_(\d+)-(\d+)-(\d+)$/; # Aufteilung Timestamp
my $pmts = "$1-$2-$3 $4:$5:$6"; # Neuzusammenstellung des Timestamp
my $dbts = "$1-$2-$3,$4:$5:$6";
und dann
fhem ("set DbRep.Statistik insert $dbts,$value");
Kam aber irgendwie ein Fehler:
2019.11.04 11:31:05.902 3: DbRep DbRep.Statistik - WARNING - old process 7101 will be killed now to start a new BlockingCall
2019.11.04 11:31:05.957 1: readingsUpdate(DbRep.Statistik,background_processing_time,0.0685) missed to call readingsBeginUpdate first.
2019.11.04 11:31:05.960 1: stacktrace:
2019.11.04 11:31:05.962 1: main::readingsBulkUpdate called by ./FHEM/93_DbRep.pm (9478)
2019.11.04 11:31:05.963 1: main::ReadingsBulkUpdateTimeState called by ./FHEM/93_DbRep.pm (3470)
2019.11.04 11:31:05.964 1: main::minval_ParseDone called by (eval 2071803) (1)
2019.11.04 11:31:05.965 1: (eval) called by fhem.pl (1137)
2019.11.04 11:31:05.967 1: main::AnalyzePerlCommand called by fhem.pl (1162)
2019.11.04 11:31:05.968 1: main::AnalyzeCommand called by fhem.pl (1091)
2019.11.04 11:31:05.969 1: main::AnalyzeCommandChain called by ./FHEM/98_telnet.pm (255)
2019.11.04 11:31:05.970 1: main::telnet_Read called by fhem.pl (3750)
2019.11.04 11:31:05.972 1: main::CallFn called by fhem.pl (750)
2019.11.04 11:31:05.976 1: readingsUpdate(DbRep.Statistik,sql_processing_time,0.0298) missed to call readingsBeginUpdate first.
2019.11.04 11:31:05.977 1: stacktrace:
2019.11.04 11:31:05.979 1: main::readingsBulkUpdate called by ./FHEM/93_DbRep.pm (9480)
2019.11.04 11:31:05.980 1: main::ReadingsBulkUpdateTimeState called by ./FHEM/93_DbRep.pm (3470)
2019.11.04 11:31:05.981 1: main::minval_ParseDone called by (eval 2071803) (1)
2019.11.04 11:31:05.982 1: (eval) called by fhem.pl (1137)
2019.11.04 11:31:05.983 1: main::AnalyzePerlCommand called by fhem.pl (1162)
2019.11.04 11:31:05.984 1: main::AnalyzeCommand called by fhem.pl (1091)
2019.11.04 11:31:05.985 1: main::AnalyzeCommandChain called by ./FHEM/98_telnet.pm (255)
2019.11.04 11:31:05.986 1: main::telnet_Read called by fhem.pl (3750)
2019.11.04 11:31:05.987 1: main::CallFn called by fhem.pl (750)
2019.11.04 11:31:05.990 1: readingsUpdate(DbRep.Statistik,state,done) missed to call readingsBeginUpdate first.
2019.11.04 11:31:05.991 1: stacktrace:
2019.11.04 11:31:05.991 1: main::readingsBulkUpdate called by ./FHEM/93_DbRep.pm (9484)
2019.11.04 11:31:05.992 1: main::ReadingsBulkUpdateTimeState called by ./FHEM/93_DbRep.pm (3470)
2019.11.04 11:31:05.993 1: main::minval_ParseDone called by (eval 2071803) (1)
2019.11.04 11:31:05.993 1: (eval) called by fhem.pl (1137)
2019.11.04 11:31:05.994 1: main::AnalyzePerlCommand called by fhem.pl (1162)
2019.11.04 11:31:05.994 1: main::AnalyzeCommand called by fhem.pl (1091)
2019.11.04 11:31:05.995 1: main::AnalyzeCommandChain called by ./FHEM/98_telnet.pm (255)
2019.11.04 11:31:05.996 1: main::telnet_Read called by fhem.pl (3750)
2019.11.04 11:31:05.996 1: main::CallFn called by fhem.pl (750)
Nabend Kai,
Zitat
dann beim Ausführen ein Event erzeugt:
2019-11-04 11:12:12.844 CUL_HM Umgebungssensor_Fassade_SuedSeite MinTempDay:9.4000
komischerweise wird aber trotzdem nix in die DB geschrieben.
Hier müssen wir schauen ob im Device Umgebungssensor_Fassade_SuedSeite das Logging für das Reading MinTempDay eingeschaltet ist, d.h. DbLogInclude bzw. DbLogExclude entsprechend gesetzt je nachdem wie du DbLog eingerichtet hast.
Wenn du den Standard nutzt, schau mal ob der Regex von DbLog richtig gesetzt ist.
Zitat
und dann
fhem ("set DbRep.Statistik insert $dbts,$value");
Kam aber irgendwie ein Fehler:
........
Ja, mein Fehler. Habe nicht bedacht, dass man mit dem Set-Kommando direkt den zuvor laufenden Prozess abschießt. Ist insofern kein Fehler, works as designed. Aber man muss dafür ein anderes DbRep-Device nutzen.
In diesem Fall würde ich auf den set addCacheLine im DbLog umschwenken, sofern du DbLog im asynchronen Modus betreibst.
Je nachdem was du bevorzugst gucken wir uns erstmal einen Lösungsweg an.
Zitat von: DS_Starter am 04 November 2019, 18:45:13
Nabend Kai,
Hier müssen wir schauen ob im Device Umgebungssensor_Fassade_SuedSeite das Logging für das Reading MinTempDay eingeschaltet ist, d.h. DbLogInclude bzw. DbLogExclude entsprechend gesetzt je nachdem wie du DbLog eingerichtet hast.
Wenn du den Standard nutzt, schau mal ob der Regex von DbLog richtig gesetzt ist.
Ja, mein Fehler. Habe nicht bedacht, dass man mit dem Set-Kommando direkt den zuvor laufenden Prozess abschießt. Ist insofern kein Fehler, works as designed. Aber man muss dafür ein anderes DbRep-Device nutzen.
In diesem Fall würde ich auf den set addCacheLine im DbLog umschwenken, sofern du DbLog im asynchronen Modus betreibst.
Je nachdem was du bevorzugst gucken wir uns erstmal einen Lösungsweg an.
Also, ich habe DbLogselectionMode = include eingestellt und im Umgebungssensor_Fassade_SuedSeite auch die ensprechenden Readings hinterlegt. Brightness etc werden auch geloggt. Hier mal das List des Devices
Internals:
.lastTimeActivity 1572874924.92943
.lastTimebatVoltage 1572890307.78151
.lastTimebattery 1572890432.31943
.lastTimebrightness 1572890307.78151
.lastTimecustomData 1572890432.31943
.lastTimedigitalInput 1572890432.31943
.lastTimehumidity 1572890307.78151
.lastTimepressure 1572890181.47528
.lastTimestate 1572890432.31943
.lastTimetemperature 1572890432.31943
DEF CC5B90
FUUID 5c509114-f33f-ce3b-592a-686607562a31c0b5
HMUART_EG_MSGCNT 124
HMUART_EG_RAWMSG 0500004F0A8470CC5B90000000004F26755400000005000D0E0000
HMUART_EG_RSSI -79
HMUART_EG_TIME 2019-11-04 19:00:32
IODev HMUART_EG
LASTInputDev HMUART_EG
MSGCNT 124
NAME Umgebungssensor_Fassade_SuedSeite
NOTIFYDEV global
NR 168
NTFY_ORDER 50-Umgebungssensor_Fassade_SuedSeite
STATE T: 7.9 P: 984.5 H: 84 B: 0.05 I: 0 X: 0
TYPE CUL_HM
chanNo 01
lastMsg No:0A - t:70 s:CC5B90 d:000000 004F26755400000005000D0E0000
protCmdDel 2
protLastRcv 2019-11-04 19:00:32
protRcv 124 last_at:2019-11-04 19:00:32
protResnd 3 last_at:2019-11-04 16:46:44
protResndFail 1 last_at:2019-11-04 17:28:35
protSnd 4 last_at:2019-11-04 17:28:31
protState CMDs_done_Errors:1
rssi_at_HMUART_EG cnt:124 min:-82 max:-75 avg:-77.61 lst:-79
.attraggr:
.attreocr:
pressure
humidity
temperature
brightness
batVoltage
MinTempDay
MaxTempDay
.attrminint:
.*:300
batVoltage:600
Helper:
DBLOG:
batVoltage:
DBLog:
TIME 1572890307.79477
VALUE 3.34
brightness:
DBLog:
TIME 1572890307.79477
VALUE 0.05
humidity:
DBLog:
TIME 1572890307.79477
VALUE 84
pressure:
DBLog:
TIME 1572890181.48843
VALUE 984.5
temperature:
DBLog:
TIME 1572890432.33514
VALUE 7.9
READINGS:
2019-10-23 18:01:18 .D-devInfo 010101
2019-10-23 18:01:18 .D-stc 70
2019-01-30 15:49:44 .R-altitude 0 m
2019-01-30 15:49:44 .R-ledMode undef lit:1
2019-01-30 15:49:44 .R-lowBatLimit 2.1 V
2019-01-30 15:49:44 .R-transmDevTryMax 6
2019-10-23 18:00:00 .R-updateIntervall 120 s
2019-10-23 18:01:10 .peerListRDate 2019-10-23 18:01:10
2019-11-04 19:00:32 .protLastRcv 2019-11-04 19:00:32
2019-11-04 14:42:04 Activity alive
2019-10-22 16:21:56 Batteriewechsel 22.10.2019
2019-10-23 17:59:42 CommandAccepted yes
2019-10-23 18:01:18 D-firmware 1.3
2019-10-23 18:01:18 D-serialNr PZK2993649
2019-11-04 11:02:10 MaxTempDay 17.8000
2019-07-25 16:38:16 MaxTempHist 76.9000
2019-07-25 16:38:16 MaxTempYear 76.9000
2019-11-04 03:51:15 MinTempDay 9.4000
2019-02-15 04:46:01 MinTempHist -3.9000
2019-02-15 04:46:01 MinTempYear -3.9000
2019-10-23 18:01:09 PairedTo 0x000000
2019-10-23 18:00:00 R-pairCentral 0x000000
2019-10-23 18:01:09 RegL_00. 00:00 05:40 0A:00 0B:00 0C:00 12:15 14:06 20:00 21:78 22:00 23:00
2019-11-04 19:00:32 batVoltage 3.34
2019-11-04 19:00:32 battery ok
2019-11-04 19:00:32 brightness 0.05
2019-11-04 19:00:32 customData 0
2019-11-04 19:00:32 digitalInput 0
2019-11-04 19:00:32 humidity 84
2019-10-23 17:59:57 powerOn 2019-10-23 17:59:57
2019-11-04 19:00:32 pressure 984.5
2019-10-23 18:01:16 recentStateType info
2019-11-04 19:00:32 state T: 7.9 P: 984.5 H: 84 B: 0.05 I: 0 X: 0
2019-11-04 19:00:32 temperature 7.9
helper:
HM_CMDNR 10
mId F103
peerFriend
peerOpt p:UniSensor1
regLst 0
rxType 156
supp_Pair_Rep 0
expert:
def 1
det 0
raw 1
tpl 0
io:
newChn +CC5B90,00,00,00
nextSend 1572890432.39607
prefIO
rxt 2
vccu VCCU
p:
CC5B90
00
00
00
mRssi:
mNo 0A
io:
HMUART_EG:
-77
-77
HMUART_OG:
prt:
bErr 0
sProc 0
q:
qReqConf
qReqStat
role:
chn 1
dev 1
rssi:
at_HMUART_EG:
avg -77.6129032258065
cnt 124
lst -79
max -75
min -82
shadowReg:
tmpl:
Attributes:
.mId F103
DbLogInclude (pressure|humidity|temperature|brightness|batVoltage|MinTempDay|MaxTempDay)
IOgrp VCCU
actCycle 000:60
actStatus alive
alexaName Terrasse
alias Umgebungssensor Fassade Süd-Seite
autoReadReg 4_reqStatus
event-min-interval .*:300,batVoltage:600
event-on-change-reading pressure,humidity,temperature,brightness,batVoltage,MinTempDay,MaxTempDay
expert 2_raw
firmware 1.3
group Umgebungssensor
icon weather_light_meter
model HB-UNI-Sensor1
peerIDs 00000000,
room HomeMatic
serialNr PZK2993649
subType UniSensor1
Hmm, auf den ersten Blick kann ich nichts falsches feststellen. Das Attr DbLogInclude kannst du aber ganz einfach als KOmma getrennte Liste schreiben, ist aber gerade nebensächlich.
Dann müssen wir im DbLog gucken ... dort verbose 4 einschalten und mal bitte den Logauszug posten wenn solch ein Event erzeugt wurde.
Beispiel:
2019.11.04 19:11:22.440 4: DbLog LogDB1 -> ################################################################
2019.11.04 19:11:22.441 4: DbLog LogDB1 -> ### start of new Logcycle ###
2019.11.04 19:11:22.441 4: DbLog LogDB1 -> ################################################################
2019.11.04 19:11:22.442 4: DbLog LogDB1 -> number of events received: 13 for device: SMA_Energymeter
2019.11.04 19:11:22.442 4: DbLog LogDB1 -> check Device: SMA_Energymeter , Event: Bezug_WirkP_Zaehler_Diff: 0.0108
2019.11.04 19:11:22.445 4: DbLog LogDB1 -> added event - Timestamp: 2019-11-04 19:11:22, Device: SMA_Energymeter, Type: SMAEM, Event: Bezug_WirkP_Zaehler_Diff: 0.0108, Reading: Bezug_WirkP_Zaehler_Diff, Value: 0.0108, Unit:
2019.11.04 19:11:22.446 4: DbLog LogDB1 -> check Device: SMA_Energymeter , Event: Bezug_WirkP_Kosten_Diff: 0.0029
2019.11.04 19:11:22.448 4: DbLog LogDB1 -> added event - Timestamp: 2019-11-04 19:11:22, Device: SMA_Energymeter, Type: SMAEM, Event: Bezug_WirkP_Kosten_Diff: 0.0029, Reading: Bezug_WirkP_Kosten_Diff, Value: 0.0029, Unit:
2019.11.04 19:11:22.449 4: DbLog LogDB1 -> check Device: SMA_Energymeter , Event: Einspeisung_WirkP_Zaehler_Diff: 0
2019.11.04 19:11:22.452 4: DbLog LogDB1 -> added event - Timestamp: 2019-11-04 19:11:22, Device: SMA_Energymeter, Type: SMAEM, Event: Einspeisung_WirkP_Zaehler_Diff: 0, Reading: Einspeisung_WirkP_Zaehler_Diff, Value: 0, Unit:
2019.11.04 19:11:22.452 4: DbLog LogDB1 -> check Device: SMA_Energymeter , Event: Einspeisung_WirkP_Verguet_Diff: 0.0000
2019.11.04 19:11:22.456 4: DbLog LogDB1 -> added event - Timestamp: 2019-11-04 19:11:22, Device: SMA_Energymeter, Type: SMAEM, Event: Einspeisung_WirkP_Verguet_Diff: 0.0000, Reading: Einspeisung_WirkP_Verguet_Diff, Value: 0.0000, Unit:
2019.11.04 19:11:22.457 4: DbLog LogDB1 -> check Device: SMA_Energymeter , Event: state: -582.7
2019.11.04 19:11:22.460 4: DbLog LogDB1 -> added event - Timestamp: 2019-11-04 19:11:22, Device: SMA_Energymeter, Type: SMAEM, Event: state: -582.7, Reading: state, Value: -582.7, Unit:
2019.11.04 19:11:22.461 4: DbLog LogDB1 -> check Device: SMA_Energymeter , Event: Saldo_Wirkleistung: -582.7
2019.11.04 19:11:22.464 4: DbLog LogDB1 -> added event - Timestamp: 2019-11-04 19:11:22, Device: SMA_Energymeter, Type: SMAEM, Event: Saldo_Wirkleistung: -582.7, Reading: Saldo_Wirkleistung, Value: -582.7, Unit: W
2019.11.04 19:11:22.464 4: DbLog LogDB1 -> check Device: SMA_Energymeter , Event: Bezug_Wirkleistung: 582.7
2019.11.04 19:11:22.467 4: DbLog LogDB1 -> check Device: SMA_Energymeter , Event: Bezug_Wirkleistung_Zaehler: 9519.7230
2019.11.04 19:11:22.470 4: DbLog LogDB1 -> added event - Timestamp: 2019-11-04 19:11:22, Device: SMA_Energymeter, Type: SMAEM, Event: Bezug_Wirkleistung_Zaehler: 9519.7230, Reading: Bezug_Wirkleistung_Zaehler, Value: 9519.7230, Unit: kWh
2019.11.04 19:11:22.471 4: DbLog LogDB1 -> check Device: SMA_Energymeter , Event: Einspeisung_Wirkleistung: 0.0
2019.11.04 19:11:22.474 4: DbLog LogDB1 -> added event - Timestamp: 2019-11-04 19:11:22, Device: SMA_Energymeter, Type: SMAEM, Event: Einspeisung_Wirkleistung: 0.0, Reading: Einspeisung_Wirkleistung, Value: 0.0, Unit: W
2019.11.04 19:11:22.475 4: DbLog LogDB1 -> check Device: SMA_Energymeter , Event: Einspeisung_Wirkleistung_Zaehler: 14974.4042
2019.11.04 19:11:22.478 4: DbLog LogDB1 -> added event - Timestamp: 2019-11-04 19:11:22, Device: SMA_Energymeter, Type: SMAEM, Event: Einspeisung_Wirkleistung_Zaehler: 14974.4042, Reading: Einspeisung_Wirkleistung_Zaehler, Value: 14974.4042, Unit: kWh
2019.11.04 19:11:22.480 4: DbLog LogDB1 -> check Device: SMA_Energymeter , Event: L1_Spannung: 231.4
2019.11.04 19:11:22.482 4: DbLog LogDB1 -> added event - Timestamp: 2019-11-04 19:11:12, Device: SMA_Energymeter, Type: SMAEM, Event: L1_Spannung: 231.4, Reading: L1_Spannung, Value: 231.4, Unit: V
2019.11.04 19:11:22.484 4: DbLog LogDB1 -> check Device: SMA_Energymeter , Event: L2_Spannung: 231.2
2019.11.04 19:11:22.487 4: DbLog LogDB1 -> added event - Timestamp: 2019-11-04 19:11:12, Device: SMA_Energymeter, Type: SMAEM, Event: L2_Spannung: 231.2, Reading: L2_Spannung, Value: 231.2, Unit: V
2019.11.04 19:11:22.488 4: DbLog LogDB1 -> check Device: SMA_Energymeter , Event: L3_Spannung: 232.4
2019.11.04 19:11:22.491 4: DbLog LogDB1 -> added event - Timestamp: 2019-11-04 19:11:22, Device: SMA_Energymeter, Type: SMAEM, Event: L3_Spannung: 232.4, Reading: L3_Spannung, Value: 232.4, Unit: V
Hi,
so ich hab da mal geloggt. Für die anderen Readings des Devices kein Problem:
2019.11.04 19:29:48.297 4: DbLog DBLog -> ### start of new Logcycle ###
2019.11.04 19:29:48.297 4: DbLog DBLog -> ################################################################
2019.11.04 19:29:48.298 4: DbLog DBLog -> number of events received: 4 for device: Umgebungssensor_Fassade_SuedSeite
2019.11.04 19:29:48.299 4: DbLog DBLog -> check Device: Umgebungssensor_Fassade_SuedSeite , Event: batVoltage: 3.34
2019.11.04 19:29:48.301 4: DbLog DBLog -> added event - Timestamp: 2019-11-04 19:29:48, Device: Umgebungssensor_Fassade_SuedSeite, Type: CUL_HM, Event: batVoltage: 3.34, Reading: batVoltage, Value: 3.34, Unit:
2019.11.04 19:29:48.303 4: DbLog DBLog -> check Device: Umgebungssensor_Fassade_SuedSeite , Event: brightness: 0.05
2019.11.04 19:29:48.304 4: DbLog DBLog -> added event - Timestamp: 2019-11-04 19:29:48, Device: Umgebungssensor_Fassade_SuedSeite, Type: CUL_HM, Event: brightness: 0.05, Reading: brightness, Value: 0.05, Unit:
2019.11.04 19:29:48.306 4: DbLog DBLog -> check Device: Umgebungssensor_Fassade_SuedSeite , Event: humidity: 86
2019.11.04 19:29:48.307 4: DbLog DBLog -> added event - Timestamp: 2019-11-04 19:29:48, Device: Umgebungssensor_Fassade_SuedSeite, Type: CUL_HM, Event: humidity: 86, Reading: humidity, Value: 86, Unit: %
2019.11.04 19:29:48.309 4: DbLog DBLog -> check Device: Umgebungssensor_Fassade_SuedSeite , Event: temperature: 8.2
2019.11.04 19:29:48.311 4: DbLog DBLog -> added event - Timestamp: 2019-11-04 19:29:48, Device: Umgebungssensor_Fassade_SuedSeite, Type: CUL_HM, Event: temperature: 8.2, Reading: temperature, Value: 8.2, Unit: °C
für das spezielle Reading finde ich nur das:
2019.11.04 19:27:30.920 4: DbLog DBLog -> ################################################################
2019.11.04 19:27:30.921 4: DbLog DBLog -> ### start of new Logcycle ###
2019.11.04 19:27:30.921 4: DbLog DBLog -> ################################################################
2019.11.04 19:27:30.922 4: DbLog DBLog -> number of events received: 1 for device: Umgebungssensor_Fassade_SuedSeite
2019.11.04 19:27:30.923 4: DbLog DBLog -> check Device: Umgebungssensor_Fassade_SuedSeite , Event: MinTempDay:7.8000
danach kommt schon der nächste Logcycle
Ja, für das Reading MinTempDay fehlt nach den check das "add event". DbLog sortiert es aus.
Es fehlt ein Leerzeichen hinter "MinTempDay:".
Der Eventbefehl müsste lauten:
fhem ("trigger $dest $read: $value");
Zitat von: DS_Starter am 04 November 2019, 19:40:34
Ja, für das Reading MinTempDay fehlt nach den check das "add event". DbLog sortiert es aus.
Es fehlt ein Leerzeichen hinter "MinTempDay:".
Der Eventbefehl müsste lauten:
fhem ("trigger $dest $read: $value");
Argh, das Leerzeichen hatte ich gar nicht mitbekommen. Vielen lieben Dank. Hat jetzt funktioniert. 8)
Habs auch nicht gleich gesehen. Schön das es jetzt funktioniert. :D
LG
Zitat von: DS_Starter am 04 November 2019, 19:53:05
Habs auch nicht gleich gesehen. Schön das es jetzt funktioniert. :D
LG
Das hat mir keine Ruhe gelassen mit dem Leerzeichen vom Trigger. Ich habe noch mal nachgeschaut, wo ich die exakte Syntax herhabe. Im Wiki steht es ohne Leerzeichen: https://wiki.fhem.de/wiki/Trigger
nur ein bestimmtes Reading triggern
Manchmal möchte man nicht auf state prüfen (wie z.B. bei einem Dummy) sondern auf ein bestimmtes Reading. Hierfür lautet die Syntax
trigger <Device> <Reading>:<Value>
Also z.B.
trigger Stromzaehler power:1000
Jetzt die Frage: ist es im Wiki falsch oder eine Besonderheit? Weil das Event kam ja, nur kein added event
Moin Kai,
im Wiki nicht ganz korrekt möchte ich sagen.
Wenn du dir im Eventmonitor die anderen Events anschaust wirst du feststellen, dass immer ein Leerzeichen zwischen Reading: und dem Wert ist.
So splittet DbLog auch die Events. Filelog z.B. muss das nicht tun und ist demzufolge auch nicht so relevant.
Ich könnte das Splitting im DbLog anpassen, muss mir aber genau überlegen ob das keine unerwünschten Nebeneffekte hat.
Vielleicht ist es besser bei Rudi nachzufragen, vllt. war früher irgendwann mal an dieser Stelle kein Leerzeichen.
Zitat von: DS_Starter am 05 November 2019, 09:24:27
Vielleicht ist es besser bei Rudi nachzufragen, vllt. war früher irgendwann mal an dieser Stelle kein Leerzeichen.
Ich mach Ihn mal auf diesen Thread aufmerksam 8)
readingsBulkUpdate fuegt die Events in die Liste mitmy $rv = "$reading: $value";
[...]
addEvent($hash, $rv);
hinzu.
Das trigger Befehl setzt die Argumente ohne Umformatierung einfach ab, bei trigger muss man nicht mal Value angeben.
Das Beispiel in der Wiki ist fuer die meisten Module (die, wie empfohlen, readings*Update verwenden) falsch.
Danke Rudi, ich werde heute Abend die Beispiele im Wiki mal anpassen wenn Kai nicht schneller sein sollte. ;)
Lg,
Heiko
Mir schreibt es immer wieder Fehler zu dieser Zeile ins log.
my $pmts = "$3-$2-$1 $4:$5:$6";
2023.03.07 20:13:51 1: PERL WARNING: Use of uninitialized value $3 in concatenation (.) or string at ./FHEM/99_rundenUtils.pm line 15.
2023.03.07 20:13:51 1: PERL WARNING: Use of uninitialized value $2 in concatenation (.) or string at ./FHEM/99_rundenUtils.pm line 15.
2023.03.07 20:13:51 1: PERL WARNING: Use of uninitialized value $1 in concatenation (.) or string at ./FHEM/99_rundenUtils.pm line 15.
2023.03.07 20:13:51 1: PERL WARNING: Use of uninitialized value $4 in concatenation (.) or string at ./FHEM/99_rundenUtils.pm line 15.
2023.03.07 20:13:51 1: PERL WARNING: Use of uninitialized value $5 in concatenation (.) or string at ./FHEM/99_rundenUtils.pm line 15.
2023.03.07 20:13:51 1: PERL WARNING: Use of uninitialized value $6 in concatenation (.) or string at ./FHEM/99_rundenUtils.pm line 15.
Hat jemand eine Idee woran das liegt?
Mir schreibt es immer wieder Fehler zu dieser Zeile ins log.
my $pmts = "$3-$2-$1 $4:$5:$6";
2023.03.07 20:13:51 1: PERL WARNING: Use of uninitialized value $3 in concatenation (.) or string at ./FHEM/99_rundenUtils.pm line 15.
2023.03.07 20:13:51 1: PERL WARNING: Use of uninitialized value $2 in concatenation (.) or string at ./FHEM/99_rundenUtils.pm line 15.
2023.03.07 20:13:51 1: PERL WARNING: Use of uninitialized value $1 in concatenation (.) or string at ./FHEM/99_rundenUtils.pm line 15.
2023.03.07 20:13:51 1: PERL WARNING: Use of uninitialized value $4 in concatenation (.) or string at ./FHEM/99_rundenUtils.pm line 15.
2023.03.07 20:13:51 1: PERL WARNING: Use of uninitialized value $5 in concatenation (.) or string at ./FHEM/99_rundenUtils.pm line 15.
2023.03.07 20:13:51 1: PERL WARNING: Use of uninitialized value $6 in concatenation (.) or string at ./FHEM/99_rundenUtils.pm line 15.
Hat jemand eine Idee woran das liegt?
Wenn man wüsste, was in Deiner 99_rundenUtils.pm dazu steht und verstehen würde, was das mit DbRep zu tun hat - könnte man Dir vielleicht helfen.
Du versuchst halt, einen String aus Werten zu erzeugen, in denen nix drinsteht.
Moin,
ist schon ein bisschen älter das Thema, aber mein File funktioniert nicht mehr. Geändert habe ich meines Wissens nichts an dem File
reload: Error:Modul 99_myDbRepUtils deactivated:
Inhalt der 99_myDbRepUtils
############################################################################################################
## 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 TempStatistik {
my ($name,$reading,$value) = @_;
my $resr;
if($reading =~ /^.*Temp.*$/) { # es ist das Ergebnis aus Ursprungdevice / ausgewertetes Reading / MAX
my ($ts,$read,undef) = split("__",$reading,3); # Extraktion Timestamp, read = Reading Name zum Erstellen, Extract aus readingNameMap
$ts =~ /^(\d+)-(\d+)-(\d+)_(\d+)-(\d+)-(\d+)$/; # Aufteilung Timestamp
my $pmts = "$1-$2-$3 $4:$5:$6"; # Neuzusammenstellung des Timestamp
my $tsdate = "$1-$2-$3";
my $tstime = "$4:$5:$6";
my $dest = AttrVal($name, "device", ""); # device Attribut dbrep auslesen
my $hash = $defs{$dest}; # hash des Zieldevices
# readingsSingleUpdate($hash, $resr, $value, 1); # wenn man den aktuellen Timestamp setzt (Normalfall)
setReadingsVal($hash,$read,$value,$pmts); # !!! Spezialfall !!! abweichenden Timestamp setzen
fhem ("trigger $dest $read: $value");
}
return;
}]
Wenn 99_myDbRepUtils nicht geladen werden kann, kommt im Log mit ziemlicher Sicherheit vor der Meldungszeile eine Perl-Fehlermeldung die auf den Grund hinweist.
Möglicherweise gibt es die Routine setReadingsVal nicht, zumindest ist das keine FHEM Standardroutine.