mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-05-04 22:19:38 +00:00
93_DbLog: V2.18.2, new command configCheck for MySQL, PostgreSQL
git-svn-id: https://svn.fhem.de/fhem/trunk@14629 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
943e2cbcf3
commit
d4f2ca559f
@ -1,5 +1,6 @@
|
|||||||
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
# 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.
|
# Do not insert empty lines here, update check depends on it.
|
||||||
|
- feature: 93_DbLog: V2.18.2, new command configCheck for MySQL, PostgreSQL
|
||||||
- new: 98_archetype: introducing new module to inheritance attributes
|
- new: 98_archetype: introducing new module to inheritance attributes
|
||||||
and defines devices
|
and defines devices
|
||||||
- bugfix: 50_TelegramBot: rewrite readfile function $_ warning - #msg651947
|
- bugfix: 50_TelegramBot: rewrite readfile function $_ warning - #msg651947
|
||||||
|
@ -16,6 +16,9 @@
|
|||||||
############################################################################################################################################
|
############################################################################################################################################
|
||||||
# Versions History done by DS_Starter & DeeSPe:
|
# Versions History done by DS_Starter & DeeSPe:
|
||||||
#
|
#
|
||||||
|
# 2.18.2 29.06.2017 check of index for DbRep added
|
||||||
|
# 2.18.1 25.06.2017 DbLog_configCheck/ DbLog_sqlget some changes, commandref revised
|
||||||
|
# 2.18.0 24.06.2017 configCheck added (MySQL, PostgreSQL)
|
||||||
# 2.17.1 17.06.2017 fix log-entries "utf8 enabled" if SVG's called, commandref revised, enable UTF8 for DbLog_get
|
# 2.17.1 17.06.2017 fix log-entries "utf8 enabled" if SVG's called, commandref revised, enable UTF8 for DbLog_get
|
||||||
# 2.17.0 15.06.2017 enable UTF8 for MySQL (entry in configuration file necessary)
|
# 2.17.0 15.06.2017 enable UTF8 for MySQL (entry in configuration file necessary)
|
||||||
# 2.16.11 03.06.2017 execmemcache changed for SQLite avoid logging if deleteOldDaysNbl or reduceLogNbL is running
|
# 2.16.11 03.06.2017 execmemcache changed for SQLite avoid logging if deleteOldDaysNbl or reduceLogNbL is running
|
||||||
@ -132,7 +135,7 @@ use Blocking;
|
|||||||
use Time::HiRes qw(gettimeofday tv_interval);
|
use Time::HiRes qw(gettimeofday tv_interval);
|
||||||
use Encode qw(encode_utf8);
|
use Encode qw(encode_utf8);
|
||||||
|
|
||||||
my $DbLogVersion = "2.17.1";
|
my $DbLogVersion = "2.18.2";
|
||||||
|
|
||||||
my %columns = ("DEVICE" => 64,
|
my %columns = ("DEVICE" => 64,
|
||||||
"TYPE" => 64,
|
"TYPE" => 64,
|
||||||
@ -378,7 +381,8 @@ sub DbLog_Set($@) {
|
|||||||
deleteOldDays deleteOldDaysNbl userCommand clearReadings:noArg
|
deleteOldDays deleteOldDaysNbl userCommand clearReadings:noArg
|
||||||
eraseReadings:noArg addLog ";
|
eraseReadings:noArg addLog ";
|
||||||
$usage .= "listCache:noArg purgeCache:noArg commitCache:noArg exportCache:nopurge,purgecache " if (AttrVal($name, "asyncMode", undef));
|
$usage .= "listCache:noArg purgeCache:noArg commitCache:noArg exportCache:nopurge,purgecache " if (AttrVal($name, "asyncMode", undef));
|
||||||
my (@logs,$dir);
|
$usage .= "configCheck:noArg " if($hash->{DBMODEL} =~ /MYSQL|POSTGRESQL/);
|
||||||
|
my (@logs,$dir);
|
||||||
|
|
||||||
if (!AttrVal($name,"expimpdir",undef)) {
|
if (!AttrVal($name,"expimpdir",undef)) {
|
||||||
$dir = $attr{global}{modpath}."/log/";
|
$dir = $attr{global}{modpath}."/log/";
|
||||||
@ -512,6 +516,10 @@ sub DbLog_Set($@) {
|
|||||||
}
|
}
|
||||||
return $cache;
|
return $cache;
|
||||||
}
|
}
|
||||||
|
elsif ($a[1] eq 'configCheck') {
|
||||||
|
my $check = DbLog_configcheck($hash);
|
||||||
|
return $check;
|
||||||
|
}
|
||||||
elsif ($a[1] eq 'exportCache') {
|
elsif ($a[1] eq 'exportCache') {
|
||||||
my $cln;
|
my $cln;
|
||||||
my $crows = 0;
|
my $crows = 0;
|
||||||
@ -2718,6 +2726,371 @@ sub DbLog_Get($@) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
##########################################################################
|
||||||
|
#
|
||||||
|
# Ermittlung von DB-Parametern für configCheck
|
||||||
|
#
|
||||||
|
##########################################################################
|
||||||
|
sub DbLog_configcheck($) {
|
||||||
|
my ($hash)= @_;
|
||||||
|
my $name = $hash->{NAME};
|
||||||
|
my $dbmodel = $hash->{DBMODEL};
|
||||||
|
my $dbconn = $hash->{dbconn};
|
||||||
|
my $dbname = (split(/;|=/, $dbconn))[1];
|
||||||
|
my ($check, $rec);
|
||||||
|
|
||||||
|
# Connection und Encoding check
|
||||||
|
my (@ce,@se);
|
||||||
|
my ($chutf8mod,$chutf8dat);
|
||||||
|
if($dbmodel =~ /MYSQL/) {
|
||||||
|
@ce = DbLog_sqlget($hash,"SHOW VARIABLES LIKE 'character_set_connection'");
|
||||||
|
$chutf8mod = @ce?uc($ce[1]):"no result";
|
||||||
|
@se = DbLog_sqlget($hash,"SHOW VARIABLES LIKE 'character_set_database'");
|
||||||
|
$chutf8dat = @se?uc($se[1]):"no result";
|
||||||
|
if($chutf8mod eq $chutf8dat) {
|
||||||
|
$rec = "settings o.k.";
|
||||||
|
} else {
|
||||||
|
$rec = "Both encodings should be identical. You can adjust the usage of UTF8 connection by setting the UTF8 parameter in file '$hash->{CONFIGURATION}' to the right value. ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if($dbmodel =~ /POSTGRESQL/) {
|
||||||
|
@ce = DbLog_sqlget($hash,"SHOW CLIENT_ENCODING");
|
||||||
|
$chutf8mod = @ce?uc($ce[0]):"no result";
|
||||||
|
@se = DbLog_sqlget($hash,"select character_set_name from information_schema.character_sets");
|
||||||
|
$chutf8dat = @se?uc($se[0]):"no result";
|
||||||
|
if($chutf8mod eq $chutf8dat) {
|
||||||
|
$rec = "settings o.k.";
|
||||||
|
} else {
|
||||||
|
$rec = "This is only an information. PostgreSQL supports automatic character set conversion between server and client for certain character set combinations. The conversion information is stored in the pg_conversion system catalog. PostgreSQL comes with some predefined conversions.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$check = "<html>";
|
||||||
|
$check .= "<u><b>Result of connection check</u></b><br><br>";
|
||||||
|
|
||||||
|
if(@ce && @se) {
|
||||||
|
$check .= "Connection to database $dbname successfully done. <br>";
|
||||||
|
$check .= "<b>Recommendation:</b> settings o.k. <br><br>";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!@ce || !@se) {
|
||||||
|
$check .= "Connection to database was not successful. <br>";
|
||||||
|
$check .= "<b>Recommendation:</b> Plese see logfile for further information. <br><br>";
|
||||||
|
$check .= "</html>";
|
||||||
|
return $check;
|
||||||
|
}
|
||||||
|
|
||||||
|
$check .= "<u><b>Result of encoding check</u></b><br><br>";
|
||||||
|
$check .= "Encoding used by Client (connection): $chutf8mod <br>";
|
||||||
|
$check .= "Encoding used by $dbname: $chutf8dat <br>";
|
||||||
|
$check .= "<b>Recommendation:</b> $rec <br><br>";
|
||||||
|
|
||||||
|
# Check Betriebsmodus
|
||||||
|
my $mode = $hash->{MODE};
|
||||||
|
my $sfx = AttrVal("global", "language", "EN");
|
||||||
|
$sfx = ($sfx eq "EN" ? "" : "_$sfx");
|
||||||
|
|
||||||
|
$check .= "<u><b>Result of logmode check</u></b><br><br>";
|
||||||
|
$check .= "Logmode of DbLog-device $name is: $mode <br>";
|
||||||
|
if($mode =~ /asynchronous/) {
|
||||||
|
$rec = "settings o.k.";
|
||||||
|
} else {
|
||||||
|
$rec = "Switch $name to the asynchronous logmode by setting the 'asyncMode' attribute. The advantage of this mode is to log events non-blocking. <br>";
|
||||||
|
$rec .= "There are attributes 'syncInterval' and 'cacheLimit' relevant for this working mode. <br>";
|
||||||
|
$rec .= "Please refer to Commandref <a href='$FW_ME/docs/commandref${sfx}.html#DbLogattr' target='_blank'>attributes</a> for further informations. ";
|
||||||
|
}
|
||||||
|
$check .= "<b>Recommendation:</b> $rec <br><br>";
|
||||||
|
|
||||||
|
# Check Spaltenbreite history
|
||||||
|
my (@sr_dev,@sr_typ,@sr_evt,@sr_rdg,@sr_val,@sr_unt);
|
||||||
|
my ($cdat_dev,$cdat_typ,$cdat_evt,$cdat_rdg,$cdat_val,$cdat_unt);
|
||||||
|
my ($cmod_dev,$cmod_typ,$cmod_evt,$cmod_rdg,$cmod_val,$cmod_unt);
|
||||||
|
|
||||||
|
if($dbmodel =~ /MYSQL/) {
|
||||||
|
@sr_dev = DbLog_sqlget($hash,"SHOW FIELDS FROM history where FIELD='DEVICE'");
|
||||||
|
@sr_typ = DbLog_sqlget($hash,"SHOW FIELDS FROM history where FIELD='TYPE'");
|
||||||
|
@sr_evt = DbLog_sqlget($hash,"SHOW FIELDS FROM history where FIELD='EVENT'");
|
||||||
|
@sr_rdg = DbLog_sqlget($hash,"SHOW FIELDS FROM history where FIELD='READING'");
|
||||||
|
@sr_val = DbLog_sqlget($hash,"SHOW FIELDS FROM history where FIELD='VALUE'");
|
||||||
|
@sr_unt = DbLog_sqlget($hash,"SHOW FIELDS FROM history where FIELD='UNIT'");
|
||||||
|
}
|
||||||
|
if($dbmodel =~ /POSTGRESQL/) {
|
||||||
|
@sr_dev = DbLog_sqlget($hash,"select column_name,character_maximum_length from information_schema.columns where table_schema='$dbname' and table_name='history' and column_name='device'");
|
||||||
|
@sr_typ = DbLog_sqlget($hash,"select column_name,character_maximum_length from information_schema.columns where table_schema='$dbname' and table_name='history' and column_name='type'");
|
||||||
|
@sr_evt = DbLog_sqlget($hash,"select column_name,character_maximum_length from information_schema.columns where table_schema='$dbname' and table_name='history' and column_name='event'");
|
||||||
|
@sr_rdg = DbLog_sqlget($hash,"select column_name,character_maximum_length from information_schema.columns where table_schema='$dbname' and table_name='history' and column_name='reading'");
|
||||||
|
@sr_val = DbLog_sqlget($hash,"select column_name,character_maximum_length from information_schema.columns where table_schema='$dbname' and table_name='history' and column_name='value'");
|
||||||
|
@sr_unt = DbLog_sqlget($hash,"select column_name,character_maximum_length from information_schema.columns where table_schema='$dbname' and table_name='history' and column_name='unit'");
|
||||||
|
}
|
||||||
|
|
||||||
|
$cdat_dev = @sr_dev?($sr_dev[1]):"no result";
|
||||||
|
$cdat_dev =~ tr/varchar\(|\)//d;
|
||||||
|
$cdat_typ = @sr_typ?($sr_typ[1]):"no result";
|
||||||
|
$cdat_typ =~ tr/varchar\(|\)//d;
|
||||||
|
$cdat_evt = @sr_evt?($sr_evt[1]):"no result";
|
||||||
|
$cdat_evt =~ tr/varchar\(|\)//d;
|
||||||
|
$cdat_rdg = @sr_rdg?($sr_rdg[1]):"no result";
|
||||||
|
$cdat_rdg =~ tr/varchar\(|\)//d;
|
||||||
|
$cdat_val = @sr_val?($sr_val[1]):"no result";
|
||||||
|
$cdat_val =~ tr/varchar\(|\)//d;
|
||||||
|
$cdat_unt = @sr_unt?($sr_unt[1]):"no result";
|
||||||
|
$cdat_unt =~ tr/varchar\(|\)//d;
|
||||||
|
|
||||||
|
$cmod_dev = $hash->{HELPER}{DEVICECOL};
|
||||||
|
$cmod_typ = $hash->{HELPER}{TYPECOL};
|
||||||
|
$cmod_evt = $hash->{HELPER}{EVENTCOL};
|
||||||
|
$cmod_rdg = $hash->{HELPER}{READINGCOL};
|
||||||
|
$cmod_val = $hash->{HELPER}{VALUECOL};
|
||||||
|
$cmod_unt = $hash->{HELPER}{UNITCOL};
|
||||||
|
|
||||||
|
if($cdat_dev >= $cmod_dev && $cdat_typ >= $cmod_typ && $cdat_evt >= $cmod_evt && $cdat_rdg >= $cmod_rdg && $cdat_val >= $cmod_val && $cdat_unt >= $cmod_unt) {
|
||||||
|
$rec = "settings o.k.";
|
||||||
|
} else {
|
||||||
|
$rec = "The relation between column width in table history and the field width used in device $name don't meet the requirements. ";
|
||||||
|
$rec .= "Please make sure that the width of database field definition is equal or larger than the field width used by the module. Compare the given results.<br>";
|
||||||
|
$rec .= "Currently the default values for field width are: <br><br>";
|
||||||
|
$rec .= "DEVICE: $columns{DEVICE} <br>";
|
||||||
|
$rec .= "TYPE: $columns{TYPE} <br>";
|
||||||
|
$rec .= "EVENT: $columns{EVENT} <br>";
|
||||||
|
$rec .= "READING: $columns{READING} <br>";
|
||||||
|
$rec .= "UNIT: $columns{UNIT} <br>";
|
||||||
|
$rec .= "DEVICE: $columns{DEVICE} <br><br>";
|
||||||
|
$rec .= "You can change the column width in database by a statement like <b>'alter table history modify VALUE varchar(128);</b>' (example for changing field 'VALUE'). ";
|
||||||
|
$rec .= "You can do it for example by executing 'sqlCMD' in DbRep or in a SQL-Editor of your choice. (switch $name to asynchron mode for non-blocking). <br>";
|
||||||
|
$rec .= "The field width used by the module can be done by setting <a href='$FW_ME/docs/commandref${sfx}.html#DbLogattr' target='_blank'>attributes</a> 'colEvent', 'colReading', 'colValue',";
|
||||||
|
}
|
||||||
|
|
||||||
|
$check .= "<u><b>Result of table 'history' check</u></b><br><br>";
|
||||||
|
$check .= "Column width set in $dbname: 'DEVICE' = $cdat_dev, 'TYPE' = $cdat_typ, 'EVENT' = $cdat_evt, 'READING' = $cdat_rdg, 'VALUE' = $cdat_val, 'UNIT' = $cdat_unt <br>";
|
||||||
|
$check .= "Column width used by $name: 'DEVICE' = $cmod_dev, 'TYPE' = $cmod_typ, 'EVENT' = $cmod_evt, 'READING' = $cmod_rdg, 'VALUE' = $cmod_val, 'UNIT' = $cmod_unt <br>";
|
||||||
|
$check .= "<b>Recommendation:</b> $rec <br><br>";
|
||||||
|
|
||||||
|
# Check Spaltenbreite current
|
||||||
|
if($dbmodel =~ /MYSQL/) {
|
||||||
|
@sr_dev = DbLog_sqlget($hash,"SHOW FIELDS FROM current where FIELD='DEVICE'");
|
||||||
|
@sr_typ = DbLog_sqlget($hash,"SHOW FIELDS FROM current where FIELD='TYPE'");
|
||||||
|
@sr_evt = DbLog_sqlget($hash,"SHOW FIELDS FROM current where FIELD='EVENT'");
|
||||||
|
@sr_rdg = DbLog_sqlget($hash,"SHOW FIELDS FROM current where FIELD='READING'");
|
||||||
|
@sr_val = DbLog_sqlget($hash,"SHOW FIELDS FROM current where FIELD='VALUE'");
|
||||||
|
@sr_unt = DbLog_sqlget($hash,"SHOW FIELDS FROM current where FIELD='UNIT'");
|
||||||
|
}
|
||||||
|
|
||||||
|
if($dbmodel =~ /POSTGRESQL/) {
|
||||||
|
@sr_dev = DbLog_sqlget($hash,"select column_name,character_maximum_length from information_schema.columns where table_schema='$dbname' and table_name='current' and column_name='device'");
|
||||||
|
@sr_typ = DbLog_sqlget($hash,"select column_name,character_maximum_length from information_schema.columns where table_schema='$dbname' and table_name='current' and column_name='type'");
|
||||||
|
@sr_evt = DbLog_sqlget($hash,"select column_name,character_maximum_length from information_schema.columns where table_schema='$dbname' and table_name='current' and column_name='event'");
|
||||||
|
@sr_rdg = DbLog_sqlget($hash,"select column_name,character_maximum_length from information_schema.columns where table_schema='$dbname' and table_name='current' and column_name='reading'");
|
||||||
|
@sr_val = DbLog_sqlget($hash,"select column_name,character_maximum_length from information_schema.columns where table_schema='$dbname' and table_name='current' and column_name='value'");
|
||||||
|
@sr_unt = DbLog_sqlget($hash,"select column_name,character_maximum_length from information_schema.columns where table_schema='$dbname' and table_name='current' and column_name='unit'");
|
||||||
|
}
|
||||||
|
|
||||||
|
$cdat_dev = @sr_dev?($sr_dev[1]):"no result";
|
||||||
|
$cdat_dev =~ tr/varchar\(|\)//d;
|
||||||
|
$cdat_typ = @sr_typ?($sr_typ[1]):"no result";
|
||||||
|
$cdat_typ =~ tr/varchar\(|\)//d;
|
||||||
|
$cdat_evt = @sr_evt?($sr_evt[1]):"no result";
|
||||||
|
$cdat_evt =~ tr/varchar\(|\)//d;
|
||||||
|
$cdat_rdg = @sr_rdg?($sr_rdg[1]):"no result";
|
||||||
|
$cdat_rdg =~ tr/varchar\(|\)//d;
|
||||||
|
$cdat_val = @sr_val?($sr_val[1]):"no result";
|
||||||
|
$cdat_val =~ tr/varchar\(|\)//d;
|
||||||
|
$cdat_unt = @sr_unt?($sr_unt[1]):"no result";
|
||||||
|
$cdat_unt =~ tr/varchar\(|\)//d;
|
||||||
|
|
||||||
|
$cmod_dev = $hash->{HELPER}{DEVICECOL};
|
||||||
|
$cmod_typ = $hash->{HELPER}{TYPECOL};
|
||||||
|
$cmod_evt = $hash->{HELPER}{EVENTCOL};
|
||||||
|
$cmod_rdg = $hash->{HELPER}{READINGCOL};
|
||||||
|
$cmod_val = $hash->{HELPER}{VALUECOL};
|
||||||
|
$cmod_unt = $hash->{HELPER}{UNITCOL};
|
||||||
|
|
||||||
|
if($cdat_dev >= $cmod_dev && $cdat_typ >= $cmod_typ && $cdat_evt >= $cmod_evt && $cdat_rdg >= $cmod_rdg && $cdat_val >= $cmod_val && $cdat_unt >= $cmod_unt) {
|
||||||
|
$rec = "settings o.k.";
|
||||||
|
} else {
|
||||||
|
$rec = "The relation between column width in table current and the field width used in device $name don't meet the requirements. ";
|
||||||
|
$rec .= "Please make sure that the width of database field definition is equal or larger than the field width used by the module. Compare the given results.<br>";
|
||||||
|
$rec .= "Currently the default values for field width are: <br><br>";
|
||||||
|
$rec .= "DEVICE: $columns{DEVICE} <br>";
|
||||||
|
$rec .= "TYPE: $columns{TYPE} <br>";
|
||||||
|
$rec .= "EVENT: $columns{EVENT} <br>";
|
||||||
|
$rec .= "READING: $columns{READING} <br>";
|
||||||
|
$rec .= "UNIT: $columns{UNIT} <br>";
|
||||||
|
$rec .= "DEVICE: $columns{DEVICE} <br><br>";
|
||||||
|
$rec .= "You can change the column width in database by a statement like <b>'alter table current modify VALUE varchar(128);</b>' (example for changing field 'VALUE'). ";
|
||||||
|
$rec .= "You can do it for example by executing 'sqlCMD' in DbRep or in a SQL-Editor of your choice. (switch $name to asynchron mode for non-blocking). <br>";
|
||||||
|
$rec .= "The field width used by the module can be done by setting <a href='$FW_ME/docs/commandref${sfx}.html#DbLogattr' target='_blank'>attributes</a> 'colEvent', 'colReading', 'colValue',";
|
||||||
|
}
|
||||||
|
|
||||||
|
$check .= "<u><b>Result of table 'current' check</u></b><br><br>";
|
||||||
|
$check .= "Column width set in $dbname: 'DEVICE' = $cdat_dev, 'TYPE' = $cdat_typ, 'EVENT' = $cdat_evt, 'READING' = $cdat_rdg, 'VALUE' = $cdat_val, 'UNIT' = $cdat_unt <br>";
|
||||||
|
$check .= "Column width used by $name: 'DEVICE' = $cmod_dev, 'TYPE' = $cmod_typ, 'EVENT' = $cmod_evt, 'READING' = $cmod_rdg, 'VALUE' = $cmod_val, 'UNIT' = $cmod_unt <br>";
|
||||||
|
$check .= "<b>Recommendation:</b> $rec <br><br>";
|
||||||
|
|
||||||
|
# Check Vorhandensein Search_Idx mit den empfohlenen Spalten
|
||||||
|
my (@six,@six_dev,@six_rdg,@six_tsp);
|
||||||
|
my ($idef,$idef_dev,$idef_rdg,$idef_tsp);
|
||||||
|
$check .= "<u><b>Result of check 'Search_Idx' availability</u></b><br><br>";
|
||||||
|
|
||||||
|
if($dbmodel =~ /MYSQL/) {
|
||||||
|
@six = DbLog_sqlget($hash,"SHOW INDEX FROM history where Key_name='Search_Idx'");
|
||||||
|
if (!@six) {
|
||||||
|
$check .= "The index 'Search_Idx' is missing. <br>";
|
||||||
|
$rec = "You can create the index by executing statement 'CREATE INDEX Search_Idx ON `history` (DEVICE, READING, TIMESTAMP);' <br>";
|
||||||
|
$rec .= "Depending on your database size this command may running a long time. <br>"
|
||||||
|
} else {
|
||||||
|
@six_dev = DbLog_sqlget($hash,"SHOW INDEX FROM history where Key_name='Search_Idx' and Column_name='DEVICE'");
|
||||||
|
@six_rdg = DbLog_sqlget($hash,"SHOW INDEX FROM history where Key_name='Search_Idx' and Column_name='READING'");
|
||||||
|
@six_tsp = DbLog_sqlget($hash,"SHOW INDEX FROM history where Key_name='Search_Idx' and Column_name='TIMESTAMP'");
|
||||||
|
if (@six_dev && @six_rdg && @six_tsp) {
|
||||||
|
$check .= "Index 'Search_Idx' exists and contains the recommended fields 'DEVICE', 'READING', 'TIMESTAMP'. <br>";
|
||||||
|
$rec = "settings o.k.";
|
||||||
|
} else {
|
||||||
|
$check .= "Index 'Search_Idx' exists but doesn't contain recommended field 'DEVICE'. <br>" if (!@six_dev);
|
||||||
|
$check .= "Index 'Search_Idx' exists but doesn't contain recommended field 'READING'. <br>" if (!@six_rdg);
|
||||||
|
$check .= "Index 'Search_Idx' exists but doesn't contain recommended field 'TIMESTAMP'. <br>" if (!@six_tsp);
|
||||||
|
$rec = "The index should contain the fields 'DEVICE', 'READING', 'TIMESTAMP'. ";
|
||||||
|
$rec .= "You can change the index by executing e.g. <br>";
|
||||||
|
$rec .= "'ALTER TABLE `history` DROP INDEX `Search_Idx`, ADD INDEX `Search_Idx` (`DEVICE`, `READING`, `TIMESTAMP`) USING BTREE' <br>";
|
||||||
|
$rec .= "Depending on your database size this command may running a long time. <br>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if($dbmodel =~ /POSTGRESQL/) {
|
||||||
|
@six = DbLog_sqlget($hash,"SELECT * FROM pg_indexes WHERE tablename='history' and indexname ='Search_Idx'");
|
||||||
|
if (!@six) {
|
||||||
|
$check .= "The index 'Search_Idx' is missing. <br>";
|
||||||
|
$rec = "You can create the index by executing statement 'CREATE INDEX \"Search_Idx\" ON history USING btree (device, reading, \"timestamp\")' <br>";
|
||||||
|
$rec .= "Depending on your database size this command may running a long time. <br>"
|
||||||
|
} else {
|
||||||
|
$idef = $six[4];
|
||||||
|
$idef_dev = 1 if($idef =~ /device/);
|
||||||
|
$idef_rdg = 1 if($idef =~ /reading/);
|
||||||
|
$idef_tsp = 1 if($idef =~ /timestamp/);
|
||||||
|
if ($idef_dev && $idef_rdg && $idef_tsp) {
|
||||||
|
$check .= "Index 'Search_Idx' exists and contains the recommended fields 'DEVICE', 'READING', 'TIMESTAMP'. <br>";
|
||||||
|
$rec = "settings o.k.";
|
||||||
|
} else {
|
||||||
|
$check .= "Index 'Search_Idx' exists but doesn't contain recommended field 'DEVICE'. <br>" if (!$idef_dev);
|
||||||
|
$check .= "Index 'Search_Idx' exists but doesn't contain recommended field 'READING'. <br>" if (!$idef_rdg);
|
||||||
|
$check .= "Index 'Search_Idx' exists but doesn't contain recommended field 'TIMESTAMP'. <br>" if (!$idef_tsp);
|
||||||
|
$rec = "The index should contain the fields 'DEVICE', 'READING', 'TIMESTAMP'. ";
|
||||||
|
$rec .= "You can change the index by executing e.g. <br>";
|
||||||
|
$rec .= "'DROP INDEX \"Search_Idx\"; CREATE INDEX \"Search_Idx\" ON history USING btree (device, reading, \"timestamp\")' <br>";
|
||||||
|
$rec .= "Depending on your database size this command may running a long time. <br>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$check .= "<b>Recommendation:</b> $rec <br><br>";
|
||||||
|
|
||||||
|
# Check Index Reading_Time_Idx für DbRep-Device falls DbRep verwendet wird
|
||||||
|
my ($dbrp,$irep,);
|
||||||
|
my (@dix,@dix_rdg,@dix_tsp,$irep_rdg,$irep_tsp);
|
||||||
|
my $isused = 0;
|
||||||
|
my @repdvs = devspec2array("TYPE=DbRep");
|
||||||
|
$check .= "<u><b>Result of check 'Reading_Time_Idx' availability for DbRep-devices</u></b><br><br>";
|
||||||
|
|
||||||
|
foreach (@repdvs) {
|
||||||
|
$dbrp = $_;
|
||||||
|
if(!$defs{$dbrp}) {
|
||||||
|
Log3 ($name, 2, "DbLog $name -> Device '$dbrp' found by configCheck doesn't exist !");
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
if ($defs{$dbrp}->{DEF} eq $name) {
|
||||||
|
# DbRep Device verwendet aktuelles DbLog-Device
|
||||||
|
Log3 ($name, 5, "DbLog $name -> DbRep-Device '$dbrp' uses $name.");
|
||||||
|
$isused = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($isused) {
|
||||||
|
if($dbmodel =~ /MYSQL/) {
|
||||||
|
@dix = DbLog_sqlget($hash,"SHOW INDEX FROM history where Key_name='Reading_Time_Idx'");
|
||||||
|
if (!@dix) {
|
||||||
|
$check .= "You use at least one DbRep-device assigned to $name, but the recommended index 'Reading_Time_Idx' is missing. <br>";
|
||||||
|
$rec = "You can create the index by executing statement 'CREATE INDEX Reading_Time_Idx ON `history` (READING, TIMESTAMP) USING BTREE;' <br>";
|
||||||
|
$rec .= "Depending on your database size this command may running a long time. <br>"
|
||||||
|
} else {
|
||||||
|
@dix_rdg = DbLog_sqlget($hash,"SHOW INDEX FROM history where Key_name='Reading_Time_Idx' and Column_name='READING'");
|
||||||
|
@dix_tsp = DbLog_sqlget($hash,"SHOW INDEX FROM history where Key_name='Reading_Time_Idx' and Column_name='TIMESTAMP'");
|
||||||
|
if (@dix_rdg && @dix_tsp) {
|
||||||
|
$check .= "You use at least one DbRep-device assigned to $name. ";
|
||||||
|
$check .= "Index 'Reading_Time_Idx' exists and contains the recommended fields 'READING', 'TIMESTAMP'. <br>";
|
||||||
|
$rec = "settings o.k.";
|
||||||
|
} else {
|
||||||
|
$check .= "You use at least one DbRep-device assigned to $name. ";
|
||||||
|
$check .= "Index 'Reading_Time_Idx' exists but doesn't contain recommended field 'READING'. <br>" if (!@dix_rdg);
|
||||||
|
$check .= "Index 'Reading_Time_Idx' exists but doesn't contain recommended field 'TIMESTAMP'. <br>" if (!@dix_tsp);
|
||||||
|
$rec = "The index should contain the fields 'READING', 'TIMESTAMP'. ";
|
||||||
|
$rec .= "You can change the index by executing e.g. <br>";
|
||||||
|
$rec .= "'ALTER TABLE `history` DROP INDEX `Reading_Time_Idx`, ADD INDEX `Reading_Time_Idx` (`READING`, `TIMESTAMP`) USING BTREE' <br>";
|
||||||
|
$rec .= "Depending on your database size this command may running a long time. <br>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if($dbmodel =~ /POSTGRESQL/) {
|
||||||
|
@dix = DbLog_sqlget($hash,"SELECT * FROM pg_indexes WHERE tablename='history' and indexname ='Reading_Time_Idx'");
|
||||||
|
if (!@dix) {
|
||||||
|
$check .= "You use at least one DbRep-device assigned to $name, but the recommended index 'Reading_Time_Idx' is missing. <br>";
|
||||||
|
$rec = "You can create the index by executing statement 'CREATE INDEX \"Reading_Time_Idx\" ON history USING btree (reading, \"timestamp\")' <br>";
|
||||||
|
$rec .= "Depending on your database size this command may running a long time. <br>"
|
||||||
|
} else {
|
||||||
|
$irep = $dix[4];
|
||||||
|
$irep_rdg = 1 if($irep =~ /reading/);
|
||||||
|
$irep_tsp = 1 if($irep =~ /timestamp/);
|
||||||
|
if ($irep_rdg && $irep_tsp) {
|
||||||
|
$check .= "Index 'Reading_Time_Idx' exists and contains the recommended fields 'READING', 'TIMESTAMP'. <br>";
|
||||||
|
$rec = "settings o.k.";
|
||||||
|
} else {
|
||||||
|
$check .= "Index 'Reading_Time_Idx' exists but doesn't contain recommended field 'READING'. <br>" if (!$irep_rdg);
|
||||||
|
$check .= "Index 'Reading_Time_Idx' exists but doesn't contain recommended field 'TIMESTAMP'. <br>" if (!$irep_tsp);
|
||||||
|
$rec = "The index should contain the fields 'READING', 'TIMESTAMP'. ";
|
||||||
|
$rec .= "You can change the index by executing e.g. <br>";
|
||||||
|
$rec .= "'DROP INDEX \"Reading_Time_Idx\"; CREATE INDEX \"Reading_Time_Idx\" ON history USING btree (reading, \"timestamp\")' <br>";
|
||||||
|
$rec .= "Depending on your database size this command may running a long time. <br>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$check .= "You don't use any DbRep-device assigned to $name. Hence an index for DbRep isn't needed. <br>";
|
||||||
|
$rec = "settings o.k.";
|
||||||
|
}
|
||||||
|
$check .= "<b>Recommendation:</b> $rec <br><br>";
|
||||||
|
|
||||||
|
$check .= "</html>";
|
||||||
|
|
||||||
|
return $check;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub DbLog_sqlget($$) {
|
||||||
|
my ($hash,$sql)= @_;
|
||||||
|
my $name = $hash->{NAME};
|
||||||
|
my ($dbh,$sth,@sr);
|
||||||
|
|
||||||
|
Log3 ($name, 4, "DbLog $name - Executing SQL: $sql");
|
||||||
|
|
||||||
|
$dbh = DbLog_ConnectNewDBH($hash);
|
||||||
|
return if(!$dbh);
|
||||||
|
|
||||||
|
eval { $sth = $dbh->prepare("$sql");
|
||||||
|
$sth->execute;
|
||||||
|
};
|
||||||
|
if($@) {
|
||||||
|
$dbh->disconnect if($dbh);
|
||||||
|
Log3 ($name, 2, "DbLog $name - $@");
|
||||||
|
return @sr;
|
||||||
|
}
|
||||||
|
|
||||||
|
@sr = $sth->fetchrow;
|
||||||
|
|
||||||
|
$sth->finish;
|
||||||
|
$dbh->disconnect;
|
||||||
|
no warnings 'uninitialized';
|
||||||
|
Log3 ($name, 4, "DbLog $name - SQL result: @sr");
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
return @sr;
|
||||||
|
}
|
||||||
|
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
#
|
#
|
||||||
# Addlog - einfügen des Readingwertes eines gegebenen Devices
|
# Addlog - einfügen des Readingwertes eines gegebenen Devices
|
||||||
@ -4131,22 +4504,33 @@ sub checkUsePK ($$){
|
|||||||
</ol>
|
</ol>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
The content of VALUE is optimized for automated post-processing, e.g.
|
The content of VALUE is optimized for automated post-processing, e.g. <code>yes</code> is translated to <code>1</code>
|
||||||
<code>yes</code> is translated to <code>1</code>
|
|
||||||
<br><br>
|
<br><br>
|
||||||
|
|
||||||
The current values can be retrieved by the following code like FileLog:<br>
|
The current values can be retrieved by the following code like FileLog:<br>
|
||||||
<ul>
|
<ul>
|
||||||
<code>get myDbLog - - 2012-11-10 2012-11-10 KS300:temperature::</code>
|
<code>get myDbLog - - 2012-11-10 2012-11-10 KS300:temperature::</code>
|
||||||
</ul>
|
</ul>
|
||||||
<br><br>
|
<br>
|
||||||
<b>Examples:</b>
|
|
||||||
|
<b>Example:</b>
|
||||||
<ul>
|
<ul>
|
||||||
<code># log everything to database</code><br>
|
<code>define myDbLog DbLog /etc/fhem/db.conf .*:.*</code> <br>
|
||||||
|
<code># log everything to database</code>
|
||||||
<code>define myDbLog DbLog /etc/fhem/db.conf .*:.*</code>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
After you have defined your DbLog-device it is recommended to run the command <br><br>
|
||||||
|
<ul>
|
||||||
|
<code>set <name> configCheck</code> <br>
|
||||||
|
</ul>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
This check reports some important settings and gives recommendations back to you if proposals are indentified.
|
||||||
|
(Available for MySQL, PostgreSQL) <br>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
<br/><br/>
|
<br><br>
|
||||||
|
|
||||||
<a name="DbLogset"></a>
|
<a name="DbLogset"></a>
|
||||||
<b>Set</b>
|
<b>Set</b>
|
||||||
@ -4176,6 +4560,10 @@ sub checkUsePK ($$){
|
|||||||
The command can be usefull in case of you want to write the cached data manually or e.g. by an AT-device on a defined
|
The command can be usefull in case of you want to write the cached data manually or e.g. by an AT-device on a defined
|
||||||
point of time into the database. </ul><br>
|
point of time into the database. </ul><br>
|
||||||
|
|
||||||
|
<code>set <name> configCheck </code><br><br>
|
||||||
|
<ul>This command checks some important settings and gives recommendations back to you if proposals are indentified.
|
||||||
|
(available for MySQL, PostgreSQL) </ul><br>
|
||||||
|
|
||||||
<code>set <name> count </code><br/><br/>
|
<code>set <name> count </code><br/><br/>
|
||||||
<ul>Count records in tables current and history and write results into readings countCurrent and countHistory.</ul><br/>
|
<ul>Count records in tables current and history and write results into readings countCurrent and countHistory.</ul><br/>
|
||||||
|
|
||||||
@ -4910,17 +5298,31 @@ sub checkUsePK ($$){
|
|||||||
Der Wert des Readings ist optimiert für eine automatisierte Nachverarbeitung
|
Der Wert des Readings ist optimiert für eine automatisierte Nachverarbeitung
|
||||||
z.B. <code>yes</code> ist transformiert nach <code>1</code>
|
z.B. <code>yes</code> ist transformiert nach <code>1</code>
|
||||||
<br><br>
|
<br><br>
|
||||||
Die gespeicherten Werte können mittels GET Funktion angezeigt werden:
|
|
||||||
|
Die gespeicherten Werte können mittels GET Funktion angezeigt werden:
|
||||||
<ul>
|
<ul>
|
||||||
<code>get myDbLog - - 2012-11-10 2012-11-10 KS300:temperature</code>
|
<code>get myDbLog - - 2012-11-10 2012-11-10 KS300:temperature</code>
|
||||||
</ul>
|
</ul>
|
||||||
<br><br>
|
<br>
|
||||||
|
|
||||||
<b>Beispiel:</b>
|
<b>Beispiel:</b>
|
||||||
<ul>
|
<ul>
|
||||||
<code>Speichert alles in der Datenbank</code><br>
|
<code>define myDbLog DbLog /etc/fhem/db.conf .*:.*</code><br>
|
||||||
<code>define myDbLog DbLog /etc/fhem/db.conf .*:.*</code>
|
<code>Speichert alles in der Datenbank</code>
|
||||||
</ul>
|
</ul>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
Nachdem das DbLog-Device definiert wurde, ist empfohlen einen Konfigurationscheck auszuführen: <br><br>
|
||||||
|
<ul>
|
||||||
|
<code>set <name> configCheck</code> <br>
|
||||||
|
</ul>
|
||||||
|
<br>
|
||||||
|
Dieser Check prüft einige wichtige Einstellungen des DbLog-Devices und gibt Empfehlungen für potentielle Verbesserungen.
|
||||||
|
(verfügbar für MySQL, PostgreSQL) <br>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
|
||||||
<a name="DbLogset"></a>
|
<a name="DbLogset"></a>
|
||||||
@ -4952,7 +5354,11 @@ sub checkUsePK ($$){
|
|||||||
und danach der Cache geleert. Der interne Timer des asynchronen Modus wird dabei neu gesetzt.
|
und danach der Cache geleert. Der interne Timer des asynchronen Modus wird dabei neu gesetzt.
|
||||||
Der Befehl kann nützlich sein um manuell oder z.B. über ein AT den Cacheinhalt zu einem definierten Zeitpunkt in die
|
Der Befehl kann nützlich sein um manuell oder z.B. über ein AT den Cacheinhalt zu einem definierten Zeitpunkt in die
|
||||||
Datenbank zu schreiben. </ul><br>
|
Datenbank zu schreiben. </ul><br>
|
||||||
|
|
||||||
|
<code>set <name> configCheck </code><br><br>
|
||||||
|
<ul>Es werden einige wichtige Einstellungen geprüft und Empfehlungen zurück gegeben wenn potentielle Verbesserungen
|
||||||
|
identifiziert wurden. (Verfügbar für MySQL, PostgreSQL) </ul><br/>
|
||||||
|
|
||||||
<code>set <name> count </code><br><br>
|
<code>set <name> count </code><br><br>
|
||||||
<ul>Zählt die Datensätze in den Tabellen current und history und schreibt die Ergebnisse in die Readings
|
<ul>Zählt die Datensätze in den Tabellen current und history und schreibt die Ergebnisse in die Readings
|
||||||
countCurrent und countHistory.</ul><br>
|
countCurrent und countHistory.</ul><br>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user