diff --git a/fhem/contrib/DS_Starter/93_DbRep.pm b/fhem/contrib/DS_Starter/93_DbRep.pm
index 391ea8847..dcf327f94 100644
--- a/fhem/contrib/DS_Starter/93_DbRep.pm
+++ b/fhem/contrib/DS_Starter/93_DbRep.pm
@@ -406,7 +406,8 @@ my $dbrep_defdecplaces = 4;
my $dbrep_dump_path_def = $attr{global}{modpath}."/log/"; # default Pfad für local Dumps
my $dbrep_dump_remotepath_def = "./"; # default Pfad für remote Dumps
my $dbrep_fName = $attr{global}{modpath}."/FHEM/FhemUtils/cacheDbRep"; # default Pfad/Name SQL Cache File
-
+my $dbrep_deftonbl = 86400; # default Timeout non-blocking Operationen
+my $dbrep_deftobl = 10; # default Timeout blocking Operationen
###################################################################################
@@ -1199,7 +1200,7 @@ sub _DbRep_sqlFormOnline {
my $name = $hash->{NAME};
my $fs = AttrVal ($name, 'sqlFormatService', 'none');
-
+
return $sqlcmd if($fs eq 'none');
if ($fs eq 'https://sqlformat.org') {
@@ -1209,7 +1210,7 @@ sub _DbRep_sqlFormOnline {
my @cmds = split ';', $sqlcmd;
my $newcmd;
-
+
for my $part (@cmds) {
$part = urlEncode ($part);
my ($err, $dat) = HttpUtils_BlockingGet ({ url => $fs,
@@ -1262,7 +1263,7 @@ sub DbRep_Get {
my $dbloghash = $defs{$hash->{HELPER}{DBLOGDEVICE}};
my $dbmodel = $dbloghash->{MODEL};
my $dbname = $hash->{DATABASE};
- my $to = AttrVal($name, "timeout", "86400");
+ my $to = AttrVal ($name, 'timeout', $dbrep_deftonbl);
my $getlist = "Unknown argument $opt, choose one of ".
"svrinfo:noArg ".
@@ -1327,9 +1328,9 @@ sub DbRep_Get {
return qq{get "$opt" needs at least an argument} if ( @a < 3 );
my @cmd = @a;
- shift @cmd;
shift @cmd;
-
+ shift @cmd;
+
my $sqlcmd = join ' ', @cmd;
$sqlcmd =~ tr/ A-Za-z0-9!"#$§%&'()*+,-.\/:;<=>?@[\\]^_`{|}~äöüÄÖÜ߀/ /cs;
$sqlcmd .= ';' if ($sqlcmd !~ m/\;$/xs);
@@ -1953,7 +1954,7 @@ sub DbRep_firstconnect {
my $string = shift;
my ($name,$opt,$prop,$fret) = split("\\|", $string);
my $hash = $defs{$name};
- my $to = AttrVal($name, "timeout", "86400");
+ my $to = AttrVal ($name, 'timeout', $dbrep_deftonbl);
RemoveInternalTimer ($hash, "DbRep_firstconnect");
return if(IsDisabled($name));
@@ -2292,9 +2293,9 @@ sub DbRep_Main {
my $opt = shift;
my $prop = shift // q{};
my $name = $hash->{NAME};
- my $to = AttrVal($name, "timeout", "86400");
- my $reading = AttrVal($name, "reading", "%");
- my $device = AttrVal($name, "device", "%");
+ my $to = AttrVal ($name, 'timeout', $dbrep_deftonbl);
+ my $reading = AttrVal ($name, 'reading', '%');
+ my $device = AttrVal ($name, 'device', '%');
my $dbloghash = $defs{$hash->{HELPER}{DBLOGDEVICE}};
my $dbmodel = $dbloghash->{MODEL};
@@ -6626,7 +6627,7 @@ sub DbRep_sqlCmd {
if($pm !~ /PRAGMA|SET/i) {
next;
}
-
+
$pm = ltrim($pm).';';
$pm =~ s/ESC_ESC_ESC/;/gx; # wiederherstellen von escapeten ";" -> umwandeln von ";;" in ";"
@@ -6680,7 +6681,7 @@ sub DbRep_sqlCmd {
if($sql =~ /^\s*PREPARE.*;/i) {
@pms = split ';', $sql;
$sql = q{};
-
+
for my $pm (@pms) {
if($pm !~ /PREPARE/i) {
$sql .= $pm.';';
@@ -6766,6 +6767,261 @@ sub DbRep_sqlCmd {
return "$name|$err|$rowstring|$opt|$cmd|$nrows|$rt";
}
+####################################################################################################
+# blockierende DB-Abfrage
+# liefert Ergebnis sofort zurück, setzt keine Readings
+####################################################################################################
+sub DbRep_sqlCmdBlocking {
+ my $name = shift;
+ my $cmd = shift;
+
+ my $hash = $defs{$name};
+ my $srs = AttrVal ($name, 'sqlResultFieldSep', '|');
+ my $to = AttrVal ($name, 'timeout', $dbrep_deftobl);
+
+ my ($ret);
+
+ readingsDelete ($hash, "errortext");
+ ReadingsSingleUpdateValue ($hash, "state", "running", 1);
+
+ my ($err,$dbh,$dbmodel) = DbRep_dbConnect($name);
+ if ($err) {
+ $err = decode_base64 ($err);
+
+ Log3 ($name, 2, "DbRep $name - ERROR - $err");
+
+ readingsBeginUpdate ($hash);
+ ReadingsBulkUpdateValue ($hash, 'errortext', $err);
+ ReadingsBulkUpdateValue ($hash, 'state', 'error');
+ readingsEndUpdate ($hash, 1);
+
+ return $err;
+ }
+
+ $cmd =~ s/\;\;/ESC_ESC_ESC/gx; # ersetzen von escapeten ";" (;;)
+
+ $cmd .= ";" if ($cmd !~ m/\;$/x);
+ my $sql = $cmd;
+
+ Log3 ($name, 4, "DbRep $name - -------- New selection --------- ");
+ Log3 ($name, 4, "DbRep $name - sqlCmdBlocking Command:\n$sql");
+
+ my @pms;
+ my $vars = AttrVal($name, "sqlCmdVars", ""); # Set Session Variablen "SET" oder PRAGMA aus Attribut "sqlCmdVars"
+
+ if ($vars) {
+ @pms = split ';', $vars;
+
+ for my $pm (@pms) {
+ if($pm !~ /PRAGMA|SET/i) {
+ next;
+ }
+
+ $pm = ltrim($pm).';';
+ $pm =~ s/ESC_ESC_ESC/;/gx; # wiederherstellen von escapeten ";" -> umwandeln von ";;" in ";"
+
+ $err = DbRep_dbhDo ($name, $dbh, $pm, "Set VARIABLE or PRAGMA: $pm");
+ if ($err) {
+ $err = decode_base64 ($err);
+
+ Log3 ($name, 2, "DbRep $name - ERROR - $err");
+
+ readingsBeginUpdate ($hash);
+ ReadingsBulkUpdateValue ($hash, 'errortext', $err);
+ ReadingsBulkUpdateValue ($hash, 'state', 'error');
+ readingsEndUpdate ($hash, 1);
+
+ return $err;
+ }
+ }
+ }
+
+ # Abarbeitung von Session Variablen vor einem SQL-Statement
+ # z.B. SET @open:=NULL, @closed:=NULL; Select ...
+ if($cmd =~ /^\s*SET.*;/i) {
+ @pms = split ';', $cmd;
+ $sql = q{};
+
+ for my $pm (@pms) {
+ if($pm !~ /SET/i) {
+ $sql .= $pm.';';
+ next;
+ }
+
+ $pm = ltrim($pm).';';
+ $pm =~ s/ESC_ESC_ESC/;/gx; # wiederherstellen von escapeten ";" -> umwandeln von ";;" in ";"
+
+ $err = DbRep_dbhDo ($name, $dbh, $pm, "Set SQL session variable: $pm");
+ if ($err) {
+ $err = decode_base64 ($err);
+
+ Log3 ($name, 2, "DbRep $name - ERROR - $err");
+
+ readingsBeginUpdate ($hash);
+ ReadingsBulkUpdateValue ($hash, 'errortext', $err);
+ ReadingsBulkUpdateValue ($hash, 'state', 'error');
+ readingsEndUpdate ($hash, 1);
+
+ return $err;
+ }
+ }
+ }
+
+ # Abarbeitung aller Pragmas vor einem SQLite Statement, SQL wird extrahiert
+ # wenn Pragmas im SQL vorangestellt sind
+ if($cmd =~ /^\s*PRAGMA.*;/i) {
+ @pms = split ';', $cmd;
+ $sql = q{};
+
+ for my $pm (@pms) {
+ if($pm !~ /PRAGMA.*=/i) { # PRAGMA ohne "=" werden als SQL-Statement mit Abfrageergebnis behandelt
+ $sql .= $pm.';';
+ next;
+ }
+
+ $pm = ltrim($pm).';';
+ $pm =~ s/ESC_ESC_ESC/;/gx; # wiederherstellen von escapeten ";" -> umwandeln von ";;" in ";"
+
+ $err = DbRep_dbhDo ($name, $dbh, $pm, "Exec PRAGMA Statement: $pm");
+ if ($err) {
+ $err = decode_base64 ($err);
+
+ Log3 ($name, 2, "DbRep $name - ERROR - $err");
+
+ readingsBeginUpdate ($hash);
+ ReadingsBulkUpdateValue ($hash, 'errortext', $err);
+ ReadingsBulkUpdateValue ($hash, 'state', 'error');
+ readingsEndUpdate ($hash, 1);
+
+ return $err;
+ }
+ }
+ }
+
+ # Abarbeitung von PREPARE statement als Befehl als Bestandteil des SQL Forum: #114293 / https://forum.fhem.de/index.php?topic=114293.0
+ # z.B. PREPARE statement FROM @CMD
+ if($sql =~ /^\s*PREPARE.*;/i) {
+ @pms = split ';', $sql;
+ $sql = q{};
+
+ for my $pm (@pms) {
+ if($pm !~ /PREPARE/i) {
+ $sql .= $pm.';';
+ next;
+ }
+
+ $pm = ltrim($pm).';';
+ $pm =~ s/ESC_ESC_ESC/;/gx; # wiederherstellen von escapeten ";" -> umwandeln von ";;" in ";"
+
+ $err = DbRep_dbhDo ($name, $dbh, $pm, "Exec PREPARE statement: $pm");
+ if ($err) {
+ $err = decode_base64 ($err);
+
+ Log3 ($name, 2, "DbRep $name - ERROR - $err");
+
+ readingsBeginUpdate ($hash);
+ ReadingsBulkUpdateValue ($hash, 'errortext', $err);
+ ReadingsBulkUpdateValue ($hash, 'state', 'error');
+ readingsEndUpdate ($hash, 1);
+
+ return $err;
+ }
+ }
+ }
+
+ my $st = [gettimeofday]; # SQL-Startzeit
+
+ my $totxt = qq{Timeout occured (limit: $to seconds). You may be able to adjust the "Timeout" attribute.};
+
+ my ($sth,$r,$failed);
+
+ eval { # outer eval fängt Alarm auf, der gerade vor diesem Alarm feuern könnte(0)
+ POSIX::sigaction(SIGALRM, POSIX::SigAction->new(sub {die "Timeout\n"})); # \n ist nötig !
+
+ alarm($to);
+ eval {
+ $sth = $dbh->prepare($sql);
+ $r = $sth->execute();
+ 1;
+ };
+ alarm(0); # Alarm aufheben (wenn der Code schnell lief)
+
+ if ($@) {
+ if($@ eq "Timeout\n") { # timeout
+ $failed = $totxt;
+
+ } else { # ein anderer Fehler
+ $failed = $@;
+ }
+ }
+ 1;
+
+ } or $failed = $@;
+
+ alarm(0); # Schutz vor Race Condition
+
+ if ($failed) {
+ $err = $failed eq "Timeout\n" ? $totxt : $failed;
+
+ Log3 ($name, 2, "DbRep $name - $err");
+
+ $sth->finish if($sth);
+ $dbh->disconnect;
+
+ readingsBeginUpdate ($hash);
+ ReadingsBulkUpdateValue ($hash, 'errortext', $err);
+ ReadingsBulkUpdateValue ($hash, 'state', 'error');
+ readingsEndUpdate ($hash, 1);
+
+ return $err;
+ }
+
+ my $nrows = 0;
+ if($sql =~ m/^\s*(call|explain|select|pragma|show)/is) {
+ while (my @line = $sth->fetchrow_array()) {
+ Log3 ($name, 4, "DbRep $name - SQL result: @line");
+ $ret .= "\n" if($nrows); # Forum: #103295
+ $ret .= join("$srs", @line);
+ $nrows++; # Anzahl der Datensätze
+ }
+ }
+ else {
+ $nrows = $sth->rows;
+
+ eval {$dbh->commit() if(!$dbh->{AutoCommit});};
+ if ($@) {
+ $err = $@;
+
+ Log3 ($name, 2, "DbRep $name - $err");
+
+ $dbh->disconnect;
+
+ readingsBeginUpdate ($hash);
+ ReadingsBulkUpdateValue ($hash, 'errortext', $err);
+ ReadingsBulkUpdateValue ($hash, 'state', 'error');
+ readingsEndUpdate ($hash, 1);
+
+ return $err;
+ }
+
+ $ret = $nrows;
+ }
+
+ $sth->finish;
+ $dbh->disconnect;
+
+ my $rt = tv_interval($st); # SQL-Laufzeit ermitteln
+ my $com = (split " ", $sql, 2)[0];
+
+ Log3 ($name, 4, "DbRep $name - Number of entries processed in db $hash->{DATABASE}: $nrows by $com");
+
+ readingsBeginUpdate ($hash);
+ ReadingsBulkUpdateTimeState ($hash, undef, $rt, 'done');
+ readingsEndUpdate ($hash, 1);
+
+return $ret;
+}
+
####################################################################################################
# Ersetzung von Schlüsselwörtern für Time*, Devices und Readings
# in SQL-Statements (unter Verwendung der Attributsyntax)
@@ -13177,261 +13433,6 @@ sub DbRep_setVersionInfo {
return;
}
-####################################################################################################
-# blockierende DB-Abfrage
-# liefert Ergebnis sofort zurück, setzt keine Readings
-####################################################################################################
-sub DbRep_sqlCmdBlocking {
- my $name = shift;
- my $cmd = shift;
- my $hash = $defs{$name};
-
- my $srs = AttrVal ($name, "sqlResultFieldSep", "|");
- my $to = AttrVal ($name, "timeout", 10 );
-
- my ($ret);
-
- readingsDelete ($hash, "errortext");
- ReadingsSingleUpdateValue ($hash, "state", "running", 1);
-
- my ($err,$dbh,$dbmodel) = DbRep_dbConnect($name);
- if ($err) {
- $err = decode_base64 ($err);
-
- Log3 ($name, 2, "DbRep $name - ERROR - $err");
-
- readingsBeginUpdate ($hash);
- ReadingsBulkUpdateValue ($hash, 'errortext', $err);
- ReadingsBulkUpdateValue ($hash, 'state', 'error');
- readingsEndUpdate ($hash, 1);
-
- return $err;
- }
-
- $cmd =~ s/\;\;/ESC_ESC_ESC/gx; # ersetzen von escapeten ";" (;;)
-
- $cmd .= ";" if ($cmd !~ m/\;$/x);
- my $sql = $cmd;
-
- Log3 ($name, 4, "DbRep $name - -------- New selection --------- ");
- Log3 ($name, 4, "DbRep $name - sqlCmdBlocking Command:\n$sql");
-
- my @pms;
- my $vars = AttrVal($name, "sqlCmdVars", ""); # Set Session Variablen "SET" oder PRAGMA aus Attribut "sqlCmdVars"
-
- if ($vars) {
- @pms = split ';', $vars;
-
- for my $pm (@pms) {
- if($pm !~ /PRAGMA|SET/i) {
- next;
- }
-
- $pm = ltrim($pm).';';
- $pm =~ s/ESC_ESC_ESC/;/gx; # wiederherstellen von escapeten ";" -> umwandeln von ";;" in ";"
-
- $err = DbRep_dbhDo ($name, $dbh, $pm, "Set VARIABLE or PRAGMA: $pm");
- if ($err) {
- $err = decode_base64 ($err);
-
- Log3 ($name, 2, "DbRep $name - ERROR - $err");
-
- readingsBeginUpdate ($hash);
- ReadingsBulkUpdateValue ($hash, 'errortext', $err);
- ReadingsBulkUpdateValue ($hash, 'state', 'error');
- readingsEndUpdate ($hash, 1);
-
- return $err;
- }
- }
- }
-
- # Abarbeitung von Session Variablen vor einem SQL-Statement
- # z.B. SET @open:=NULL, @closed:=NULL; Select ...
- if($cmd =~ /^\s*SET.*;/i) {
- @pms = split ';', $cmd;
- $sql = q{};
-
- for my $pm (@pms) {
- if($pm !~ /SET/i) {
- $sql .= $pm.';';
- next;
- }
-
- $pm = ltrim($pm).';';
- $pm =~ s/ESC_ESC_ESC/;/gx; # wiederherstellen von escapeten ";" -> umwandeln von ";;" in ";"
-
- $err = DbRep_dbhDo ($name, $dbh, $pm, "Set SQL session variable: $pm");
- if ($err) {
- $err = decode_base64 ($err);
-
- Log3 ($name, 2, "DbRep $name - ERROR - $err");
-
- readingsBeginUpdate ($hash);
- ReadingsBulkUpdateValue ($hash, 'errortext', $err);
- ReadingsBulkUpdateValue ($hash, 'state', 'error');
- readingsEndUpdate ($hash, 1);
-
- return $err;
- }
- }
- }
-
- # Abarbeitung aller Pragmas vor einem SQLite Statement, SQL wird extrahiert
- # wenn Pragmas im SQL vorangestellt sind
- if($cmd =~ /^\s*PRAGMA.*;/i) {
- @pms = split ';', $cmd;
- $sql = q{};
-
- for my $pm (@pms) {
- if($pm !~ /PRAGMA.*=/i) { # PRAGMA ohne "=" werden als SQL-Statement mit Abfrageergebnis behandelt
- $sql .= $pm.';';
- next;
- }
-
- $pm = ltrim($pm).';';
- $pm =~ s/ESC_ESC_ESC/;/gx; # wiederherstellen von escapeten ";" -> umwandeln von ";;" in ";"
-
- $err = DbRep_dbhDo ($name, $dbh, $pm, "Exec PRAGMA Statement: $pm");
- if ($err) {
- $err = decode_base64 ($err);
-
- Log3 ($name, 2, "DbRep $name - ERROR - $err");
-
- readingsBeginUpdate ($hash);
- ReadingsBulkUpdateValue ($hash, 'errortext', $err);
- ReadingsBulkUpdateValue ($hash, 'state', 'error');
- readingsEndUpdate ($hash, 1);
-
- return $err;
- }
- }
- }
-
- # Abarbeitung von PREPARE statement als Befehl als Bestandteil des SQL Forum: #114293 / https://forum.fhem.de/index.php?topic=114293.0
- # z.B. PREPARE statement FROM @CMD
- if($sql =~ /^\s*PREPARE.*;/i) {
- @pms = split ';', $sql;
- $sql = q{};
-
- for my $pm (@pms) {
- if($pm !~ /PREPARE/i) {
- $sql .= $pm.';';
- next;
- }
-
- $pm = ltrim($pm).';';
- $pm =~ s/ESC_ESC_ESC/;/gx; # wiederherstellen von escapeten ";" -> umwandeln von ";;" in ";"
-
- $err = DbRep_dbhDo ($name, $dbh, $pm, "Exec PREPARE statement: $pm");
- if ($err) {
- $err = decode_base64 ($err);
-
- Log3 ($name, 2, "DbRep $name - ERROR - $err");
-
- readingsBeginUpdate ($hash);
- ReadingsBulkUpdateValue ($hash, 'errortext', $err);
- ReadingsBulkUpdateValue ($hash, 'state', 'error');
- readingsEndUpdate ($hash, 1);
-
- return $err;
- }
- }
- }
-
- my $st = [gettimeofday]; # SQL-Startzeit
-
- my $totxt = qq{Timeout occured (limit: $to seconds). You may be able to adjust the "Timeout" attribute.};
-
- my ($sth,$r,$failed);
-
- eval { # outer eval fängt Alarm auf, der gerade vor diesem Alarm feuern könnte(0)
- POSIX::sigaction(SIGALRM, POSIX::SigAction->new(sub {die "Timeout\n"})); # \n ist nötig !
-
- alarm($to);
- eval {
- $sth = $dbh->prepare($sql);
- $r = $sth->execute();
- 1;
- };
- alarm(0); # Alarm aufheben (wenn der Code schnell lief)
-
- if ($@) {
- if($@ eq "Timeout\n") { # timeout
- $failed = $totxt;
-
- } else { # ein anderer Fehler
- $failed = $@;
- }
- }
- 1;
-
- } or $failed = $@;
-
- alarm(0); # Schutz vor Race Condition
-
- if ($failed) {
- $err = $failed eq "Timeout\n" ? $totxt : $failed;
-
- Log3 ($name, 2, "DbRep $name - $err");
-
- $sth->finish if($sth);
- $dbh->disconnect;
-
- readingsBeginUpdate ($hash);
- ReadingsBulkUpdateValue ($hash, 'errortext', $err);
- ReadingsBulkUpdateValue ($hash, 'state', 'error');
- readingsEndUpdate ($hash, 1);
-
- return $err;
- }
-
- my $nrows = 0;
- if($sql =~ m/^\s*(call|explain|select|pragma|show)/is) {
- while (my @line = $sth->fetchrow_array()) {
- Log3 ($name, 4, "DbRep $name - SQL result: @line");
- $ret .= "\n" if($nrows); # Forum: #103295
- $ret .= join("$srs", @line);
- $nrows++; # Anzahl der Datensätze
- }
- }
- else {
- $nrows = $sth->rows;
-
- eval {$dbh->commit() if(!$dbh->{AutoCommit});};
- if ($@) {
- $err = $@;
-
- Log3 ($name, 2, "DbRep $name - $err");
-
- $dbh->disconnect;
-
- readingsBeginUpdate ($hash);
- ReadingsBulkUpdateValue ($hash, 'errortext', $err);
- ReadingsBulkUpdateValue ($hash, 'state', 'error');
- readingsEndUpdate ($hash, 1);
-
- return $err;
- }
-
- $ret = $nrows;
- }
-
- $sth->finish;
- $dbh->disconnect;
-
- my $rt = tv_interval($st); # SQL-Laufzeit ermitteln
- my $com = (split " ", $sql, 2)[0];
-
- Log3 ($name, 4, "DbRep $name - Number of entries processed in db $hash->{DATABASE}: $nrows by $com");
-
- readingsBeginUpdate ($hash);
- ReadingsBulkUpdateTimeState ($hash, undef, $rt, 'done');
- readingsEndUpdate ($hash, 1);
-
-return $ret;
-}
-
####################################################################################################
# blockierende DB-Abfrage
# liefert den Wert eines Device:Readings des nächstmöglichen Logeintrags zum
@@ -13844,68 +13845,61 @@ return;
cancelDump - stops a running database dump.
- changeValue - changes the stored value of a reading.
- If the selection is limited to certain device/reading combinations by the attributes
- device or reading, they are taken into account
- in the same way as set time limits (attributes time.*).
- If these constraints are missing, the entire database is searched and the specified value is
- is changed.
+
+ changeValue old="<old String>" new="<new String>"
-
- Syntax:
- set <name> changeValue old="<old string>" new="<new string>"
+ Changes the stored value of a reading.
+ If the selection is limited to certain device/reading combinations by the attributes
+ device or reading, they are taken into account
+ in the same way as set time limits (time.* attributes).
+ If these constraints are missing, the entire database is searched and the specified value is
+ is changed.
- The "string" can be:
+ The "string" can be:
+
+
+ <old String> : | - a simple string with/without spaces, e.g. "OL 12"
|
+ | - a string with use of SQL wildcard, e.g. "%OL%"
|
+ | |
+ | |
+ <new String> : | - a simple string with/without spaces, e.g. "12 kWh"
|
+ | - Perl code enclosed in {"..."} including quotes, e.g. {"($VALUE,$UNIT) = split(" ",$VALUE)"}
|
+ | The variables $VALUE and $UNIT are passed to the Perl expression. They can be changed |
+ | within the Perl code. The returned value of $VALUE and $UNIT is stored |
+ | in the VALUE or UNIT field of the record. |
+
+
-
-
- <old String> : | - a simple string with/without spaces, e.g. "OL 12"
|
- | - a string with use of SQL wildcard, e.g. "%OL%"
|
- | |
- | |
- <new String> : | - a simple string with/without spaces, e.g. "12 kWh"
|
- | - Perl code enclosed in {"..."} including quotes, e.g. {"($VALUE,$UNIT) = split(" ",$VALUE)"}
|
- | The variables $VALUE and $UNIT are passed to the Perl expression. They can be changed |
- | within the Perl code. The returned value of $VALUE and $UNIT is stored |
- | in the VALUE or UNIT field of the record. |
-
-
+ Examples:
+ set <name> changeValue old="OL" new="12 OL"
+ # the old field value "OL" is changed to "12 OL".
- Examples:
- set <name> changeValue "OL","12 OL"
- # the old field value "OL" is changed to "12 OL".
+ set <name> changeValue old="%OL%" new="12 OL"
+ # contains the field VALUE the substring "OL", it is changed to "12 OL".
- set <name> changeValue "%OL%","12 OL"
- # contains the field VALUE the substring "OL", it is changed to "12 OL".
+ set <name> changeValue old="12 kWh" new={"($VALUE,$UNIT) = split(" ",$VALUE)"}
+ # the old field value "12 kWh" is splitted to VALUE=12 and UNIT=kWh and saved into the database fields
- set <name> changeValue "12 kWh",{"($VALUE,$UNIT) = split(" ",$VALUE)"}
- # the old field value "12 kWh" is splitted to VALUE=12 and UNIT=kWh and saved into the database fields
+ set <name> changeValue old="24%" new={"$VALUE = (split(" ",$VALUE))[0]"}
+ # if the old field value begins with "24", it is splitted and VALUE=24 is saved (e.g. "24 kWh")
+
- set <name> changeValue "24%",{"$VALUE = (split(" ",$VALUE))[0]"}
- # if the old field value begins with "24", it is splitted and VALUE=24 is saved (e.g. "24 kWh")
-
+ Summarized the relevant attributes to control function changeValue are:
- Summarized the relevant attributes to control function changeValue are:
-
-
-
-
- device | : include or exclude <device> from selection |
- reading | : include or exclude <reading> from selection |
- time.* | : a number of attributes to limit selection by time |
- executeBeforeProc | : execute a FHEM command (or Perl-routine) before start of changeValue |
- executeAfterProc | : execute a FHEM command (or Perl-routine) after changeValue is finished |
- valueFilter | : an additional REGEXP to control the record selection. The REGEXP is applied to the database field 'VALUE'. |
-
-
-
-
-
- Note:
- Even though the function itself is designed non-blocking, make sure the assigned DbLog-device
- is operating in asynchronous mode to avoid FHEMWEB from blocking.
-
-
+
+
+
+ device | : include or exclude <device> from selection |
+ reading | : include or exclude <reading> from selection |
+ time.* | : a number of attributes to limit selection by time |
+ executeBeforeProc | : execute a FHEM command (or Perl-routine) before start of changeValue |
+ executeAfterProc | : execute a FHEM command (or Perl-routine) after changeValue is finished |
+ valueFilter | : an additional REGEXP to control the record selection. The REGEXP is applied to the database field 'VALUE'. |
+
+
+
+
+
countEntries [history|current] - provides the number of table entries (default: history) between time period set
by time.* -attributes if set.
@@ -14978,113 +14972,113 @@ return;
will are listed.
- sqlCmd - executes any user-specific command.
- If this command contains a delete operation, for safety reasons the attribute
- allowDeletion has to be set.
+ sqlCmd
- sqlCmd also accepts the setting of SQL session variables such as.
- "SET @open:=NULL, @closed:=NULL;" or the use of SQLite PRAGMA prior to the
- execution of the SQL statement.
- If the session variable or PRAGMA has to be set every time before executing a SQL statement, the
- attribute sqlCmdVars can be set.
+ Executes any user-specific command.
+ If this command contains a delete operation, for safety reasons the attribute
+ allowDeletion has to be set.
- If the attributes device, reading,
- timestamp_begin respectively
- timestamp_end
- set in the module are to be taken into account in the statement,
- the placeholders §device§, §reading§, §timestamp_begin§ respectively
- §timestamp_end§ can be used for this purpose.
- It should be noted that the placeholders §device§ and §reading§ complex are resolved and
- should be applied accordingly as in the example below.
-
+ sqlCmd also accepts the setting of SQL session variables such as.
+ "SET @open:=NULL, @closed:=NULL;" or the use of SQLite PRAGMA prior to the
+ execution of the SQL statement.
+ If the session variable or PRAGMA has to be set every time before executing a SQL statement, the
+ attribute sqlCmdVars can be set.
- If you want update a dataset, you have to add "TIMESTAMP=TIMESTAMP" to the update-statement to avoid changing the
- original timestamp.
+ If the attributes device, reading,
+ timestamp_begin respectively
+ timestamp_end
+ set in the module are to be taken into account in the statement,
+ the placeholders §device§, §reading§, §timestamp_begin§ respectively
+ §timestamp_end§ can be used for this purpose.
+ It should be noted that the placeholders §device§ and §reading§ complex are resolved and
+ should be applied accordingly as in the example below.
+
-
- Examples of SQL-statements:
-
- - set <name> sqlCmd select DEVICE, count(*) from history where TIMESTAMP >= "2017-01-06 00:00:00" group by DEVICE having count(*) > 800
- - set <name> sqlCmd select DEVICE, count(*) from history where TIMESTAMP >= "2017-05-06 00:00:00" group by DEVICE
- - set <name> sqlCmd select DEVICE, count(*) from history where TIMESTAMP >= §timestamp_begin§ group by DEVICE
- - set <name> sqlCmd select * from history where DEVICE like "Te%t" order by `TIMESTAMP` desc
- - set <name> sqlCmd select * from history where `TIMESTAMP` > "2017-05-09 18:03:00" order by `TIMESTAMP` desc
- - set <name> sqlCmd select * from current order by `TIMESTAMP` desc
- - set <name> sqlCmd select sum(VALUE) as 'Einspeisung am 04.05.2017', count(*) as 'Anzahl' FROM history where `READING` = "Einspeisung_WirkP_Zaehler_Diff" and TIMESTAMP between '2017-05-04' AND '2017-05-05'
- - set <name> sqlCmd delete from current
- - set <name> sqlCmd delete from history where TIMESTAMP < "2016-05-06 00:00:00"
- - set <name> sqlCmd update history set TIMESTAMP=TIMESTAMP,VALUE='Val' WHERE VALUE='TestValue'
- - set <name> sqlCmd select * from history where DEVICE = "Test"
- - set <name> sqlCmd insert into history (TIMESTAMP, DEVICE, TYPE, EVENT, READING, VALUE, UNIT) VALUES ('2017-05-09 17:00:14','Test','manuell','manuell','Tes§e','TestValue','°C')
- - set <name> sqlCmd select DEVICE, count(*) from history where §device§ AND TIMESTAMP >= §timestamp_begin§ group by DEVICE
- - set <name> sqlCmd select DEVICE, READING, count(*) from history where §device§ AND §reading§ AND TIMESTAMP >= §timestamp_begin§ group by DEVICE, READING
-
-
+ If you want update a dataset, you have to add "TIMESTAMP=TIMESTAMP" to the update-statement to avoid changing the
+ original timestamp.
- Here you can see examples of a more complex statement (MySQL) with setting SQL session
- variables and the SQLite PRAGMA usage:
+ Examples of SQL-statements:
+
+ - set <name> sqlCmd select DEVICE, count(*) from history where TIMESTAMP >= "2017-01-06 00:00:00" group by DEVICE having count(*) > 800
+ - set <name> sqlCmd select DEVICE, count(*) from history where TIMESTAMP >= "2017-05-06 00:00:00" group by DEVICE
+ - set <name> sqlCmd select DEVICE, count(*) from history where TIMESTAMP >= §timestamp_begin§ group by DEVICE
+ - set <name> sqlCmd select * from history where DEVICE like "Te%t" order by `TIMESTAMP` desc
+ - set <name> sqlCmd select * from history where `TIMESTAMP` > "2017-05-09 18:03:00" order by `TIMESTAMP` desc
+ - set <name> sqlCmd select * from current order by `TIMESTAMP` desc
+ - set <name> sqlCmd select sum(VALUE) as 'Einspeisung am 04.05.2017', count(*) as 'Anzahl' FROM history where `READING` = "Einspeisung_WirkP_Zaehler_Diff" and TIMESTAMP between '2017-05-04' AND '2017-05-05'
+ - set <name> sqlCmd delete from current
+ - set <name> sqlCmd delete from history where TIMESTAMP < "2016-05-06 00:00:00"
+ - set <name> sqlCmd update history set TIMESTAMP=TIMESTAMP,VALUE='Val' WHERE VALUE='TestValue'
+ - set <name> sqlCmd select * from history where DEVICE = "Test"
+ - set <name> sqlCmd insert into history (TIMESTAMP, DEVICE, TYPE, EVENT, READING, VALUE, UNIT) VALUES ('2017-05-09 17:00:14','Test','manuell','manuell','Tes§e','TestValue','°C')
+ - set <name> sqlCmd select DEVICE, count(*) from history where §device§ AND TIMESTAMP >= §timestamp_begin§ group by DEVICE
+ - set <name> sqlCmd select DEVICE, READING, count(*) from history where §device§ AND §reading§ AND TIMESTAMP >= §timestamp_begin§ group by DEVICE, READING
+
-
- - set <name> sqlCmd SET @open:=NULL, @closed:=NULL;
- SELECT
- TIMESTAMP, VALUE,DEVICE,
- @open AS open,
- @open := IF(VALUE = 'open', TIMESTAMP, NULL) AS curr_open,
- @closed := IF(VALUE = 'closed', TIMESTAMP, NULL) AS closed
- FROM history WHERE
- DATE(TIMESTAMP) = CURDATE() AND
- DEVICE = "HT_Fensterkontakt" AND
- READING = "state" AND
- (VALUE = "open" OR VALUE = "closed")
- ORDER BY TIMESTAMP;
- - set <name> sqlCmd PRAGMA temp_store=MEMORY; PRAGMA synchronous=FULL; PRAGMA journal_mode=WAL; PRAGMA cache_size=4000; select count(*) from history;
- - set <name> sqlCmd PRAGMA temp_store=FILE; PRAGMA temp_store_directory = '/opt/fhem/'; VACUUM;
-
-
+ Here you can see examples of a more complex statement (MySQL) with setting SQL session
+ variables and the SQLite PRAGMA usage:
- The formatting of result can be choosen by attribute sqlResultFormat,
- as well as the used field separator can be determined by attribute
- sqlResultFieldSep.
+ - set <name> sqlCmd SET @open:=NULL, @closed:=NULL;
+ SELECT
+ TIMESTAMP, VALUE,DEVICE,
+ @open AS open,
+ @open := IF(VALUE = 'open', TIMESTAMP, NULL) AS curr_open,
+ @closed := IF(VALUE = 'closed', TIMESTAMP, NULL) AS closed
+ FROM history WHERE
+ DATE(TIMESTAMP) = CURDATE() AND
+ DEVICE = "HT_Fensterkontakt" AND
+ READING = "state" AND
+ (VALUE = "open" OR VALUE = "closed")
+ ORDER BY TIMESTAMP;
+ - set <name> sqlCmd PRAGMA temp_store=MEMORY; PRAGMA synchronous=FULL; PRAGMA journal_mode=WAL; PRAGMA cache_size=4000; select count(*) from history;
+ - set <name> sqlCmd PRAGMA temp_store=FILE; PRAGMA temp_store_directory = '/opt/fhem/'; VACUUM;
+
+
- The module provides a command history once a sqlCmd command was executed successfully.
- To use this option, activate the attribute sqlCmdHistoryLength
- with list lenght you want.
- If the command history is enabled, an indexed list of stored SQL statements is available
- with ___list_sqlhistory___ within the sqlCmdHistory command.
- An SQL statement can be executed by specifying its index in sqlCmd in this form:
-
+ The formatting of result can be choosen by attribute sqlResultFormat,
+ as well as the used field separator can be determined by attribute
+ sqlResultFieldSep.
-
- set <name> sqlCmd ckey:<Index> (e.g. ckey:4)
-
-
+ The module provides a command history once a sqlCmd command was executed successfully.
+ To use this option, activate the attribute sqlCmdHistoryLength
+ with list lenght you want.
+ If the command history is enabled, an indexed list of stored SQL statements is available
+ with ___list_sqlhistory___ within the sqlCmdHistory command.
- The attributes relevant for controlling sqlCmd are:
+ An SQL statement can be executed by specifying its index in this form:
+
+
+ set <name> sqlCmd ckey:<Index> (e.g. ckey:4)
+
+
-
-
-
- allowDeletion | : activates capabilty to delete datasets |
- executeBeforeProc | : execution of FHEM command (or Perl-routine) before operation |
- executeAfterProc | : execution of FHEM command (or Perl-routine) after operation |
- sqlResultFormat | : determines presentation style of command result |
- sqlResultFieldSep | : choice of a useful field separator for result |
- sqlCmdHistoryLength | : activates command history and length |
- sqlCmdVars | : set SQL session variable or PRAGMA before execute the SQL statement |
- useAdminCredentials | : use privileged user for the operation |
-
-
-
-
+ The attributes relevant for controlling sqlCmd are:
- Note:
- Even though the module works non-blocking regarding to database operations, a huge
- sample space (number of rows/readings) could block the browser session respectively
- FHEMWEB.
- If you are unsure about the result of the statement, you should preventively add a limit to
- the statement.
-
-
+
+
+
+ allowDeletion | : activates capabilty to delete datasets |
+ executeBeforeProc | : execution of FHEM command (or Perl-routine) before operation |
+ executeAfterProc | : execution of FHEM command (or Perl-routine) after operation |
+ sqlResultFormat | : determines presentation style of command result |
+ sqlResultFieldSep | : choice of a useful field separator for result |
+ sqlCmdHistoryLength | : activates command history and length |
+ sqlCmdVars | : set SQL session variable or PRAGMA before execute the SQL statement |
+ sqlFormatService | : activates the formatting of the SQL statement via an online service |
+ useAdminCredentials | : use privileged user for the operation |
+
+
+
+
+
+ Note:
+ Even though the module works non-blocking regarding to database operations, a huge
+ sample space (number of rows/readings) could block the browser session respectively
+ FHEMWEB.
+ If you are unsure about the result of the statement, you should preventively add a limit to
+ the statement.
+
+
sqlCmdHistory - If activated with the attribute sqlCmdHistoryLength,
a stored SQL statement can be selected from a list and executed.
@@ -15402,7 +15396,7 @@ return;
If you create a little routine in 99_myUtils, for example:
-
+
sub dbval {
my $name = shift;
@@ -15411,7 +15405,7 @@ sub dbval {
return $ret;
}
-
+
it can be accessed with e.g. those calls:
@@ -15982,7 +15976,7 @@ sub bdump {
showTableInfo
-
+
Limits the result set of the command "get <name> tableinfo". SQL wildcard (%) can be used.
@@ -16018,26 +16012,26 @@ sub bdump {
-
+
sqlFormatService
-
+
Automated formatting of SQL statements can be activated via an online service.
- This option is especially useful for complex SQL statements of the setters sqlCmd, sqlCmdHistory, and sqlSpecial
+ This option is especially useful for complex SQL statements of the setters sqlCmd, sqlCmdHistory, and sqlSpecial
to improve structuring and readability.
- An Internet connection is required.
+ An internet connection is required and the global attribute dnsServer should be set.
(default: none)
-
-
+
+
sqlResultFieldSep
-
- Sets the used field separator in the result of the command "set ... sqlCmd".
+
+ Sets the used field separator in the result of the command "set ... sqlCmd".
(default: "|")
-
-
+
+
@@ -16706,74 +16700,61 @@ return;
cancelDump - bricht einen laufenden Datenbankdump ab.
+
+ changeValue old="<alter String>" new="<neuer String>"
- changeValue - ändert den gespeicherten Wert eines Readings.
- Ist die Selektion auf bestimmte Device/Reading-Kombinationen durch die Attribute
- device bzw. reading beschränkt, werden sie genauso
- berücksichtigt wie gesetzte Zeitgrenzen (Attribute time.*).
- Fehlen diese Beschränkungen, wird die gesamte Datenbank durchsucht und der angegebene Wert
- geändert.
-
+ Ändert den gespeicherten Wert eines Readings.
+ Ist die Selektion auf bestimmte Device/Reading-Kombinationen durch die Attribute
+ device bzw. reading beschränkt, werden sie genauso
+ berücksichtigt wie gesetzte Zeitgrenzen (time.* Attribute).
+ Fehlen diese Beschränkungen, wird die gesamte Datenbank durchsucht und der angegebene Wert
+ geändert.
-
- Syntax:
- set <name> changeValue old="<alter String>" new="<neuer String>"
+ "String" kann sein:
+
+
+ <alter String> : | - ein einfacher String mit/ohne Leerzeichen, z.B. "OL 12"
|
+ | - ein String mit Verwendung von SQL-Wildcard, z.B. "%OL%"
|
+ | |
+ | |
+ <neuer String> : | - ein einfacher String mit/ohne Leerzeichen, z.B. "12 kWh"
|
+ | - Perl Code eingeschlossen in {"..."} inkl. Quotes, z.B. {"($VALUE,$UNIT) = split(" ",$VALUE)"}
|
+ | Dem Perl-Ausdruck werden die Variablen $VALUE und $UNIT übergeben. Sie können innerhalb |
+ | des Perl-Code geändert werden. Der zurückgebene Wert von $VALUE und $UNIT wird in dem Feld |
+ | VALUE bzw. UNIT des Datensatzes gespeichert. |
+
+
- "String" kann sein:
+ Beispiele:
+ set <name> changeValue old="OL" new="12 OL"
+ # der alte Feldwert "OL" wird in "12 OL" geändert.
-
-
- <alter String> : | - ein einfacher String mit/ohne Leerzeichen, z.B. "OL 12"
|
- | - ein String mit Verwendung von SQL-Wildcard, z.B. "%OL%"
|
- | |
- | |
- <neuer String> : | - ein einfacher String mit/ohne Leerzeichen, z.B. "12 kWh"
|
- | - Perl Code eingeschlossen in {"..."} inkl. Quotes, z.B. {"($VALUE,$UNIT) = split(" ",$VALUE)"}
|
- | Dem Perl-Ausdruck werden die Variablen $VALUE und $UNIT übergeben. Sie können innerhalb |
- | des Perl-Code geändert werden. Der zurückgebene Wert von $VALUE und $UNIT wird in dem Feld |
- | VALUE bzw. UNIT des Datensatzes gespeichert. |
-
-
-
+ set <name> changeValue old="%OL%" new="12 OL"
+ # enthält das Feld VALUE den Teilstring "OL", wird es in "12 OL" geändert.
-
- Beispiele:
- set <name> changeValue "OL","12 OL"
- # der alte Feldwert "OL" wird in "12 OL" geändert.
+ set <name> changeValue old="12 kWh" new={"($VALUE,$UNIT) = split(" ",$VALUE)"}
+ # der alte Feldwert "12 kWh" wird in VALUE=12 und UNIT=kWh gesplittet und in den Datenbankfeldern gespeichert
- set <name> changeValue "%OL%","12 OL"
- # enthält das Feld VALUE den Teilstring "OL", wird es in "12 OL" geändert.
+ set <name> changeValue old="24%" new={"$VALUE = (split(" ",$VALUE))[0]"}
+ # beginnt der alte Feldwert mit "24", wird er gesplittet und VALUE=24 gespeichert (z.B. "24 kWh")
+
- set <name> changeValue "12 kWh",{"($VALUE,$UNIT) = split(" ",$VALUE)"}
- # der alte Feldwert "12 kWh" wird in VALUE=12 und UNIT=kWh gesplittet und in den Datenbankfeldern gespeichert
-
- set <name> changeValue "24%",{"$VALUE = (split(" ",$VALUE))[0]"}
- # beginnt der alte Feldwert mit "24", wird er gesplittet und VALUE=24 gespeichert (z.B. "24 kWh")
-
-
- Zusammengefasst sind die zur Steuerung von changeValue relevanten Attribute:
-
-
-
-
- device | : einschließen oder ausschließen von Datensätzen die <device> enthalten |
- aggregation | : Auswahl einer Aggregationsperiode |
- reading | : einschließen oder ausschließen von Datensätzen die <reading> enthalten |
- time.* | : eine Reihe von Attributen zur Zeitabgrenzung |
- executeBeforeProc | : ausführen FHEM Kommando (oder Perl-Routine) vor Start changeValue |
- executeAfterProc | : ausführen FHEM Kommando (oder Perl-Routine) nach Ende changeValue |
- valueFilter | : ein zusätzliches REGEXP um die Datenselektion zu steuern. Der REGEXP wird auf das Datenbankfeld 'VALUE' angewendet. |
-
-
-
-
-
- Hinweis:
- Obwohl die Funktion selbst non-blocking ausgelegt ist, sollte das zugeordnete DbLog-Device
- im asynchronen Modus betrieben werden um ein Blockieren von FHEMWEB zu vermeiden (Tabellen-Lock).
-
-
+ Zusammengefasst sind die zur Steuerung von changeValue relevanten Attribute:
+
+
+
+ device | : einschließen oder ausschließen von Datensätzen die <device> enthalten |
+ reading | : einschließen oder ausschließen von Datensätzen die <reading> enthalten |
+ time.* | : eine Reihe von Attributen zur Zeitabgrenzung |
+ executeBeforeProc | : ausführen FHEM Kommando (oder Perl-Routine) vor Start changeValue |
+ executeAfterProc | : ausführen FHEM Kommando (oder Perl-Routine) nach Ende changeValue |
+ valueFilter | : ein zusätzliches REGEXP um die Datenselektion zu steuern. Der REGEXP wird auf das Datenbankfeld 'VALUE' angewendet. |
+
+
+
+
+
countEntries [history | current]
- liefert die Anzahl der Tabelleneinträge (default: history) in den gegebenen
@@ -17871,111 +17852,112 @@ return;
verbundenen Datenbank beginnt, aufgelistet .
- sqlCmd - führt ein beliebiges benutzerspezifisches Kommando aus.
- Enthält dieses Kommando eine Delete-Operation, muss zur Sicherheit das Attribut
- allowDeletion gesetzt sein.
- sqlCmd akzeptiert ebenfalls das Setzen von SQL Session Variablen wie z.B.
- "SET @open:=NULL, @closed:=NULL;" oder die Verwendung von SQLite PRAGMA vor der
- Ausführung des SQL-Statements.
- Soll die Session Variable oder das PRAGMA vor jeder Ausführung eines SQL Statements
- gesetzt werden, kann dafür das Attribut sqlCmdVars
- verwendet werden.
+ sqlCmd
- Sollen die im Modul gesetzten Attribute device, reading,
- timestamp_begin bzw.
- timestamp_end im Statement berücksichtigt werden, können die Platzhalter
- §device§, §reading§, §timestamp_begin§ bzw.
- §timestamp_end§ eingesetzt werden.
- Dabei ist zu beachten, dass die Platzhalter §device§ und §reading§ komplex aufgelöst werden
- und dementsprechend wie im unten stehenden Beispiel anzuwenden sind.
-
+ Führt ein beliebiges benutzerspezifisches Kommando aus.
+ Enthält dieses Kommando eine Delete-Operation, muss zur Sicherheit das Attribut
+ allowDeletion gesetzt sein.
+ sqlCmd akzeptiert ebenfalls das Setzen von SQL Session Variablen wie z.B.
+ "SET @open:=NULL, @closed:=NULL;" oder die Verwendung von SQLite PRAGMA vor der
+ Ausführung des SQL-Statements.
+ Soll die Session Variable oder das PRAGMA vor jeder Ausführung eines SQL Statements
+ gesetzt werden, kann dafür das Attribut sqlCmdVars
+ verwendet werden.
- Soll ein Datensatz upgedated werden, ist dem Statement "TIMESTAMP=TIMESTAMP" hinzuzufügen um eine Änderung des
- originalen Timestamps zu verhindern.
+ Sollen die im Modul gesetzten Attribute device, reading,
+ timestamp_begin bzw.
+ timestamp_end im Statement berücksichtigt werden, können die Platzhalter
+ §device§, §reading§, §timestamp_begin§ bzw.
+ §timestamp_end§ eingesetzt werden.
+ Dabei ist zu beachten, dass die Platzhalter §device§ und §reading§ komplex aufgelöst werden
+ und dementsprechend wie im unten stehenden Beispiel anzuwenden sind.
+
-
- Beispiele für Statements:
-
- - set <name> sqlCmd select DEVICE, count(*) from history where TIMESTAMP >= "2017-01-06 00:00:00" group by DEVICE having count(*) > 800
- - set <name> sqlCmd select DEVICE, count(*) from history where TIMESTAMP >= "2017-05-06 00:00:00" group by DEVICE
- - set <name> sqlCmd select DEVICE, count(*) from history where TIMESTAMP >= §timestamp_begin§ group by DEVICE
- - set <name> sqlCmd select * from history where DEVICE like "Te%t" order by `TIMESTAMP` desc
- - set <name> sqlCmd select * from history where `TIMESTAMP` > "2017-05-09 18:03:00" order by `TIMESTAMP` desc
- - set <name> sqlCmd select * from current order by `TIMESTAMP` desc
- - set <name> sqlCmd select sum(VALUE) as 'Einspeisung am 04.05.2017', count(*) as 'Anzahl' FROM history where `READING` = "Einspeisung_WirkP_Zaehler_Diff" and TIMESTAMP between '2017-05-04' AND '2017-05-05'
- - set <name> sqlCmd delete from current
- - set <name> sqlCmd delete from history where TIMESTAMP < "2016-05-06 00:00:00"
- - set <name> sqlCmd update history set TIMESTAMP=TIMESTAMP,VALUE='Val' WHERE VALUE='TestValue'
- - set <name> sqlCmd select * from history where DEVICE = "Test"
- - set <name> sqlCmd insert into history (TIMESTAMP, DEVICE, TYPE, EVENT, READING, VALUE, UNIT) VALUES ('2017-05-09 17:00:14','Test','manuell','manuell','Tes§e','TestValue','°C')
- - set <name> sqlCmd select DEVICE, count(*) from history where §device§ AND TIMESTAMP >= §timestamp_begin§ group by DEVICE
- - set <name> sqlCmd select DEVICE, READING, count(*) from history where §device§ AND §reading§ AND TIMESTAMP >= §timestamp_begin§ group by DEVICE, READING
-
-
+ Soll ein Datensatz upgedated werden, ist dem Statement "TIMESTAMP=TIMESTAMP" hinzuzufügen um eine Änderung des
+ originalen Timestamps zu verhindern.
- Nachfolgend Beispiele für ein komplexeres Statement (MySQL) unter Mitgabe von
- SQL Session Variablen und die SQLite PRAGMA-Verwendung:
+ Beispiele für Statements:
+
+ - set <name> sqlCmd select DEVICE, count(*) from history where TIMESTAMP >= "2017-01-06 00:00:00" group by DEVICE having count(*) > 800
+ - set <name> sqlCmd select DEVICE, count(*) from history where TIMESTAMP >= "2017-05-06 00:00:00" group by DEVICE
+ - set <name> sqlCmd select DEVICE, count(*) from history where TIMESTAMP >= §timestamp_begin§ group by DEVICE
+ - set <name> sqlCmd select * from history where DEVICE like "Te%t" order by `TIMESTAMP` desc
+ - set <name> sqlCmd select * from history where `TIMESTAMP` > "2017-05-09 18:03:00" order by `TIMESTAMP` desc
+ - set <name> sqlCmd select * from current order by `TIMESTAMP` desc
+ - set <name> sqlCmd select sum(VALUE) as 'Einspeisung am 04.05.2017', count(*) as 'Anzahl' FROM history where `READING` = "Einspeisung_WirkP_Zaehler_Diff" and TIMESTAMP between '2017-05-04' AND '2017-05-05'
+ - set <name> sqlCmd delete from current
+ - set <name> sqlCmd delete from history where TIMESTAMP < "2016-05-06 00:00:00"
+ - set <name> sqlCmd update history set TIMESTAMP=TIMESTAMP,VALUE='Val' WHERE VALUE='TestValue'
+ - set <name> sqlCmd select * from history where DEVICE = "Test"
+ - set <name> sqlCmd insert into history (TIMESTAMP, DEVICE, TYPE, EVENT, READING, VALUE, UNIT) VALUES ('2017-05-09 17:00:14','Test','manuell','manuell','Tes§e','TestValue','°C')
+ - set <name> sqlCmd select DEVICE, count(*) from history where §device§ AND TIMESTAMP >= §timestamp_begin§ group by DEVICE
+ - set <name> sqlCmd select DEVICE, READING, count(*) from history where §device§ AND §reading§ AND TIMESTAMP >= §timestamp_begin§ group by DEVICE, READING
+
-
- - set <name> sqlCmd SET @open:=NULL, @closed:=NULL;
- SELECT
- TIMESTAMP, VALUE,DEVICE,
- @open AS open,
- @open := IF(VALUE = 'open', TIMESTAMP, NULL) AS curr_open,
- @closed := IF(VALUE = 'closed', TIMESTAMP, NULL) AS closed
- FROM history WHERE
- DATE(TIMESTAMP) = CURDATE() AND
- DEVICE = "HT_Fensterkontakt" AND
- READING = "state" AND
- (VALUE = "open" OR VALUE = "closed")
- ORDER BY TIMESTAMP;
- - set <name> sqlCmd PRAGMA temp_store=MEMORY; PRAGMA synchronous=FULL; PRAGMA journal_mode=WAL; PRAGMA cache_size=4000; select count(*) from history;
- - set <name> sqlCmd PRAGMA temp_store=FILE; PRAGMA temp_store_directory = '/opt/fhem/'; VACUUM;
-
-
+ Nachfolgend Beispiele für ein komplexeres Statement (MySQL) unter Mitgabe von
+ SQL Session Variablen und die SQLite PRAGMA-Verwendung:
- Die Ergebnis-Formatierung kann durch das Attribut sqlResultFormat ausgewählt,
- sowie der verwendete Feldtrenner durch das Attribut sqlResultFieldSep
- festgelegt werden.
+ - set <name> sqlCmd SET @open:=NULL, @closed:=NULL;
+ SELECT
+ TIMESTAMP, VALUE,DEVICE,
+ @open AS open,
+ @open := IF(VALUE = 'open', TIMESTAMP, NULL) AS curr_open,
+ @closed := IF(VALUE = 'closed', TIMESTAMP, NULL) AS closed
+ FROM history WHERE
+ DATE(TIMESTAMP) = CURDATE() AND
+ DEVICE = "HT_Fensterkontakt" AND
+ READING = "state" AND
+ (VALUE = "open" OR VALUE = "closed")
+ ORDER BY TIMESTAMP;
+ - set <name> sqlCmd PRAGMA temp_store=MEMORY; PRAGMA synchronous=FULL; PRAGMA journal_mode=WAL; PRAGMA cache_size=4000; select count(*) from history;
+ - set <name> sqlCmd PRAGMA temp_store=FILE; PRAGMA temp_store_directory = '/opt/fhem/'; VACUUM;
+
+
- Das Modul stellt optional eine Kommando-Historie zur Verfügung sobald ein SQL-Kommando erfolgreich
- ausgeführt wurde.
- Um diese Option zu nutzen, ist das Attribut sqlCmdHistoryLength mit der
- gewünschten Listenlänge zu aktivieren.
- Ist die Kommando-Historie aktiviert, ist mit ___list_sqlhistory___ innerhalb des Kommandos
- sqlCmdHistory eine indizierte Liste der gespeicherten SQL-Statements verfügbar.
- Ein SQL-Statement kann durch Angabe seines Index im sqlCmd ausgeführt werden mit:
-
+ Die Ergebnis-Formatierung kann durch das Attribut sqlResultFormat ausgewählt,
+ sowie der verwendete Feldtrenner durch das Attribut sqlResultFieldSep
+ festgelegt werden.
-
- set <name> sqlCmd ckey:<Index> (e.g. ckey:4)
-
-
+ Das Modul stellt optional eine Kommando-Historie zur Verfügung sobald ein SQL-Kommando erfolgreich
+ ausgeführt wurde.
+ Um diese Option zu nutzen, ist das Attribut sqlCmdHistoryLength mit der
+ gewünschten Listenlänge zu aktivieren.
+ Ist die Kommando-Historie aktiviert, ist mit ___list_sqlhistory___ innerhalb des Kommandos
+ sqlCmdHistory eine indizierte Liste der gespeicherten SQL-Statements verfügbar.
- Die zur Steuerung von sqlCmd relevanten Attribute sind:
+ Ein SQL-Statement kann durch Angabe seines Index im ausgeführt werden mit:
+
+
+ set <name> sqlCmd ckey:<Index> (e.g. ckey:4)
+
+
-
-
-
- executeBeforeProc | : FHEM Kommando (oder Perl-Routine) vor der Operation ausführen |
- executeAfterProc | : FHEM Kommando (oder Perl-Routine) nach der Operation ausführen |
- allowDeletion | : aktiviert Löschmöglichkeit |
- sqlResultFormat | : legt die Darstellung des Kommandoergebnisses fest |
- sqlResultFieldSep | : Auswahl Feldtrenner im Ergebnis |
- sqlCmdHistoryLength | : Aktivierung Kommando-Historie und deren Umfang |
- sqlCmdVars | : setzt SQL Session Variablen oder PRAGMA vor jeder Ausführung des SQL-Statements |
- useAdminCredentials | : benutzt einen privilegierten User für die Operation |
-
-
-
+ Die zur Steuerung von sqlCmd relevanten Attribute sind:
- Hinweis:
- Auch wenn das Modul bezüglich der Datenbankabfrage nichtblockierend arbeitet, kann eine
- zu große Ergebnismenge (Anzahl Zeilen bzw. Readings) die Browsersesssion bzw. FHEMWEB
- blockieren. Wenn man sich unsicher ist, sollte man vorsorglich dem Statement ein Limit
- hinzufügen.
-
-
+
+
+
+ executeBeforeProc | : FHEM Kommando (oder Perl-Routine) vor der Operation ausführen |
+ executeAfterProc | : FHEM Kommando (oder Perl-Routine) nach der Operation ausführen |
+ allowDeletion | : aktiviert Löschmöglichkeit |
+ sqlResultFormat | : legt die Darstellung des Kommandoergebnisses fest |
+ sqlResultFieldSep | : Auswahl Feldtrenner im Ergebnis |
+ sqlCmdHistoryLength | : Aktivierung Kommando-Historie und deren Umfang |
+ sqlCmdVars | : setzt SQL Session Variablen oder PRAGMA vor jeder Ausführung eines SQL-Statements |
+ sqlFormatService | : aktiviert die Formatierung des SQL Statements über einen Onlinedienst |
+ useAdminCredentials | : benutzt einen privilegierten User für die Operation |
+
+
+
+
+ Hinweis:
+ Auch wenn das Modul bezüglich der Datenbankabfrage nichtblockierend arbeitet, kann eine
+ zu große Ergebnismenge (Anzahl Zeilen bzw. Readings) die Browsersesssion bzw. FHEMWEB
+ blockieren.
+ Wenn man sich unsicher ist, sollte man vorsorglich dem Statement ein Limit
+ hinzufügen.
+
+
sqlCmdHistory - Wenn mit dem Attribut sqlCmdHistoryLength aktiviert, kann
ein gespeichertes SQL-Statement aus einer Liste ausgewählt und ausgeführt werden.
@@ -18273,7 +18255,7 @@ return;
sqlCmdBlocking <SQL-Statement>
-
+
Führt das angegebene SQL-Statement blockierend mit einem Standardtimeout von 10 Sekunden aus.
Der Timeout kann mit dem Attribut timeout eingestellt werden.
@@ -18300,7 +18282,7 @@ return;
Erstellt man eine kleine Routine in 99_myUtils, wie z.B.:
-
+
sub dbval {
my $name = shift;
@@ -18309,7 +18291,7 @@ sub dbval {
return $ret;
}
-
+
kann sqlCmdBlocking vereinfacht verwendet werden mit Aufrufen wie:
@@ -18893,7 +18875,7 @@ sub bdump {
showTableInfo
-
+
Grenzt die Ergebnismenge des Befehls "get <name> tableinfo" ein. Es können SQL-Wildcard (%) verwendet werden.
@@ -18929,26 +18911,26 @@ sub bdump {
-
+
sqlFormatService
-
+
Über einen Online-Dienst kann eine automatisierte Formatierung von SQL-Statements aktiviert werden.
- Diese Möglichkeit ist insbesondere für komplexe SQL-Statements der Setter sqlCmd, sqlCmdHistory und sqlSpecial
+ Diese Möglichkeit ist insbesondere für komplexe SQL-Statements der Setter sqlCmd, sqlCmdHistory und sqlSpecial
hilfreich um die Strukturierung und Lesbarkeit zu verbessern.
- Eine Internetverbindung wird benötigt.
+ Eine Internetverbindung wird benötigt und es sollte das globale Attribut dnsServer gesetzt sein.
(default: none)
-
-
+
+
sqlResultFieldSep
-
- Legt den verwendeten Feldseparator im Ergebnis des Kommandos "set ... sqlCmd" fest.
+
+ Legt den verwendeten Feldseparator im Ergebnis des Kommandos "set ... sqlCmd" fest.
(default: "|")
-
-
+
+
@@ -18970,7 +18952,7 @@ sub bdump {
des Datensatzes (Key) und dessen Wert zusammen.
Die Weiterverarbeitung des Ergebnisses kann z.B. mit der folgenden userExitFn in 99_myUtils.pm erfolgen:
-
+
sub resfromjson {
my ($name,$reading,$value) = @_;