Statistics: Ich bräuchte Duration-Readings für die letzten 24 und 36 Stunden.--

Begonnen von Reinerlein, 27 Juni 2018, 08:00:59

Vorheriges Thema - Nächstes Thema

Reinerlein

Hallo,

ich benötige an einigen Stellen die Information darüber, wie lange meine Devices welche Zustände in den letzten 24 bzw. 36 Stunden hatten.

Leider gibt es nur eine Definitionsmöglichkeit für "specialDeltaPeriods".
Ich bräuchte sowas wie "specialDurationPeriods".

Ich habe mal kurz in das Modul reingeschaut, und so direkt leider keine einfache Möglichkeit des Einbaus gefunden :-[
Wäre es für den Maintainer machbar, oder ist das viel zuviel Aufwand?

Danke schon mal...

Grüße
Reinerlein

Ellert


Thyraz

Ich schütte hier mal eine Ladung SQL Zeilen ab,
in der Hoffung, dass du DBLog verwendest und die gewünschen Werte auch bisher schon geloggt hast.

Dann könntest du die gewünschten Werte sogar noch rückwirkend für bereits vorhandene Daten ermitteln.
Das Ganze ist jetzt einfach mal kurz in phpMyAdmin zusammengehackt.

Müsste man für einen Automatismus evtl. über eine DBRep Instanz machen, die das dann regelmässig ausführt.

Vom logischen Ablauf von 1) bis 4) durchkämpfen und bei Unklarheiten einfach fragen.  ;D


-- 4) Gruppieren der Tabellenzeilen nach Zustand (value) und summieren der zugehörigen Duration-Werte
SELECT
  val,
  SUM(duration) as total_duration
FROM (
  -- 3) Tabelle um eine weitere Spalte "Duration" erweitern, die die Zeitspanne des Zustands bis zum nächsten Zustandswechsel beinhaltet
  --     Hier wird rückwärts durch die Zeit gelaufenen vom Ende der Zeitspanne bis zum Anfang
  --     Dadurch beinhaltet die Variable OLDTIME immer den Zeitpunkt des nächsten Ereignisses, wodurch man in dem Fake-IF Konstrukt die Dauer berechnen kann
  SELECT
    start_time,
    val,
    IF (IF (@DURATION := TIMESTAMPDIFF(SECOND, start_time, @OLDTIME), 1, 1) AND IF (@OLDTIME := start_time, 1, 1), @DURATION , 0) as duration
  FROM (
    (
      -- 1) Alle Werte aus dem Zeitraum als "Zeitstempel -> Wert" Tabelle holen
      SELECT
        TIMESTAMP as start_time,
        VALUE as val
      FROM history
      WHERE READING="running" AND DEVICE="PowerSwitch02" AND TIMESTAMP >= DATE_SUB(NOW(),INTERVAL 96 HOUR) AND TIMESTAMP <= NOW()
    )
    UNION
    (
      -- 2) Letzten Wert vor dem aktuellen Zeitraum holen und mit Startzeitpunkt des Zeitraums an die Tabelle anhängen
      SELECT
        DATE_SUB(NOW(),INTERVAL 96 HOUR) as start_time,
        VALUE as val
      FROM history
      WHERE READING="running" AND DEVICE="PowerSwitch02" AND TIMESTAMP <= DATE_SUB(NOW(),INTERVAL 96 HOUR)
      ORDER BY TIMESTAMP DESC
      LIMIT 1   
    )
  ) s1
  -- Hier wird der Startwert der Variable festgelegt. Dadurch ergibt sich der Durationwert vom neusten Wert in der DB
  -- Bei der Auswertung von Altdaten müsste man hier NOW durch den Endzeitpunkt des betrachteten Zeitraums ersetzen
  JOIN (SELECT @OLDTIME := NOW()) AS var
  ORDER BY start_time DESC
) s2
GROUP by val



edit: Hier noch wie das Ergebnis überhaupt aussieht:

val | total_duration
0      288152
1      57448


Du erhälst also für jeden Zustand eine Zeile mit dem aufsummierten Sekundenwert.
Meine Waschmaschine lief in den letzten 4 Tagen also insgesamt etwa 16h und war 80h ausgeschaltet.
Fhem und MariaDB auf NUC6i5SYH in Proxmox Container (Ubuntu)
Zwave, Conbee II, Hue, Harmony, Solo4k, LaMetric, Echo, Sonos, Roborock S5, Nuki, Prusa Mini, Doorbird, ...

Reinerlein

Hi,

Danke für die Antworten...
DBLog verwende ich nicht, und bei readingsHistory müsste ich das ja auch noch zusammenbauen, damit ich das so habe, wie die anderen Statistiken.
Da erscheint es mir doch einfacher, wenn ich das Modul statistics erweitern würde...

Trotzdem Danke für die Ideen.

Grüße
Reinerlein