mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-20 01:06:04 +00:00
93_DbRep: sumValue - create 0 instaed of '-' if value of DS is 0, set fastStart as default for TYPE Client
git-svn-id: https://svn.fhem.de/fhem/trunk@23462 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
48a89ae5bc
commit
b5531e80ed
@ -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.
|
||||
- change: 93_DbRep: set fastStart as default for TYPE Client
|
||||
- bugfix: 93_DbRep: sumValue - create 0 instaed of '-' if value of DS is 0
|
||||
- feature: 49_TBot_List: new silentStrt option
|
||||
- change: 49_TBot_List: chat/groupid can be added in start
|
||||
- bugfix: 98_weekprofile: Log ccutype not defined (forum #1113306)
|
||||
|
@ -3,7 +3,7 @@
|
||||
##########################################################################################################
|
||||
# 93_DbRep.pm
|
||||
#
|
||||
# (c) 2016-2020 by Heiko Maaz
|
||||
# (c) 2016-2021 by Heiko Maaz
|
||||
# e-mail: Heiko dot Maaz at t-online dot de
|
||||
#
|
||||
# This Module can be used to select and report content of databases written by 93_DbLog module
|
||||
@ -57,7 +57,9 @@ no if $] >= 5.017011, warnings => 'experimental::smartmatch';
|
||||
|
||||
# Version History intern
|
||||
my %DbRep_vNotesIntern = (
|
||||
"8.42.1" => "22.11.2020 fix delete \$hash->{HELPER}{REDUCELOG} Forum:#116057",
|
||||
"8.42.3" => "03.01.2021 set fastStart as default for TYPE Client ",
|
||||
"8.42.2" => "03.01.2021 sumValue - create 0 instaed of '-' if value of DS is 0, Forum:#index.php/topic,53584.msg1116910.html#msg1116910 ",
|
||||
"8.42.1" => "22.11.2020 fix delete \$hash->{HELPER}{REDUCELOG} Forum:#116057 ",
|
||||
"8.42.0" => "14.11.2020 new vals next_day_begin, next_day_end for time attr Forum: https://forum.fhem.de/index.php/topic,53584.msg1100040.html#msg1100040 ",
|
||||
"8.41.0" => "08.11.2020 new attrbute avgDailyMeanGWSwithGTS for Grassland temperature sum, minor bugfixes in create time array ",
|
||||
"8.40.8" => "17.09.2020 sqlCmd supports PREPARE statament Forum: #114293, commandRef revised ",
|
||||
@ -95,6 +97,7 @@ my %DbRep_vNotesIntern = (
|
||||
|
||||
# Version History extern:
|
||||
my %DbRep_vNotesExtern = (
|
||||
"8.42.3" => "03.01.2021 The attribute fastStart is set now as default for TYPE Client. This way the DbRep device only connects to the database when it has to process a task and not immediately when FHEM is started. ",
|
||||
"8.40.7" => "03.09.2020 The get Command \"dbValue\" has been renamed to \"sqlCmdBlocking\. You can use \"dbValue\" furthermore in your scripts, but it is ".
|
||||
"deprecated and will be removed soon. Please change your scripts to use \"sqlCmdBlocking\" instead. ",
|
||||
"8.40.4" => "23.07.2020 The new aggregation type 'minute' is now available. ",
|
||||
@ -339,7 +342,7 @@ sub DbRep_Initialize {
|
||||
"executeBeforeProc ".
|
||||
"executeAfterProc ".
|
||||
"expimpfile ".
|
||||
"fastStart:1,0 ".
|
||||
"fastStart:0,1 ".
|
||||
"fetchRoute:ascent,descent ".
|
||||
"fetchMarkDuplicates:red,blue,brown,green,orange ".
|
||||
"fetchValueFn:textField-long ".
|
||||
@ -1145,7 +1148,6 @@ sub DbRep_Attr {
|
||||
executeBeforeProc
|
||||
executeAfterProc
|
||||
expimpfile
|
||||
fastStart
|
||||
ftpUse
|
||||
ftpUser
|
||||
ftpUseSSL
|
||||
@ -1457,7 +1459,7 @@ sub DbRep_Notify {
|
||||
return if(!$events);
|
||||
|
||||
foreach my $event (@{$events}) {
|
||||
$event = "" if(!defined($event));
|
||||
$event = "" if(!defined($event));
|
||||
my @evl = split("[ \t][ \t]*", $event);
|
||||
|
||||
if($event =~ /DELETED/) {
|
||||
@ -1469,13 +1471,12 @@ sub DbRep_Notify {
|
||||
# wenn Rolle "Agent" Verbeitung von RENAMED Events
|
||||
next if ($event !~ /RENAMED/);
|
||||
|
||||
my $strucChanged;
|
||||
# altes in neues device in der DEF des angeschlossenen DbLog-device ändern (neues device loggen)
|
||||
my $strucChanged; # altes in neues device in der DEF des angeschlossenen DbLog-device ändern (neues device loggen)
|
||||
my $dblog_name = $own_hash->{HELPER}{DBLOGDEVICE}; # Name des an den DbRep-Agenten angeschlossenen DbLog-Dev
|
||||
my $dblog_hash = $defs{$dblog_name};
|
||||
|
||||
if ( $dblog_hash->{DEF} =~ m/( |\(|\|)$evl[1]( |\)|\||:)/ ) {
|
||||
$dblog_hash->{DEF} =~ s/$evl[1]/$evl[2]/;
|
||||
$dblog_hash->{DEF} =~ s/$evl[1]/$evl[2]/;
|
||||
$dblog_hash->{REGEXP} =~ s/$evl[1]/$evl[2]/;
|
||||
# Definitionsänderung wurde vorgenommen
|
||||
$strucChanged = 1;
|
||||
@ -1572,22 +1573,26 @@ return;
|
||||
# Verbindung zur DB aufbauen und Datenbankeigenschaften ermitteln
|
||||
###################################################################################
|
||||
sub DbRep_firstconnect {
|
||||
my ($string) = @_;
|
||||
my ($name,$opt,$prop,$fret) = split("\\|", $string);
|
||||
my $hash = $defs{$name};
|
||||
my $to = AttrVal($name, "timeout", "86400");
|
||||
my $dbloghash = $defs{$hash->{HELPER}{DBLOGDEVICE}};
|
||||
my $dbconn = $dbloghash->{dbconn};
|
||||
my $dbuser = $dbloghash->{dbuser};
|
||||
my $string = shift;
|
||||
|
||||
RemoveInternalTimer($hash, "DbRep_firstconnect");
|
||||
my ($name,$opt,$prop,$fret) = split("\\|", $string);
|
||||
my $hash = $defs{$name};
|
||||
my $to = AttrVal($name, "timeout", "86400");
|
||||
|
||||
RemoveInternalTimer ($hash, "DbRep_firstconnect");
|
||||
return if(IsDisabled($name));
|
||||
|
||||
if ($init_done == 1) {
|
||||
if (AttrVal($name, "fastStart", 0) && $prop eq "onBoot" ) {
|
||||
my $dbloghash = $defs{$hash->{HELPER}{DBLOGDEVICE}};
|
||||
my $dbconn = $dbloghash->{dbconn};
|
||||
my $dbuser = $dbloghash->{dbuser};
|
||||
my $fadef = $hash->{MODEL} eq "Client" ? 1 : 0; # fastStart default immer 1 für Clients (0 für Agenten)
|
||||
|
||||
if (AttrVal($name, "fastStart", $fadef) && $prop eq "onBoot" ) {
|
||||
$hash->{LASTCMD} = "initial database connect stopped due to attribute 'fastStart'";
|
||||
return;
|
||||
}
|
||||
|
||||
# DB Struktur aus DbLog Instanz übernehmen
|
||||
$hash->{HELPER}{DBREPCOL}{COLSET} = $dbloghash->{HELPER}{COLSET};
|
||||
$hash->{HELPER}{DBREPCOL}{DEVICE} = $dbloghash->{HELPER}{DEVICECOL};
|
||||
@ -1599,9 +1604,11 @@ sub DbRep_firstconnect {
|
||||
|
||||
# DB Strukturelemente abrufen
|
||||
Log3 ($name, 3, "DbRep $name - Connectiontest to database $dbconn with user $dbuser") if($hash->{LASTCMD} ne "minTimestamp");
|
||||
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("DbRep_getInitData", "$name|$opt|$prop|$fret", "DbRep_getInitDataDone", $to, "DbRep_getInitDataAborted", $hash);
|
||||
$hash->{HELPER}{RUNNING_PID}{loglevel} = 5 if($hash->{HELPER}{RUNNING_PID}); # Forum #77057
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
InternalTimer(time+1, "DbRep_firstconnect", "$name|$opt|$prop|$fret", 0);
|
||||
}
|
||||
|
||||
@ -4278,10 +4285,10 @@ return;
|
||||
}
|
||||
|
||||
####################################################################################################
|
||||
# nichtblockierende DB-Abfrage sumValue
|
||||
# nichtblockierende DB-Abfrage sumValue
|
||||
####################################################################################################
|
||||
sub sumval_DoParse {
|
||||
my ($string) = @_;
|
||||
my $string = shift;
|
||||
my ($name,$device,$reading,$prop,$ts) = split("\\§", $string);
|
||||
my $hash = $defs{$name};
|
||||
my $dbloghash = $defs{$hash->{HELPER}{DBLOGDEVICE}};
|
||||
@ -4289,6 +4296,7 @@ sub sumval_DoParse {
|
||||
my $dbuser = $dbloghash->{dbuser};
|
||||
my $dblogname = $dbloghash->{NAME};
|
||||
my $dbpassword = $attr{"sec$dblogname"}{secret};
|
||||
|
||||
my ($dbh,$sql,$sth,$err,$selspec);
|
||||
|
||||
# Background-Startzeit
|
||||
@ -4301,42 +4309,40 @@ sub sumval_DoParse {
|
||||
return "$name|''|$device|$reading|''|$err|''";
|
||||
}
|
||||
|
||||
# only for this block because of warnings if details of readings are not set
|
||||
no warnings 'uninitialized';
|
||||
|
||||
# ist Zeiteingrenzung und/oder Aggregation gesetzt ? (wenn ja -> "?" in SQL sonst undef)
|
||||
my ($IsTimeSet,$IsAggrSet) = DbRep_checktimeaggr($hash);
|
||||
no warnings 'uninitialized'; # only for this block because of warnings if details of readings are not set
|
||||
|
||||
my ($IsTimeSet,$IsAggrSet) = DbRep_checktimeaggr($hash); # ist Zeiteingrenzung und/oder Aggregation gesetzt ? (wenn ja -> "?" in SQL sonst undef)
|
||||
Log3 ($name, 5, "DbRep $name - IsTimeSet: $IsTimeSet, IsAggrSet: $IsAggrSet");
|
||||
|
||||
# Timestampstring to Array
|
||||
my @ts = split("\\|", $ts);
|
||||
my @ts = split("\\|", $ts); # Timestampstring to Array
|
||||
Log3 ($name, 5, "DbRep $name - Timestamp-Array: \n@ts");
|
||||
|
||||
#vorbereiten der DB-Abfrage, DB-Modell-abhaengig
|
||||
if ($dbloghash->{MODEL} eq "POSTGRESQL") {
|
||||
if ($dbloghash->{MODEL} eq "POSTGRESQL") { #vorbereiten der DB-Abfrage, DB-Modell-abhaengig
|
||||
$selspec = "SUM(VALUE::numeric)";
|
||||
} elsif ($dbloghash->{MODEL} eq "MYSQL") {
|
||||
}
|
||||
elsif ($dbloghash->{MODEL} eq "MYSQL") {
|
||||
$selspec = "SUM(VALUE)";
|
||||
} elsif ($dbloghash->{MODEL} eq "SQLITE") {
|
||||
}
|
||||
elsif ($dbloghash->{MODEL} eq "SQLITE") {
|
||||
$selspec = "SUM(VALUE)";
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$selspec = "SUM(VALUE)";
|
||||
}
|
||||
|
||||
# SQL-Startzeit
|
||||
my $st = [gettimeofday];
|
||||
my $st = [gettimeofday]; # SQL-Startzeit
|
||||
|
||||
# DB-Abfrage zeilenweise für jeden Array-Eintrag
|
||||
my ($arrstr,$wrstr,@rsf,@rsn,@wsf,@wsn);
|
||||
foreach my $row (@ts) {
|
||||
my @a = split("#", $row);
|
||||
my $runtime_string = $a[0];
|
||||
my $runtime_string_first = $a[1];
|
||||
my $runtime_string_next = $a[2];
|
||||
for my $row (@ts) { # DB-Abfrage zeilenweise für jeden Array-Eintrag
|
||||
my @a = split("#", $row);
|
||||
my $runtime_string = $a[0];
|
||||
my $runtime_string_first = $a[1];
|
||||
my $runtime_string_next = $a[2];
|
||||
|
||||
if ($IsTimeSet || $IsAggrSet) {
|
||||
$sql = DbRep_createSelectSql($hash,"history",$selspec,$device,$reading,"'$runtime_string_first'","'$runtime_string_next'",'');
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$sql = DbRep_createSelectSql($hash,"history",$selspec,$device,$reading,undef,undef,'');
|
||||
}
|
||||
Log3 ($name, 4, "DbRep $name - SQL execute: $sql");
|
||||
@ -4351,8 +4357,7 @@ sub sumval_DoParse {
|
||||
return "$name|''|$device|$reading|''|$err|''";
|
||||
}
|
||||
|
||||
# DB-Abfrage -> Ergebnis in @arr aufnehmen
|
||||
my @line = $sth->fetchrow_array();
|
||||
my @line = $sth->fetchrow_array(); # DB-Abfrage -> Ergebnis in @arr aufnehmen
|
||||
|
||||
Log3 ($name, 5, "DbRep $name - SQL result: $line[0]") if($line[0]);
|
||||
|
||||
@ -4360,7 +4365,8 @@ sub sumval_DoParse {
|
||||
@rsf = split(/[ :]/,$runtime_string_first);
|
||||
@rsn = split(/[ :]/,$runtime_string_next);
|
||||
$arrstr .= $runtime_string."#".$line[0]."#".$rsf[0]."_".$rsf[1]."|";
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
@rsf = split(" ",$runtime_string_first);
|
||||
@rsn = split(" ",$runtime_string_next);
|
||||
$arrstr .= $runtime_string."#".$line[0]."#".$rsf[0]."|";
|
||||
@ -4373,11 +4379,9 @@ sub sumval_DoParse {
|
||||
$sth->finish;
|
||||
$dbh->disconnect;
|
||||
|
||||
# SQL-Laufzeit ermitteln
|
||||
my $rt = tv_interval($st);
|
||||
my $rt = tv_interval($st); # SQL-Laufzeit ermitteln
|
||||
|
||||
# Ergebnisse in Datenbank schreiben
|
||||
my ($wrt,$irowdone);
|
||||
my ($wrt,$irowdone); # Ergebnisse in Datenbank schreiben
|
||||
if($prop =~ /writeToDB/) {
|
||||
($wrt,$irowdone,$err) = DbRep_OutputWriteToDB($name,$device,$reading,$wrstr,"sum");
|
||||
if ($err) {
|
||||
@ -4388,12 +4392,10 @@ sub sumval_DoParse {
|
||||
$rt = $rt+$wrt;
|
||||
}
|
||||
|
||||
# Daten müssen als Einzeiler zurückgegeben werden
|
||||
$arrstr = encode_base64($arrstr,"");
|
||||
$arrstr = encode_base64($arrstr,""); # Daten müssen als Einzeiler zurückgegeben werden
|
||||
$device = encode_base64($device,"");
|
||||
|
||||
# Background-Laufzeit ermitteln
|
||||
my $brt = tv_interval($bst);
|
||||
my $brt = tv_interval($bst); # Background-Laufzeit ermitteln
|
||||
|
||||
$rt = $rt.",".$brt;
|
||||
|
||||
@ -4404,7 +4406,7 @@ sub sumval_DoParse {
|
||||
# Auswertungsroutine der nichtblockierenden DB-Abfrage sumValue
|
||||
####################################################################################################
|
||||
sub sumval_ParseDone {
|
||||
my ($string) = @_;
|
||||
my $string = shift;
|
||||
my @a = split("\\|",$string);
|
||||
my $hash = $defs{$a[0]};
|
||||
my $name = $hash->{NAME};
|
||||
@ -4415,53 +4417,53 @@ sub sumval_ParseDone {
|
||||
$reading =~ s/[^A-Za-z\/\d_\.-]/\//g;
|
||||
my $bt = $a[4];
|
||||
my ($rt,$brt) = split(",", $bt);
|
||||
my $err = $a[5]?decode_base64($a[5]):undef;
|
||||
my $err = $a[5] ? decode_base64($a[5]) : undef;
|
||||
my $irowdone = $a[6];
|
||||
my $reading_runtime_string;
|
||||
my $erread;
|
||||
|
||||
my ($reading_runtime_string,$erread);
|
||||
|
||||
delete($hash->{HELPER}{RUNNING_PID});
|
||||
|
||||
# Befehl nach Procedure ausführen
|
||||
$erread = DbRep_afterproc($hash, "$hash->{LASTCMD}");
|
||||
$erread = DbRep_afterproc($hash, "$hash->{LASTCMD}"); # Befehl nach Procedure ausführen
|
||||
|
||||
if ($err) {
|
||||
ReadingsSingleUpdateValue ($hash, "errortext", $err, 1);
|
||||
ReadingsSingleUpdateValue ($hash, "state", "error", 1);
|
||||
ReadingsSingleUpdateValue ($hash, "state", "error", 1);
|
||||
return;
|
||||
}
|
||||
|
||||
# only for this block because of warnings if details of readings are not set
|
||||
no warnings 'uninitialized';
|
||||
no warnings 'uninitialized'; # only for this block because of warnings if details of readings are not set
|
||||
|
||||
# Readingaufbereitung
|
||||
my $state = $erread?$erread:"done";
|
||||
readingsBeginUpdate($hash);
|
||||
my $state = $erread // "done";
|
||||
|
||||
readingsBeginUpdate ($hash);
|
||||
|
||||
my @arr = split("\\|", $arrstr);
|
||||
foreach my $row (@arr) {
|
||||
my @a = split("#", $row);
|
||||
my $runtime_string = $a[0];
|
||||
my $c = $a[1];
|
||||
my $rsf = $a[2]."__";
|
||||
for my $row (@arr) {
|
||||
my @a = split("#", $row);
|
||||
my $runtime_string = $a[0];
|
||||
my $c = $a[1] // "";
|
||||
my $rsf = $a[2]."__";
|
||||
|
||||
if (AttrVal($hash->{NAME}, "readingNameMap", "")) {
|
||||
$reading_runtime_string = $rsf.AttrVal($hash->{NAME}, "readingNameMap", "")."__".$runtime_string;
|
||||
} else {
|
||||
my $ds = $device."__" if ($device);
|
||||
my $rds = $reading."__" if ($reading);
|
||||
}
|
||||
else {
|
||||
my $ds = $device. "__" if ($device);
|
||||
my $rds = $reading."__" if ($reading);
|
||||
$reading_runtime_string = $rsf.$ds.$rds."SUM__".$runtime_string;
|
||||
}
|
||||
|
||||
ReadingsBulkUpdateValue ($hash, $reading_runtime_string, $c?sprintf("%.4f",$c):"-");
|
||||
|
||||
ReadingsBulkUpdateValue ($hash, $reading_runtime_string, $c ne "" ? sprintf "%.4f", $c : "-");
|
||||
}
|
||||
|
||||
ReadingsBulkUpdateValue ($hash, "db_lines_processed", $irowdone) if($hash->{LASTCMD} =~ /writeToDB/);
|
||||
ReadingsBulkUpdateTimeState($hash,$brt,$rt,$state);
|
||||
readingsEndUpdate($hash, 1);
|
||||
ReadingsBulkUpdateValue ($hash, "db_lines_processed", $irowdone) if($hash->{LASTCMD} =~ /writeToDB/);
|
||||
ReadingsBulkUpdateTimeState ($hash, $brt, $rt, $state);
|
||||
|
||||
readingsEndUpdate ($hash, 1);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
####################################################################################################
|
||||
# nichtblockierendes DB delete
|
||||
@ -14042,8 +14044,8 @@ sub bdump {
|
||||
retrieve some important informations and the reading "state" switches to "connected" on success.
|
||||
If this attrbute is set, the initial database connection is executed not till then the
|
||||
DbRep device is processing its first command. <br>
|
||||
While the reading "state" is remaining in state "initialized" after FHEM-start.
|
||||
This approach my be helpful if a lot of DbRep devices are defined.
|
||||
While the reading "state" is remaining in state "initialized" after FHEM-start. <br>
|
||||
(default: 1 for TYPE Client)
|
||||
</li> <br>
|
||||
|
||||
<a name="fetchMarkDuplicates"></a>
|
||||
@ -16692,8 +16694,8 @@ sub bdump {
|
||||
benötigte Informationen abzurufen und das Reading "state" springt bei Erfolg auf "connected".
|
||||
Ist dieses Attribut gesetzt, erfolgt die initiale Datenbankverbindung erst dann wenn das
|
||||
DbRep-Device sein erstes Kommando ausführt. <br>
|
||||
Das Reading "state" verbleibt nach FHEM-Start solange im Status "initialized". Diese Einstellung
|
||||
kann hilfreich sein wenn viele DbRep-Devices definiert sind.
|
||||
Das Reading "state" verbleibt nach FHEM-Start solange im Status "initialized". <br>
|
||||
(default: 1 für TYPE Client)
|
||||
</li> <br>
|
||||
|
||||
<a name="fetchMarkDuplicates"></a>
|
||||
|
@ -1,9 +1,9 @@
|
||||
##########################################################################################################
|
||||
# $Id: 93_DbRep.pm 23163 2020-11-15 15:55:09Z DS_Starter $
|
||||
# $Id: 93_DbRep.pm 23214 2020-11-22 15:56:42Z DS_Starter $
|
||||
##########################################################################################################
|
||||
# 93_DbRep.pm
|
||||
#
|
||||
# (c) 2016-2020 by Heiko Maaz
|
||||
# (c) 2016-2021 by Heiko Maaz
|
||||
# e-mail: Heiko dot Maaz at t-online dot de
|
||||
#
|
||||
# This Module can be used to select and report content of databases written by 93_DbLog module
|
||||
@ -57,7 +57,9 @@ no if $] >= 5.017011, warnings => 'experimental::smartmatch';
|
||||
|
||||
# Version History intern
|
||||
my %DbRep_vNotesIntern = (
|
||||
"8.42.1" => "22.11.2020 fix delete \$hash->{HELPER}{REDUCELOG} ",
|
||||
"8.42.3" => "03.01.2021 set fastStart as default for TYPE Client ",
|
||||
"8.42.2" => "03.01.2021 sumValue - create 0 instaed of '-' if value of DS is 0, Forum:#index.php/topic,53584.msg1116910.html#msg1116910 ",
|
||||
"8.42.1" => "22.11.2020 fix delete \$hash->{HELPER}{REDUCELOG} Forum:#116057 ",
|
||||
"8.42.0" => "14.11.2020 new vals next_day_begin, next_day_end for time attr Forum: https://forum.fhem.de/index.php/topic,53584.msg1100040.html#msg1100040 ",
|
||||
"8.41.0" => "08.11.2020 new attrbute avgDailyMeanGWSwithGTS for Grassland temperature sum, minor bugfixes in create time array ",
|
||||
"8.40.8" => "17.09.2020 sqlCmd supports PREPARE statament Forum: #114293, commandRef revised ",
|
||||
@ -95,6 +97,7 @@ my %DbRep_vNotesIntern = (
|
||||
|
||||
# Version History extern:
|
||||
my %DbRep_vNotesExtern = (
|
||||
"8.42.3" => "03.01.2021 The attribute fastStart is set now as default for TYPE Client. This way the DbRep device only connects to the database when it has to process a task and not immediately when FHEM is started. ",
|
||||
"8.40.7" => "03.09.2020 The get Command \"dbValue\" has been renamed to \"sqlCmdBlocking\. You can use \"dbValue\" furthermore in your scripts, but it is ".
|
||||
"deprecated and will be removed soon. Please change your scripts to use \"sqlCmdBlocking\" instead. ",
|
||||
"8.40.4" => "23.07.2020 The new aggregation type 'minute' is now available. ",
|
||||
@ -339,7 +342,7 @@ sub DbRep_Initialize {
|
||||
"executeBeforeProc ".
|
||||
"executeAfterProc ".
|
||||
"expimpfile ".
|
||||
"fastStart:1,0 ".
|
||||
"fastStart:0,1 ".
|
||||
"fetchRoute:ascent,descent ".
|
||||
"fetchMarkDuplicates:red,blue,brown,green,orange ".
|
||||
"fetchValueFn:textField-long ".
|
||||
@ -1145,7 +1148,6 @@ sub DbRep_Attr {
|
||||
executeBeforeProc
|
||||
executeAfterProc
|
||||
expimpfile
|
||||
fastStart
|
||||
ftpUse
|
||||
ftpUser
|
||||
ftpUseSSL
|
||||
@ -1457,7 +1459,7 @@ sub DbRep_Notify {
|
||||
return if(!$events);
|
||||
|
||||
foreach my $event (@{$events}) {
|
||||
$event = "" if(!defined($event));
|
||||
$event = "" if(!defined($event));
|
||||
my @evl = split("[ \t][ \t]*", $event);
|
||||
|
||||
if($event =~ /DELETED/) {
|
||||
@ -1469,13 +1471,12 @@ sub DbRep_Notify {
|
||||
# wenn Rolle "Agent" Verbeitung von RENAMED Events
|
||||
next if ($event !~ /RENAMED/);
|
||||
|
||||
my $strucChanged;
|
||||
# altes in neues device in der DEF des angeschlossenen DbLog-device ändern (neues device loggen)
|
||||
my $strucChanged; # altes in neues device in der DEF des angeschlossenen DbLog-device ändern (neues device loggen)
|
||||
my $dblog_name = $own_hash->{HELPER}{DBLOGDEVICE}; # Name des an den DbRep-Agenten angeschlossenen DbLog-Dev
|
||||
my $dblog_hash = $defs{$dblog_name};
|
||||
|
||||
if ( $dblog_hash->{DEF} =~ m/( |\(|\|)$evl[1]( |\)|\||:)/ ) {
|
||||
$dblog_hash->{DEF} =~ s/$evl[1]/$evl[2]/;
|
||||
$dblog_hash->{DEF} =~ s/$evl[1]/$evl[2]/;
|
||||
$dblog_hash->{REGEXP} =~ s/$evl[1]/$evl[2]/;
|
||||
# Definitionsänderung wurde vorgenommen
|
||||
$strucChanged = 1;
|
||||
@ -1572,22 +1573,26 @@ return;
|
||||
# Verbindung zur DB aufbauen und Datenbankeigenschaften ermitteln
|
||||
###################################################################################
|
||||
sub DbRep_firstconnect {
|
||||
my ($string) = @_;
|
||||
my ($name,$opt,$prop,$fret) = split("\\|", $string);
|
||||
my $hash = $defs{$name};
|
||||
my $to = AttrVal($name, "timeout", "86400");
|
||||
my $dbloghash = $defs{$hash->{HELPER}{DBLOGDEVICE}};
|
||||
my $dbconn = $dbloghash->{dbconn};
|
||||
my $dbuser = $dbloghash->{dbuser};
|
||||
my $string = shift;
|
||||
|
||||
RemoveInternalTimer($hash, "DbRep_firstconnect");
|
||||
my ($name,$opt,$prop,$fret) = split("\\|", $string);
|
||||
my $hash = $defs{$name};
|
||||
my $to = AttrVal($name, "timeout", "86400");
|
||||
|
||||
RemoveInternalTimer ($hash, "DbRep_firstconnect");
|
||||
return if(IsDisabled($name));
|
||||
|
||||
if ($init_done == 1) {
|
||||
if (AttrVal($name, "fastStart", 0) && $prop eq "onBoot" ) {
|
||||
my $dbloghash = $defs{$hash->{HELPER}{DBLOGDEVICE}};
|
||||
my $dbconn = $dbloghash->{dbconn};
|
||||
my $dbuser = $dbloghash->{dbuser};
|
||||
my $fadef = $hash->{MODEL} eq "Client" ? 1 : 0; # fastStart default immer 1 für Clients (0 für Agenten)
|
||||
|
||||
if (AttrVal($name, "fastStart", $fadef) && $prop eq "onBoot" ) {
|
||||
$hash->{LASTCMD} = "initial database connect stopped due to attribute 'fastStart'";
|
||||
return;
|
||||
}
|
||||
|
||||
# DB Struktur aus DbLog Instanz übernehmen
|
||||
$hash->{HELPER}{DBREPCOL}{COLSET} = $dbloghash->{HELPER}{COLSET};
|
||||
$hash->{HELPER}{DBREPCOL}{DEVICE} = $dbloghash->{HELPER}{DEVICECOL};
|
||||
@ -1599,9 +1604,11 @@ sub DbRep_firstconnect {
|
||||
|
||||
# DB Strukturelemente abrufen
|
||||
Log3 ($name, 3, "DbRep $name - Connectiontest to database $dbconn with user $dbuser") if($hash->{LASTCMD} ne "minTimestamp");
|
||||
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("DbRep_getInitData", "$name|$opt|$prop|$fret", "DbRep_getInitDataDone", $to, "DbRep_getInitDataAborted", $hash);
|
||||
$hash->{HELPER}{RUNNING_PID}{loglevel} = 5 if($hash->{HELPER}{RUNNING_PID}); # Forum #77057
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
InternalTimer(time+1, "DbRep_firstconnect", "$name|$opt|$prop|$fret", 0);
|
||||
}
|
||||
|
||||
@ -1857,15 +1864,16 @@ sub DbRep_Main {
|
||||
DbRep_delread($hash);
|
||||
|
||||
if ($opt =~ /dumpMySQL|dumpSQLite/) {
|
||||
BlockingKill($hash->{HELPER}{RUNNING_BACKUP_CLIENT}) if (exists($hash->{HELPER}{RUNNING_BACKUP_CLIENT}));
|
||||
BlockingKill($hash->{HELPER}{RUNNING_BACKUP_CLIENT}) if (exists($hash->{HELPER}{RUNNING_BACKUP_CLIENT}));
|
||||
BlockingKill($hash->{HELPER}{RUNNING_BCKPREST_SERVER}) if (exists($hash->{HELPER}{RUNNING_BCKPREST_SERVER}));
|
||||
BlockingKill($hash->{HELPER}{RUNNING_OPTIMIZE}) if (exists($hash->{HELPER}{RUNNING_OPTIMIZE}));
|
||||
BlockingKill($hash->{HELPER}{RUNNING_OPTIMIZE}) if (exists($hash->{HELPER}{RUNNING_OPTIMIZE}));
|
||||
|
||||
if($dbmodel =~ /MYSQL/) {
|
||||
if ($prop eq "serverSide") {
|
||||
$hash->{HELPER}{RUNNING_BCKPREST_SERVER} = BlockingCall("mysql_DoDumpServerSide", "$name", "DbRep_DumpDone", $to, "DbRep_DumpAborted", $hash);
|
||||
ReadingsSingleUpdateValue ($hash, "state", "serverSide Dump is running - be patient and see Logfile !", 1);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$hash->{HELPER}{RUNNING_BACKUP_CLIENT} = BlockingCall("mysql_DoDumpClientSide", "$name", "DbRep_DumpDone", $to, "DbRep_DumpAborted", $hash);
|
||||
ReadingsSingleUpdateValue ($hash, "state", "clientSide Dump is running - be patient and see Logfile !", 1);
|
||||
}
|
||||
@ -1878,14 +1886,16 @@ sub DbRep_Main {
|
||||
}
|
||||
|
||||
if ($opt =~ /restoreMySQL/) {
|
||||
BlockingKill($hash->{HELPER}{RUNNING_RESTORE}) if (exists($hash->{HELPER}{RUNNING_RESTORE}));
|
||||
BlockingKill($hash->{HELPER}{RUNNING_RESTORE}) if (exists($hash->{HELPER}{RUNNING_RESTORE}));
|
||||
BlockingKill($hash->{HELPER}{RUNNING_OPTIMIZE}) if (exists($hash->{HELPER}{RUNNING_OPTIMIZE}));
|
||||
|
||||
if($prop =~ /csv/) {
|
||||
$hash->{HELPER}{RUNNING_RESTORE} = BlockingCall("mysql_RestoreServerSide", "$name|$prop", "DbRep_restoreDone", $to, "DbRep_restoreAborted", $hash);
|
||||
} elsif ($prop =~ /sql/) {
|
||||
}
|
||||
elsif ($prop =~ /sql/) {
|
||||
$hash->{HELPER}{RUNNING_RESTORE} = BlockingCall("mysql_RestoreClientSide", "$name|$prop", "DbRep_restoreDone", $to, "DbRep_restoreAborted", $hash);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
ReadingsSingleUpdateValue ($hash, "state", "restore database error - unknown fileextension \"$prop\"", 1);
|
||||
}
|
||||
|
||||
@ -1894,7 +1904,7 @@ sub DbRep_Main {
|
||||
}
|
||||
|
||||
if ($opt =~ /restoreSQLite/) {
|
||||
BlockingKill($hash->{HELPER}{RUNNING_RESTORE}) if (exists($hash->{HELPER}{RUNNING_RESTORE}));
|
||||
BlockingKill($hash->{HELPER}{RUNNING_RESTORE}) if (exists($hash->{HELPER}{RUNNING_RESTORE}));
|
||||
BlockingKill($hash->{HELPER}{RUNNING_OPTIMIZE}) if (exists($hash->{HELPER}{RUNNING_OPTIMIZE}));
|
||||
$hash->{HELPER}{RUNNING_RESTORE} = BlockingCall("DbRep_sqliteRestore", "$name|$prop", "DbRep_restoreDone", $to, "DbRep_restoreAborted", $hash);
|
||||
ReadingsSingleUpdateValue ($hash, "state", "restore database is running - be patient and see Logfile !", 1);
|
||||
@ -1903,7 +1913,7 @@ sub DbRep_Main {
|
||||
|
||||
if ($opt =~ /optimizeTables|vacuum/) {
|
||||
BlockingKill($hash->{HELPER}{RUNNING_OPTIMIZE}) if (exists($hash->{HELPER}{RUNNING_OPTIMIZE}));
|
||||
BlockingKill($hash->{HELPER}{RUNNING_RESTORE}) if (exists($hash->{HELPER}{RUNNING_RESTORE}));
|
||||
BlockingKill($hash->{HELPER}{RUNNING_RESTORE}) if (exists($hash->{HELPER}{RUNNING_RESTORE}));
|
||||
$hash->{HELPER}{RUNNING_OPTIMIZE} = BlockingCall("DbRep_optimizeTables", "$name", "DbRep_OptimizeDone", $to, "DbRep_OptimizeAborted", $hash);
|
||||
ReadingsSingleUpdateValue ($hash, "state", "optimize tables is running - be patient and see Logfile !", 1);
|
||||
return;
|
||||
@ -1911,8 +1921,8 @@ sub DbRep_Main {
|
||||
|
||||
if ($opt =~ /repairSQLite/) {
|
||||
BlockingKill($hash->{HELPER}{RUNNING_BACKUP_CLIENT}) if (exists($hash->{HELPER}{RUNNING_BACKUP_CLIENT}));
|
||||
BlockingKill($hash->{HELPER}{RUNNING_OPTIMIZE}) if (exists($hash->{HELPER}{RUNNING_OPTIMIZE}));
|
||||
BlockingKill($hash->{HELPER}{RUNNING_REPAIR}) if (exists($hash->{HELPER}{RUNNING_REPAIR}));
|
||||
BlockingKill($hash->{HELPER}{RUNNING_OPTIMIZE}) if (exists($hash->{HELPER}{RUNNING_OPTIMIZE}));
|
||||
BlockingKill($hash->{HELPER}{RUNNING_REPAIR}) if (exists($hash->{HELPER}{RUNNING_REPAIR}));
|
||||
$hash->{HELPER}{RUNNING_REPAIR} = BlockingCall("DbRep_sqliteRepair", "$name", "DbRep_RepairDone", $to, "DbRep_RepairAborted", $hash);
|
||||
ReadingsSingleUpdateValue ($hash, "state", "repair database is running - be patient and see Logfile !", 1);
|
||||
return;
|
||||
@ -1962,7 +1972,8 @@ sub DbRep_Main {
|
||||
|
||||
if($IsTimeSet || $IsAggrSet) {
|
||||
($epoch_seconds_begin,$epoch_seconds_end,$runtime_string_first,$runtime_string_next,$ts) = DbRep_createTimeArray($hash,$aggregation,$opt);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
Log3 ($name, 4, "DbRep $name - Timestamp begin human readable: not set") if($opt !~ /tableCurrentPurge/);
|
||||
Log3 ($name, 4, "DbRep $name - Timestamp end human readable: not set") if($opt !~ /tableCurrentPurge/);
|
||||
}
|
||||
@ -1973,45 +1984,45 @@ sub DbRep_Main {
|
||||
#############################
|
||||
if ($opt eq "sumValue") {
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("sumval_DoParse", "$name§$device§$reading§$prop§$ts", "sumval_ParseDone", $to, "DbRep_ParseAborted", $hash);
|
||||
|
||||
} elsif ($opt =~ m/countEntries/) {
|
||||
}
|
||||
elsif ($opt =~ m/countEntries/) {
|
||||
my $table = $prop;
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("count_DoParse", "$name§$table§$device§$reading§$ts", "count_ParseDone", $to, "DbRep_ParseAborted", $hash);
|
||||
|
||||
} elsif ($opt eq "averageValue") {
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("count_DoParse", "$name§$table§$device§$reading§$ts", "count_ParseDone", $to, "DbRep_ParseAborted", $hash);
|
||||
}
|
||||
elsif ($opt eq "averageValue") {
|
||||
Log3 ($name, 4, "DbRep $name - averageValue calculation sceme: ".AttrVal($name,"averageCalcForm","avgArithmeticMean"));
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("averval_DoParse", "$name§$device§$reading§$prop§$ts", "averval_ParseDone", $to, "DbRep_ParseAborted", $hash);
|
||||
|
||||
} elsif ($opt eq "fetchrows") {
|
||||
}
|
||||
elsif ($opt eq "fetchrows") {
|
||||
my $table = $prop;
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("fetchrows_DoParse", "$name|$table|$device|$reading|$runtime_string_first|$runtime_string_next", "fetchrows_ParseDone", $to, "DbRep_ParseAborted", $hash);
|
||||
|
||||
} elsif ($opt =~ /delDoublets/) {
|
||||
}
|
||||
elsif ($opt =~ /delDoublets/) {
|
||||
my $cmd = $prop?$prop:"adviceDelete";
|
||||
# delseqdoubl_ParseDone ist Auswertefunktion auch für delDoublets
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("deldoublets_DoParse", "$name§$cmd§$device§$reading§$ts", "delseqdoubl_ParseDone", $to, "DbRep_ParseAborted", $hash);
|
||||
|
||||
} elsif ($opt =~ /delSeqDoublets/) {
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("deldoublets_DoParse", "$name§$cmd§$device§$reading§$ts", "delseqdoubl_ParseDone", $to, "DbRep_ParseAborted", $hash);
|
||||
}
|
||||
elsif ($opt =~ /delSeqDoublets/) {
|
||||
my $cmd = $prop?$prop:"adviceRemain";
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("delseqdoubl_DoParse", "$name§$cmd§$device§$reading§$ts", "delseqdoubl_ParseDone", $to, "DbRep_ParseAborted", $hash);
|
||||
|
||||
} elsif ($opt eq "exportToFile") {
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("delseqdoubl_DoParse", "$name§$cmd§$device§$reading§$ts", "delseqdoubl_ParseDone", $to, "DbRep_ParseAborted", $hash);
|
||||
}
|
||||
elsif ($opt eq "exportToFile") {
|
||||
my $file = $prop;
|
||||
DbRep_beforeproc($hash, "export");
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("expfile_DoParse", "$name§$device§$reading§$runtime_string_first§$file§$ts", "expfile_ParseDone", $to, "DbRep_ParseAborted", $hash);
|
||||
|
||||
} elsif ($opt eq "importFromFile") {
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("expfile_DoParse", "$name§$device§$reading§$runtime_string_first§$file§$ts", "expfile_ParseDone", $to, "DbRep_ParseAborted", $hash);
|
||||
}
|
||||
elsif ($opt eq "importFromFile") {
|
||||
my $file = $prop;
|
||||
DbRep_beforeproc($hash, "import");
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("impfile_Push", "$name|$runtime_string_first|$file", "impfile_PushDone", $to, "DbRep_ParseAborted", $hash);
|
||||
|
||||
} elsif ($opt eq "maxValue") {
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("maxval_DoParse", "$name§$device§$reading§$prop§$ts", "maxval_ParseDone", $to, "DbRep_ParseAborted", $hash);
|
||||
|
||||
} elsif ($opt eq "minValue") {
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("minval_DoParse", "$name§$device§$reading§$prop§$ts", "minval_ParseDone", $to, "DbRep_ParseAborted", $hash);
|
||||
|
||||
} elsif ($opt eq "delEntries") {
|
||||
}
|
||||
elsif ($opt eq "maxValue") {
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("maxval_DoParse", "$name§$device§$reading§$prop§$ts", "maxval_ParseDone", $to, "DbRep_ParseAborted", $hash);
|
||||
}
|
||||
elsif ($opt eq "minValue") {
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("minval_DoParse", "$name§$device§$reading§$prop§$ts", "minval_ParseDone", $to, "DbRep_ParseAborted", $hash);
|
||||
}
|
||||
elsif ($opt eq "delEntries") {
|
||||
delete $hash->{HELPER}{DELENTRIES};
|
||||
if($IsTimeSet || $IsAggrSet) { # Forum:#113202
|
||||
my ($yyyy1, $mm1, $dd1, $hh1, $min1, $sec1) = $runtime_string_first =~ /(\d+)-(\d+)-(\d+)\s(\d+):(\d+):(\d+)/x;
|
||||
@ -2024,20 +2035,20 @@ sub DbRep_Main {
|
||||
}
|
||||
}
|
||||
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("del_DoParse", "$name|history|$device|$reading|$runtime_string_first|$runtime_string_next", "del_ParseDone", $to, "DbRep_ParseAborted", $hash);
|
||||
|
||||
} elsif ($opt eq "tableCurrentPurge") {
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("del_DoParse", "$name|history|$device|$reading|$runtime_string_first|$runtime_string_next", "del_ParseDone", $to, "DbRep_ParseAborted", $hash);
|
||||
}
|
||||
elsif ($opt eq "tableCurrentPurge") {
|
||||
undef $runtime_string_first;
|
||||
undef $runtime_string_next;
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("del_DoParse", "$name|current|$device|$reading|$runtime_string_first|$runtime_string_next", "del_ParseDone", $to, "DbRep_ParseAborted", $hash);
|
||||
|
||||
} elsif ($opt eq "tableCurrentFillup") {
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("currentfillup_Push", "$name|$device|$reading|$runtime_string_first|$runtime_string_next", "currentfillup_Done", $to, "DbRep_ParseAborted", $hash);
|
||||
|
||||
} elsif ($opt eq "diffValue") {
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("diffval_DoParse", "$name§$device§$reading§$prop§$ts", "diffval_ParseDone", $to, "DbRep_ParseAborted", $hash);
|
||||
|
||||
} elsif ($opt eq "insert") {
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("del_DoParse", "$name|current|$device|$reading|$runtime_string_first|$runtime_string_next", "del_ParseDone", $to, "DbRep_ParseAborted", $hash);
|
||||
}
|
||||
elsif ($opt eq "tableCurrentFillup") {
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("currentfillup_Push", "$name|$device|$reading|$runtime_string_first|$runtime_string_next", "currentfillup_Done", $to, "DbRep_ParseAborted", $hash);
|
||||
}
|
||||
elsif ($opt eq "diffValue") {
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("diffval_DoParse", "$name§$device§$reading§$prop§$ts", "diffval_ParseDone", $to, "DbRep_ParseAborted", $hash);
|
||||
}
|
||||
elsif ($opt eq "insert") {
|
||||
# Daten auf maximale Länge (entsprechend der Feldlänge in DbLog) beschneiden wenn nicht SQLite
|
||||
if ($dbmodel ne 'SQLITE') {
|
||||
$hash->{HELPER}{I_DEVICE} = substr($hash->{HELPER}{I_DEVICE},0, $hash->{HELPER}{DBREPCOL}{DEVICE});
|
||||
@ -2045,16 +2056,15 @@ sub DbRep_Main {
|
||||
$hash->{HELPER}{I_VALUE} = substr($hash->{HELPER}{I_VALUE},0, $hash->{HELPER}{DBREPCOL}{VALUE});
|
||||
$hash->{HELPER}{I_UNIT} = substr($hash->{HELPER}{I_UNIT},0, $hash->{HELPER}{DBREPCOL}{UNIT}) if($hash->{HELPER}{I_UNIT});
|
||||
}
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("insert_Push", "$name", "insert_Done", $to, "DbRep_ParseAborted", $hash);
|
||||
|
||||
} elsif ($opt =~ /deviceRename|readingRename/) {
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("change_Push", "$name|$device|$reading|$runtime_string_first|$runtime_string_next", "change_Done", $to, "DbRep_ParseAborted", $hash);
|
||||
|
||||
} elsif ($opt =~ /changeValue/) {
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("changeval_Push", "$name§$device§$reading§$runtime_string_first§$runtime_string_next§$ts", "change_Done", $to, "DbRep_ParseAborted", $hash);
|
||||
|
||||
} elsif ($opt =~ /sqlCmd|sqlSpecial/ ) {
|
||||
# Execute a generic sql command or special sql
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("insert_Push", "$name", "insert_Done", $to, "DbRep_ParseAborted", $hash);
|
||||
}
|
||||
elsif ($opt =~ /deviceRename|readingRename/) {
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("change_Push", "$name|$device|$reading|$runtime_string_first|$runtime_string_next", "change_Done", $to, "DbRep_ParseAborted", $hash);
|
||||
}
|
||||
elsif ($opt =~ /changeValue/) {
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("changeval_Push", "$name§$device§$reading§$runtime_string_first§$runtime_string_next§$ts", "change_Done", $to, "DbRep_ParseAborted", $hash);
|
||||
}
|
||||
elsif ($opt =~ /sqlCmd|sqlSpecial/ ) { # Execute a generic sql command or special sql
|
||||
if ($opt =~ /sqlSpecial/) {
|
||||
my ($tq,$gcl);
|
||||
|
||||
@ -2062,14 +2072,14 @@ sub DbRep_Main {
|
||||
$prop = "select Device, reading, count(0) AS `countA` from history where ( TIMESTAMP > (now() - interval 2 day)) group by DEVICE, READING order by countA desc, DEVICE limit 50;" if($dbmodel =~ /MYSQL/);
|
||||
$prop = "select Device, reading, count(0) AS `countA` from history where ( TIMESTAMP > ('now' - '2 days')) group by DEVICE, READING order by countA desc, DEVICE limit 50;" if($dbmodel =~ /SQLITE/);
|
||||
$prop = "select Device, reading, count(0) AS countA from history where ( TIMESTAMP > (NOW() - INTERVAL '2' DAY)) group by DEVICE, READING order by countA desc, DEVICE limit 50;" if($dbmodel =~ /POSTGRESQL/);
|
||||
|
||||
} elsif ($prop eq "allDevReadCount") {
|
||||
}
|
||||
elsif ($prop eq "allDevReadCount") {
|
||||
$prop = "select device, reading, count(*) from history group by DEVICE, READING;";
|
||||
|
||||
} elsif ($prop eq "allDevCount") {
|
||||
}
|
||||
elsif ($prop eq "allDevCount") {
|
||||
$prop = "select device, count(*) from history group by DEVICE;";
|
||||
|
||||
} elsif ($prop eq "recentReadingsOfDevice") {
|
||||
}
|
||||
elsif ($prop eq "recentReadingsOfDevice") {
|
||||
if($dbmodel =~ /MYSQL/) {$tq = "NOW() - INTERVAL 1 DAY"; $gcl = "READING"};
|
||||
if($dbmodel =~ /SQLITE/) {$tq = "datetime('now','-1 day')"; $gcl = "READING"};
|
||||
if($dbmodel =~ /POSTGRESQL/) {$tq = "CURRENT_TIMESTAMP - INTERVAL '1 day'"; $gcl = "READING,DEVICE"};
|
||||
@ -2084,8 +2094,8 @@ sub DbRep_Main {
|
||||
x.READING = t1.READING;");
|
||||
|
||||
$prop = join(" ", @cmd);
|
||||
|
||||
} elsif ($prop eq "readingsDifferenceByTimeDelta") {
|
||||
}
|
||||
elsif ($prop eq "readingsDifferenceByTimeDelta") {
|
||||
my @cmd = split(/\s/, "SET \@diff=0;
|
||||
SET \@delta=NULL;
|
||||
SELECT t1.TIMESTAMP,t1.READING,t1.VALUE,t1.DIFF,t1.TIME_DELTA
|
||||
@ -2107,15 +2117,13 @@ sub DbRep_Main {
|
||||
}
|
||||
}
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("sqlCmd_DoParse", "$name|$opt|$runtime_string_first|$runtime_string_next|$prop", "sqlCmd_ParseDone", $to, "DbRep_ParseAborted", $hash);
|
||||
|
||||
} elsif ($opt =~ /syncStandby/ ) {
|
||||
# Befehl vor Procedure ausführen
|
||||
DbRep_beforeproc($hash, "syncStandby");
|
||||
}
|
||||
elsif ($opt =~ /syncStandby/ ) {
|
||||
DbRep_beforeproc($hash, "syncStandby"); # Befehl vor Procedure ausführen
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("DbRep_syncStandby", "$name§$device§$reading§$runtime_string_first§$runtime_string_next§$ts§$prop", "DbRep_syncStandbyDone", $to, "DbRep_ParseAborted", $hash);
|
||||
}
|
||||
|
||||
if ($opt =~ /reduceLog/) {
|
||||
# delete $hash->{HELPER}{REDUCELOG};
|
||||
my ($yyyy1, $mm1, $dd1, $hh1, $min1, $sec1) = $runtime_string_first =~ /(\d+)-(\d+)-(\d+)\s(\d+):(\d+):(\d+)/x;
|
||||
my ($yyyy2, $mm2, $dd2, $hh2, $min2, $sec2) = $runtime_string_next =~ /(\d+)-(\d+)-(\d+)\s(\d+):(\d+):(\d+)/x;
|
||||
my $nthants = fhemTimeLocal($sec1, $min1, $hh1, $dd1, $mm1-1, $yyyy1-1900);
|
||||
@ -4277,10 +4285,10 @@ return;
|
||||
}
|
||||
|
||||
####################################################################################################
|
||||
# nichtblockierende DB-Abfrage sumValue
|
||||
# nichtblockierende DB-Abfrage sumValue
|
||||
####################################################################################################
|
||||
sub sumval_DoParse {
|
||||
my ($string) = @_;
|
||||
my $string = shift;
|
||||
my ($name,$device,$reading,$prop,$ts) = split("\\§", $string);
|
||||
my $hash = $defs{$name};
|
||||
my $dbloghash = $defs{$hash->{HELPER}{DBLOGDEVICE}};
|
||||
@ -4288,6 +4296,7 @@ sub sumval_DoParse {
|
||||
my $dbuser = $dbloghash->{dbuser};
|
||||
my $dblogname = $dbloghash->{NAME};
|
||||
my $dbpassword = $attr{"sec$dblogname"}{secret};
|
||||
|
||||
my ($dbh,$sql,$sth,$err,$selspec);
|
||||
|
||||
# Background-Startzeit
|
||||
@ -4300,42 +4309,40 @@ sub sumval_DoParse {
|
||||
return "$name|''|$device|$reading|''|$err|''";
|
||||
}
|
||||
|
||||
# only for this block because of warnings if details of readings are not set
|
||||
no warnings 'uninitialized';
|
||||
|
||||
# ist Zeiteingrenzung und/oder Aggregation gesetzt ? (wenn ja -> "?" in SQL sonst undef)
|
||||
my ($IsTimeSet,$IsAggrSet) = DbRep_checktimeaggr($hash);
|
||||
no warnings 'uninitialized'; # only for this block because of warnings if details of readings are not set
|
||||
|
||||
my ($IsTimeSet,$IsAggrSet) = DbRep_checktimeaggr($hash); # ist Zeiteingrenzung und/oder Aggregation gesetzt ? (wenn ja -> "?" in SQL sonst undef)
|
||||
Log3 ($name, 5, "DbRep $name - IsTimeSet: $IsTimeSet, IsAggrSet: $IsAggrSet");
|
||||
|
||||
# Timestampstring to Array
|
||||
my @ts = split("\\|", $ts);
|
||||
my @ts = split("\\|", $ts); # Timestampstring to Array
|
||||
Log3 ($name, 5, "DbRep $name - Timestamp-Array: \n@ts");
|
||||
|
||||
#vorbereiten der DB-Abfrage, DB-Modell-abhaengig
|
||||
if ($dbloghash->{MODEL} eq "POSTGRESQL") {
|
||||
if ($dbloghash->{MODEL} eq "POSTGRESQL") { #vorbereiten der DB-Abfrage, DB-Modell-abhaengig
|
||||
$selspec = "SUM(VALUE::numeric)";
|
||||
} elsif ($dbloghash->{MODEL} eq "MYSQL") {
|
||||
}
|
||||
elsif ($dbloghash->{MODEL} eq "MYSQL") {
|
||||
$selspec = "SUM(VALUE)";
|
||||
} elsif ($dbloghash->{MODEL} eq "SQLITE") {
|
||||
}
|
||||
elsif ($dbloghash->{MODEL} eq "SQLITE") {
|
||||
$selspec = "SUM(VALUE)";
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$selspec = "SUM(VALUE)";
|
||||
}
|
||||
|
||||
# SQL-Startzeit
|
||||
my $st = [gettimeofday];
|
||||
my $st = [gettimeofday]; # SQL-Startzeit
|
||||
|
||||
# DB-Abfrage zeilenweise für jeden Array-Eintrag
|
||||
my ($arrstr,$wrstr,@rsf,@rsn,@wsf,@wsn);
|
||||
foreach my $row (@ts) {
|
||||
my @a = split("#", $row);
|
||||
my $runtime_string = $a[0];
|
||||
my $runtime_string_first = $a[1];
|
||||
my $runtime_string_next = $a[2];
|
||||
for my $row (@ts) { # DB-Abfrage zeilenweise für jeden Array-Eintrag
|
||||
my @a = split("#", $row);
|
||||
my $runtime_string = $a[0];
|
||||
my $runtime_string_first = $a[1];
|
||||
my $runtime_string_next = $a[2];
|
||||
|
||||
if ($IsTimeSet || $IsAggrSet) {
|
||||
$sql = DbRep_createSelectSql($hash,"history",$selspec,$device,$reading,"'$runtime_string_first'","'$runtime_string_next'",'');
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$sql = DbRep_createSelectSql($hash,"history",$selspec,$device,$reading,undef,undef,'');
|
||||
}
|
||||
Log3 ($name, 4, "DbRep $name - SQL execute: $sql");
|
||||
@ -4350,8 +4357,7 @@ sub sumval_DoParse {
|
||||
return "$name|''|$device|$reading|''|$err|''";
|
||||
}
|
||||
|
||||
# DB-Abfrage -> Ergebnis in @arr aufnehmen
|
||||
my @line = $sth->fetchrow_array();
|
||||
my @line = $sth->fetchrow_array(); # DB-Abfrage -> Ergebnis in @arr aufnehmen
|
||||
|
||||
Log3 ($name, 5, "DbRep $name - SQL result: $line[0]") if($line[0]);
|
||||
|
||||
@ -4359,7 +4365,8 @@ sub sumval_DoParse {
|
||||
@rsf = split(/[ :]/,$runtime_string_first);
|
||||
@rsn = split(/[ :]/,$runtime_string_next);
|
||||
$arrstr .= $runtime_string."#".$line[0]."#".$rsf[0]."_".$rsf[1]."|";
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
@rsf = split(" ",$runtime_string_first);
|
||||
@rsn = split(" ",$runtime_string_next);
|
||||
$arrstr .= $runtime_string."#".$line[0]."#".$rsf[0]."|";
|
||||
@ -4372,11 +4379,9 @@ sub sumval_DoParse {
|
||||
$sth->finish;
|
||||
$dbh->disconnect;
|
||||
|
||||
# SQL-Laufzeit ermitteln
|
||||
my $rt = tv_interval($st);
|
||||
my $rt = tv_interval($st); # SQL-Laufzeit ermitteln
|
||||
|
||||
# Ergebnisse in Datenbank schreiben
|
||||
my ($wrt,$irowdone);
|
||||
my ($wrt,$irowdone); # Ergebnisse in Datenbank schreiben
|
||||
if($prop =~ /writeToDB/) {
|
||||
($wrt,$irowdone,$err) = DbRep_OutputWriteToDB($name,$device,$reading,$wrstr,"sum");
|
||||
if ($err) {
|
||||
@ -4387,12 +4392,10 @@ sub sumval_DoParse {
|
||||
$rt = $rt+$wrt;
|
||||
}
|
||||
|
||||
# Daten müssen als Einzeiler zurückgegeben werden
|
||||
$arrstr = encode_base64($arrstr,"");
|
||||
$arrstr = encode_base64($arrstr,""); # Daten müssen als Einzeiler zurückgegeben werden
|
||||
$device = encode_base64($device,"");
|
||||
|
||||
# Background-Laufzeit ermitteln
|
||||
my $brt = tv_interval($bst);
|
||||
my $brt = tv_interval($bst); # Background-Laufzeit ermitteln
|
||||
|
||||
$rt = $rt.",".$brt;
|
||||
|
||||
@ -4403,7 +4406,7 @@ sub sumval_DoParse {
|
||||
# Auswertungsroutine der nichtblockierenden DB-Abfrage sumValue
|
||||
####################################################################################################
|
||||
sub sumval_ParseDone {
|
||||
my ($string) = @_;
|
||||
my $string = shift;
|
||||
my @a = split("\\|",$string);
|
||||
my $hash = $defs{$a[0]};
|
||||
my $name = $hash->{NAME};
|
||||
@ -4414,53 +4417,53 @@ sub sumval_ParseDone {
|
||||
$reading =~ s/[^A-Za-z\/\d_\.-]/\//g;
|
||||
my $bt = $a[4];
|
||||
my ($rt,$brt) = split(",", $bt);
|
||||
my $err = $a[5]?decode_base64($a[5]):undef;
|
||||
my $err = $a[5] ? decode_base64($a[5]) : undef;
|
||||
my $irowdone = $a[6];
|
||||
my $reading_runtime_string;
|
||||
my $erread;
|
||||
|
||||
my ($reading_runtime_string,$erread);
|
||||
|
||||
delete($hash->{HELPER}{RUNNING_PID});
|
||||
|
||||
# Befehl nach Procedure ausführen
|
||||
$erread = DbRep_afterproc($hash, "$hash->{LASTCMD}");
|
||||
$erread = DbRep_afterproc($hash, "$hash->{LASTCMD}"); # Befehl nach Procedure ausführen
|
||||
|
||||
if ($err) {
|
||||
ReadingsSingleUpdateValue ($hash, "errortext", $err, 1);
|
||||
ReadingsSingleUpdateValue ($hash, "state", "error", 1);
|
||||
ReadingsSingleUpdateValue ($hash, "state", "error", 1);
|
||||
return;
|
||||
}
|
||||
|
||||
# only for this block because of warnings if details of readings are not set
|
||||
no warnings 'uninitialized';
|
||||
no warnings 'uninitialized'; # only for this block because of warnings if details of readings are not set
|
||||
|
||||
# Readingaufbereitung
|
||||
my $state = $erread?$erread:"done";
|
||||
readingsBeginUpdate($hash);
|
||||
my $state = $erread // "done";
|
||||
|
||||
readingsBeginUpdate ($hash);
|
||||
|
||||
my @arr = split("\\|", $arrstr);
|
||||
foreach my $row (@arr) {
|
||||
my @a = split("#", $row);
|
||||
my $runtime_string = $a[0];
|
||||
my $c = $a[1];
|
||||
my $rsf = $a[2]."__";
|
||||
for my $row (@arr) {
|
||||
my @a = split("#", $row);
|
||||
my $runtime_string = $a[0];
|
||||
my $c = $a[1] // "";
|
||||
my $rsf = $a[2]."__";
|
||||
|
||||
if (AttrVal($hash->{NAME}, "readingNameMap", "")) {
|
||||
$reading_runtime_string = $rsf.AttrVal($hash->{NAME}, "readingNameMap", "")."__".$runtime_string;
|
||||
} else {
|
||||
my $ds = $device."__" if ($device);
|
||||
my $rds = $reading."__" if ($reading);
|
||||
}
|
||||
else {
|
||||
my $ds = $device. "__" if ($device);
|
||||
my $rds = $reading."__" if ($reading);
|
||||
$reading_runtime_string = $rsf.$ds.$rds."SUM__".$runtime_string;
|
||||
}
|
||||
|
||||
ReadingsBulkUpdateValue ($hash, $reading_runtime_string, $c?sprintf("%.4f",$c):"-");
|
||||
|
||||
ReadingsBulkUpdateValue ($hash, $reading_runtime_string, $c ne "" ? sprintf "%.4f", $c : "-");
|
||||
}
|
||||
|
||||
ReadingsBulkUpdateValue ($hash, "db_lines_processed", $irowdone) if($hash->{LASTCMD} =~ /writeToDB/);
|
||||
ReadingsBulkUpdateTimeState($hash,$brt,$rt,$state);
|
||||
readingsEndUpdate($hash, 1);
|
||||
ReadingsBulkUpdateValue ($hash, "db_lines_processed", $irowdone) if($hash->{LASTCMD} =~ /writeToDB/);
|
||||
ReadingsBulkUpdateTimeState ($hash, $brt, $rt, $state);
|
||||
|
||||
readingsEndUpdate ($hash, 1);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
####################################################################################################
|
||||
# nichtblockierendes DB delete
|
||||
@ -11664,12 +11667,12 @@ sub DbRep_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{SMAPortal}{META}}
|
||||
if($modules{$type}{META}{x_version}) { # {x_version} ( nur gesetzt wenn $Id: 93_DbRep.pm 23163 2020-11-15 15:55:09Z DS_Starter $ im Kopf komplett! vorhanden )
|
||||
if($modules{$type}{META}{x_version}) { # {x_version} ( nur gesetzt wenn $Id: 93_DbRep.pm 23214 2020-11-22 15:56:42Z DS_Starter $ im Kopf komplett! vorhanden )
|
||||
$modules{$type}{META}{x_version} =~ s/1.1.1/$v/g;
|
||||
} else {
|
||||
$modules{$type}{META}{x_version} = $v;
|
||||
}
|
||||
return $@ unless (FHEM::Meta::SetInternals($hash)); # FVERSION wird gesetzt ( nur gesetzt wenn $Id: 93_DbRep.pm 23163 2020-11-15 15:55:09Z DS_Starter $ im Kopf komplett! vorhanden )
|
||||
return $@ unless (FHEM::Meta::SetInternals($hash)); # FVERSION wird gesetzt ( nur gesetzt wenn $Id: 93_DbRep.pm 23214 2020-11-22 15:56:42Z 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
|
||||
@ -14041,8 +14044,8 @@ sub bdump {
|
||||
retrieve some important informations and the reading "state" switches to "connected" on success.
|
||||
If this attrbute is set, the initial database connection is executed not till then the
|
||||
DbRep device is processing its first command. <br>
|
||||
While the reading "state" is remaining in state "initialized" after FHEM-start.
|
||||
This approach my be helpful if a lot of DbRep devices are defined.
|
||||
While the reading "state" is remaining in state "initialized" after FHEM-start. <br>
|
||||
(default: 1 for TYPE Client)
|
||||
</li> <br>
|
||||
|
||||
<a name="fetchMarkDuplicates"></a>
|
||||
@ -16691,8 +16694,8 @@ sub bdump {
|
||||
benötigte Informationen abzurufen und das Reading "state" springt bei Erfolg auf "connected".
|
||||
Ist dieses Attribut gesetzt, erfolgt die initiale Datenbankverbindung erst dann wenn das
|
||||
DbRep-Device sein erstes Kommando ausführt. <br>
|
||||
Das Reading "state" verbleibt nach FHEM-Start solange im Status "initialized". Diese Einstellung
|
||||
kann hilfreich sein wenn viele DbRep-Devices definiert sind.
|
||||
Das Reading "state" verbleibt nach FHEM-Start solange im Status "initialized". <br>
|
||||
(default: 1 für TYPE Client)
|
||||
</li> <br>
|
||||
|
||||
<a name="fetchMarkDuplicates"></a>
|
||||
|
Loading…
x
Reference in New Issue
Block a user