Modul 93_DbRep - Reporting und Management von Datenbankinhalten (DbLog)

Begonnen von DS_Starter, 19 Mai 2016, 22:52:13

Vorheriges Thema - Nächstes Thema

DS_Starter

#645
Hallo zusammen,

für SQLite Benutzer habe ich in der Version 7.11.0 eine Möglichkeit eingebaut eine korrupte DB automatisiert zu reparieren.
Die Reparatur ist nicht garantiert (siehe Hinweis), aber sicherlich in sehr vielen Fällen eine gute Möglichkeit die DB wieder operabel zu machen.
Man kann es mit einer nicht kaputten DB ebenfalls testen.

repairSQLite - repariert eine korrupte SQLite-Datenbank.
Eine Korruption liegt im Allgemeinen vor wenn die Fehlermitteilung "database disk image is malformed" im state des DbLog-Devices erscheint. Wird dieses Kommando gestartet, wird das angeschlossene DbLog-Device zunächst automatisch für 10 Stunden (36000 Sekunden) von der Datenbank getrennt (Trennungszeit). Nach Abschluss der Reparatur erfolgt wieder eine sofortige Neuverbindung zur reparierten Datenbank.
Dem Befehl kann eine abweichende Trennungszeit (in Sekunden) als Argument angegeben werden.
Die korrupte Datenbank wird als <database>.corrupt im gleichen Verzeichnis gespeichert.

    Beispiel:
    set <name> repairSQLite
    # Die Datenbank wird repariert, Trennungszeit beträgt 10 Stunden
    set <name> repairSQLite 600
    # Die Datenbank wird repariert, Trennungszeit beträgt 10 Minuten

    Hinweis:
    Es ist nicht garantiert, dass die Reparatur erfolgreich verläuft und keine Daten verloren gehen. Je nach Schwere der Korruption kann Datenverlust 
    auftreten oder die Reparatur scheitern, auch wenn kein Fehler im Ablauf signalisiert wird. Ein Backup der Datenbank sollte unbedingt vorhanden sein !


Grüße
Heiko
ESXi@NUC+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

DS_Starter

Hallo zusammen,

für die Backupfunktionen dumpMySQL bzw. dumpSQLite gibt es nun die Möglichkeit die erstellten Dumpfiles zu komprimieren.
Dazu gibt es das Attribut "dumpCompress".

Die entsprechnden Restorefunktionen können die komprimierten Files direkt verarbeiten. Sie werden im Drop-Down-Menü mit angezeigt.

File im ersten Beitrag.

viele Grüße
Heiko
ESXi@NUC+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

knxler

Hallo Heiko,

sorry das ich mich erst jetzt melde. Leider habe ich momentan nicht so viel Zeit um mich um mein FHEM zu kümmern.
Nun aber die Info zu deinem Mittelwert. Der ist Korrekt. Excel scheint offenbar beim Umgang mit Zeitdifferenzen ein Problem zu haben und macht dann bei Divisionen oder Multiplikationen in den letzten Stellen einen Fehler.
Kannst du mir jetzt noch einmal näher erläutern wie ich es schaffe meinen Text aus den Datenfeldern zu löschen?

Gruß und Danke!!

Martin

DS_Starter

Hallo Martin,

danke für die Rückmeldung.  :)

ZitatKannst du mir jetzt noch einmal näher erläutern wie ich es schaffe meinen Text aus den Datenfeldern zu löschen?
Für eine einfache Ersetzung hatte ich vorgesehen:

set name changeValue "alter String","neuer String"
Das klappt aber nur wenn der Zahlenwert in "alter String" immer gleich ist, sonst würde man den Wert falsch ersetzen.

Ich arbeite zur Zeit an einer Erweiterung der changeValue-Funktion mit der man dann universelle Ersetzungen vornehmen kann.
Ein bisschen Geduld müstest du noch haben ...

Grüße
Heiko
ESXi@NUC+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

DS_Starter

Hallo zusammen,

die V7.13.0 im ersten Beitrag bietet nun in der Funktion changeValue dem Nutzer umfangreiche Möglichkeiten der Einflussnahme zur Werteänderung.

* 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.

    Syntax:
    set <name> changeValue "<alter String>","<neuer String>"

    Die Strings werden in Doppelstrich eingeschlossen und durch Komma getrennt. Dabei kann "String" 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 {}, z.B. {$VALUE = (split(",",$VALUE))[1]}.
                                 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.                       

    Beispiele:
    set <name> changeValue "OL","12 OL"
    # der alte Feldwert "OL" wird in "12 OL" geändert.

    set <name> changeValue "%OL%","12 OL"
    # enthält das Feld VALUE den Teilstring "OL", wird es in "12 OL" geändert.

    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    : Selektion nur von Datensätzen die <device> enthalten
        reading    : Selektion nur 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


    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).


@Martin, damit kannst du deine Aufgabenstellung nun umsetzen. Falls Fragen sind ... gerne posten.

LG,
Heiko
ESXi@NUC+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

ToKa

Hallo Heiko,

ich fange gerade an, Dein tolles Modul zu nutzen. Dabei würde ich gerne in meiner Datenbank bei einigen Readings die Spalte Value um die Einheiten bereinigen, so wie Du es beschreibst.

Zitat von: DS_Starter am 17 Februar 2018, 16:59:56
    <neuer String> : * ein einfacher String mit/ohne Leerzeichen, z.B. "12 kWh"
                              * Perl Code eingeschlossen in {}, z.B. {$VALUE = (split(",",$VALUE))[1]}.
                                 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 "12 kWh","{$VALUE,$UNIT = split(" ",$VALUE)}"
    # der alte Feldwert "12 kWh" wird in VALUE=12 und UNIT=kWh gesplittet und in den Datenbankfeldern gespeichert

Mein Problem sind aber Einträge, die als Einheit das Prozentzeichen haben. Wie muss ich denn z.B. für Wert von "98 %" das %-Zeichen im Set-Befehl maskieren / escapen? Könnte man für alle Einträge, die mit "%" im Value vorhanden sind, mit Wildcards arbeiten oder muss ich für jeden einzelnen Wert den Befehl ausführen? (Habe leider bei Google zum Thema % ins SQL escapen nichts gefunden.)

Besten Dank und Grüße
Torsten
RaspberryPi3 mit RaZberry2 und Conbee II
Fibaro: FGWPE/F-101 Switch & FIBARO System FGWPE/F Wall Plug Gen5, FGSD002 Smoke Sensor
EUROtronic: SPIRIT Wall Radiator Thermostat Valve Control
Shelly2.5 Rollladenaktoren
Zipato Bulb 2, Osram und InnrLight

DS_Starter

Hallo Torsten,

ich glaube, für diesen Fall muss ich noch etwas einbauen.  Gibt doch immer wieder genau das woran man noch nicht gedacht hat  ;)
Melde mich wieder ...

LG,
Heiko
ESXi@NUC+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

DS_Starter

Hi Torsten,

also klappt mit der vorliegenden Implementierung schon einwandfrei.
Habe es gerade nochmal getestet.
Wenn du z.B. Datensätze hast mit:


"OL %"


kannst du ausführen:


"%","{$VALUE= (split(" ",$VALUE))[0]}"  oder
"%","{$VALUE,$UNIT= split(" ",$VALUE) }"


Der Datensatz wird dann in Value = OL und Unit = % aufgesplittet und die Werte gesetzt.
Ich würde aber die Selektion mit den Attributen device und/oder reading sowie den Zeitattributen einschränken, damit er nicht durch jeden Datensatz durchgeht.

LG,
Heiko
ESXi@NUC+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

DS_Starter

Guten Abend,

in der Version 7.14.0 ist es nun möglich Datensätze direkt aus der Quelldatenbank in eine weitere (Standby) Datenbank zu übertragen.

Für die Standby-Datenbank definiert man ein nicht loggendes DbLog-Device z.B. so:

define LogSQLITE1 DbLog ./db_sqlite1.conf aaaa:bbbbb

Dann kann man einfach mit

set <DbRep> syncStandby LogSQLITE1

Datensätze aus der mit DbRep verbundenen Datenbank in die DB "LogSQLITE1" übertragen.

Aus der Commandref:

* syncStandby <DbLog-Device Standby>

- Es werden die Datensätze aus der angeschlossenen Datenbank (Quelle) direkt in eine weitere Datenbank (Standby-Datenbank) übertragen. Dabei ist "<DbLog-Device Standby>" das DbLog-Device, welches mit der Standby-Datenbank verbunden ist.

Es werden alle Datensätze übertragen, die durch Timestamp-Attribute bzw. die Attribute "device", "reading" bestimmt sind.
Die Datensätze werden dabei in Zeitscheiben entsprechend der eingestellten Aggregation übertragen. Hat das Attribut "aggregation" den Wert "no" oder "month", werden die Datensätze automatisch in Tageszeitscheiben zur Standby-Datenbank übertragen. Quell- und Standby-Datenbank können unterschiedlichen Typs sein.

Die zur Steuerung der syncStandby Funktion relevanten Attribute sind:

    aggregation    : Einstellung der Zeitscheiben zur Übertragung (hour,day,week)
    device            : Übertragung nur von Datensätzen die <device> enthalten
    reading            : Übertragung nur von Datensätzen die <reading> enthalten
    time.*            : Attribute zur Zeitabgrenzung der zu übertragenden Datensätze.

LG,
Heiko
ESXi@NUC+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

Pyromane

Hallo Heiko,

um die aktuellen Devices in der current Tabelle zu haben, habe ich diese geleert und wollten dann diese neu erstellen:
2018.02.28 23:32:00 4: DbRep MyDbRep - -------- New selection ---------
2018.02.28 23:32:00 4: DbRep MyDbRep - Command: tableCurrentPurge
2018.02.28 23:32:00 4: DbRep MyDbRep -> Start BlockingCall del_DoParse
2018.02.28 23:32:00 4: DbRep MyDbRep - SQL execute: delete FROM current;
2018.02.28 23:32:00 4: DbRep MyDbRep -> BlockingCall del_DoParse finished
2018.02.28 23:32:00 4: DbRep MyDbRep -> Start BlockingCall del_ParseDone
2018.02.28 23:32:00 3: DbRep MyDbRep - Entries of fhemdaten.current deleted: 967
2018.02.28 23:32:00 4: DbRep MyDbRep -> BlockingCall del_ParseDone finished
2018.02.28 23:32:05 4: DbRep MyDbRep - -------- New selection ---------
2018.02.28 23:32:05 4: DbRep MyDbRep - Command: tableCurrentFillup
2018.02.28 23:32:05 4: DbRep MyDbRep - Timestamp begin human readable: not set
2018.02.28 23:32:05 4: DbRep MyDbRep - Timestamp end human readable: not set
2018.02.28 23:32:05 4: DbRep MyDbRep -> Start BlockingCall currentfillup_Push
2018.02.28 23:32:05 4: DbRep MyDbRep - SQL execute: INSERT INTO current (TIMESTAMP,DEVICE,READING) SELECT '',device,reading FROM history where true group by device,reading ORDER BY 2 ASC, 3 ASC;
2018.02.28 23:32:05 2: DbRep MyDbRep - Insert new dataset into database failed: DBD::Pg::st execute failed: ERROR:  invalid input syntax for type timestamp: ""
LINE 1: ...RT INTO current (TIMESTAMP,DEVICE,READING) SELECT '',device,...
                                                             ^ at ./FHEM/93_DbRep.pm line 3981.

2018.02.28 23:32:05 4: DbRep MyDbRep -> BlockingCall currentfillup_Push finished
2018.02.28 23:32:05 4: DbRep MyDbRep -> Start BlockingCall currentfillup_Done
2018.02.28 23:32:05 4: DbRep MyDbRep -> BlockingCall currentfillup_Done finished


Grüße Pyro

DS_Starter

Hallo Pyro,

da ist mir so wie es aussieht ein Syntaxfehler für Postgre unterlaufen.
Schaue ich mir morgen an und fixe das ...

EDIT: der Fehler tritt bei Postgre nur auf wenn kein timestamp-Eingrenzung gemacht ist. Wenn du es eilig hast, setze die z.B. timeDiffToNow = d:180.

LG,
Heiko
ESXi@NUC+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

Pyromane

Guten Morgen Heiko,

danke für die schnelle Antwort und den Workaround.
Mach dir keinen Stress mit der Behebung, ich kann meine Devices auch händisch in die SVG eintragen :)

Grüße
Pyro

RoKoInfo

Hallo DS_Starter, hallo in die Runde,

Error bei "set DbRep delSeqDoublets delete"?

Ich bin weder ein Rechner- noch ein Fhem-Neuling, aber neu bei DbRep/DbLog. Obige Funktion finde ich toll, und diese hat auch einmal prächtig funktioniert: Pro Stunde laufen hier etwa 350 Datensätze auf, und der erste Versuch hat das Volumen auf etwa 17% (von damals etwa 20T Sätzen) reduziert.

Nun habe ich drei weitere Versuche hinter mir (mit dem gleichen, dublettenbereinigten Datensatz, der sich halt wieder verlängert hat), die alle mit einem Fehler


DBD::SQLite::st execute failed: database disk image is malformed at /usr/share/fhem/FHEM/93_DbRep.pm line 4549. 2018-03-01 21:50:08


abbrechen (nach etwa 1h bei 50T Datensätzen insgesamt). Das ganze läuft auf einem RPi mit Arch Linux seit längerem (ohne DbLog/DbRep natürlich) sehr stabil.


version =

Latest Revision: 16296

File              Rev   Last Change

fhem.pl           16291 2018-02-28 21:09:20Z rudolfkoenig
...
93_DbLog.pm       16271 2018-02-25 19:14:46Z DS_Starter (3.8.6)
93_DbRep.pm       16292 2018-02-28 21:23:28Z DS_Starter (7.14.0)
...



SQLite version 3.22.0 2018-01-22 18:45:57
Enter ".help" for usage hints.
sqlite> .version
SQLite 3.22.0 2018-01-22 18:45:57 ...
gcc-7.2.1 20180116
sqlite>



Die beiden ersten erfolglosen Versuche sind mit geringfügig älteren Versionen gelaufen, aber im wesentlichen das gleiche Fehlerbild.

Was könnte das sein? Ich kann Daten nachliefern, aber aus der Fehlerbeschreibung werde ich nicht so recht schlau. Vielen Dank im voraus.

Viele Grüße
RoKoInfo

DS_Starter

Hallo RoKoInfo,

das kann eine DB-Korruption sein.

Führe aus im DbRep:

set ... repairSQLite

Wenn die DB wieder repariert ist, setze dir :


executeAfterProc set <DbLog-Device> reopen
executeBeforeProc set <DbLog-Device> reopen 3600


DbLog-Device ist das mit DbRep verbundene Device.
Durch diese Massnahme wird vermieden, dass während des Löschens von Datensätzen DbLog versucht seinerseits Daten zu schreiben.

Grüße
Heiko
ESXi@NUC+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

DS_Starter

Hallo Pyro,

in der V7.14.1 habe ich die Syntax für Postgre gefixt.
Bitte teste es mal auch bei dir.

Grüße
Heiko
ESXi@NUC+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter