(older than) one !", 1);
+ $valid = 0;
+ }
+
+return $valid;
+}
+
################################################################
# extrahiert aus dem übergebenen Wert nur die Zahl
################################################################
@@ -11800,16 +12053,52 @@ sub DbRep_removeLeadingZero {
return $val;
}
-####################################################################################################
-# löscht einen Wert vom $hash des Hauptprozesses aus einem BlockingCall heraus
-####################################################################################################
+################################################################
+# Werte aus BlockingCall heraus setzen
+# Erwartete Liste:
+# @setl = $name,$setread,$helper
+################################################################
+sub DbRep_setFromBlocking {
+ my $name = shift;
+ my $setread = shift // "NULL";
+ my $helper = shift // "NULL";
+
+ my $hash = $defs{$name};
+
+ if($setread ne "NULL") {
+ my @cparts = split ":", $setread, 2;
+ ReadingsSingleUpdateValue ($hash, $cparts[0], $cparts[1], 1);
+ }
+
+ if($helper ne "NULL") {
+ my ($hnam,$k1,$k2,$k3) = split ":", $helper, 4;
+
+ if(defined $k3) {
+ $hash->{HELPER}{"$hnam"}{"$k1"}{"$k2"} = $k3;
+ }
+ elsif (defined $k2) {
+ $hash->{HELPER}{"$hnam"}{"$k1"} = $k2;
+ }
+ else {
+ $hash->{HELPER}{"$hnam"} = $k1;
+ }
+ }
+
+return 1;
+}
+
+################################################################
+# löscht einen Wert vom $hash des Hauptprozesses aus
+# einem BlockingCall heraus
+################################################################
sub DbRep_delHashValFromBlocking {
my ($name,$v1,$v2) = @_;
my $hash = $defs{$name};
if($v2) {
delete $hash->{$v1}{$v2};
- } elsif ($v1) {
+ }
+ elsif ($v1) {
delete $hash->{$v1};
}
@@ -13377,10 +13666,17 @@ return;
Method without option specification
- If no options are specified, the data will be stored within the time specified by the time.* attributes.
- Time limits reduced to one entry (the first) per hour per Device & Reading.
- At least one of the time.* attributes must be set (see table below).
- In this case, the missing time limit is calculated by the module.
+ The data within the time limits defined by the time.* attributes will be
+ reduced to one entry (the first) per hour per device & reading.
+ At least one of the time.* attributes must be set (see table below).
+ The FullDay option (full days are always selected) is used implicitly.
+ The respective missing time delimitation is calculated by the module in this case.
+
+
+ By optionally specifying average, not only the database will be cleaned up, but
+ all numeric values of an hour are reduced to a single average value.
+ With the option average=day, all numeric values of a day are reduced to a single
+ average value (implies 'average').
With the attributes device and reading the data records to be considered can be included
@@ -13408,28 +13704,28 @@ return;
Examples:
- attr <name> timeOlderThan = d:200
+ attr <name> timeOlderThan d:200
set <name> reduceLog
# Records older than 200 days are written to the first entry per hour per Device & Reading.
- attr <name> timeDiffToNow = d:200
+ attr <name> timeDiffToNow d:200
set <name> reduceLog average=day
# Records newer than 200 days are limited to one entry per day per Device & Reading.
- attr <name> timeDiffToNow = d:30
- attr <name> device = TYPE=SONOSPLAYER EXCLUDE=Sonos_Kueche
- attr <name> reading = room% EXCLUDE=roomNameAlias
+ attr <name> timeDiffToNow d:30
+ attr <name> device TYPE=SONOSPLAYER EXCLUDE=Sonos_Kueche
+ attr <name> reading room% EXCLUDE=roomNameAlias
set <name> reduceLog
# Records newer than 30 days that are devices of type SONOSPLAYER
(except Device "Sonos_Kitchen") and the readings start with "room" (except "roomNameAlias")
are reduced to the first entry per hour per Device & Reading.
- attr <name> timeDiffToNow = d:10
- attr <name> timeOlderThan = d:5
- attr <name> device = Luftdaten_remote
+ attr <name> timeDiffToNow d:10
+ attr <name> timeOlderThan d:5
+ attr <name> device Luftdaten_remote
set <name> reduceLog average
# Records older than 5 and newer than 10 days and containing DEVICE "Luftdaten_remote
are adjusted. Numerical values of an hour are reduced to an average value
@@ -13446,9 +13742,19 @@ return;
With the option average=day all numerical values of a day are reduced to a single
Average value reduced (implies 'average').
- The additions "EXCLUDE" and "INCLUDE" can be added to exclude device/reading combinations of reduceLog
- or to include them. This specification is evaluated as regex and overwrites the setting of the attributes "device".
- and "reading", which are not considered in this case.
+ The additions "EXCLUDE" or "INCLUDE" can be added to exclude or include device/reading combinations in reduceLog
+ and override the "device" and "reading" attributes, which are ignored in this case.
+ The specification in "EXCLUDE" is evaluated as a regex. Inside "INCLUDE", SQL wildcards
+ can be used. (for more information on SQL wildcards, see with get <name> versionNotes 6)
+
+
+ Examples:
+
+ set <name> reduceLog 174:180 average EXCLUDE=SMA_Energymeter:Bezug_Wirkleistung INCLUDE=SMA_Energymeter:%
+ # Records older than 174 and newer than 180 days are reduced to average per hour.
+ # All readings from the device "SMA_Energymeter" except "Bezug_Wirkleistung" are taken reduced.
+
+
Note:
Although the function itself is designed non-blocking, the assigned DbLog device should
@@ -14705,48 +15011,87 @@ sub bdump {
(only valid if database type is MYSQL and DbRep-type "Client")
-
- - userExitFn - provides an interface to execute user specific program code.
- To activate the interfaace, at first you should implement the subroutine which will be
- called by the interface in your 99_myUtils.pm as shown by the example:
+
+ - userExitFn - provides an interface for executing custom user code.
+ Basically, the interface works without event generation or does not require an event to function.
+ The interface can be used with the following variants.
+
+
+
+ 1. call a subroutine, e.g. in 99_myUtils.pm
.
+
+ The subroutine to be called is created in 99_myUtils.pm according to the following pattern:
-
- sub UserFunction {
- my ($name,$reading,$value) = @_;
- my $hash = $defs{$name};
- ...
- # e.g. output transfered data
- Log3 $name, 1, "UserExitFn $name called - transfer parameter are Reading: $reading, Value: $value " ;
- ...
- return;
- }
-
- The interface activation takes place by setting the subroutine name into the attribute.
- Optional you may set a Reading:Value combination (Regex) as argument. If no Regex is
- specified, all value combinations will be evaluated as "true" (related to .*:.*).
+
+sub UserFunction {
+ my $name = shift; # the name of the DbRep device.
+ my $reading = shift; # the name of the reading to create
+ my $value = shift; # the value of the reading
+ my $hash = $defs{$name};
+ ...
+ # e.g. log passed data
+ Log3 $name, 1, "UserExitFn $name called - transfer parameters are Reading: $reading, Value: $value " ;
+ ...
+return;
+}
+
+
+ In the attribute the subroutine and optionally a Reading:Value regex
+ must be specified as an argument. Without this specification all Reading:Value combinations are
+ evaluated as "true" and passed to the subroutine (equivalent to .*:.*).
Example:
- attr userExitFn UserFunction .*:.*
- # "UserFunction" is the name of subroutine in 99_myUtils.pm.
+ attr userExitFn UserFunction Meter:Energy.*
+ # "UserFunction" is the subroutine in 99_myUtils.pm.
- The interface works generally without and independent from events.
- If the attribute is set, after every reading creation in the device the Regex will be
- evaluated.
- If the evaluation is true, the subroutine will be called.
- For further processing the following parameters are forwarded to the function:
+ The regex is checked after the creation of each reading.
+ If the check is true, the specified function is called.
+
+ 2. Direct input of custom code
.
+
+ The custom code is enclosed in curly braces.
+ The code is called after the creation of each reading.
+ In the code, the following variables are available for evaluation:
- - $name - the name of the DbRep-Device
- - $reading - the name of the created reading
- - $value - the value of the reading
-
+ - $NAME - the name of the DbRep device
+ - $READING - the name of the reading created
+ - $VALUE - the value of the reading
-
-
+
+
+
+
+{
+ if ($READING =~ /PrEnergySumHwc1_0_value__DIFF/) {
+ my $mpk = AttrVal($NAME, 'multiplier', '0');
+ my $tarf = AttrVal($NAME, 'Tariff', '0'); # cost €/kWh
+ my $m3 = sprintf "%.3f", $VALUE/10000 * $mpk; # consumed m3
+ my $kwh = sprintf "%.3f", $m3 * AttrVal($NAME, 'Calorific_kWh/m3', '0'); # conversion m3 -> kWh
+ my $cost = sprintf "%.2f", $kwh * $tarf;
+
+ my $hash = $defs{$NAME};
+
+ readingsBulkUpdate ($hash, 'gas_consumption_m3', $m3);
+ readingsBulkUpdate ($hash, 'gas_consumption_kwh', $kwh);
+ readingsBulkUpdate ($hash, 'gas_costs_euro', $cost);
+ }
+}
+
+ # The readings gas_consumption_m3, gas_consumption_kwh and gas_costs_euro are calculated
+ And generated in the DbRep device.
+
+
+
+
+
+
valueFilter - Regular expression (REGEXP) to filter datasets within particular functions. The REGEXP is
@@ -16023,14 +16368,20 @@ sub bdump {
reduceLog [<no>[:<nn>]] [average[=day]] [EXCLUDE=device1:reading1,device2:reading2,...] [INCLUDE=device:reading]
Reduziert historische Datensätze.
- Arbeitsweise ohne Optionsangabe
+ Arbeitsweise ohne Optionsangabe
- Sind keine Optionen angegeben, werden die Daten innerhalb der durch die time.*-Attribute bestimmten
+ Es werden die Daten innerhalb der durch die time.*-Attribute bestimmten
Zeitgrenzen auf einen Eintrag (den ersten) pro Stunde je Device & Reading reduziert.
- Es muss mindestens eines der time.*-Attribute gesetzt sein (siehe Tabelle unten).
+ Es muss mindestens eines der time.*-Attribute gesetzt sein (siehe Tabelle unten).
+ Die FullDay-Option (es werden immer volle Tage selektiert) wird impliziert verwendet.
Die jeweils fehlende Zeitabgrenzung wird in diesem Fall durch das Modul errechnet.
+ Durch die optionale Angabe von average wird nicht nur die Datenbank bereinigt, sondern
+ alle numerischen Werte einer Stunde werden auf einen einzigen Mittelwert reduziert.
+ Mit der Option average=day werden alle numerischen Werte eines Tages auf einen einzigen
+ Mittelwert reduziert (impliziert 'average').
+
Mit den Attributen device und reading können die zu berücksichtigenden Datensätze eingeschlossen
bzw. ausgeschlossen werden. Beide Eingrenzungen reduzieren die selektierten Daten und verringern den
Ressourcenbedarf.
@@ -16056,30 +16407,30 @@ sub bdump {
Beispiele:
- attr <name> timeOlderThan = d:200
+ attr <name> timeOlderThan d:200
set <name> reduceLog
# Datensätze die älter als 200 Tage sind, werden auf den ersten Eintrag pro Stunde je Device & Reading
reduziert.
- attr <name> timeDiffToNow = d:200
+ attr <name> timeDiffToNow d:200
set <name> reduceLog average=day
# Datensätze die neuer als 200 Tage sind, werden auf einen Eintrag pro Tag je Device & Reading
reduziert.
- attr <name> timeDiffToNow = d:30
- attr <name> device = TYPE=SONOSPLAYER EXCLUDE=Sonos_Kueche
- attr <name> reading = room% EXCLUDE=roomNameAlias
+ attr <name> timeDiffToNow d:30
+ attr <name> device TYPE=SONOSPLAYER EXCLUDE=Sonos_Kueche
+ attr <name> reading room% EXCLUDE=roomNameAlias
set <name> reduceLog
# Datensätze die neuer als 30 Tage sind, die Devices vom Typ SONOSPLAYER sind
(außer Device "Sonos_Kueche"), die Readings mit "room" beginnen (außer "roomNameAlias"),
werden auf den ersten Eintrag pro Stunde je Device & Reading reduziert.
- attr <name> timeDiffToNow = d:10
- attr <name> timeOlderThan = d:5
- attr <name> device = Luftdaten_remote
+ attr <name> timeDiffToNow d:10
+ attr <name> timeOlderThan d:5
+ attr <name> device Luftdaten_remote
set <name> reduceLog average
# Datensätze die älter als 5 und neuer als 10 Tage sind und DEVICE "Luftdaten_remote" enthalten,
werden bereinigt. Numerische Werte einer Stunde werden auf einen Mittelwert reduziert
@@ -16087,7 +16438,7 @@ sub bdump {
- Arbeitsweise mit Optionsangabe
+ Arbeitsweise mit Optionsangabe
Es werden Datensätze berücksichtigt die älter sind als <no> Tage und (optional) neuer sind als
<nn> Tage.
@@ -16096,9 +16447,21 @@ sub bdump {
Mit der Option average=day werden alle numerischen Werte eines Tages auf einen einzigen
Mittelwert reduziert (impliziert 'average').
- Die Zusätze "EXCLUDE" bzw. "INCLUDE" können ergänzt werden um device/reading Kombinationen von reduceLog auszuschließen
- bzw. einzuschließen. Diese Angabe wird als Regex ausgewertet und überschreibt die Einstellung der Attribute "device"
- und "reading", die in diesem Fall nicht beachtet werden.
+ Die Zusätze "EXCLUDE" bzw. "INCLUDE" können ergänzt werden um device/reading Kombinationen in reduceLog auszuschließen
+ bzw. einzuschließen und überschreiben die Einstellung der Attribute "device" und "reading", die in diesem Fall
+ nicht beachtet werden.
+ Die Angabe in "EXCLUDE" wird als Regex ausgewertet. Innerhalb von "INCLUDE" können SQL-Wildcards
+ verwendet werden (weitere Informationen zu SQL-Wildcards siehe mit get <name> versionNotes 6).
+
+
+ Beispiele:
+
+ set <name> reduceLog 174:180 average EXCLUDE=SMA_Energymeter:Bezug_Wirkleistung INCLUDE=SMA_Energymeter:%
+ # Datensätze älter als 174 und neuer als 180 Tage werden auf den Durchschnitt pro Stunde reduziert.
+ # Es werden alle Readings vom Device "SMA_Energymeter" außer "Bezug_Wirkleistung" berücksichtigt.
+ reduziert.
+
+
Hinweis:
Obwohl die Funktion selbst non-blocking ausgelegt ist, sollte das zugeordnete DbLog-Device
@@ -16107,6 +16470,7 @@ sub bdump {
Weiterhin wird dringend empfohlen den standard INDEX 'Search_Idx' in der Tabelle 'history'
anzulegen !
Die Abarbeitung dieses Befehls dauert unter Umständen (ohne INDEX) extrem lange.
+
repairSQLite - repariert eine korrupte SQLite-Datenbank.
@@ -17372,43 +17736,82 @@ sub bdump {
userExitFn - stellt eine Schnittstelle zur Ausführung eigenen Usercodes zur Verfügung.
- Um die Schnittstelle zu aktivieren, wird zunächst die aufzurufende Subroutine in
- 99_myUtils.pm nach folgendem Muster erstellt:
+ Grundsätzlich arbeitet die Schnittstelle ohne Eventgenerierung bzw. benötigt zur Funktion
+ keinen Event.
+ Die Schnittstelle kann mit folgenden Varianten verwendet werden.
+
+
+
+ 1. Aufruf einer Subroutine, z.B. in 99_myUtils.pm
+
+ Die aufzurufende Subroutine wird in 99_myUtils.pm nach folgendem Muster erstellt:
-
- sub UserFunction {
- my ($name,$reading,$value) = @_;
- my $hash = $defs{$name};
- ...
- # z.B. übergebene Daten loggen
- Log3 $name, 1, "UserExitFn $name called - transfer parameter are Reading: $reading, Value: $value " ;
- ...
- return;
- }
-
+
+sub UserFunction {
+ my $name = shift; # der Name des DbRep-Devices
+ my $reading = shift; # der Namen des erstellen Readings
+ my $value = shift; # der Wert des Readings
+ my $hash = $defs{$name};
+ ...
+ # z.B. übergebene Daten loggen
+ Log3 $name, 1, "UserExitFn $name called - transfer parameter are Reading: $reading, Value: $value " ;
+ ...
+return;
+}
+
- Die Aktivierung der Schnittstelle erfogt durch Setzen des Funktionsnamens im Attribut.
- Optional kann ein Reading:Value Regex als Argument angegeben werden. Wird kein Regex
- angegeben, werden alle Wertekombinationen als "wahr" gewertet (entspricht .*:.*).
+ Im Attribut wird die Subroutine und optional ein Reading:Value Regex
+ als Argument angegeben. Ohne diese Angabe werden alle Wertekombinationen als "wahr"
+ gewertet und an die Subroutine übergeben (entspricht .*:.*).
Beispiel:
- attr userExitFn UserFunction .*:.*
+ attr userExitFn UserFunction Meter:Energy.*
# "UserFunction" ist die Subroutine in 99_myUtils.pm.
- Grundsätzlich arbeitet die Schnittstelle ohne Eventgenerierung bzw. benötigt zur Funktion keinen
- Event. Sofern das Attribut gesetzt ist, erfolgt Die Regexprüfung nach der Erstellung jedes
- Readings im Device. Ist die Prüfung wahr, wird die angegebene Funktion aufgerufen.
- Zur Weiterverarbeitung werden der aufgerufenenen Funktion folgende Variablen übergeben:
+ Die Regexprüfung nach der Erstellung jedes Readings.
+ Ist die Prüfung wahr, wird die angegebene Funktion aufgerufen.
+
+ 2. direkte Einngabe von eigenem Code
+
+ Der eigene Code wird in geschweifte Klammern eingeschlossen.
+ Der Aufruf des Codes erfolgt nach der Erstellung jedes Readings.
+ Im Code stehen folgende Variablen für eine Auswertung zur Verfügung:
- - $name - der Name des DbRep-Devices
- - $reading - der Namen des erstellen Readings
- - $value - der Wert des Readings
+ - $NAME - der Name des DbRep-Devices
+ - $READING - der Namen des erstellen Readings
+ - $VALUE - der Wert des Readings
+
+
+
+
+{
+ if ($READING =~ /PrEnergySumHwc1_0_value__DIFF/) {
+ my $mpk = AttrVal($NAME, 'Multiplikator', '0');
+ my $tarf = AttrVal($NAME, 'Tarif', '0'); # Kosten €/kWh
+ my $m3 = sprintf "%.3f", $VALUE/10000 * $mpk; # verbrauchte m3
+ my $kwh = sprintf "%.3f", $m3 * AttrVal($NAME, 'Brennwert_kWh/m3', '0'); # Umrechnung m3 -> kWh
+ my $cost = sprintf "%.2f", $kwh * $tarf;
+
+ my $hash = $defs{$NAME};
+
+ readingsBulkUpdate ($hash, 'gas_consumption_m3', $m3);
+ readingsBulkUpdate ($hash, 'gas_consumption_kwh', $kwh);
+ readingsBulkUpdate ($hash, 'gas_costs_euro', $cost);
+ }
+}
+
+ # Es werden die Readings gas_consumption_m3, gas_consumption_kwh und gas_costs_euro berechnet
+ und im DbRep-Device erzeugt.
+
+