mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-01-31 12:49:34 +00:00
93_DbLog: its now version 2.10.4, some improvements and new
attributes git-svn-id: https://svn.fhem.de/fhem/trunk@13193 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
ee1663568e
commit
52edb81980
@ -1,5 +1,7 @@
|
||||
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
||||
# Do not insert empty lines here, update check depends on it.
|
||||
- update: 93_DbLog: its now version 2.10.4, some improvements and new
|
||||
attributes
|
||||
- update: 74_XiaomiFlowerSens: 0.6.0 rewrite subroutinen for better handling
|
||||
- bugfix: 88_HMCCU.pm: fixed default attributes
|
||||
- update: 98_DOIFtools.pm: filter mentioned in event report
|
||||
|
@ -1,4 +1,4 @@
|
||||
############################################################################################################################
|
||||
################################################################################################################################
|
||||
# $Id$
|
||||
#
|
||||
# 93_DbLog.pm
|
||||
@ -10,9 +10,16 @@
|
||||
#
|
||||
# reduceLog() created by Claudiu Schuster (rapster)
|
||||
#
|
||||
############################################################################################################################
|
||||
################################################################################################################################
|
||||
# Versions History done by DS_Starter:
|
||||
#
|
||||
# 2.10.4 22.01.2017 new sub setinternalcols, new attributes colEvent, colReading, colValue
|
||||
# 2.10.3 21.01.2017 query of cacheEvents changed, attr timeout adjustable
|
||||
# 2.10.2 19.01.2017 DbLog_reduceLog now use DbLog_ConnectNewDBH -> makes start of DbLog_reduceLog stable
|
||||
# 2.10.1 19.01.2017 commandref edited, cache events don't get lost even if other errors than "db not available" occure
|
||||
# 2.10 18.10.2017 new attribute cacheLimit, showNotifyTime
|
||||
# 2.9.3 17.01.2017 new sub DbLog_ConnectNewDBH (own new dbh for separate use in functions except logging functions),
|
||||
# DbLog_sampleDataFn, dbReadings now use DbLog_ConnectNewDBH
|
||||
# 2.9.2 16.01.2017 new bugfix for SQLite issue SVGs, DbLog_Log changed to $dev_hash->{CHANGETIME}, DbLog_Push
|
||||
# changed (db handle new separated)
|
||||
# 2.9.1 14.01.2017 changed DbLog_ParseEvent to CallInstanceFn, renamed flushCache to purgeCache,
|
||||
@ -62,7 +69,7 @@ use Data::Dumper;
|
||||
use Blocking;
|
||||
use Time::HiRes qw(gettimeofday tv_interval);
|
||||
|
||||
my $DbLogVersion = "2.9.2";
|
||||
my $DbLogVersion = "2.10.4";
|
||||
|
||||
my %columns = ("DEVICE" => 64,
|
||||
"TYPE" => 64,
|
||||
@ -87,7 +94,10 @@ sub DbLog_Initialize($)
|
||||
$hash->{AttrFn} = "DbLog_Attr";
|
||||
$hash->{SVG_regexpFn} = "DbLog_regexpFn";
|
||||
$hash->{ShutdownFn} = "DbLog_Shutdown";
|
||||
$hash->{AttrList} = "disable:1,0 ".
|
||||
$hash->{AttrList} = "colEvent ".
|
||||
"colReading ".
|
||||
"colValue ".
|
||||
"disable:1,0 ".
|
||||
"DbLogType:Current,History,Current/History ".
|
||||
"shutdownWait ".
|
||||
"suppressUndef:0,1 ".
|
||||
@ -98,7 +108,10 @@ sub DbLog_Initialize($)
|
||||
"showproctime:1,0 ".
|
||||
"asyncMode:1,0 ".
|
||||
"cacheEvents:2,1,0 ".
|
||||
"cacheLimit ".
|
||||
"syncEvents:1,0 ".
|
||||
"showNotifyTime:1,0 ".
|
||||
"timeout " .
|
||||
"DbLogSelectionMode:Exclude,Include,Exclude/Include ".
|
||||
$readingFnAttributes;
|
||||
|
||||
@ -154,6 +167,9 @@ sub DbLog_Define($@)
|
||||
my $ret = _DbLog_readCfg($hash);
|
||||
return $ret if ($ret); # return on error while reading configuration
|
||||
|
||||
# set used COLUMNS in Internals
|
||||
setinternalcols($hash);
|
||||
|
||||
readingsSingleUpdate($hash, 'state', 'waiting for connection', 1);
|
||||
eval { DbLog_Connect($hash); };
|
||||
if($hash->{DBMODEL} eq "MYSQL") {
|
||||
@ -206,11 +222,18 @@ sub DbLog_Attr(@) {
|
||||
my $do = 0;
|
||||
|
||||
if($cmd eq "set") {
|
||||
if ($aName eq "syncInterval") {
|
||||
unless ($aVal =~ /^[0-9]+$/) { return " The Value of $aVal is not valid. Use only figures 1-9 !";}
|
||||
if ($aName eq "syncInterval" || $aName eq "cacheLimit" || $aName eq "timeout") {
|
||||
unless ($aVal =~ /^[0-9]+$/) { return " The Value of $aName is not valid. Use only figures 0-9 !";}
|
||||
}
|
||||
}
|
||||
|
||||
if($aName eq "colEvent" || $aName eq "colReading" || $aName eq "colValue") {
|
||||
if ($cmd eq "set" && $aVal) {
|
||||
unless ($aVal =~ /^[0-9]+$/) { return " The Value of $aName is not valid. Use only figures 0-9 !";}
|
||||
}
|
||||
InternalTimer(gettimeofday()+2, "setinternalcols", $hash, 0);
|
||||
}
|
||||
|
||||
if($aName eq "asyncMode") {
|
||||
if ($cmd eq "set" && $aVal) {
|
||||
$hash->{MODE} = "asynchronous";
|
||||
@ -232,6 +255,12 @@ sub DbLog_Attr(@) {
|
||||
}
|
||||
}
|
||||
|
||||
if($aName eq "showNotifyTime") {
|
||||
if ($cmd ne "set" || !$aVal) {
|
||||
delete($defs{$name}{READINGS}{notify_processing_time});
|
||||
}
|
||||
}
|
||||
|
||||
if($aName eq "noNotifyDev") {
|
||||
my $regexp = $hash->{REGEXP};
|
||||
if ($cmd eq "set" && $aVal) {
|
||||
@ -272,11 +301,6 @@ sub DbLog_Set($@) {
|
||||
my $ret;
|
||||
|
||||
if ($a[1] eq 'reduceLog') {
|
||||
if ( !$dbh || not $dbh->ping ) {
|
||||
Log3($name, 1, "DbLog $name: DBLog_Set - reduceLog - DB Session dead, try to reopen now !");
|
||||
DbLog_Connect($hash);
|
||||
}
|
||||
else {
|
||||
if (defined $a[2] && $a[2] =~ /^\d+$/) {
|
||||
$ret = DbLog_reduceLog($hash,@a);
|
||||
InternalTimer(gettimeofday()+5, "DbLog_execmemcache", $hash, 0);
|
||||
@ -285,7 +309,6 @@ sub DbLog_Set($@) {
|
||||
$ret = "reduceLog error, no <days> given.";
|
||||
}
|
||||
}
|
||||
}
|
||||
elsif ($a[1] eq 'reopen') {
|
||||
Log3($name, 4, "DbLog $name: Reopen requested.");
|
||||
|
||||
@ -293,8 +316,11 @@ sub DbLog_Set($@) {
|
||||
$dbh->commit() if(!$dbh->{AutoCommit});
|
||||
$dbh->disconnect();
|
||||
}
|
||||
|
||||
DbLog_Connect($hash);
|
||||
if($hash->{DBMODEL} eq "MYSQL") {
|
||||
# eigenes db-handle bhp für MySQL wegen Error "MySQL-Server has gone"
|
||||
DbLog_ConnectPush($hash);
|
||||
}
|
||||
$ret = "Reopen executed.";
|
||||
}
|
||||
elsif ($a[1] eq 'rereadcfg') {
|
||||
@ -304,10 +330,13 @@ sub DbLog_Set($@) {
|
||||
$dbh->commit() if(!$dbh->{AutoCommit});
|
||||
$dbh->disconnect();
|
||||
}
|
||||
|
||||
$ret = _DbLog_readCfg($hash);
|
||||
return $ret if $ret;
|
||||
DbLog_Connect($hash);
|
||||
if($hash->{DBMODEL} eq "MYSQL") {
|
||||
# eigenes db-handle bhp für MySQL wegen Error "MySQL-Server has gone"
|
||||
DbLog_ConnectPush($hash);
|
||||
}
|
||||
$ret = "Rereadcfg executed.";
|
||||
}
|
||||
elsif ($a[1] eq 'purgeCache') {
|
||||
@ -700,9 +729,15 @@ sub DbLog_Log($$) {
|
||||
my $dev_name = $dev_hash->{NAME};
|
||||
my $dev_type = uc($dev_hash->{TYPE});
|
||||
my $async = AttrVal($name, "asyncMode", undef);
|
||||
my $clim = AttrVal($name, "cacheLimit", 500);
|
||||
my $ce = AttrVal($name, "cacheEvents", 0);
|
||||
my $net;
|
||||
|
||||
return if(IsDisabled($name) || $init_done != 1);
|
||||
|
||||
# Notify-Routine Startzeit
|
||||
my $nst = [gettimeofday];
|
||||
|
||||
my $events = deviceEvents($dev_hash,0);
|
||||
return if(!$events);
|
||||
|
||||
@ -854,12 +889,18 @@ sub DbLog_Log($$) {
|
||||
$hash->{cache}{memcache}{$index} = $row;
|
||||
|
||||
my $memcount = $hash->{cache}{memcache}?scalar(keys%{$hash->{cache}{memcache}}):0;
|
||||
if(AttrVal($name, "cacheEvents", undef) && AttrVal($name, "cacheEvents", undef) == 1) {
|
||||
readingsSingleUpdate($hash, "CacheUsage", $memcount, 1)
|
||||
if($ce == 1) {
|
||||
readingsSingleUpdate($hash, "CacheUsage", $memcount, 1);
|
||||
} else {
|
||||
readingsSingleUpdate($hash, "CacheUsage", $memcount, 0)
|
||||
readingsSingleUpdate($hash, 'CacheUsage', $memcount, 0);
|
||||
}
|
||||
|
||||
# asynchrone Schreibroutine aufrufen wenn Füllstand des Cache erreicht ist
|
||||
if($memcount >= $clim) {
|
||||
Log3 $hash->{NAME}, 5, "DbLog $name -> Number of cache entries reached cachelimit $clim - start database sync.";
|
||||
DbLog_execmemcache($hash);
|
||||
}
|
||||
# Notify-Routine Laufzeit ermitteln
|
||||
$net = tv_interval($nst);
|
||||
} else {
|
||||
# synchoner Mode
|
||||
push(@row_array, $row);
|
||||
@ -878,8 +919,13 @@ sub DbLog_Log($$) {
|
||||
} else {
|
||||
readingsSingleUpdate($hash, "state", "connected", 0);
|
||||
}
|
||||
# Notify-Routine Laufzeit ermitteln
|
||||
$net = tv_interval($nst);
|
||||
}
|
||||
}
|
||||
if($net && AttrVal($name, "showNotifyTime", undef)) {
|
||||
readingsSingleUpdate($hash, "notify_processing_time", sprintf("%.4f",$net), 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -908,6 +954,8 @@ sub DbLog_Push(@) {
|
||||
if ($@) {
|
||||
Log3($name, 1, "DbLog $name: DBLog_Push - DB Session dead! - $@");
|
||||
return $@;
|
||||
} else {
|
||||
$dbh = $hash->{DBH};
|
||||
}
|
||||
}
|
||||
if($hash->{DBMODEL} eq "MYSQL") {
|
||||
@ -1073,11 +1121,13 @@ sub DbLog_execmemcache ($) {
|
||||
my ($hash) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $syncival = AttrVal($name, "syncInterval", 30);
|
||||
my $clim = AttrVal($name, "cacheLimit", 500);
|
||||
my $async = AttrVal($name, "asyncMode", undef);
|
||||
my $ce = AttrVal($name, "cacheEvents", 0);
|
||||
my $timeout = AttrVal($name, "timeout", 120);
|
||||
my $dbconn = $hash->{dbconn};
|
||||
my $dbuser = $hash->{dbuser};
|
||||
my $dbpassword = $attr{"sec$name"}{secret};
|
||||
my $timeout = 60;
|
||||
my $state = "connected";
|
||||
my $error = 0;
|
||||
my (@row_array,$memcount,$dbh);
|
||||
@ -1108,12 +1158,12 @@ sub DbLog_execmemcache ($) {
|
||||
} else {
|
||||
# Testverbindung abbauen
|
||||
$dbh->disconnect();
|
||||
$memcount = $hash->{cache}{memcache}?scalar(keys%{$hash->{cache}{memcache}}):0;
|
||||
|
||||
if(AttrVal($name, "cacheEvents", undef) && AttrVal($name, "cacheEvents", undef) == 2) {
|
||||
readingsSingleUpdate($hash, "CacheUsage", $memcount, 1)
|
||||
$memcount = $hash->{cache}{memcache}?scalar(keys%{$hash->{cache}{memcache}}):0;
|
||||
if($ce == 2) {
|
||||
readingsSingleUpdate($hash, "CacheUsage", $memcount, 1);
|
||||
} else {
|
||||
readingsSingleUpdate($hash, "CacheUsage", $memcount, 0)
|
||||
readingsSingleUpdate($hash, 'CacheUsage', $memcount, 0);
|
||||
}
|
||||
|
||||
if($memcount && !$hash->{HELPER}{RUNNING_PID}) {
|
||||
@ -1152,9 +1202,9 @@ sub DbLog_execmemcache ($) {
|
||||
my $nsdt = FmtDateTime($nextsync);
|
||||
|
||||
if(AttrVal($name, "syncEvents", undef)) {
|
||||
readingsSingleUpdate($hash, "NextSync", $nsdt, 1);
|
||||
readingsSingleUpdate($hash, "NextSync", $nsdt. " or if CacheUsage ".$clim." reached", 1);
|
||||
} else {
|
||||
readingsSingleUpdate($hash, "NextSync", $nsdt, 0);
|
||||
readingsSingleUpdate($hash, "NextSync", $nsdt. " or if CacheUsage ".$clim." reached", 0);
|
||||
}
|
||||
|
||||
if($error) {
|
||||
@ -1184,6 +1234,7 @@ sub DbLog_PushAsync(@) {
|
||||
my $error = 0;
|
||||
my $doins = 0; # Hilfsvariable, wenn "1" sollen inserts in Tabelle current erfolgen (updates schlugen fehl)
|
||||
my $dbh;
|
||||
my $rowlback = 0; # Eventliste für Rückgabe wenn Fehler
|
||||
|
||||
Log3 ($name, 5, "DbLog $name -> Start DbLog_PushAsync");
|
||||
|
||||
@ -1199,8 +1250,8 @@ sub DbLog_PushAsync(@) {
|
||||
return "$name|$error|0|$rowlist";
|
||||
}
|
||||
|
||||
$rowlist = decode_base64($rowlist);
|
||||
my @row_array = split('§', $rowlist);
|
||||
my $rowldec = decode_base64($rowlist);
|
||||
my @row_array = split('§', $rowldec);
|
||||
|
||||
my (@timestamp,@device,@type,@event,@reading,@value,@unit);
|
||||
my (@timestamp_cur,@device_cur,@type_cur,@event_cur,@reading_cur,@value_cur,@unit_cur);
|
||||
@ -1224,7 +1275,14 @@ sub DbLog_PushAsync(@) {
|
||||
|
||||
if (lc($DbLogType) =~ m(history)) {
|
||||
# for insert history
|
||||
$sth_ih = $dbh->prepare("INSERT INTO history (TIMESTAMP, DEVICE, TYPE, EVENT, READING, VALUE, UNIT) VALUES (?,?,?,?,?,?,?)");
|
||||
eval { $sth_ih = $dbh->prepare("INSERT INTO history (TIMESTAMP, DEVICE, TYPE, EVENT, READING, VALUE, UNIT) VALUES (?,?,?,?,?,?,?)"); };
|
||||
if ($@) {
|
||||
# Eventliste zurückgeben wenn z.B. disk I/O error (SQLITE)
|
||||
$error = encode_base64($@,"");
|
||||
Log3 ($name, 2, "DbLog $name - Error: $@");
|
||||
Log3 ($name, 5, "DbLog $name -> DbLog_PushAsync finished");
|
||||
return "$name|$error|0|$rowlist";
|
||||
}
|
||||
$sth_ih->bind_param_array(1, [@timestamp]);
|
||||
$sth_ih->bind_param_array(2, [@device]);
|
||||
$sth_ih->bind_param_array(3, [@type]);
|
||||
@ -1236,8 +1294,14 @@ sub DbLog_PushAsync(@) {
|
||||
|
||||
if (lc($DbLogType) =~ m(current) ) {
|
||||
# for insert current
|
||||
$sth_ic = $dbh->prepare("INSERT INTO current (TIMESTAMP, DEVICE, TYPE, EVENT, READING, VALUE, UNIT) VALUES (?,?,?,?,?,?,?)");
|
||||
|
||||
eval { $sth_ic = $dbh->prepare("INSERT INTO current (TIMESTAMP, DEVICE, TYPE, EVENT, READING, VALUE, UNIT) VALUES (?,?,?,?,?,?,?)"); };
|
||||
if ($@) {
|
||||
# Eventliste zurückgeben wenn z.B. disk I/O error (SQLITE)
|
||||
$error = encode_base64($@,"");
|
||||
Log3 ($name, 2, "DbLog $name - Error: $@");
|
||||
Log3 ($name, 5, "DbLog $name -> DbLog_PushAsync finished");
|
||||
return "$name|$error|0|$rowlist";
|
||||
}
|
||||
# for update current
|
||||
$sth_uc = $dbh->prepare("UPDATE current SET TIMESTAMP=?, TYPE=?, EVENT=?, VALUE=?, UNIT=? WHERE (DEVICE=?) AND (READING=?)");
|
||||
$sth_uc->bind_param_array(1, [@timestamp]);
|
||||
@ -1328,6 +1392,7 @@ sub DbLog_PushAsync(@) {
|
||||
$dbh->rollback() if(!$dbh->{AutoCommit});
|
||||
$error = $@;
|
||||
$dbh->disconnect();
|
||||
$rowlback = $rowlist;
|
||||
}
|
||||
else {
|
||||
$dbh->commit() if(!$dbh->{AutoCommit});
|
||||
@ -1344,7 +1409,7 @@ sub DbLog_PushAsync(@) {
|
||||
|
||||
$rt = $rt.",".$brt;
|
||||
|
||||
return "$name|$error|$rt|0";
|
||||
return "$name|$error|$rt|$rowlback";
|
||||
}
|
||||
|
||||
#############################################################################################
|
||||
@ -1385,7 +1450,7 @@ sub DbLog_PushAsyncDone ($) {
|
||||
$memcount = $hash->{cache}{memcache}?scalar(keys%{$hash->{cache}{memcache}}):0;
|
||||
readingsSingleUpdate($hash, 'CacheUsage', $memcount, 0);
|
||||
|
||||
if(AttrVal($name, "showproctime", undef)) {
|
||||
if(AttrVal($name, "showproctime", undef) && $bt) {
|
||||
readingsBeginUpdate($hash);
|
||||
readingsBulkUpdate($hash, "background_processing_time", sprintf("%.4f",$brt));
|
||||
readingsBulkUpdate($hash, "sql_processing_time", sprintf("%.4f",$rt));
|
||||
@ -1402,6 +1467,7 @@ sub DbLog_PushAsyncDone ($) {
|
||||
delete($defs{$name}{READINGS}{NextSync});
|
||||
delete($defs{$name}{READINGS}{background_processing_time});
|
||||
delete($defs{$name}{READINGS}{sql_processing_time});
|
||||
delete($defs{$name}{READINGS}{CacheUsage});
|
||||
}
|
||||
|
||||
delete $hash->{HELPER}{RUNNING_PID};
|
||||
@ -1588,6 +1654,28 @@ sub DbLog_ConnectPush($) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub DbLog_ConnectNewDBH($) {
|
||||
# new dbh for every use (except DbLog_Push..)
|
||||
my ($hash)= @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $dbconn = $hash->{dbconn};
|
||||
my $dbuser = $hash->{dbuser};
|
||||
my $dbpassword = $attr{"sec$name"}{secret};
|
||||
my $dbh;
|
||||
|
||||
eval { $dbh = DBI->connect("dbi:$dbconn", $dbuser, $dbpassword, { PrintError => 0 }); };
|
||||
|
||||
if($@) {
|
||||
Log3($name, 2, "DbLog $name: - $@");
|
||||
}
|
||||
|
||||
if($dbh) {
|
||||
return $dbh;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
################################################################
|
||||
#
|
||||
# Prozeduren zum Ausfuehren des SQLs
|
||||
@ -2164,7 +2252,9 @@ DbLog_Get($@)
|
||||
sub DbLog_reduceLog($@) {
|
||||
my ($hash,@a) = @_;
|
||||
my ($ret,$cmd,$row,$filter,$exclude,$c,$day,$hour,$lastHour,$updDate,$updHour,$average,$processingDay,$lastUpdH,%hourlyKnown,%averageHash,@excludeRegex,@dayRows,@averageUpd,@averageUpdD);
|
||||
my ($dbh,$name,$startTime,$currentHour,$currentDay,$deletedCount,$updateCount,$sum,$rowCount,$excludeCount) = ($hash->{DBH},$hash->{NAME},time(),99,0,0,0,0,0,0);
|
||||
my ($name,$startTime,$currentHour,$currentDay,$deletedCount,$updateCount,$sum,$rowCount,$excludeCount) = ($hash->{NAME},time(),99,0,0,0,0,0,0);
|
||||
my $dbh = DbLog_ConnectNewDBH($hash);
|
||||
return if(!$dbh);
|
||||
|
||||
if ($a[-1] =~ /^EXCLUDE=(.+:.+)+/i) {
|
||||
($filter) = $a[-1] =~ /^EXCLUDE=(.+)/i;
|
||||
@ -2368,7 +2458,7 @@ sub DbLog_reduceLog($@) {
|
||||
readingsSingleUpdate($hash, 'lastReduceLogResult', $result ,1);
|
||||
$ret = "reduceLog executed. $result";
|
||||
}
|
||||
|
||||
$dbh->disconnect();
|
||||
return $ret;
|
||||
}
|
||||
|
||||
@ -2690,22 +2780,14 @@ DbLog_sampleDataFn($$$$$)
|
||||
my @example;
|
||||
my @colregs;
|
||||
my $counter;
|
||||
|
||||
# Fix keine Vorschlagswerte aus Current im asynchronen Mode
|
||||
my $hash = $defs{$dlName};
|
||||
my $dbh = $defs{$dlName}{DBH};
|
||||
eval {
|
||||
if ( !$dbh || not $dbh->ping ) {
|
||||
#### DB Session dead, try to reopen now !
|
||||
DbLog_Connect($hash);
|
||||
}
|
||||
};
|
||||
|
||||
my $currentPresent = AttrVal($dlName,'DbLogType','Current');
|
||||
|
||||
my $dbhf = DbLog_ConnectNewDBH($defs{$dlName});
|
||||
return if(!$dbhf);
|
||||
|
||||
if($currentPresent =~ m/Current/) {
|
||||
# Table Current present, use it for sample data
|
||||
|
||||
my $dbhf = $defs{$dlName}{DBHF};
|
||||
my $query = "select device,reading,value from current where device <> '' order by device,reading";
|
||||
my $sth = $dbhf->prepare( $query );
|
||||
$sth->execute();
|
||||
@ -2714,6 +2796,7 @@ DbLog_sampleDataFn($$$$$)
|
||||
push (@example, join (" ",@line)) if($counter <= 8); # show max 8 examples
|
||||
push (@colregs, "$line[0]:$line[1]"); # push all eventTypes to selection list
|
||||
}
|
||||
$dbhf->disconnect();
|
||||
my $cols = join(",", sort @colregs);
|
||||
|
||||
$max = 8 if($max > 8);
|
||||
@ -2753,7 +2836,10 @@ DbLog_sampleDataFn($$$$$)
|
||||
#
|
||||
sub dbReadings($@) {
|
||||
my($hash,@a) = @_;
|
||||
my $dbhf= $hash->{DBHF};
|
||||
|
||||
my $dbhf = DbLog_ConnectNewDBH($hash);
|
||||
return if(!$dbhf);
|
||||
|
||||
return 'Wrong Syntax for ReadingsVal!' unless defined($a[4]);
|
||||
my $DbLogType = AttrVal($a[0],'DbLogType','current');
|
||||
my $query;
|
||||
@ -2763,6 +2849,8 @@ sub dbReadings($@) {
|
||||
$query = "select VALUE,TIMESTAMP from history where DEVICE= '$a[2]' and READING= '$a[3]' order by TIMESTAMP desc limit 1";
|
||||
}
|
||||
my ($reading,$timestamp) = $dbhf->selectrow_array($query);
|
||||
$dbhf->disconnect();
|
||||
|
||||
$reading = (defined($reading)) ? $reading : $a[4];
|
||||
$timestamp = (defined($timestamp)) ? $timestamp : $a[4];
|
||||
return $reading if $a[1] eq 'ReadingsVal';
|
||||
@ -2770,6 +2858,26 @@ sub dbReadings($@) {
|
||||
return "Syntax error: $a[1]";
|
||||
}
|
||||
|
||||
################################################################
|
||||
# benutzte DB-Feldlängen zur Info in Internalos setzen
|
||||
################################################################
|
||||
sub setinternalcols ($){
|
||||
my ($hash)= @_;
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
$columns{EVENT} = AttrVal($name, "colEvent", 512);
|
||||
$columns{READING} = AttrVal($name, "colReading", 64);
|
||||
$columns{VALUE} = AttrVal($name, "colValue", 128);
|
||||
|
||||
$hash->{COLUMNS} = "field length used for Device: $columns{DEVICE},
|
||||
Type: $columns{TYPE},
|
||||
Event: $columns{EVENT},
|
||||
Reading: $columns{READING},
|
||||
Value: $columns{VALUE},
|
||||
Unit: $columns{UNIT}";
|
||||
return;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=pod
|
||||
@ -3086,10 +3194,12 @@ sub dbReadings($@) {
|
||||
</code><br>
|
||||
|
||||
This attribute determines the operation mode of DbLog. If asynchronous mode is active (asyncMode=1), the events which should be saved
|
||||
at first will be cached in memory. After synchronisation time cycle (attribute syncInterval) the cached events get saved into
|
||||
the database with bulk insert.
|
||||
at first will be cached in memory. After synchronisation time cycle (attribute syncInterval), or if the count limit of datasets in cache
|
||||
is reached (attribute cacheLimit), the cached events get saved into the database using bulk insert.
|
||||
If the database isn't available, the events will be cached in memeory furthermore, and tried to save into database again after
|
||||
the next synchronisation time cycle if the database is available. <br>
|
||||
In asynchronous mode the data insert into database will be executed non-blocking by a background process.
|
||||
You can adjust the timeout value for this background process by attribute "timeout" (default 120s). <br>
|
||||
In synchronous mode (normal mode) the events won't be cached im memory and get saved into database immediately. If the database isn't
|
||||
available the events are get lost. <br>
|
||||
</ul>
|
||||
@ -3110,6 +3220,55 @@ sub dbReadings($@) {
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<ul><b>cacheLimit</b>
|
||||
<ul>
|
||||
<code>
|
||||
attr <device> cacheLimit <n>
|
||||
</code><br>
|
||||
|
||||
In asynchronous logging mode the content of cache will be written into the database and cleared if the number <n> datasets
|
||||
in cache has reached (default: 500). Thereby the timer of asynchronous logging mode will be set new to the value of
|
||||
attribute "syncInterval". <br>
|
||||
</ul>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<ul><b>colEvent</b>
|
||||
<ul>
|
||||
<code>
|
||||
attr <device> colEvent <n>
|
||||
</code><br>
|
||||
|
||||
The field length of database field EVENT will be adjusted. By this attribute the default value in the DbLog-device can be
|
||||
adjusted if the field length in the databse was changed nanually. <br>
|
||||
</ul>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<ul><b>colReading</b>
|
||||
<ul>
|
||||
<code>
|
||||
attr <device> colReading <n>
|
||||
</code><br>
|
||||
|
||||
The field length of database field READING will be adjusted. By this attribute the default value in the DbLog-device can be
|
||||
adjusted if the field length in the databse was changed nanually. <br>
|
||||
</ul>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<ul><b>colValue</b>
|
||||
<ul>
|
||||
<code>
|
||||
attr <device> colValue <n>
|
||||
</code><br>
|
||||
|
||||
The field length of database field VALUE will be adjusted. By this attribute the default value in the DbLog-device can be
|
||||
adjusted if the field length in the databse was changed nanually. <br>
|
||||
</ul>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<ul><b>DbLogType</b>
|
||||
<ul>
|
||||
<code>
|
||||
@ -3146,7 +3305,7 @@ sub dbReadings($@) {
|
||||
<ul><b>DbLogInclude</b>
|
||||
<ul>
|
||||
<code>
|
||||
attr <device> DbLogInclude regex:MinInterval [regex:MinInterval] ...
|
||||
attr <device> DbLogInclude regex:MinInterval,[regex:MinInterval] ...
|
||||
</code><br>
|
||||
|
||||
A new Attribute DbLogInclude will be propagated
|
||||
@ -3156,7 +3315,7 @@ sub dbReadings($@) {
|
||||
on how DbLogExclude and DbLogInclude are handled. <br>
|
||||
|
||||
<b>Example</b> <br>
|
||||
<code>attr MyDevice1 DbLogInclude .*</code>
|
||||
<code>attr MyDevice1 DbLogInclude .*</code> <br>
|
||||
<code>attr MyDevice2 DbLogInclude state,(floorplantext|MyUserReading):300,battery:3600</code>
|
||||
</ul>
|
||||
</ul>
|
||||
@ -3165,7 +3324,7 @@ sub dbReadings($@) {
|
||||
<ul><b>DbLogExclude</b>
|
||||
<ul>
|
||||
<code>
|
||||
attr <device> DbLogExclude regex:MinInterval [regex:MinInterval] ...
|
||||
attr <device> DbLogExclude regex:MinInterval,[regex:MinInterval] ...
|
||||
</code><br>
|
||||
|
||||
A new Attribute DbLogExclude will be propagated to all Devices if DBLog is used.
|
||||
@ -3173,7 +3332,7 @@ sub dbReadings($@) {
|
||||
If a MinInterval is set, the logentry is dropped if the defined interval is not reached and value vs. lastvalue is eqal. <br>
|
||||
|
||||
<b>Example</b> <br>
|
||||
<code>attr MyDevice1 DbLogExclude .*</code>
|
||||
<code>attr MyDevice1 DbLogExclude .*</code> <br>
|
||||
<code>attr MyDevice2 DbLogExclude state,(floorplantext|MyUserReading):300,battery:3600</code>
|
||||
</ul>
|
||||
</ul>
|
||||
@ -3241,6 +3400,20 @@ sub dbReadings($@) {
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<ul><b>showNotifyTime</b>
|
||||
<ul>
|
||||
<code>attr <device> showNotifyTime [1|0]
|
||||
</code><br>
|
||||
|
||||
If set,
|
||||
Wenn gesetzt, the reading "notify_processing_time" shows the required execution time (in seconds) in the DbLog
|
||||
Notify-function. This attribute is practical for performance analyses and helps to determine the differences of time
|
||||
required when the operation mode was switched from synchronous to the asynchronous mode. <br>
|
||||
|
||||
</ul>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<ul><b>syncInterval</b>
|
||||
<ul>
|
||||
<code>attr <device> syncInterval <n>
|
||||
@ -3266,6 +3439,17 @@ sub dbReadings($@) {
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<ul><b>timeout</b>
|
||||
<ul>
|
||||
<code>
|
||||
attr <device> timeout <n>
|
||||
</code><br>
|
||||
setup timeout of the write cycle into database in asynchronous mode (default 120s) <br>
|
||||
|
||||
</ul>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<ul><b>verbose4Devs</b>
|
||||
<ul>
|
||||
<code>
|
||||
@ -3622,9 +3806,12 @@ sub dbReadings($@) {
|
||||
</code><br>
|
||||
|
||||
Dieses Attribut stellt den Arbeitsmodus von DbLog ein. Im asynchronen Modus (asyncMode=1), werden die zu speichernden Events zunächst in Speicher
|
||||
gecacht. Nach Ablauf der Synchronisationszeit (Attribut syncInterval) werden die gecachten Events im Block in die Datenbank geschrieben.
|
||||
gecacht. Nach Ablauf der Synchronisationszeit (Attribut syncInterval) oder bei Erreichen der maximalen Anzahl der Datensätze im Cache
|
||||
(Attribut cacheLimit) werden die gecachten Events im Block in die Datenbank geschrieben.
|
||||
Ist die Datenbank nicht verfügbar, werden die Events weiterhin im Speicher gehalten und nach Ablauf des Syncintervalls in die Datenbank
|
||||
geschrieben falls sie dann verfügbar ist. <br>
|
||||
Im asynchronen Mode werden die Daten nicht blockierend mit einem separaten Hintergrundprozess in die Datenbank geschrieben.
|
||||
Det Timeout-Wert für diesen Hintergrundprozess kann mit dem Attribut "timeout" (Default 120s) eingestellt werden.
|
||||
Im synchronen Modus (Normalmodus) werden die Events nicht gecacht und sofort in die Datenbank geschrieben. Ist die Datenbank nicht
|
||||
verfügbar gehen sie verloren.<br>
|
||||
</ul>
|
||||
@ -3645,6 +3832,55 @@ sub dbReadings($@) {
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<ul><b>cacheLimit</b>
|
||||
<ul>
|
||||
<code>
|
||||
attr <device> cacheLimit <n>
|
||||
</code><br>
|
||||
|
||||
Im asynchronen Logmodus wird der Cache in die Datenbank weggeschrieben und geleert wenn die Anzahl <n> Datensätze
|
||||
im Cache erreicht ist (Default: 500). Der Timer des asynchronen Logmodus wird dabei neu auf den Wert des Attributs "syncInterval"
|
||||
gesetzt. <br>
|
||||
</ul>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<ul><b>colEvent</b>
|
||||
<ul>
|
||||
<code>
|
||||
attr <device> colEvent <n>
|
||||
</code><br>
|
||||
|
||||
Die Feldlänge für das DB-Feld EVENT wird userspezifisch angepasst. Mit dem Attribut kann der Default-Wert im Modul
|
||||
verändert werden wenn die Feldlänge in der Datenbank manuell geändert wurde. <br>
|
||||
</ul>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<ul><b>colReading</b>
|
||||
<ul>
|
||||
<code>
|
||||
attr <device> colReading <n>
|
||||
</code><br>
|
||||
|
||||
Die Feldlänge für das DB-Feld READING wird userspezifisch angepasst. Mit dem Attribut kann der Default-Wert im Modul
|
||||
verändert werden wenn die Feldlänge in der Datenbank manuell geändert wurde. <br>
|
||||
</ul>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<ul><b>colValue</b>
|
||||
<ul>
|
||||
<code>
|
||||
attr <device> colValue <n>
|
||||
</code><br>
|
||||
|
||||
Die Feldlänge für das DB-Feld VALUE wird userspezifisch angepasst. Mit dem Attribut kann der Default-Wert im Modul
|
||||
verändert werden wenn die Feldlänge in der Datenbank manuell geändert wurde. <br>
|
||||
</ul>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<ul><b>DbLogType</b>
|
||||
<ul>
|
||||
<code>
|
||||
@ -3686,7 +3922,7 @@ sub dbReadings($@) {
|
||||
<ul><b>DbLogInclude</b>
|
||||
<ul>
|
||||
<code>
|
||||
attr <device> DbLogInclude regex:MinInterval [regex:MinInterval] ...
|
||||
attr <device> DbLogInclude regex:MinInterval,[regex:MinInterval] ...
|
||||
</code><br>
|
||||
|
||||
Wenn DbLog genutzt wird, wird in allen Devices das Attribut <i>DbLogInclude</i> propagiert.
|
||||
@ -3696,7 +3932,7 @@ sub dbReadings($@) {
|
||||
DbLogExclude und DbLogInclude ausgewertet werden. <br>
|
||||
|
||||
<b>Beispiel</b> <br>
|
||||
<code>attr MyDevice1 DbLogInclude .*</code>
|
||||
<code>attr MyDevice1 DbLogInclude .*</code> <br>
|
||||
<code>attr MyDevice2 DbLogInclude state,(floorplantext|MyUserReading):300,battery:3600</code>
|
||||
</ul>
|
||||
</ul>
|
||||
@ -3705,7 +3941,7 @@ sub dbReadings($@) {
|
||||
<ul><b>DbLogExclude</b>
|
||||
<ul>
|
||||
<code>
|
||||
attr <device> DbLogExclude regex:MinInterval [regex:MinInterval] ...
|
||||
attr <device> DbLogExclude regex:MinInterval,[regex:MinInterval] ...
|
||||
</code><br>
|
||||
|
||||
Wenn DbLog genutzt wird, wird in alle Devices das Attribut <i>DbLogExclude</i> propagiert.
|
||||
@ -3714,7 +3950,7 @@ sub dbReadings($@) {
|
||||
dann nicht geloggt, wenn das Intervall noch nicht erreicht und der Wert des Readings sich nicht verändert hat. <br>
|
||||
|
||||
<b>Beispiel</b> <br>
|
||||
<code>attr MyDevice1 DbLogExclude .*</code>
|
||||
<code>attr MyDevice1 DbLogExclude .*</code> <br>
|
||||
<code>attr MyDevice2 DbLogExclude state,(floorplantext|MyUserReading):300,battery:3600</code>
|
||||
</ul>
|
||||
</ul>
|
||||
@ -3775,6 +4011,19 @@ sub dbReadings($@) {
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<ul><b>showNotifyTime</b>
|
||||
<ul>
|
||||
<code>attr <device> showNotifyTime [1|0]
|
||||
</code><br>
|
||||
|
||||
Wenn gesetzt, zeigt das Reading "notify_processing_time" die benötigte Abarbeitungszeit (in Sekunden) für die
|
||||
Abarbeitung der DbLog Notify-Funktion. Das Attribut ist für Performance Analysen geeignet und hilft auch die Unterschiede
|
||||
im Zeitbedarf bei der Umschaltung des synchronen in den asynchronen Modus festzustellen. <br>
|
||||
|
||||
</ul>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<ul><b>syncEvents</b>
|
||||
<ul>
|
||||
<code>attr <device> syncEvents [1|0]
|
||||
@ -3809,6 +4058,17 @@ sub dbReadings($@) {
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<ul><b>timeout</b>
|
||||
<ul>
|
||||
<code>
|
||||
attr <device> timeout <n>
|
||||
</code><br>
|
||||
Setzt den Timeout-Wert für den Schreibzyklus in die Datenbank im asynchronen Modus (default 120s). <br>
|
||||
|
||||
</ul>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<ul><b>verbose4Devs</b>
|
||||
<ul>
|
||||
<code>
|
||||
|
Loading…
Reference in New Issue
Block a user