93_DbLog: contrib 4.8.0

git-svn-id: https://svn.fhem.de/fhem/trunk@20335 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
DS_Starter
2019-10-08 20:51:34 +00:00
parent 7d5de76add
commit cf8f3f04bb

View File

@@ -1,5 +1,5 @@
############################################################################################################################################ ############################################################################################################################################
# $Id: 93_DbLog.pm 20114 2019-09-06 11:21:03Z DS_Starter $ # $Id: 93_DbLog.pm 20329 2019-10-07 22:34:08Z DS_Starter $
# #
# 93_DbLog.pm # 93_DbLog.pm
# written by Dr. Boris Neubert 2007-12-30 # written by Dr. Boris Neubert 2007-12-30
@@ -30,7 +30,10 @@ no if $] >= 5.017011, warnings => 'experimental::smartmatch';
# Version History intern by DS_Starter: # Version History intern by DS_Starter:
our %DbLog_vNotesIntern = ( our %DbLog_vNotesIntern = (
"4.7.4" => "03.10.2019 bugfix test of TIMESTAMP got from DbLogValueFn or valueFn in DbLog_Log and DbLog_AddLog", "4.8.0" => "08.10.2019 change SQL-Statement for delta-h, delta-d (SVG getter) ",
"4.7.5" => "07.10.2019 fix warning \"error valueFn: Global symbol \$CN requires ...\" in DbLog_addCacheLine ".
"enhanced configCheck by insert mode check ",
"4.7.4" => "03.10.2019 bugfix test of TIMESTAMP got from DbLogValueFn or valueFn in DbLog_Log and DbLog_AddLog ",
"4.7.3" => "02.10.2019 improved log out entries of DbLog_Get for SVG ", "4.7.3" => "02.10.2019 improved log out entries of DbLog_Get for SVG ",
"4.7.2" => "28.09.2019 change cache from %defs to %data ", "4.7.2" => "28.09.2019 change cache from %defs to %data ",
"4.7.1" => "10.09.2019 release the memcache memory: https://www.effectiveperlprogramming.com/2018/09/undef-a-scalar-to-release-its-memory/ in asynchron mode: https://www.effectiveperlprogramming.com/2018/09/undef-a-scalar-to-release-its-memory/ ", "4.7.1" => "10.09.2019 release the memcache memory: https://www.effectiveperlprogramming.com/2018/09/undef-a-scalar-to-release-its-memory/ in asynchron mode: https://www.effectiveperlprogramming.com/2018/09/undef-a-scalar-to-release-its-memory/ ",
@@ -2144,7 +2147,7 @@ sub DbLog_execmemcache ($) {
Log3 $hash->{NAME}, 5, "DbLog $name -> MemCache contains: ".$data{DbLog}{$name}{cache}{memcache}{$key}; Log3 $hash->{NAME}, 5, "DbLog $name -> MemCache contains: ".$data{DbLog}{$name}{cache}{memcache}{$key};
push(@row_array, delete($data{DbLog}{$name}{cache}{memcache}{$key})); push(@row_array, delete($data{DbLog}{$name}{cache}{memcache}{$key}));
} }
delete $data{DbLog}{$name}{cache}{memcache}; # sicherheitshalber Memory freigeben: https://www.effectiveperlprogramming.com/2018/09/undef-a-scalar-to-release-its-memory/ delete $data{DbLog}{$name}{cache}{memcache}; # sicherheitshalber Memory freigeben: https://perlmaven.com/undef-on-perl-arrays-and-hashes, bzw. https://www.effectiveperlprogramming.com/2018/09/undef-a-scalar-to-release-its-memory/
my $rowlist = join('§', @row_array); my $rowlist = join('§', @row_array);
$rowlist = encode_base64($rowlist,""); $rowlist = encode_base64($rowlist,"");
@@ -3214,10 +3217,34 @@ sub DbLog_Get($@) {
$deltacalc = 1; $deltacalc = 1;
} }
my $stm; my ($stm);
my $stm2; if($deltacalc) {
my $stmdelta; # delta-h und delta-d
$stm = "SELECT $stm = "SELECT Z.TIMESTAMP, Z.DEVICE, Z.READING, Z.VALUE from ";
$stm .= "(SELECT $sqlspec{get_timestamp} AS TIMESTAMP,
DEVICE AS DEVICE,
READING AS READING,
VALUE AS VALUE ";
$stm .= "FROM $current " if($inf eq "current");
$stm .= "FROM $history " if($inf eq "history");
$stm .= "WHERE 1=1 ";
$stm .= "AND DEVICE = '".$readings[$i]->[0]."' " if ($readings[$i]->[0] !~ m(\%));
$stm .= "AND DEVICE LIKE '".$readings[$i]->[0]."' " if(($readings[$i]->[0] !~ m(^\%$)) && ($readings[$i]->[0] =~ m(\%)));
$stm .= "AND READING = '".$readings[$i]->[1]."' " if ($readings[$i]->[1] !~ m(\%));
$stm .= "AND READING LIKE '".$readings[$i]->[1]."' " if(($readings[$i]->[1] !~ m(^%$)) && ($readings[$i]->[1] =~ m(\%)));
$stm .= "AND TIMESTAMP < $sqlspec{from_timestamp} ";
$stm .= "AND TIMESTAMP > $sqlspec{day_before} ";
$stm .= "ORDER BY TIMESTAMP DESC LIMIT 1 ) AS Z
UNION ALL ";
$stm .= "SELECT
MAX($sqlspec{get_timestamp}) AS TIMESTAMP, MAX($sqlspec{get_timestamp}) AS TIMESTAMP,
MAX(DEVICE) AS DEVICE, MAX(DEVICE) AS DEVICE,
MAX(READING) AS READING, MAX(READING) AS READING,
@@ -3235,47 +3262,38 @@ sub DbLog_Get($@) {
$stm .= "AND READING = '".$readings[$i]->[1]."' " if ($readings[$i]->[1] !~ m(\%)); $stm .= "AND READING = '".$readings[$i]->[1]."' " if ($readings[$i]->[1] !~ m(\%));
$stm .= "AND READING LIKE '".$readings[$i]->[1]."' " if(($readings[$i]->[1] !~ m(^%$)) && ($readings[$i]->[1] =~ m(\%))); $stm .= "AND READING LIKE '".$readings[$i]->[1]."' " if(($readings[$i]->[1] !~ m(^%$)) && ($readings[$i]->[1] =~ m(\%)));
$stmdelta = $stm; $stm .= "AND TIMESTAMP >= $sqlspec{from_timestamp} ";
$stm .= "AND TIMESTAMP <= $sqlspec{to_timestamp} "; # 03.09.2018 : https://forum.fhem.de/index.php/topic,65860.msg815640.html#msg815640
$stm .= "AND TIMESTAMP < $sqlspec{from_timestamp} "; $stm .= "GROUP BY $sqlspec{order_by_hour} " if($deltacalc);
$stm .= "AND TIMESTAMP > $sqlspec{day_before} "; $stm .= "ORDER BY TIMESTAMP";
$stm .= "UNION ALL "; } else {
# kein delta
$stm2 = "SELECT $stm = "SELECT
$sqlspec{get_timestamp}, $sqlspec{get_timestamp},
DEVICE, DEVICE,
READING, READING,
VALUE VALUE
$sqlspec{all} "; $sqlspec{all} ";
$stm2 .= "FROM $current " if($inf eq "current"); $stm .= "FROM $current " if($inf eq "current");
$stm2 .= "FROM $history " if($inf eq "history"); $stm .= "FROM $history " if($inf eq "history");
$stm2 .= "WHERE 1=1 "; $stm .= "WHERE 1=1 ";
$stm2 .= "AND DEVICE = '".$readings[$i]->[0]."' " if ($readings[$i]->[0] !~ m(\%)); $stm .= "AND DEVICE = '".$readings[$i]->[0]."' " if ($readings[$i]->[0] !~ m(\%));
$stm2 .= "AND DEVICE LIKE '".$readings[$i]->[0]."' " if(($readings[$i]->[0] !~ m(^\%$)) && ($readings[$i]->[0] =~ m(\%))); $stm .= "AND DEVICE LIKE '".$readings[$i]->[0]."' " if(($readings[$i]->[0] !~ m(^\%$)) && ($readings[$i]->[0] =~ m(\%)));
$stm2 .= "AND READING = '".$readings[$i]->[1]."' " if ($readings[$i]->[1] !~ m(\%)); $stm .= "AND READING = '".$readings[$i]->[1]."' " if ($readings[$i]->[1] !~ m(\%));
$stm2 .= "AND READING LIKE '".$readings[$i]->[1]."' " if(($readings[$i]->[1] !~ m(^%$)) && ($readings[$i]->[1] =~ m(\%))); $stm .= "AND READING LIKE '".$readings[$i]->[1]."' " if(($readings[$i]->[1] !~ m(^%$)) && ($readings[$i]->[1] =~ m(\%)));
$stm2 .= "AND TIMESTAMP >= $sqlspec{from_timestamp} "; $stm .= "AND TIMESTAMP >= $sqlspec{from_timestamp} ";
$stm2 .= "AND TIMESTAMP <= $sqlspec{to_timestamp} "; # 03.09.2018 : https://forum.fhem.de/index.php/topic,65860.msg815640.html#msg815640 $stm .= "AND TIMESTAMP <= $sqlspec{to_timestamp} "; # 03.09.2018 : https://forum.fhem.de/index.php/topic,65860.msg815640.html#msg815640
$stm2 .= "ORDER BY TIMESTAMP"; $stm .= "ORDER BY TIMESTAMP";
if($deltacalc) {
$stmdelta .= "AND TIMESTAMP >= $sqlspec{from_timestamp} ";
$stmdelta .= "AND TIMESTAMP <= $sqlspec{to_timestamp} "; # 03.09.2018 : https://forum.fhem.de/index.php/topic,65860.msg815640.html#msg815640
$stmdelta .= "GROUP BY $sqlspec{order_by_hour} " if($deltacalc);
$stmdelta .= "ORDER BY TIMESTAMP";
$stm .= $stmdelta;
} else {
$stm = $stm2;
} }
Log3 ($name, 4, "$name - Processing Statement: $stm"); Log3 ($name, 4, "$name - Processing Statement:\n$stm");
my $sth = $dbh->prepare($stm) || return "Cannot prepare statement $stm: $DBI::errstr"; my $sth = $dbh->prepare($stm) || return "Cannot prepare statement $stm: $DBI::errstr";
my $rc = $sth->execute() || return "Cannot execute statement $stm: $DBI::errstr"; my $rc = $sth->execute() || return "Cannot execute statement $stm: $DBI::errstr";
@@ -3315,17 +3333,10 @@ sub DbLog_Get($@) {
#evaluate #evaluate
my $val = $sql_value; my $val = $sql_value;
my $ts = $sql_timestamp; my $ts = $sql_timestamp;
no warnings 'uninitialized';
eval("$readings[$i]->[4]"); eval("$readings[$i]->[4]");
if($@) {
Log3 $hash->{NAME}, 3, "DbLog: Error in inline function: <".$readings[$i]->[4].">, Error: $@";
} else {
$sql_value = $val; $sql_value = $val;
$sql_timestamp = $ts; $sql_timestamp = $ts;
} if($@) {Log3 $hash->{NAME}, 3, "DbLog: Error in inline function: <".$readings[$i]->[4].">, Error: $@";}
$ds = "TS: $sql_timestamp, DEV: $sql_device, RD: $sql_reading, VAL: $sql_value";
Log3 ($name, 5, "$name - Result after Regex -> $ds");
use warnings;
} }
if($sql_timestamp lt $from && $deltacalc) { if($sql_timestamp lt $from && $deltacalc) {
@@ -3734,6 +3745,7 @@ sub DbLog_configcheck($) {
### Check Betriebsmodus ### Check Betriebsmodus
####################################################################### #######################################################################
my $mode = $hash->{MODE}; my $mode = $hash->{MODE};
my $bi = AttrVal($name, "bulkInsert", 0);
my $sfx = AttrVal("global", "language", "EN"); my $sfx = AttrVal("global", "language", "EN");
$sfx = ($sfx eq "EN" ? "" : "_$sfx"); $sfx = ($sfx eq "EN" ? "" : "_$sfx");
@@ -3754,6 +3766,19 @@ sub DbLog_configcheck($) {
} }
$check .= "<b>Recommendation:</b> $rec <br><br>"; $check .= "<b>Recommendation:</b> $rec <br><br>";
$check .= "<u><b>Result of insert mode check</u></b><br><br>";
if(!$bi) {
$bi = "Array";
$check .= "Insert mode of DbLog-device $name is: $bi <br>";
$rec = "Setting attribute \"bulkInsert\" to \"1\" may result a higher write performance in most cases. ";
$rec .= "Feel free to try this mode.";
} else {
$bi = "Bulk";
$check .= "Insert mode of DbLog-device $name is: $bi <br>";
$rec = "settings o.k.";
}
$check .= "<b>Recommendation:</b> $rec <br><br>";
### Check Plot Erstellungsmodus ### Check Plot Erstellungsmodus
####################################################################### #######################################################################
$check .= "<u><b>Result of plot generation method check</u></b><br><br>"; $check .= "<u><b>Result of plot generation method check</u></b><br><br>";
@@ -4492,6 +4517,7 @@ sub DbLog_addCacheLine($$$$$$$$) {
my $VALUE = $i_val; my $VALUE = $i_val;
my $UNIT = $i_unit; my $UNIT = $i_unit;
my $IGNORE = 0; my $IGNORE = 0;
my $CN = " ";
eval $value_fn; eval $value_fn;
Log3 $name, 2, "DbLog $name -> error valueFn: ".$@ if($@); Log3 $name, 2, "DbLog $name -> error valueFn: ".$@ if($@);
@@ -5933,12 +5959,12 @@ sub DbLog_setVersionInfo($) {
if($modules{$type}{META}{x_prereqs_src} && !$hash->{HELPER}{MODMETAABSENT}) { if($modules{$type}{META}{x_prereqs_src} && !$hash->{HELPER}{MODMETAABSENT}) {
# META-Daten sind vorhanden # META-Daten sind vorhanden
$modules{$type}{META}{version} = "v".$v; # Version aus META.json überschreiben, Anzeige mit {Dumper $modules{DbLog}{META}} $modules{$type}{META}{version} = "v".$v; # Version aus META.json überschreiben, Anzeige mit {Dumper $modules{DbLog}{META}}
if($modules{$type}{META}{x_version}) { # {x_version} ( nur gesetzt wenn $Id: 93_DbLog.pm 20114 2019-09-06 11:21:03Z DS_Starter $ im Kopf komplett! vorhanden ) if($modules{$type}{META}{x_version}) { # {x_version} ( nur gesetzt wenn $Id: 93_DbLog.pm 20329 2019-10-07 22:34:08Z DS_Starter $ im Kopf komplett! vorhanden )
$modules{$type}{META}{x_version} =~ s/1.1.1/$v/g; $modules{$type}{META}{x_version} =~ s/1.1.1/$v/g;
} else { } else {
$modules{$type}{META}{x_version} = $v; $modules{$type}{META}{x_version} = $v;
} }
return $@ unless (FHEM::Meta::SetInternals($hash)); # FVERSION wird gesetzt ( nur gesetzt wenn $Id: 93_DbLog.pm 20114 2019-09-06 11:21:03Z DS_Starter $ im Kopf komplett! vorhanden ) return $@ unless (FHEM::Meta::SetInternals($hash)); # FVERSION wird gesetzt ( nur gesetzt wenn $Id: 93_DbLog.pm 20329 2019-10-07 22:34:08Z DS_Starter $ im Kopf komplett! vorhanden )
if(__PACKAGE__ eq "FHEM::$type" || __PACKAGE__ eq $type) { if(__PACKAGE__ eq "FHEM::$type" || __PACKAGE__ eq $type) {
# es wird mit Packages gearbeitet -> Perl übliche Modulversion setzen # es wird mit Packages gearbeitet -> Perl übliche Modulversion setzen
# mit {<Modul>->VERSION()} im FHEMWEB kann Modulversion abgefragt werden # mit {<Modul>->VERSION()} im FHEMWEB kann Modulversion abgefragt werden
@@ -6889,6 +6915,7 @@ attr SMA_Energymeter DbLogValueFn
} }
if ($READING =~ /Einspeisung_Wirkleistung_Zaehler/ && $VALUE < 2){ if ($READING =~ /Einspeisung_Wirkleistung_Zaehler/ && $VALUE < 2){
$IGNORE=1; $IGNORE=1;
}
} }
</pre> </pre>
</ul> </ul>
@@ -8248,6 +8275,7 @@ attr SMA_Energymeter DbLogValueFn
} }
if ($READING =~ /Einspeisung_Wirkleistung_Zaehler/ && $VALUE < 2){ if ($READING =~ /Einspeisung_Wirkleistung_Zaehler/ && $VALUE < 2){
$IGNORE=1; $IGNORE=1;
}
} }
</pre> </pre>
</ul> </ul>