dblog userCommand non blocking

Begonnen von Rothammel, 08 Oktober 2018, 08:59:20

Vorheriges Thema - Nächstes Thema

Rothammel

Hallo zusammen,

ich habe ein aufwendiges userCommand, was mir aus dem dblog die Summe der Laufzeit einer Pumpe ermittelt.
SELECT
    IFNULL(SUM(diff) / 60 / 60, 0)
FROM
    (SELECT
        a.`TIMESTAMP`,
            TIMESTAMPDIFF(SECOND, (SELECT
                    `TIMESTAMP`
                FROM
                    fhem.history AS b
                WHERE
                    b.`TIMESTAMP` < a.`TIMESTAMP`
                        AND DEVICE = 'Status_Pufferspeicher_Ladepumpe'
                        AND VALUE = 1
                ORDER BY b.`TIMESTAMP` DESC
                LIMIT 1), `TIMESTAMP`) AS `diff`
    FROM
        fhem.history AS a
    WHERE
        DEVICE = 'Status_Pufferspeicher_Ladepumpe'
            AND VALUE = 0
    ORDER BY a.TIMESTAMP DESC) AS Summe


die query läuft zum Ende des Jahres bald 30 Sekunden, und ich habe das Gefühl ein dblog userCommand ist blocking. wenn der durchgelaufen ist, dann muss fhem erstmal alle mqtt Nachrichten abholen und ist wieder eine Minute 100% ausgelastet.

gibt es eine bessere Lösung mit der Datenbank zu arbeiten?

DS_Starter

Ja, führe dein userCommand in einem DbRep-Device aus.
Dort erfolgt es non-blocking. Der Set-Befehl ist sqlCmd.

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

Rothammel

danke dir für die Info, ich habe deinen Tipp probiert.

allerdings stelle ich mich dumm an, wie bekomme ich nach einem sqlCmd das zurück gegebene Reading SqlResultRow_1 in mein dummy device?

DS_Starter

Dafür gibt es verschiedenene Methoden die ich recht ausführlich im Wiki beschrieben habe.

https://wiki.fhem.de/wiki/DbRep_-_Reporting_und_Management_von_DbLog-Datenbankinhalten#Readingwerte_von_DbRep_nach_Dummy_.C3.BCbertragen

Schau es dir mal an und wenn Fragen sind einfach fragen  :)
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

Rothammel

Zitat von: DS_Starter am 22 November 2018, 11:28:43
Dafür gibt es verschiedenene Methoden die ich recht ausführlich im Wiki beschrieben habe.

https://wiki.fhem.de/wiki/DbRep_-_Reporting_und_Management_von_DbLog-Datenbankinhalten#Readingwerte_von_DbRep_nach_Dummy_.C3.BCbertragen

Schau es dir mal an und wenn Fragen sind einfach fragen  :)

das habe ich schon durch gelesen, kann ich nicht einfach ein notify erstellen, was den sqlCmd vergleicht und dann mein dummy state mit dem SqlResultRow_1 setzt?

DS_Starter

Ja klar, ist ja auch als eine Variante im Abschnitt "Werte mittels Event übertragen" beschrieben. Kannst du so vorgehen.
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

Rothammel

das kapiere ich nicht, die Events sehen so aus:

2018-11-22 13:08:29 DbRep meinDbRep running
2018-11-22 13:09:09 DbRep meinDbRep sqlCmd: SELECT IFNULL(SUM(diff) / 60 / 60, 0) FROM (SELECT a.`TIMESTAMP`, TIMESTAMPDIFF(SECOND, (SELECT `TIMESTAMP` FROM fhem.history AS b WHERE b.`TIMESTAMP` < a.`TIMESTAMP` AND DEVICE = 'Status_Pufferspeicher_Ladepumpe' AND VALUE = 1 ORDER BY b.`TIMESTAMP` DESC LIMIT 1), `TIMESTAMP`) AS `diff` FROM fhem.history AS a WHERE DEVICE = 'Status_Pufferspeicher_Ladepumpe' AND VALUE = 0 ORDER BY a.TIMESTAMP DESC) AS Summe;
2018-11-22 13:09:09 DbRep meinDbRep sqlResultNumRows: 1
2018-11-22 13:09:09 DbRep meinDbRep SqlResultRow_1: 336.29777778
2018-11-22 13:09:09 DbRep meinDbRep done

wenn jetzt der sqlCmd kommt, ist doch ein Ergebnis noch nicht im SqlResultRow_1  :o

DS_Starter

Sorry, du hast natürlich recht. Du musst auf den Event "SqlResultRow_1" lauschen. Auf "sqlCmd" wäre nicht hilfreich.
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

Rothammel

das ist doch unglaublich kompliziert, ist es nicht einfacher die sqlCmd Funktion um einen Parameter mit Device und Reading zu erweitern?

DS_Starter

Zitatdas ist doch unglaublich kompliziert, ist es nicht einfacher die sqlCmd Funktion um einen Parameter mit Device und Reading zu erweitern?
Die Frage verstehe ich nicht wirklich oder wir reden aneinander vorbei.
Die sqlCmd ist ja dazu da einen beliebigen SQL-Request an die Datenbank zu senden. Wo sollte denn da ein Parameter mit Device und Reading hinzugefügt werden ?
Vielleicht kannst du es etwas näher erläutern.
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

Rothammel

na gerne, wenn der SQL Request einen Wert zurück gibt, dann könnte er direkt in das Reading

DS_Starter

Ja, könnte ich machen mit einem Attribut.
Allerdings könnte im Ergebnis von sqlCmd  auch mehr als ein Reading entstehen, also SqlResultRow_2, SqlResultRow_3, SqlResultRow_x ...
Welches soll ich da nehmen ? Alle ?
Und welche Readingnamen sollen dann in dem Dummy verwendet werden wenn nur eins als Zielreading angegeben werden kann ? Oder soll ich eine Liste im Attribut angeben lassen ?

Hmm ... viele Fragen ....

Dann finde ich die Lösung mit dem Notify einfacher. Hier nochmal zusammengefasst.
Dummy erstellen:


define Dum.Rep dummy
attr Dum.Rep room DbLog


Notify erstellen:


define N.Dum.Rep notify <DbRep-Device>:SqlResultRow_1.* { fhem "setreading Dum.Rep <DeinReading>"." $EVTPART1"}
attr N.Dum.Rep room DbLog


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

Rothammel

Dein Beispiel verstehe ich, aber was wenn ich 10 verschiedene sqlCmd Querys habe? Wie soll das Notify das unterscheiden. Es reagiert ja nur auf das Event von SqlResultRow_1

DS_Starter

#13
ZitatWie soll das Notify das unterscheiden. Es reagiert ja nur auf das Event von SqlResultRow_1
Auch wieder war.

Ein Parameter mitzugeben ist insofern schwierig weil man nicht weiß wann das Statement endet (";" ist nicht verpflichtend).

Was ich mir vorstellen könnte ist ein solches Konstrukt als Eingabemöglichkeit vorzusehen:

set ... sqlCmd <SQL-Statement> DUMMY=<DummyName>, READINGS = (SqlResultRow_1 => <Reading im Dummy>, SqlResultRow_2 => <Reading im DUmmy>, ... ) 

Das wäre eine Möglichkeit die (programmtechnisch) funktionieren könnte und auch anwendbar wäre.
Was denkst du ?

EDIT: Wie Frank schon schrieb ... 10 Reps einfachste und sofort umsetzbare Lösung
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

Frank_Huber

10 DbRep devices z. B.

Gesendet von meinem Doogee S60 mit Tapatalk