DbLog: Unterschied zwischen den Versionen
K (Vorlage Link2CmdRef) |
Mike73 (Diskussion | Beiträge) |
||
Zeile 42: | Zeile 42: | ||
:<code>define logdb DbLog ./db.conf .*:.* </code> | :<code>define logdb DbLog ./db.conf .*:.* </code> | ||
Die Angabe von <code>.*:.*</code> bedeutet, dass sämtliche DeviceMessages (Messwerte, Batteriestatus, KeepAlives, etc.) in die Datenbank geschrieben werden. Dies führt u.U. dazu, dass die Datenbank auch mit vielen teils irrelevanten Werten gefüllt wird. Man kann daher die zu loggenden Werte einschränken, indem man genau angibt welche Werte übertragen werden sollen. Dies ist in [[#Finetuning des Loggings]] beschrieben. | Die Angabe von <code>.*:.*</code> bedeutet, dass sämtliche DeviceMessages (Messwerte, Batteriestatus, KeepAlives, etc.) in die Datenbank geschrieben werden. Dies führt u.U. dazu, dass die Datenbank auch mit vielen teils irrelevanten Werten gefüllt wird. Man kann daher die zu loggenden Werte einschränken, indem man genau angibt welche Werte übertragen werden sollen. Dies ist in [[#Finetuning des Loggings]] beschrieben. | ||
Unbedingt beachten: bei Verwendung des Moduls configdb wird die Konfigurationsdatei aus der '''''Datenbank''''' gelesen. Deshalb ist es erforderlich, das File mittels <code>configdb fileimport db.conf </code> vorher zu importieren ! | |||
=== Finetuning des Loggings === | === Finetuning des Loggings === |
Version vom 4. Februar 2018, 12:11 Uhr
DbLog | |
---|---|
Zweck / Funktion | |
Protokolliert Ereignisse in einer Datenbank | |
Allgemein | |
Typ | Hilfsmodul |
Details | |
Dokumentation | EN / DE |
Support (Forum) | Automatisierung |
Modulname | 93_DbLog.pm |
Ersteller | tobiasfaust (Forum /Wiki) DS_Starter (Forum /Wiki) |
Wichtig: sofern vorhanden, gilt im Zweifel immer die (englische) Beschreibung in der commandref! |
Einleitung
Mit der Zeit entstehen in FHEM recht umfangreiche Log-Daten für die verschiedensten konfigurierten Devices. Die übliche Einstiegs-Konfiguration sieht vor, dass die Logs als FileLog gespeichert werden - je nach Einstellung in wenigen sehr großen oder vielen kleineren Dateien. Der Datei-basierte Zugriff ist allerdings nicht wirklick performant und kann schnell zum Flaschenhals werden (z.B. bei der Darstellung von Graphen über einen längeren Zeitraum).
Alternativ kann FHEM die Log-Daten mittels DbLog in einer Datenbank speichern. Diese kann lokal als einfache SQLite- oder als zentrale Server-Datenbank (s.u.) gestaltet sein. Schon eine lokale einfache SQLite-Datenbank ist in der Regel deutlich performanter als File-basierte Logs.
Damit eine Datenbank-Nutzung möglich ist, müssen folgende Anpassungen gemacht werden:
- Erstellen einer entsprechenden Datenbank
- Konfiguration der Datenbank-Anbindung in FHEM
- Anpassen aller (oder einzelner) Konfigurationen von FileLog nach DbLog
- Ggf. Anpassen der gplot-Konfigurationen
- Hinweis
Reporting und Management von DbLog-Datenbankinhalten kann mit dem Modul DbRep stattfinden.
Konfiguration
Datenbank-Anbindung mittels db.conf
DbLog wird durch 2 verschiedene Einträge aktiviert/definiert. In einer Datei namens db.conf werden die Parameter für eine Verbindung zur Datenbank (host, username, password, etc.) hinterlegt. Diese Datei kann in einem beliebigen Verzeichnis angelegt werden. Für eine MySQL-Datenbank sieht die db.conf folgendermaßen aus:
%dbconfig= ( connection => "mysql:database=fhem;host=db;port=3306", user => "fhemuser", password => "fhempassword", );
Im Verzeichnis contrib/dblog der FHEM-Installation befindet sich eine Beispielkonfiguration mit der Syntax für jeden unterstützen Datenbanktyp. Es wird empfohlen diese Datei zu kopieren und erst dann entsprechend zu bearbeiten. Am Besten kopiert man diese Datei in das FHEM Home Directory /opt/fhem/ und achtet auf die entsprechenden Rechte!
chown fhem:dialout /opt/fhem/db.conf
Konfiguration als Device
Das DbLog Device wird dann definiert mit
define <name> DbLog <configfilename> <regexp>
wobei <configfilename> dem Pfad zur zuvor angelegten db.conf entspricht. Ein Beispiel hierfür wäre:
define logdb DbLog ./db.conf .*:.*
Die Angabe von .*:.*
bedeutet, dass sämtliche DeviceMessages (Messwerte, Batteriestatus, KeepAlives, etc.) in die Datenbank geschrieben werden. Dies führt u.U. dazu, dass die Datenbank auch mit vielen teils irrelevanten Werten gefüllt wird. Man kann daher die zu loggenden Werte einschränken, indem man genau angibt welche Werte übertragen werden sollen. Dies ist in #Finetuning des Loggings beschrieben.
Unbedingt beachten: bei Verwendung des Moduls configdb wird die Konfigurationsdatei aus der Datenbank gelesen. Deshalb ist es erforderlich, das File mittels configdb fileimport db.conf
vorher zu importieren !
Finetuning des Loggings
Bei der Konfiguration des Log-Devices werden die zu loggenden Daten definiert - in der einfachsten Form sieht das so aus: define logdb DbLog ./db.conf .*:.*
. Die Angabe von .*:.*
bedeutet, dass sämtliche DeviceMessages (Messwerte, Batteriestatus, KeepAlives, etc.) in die Datenbank geschrieben werden. Dies führt u.U. dazu, dass die Datenbank auch mit sehr vielen und teils nicht benötigten Werten gefüllt wird und schnell wächst. Die Datenbank ist zwar deutlich leistungsfähiger, was große Datenmengen angeht, Datensparsamkeit kann aber schnell sinnvoll werden...
Um das Log-Aufkommen einzugrenzen gibt es 2 Ansätze:
- Einschränkung über den
define
-Eintrag - Einschränkung über DbLogExclude-Einträge der jeweiligen Devices
- Einschränkung über DbLogInclude-Einträge des jeweiligen Devices
Einschränkung über den zentralen define
-Eintrag
Man kann die zu loggenden Werte einschränken, indem man genau angibt welche Werte übertragen werden sollen. Die erste Wildcard, also das erste .*
, entspricht dem in FHEM verwendeten Device-Namen. Die zweite Wildcard entspricht dem vom Device ausgegebenen zu loggenden Wert. Separiert werden beiden Angaben durch einen Doppelpunkt.
Ein Beispiel, um zwar alle definierten Devices zu erfassen, aber nur die Werte Temperatur, Ventilposition und Luftfeuchte in die Datenbank zu schreiben wäre:
define myDbLog DbLog ./db.conf .*:(temperature|valveposition|humidity).*
Einschränkung über die jeweiligen Devices
Man kann die zu loggenden Werte für einzelne Devices separat einschränken, ohne dies im zentralen define-Eintrag machen zu müssen. Dies kann interessant sein, wenn beispielsweise ein Device Fehlerwerte meldet, die uninteressant sind, oder es meldet unnötig häufig Werte - beides ist z.B. bei 1-wire-Temperatursensoren gerne der Fall.
Um das einzuschränken gibt es 2 Stellparameter, die als Attribute direkt zum jeweiligen Device konfiguriert werden:
- DbLogExclude - definiert Werte, die nicht geloggt werden sollen
- DbLogInclude - definiert Werte, die geloggt werden sollen ( siehe attr DbLogSelectionMode )
- event-min-interval, event-on-change-reading und event-on-update-reading beeinflussen, wie häufig Werte geloggt werden (vgl. commandref/event-on-update-reading)
Eine konkrete Konfiguration für einen sehr gesprächigen 1-wire-Temperatursensor könnte wie folgt aussehen:
define EG_Balkon GPIO4 BUSMASTER attr EG_Balkon DbLogExclude failures,T,85 # logge keine "failures", "T"-Werte und "85"-Werte (default-Werte, wenn keine Temperatur gelesen werden kann) attr EG_Balkon event-on-change-reading state # logge nur, wenn sich ein Wert ändert (wenn sich die Temperatur nicht ändert, logge das nicht) attr EG_Balkon event-min-interval state:900 # logge spätestens alle 900sec = 15min attr EG_Balkon event-on-update-reading .* # logge alle Werte, die aktualisiert werden attr <1-Wire-Device vom Typ OWTHERM oder OWSWITCH> DbLogExclude data.* # verhindert das Logging der state-Eintragungen
Eine in diesem Beitrag vorgestellte Strategie zur Vermeidung unnötigen Loggings ist, dass bei der Definition von Devices durch das nachfolgende notify
automatisch ein DbLogExclude für alle Werte (.*) des Devices zugewiesen wird und dies nur bei Interesse an geloggten Werten gelöscht bzw. angepasst wird:
define nDbLogExclude notify global:DEFINED.* attr $EVTPART1 DbLogExclude .*
Ebenso ist es mittlerweile möglich, lediglich erwünschte Werte (Positiv-Liste) zu loggen und alle anderen zu verwerfen. Hierfür wird im LogDevice das attribut DbLogSelectionMode Include verwendet. Nun kann für jedes Device mit DbLogInclude <Reading1>,<Reading2>,... angegeben werden, welche Readings geloggt werden sollen. Integriert ist ebenfalls ein "min-interval", siehe commandref.
Datenbank
Unterstützte Datenbanksysteme (Auswahl):
- Sqlite
- MySQL
- PostGreSql
Tabellen
Die Datenbank ist relativ simpel gestaltet und besteht lediglich aus den folgenden beiden Tabellen:
- current
- history
DbLog ist auf eine feste Tabellenstruktur angewiesen. Man muss daher in seiner Datenbank eine Tabelle mit folgenden Spalten anlegen:
Spalte | Beschreibung (en) | Beschreibung (de) | Beispiel |
---|---|---|---|
TIMESTAMP | timestamp of event | Zeitstempel | 2007-12-30 21:45:22 |
DEVICE | device name | Device-Name | Wetterstation |
TYPE | device type | Device-Typ | KS300 |
EVENT | event specification as full string | Eventspezifikation als Text | humidity: 71 (%) |
READING | name of reading extracted from event | Bezeichnung des Readings | humidity |
VALUE | actual reading extracted from event | Wert des Readings | 71 |
UNIT | unit extracted from event | Einheit des Readings | % |
Die Vorlagen zur Anlage von Tabellen und Indizes sind für jeden unterstützten Datenbanktyp im Verzeichnis contrib/dblog der FHEM-Installation, oder hier zu finden: Link. Das MySQL-Skript (db_create_mysql.sql) legt eine neue Datenbank, das PostGres-Skript (db_create_postgresql.sql) ein neues Schema mit Namen "fhem" an.
current
Die Tabelle current enthält für jedes zu loggende Device lediglich den letzten Wert. Falls noch kein Wert geloggt wurde, ist diese Tabelle leer. Falls der Inhalt gelöscht wird, bauen sich die Daten automatisch wieder auf. Es gehen durch das löschen der Tabelle current keine Log-Informationen verloren. Der Inhalt wird aber u.a. für die Dropdown-Felder beim Plot-Editor verwendet.
Um doppelte Einträge in der Tabelle zu vermeiden, wurden die Möglichkeit geschaffen Primary Keys zu definieren. Da in der Spalte READING
u.U. bei verschiedenen Geräten gleiche Namen vorkommen können, sollte der Primary Key um den Gerätenamen erweitert werden. Der Primary Key sollte also aus DEVICE
und READING
bestehen. Um in der Datenbank fhem diesen PK zu setzen, kann folgender SQL Code verwendet werden:
ALTER TABLE `fhem`.`current`
CHANGE COLUMN `DEVICE` `DEVICE` VARCHAR(64) CHARACTER SET 'utf8' COLLATE 'utf8_bin' NOT NULL ,
CHANGE COLUMN `READING` `READING` VARCHAR(64) CHARACTER SET 'utf8' COLLATE 'utf8_bin' NOT NULL ,
ADD PRIMARY KEY (`DEVICE`, `READING`);
history
Die Tabelle history enthält alle bisher geloggten Daten. Löschen in dieser Tabelle bedeutet automatisch Datenverlust (gewollt oder nicht ... ) Der Inhalt dieser Tabelle wird verwendet, um die Plots zu zeichnen oder Auswertungen mit DbRep anzufertigen
Todo: Ausbauen |
Um Problem beim Import von cacheFiles zu vermeiden, kann in der Datenbank ein PK angelegt werden, welcher Timestamp, Device und Reading umfasst. Dadurch werden doppelte Einträge wirksam verhindert.
Anpassen der gplot-Konfigurationen
Die meisten gplot-Konfigurationen sind bisher lediglich auf FileLog-Konfigurationen ausgelegt. Deshalb müssen sie für die Verwendung mit DbLog angepasst werden. Glücklicherweise beschränkt sich dies auf die reinen FileLog-Zeilen - es müssen die DbLog-Äquivalente hinzugefügt werden. Die FileLog-Einträge müssen zwar nicht gelöscht werden, wenn man aber FileLog und DbLog parallel betreibt, sollte man getrennte gplot-Dateien für beide Logging-Typen haben um Auswertungsprobleme erkennen zu können.
Für die fht.gplot Konfiguration sähe die Anpassung wie folgt aus (lediglich die vier DbLog-Zeilen wurden hinzugefügt):
# Created by FHEM/98_SVG.pm, 2014-12-25 21:53:30 set terminal png transparent size <SIZE> crop set output '<OUT>.png' set xdata time set timefmt "%Y-%m-%d_%H:%M:%S" set xlabel " " set title '<L1>' set ytics nomirror set y2tics set grid y2tics set ylabel "Actuator/Window (%)" set y2label "Temperature in C" set yrange 0:100 set y2range 5:25 #FileLog 4:.measured-temp\x3a:0: #FileLog 4:.actuator\x3a:0:int #FileLog 4:.desired-temp:: #FileLog 4:.window\x3a:: #DbLog <SPEC1>:.measured-temp:0: #DbLog <SPEC1>:.actuator:0:int #DbLog <SPEC1>:.desired-temp:: #DbLog <SPEC1>:.window:: plot "<IN>" using 1:2 axes x1y2 title 'Measured temperature' ls l0 lw 1 with lines,\ "<IN>" using 1:2 axes x1y1 title 'Actuator (%)' ls l1 lw 1 with lines,\ "<IN>" using 1:2 axes x1y2 title 'Desired Temperature' ls l2 lw 1 with steps,\ "<IN>" using 1:2 axes x1y1 title 'Window' ls l3 lw 1 with steps
Des Weiteren ist zu beachten:
On-Off-Plots
EG_Bad:window:::$val=~s/(on|off)(\d*).*/$1eq"on"?1:0/eg
unter Berücksichtigung von dim-Werten:
EG_WoZi_Licht:value:::$val=~s/(on|off)(\d*).*/$1eq"on"?1:($1eq"dim"?$2*0.01:0)/eg
Beispiel: Anlegen und Nutzung einer SQLite-Datenbank
Im folgenden wird eine lokale SQLite-Datenbank auf einen Ubuntu-System angelegt (nach Quelle: http://www.tatsch-it.de/fhem-dblog/)
-
Installation von SQLite:
sudo aptitude install sqlite3 libdbi-perl libdbd-sqlite3-perl
-
Anlegen der SQLite-Datenbank fhem.db (öffnet auch direkt eine SQL-Kommandozeile):
sudo sqlite3 /opt/fhem/fhem.db
In der geöffneten SQL-Kommandozeile eingeben:
CREATE TABLE 'history' (TIMESTAMP TIMESTAMP, DEVICE varchar(64), TYPE varchar(64), EVENT varchar(512), READING varchar(64), VALUE varchar(128), UNIT varchar(32)); CREATE TABLE 'current' (TIMESTAMP TIMESTAMP, DEVICE varchar(64), TYPE varchar(64), EVENT varchar(512), READING varchar(64), VALUE varchar(128), UNIT varchar(32)); CREATE INDEX Search_Idx ON `history` (DEVICE, READING, TIMESTAMP);
Die Kommandozeile verlässt man mit
.exit
. -
Anpassen des Besitzers und der Rechte der Datenbank-Datei:
sudo chown fhem /opt/fhem/fhem.db sudo chmod 666 /opt/fhem/fhem.db
-
Datenbank-Anbindung des FHEM konfigurieren:
sudo nano /opt/fhem/db.conf
Inhalt:
%dbconfig= ( connection => "SQLite:dbname=/opt/fhem/fhem.db", user => "", password => "" );
-
Logging des FHEM auf die Datenbank konfigurieren: (hier sind nur die Anpassungen aufgeführt)
sudo nano /opt/fhem/fhem.cfg
... attr global userattr DbLogExclude ... # erlaubt es einzelne Einträge nicht zu loggen ... define logdb DbLog ./db.conf .*:.* # logt alle(!) auflaufenden Events aller Konfigurationen ...
Da durch diese
define
-Definition alle auflaufenden Events gelogt werden, müssen keine weiteren Anpassungen in der Konfiguration gemacht werden. Die FileLog-Einträge können bedenkenlos bestehen bleiben - dann wird in Datenbank und FileLog gelogt und man verliert keine Daten, falls etwas nicht klappt. Wenn alles wie geplant läuft, können die FileLog-Definitionen gelöscht werden (ebenso die Log-Dateien). Ebenso können die zu loggenden Daten später eingegrenzt werden (s. #Finetuning des Loggings). -
FHEM neu starten:
sudo service fhem stop sudo service fhem start
-
Kontrollieren, ob Logs in die Datenbank geschrieben werden:
sudo sqlite3 /opt/fhem/fhem.db
In der geöffneten SQL-Kommandozeile eingeben:
select * from history order by TIMESTAMP; # dies gibt alle(!) Logs chronologisch aus (kann nach längerem Betrieb recht lange dauern)
Die Kommandozeile verlässt man mit
.exit
. - Anpassung der glot-Dateien: siehe #Anpassen der gplot-Konfigurationen
Beispiel: Anlegen und Nutzung einer Mysql-Datenbank
Anstatt nano kann jeder andere kompatible Editor verwendet werden. Weiterhin bitte beachten, dass die hier genannten Befehle teilweise root-Rechte voraussetzen. Entweder komplett als root arbeiten, oder mittels sudo.
Unter Ubuntu/debian:
apt-get update && apt-get install mysql-server mysql-client libdbd-mysql libdbd-mysql-perl
Bei der Installation sollte man aus Sicherheitsgründen ein Passwort für den mysql-root vergeben, wenn man nicht sogar ganz den Login verbietet.
Hinweis: im Folgenden ist "#" der normale Prompt und "mysql>" der prompt innerhalb mysql, dieser kann mit exit verlassen werden.
Zum Test mal mit mysql verbinden:
# mysql -p -u root Enter password: mysql> exit
Jetzt die Tabellenstruktur anlegen. Hierfür kann die Datei /opt/fhem/contrib/dblog/db_create_mysql.sql als Vorlage verwendet und das Passwort und der Benutzername geändert werden.
cd /opt/fhem/contrib/dblog/ nano db_create_mysql.sql
Dann wird die Datei eingelesen (root Passwort wird abgefragt):
# mysql -u root -p < db_create_mysql.sql
Jetzt kann man den Zugang testen:
# mysql -p -u <fhemuser> Enter password: <fhempassword> mysql> show databases;
Nun müsste eine Datenbank "fhem" angezeigt werden, die die Tabellen current und history enthält.
Nun in der Datei db.conf den mysql-Block auskommentieren und ebenfalls Benutzername, Passwort UND HOST anpassen. Leider ist hier nicht standardmäßig localhost eingestellt.
nano /opt/fhem/db.conf
Jetzt kann unter FHEM ein DbLog-Device angelegt werden (mit dem beispiel wird alles geloggt:
define logdb DbLog ./db.conf .*:.*
Als State muss ein "connected" angezeigt werden.
Ein rereadcfg in FHEM stellt sicher, dass die neue Konfiguration übernommen wird - ein Neustart ist nicht erforderlich.
Nun kann die Funktion noch einmal überprüft werden:
# mysql -u <fhemuser> -p
Enter password: <fhempassword>
mysql> use fhem;
Database changed
mysql> show tables;
+----------------+
| Tables_in_fhem |
+----------------+
| current |
| history |
+----------------+
2 rows in set (0,00 sec)
mysql> select * from history; # Achtung, kann sehr groß werden .... #
Beispiel: Abfragescript PHP/MySQL
Um eine schnelle Übersicht zu bekommen habe ich mir dieses Script geschrieben:
<?php $pdo = new PDO('mysql:host=localhost;dbname=fhem', 'fhemuser', 'fhempasswort');
echo '<h2>Tabelle Current</h1><br><table border="1">';
echo "<tr><th>Anzahl</th><th>Name</th><th>Readings</th></tr>";
$sql = "SELECT COUNT(*), DEVICE, GROUP_CONCAT(DISTINCT READING ORDER BY READING DESC SEPARATOR '</li><li>') FROM current GROUP BY DEVICE;"; foreach ($pdo->query($sql) as
$row) {
echo "<tr><td>" . $row[0] . "</td><td>" . $row[1] . "</td><td><ol><li>" . $row[2] . "</li></ol></td></tr>";
}
echo "</table>";
echo '<h2>Tabelle History</h1><br><table border="1">';
echo "<tr><th>Anzahl</th><th>Name</th></tr>";
$sql = "SELECT COUNT(*), DEVICE FROM history GROUP BY DEVICE;"; foreach ($pdo->query($sql) as
$row) {
echo "<tr><td>" . $row[0] . "</td><td>" . $row[1] . "</td></tr>";
}
echo "</table>";
?>
Bitte passt fhemuser und fhempasswort an. Das Ganze kommt dann nach /var/www/html/fhemdb.php und ist mit <IP>/fhemdb.php aufrufbar. Wenn ihr den 2. Block für die history Tabelle ausklammert oder entfernt läuft das Script viel schneller ab - klar die history Tabelle ist meist randvoll.
Integration von DBLog in eigene Module
Bereitstellung der UNITS
Mit der DbLog_splitFn kann der Modulautor selbst festlegen, wie die Events des Moduls in die Bestandteile Reading/Value/Unit zerlegt werden um ein korrektes Logging per DbLog zu gewährleisten.
Dazu muss der Modulautor in der Initialize-Funktion eine DbLog_splitFn
bereitstellen:
sub X_Initialize($)
{
my ($hash) = @_;
...
$hash->{DbLog_splitFn} = "X_DbLog_splitFn";
}
Die genaue Aufrufsyntax und Funktionweise einer DbLog_split-Funktion findet man hier.
Werte auslesen
Manchmal möchte man Daten aus den Logs abrufen ohne händisch in der Datenbank herumzuwühlen (s.u.). Dies ist insb. auch dann hilfreich, wenn man eigenen Funktionen, Notifys oder spezielle Plots entwirft, bei denen man auf Logdaten zugreifen möchte.
Grundsätzlich beschrieben ist dies in der commandref/DbLog und unterscheidet sich minimal (aber entscheidend) von der Struktur bei FileLogs.
Hier ein paar Beispiele, was man damit anstellen kann:
get meineDB - - 2016-10-01 2016-10-03 meinSensor
alle Einträge des meinSensor vom 01.10.-03.10.2016get meineDB - - 2016-10-01_08:00:00 2016-10-01_16:00:00 meinSensor
alle Einträge des meinSensor von 8-16 Uhr am 01.10.2016get meineDB - - 2016-10-01_08:00:00 2016-10-01_16:00:00 meinSensor:temperature
nur die temperature Werte{ ReadingsTimestamp("meinSensor","state","0") }
Timestamp des aktuellen state des meinSensor{ OldTimestamp("meinSensor") }
Timestamp des letzten state des FHT_3a32{ time_str2num(OldTimestamp("meinSensor")) }
Timestamp in Sekunden des letzten state des meinSensor- ...
Bearbeitung von Datenbank-Einträgen
Irgendwann wird der Fall eintreten, dass in der Datenbank Einträge drinstehen, die geändert oder gelöscht werden sollen (zB. fehlerhafte Sensor-Rückmeldungen, umbenannte Readings). In klassischen Log-Dateien würde man diese einfach bearbeiten und löschen/anpassen (wobei man aber tunlichst zuvor FHEM stoppt, um Datenfehler zu vermeiden). Eine Datenbank kann bearbeitet werden, ohne FHEM stoppen zu müssen.
Datenbanken kann man ohne weitere Hilfsmittel direkt von der Kommandozeile/Shell aus bearbeiten. Alternativ gibt es auch verschiedenste Tools (webbasiert oder als Applikation), die einen dabei unterstützen (Bsp. findet man u.a. hier). Für einfache Arbeiten reicht allerdings idR. Shell.
SQLite-Datenbanken
Öffnen der DB unter Linux:
(Es werden Schreibrechte benötigt,ohne kann man die DB zwar öffnen, aber nichts machen)
sudo sqlite3 fhem.db
Dadurch öffnet sich ein SQL-Konsole, auf der alle weiteren Befehle ausgeführt werden.
Schliessen der DB:
sqlite> .exit
Hilfe anzeigen:
sqlite> .help
Alle Tabellen anzeigen:
sqlite> .tables
Das Schema der DB anzeigen:
(vgl. oben DbLog#Datenbanken und DbLog#Beispiel: Anlegen und Nutzung einer SQLite-Datenbank)
sqlite> .schema
Alle Eintäge anzeigen:
Die Einträge liegen alle in der Tabelle "History".
Ganz wichtig ist immer das ";" am Ende Zeile (bei allen Kommandos, die nicht mit einem "." anfangen). Wenn es vergessen wurde zeigt die Konsole solange neue Zeilen bis ein ";" eingegeben wird. So kann ein Befehl auch bequem über mehrere Zeilen geschrieben werden.
sqlite> select * from HISTORY;
Dies kann sehr lange dauern und kann ggf. mit STRG-C
abgebrochen werden.
Alle Einträge eines Geräts anzeigen:
In where
-Statements werden Strings in einfache Anführungsstriche gesetzt, Zahlen nicht.
sqlite> select * from HISTORY where DEVICE='Pollenflug';
Alle Einträge eines Readings eines Geräts anzeigen:
sqlite> select * from HISTORY where DEVICE='Pollenflug' and READING='Graeser';
Alle Einträge eines bestimmten Wertes eines Readings eines Geräts anzeigen:
sqlite> select * from HISTORY where DEVICE='Pollenflug' and READING='Graeser' and VALUE>1;
LÖSCHEN aller Einträge eines bestimmten Wertes eines Readings eines Geräts anzeigen:
Achtung: Löschen kann nicht rückgängig gemacht werden!! Also IMMER erst die entsprechenden SELECT-Statements solange verfeinern bis wirklich nur die gewünschten Einträge angezeigt werden. Dann das select *
durch delete
ersetzen.
sqlite> delete from HISTORY where DEVICE='Pollenflug' and READING='Graeser' and VALUE>1;
Datenbank reparieren
Es kann immer wieder mal vorkommen, dass Datenbanken Fehler enthalten. Das muss im Alltag garnicht auffallen und auch nicht immer schlimm enden. Wenn man auf der SQL-Konsole aber bspw. eine Meldung Error: database disk image is malformed
erhält, sollte man ein Reparatur vornehmen.
SQLite-Datenbanken
Die folgenden Schritte beschreiben, wie man eine SQLite-DB reparieren kann (Quelle: [1]):
-
DB öffnen:
sudo sqlite3 fhem.db
-
Integritäts-Check durchführen:
sqlite> pragma integrity_check;
Kommt hier ein "ok" ist die DB gesund. Ansonsten erscheint etwas wie
*** in database main *** On tree page 118786 cell 1: Rowid 75 out of order (previous was 816660) On tree page 118786 cell 4: Rowid 815704 out of order (previous was 816727) Corruption detected in cell 0 on page 118786 Multiple uses for byte 132 of page 118786 ...
-
Datenbank-Dump erstellen (Export gesamten DB in die Datei "dump_all_20160516_1043.sql") und DB verlassen:
sqlite> .mode insert sqlite> .output dump_all_20160516_1043.sql sqlite> .dump sqlite> .exit
-
Neue Datenbank erstellen und den Dump einlesen, Integritäts-Check machen und verlassen:
sudo sqlite3 fhem-neu.db
sqlite> .read dump_all_20160516_1043.sql sqlite> pragma integrity_check; ok sqlite> .exit
-
Spätestens jetzt FHEM stoppen:
sudo service fhem stop
-
Alte DB sichern und neue aktivieren:
sudo mv fhem.db fhem.db.sv_20160516 sudo mv fhem-neu.db fhem.db
-
Kontrollieren, dass die neue DB die gleichen Rechte wie die alte DB hat (und ggf. korrigieren):
~/fhem$ ls -lha insgesamt 6,3G drwxr-xr-x 12 fhem root 4,0K Mai 16 11:07 . drwxr-xr-x 4 root root 4,0K Dez 25 17:50 .. ... -rw-r--r-- 1 root root 1,4G Mai 16 11:04 fhem.db -rw-r--r-- 1 fhem root 2,6G Mai 16 10:59 fhem.db.sv_20160516 ... ~/fhem$ sudo chown fhem:root fhem.db ~/fhem$ ls -lha insgesamt 6,3G drwxr-xr-x 12 fhem root 4,0K Mai 16 11:07 . drwxr-xr-x 4 root root 4,0K Dez 25 17:50 .. ... -rw-r--r-- 1 fhem root 1,4G Mai 16 11:04 fhem.db -rw-r--r-- 1 fhem root 2,6G Mai 16 10:59 fhem.db.sv_20160516 ...
-
FHEM wieder starten (und natürlich kontrollieren):
sudo service fhem start
Nützliche Codeschnipsel
Anbei ein paar nützliche Codeschnipsel rund um DbLog
Dateigrösse mitloggen
Da die Datenbank ins Unermessliche wachsen kann, empfiehlt es sich - je nach Speicherplatz - ab einer bestimmten Grösse tätig zu werden. Dazu muss diese Grösse allerdings ermittelt werden. Diese geschieht mittels des Userreadings, welches man vorteilshafterweise mit im DbLog-device anlegt:
attr myDbLog userReadings DbFileSize:reduceLogState.* { (split(' ',`du -m fhem.db`))[0] }
Mittels dieses Attributs wird die Grösse der .db-Datei immer nach dem Ausführen des ReduceLog in das Reading "DbFileSize" in ganzzahligen MByte abgelegt.
Basierend auf diesem Reading können dann weitere Aktionen, beispielsweise ein Plot, erstellt werden.