2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-02-25 09:55:38 +00:00

93_DbLog: contrib 5.5.9

git-svn-id: https://svn.fhem.de/fhem/trunk@26917 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
nasseeder1 2022-12-28 20:07:14 +00:00
parent 80d0f35ba5
commit 6ca79ed1cb

View File

@ -1,5 +1,5 @@
############################################################################################################################################
# $Id: 93_DbLog.pm 26750 2022-12-25 16:38:54Z DS_Starter $
# $Id: 93_DbLog.pm 26907 2022-12-27 11:38:39Z DS_Starter $
#
# 93_DbLog.pm
# written by Dr. Boris Neubert 2007-12-30
@ -38,6 +38,9 @@ no if $] >= 5.017011, warnings => 'experimental::smartmatch';
# Version History intern by DS_Starter:
my %DbLog_vNotesIntern = (
"5.5.9" => "28.12.2022 delete \$hash->{HELPER}{TH}, \$hash->{HELPER}{TC} ".
"Forum: https://forum.fhem.de/index.php/topic,130588.msg1254073.html#msg1254073 ",
"5.5.8" => "27.12.2022 two-line output of long state messages, define LONGRUN_PID threshold ",
"5.5.7" => "20.12.2022 cutted _DbLog_SBP_onRun_Log into _DbLog_SBP_onRun_LogArray and _DbLog_SBP_onRun_LogBulk ".
"__DbLog_SBP_onRun_LogCurrent, __DbLog_SBP_fieldArrays, some bugfixes, add drivers to configCheck, edit comref ",
"5.5.6" => "12.12.2022 Serialize with Storable instead of JSON, more code rework ",
@ -313,6 +316,7 @@ my %DbLog_columns = ("DEVICE" => 64,
my $dblog_cachedef = 500; # default Größe cacheLimit bei asynchronen Betrieb
my $dblog_cmdef = 'basic_ta:on'; # default commitMode
my $dblog_todef = 86400; # default timeout Sekunden
my $dblog_lrpth = 0.8; # Schwellenwert für LONGRUN_PID ab dem "Another operation is in progress...." im state ausgegeben wird
################################################################
sub DbLog_Initialize {
@ -412,8 +416,6 @@ sub DbLog_Define {
$hash->{MODE} = 'synchronous';
$hash->{HELPER}{OLDSTATE} = 'initialized';
$hash->{HELPER}{MODMETAABSENT} = 1 if($modMetaAbsent); # Modul Meta.pm nicht vorhanden
$hash->{HELPER}{TH} = 'history'; # Tabelle history (wird ggf. durch Datenbankschema ergänzt)
$hash->{HELPER}{TC} = 'current'; # Tabelle current (wird ggf. durch Datenbankschema ergänzt)
DbLog_setVersionInfo ($hash); # Versionsinformationen setzen
notifyRegexpChanged ($hash, $regexp); # nur Events dieser Devices an NotifyFn weiterleiten, NOTIFYDEV wird gesetzt wenn möglich
@ -521,7 +523,7 @@ sub DbLog_DelayedShutdown {
DbLog_execMemCacheAsync ($hash);
my $delay_needed = IsDisabled($name) ? 0 :
$hash->{HELPER}{LONGRUN_PID} ? 1 :
defined $hash->{HELPER}{LONGRUN_PID} ? 1 :
0;
if ($delay_needed) {
@ -708,15 +710,6 @@ sub DbLog_Attr {
$do = 0 if($cmd eq "del");
if ($do == 1) {
$hash->{HELPER}{TH} = $aVal.'.history';
$hash->{HELPER}{TC} = $aVal.'.current';
}
else {
$hash->{HELPER}{TH} = 'history';
$hash->{HELPER}{TC} = 'current';
}
if ($init_done == 1) {
DbLog_SBP_sendDbDisconnect ($hash, 1); # DB Verbindung und Verbindungsdaten im SubProzess löschen
@ -1399,7 +1392,7 @@ sub DbLog_Log {
}
}
my $log4rel = $vb4show && !$hash->{HELPER}{LONGRUN_PID} ? 1 : 0;
my $log4rel = $vb4show && !defined $hash->{HELPER}{LONGRUN_PID} ? 1 : 0;
if(AttrVal ($name, 'verbose', 3) =~ /[45]/xs) {
if($log4rel) {
@ -2158,7 +2151,7 @@ sub DbLog_execMemCacheAsync {
my $verbose = AttrVal ($name, 'verbose', 3);
my $dolog = $memcount ? 1 : 0;
if($hash->{HELPER}{LONGRUN_PID}) {
if(defined $hash->{HELPER}{LONGRUN_PID}) {
$dolog = 0;
}
@ -2182,12 +2175,12 @@ sub DbLog_execMemCacheAsync {
$err = DbLog_SBP_sendLogData ($hash, 'log_asynch', $memc); # Subprocess Prozessdaten senden, Log-Daten sind in $memc->{cdata} gespeichert
}
else {
if($hash->{HELPER}{LONGRUN_PID}) {
if(defined $hash->{HELPER}{LONGRUN_PID}) {
$err = 'Another operation is in progress - resync at NextSync';
DbLog_writeFileIfCacheOverflow ($params); # Cache exportieren bei Overflow
}
else {
if($hash->{HELPER}{SHUTDOWNSEQ}) {
if(defined $hash->{HELPER}{SHUTDOWNSEQ}) {
Log3 ($name, 2, "DbLog $name - no data for last database write cycle");
_DbLog_finishDelayedShutdown ($hash);
}
@ -2210,9 +2203,11 @@ sub DbLog_execMemCacheSync {
my $err = DbLog_SBP_CheckAndInit ($hash); # Subprocess checken und ggf. initialisieren
return $err if(!defined $hash->{".fhem"}{subprocess});
if($hash->{HELPER}{LONGRUN_PID}) {
$err = 'Another operation is in progress - data is stored temporarily (check with listCache)';
if(defined $hash->{HELPER}{LONGRUN_PID}) {
if (gettimeofday() - $hash->{HELPER}{LONGRUN_PID} > $dblog_lrpth) {
$err = 'Another operation is in progress. <br>Data is stored temporarily.';
DbLog_setReadingstate ($hash, $err);
}
return;
}
@ -2261,18 +2256,23 @@ return $memc;
# $subprocess->readFromParent()
#
# my $parent = $subprocess->parent();
#
# $store - semipermanenter Datenspeicher
# $logstore - temporärer Logdatenspeicher
# $memc - Operationsspeicher
#
#################################################################
sub DbLog_SBP_onRun {
my $subprocess = shift;
my $name = $subprocess->{name};
my $store; # Datenspeicher
my $store; # semipermanenter Datenspeicher
my $logstore; # temporärer Logdatenspeicher
while (1) {
my $serial = $subprocess->readFromParent();
if(defined $serial) {
my $memc = eval { thaw ($serial) };
my $memc = eval { thaw ($serial) }; # Operationsspeicher
my $dbstorepars = $memc->{dbstorepars}; # 1 -> DB Parameter werden zum Speichern übermittelt, sonst 0
my $dbdelpars = $memc->{dbdelpars}; # 1 -> gespeicherte DB Parameter sollen gelöscht werden
@ -2306,8 +2306,8 @@ sub DbLog_SBP_onRun {
delete $store->{dbparams};
}
my $msg0 = $dbdelpars ? ' and stored DB params in SubProcess were deleted' : '';
my $msg1 = 'database disconnected by request'.$msg0;
my $msg0 = $dbdelpars ? ' <br>Stored DB params in SubProcess were deleted.' : '';
my $msg1 = 'Database disconnected by request.'.$msg0;
Log3 ($name, 3, "DbLog $name - $msg1");
@ -2344,7 +2344,7 @@ sub DbLog_SBP_onRun {
$ret = {
name => $name,
msg => 'connection params saved into SubProcess. Connection to DB is established when it is needed',
msg => 'Connection parameters saved into SubProcess. <br>Connection to DB is established when it is needed.',
oper => $operation,
ot => 0
};
@ -2378,24 +2378,19 @@ sub DbLog_SBP_onRun {
next;
}
my $model = $store->{dbparams}{model};
my $dbconn = $store->{dbparams}{dbconn};
my $cm = $store->{dbparams}{cm};
my $history = $store->{dbparams}{history};
my $current = $store->{dbparams}{current};
my ($useac,$useta) = DbLog_commitMode ($name, $cm);
## Verbindungsaufbau Datenbank
################################
my $params = { name => $name,
dbconn => $dbconn,
dbconn => $store->{dbparams}{dbconn},
dbname => $store->{dbparams}{dbname},
dbuser => $store->{dbparams}{dbuser},
dbpassword => $store->{dbparams}{dbpassword},
utf8 => $store->{dbparams}{utf8},
useac => $useac,
model => $model,
model => $store->{dbparams}{model},
sltjm => $store->{dbparams}{sltjm},
sltcs => $store->{dbparams}{sltcs}
};
@ -4325,7 +4320,7 @@ sub DbLog_SBP_CheckAndInit {
if (defined $hash->{SBP_PID} && defined $hash->{HELPER}{LONGRUN_PID}) { # Laufzeit des letzten Kommandos prüfen -> timeout
my $to = AttrVal($name, 'timeout', $dblog_todef);
my $rt = time() - $hash->{HELPER}{LONGRUN_PID}; # aktuelle Laufzeit
my $rt = gettimeofday() - $hash->{HELPER}{LONGRUN_PID}; # aktuelle Laufzeit
if ($rt >= $to) { # SubProcess beenden, möglicherweise tot
Log3 ($name, 2, qq{DbLog $name - The Subprocess >$hash->{SBP_PID}< has exceeded the timeout of $to seconds});
@ -4416,8 +4411,8 @@ sub DbLog_SBP_sendConnectionData {
$memc->{cm} = AttrVal ($name, 'commitMode', $dblog_cmdef);
$memc->{verbose} = AttrVal ($name, 'verbose', 3);
$memc->{utf8} = defined ($hash->{UTF8}) ? $hash->{UTF8} : 0;
$memc->{history} = $hash->{HELPER}{TH};
$memc->{current} = $hash->{HELPER}{TC};
$memc->{history} = DbLog_combineTablename ($hash, 'history');
$memc->{current} = DbLog_combineTablename ($hash, 'current');
$memc->{operation} = 'sendDbConnectData';
if ($hash->{MODEL} eq 'SQLITE') {
@ -4461,7 +4456,7 @@ sub DbLog_SBP_sendLogData {
my $err = _DbLog_SBP_sendToChild ($name, $subprocess, $memc);
return $err if($err);
$hash->{HELPER}{LONGRUN_PID} = time(); # Statusbit laufende Verarbeitung mit Startzeitstempel;
$hash->{HELPER}{LONGRUN_PID} = gettimeofday(); # Statusbit laufende Verarbeitung mit Startzeitstempel;
return;
}
@ -4501,7 +4496,7 @@ sub DbLog_SBP_sendCommand {
my $err = _DbLog_SBP_sendToChild ($name, $subprocess, $memc);
return $err if($err);
$hash->{HELPER}{LONGRUN_PID} = time(); # Statusbit laufende Verarbeitung mit Startzeitstempel;
$hash->{HELPER}{LONGRUN_PID} = gettimeofday(); # Statusbit laufende Verarbeitung mit Startzeitstempel;
DbLog_setReadingstate ($hash, "operation '$oper' is running");
@ -4796,8 +4791,9 @@ sub DbLog_setReadingstate {
my $val = shift // $hash->{HELPER}{OLDSTATE};
my $evt = $val eq $hash->{HELPER}{OLDSTATE} ? 0 : 1;
my $out = $val =~ /<br>/xs ? '<html>'.$val.'</html>' : $val;
readingsSingleUpdate($hash, 'state', $val, $evt);
readingsSingleUpdate($hash, 'state', $out, $evt);
$hash->{HELPER}{OLDSTATE} = $val;
@ -4993,8 +4989,8 @@ sub DbLog_Get {
my ($hash, @a) = @_;
my $name = $hash->{NAME};
my $utf8 = defined($hash->{UTF8})?$hash->{UTF8}:0;
my $history = $hash->{HELPER}{TH};
my $current = $hash->{HELPER}{TC};
my $history = DbLog_combineTablename ($hash, 'history');
my $current = DbLog_combineTablename ($hash, 'current');
my ($dbh,$err);
return DbLog_dbReadings($hash,@a) if $a[1] =~ m/^Readings/;
@ -5656,8 +5652,8 @@ sub DbLog_configcheck {
my $dbmodel = $hash->{MODEL};
my $dbconn = $hash->{dbconn};
my $dbname = (split(/;|=/, $dbconn))[1];
my $history = $hash->{HELPER}{TH};
my $current = $hash->{HELPER}{TC};
my $history = DbLog_combineTablename ($hash, 'history');
my $current = DbLog_combineTablename ($hash, 'current');
my ($check, $rec,%dbconfig);
@ -6933,9 +6929,11 @@ sub DbLog_fhemwebFn {
my $ret;
my $newIdx = 1;
while($defs{"SVG_${d}_$newIdx"}) {
$newIdx++;
}
my $name = "SVG_${d}_$newIdx";
$ret .= FW_pH("cmd=define $name SVG $d:templateDB:HISTORY;".
"set $name copyGplotFile&detail=$name",
@ -6950,7 +6948,7 @@ sub DbLog_sampleDataFn {
my ($dlName, $dlog, $max, $conf, $wName) = @_;
my $desc = "Device:Reading";
my $hash = $defs{$dlName};
my $current = $hash->{HELPER}{TC};
my $current = DbLog_combineTablename ($hash, 'current');
my @htmlArr;
my @example;
@ -7024,6 +7022,20 @@ sub DbLog_jsonError {
return $json;
}
################################################################
# Tabellenname incl. Schema erstellen
################################################################
sub DbLog_combineTablename {
my $hash = shift;
my $table = shift;
my $name = $hash->{NAME};
my $scheme = AttrVal($name, 'dbSchema', '');
$table = $scheme.'.'.$table if($scheme);
return $table;
}
################################################################
# Check Zeitformat
# Zeitformat: YYYY-MM-DD HH:MI:SS
@ -7064,8 +7076,8 @@ sub DbLog_prepareSql {
my $pagingstart = $_[13];
my $paginglimit = $_[14];
my $dbmodel = $hash->{MODEL};
my $history = $hash->{HELPER}{TH};
my $current = $hash->{HELPER}{TC};
my $history = DbLog_combineTablename ($hash, 'history');
my $current = DbLog_combineTablename ($hash, 'current');
my ($sql, $jsonstring, $countsql, $hourstats, $daystats, $weekstats, $monthstats, $yearstats);
if ($dbmodel eq "POSTGRESQL") {
@ -7351,7 +7363,7 @@ return $jsonstring;
sub DbLog_dbReadings {
my($hash,@a) = @_;
my $history = $hash->{HELPER}{TH};
my $history = DbLog_combineTablename ($hash, 'history');
my $dbh = _DbLog_ConnectNewDBH($hash);
return if(!$dbh);
@ -7387,13 +7399,13 @@ sub DbLog_setVersionInfo {
if($modules{$type}{META}{x_prereqs_src} && !$hash->{HELPER}{MODMETAABSENT}) { # META-Daten sind vorhanden
$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 26750 2022-11-26 16:38:54Z DS_Starter $ im Kopf komplett! vorhanden )
if($modules{$type}{META}{x_version}) { # {x_version} ( nur gesetzt wenn $Id: 93_DbLog.pm 26907 2022-12-27 11:38:39Z DS_Starter $ im Kopf komplett! vorhanden )
$modules{$type}{META}{x_version} =~ s/1\.1\.1/$v/xsg;
}
else {
$modules{$type}{META}{x_version} = $v;
}
return $@ unless (FHEM::Meta::SetInternals($hash)); # FVERSION wird gesetzt ( nur gesetzt wenn $Id: 93_DbLog.pm 26750 2022-11-26 16:38:54Z DS_Starter $ im Kopf komplett! vorhanden )
return $@ unless (FHEM::Meta::SetInternals($hash)); # FVERSION wird gesetzt ( nur gesetzt wenn $Id: 93_DbLog.pm 26907 2022-12-27 11:38:39Z DS_Starter $ im Kopf komplett! vorhanden )
if(__PACKAGE__ eq "FHEM::$type" || __PACKAGE__ eq $type) {
# es wird mit Packages gearbeitet -> Perl übliche Modulversion setzen
# mit {<Modul>->VERSION()} im FHEMWEB kann Modulversion abgefragt werden
@ -7658,7 +7670,6 @@ return;
</ul>
<br>
<ul>
<li><b>set &lt;name&gt; addCacheLine YYYY-MM-DD HH:MM:SS|&lt;device&gt;|&lt;type&gt;|&lt;event&gt;|&lt;reading&gt;|&lt;value&gt;|[&lt;unit&gt;] </b> <br><br>
<ul>