2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-19 18:56:03 +00:00

93_DbRep: contrib v 8.46.0

git-svn-id: https://svn.fhem.de/fhem/trunk@25310 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
nasseeder1 2021-12-06 22:45:23 +00:00
parent 738018d9fd
commit 06184d91ba

View File

@ -57,6 +57,7 @@ no if $] >= 5.017011, warnings => 'experimental::smartmatch';
# Version History intern # Version History intern
my %DbRep_vNotesIntern = ( my %DbRep_vNotesIntern = (
"8.46.0" => "06.12.2021 reduceLog options INCLUDE / EXCLUCE parse by parseParams ",
"8.45.0" => "05.12.2021 revised userExitFn, fix average=day problem in reduceLog (Forum: https://forum.fhem.de/index.php/topic,53584.msg1177799.html#msg1177799) ", "8.45.0" => "05.12.2021 revised userExitFn, fix average=day problem in reduceLog (Forum: https://forum.fhem.de/index.php/topic,53584.msg1177799.html#msg1177799) ",
"8.44.1" => "27.11.2021 change diffValue: recognize if diff is 0 or no value available ", "8.44.1" => "27.11.2021 change diffValue: recognize if diff is 0 or no value available ",
"8.44.0" => "21.11.2021 new attr numDecimalPlaces ", "8.44.0" => "21.11.2021 new attr numDecimalPlaces ",
@ -9018,16 +9019,13 @@ sub DbRep_reduceLog {
} }
@a = @b; @a = @b;
my ($pa,$ph) = parseParams(join ' ', @a); # für späteren Einsatz ! my ($pa,$ph) = parseParams(join ' ', @a);
#Log3 ($name, 1, "DbRep $name -> parseParams pa: ".Dumper (bless $pa));
#Log3 ($name, 1, "DbRep $name -> parseParams ph: ".Dumper (bless $ph));
my $avgstring = q{}; my $avgstring = (@$pa[1] && @$pa[1] =~ /average/i) ? 'AVERAGE=HOUR' :
if (defined($a[1])) { ($ph->{average} && $ph->{average} eq "day") ? 'AVERAGE=DAY' :
$avgstring = ($a[1] =~ /average=day/i) ? 'AVERAGE=DAY' :
($a[1] =~ /average/i) ? 'AVERAGE=HOUR' :
q{}; q{};
}
Log3 ($name, 2, "DbRep $name - DbRep_reduceLog Arraystr - $avgstring");
# Korrektur des Select-Zeitraums + eine Stunde # Korrektur des Select-Zeitraums + eine Stunde
# (Forum: https://forum.fhem.de/index.php/topic,53584.msg1177799.html#msg1177799) # (Forum: https://forum.fhem.de/index.php/topic,53584.msg1177799.html#msg1177799)
@ -9036,13 +9034,11 @@ sub DbRep_reduceLog {
my $splus = $avgstring =~ /AVERAGE/ ? 3600 : 0; my $splus = $avgstring =~ /AVERAGE/ ? 3600 : 0;
$ots = strftime "%Y-%m-%d %H:%M:%S", localtime($epoche+$splus); $ots = strftime "%Y-%m-%d %H:%M:%S", localtime($epoche+$splus);
my $excludes = $ph->{EXCLUDE} // q{};
my $includes = $ph->{INCLUDE} // q{};
if ($a[-1] =~ /^EXCLUDE=(.+:.+)+/i) { if ($excludes) {
($filter) = $a[-1] =~ /^EXCLUDE=(.+)/i; @excludeRegex = split(',',$excludes);
@excludeRegex = split(',',$filter);
}
elsif ($a[-1] =~ /^INCLUDE=.+:.+$/i) {
$filter = 1;
} }
eval { $dbh = DBI->connect("dbi:$dbconn", $dbuser, $dbpassword, { PrintError => 0, eval { $dbh = DBI->connect("dbi:$dbconn", $dbuser, $dbpassword, { PrintError => 0,
@ -9067,9 +9063,9 @@ sub DbRep_reduceLog {
my $selspec = "SELECT TIMESTAMP,DEVICE,'',READING,VALUE FROM history where "; my $selspec = "SELECT TIMESTAMP,DEVICE,'',READING,VALUE FROM history where ";
my $addon = "ORDER BY TIMESTAMP ASC"; my $addon = "ORDER BY TIMESTAMP ASC";
if($filter) { # Option EX/INCLUDE wurde angegeben if($includes) { # Option EX/INCLUDE wurde angegeben
$sql = "SELECT TIMESTAMP,DEVICE,'',READING,VALUE FROM history WHERE " $sql = "SELECT TIMESTAMP,DEVICE,'',READING,VALUE FROM history WHERE "
.($a[-1] =~ /^INCLUDE=(.+):(.+)$/i ? "DEVICE like '$1' AND READING like '$2' AND " : '') .($includes =~ /^(.+):(.+)$/i ? "DEVICE like '$1' AND READING like '$2' AND " : '')
."TIMESTAMP <= '$ots'" ."TIMESTAMP <= '$ots'"
.($nts ? " AND TIMESTAMP >= '$nts' " : " ") .($nts ? " AND TIMESTAMP >= '$nts' " : " ")
."ORDER BY TIMESTAMP ASC"; ."ORDER BY TIMESTAMP ASC";
@ -9087,11 +9083,17 @@ sub DbRep_reduceLog {
Log3 ($name, 3, "DbRep $name - reduceLog requested with options: " Log3 ($name, 3, "DbRep $name - reduceLog requested with options: "
.$avgstring .$avgstring
.($filter ? ((($avgstring && $filter) ? ", " : '').(uc((split('=',$a[-1]))[0]).'='.(split('=',$a[-1]))[1])) : ."\n"
((($idanz || $idevswc || $iranz || $irdswc) ? " INCLUDE -> " : ''). .($includes ? "INCLUDE -> $includes " :
(($idanz || $idevswc) ? "Devs: ".($idevs ? $idevs:'').($idevswc ? $idevswc : '') : '').(($iranz || $irdswc) ? " Readings: ".($ireading ? $ireading : '').($irdswc ? $irdswc : '') : ''). ((($idanz || $idevswc || $iranz || $irdswc) ? "INCLUDE -> " : '')
(($edanz || $edevswc || $eranz || $erdswc) ? " EXCLUDE -> " : ''). . (($idanz || $idevswc) ? "Devs: ".($idevs ? $idevs : '').($idevswc ? $idevswc : '').' ' : '').(($iranz || $irdswc) ? "Readings: ".($ireading ? $ireading : '').($irdswc ? $irdswc : '') : '')
(($edanz || $edevswc) ? "Devs: ".($edevs ? $edevs : '').($edevswc ? $edevswc : '') : '').(($eranz || $erdswc) ? " Readings: ".($ereading ? $ereading:'').($erdswc ? $erdswc : '') : '')) )); ))
."\n"
.($excludes ? "EXCLUDE -> $excludes " :
((($edanz || $edevswc || $eranz || $erdswc) ? "EXCLUDE -> " : '')
. (($edanz || $edevswc) ? "Devs: ".($edevs ? $edevs : '').($edevswc ? $edevswc : '').' ' : '').(($eranz || $erdswc) ? "Readings: ".($ereading ? $ereading : '').($erdswc ? $erdswc : '') : '')
))
);
my ($sth_del, $sth_upd, $sth_delD, $sth_updD, $sth_get); my ($sth_del, $sth_upd, $sth_delD, $sth_updD, $sth_get);
@ -13562,12 +13564,17 @@ return;
<b>Method without option specification</b> <br><br> <b>Method without option specification</b> <br><br>
If no options are specified, the data will be reduced to one entry (the first) per hour per The data within the time limits defined by the <b>time.*</b> attributes will be
device & reading within the time limits specified by the <b>time.*</b> attributes. reduced to one entry (the first) per hour per device & reading.
At least one of the <b>time.*</b> attributes must be set (see table below). At least one of the <b>time.*</b> attributes must be set (see table below).
The FullDay option (full days are always selected) is used implicitly. The FullDay option (full days are always selected) is used implicitly.
The respective missing time delimitation is calculated by the module in this case. The respective missing time delimitation is calculated by the module in this case.
<br><br>
By optionally specifying <b>average</b>, 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 <b>average=day</b>, all numeric values of a day are reduced to a single
average value (implies 'average').
<br><br> <br><br>
With the attributes <b>device</b> and <b>reading</b> the data records to be considered can be included With the attributes <b>device</b> and <b>reading</b> the data records to be considered can be included
@ -13595,28 +13602,28 @@ return;
<b>Examples: </b><br><br> <b>Examples: </b><br><br>
<ul> <ul>
attr &lt;name&gt; timeOlderThan = d:200 <br> attr &lt;name&gt; timeOlderThan d:200 <br>
set &lt;name&gt; reduceLog <br> set &lt;name&gt; reduceLog <br>
# Records older than 200 days are written to the first entry per hour per Device & Reading. <br> # Records older than 200 days are written to the first entry per hour per Device & Reading. <br>
<br> <br>
attr &lt;name&gt; timeDiffToNow = d:200 <br> attr &lt;name&gt; timeDiffToNow d:200 <br>
set &lt;name&gt; reduceLog average=day <br> set &lt;name&gt; reduceLog average=day <br>
# Records newer than 200 days are limited to one entry per day per Device & Reading. <br> # Records newer than 200 days are limited to one entry per day per Device & Reading. <br>
<br> <br>
attr &lt;name&gt; timeDiffToNow = d:30 <br> attr &lt;name&gt; timeDiffToNow d:30 <br>
attr &lt;name&gt; device = TYPE=SONOSPLAYER EXCLUDE=Sonos_Kueche <br> attr &lt;name&gt; device TYPE=SONOSPLAYER EXCLUDE=Sonos_Kueche <br>
attr &lt;name&gt; reading = room% EXCLUDE=roomNameAlias <br> attr &lt;name&gt; reading room% EXCLUDE=roomNameAlias <br>
set &lt;name&gt; reduceLog <br> set &lt;name&gt; reduceLog <br>
# Records newer than 30 days that are devices of type SONOSPLAYER # Records newer than 30 days that are devices of type SONOSPLAYER
(except Device "Sonos_Kitchen") and the readings start with "room" (except "roomNameAlias") (except Device "Sonos_Kitchen") and the readings start with "room" (except "roomNameAlias")
are reduced to the first entry per hour per Device & Reading. <br> are reduced to the first entry per hour per Device & Reading. <br>
<br> <br>
attr &lt;name&gt; timeDiffToNow = d:10 <br> attr &lt;name&gt; timeDiffToNow d:10 <br>
attr &lt;name&gt; timeOlderThan = d:5 <br> attr &lt;name&gt; timeOlderThan d:5 <br>
attr &lt;name&gt; device = Luftdaten_remote <br> attr &lt;name&gt; device Luftdaten_remote <br>
set &lt;name&gt; reduceLog average <br> set &lt;name&gt; reduceLog average <br>
# Records older than 5 and newer than 10 days and containing DEVICE "Luftdaten_remote # 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 <br> are adjusted. Numerical values of an hour are reduced to an average value <br>
@ -13637,6 +13644,14 @@ return;
or to include them. This specification is evaluated as regex and overwrites the setting of the attributes "device". 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. <br><br> and "reading", which are not considered in this case. <br><br>
<b>Examples: </b><br><br>
<ul>
set &lt;name&gt; reduceLog 174:180 average EXCLUDE=SMA_Energymeter:Bezug_Wirkleistung INCLUDE=SMA_Energymeter:% <br>
# Records older than 174 and newer than 180 days are reduced to average per hour. <br>
# All readings from the device "SMA_Energymeter" except "Bezug_Wirkleistung" are taken reduced. <br>
</ul>
<br>
<b>Note:</b> <br> <b>Note:</b> <br>
Although the function itself is designed non-blocking, the assigned DbLog device should Although the function itself is designed non-blocking, the assigned DbLog device should
operated in asynchronous mode to avoid blocking of FHEMWEB (table lock). <br> operated in asynchronous mode to avoid blocking of FHEMWEB (table lock). <br>
@ -16251,13 +16266,18 @@ return;
<b>Arbeitsweise ohne Optionsangabe </b> <br><br> <b>Arbeitsweise ohne Optionsangabe </b> <br><br>
Sind keine Optionen angegeben, werden die Daten innerhalb der durch die <b>time.*</b>-Attribute bestimmten Es werden die Daten innerhalb der durch die <b>time.*</b>-Attribute bestimmten
Zeitgrenzen auf einen Eintrag (den ersten) pro Stunde je Device & Reading reduziert. Zeitgrenzen auf einen Eintrag (den ersten) pro Stunde je Device & Reading reduziert.
Es muss mindestens eines der <b>time.*</b>-Attribute gesetzt sein (siehe Tabelle unten). Es muss mindestens eines der <b>time.*</b>-Attribute gesetzt sein (siehe Tabelle unten).
Die FullDay-Option (es werden immer volle Tage selektiert) wird impliziert verwendet. Die FullDay-Option (es werden immer volle Tage selektiert) wird impliziert verwendet.
Die jeweils fehlende Zeitabgrenzung wird in diesem Fall durch das Modul errechnet. Die jeweils fehlende Zeitabgrenzung wird in diesem Fall durch das Modul errechnet.
<br><br> <br><br>
Durch die optionale Angabe von <b>average</b> wird nicht nur die Datenbank bereinigt, sondern
alle numerischen Werte einer Stunde werden auf einen einzigen Mittelwert reduziert.
Mit der Option <b>average=day</b> werden alle numerischen Werte eines Tages auf einen einzigen
Mittelwert reduziert (impliziert 'average'). <br><br>
Mit den Attributen <b>device</b> und <b>reading</b> können die zu berücksichtigenden Datensätze eingeschlossen Mit den Attributen <b>device</b> und <b>reading</b> können die zu berücksichtigenden Datensätze eingeschlossen
bzw. ausgeschlossen werden. Beide Eingrenzungen reduzieren die selektierten Daten und verringern den bzw. ausgeschlossen werden. Beide Eingrenzungen reduzieren die selektierten Daten und verringern den
Ressourcenbedarf. Ressourcenbedarf.
@ -16283,30 +16303,30 @@ return;
<b>Beispiele: </b><br><br> <b>Beispiele: </b><br><br>
<ul> <ul>
attr &lt;name&gt; timeOlderThan = d:200 <br> attr &lt;name&gt; timeOlderThan d:200 <br>
set &lt;name&gt; reduceLog <br> set &lt;name&gt; reduceLog <br>
# Datensätze die älter als 200 Tage sind, werden auf den ersten Eintrag pro Stunde je Device & Reading # Datensätze die älter als 200 Tage sind, werden auf den ersten Eintrag pro Stunde je Device & Reading
reduziert. <br> reduziert. <br>
<br> <br>
attr &lt;name&gt; timeDiffToNow = d:200 <br> attr &lt;name&gt; timeDiffToNow d:200 <br>
set &lt;name&gt; reduceLog average=day <br> set &lt;name&gt; reduceLog average=day <br>
# Datensätze die neuer als 200 Tage sind, werden auf einen Eintrag pro Tag je Device & Reading # Datensätze die neuer als 200 Tage sind, werden auf einen Eintrag pro Tag je Device & Reading
reduziert. <br> reduziert. <br>
<br> <br>
attr &lt;name&gt; timeDiffToNow = d:30 <br> attr &lt;name&gt; timeDiffToNow d:30 <br>
attr &lt;name&gt; device = TYPE=SONOSPLAYER EXCLUDE=Sonos_Kueche <br> attr &lt;name&gt; device TYPE=SONOSPLAYER EXCLUDE=Sonos_Kueche <br>
attr &lt;name&gt; reading = room% EXCLUDE=roomNameAlias <br> attr &lt;name&gt; reading room% EXCLUDE=roomNameAlias <br>
set &lt;name&gt; reduceLog <br> set &lt;name&gt; reduceLog <br>
# Datensätze die neuer als 30 Tage sind, die Devices vom Typ SONOSPLAYER sind # 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"), (außer Device "Sonos_Kueche"), die Readings mit "room" beginnen (außer "roomNameAlias"),
werden auf den ersten Eintrag pro Stunde je Device & Reading reduziert. <br> werden auf den ersten Eintrag pro Stunde je Device & Reading reduziert. <br>
<br> <br>
attr &lt;name&gt; timeDiffToNow = d:10 <br> attr &lt;name&gt; timeDiffToNow d:10 <br>
attr &lt;name&gt; timeOlderThan = d:5 <br> attr &lt;name&gt; timeOlderThan d:5 <br>
attr &lt;name&gt; device = Luftdaten_remote <br> attr &lt;name&gt; device Luftdaten_remote <br>
set &lt;name&gt; reduceLog average <br> set &lt;name&gt; reduceLog average <br>
# Datensätze die älter als 5 und neuer als 10 Tage sind und DEVICE "Luftdaten_remote" enthalten, # 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 <br> werden bereinigt. Numerische Werte einer Stunde werden auf einen Mittelwert reduziert <br>
@ -16325,7 +16345,17 @@ return;
Die Zusätze "EXCLUDE" bzw. "INCLUDE" können ergänzt werden um device/reading Kombinationen von reduceLog auszuschließen 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" 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. <br><br> und "reading", die in diesem Fall nicht beachtet werden.
<br><br>
<b>Beispiele: </b><br><br>
<ul>
set &lt;name&gt; reduceLog 174:180 average EXCLUDE=SMA_Energymeter:Bezug_Wirkleistung INCLUDE=SMA_Energymeter:% <br>
# Datensätze älter als 174 und neuer als 180 Tage werden auf den Durchschnitt pro Stunde reduziert. <br>
# Es werden alle Readings vom Device "SMA_Energymeter" außer "Bezug_Wirkleistung" berücksichtigt.
reduziert. <br>
</ul>
<br>
<b>Hinweis:</b> <br> <b>Hinweis:</b> <br>
Obwohl die Funktion selbst non-blocking ausgelegt ist, sollte das zugeordnete DbLog-Device Obwohl die Funktion selbst non-blocking ausgelegt ist, sollte das zugeordnete DbLog-Device
@ -16334,6 +16364,7 @@ return;
Weiterhin wird dringend empfohlen den standard INDEX 'Search_Idx' in der Tabelle 'history' Weiterhin wird dringend empfohlen den standard INDEX 'Search_Idx' in der Tabelle 'history'
anzulegen ! <br> anzulegen ! <br>
Die Abarbeitung dieses Befehls dauert unter Umständen (ohne INDEX) extrem lange. <br><br> Die Abarbeitung dieses Befehls dauert unter Umständen (ohne INDEX) extrem lange. <br><br>
</li> <br> </li> <br>
<li><b> repairSQLite </b> - repariert eine korrupte SQLite-Datenbank. <br> <li><b> repairSQLite </b> - repariert eine korrupte SQLite-Datenbank. <br>