2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-05-05 02:19:31 +00:00

93_DbRep: V8.15.0, readingsRename can be restricted to readings of a optional given device, fix deldoublets in SQLite

git-svn-id: https://svn.fhem.de/fhem/trunk@18837 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
nasseeder1 2019-03-09 20:13:59 +00:00
parent e44297716c
commit b59db141d2
2 changed files with 64 additions and 24 deletions

View File

@ -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.
- feature: 93_DbRep: V8.15.0, readingsRename can be restricted to readings of
a optional given device, fix deldoublets in SQLite
- bugfix: 49_SSCam: V8.11.3, fhem hang in loop while restart or get snapinfo
Forum: #45671.msg915546.html#msg915546
- feature: mqtt2.template: A_00_MQTT2_CLIENT_general_bridge revised for better

View File

@ -57,6 +57,9 @@ no if $] >= 5.017011, warnings => 'experimental::smartmatch';
# Versions History intern
our %DbRep_vNotesIntern = (
"8.15.0" => "04.03.2019 readingsRename can rename readings of a given (optional) device ",
"8.14.1" => "04.03.2019 Bugfix in deldoublets with SQLite, Forum: https://forum.fhem.de/index.php/topic,53584.msg914489.html#msg914489 ",
"8.14.0" => "19.02.2019 delete Readings if !goodReadingName and featurelevel > 5.9 ",
"8.13.0" => "11.02.2019 executeBeforeProc / executeAfterProc for sumValue, maxValue, minValue, diffValue, averageValue ",
"8.12.0" => "10.02.2019 executeBeforeProc / executeAfterProc for sqlCmd ",
"8.11.2" => "03.02.2019 fix no running tableCurrentFillup if database is closed ",
@ -137,9 +140,10 @@ our %DbRep_vNotesIntern = (
# Versions History extern:
our %DbRep_vNotesExtern = (
"8.15.0" => "04.03.2019 readingsRename can now rename readings of a given (optional) device instead of all found readings specified in command ",
"8.13.0" => "11.02.2019 executeBeforeProc / executeAfterProc is now available for sqlCmd,sumValue, maxValue, minValue, diffValue, averageValue ",
"8.11.0" => "24.01.2019 command exportToFile or attribute \"expimpfile\" accepts option \"MAXLINES=\" ",
"8.10.0" => "19.01.2019 In commands sqlCmd, dbValue you may now use SQL session variables like \"SET \@open:=NULL,\@closed:=NULL; SELECT ...\", Forum:#96082",
"8.10.0" => "19.01.2019 In commands sqlCmd, dbValue you may now use SQL session variables like \"SET \@open:=NULL,\@closed:=NULL; SELECT ...\", Forum:#96082 ",
"8.9.0" => "07.11.2018 new command set delDoublets added. This command allows to delete multiple occuring identical records. ",
"8.8.0" => "06.11.2018 new attribute 'fastStart'. Usually every DbRep-device is making a short connect to its database when "
."FHEM is restarted. When this attribute is set, the initial connect is done when the DbRep-device is doing its "
@ -4301,7 +4305,7 @@ sub change_Push($) {
my $dblogname = $dbloghash->{NAME};
my $dbpassword = $attr{"sec$dblogname"}{secret};
my $table = "history";
my ($dbh,$err,$sql);
my ($dbh,$err,$sql,$dev);
# Background-Startzeit
my $bst = [gettimeofday];
@ -4340,16 +4344,21 @@ sub change_Push($) {
$sth = $dbh->prepare($sql) ;
} elsif ($renmode eq "readren") {
$old = delete $hash->{HELPER}{OLDREAD};
$old = delete $hash->{HELPER}{OLDREAD}; # Wert besteht aus [device]:old_readingname
($dev,$old) = split(":",$old,2);
$new = delete $hash->{HELPER}{NEWREAD};
# SQL zusammenstellen für DB-Operation
Log3 ($name, 5, "DbRep $name -> Rename old reading name \"$old\" to new reading name \"$new\" in database $dblogname ");
Log3 ($name, 5, "DbRep $name -> Rename old reading name \"$old\" ".($dev?"(of device $dev)":"")." to new reading name \"$new\" in database $dblogname ");
# prepare DB operation
$old =~ s/'/''/g; # escape ' with ''
$new =~ s/'/''/g; # escape ' with ''
$sql = "UPDATE history SET TIMESTAMP=TIMESTAMP,READING='$new' WHERE READING='$old'; ";
if($dev) {
$sql = "UPDATE history SET TIMESTAMP=TIMESTAMP,READING='$new' WHERE DEVICE='$dev' AND READING='$old'; ";
} else {
$sql = "UPDATE history SET TIMESTAMP=TIMESTAMP,READING='$new' WHERE READING='$old'; ";
}
Log3 ($name, 4, "DbRep $name - SQL execute: $sql");
$sth = $dbh->prepare($sql) ;
@ -4380,6 +4389,7 @@ sub change_Push($) {
my $brt = tv_interval($bst);
$rt = $rt.",".$brt;
$old = $dev?"$dev:$old":$old;
return "$name|$urow|$rt|0|$old|$new";
}
@ -4851,10 +4861,19 @@ sub deldoublets_DoParse($) {
$table = "history";
$selspec = "TIMESTAMP,DEVICE,READING,VALUE,count(*)";
$addon = "GROUP BY TIMESTAMP, DEVICE, READING, VALUE ASC HAVING count(*) > 1";
if($dbloghash->{MODEL} eq 'SQLITE') {
$addon = "GROUP BY TIMESTAMP, DEVICE, READING, VALUE HAVING count(*) > 1 ORDER BY TIMESTAMP ASC"; # Forum: https://forum.fhem.de/index.php/topic,53584.msg914489.html#msg914489
}
# SQL zusammenstellen für DB-Abfrage
$sql = DbRep_createSelectSql($hash,$table,$selspec,$device,$reading,"?","?",$addon);
$sth = $dbh->prepare_cached($sql);
eval{$sth = $dbh->prepare_cached($sql);};
if ($@) {
$err = encode_base64($@,"");
Log3 ($name, 2, "DbRep $name - $@");
$dbh->disconnect;
return "$name|''|''|$err|''|$opt";
}
# DB-Abfrage zeilenweise für jeden Timearray-Eintrag
my @todel;
@ -9084,6 +9103,8 @@ sub DbRep_delread($;$$) {
my ($hash,$shutdown) = @_;
my $name = $hash->{NAME};
my @allrds = keys%{$defs{$name}{READINGS}};
my $featurelevel = AttrVal("global","featurelevel",99.99);
if($shutdown) {
my $do = 0;
foreach my $key(@allrds) {
@ -9092,6 +9113,11 @@ sub DbRep_delread($;$$) {
$do = 1;
delete($defs{$name}{READINGS}{$key});
}
# Reading löschen wenn Featuelevel > 5.9 und zu lang nach der neuen Festlegung
if($do == 0 && $featurelevel > 5.9 && !goodReadingName($key)) {
$do = 1;
delete($defs{$name}{READINGS}{$key});
}
}
WriteStatefile() if($do == 1);
return undef;
@ -11289,23 +11315,29 @@ return;
</li><br>
</ul>
<li><b> readingRename </b> - renames the reading name of a device inside the connected database (see Internal DATABASE).
<li><b> readingRename &lt;[device:]oldreadingname&gt;,&lt;newreadingname&gt; </b> <br>
Renames the reading name of a device inside the connected database (see Internal DATABASE).
The readingname will allways be changed in the <b>entire</b> database. Possibly set time limits or restrictions by
<a href="#DbRepattr">attributes</a> device and/or reading will not be considered. <br><br>
<a href="#DbRepattr">attributes</a> device and/or reading will not be considered. <br>
As an option a device can be specified. In this case only the old readings of this device
will be renamed. <br><br>
<ul>
<b>Example: </b> <br>
set &lt;name&gt; readingRename &lt;old reading name&gt;,&lt;new reading name&gt; <br>
# The amount of renamed reading names (datasets) will be displayed in reading "reading_renamed". <br>
# If the reading name to be renamed was not found in the database, a WARNUNG will appear in reading "reading_not_renamed". <br>
# Appropriate entries will be written to Logfile if verbose >= 3 is set.
<b>Examples: </b> <br>
set &lt;name&gt; readingRename TotalConsumtion,L1_TotalConsumtion <br>
set &lt;name&gt; readingRename Dum.Energy:TotalConsumtion,L1_TotalConsumtion <br>
</ul>
<br>
The amount of renamed reading names (datasets) will be displayed in reading "reading_renamed". <br>
If the reading name to be renamed was not found in the database, a WARNING will appear in reading "reading_not_renamed". <br>
Appropriate entries will be written to Logfile if verbose >= 3 is set.
<br><br>
<b>Note:</b> <br>
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. <br><br>
</li> <br>
</ul>
<li><b> reduceLog [average[=day]] </b> <br>
Reduces historical records within the limits given by the "time.*"-attributes to one record
@ -13654,26 +13686,32 @@ sub bdump {
</li>
</ul><br>
<li><b> readingRename </b> - benennt den Namen eines Readings innerhalb der angeschlossenen Datenbank (siehe Internal DATABASE) um.
<li><b> readingRename &lt;[Device:]alterReadingname&gt;,&lt;neuerReadingname&gt; </b> <br>
Benennt den Namen eines Readings innerhalb der angeschlossenen Datenbank (siehe Internal DATABASE) um.
Der Readingname wird immer in der <b>gesamten</b> Datenbank umgesetzt. Eventuell
gesetzte Zeitgrenzen oder Beschränkungen durch die <a href="#DbRepattr">Attribute</a>
Device bzw. Reading werden nicht berücksichtigt. <br><br>
Device bzw. Reading werden nicht berücksichtigt. <br>
Optional kann eine Device angegeben werden. In diesem Fall werden <b>nur</b> die alten Readings
dieses Devices in den neuen Readingnamen umgesetzt.
<br><br>
<ul>
<b>Beispiel: </b><br>
set &lt;name&gt; readingRename &lt;alter Readingname&gt;,&lt;neuer Readingname&gt; <br>
# Die Anzahl der umbenannten Device-Datensätze wird im Reading "reading_renamed"
ausgegeben. <br>
# Wird der umzubenennende Readingname in der Datenbank nicht gefunden, wird eine
WARNUNG im Reading "reading_not_renamed" ausgegeben. <br>
# Entsprechende Einträge erfolgen auch im Logfile mit verbose=3.
<b>Beispiele: </b><br>
set &lt;name&gt; readingRename TotalConsumption,L1_TotalConsumption <br>
set &lt;name&gt; readingRename Dum.Energy:TotalConsumption,L1_TotalConsumption <br>
</ul>
<br>
Die Anzahl der umbenannten Device-Datensätze wird im Reading "reading_renamed" ausgegeben. <br>
Wird der umzubenennende Readingname in der Datenbank nicht gefunden, wird eine WARNUNG im Reading
"reading_not_renamed" ausgegeben. <br>
Entsprechende Einträge erfolgen auch im Logfile mit verbose=3.
<br><br>
<b>Hinweis:</b> <br>
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). <br><br>
</li> <br>
</ul>
<li><b> reduceLog [average[=day]] </b> <br>
Reduziert historische Datensätze innerhalb der durch die "time.*"-Attribute bestimmten