Smart Home: Verbrauchsstatistiken fĂŒr Wasser und Strom in Home Assistant erstellen

Smart Home: Verbrauchsstatistiken fĂŒr Wasser und Strom in Home Assistant erstellen
Jedes Mal, wenn ich die Rechnung fĂŒr Strom und Wasser bekomme, frage ich mich, verbraucht meine Familie wirklich soooo viel? Ja, der Fußboden im Bad ist beheizt und es gibt einen Boiler, aber die laufen doch nicht stĂ€ndig. Auch beim Wasser sparen wir anscheinend (obwohl wir gerne auch mal im Bad planschen). Vor einigen Jahren habe ich bereits WasserzĂ€hler und StromzĂ€hler mit dem Smart Home verbunden, aber damit bin ich nicht weitergekommen. Erst jetzt habe ich die Datenanalyse angegangen, worum es in diesem Artikel geht.

KĂŒrzlich bin ich auf Home Assistant als mein Smart Home-System umgestiegen. Ein Grund war gerade die Möglichkeit, eine große Menge an Daten zu sammeln und auf einfache Weise verschiedene Arten von Grafiken zu erstellen.

Die Informationen in diesem Artikel sind nicht neu; all diese Dinge wurden bereits im Internet unter verschiedenen VorwÀnden behandelt. Dennoch beschreibt jeder Artikel in der Regel nur einen Ansatz oder Aspekt. Daher musste ich selbst vergleichen und den passendsten Ansatz auswÀhlen. Der Artikel bietet zwar keine umfassenden Informationen zur Datensammlung, ist aber eine Art Zusammenfassung dessen, wie ich es gemacht habe. Konstruktive Kritik und VerbesserungsvorschlÀge sind daher willkommen.

Problemstellung

Das Ziel der heutigen Übung ist es, schöne Grafiken fĂŒr Wasser- und Stromverbrauch zu erstellen:

  • StĂŒndlich ĂŒber 2 Tage
  • TĂ€glich ĂŒber 2 Wochen
  • (optional) wöchentlich und monatlich

Hierbei stoßen wir auf einige Herausforderungen:

  • Die Standardgrafikomponenten sind in der Regel ziemlich begrenzt. Im besten Fall kann man ein Liniendiagramm aus den Punkten erstellen.

    Wenn man gut sucht, findet man externe Komponenten, die die FĂ€higkeiten der Standardgrafiken erweitern. FĂŒr Home Assistant ist die Komponente mini-graph-card, im Grunde genommen jedoch auch etwas eingeschrĂ€nkt:

    • Es ist schwierig, die Parameter fĂŒr das Balkendiagramm ĂŒber große ZeitrĂ€ume festzulegen (die Breite des Balkens wird in Stundenbruchteilen angegeben, was bedeutet, dass ZeitrĂ€ume lĂ€nger als eine Stunde als Dezimalzahlen dargestellt werden mĂŒssen).
    • Verschiedene EntitĂ€ten können nicht in ein einziges Diagramm eingefĂŒgt werden (zum Beispiel Temperatur und Luftfeuchtigkeit oder das Kombinieren eines Balkendiagramms mit einer Linie).
  • Es ist nicht nur so, dass Home Assistant standardmĂ€ĂŸig die einfachste Datenbank, SQLite, verwendet (und ich bin, blöd wie ich bin, nicht mit der Installation von MySQL oder Postgres klargekommen), sondern auch, dass die Daten nicht optimal gespeichert werden. Bei jeder Änderung auch der kleinsten digitalen Parameter wird ein riesiges JSON von etwa einem Kilobyte in die Datenbank geschrieben.
    {"entity_id": "sensor.water_cold_hourly", "old_state": {"entity_id": "sensor.water_cold_hourly", "state": "3", "attributes": {"source": "sensor.water_meter_cold", "status": "collecting", "last_period": "29", "last_reset": "2020-02-23T21:00:00.022246+02:00", "meter_period": "hourly", "unit_of_measurement": "l", "friendly_name": "water_cold_hourly", "icon": "mdi:counter"}, "last_changed": "2020-02-23T19:05:06.897604+00:00", "last_updated": "2020-02-23T19:05:06.897604+00:00", "context": {"id": "aafc8ca305ba4e49ad4c97f0eddd8893", "parent_id": null, "user_id": null}}, "new_state": {"entity_id": "sensor.water_cold_hourly", "state": "4", "attributes": {"source": "sensor.water_meter_cold", "status": "collecting", "last_period": "29", "last_reset": "2020-02-23T21:00:00.022246+02:00", "meter_period": "hourly", "unit_of_measurement": "l", "friendly_name": "water_cold_hourly", "icon": "mdi:counter"}, "last_changed": "2020-02-23T19:11:11.251545+00:00", "last_updated": "2020-02-23T19:11:11.251545+00:00", "context": {"id": "0de64b8af6f14bb9a419dcf3b200ef56", "parent_id": null, "user_id": null}}}

    Ich habe ziemlich viele Sensoren (Temperatursensoren in jedem Raum sowie Wasser- und StromzĂ€hler), und einige davon erzeugen eine betrĂ€chtliche Menge an Daten. Der StromzĂ€hler SDM220 zum Beispiel generiert alle 10–15 Sekunden etwa zehn Werte, und ich möchte davon etwa acht installieren. Zudem gibt es eine ganze Reihe von Parametern, die auf Basis anderer Sensoren berechnet werden. Diese Werte können die Datenbank leicht um tĂ€glich 100–200 MB vergrĂ¶ĂŸern. Nach einer Woche wird das System kaum noch funktionieren, und nach einem Monat wird der Flash-Speicher (bei einer typischen Installation von Home Assistant auf einem Raspberry Pi) den Geist aufgeben. Von einer Datenspeicherung ĂŒber ein ganzes Jahr will ich gar nicht erst reden.

  • Wenn Sie GlĂŒck haben, kann Ihr ZĂ€hler den Verbrauch selbst berechnen. Sie können jederzeit den ZĂ€hler abfragen, um den aktuellen Stand des Verbrauchs zu erfahren. In der Regel bieten alle StromzĂ€hler mit einer digitalen Schnittstelle (RS232/RS485/Modbus/Zigbee) diese Möglichkeit.

    Schlimmer wĂ€re es, wenn das GerĂ€t einfach nur einen bestimmten Momentanparameter (wie Momentanleistung oder Strom) messen oder regelmĂ€ĂŸig Impulse alle X Wattstunden oder Liter erzeugen kann. Dann muss man ĂŒberlegen, wie und womit dies integriert werden kann und wo die Werte gespeichert werden. Es besteht das Risiko, einen weiteren Bericht aus irgendeinem Grund zu verpassen, und die Genauigkeit des Systems insgesamt wirft Fragen auf. Man könnte das natĂŒrlich alles einem Smart-Home-System wie Home Assistant anvertrauen, aber die Anzahl der DatensĂ€tze in der Datenbank bleibt eine Herausforderung, und es wird nicht möglich sein, die Sensoren öfter als einmal pro Sekunde abzufragen (Architekturgrenze von Home Assistant).

Ansatz 1

ZunĂ€chst schauen wir, was Home Assistant standardmĂ€ĂŸig bietet. Die Messung des Verbrauchs ĂŒber einen Zeitraum ist eine sehr gefragte FunktionalitĂ€t. NatĂŒrlich wurde dies schon vor lĂ€ngerer Zeit in Form eines spezialisierten Components — utility_meter — realisiert.

Die Funktion des Components besteht darin, eine Variable namens current_accumulated_value intern zu fĂŒhren und diese nach Ablauf eines festgelegten Zeitraums (Stunde/Woche/Monat) zurĂŒckzusetzen. Der Component ĂŒberwacht selbst die eingehende Variable (den Wert eines Sensors) und abonniert Änderungen an diesem Wert – Sie erhalten einfach das fertige Ergebnis. Diese Funktion wird in nur wenigen Zeilen in der Konfigurationsdatei beschrieben.

utility_meter:
  water_cold_hour_um:
    source: sensor.water_meter_cold
    cycle: hourly
  water_cold_day_um:
    source: sensor.water_meter_cold
    cycle: daily

Hierbei ist sensor.water_meter_cold der aktuelle Wert des ZĂ€hlers in Litern, den ich erhalte direkt von der Hardware ĂŒber MQTT. Die Konstruktion erstellt zwei neue Sensoren, water_cold_hour_um und water_cold_day_um, die stĂŒndliche und tĂ€gliche Werte accumulieren und diese am Ende des Zeitraums zurĂŒcksetzen. Hier ist das Diagramm des stĂŒndlichen Akkumulators fĂŒr einen halben Tag.

Smart Home: Verbrauchsstatistiken fĂŒr Wasser und Strom in Home Assistant erstellen

Der Code fĂŒr die stĂŒndlichen und tĂ€glichen Diagramme fĂŒr das Lovelace-UI sieht so aus:

      - type: history-graph
        title: 'StĂŒndlicher Wasserverbrauch mit Variablen'
        hours_to_show: 48
        entities:
          - sensor.water_hour

      - type: history-graph
        title: 'TĂ€glicher Wasserverbrauch mit Variablen'
        hours_to_show: 360
        entities:
          - sensor.water_day

Eigentlich liegt das Problem dieses Ansatzes in diesem Algorithmus. Wie bereits erwĂ€hnt, wird fĂŒr jeden eingehenden Wert (aktuelle ZĂ€hlerstand fĂŒr jeden nĂ€chsten Liter) 1 kB Datensatz in der Datenbank generiert. Jeder Utility Meter erzeugt ebenso einen neuen Wert, der ebenfalls in der Datenbank gespeichert wird. Wenn ich stĂŒndliche, tĂ€gliche, wöchentliche oder monatliche Messwerte erfassen möchte, und das fĂŒr mehrere Wasserverteiler und noch eine Reihe von StromzĂ€hlern hinzufĂŒge – wird es eine enorme Menge an Daten geben. Es sind zwar nicht viele Daten an sich, aber da der Home Assistant eine Menge unnötiger Informationen in die Datenbank schreibt, wird die DatenbankgrĂ¶ĂŸe exponentiell wachsen. Ich habe sogar Bedenken, die DatenbankgrĂ¶ĂŸe fĂŒr wöchentliche und monatliche Diagramme abzuschĂ€tzen.

DarĂŒber hinaus löst der Utility Meter das vorgestellte Problem nicht allein. Das Diagramm der Werte, die der Utility Meter liefert, ist eine monoton steigende Funktion, die jede Stunde auf 0 zurĂŒckgesetzt wird. Wir benötigen jedoch ein verstĂ€ndliches Diagramm fĂŒr den Benutzer, das zeigt, wie viele Liter ĂŒber einen Zeitraum konsumiert wurden. Der Standardkomponent history-graph kann das nicht, aber der externe Komponenten mini-graph-card kann uns dabei helfen.

Das ist der Code fĂŒr die Karte in der lovelace-UI:

      - aggregate_func: max
        entities:
          - color: var(--primary-color)
            entity: sensor.water_cold_hour_um
        group_by: hour
        hours_to_show: 48
        name: "StĂŒndlicher Wasserverbrauch aggregiert nach VerbrauchszĂ€hler"
        points_per_hour: 1
        show:
          graph: bar
        type: 'custom:mini-graph-card'

Neben den Standardoptionen wie Sensornamen, Grafiktyp und Farbe (das Standardorange hat mir nicht gefallen) sind hier drei Einstellungen wichtig:

  • group_by:hour — Der Grafik wird mit einer Ausrichtung der Balken zum Beginn der Stunde erstellt.
  • points_per_hour: 1 — Ein Balken pro Stunde.
  • Und das Wichtigste, aggregate_func: max — Der maximalen Wert innerhalb jeder Stunde wird genommen. Dieses Parameter verwandelt das gezackte Diagramm in Balken.

Smart Home: Verbrauchsstatistiken fĂŒr Wasser und Strom in Home Assistant erstellen

Ignorieren Sie die Reihe an Balken links — das ist das Standardverhalten des Komponenten, wenn keine Daten vorhanden sind. Und Daten gab es nicht — ich habe erst vor ein paar Stunden mit der Datenerhebung ĂŒber den VerbrauchszĂ€hler nur fĂŒr diesen Artikel begonnen (meinen aktuellen Ansatz werde ich gleich darunter beschreiben).

In diesem Bild wollte ich zeigen, dass die Datenanzeige manchmal tatsĂ€chlich funktioniert und die Balken die richtigen Werte widerspiegeln. Nur leider nicht alle. Der hervorgehobene Balken fĂŒr den Zeitraum von 11 bis 12 Uhr zeigt aus irgendeinem Grund 19 Liter an, wĂ€hrend wir im gezackten Diagramm etwas weiter oben fĂŒr denselben Zeitraum von demselben Sensor einen Verbrauch von 62 Litern sehen. Entweder ein Fehler oder es liegt an uns. Aber ich habe noch nicht verstanden, warum die Daten rechts fehlen — der Verbrauch war dort in Ordnung, was auch im gezackten Diagramm zu sehen ist.

Insgesamt ist es mir nicht gelungen, die GlaubwĂŒrdigkeit dieses Ansatzes zu erreichen – das Diagramm zeigt fast immer irgendeinen Unsinn.

Ähnlicher Code fĂŒr den Tagessensor.

      - aggregate_func: max
        entities:
          - color: var(--primary-color)
            entity: sensor.water_cold_day_um
        group_by: interval
        hours_to_show: 360
        name: "TĂ€glicher Wasserverbrauch aggregiert nach ZĂ€hler"
        points_per_hour: 0.0416666666
        show:
          graph: bar
        type: 'custom:mini-graph-card'

Bitte beachten Sie, dass der Parameter group_by auf den Wert interval eingestellt ist und der Parameter points_per_hour alles steuert. Das fĂŒhrt zu einem weiteren Problem dieses Components – points_per_hour funktioniert gut fĂŒr Grafiken, die einen Zeitraum von einer Stunde oder weniger abdecken, ist aber schlecht fĂŒr grĂ¶ĂŸere ZeitrĂ€ume. Um eine SĂ€ule fĂŒr einen Tag darzustellen, musste ich den Wert 1/24=0.04166666 eingeben. Von wöchentlichen und monatlichen Grafiken ganz zu schweigen.

Ansatz 2

Als ich mich gerade mit Home Assistant beschĂ€ftigte, stieß ich auf dieses Video:

Video abspielen

Ein Bekannter erfasst den Verbrauch von mehreren Arten von Xiaomi-Steckdosen. Seine Aufgabe ist etwas einfacher – er möchte einfach die Verbrauchswerte von heute, gestern und fĂŒr den Monat anzeigen. Keine Grafiken sind notwendig.

Lassen wir die Überlegungen zu einer manuellen Integration der aktuellen Leistungswerte beiseite – ĂŒber die "Genauigkeit" dieses Ansatzes habe ich bereits oben geschrieben. Es ist unklar, warum er die akkumulierten Verbrauchswerte, die bereits von der gleichen Steckdose erfasst werden, nicht verwendet hat. Meiner Meinung nach wird die Integration innerhalb des GerĂ€ts besser funktionieren.

Wir nehmen aus dem Video die Idee einer manuellen VerbrauchszĂ€hlung ĂŒber einen bestimmten Zeitraum. Der Fokus liegt auf den Werten von heute und gestern, aber wir gehen einen Schritt weiter und versuchen, ein Diagramm zu erstellen. Der Kern der vorgeschlagenen Methode in meinem Fall ist wie folgt.

Wir erstellen eine Variable namens wert_zu_stundenbeginn, in der wir die aktuellen Messwerte des ZĂ€hlers speichern.
Bei einem Timer am Ende der Stunde (oder zu Beginn der nĂ€chsten) berechnen wir die Differenz zwischen dem aktuellen Wert und dem zu Beginn der Stunde gespeicherten Wert. Diese Differenz stellt den Verbrauch der aktuellen Stunde dar — wir speichern den Wert in einem Sensor und werden in Zukunft auf dieser Grundlage ein Diagramm erstellen.
Außerdem muss die Variable wert_zu_stundenbeginn „zurĂŒckgesetzt“ werden, indem der aktuelle ZĂ€hlerstand dort gespeichert wird.

All dies kann ĂŒber die Mittel des Home Assistant realisiert werden.

Der Code wird etwas umfangreicher sein als beim vorherigen Ansatz. ZunĂ€chst definieren wir diese „Variablen“. Aus der Box heraus haben wir kein Konzept fĂŒr „Variablen“, aber wir können die Dienste eines MQTT-Brokers in Anspruch nehmen. Wir werden dort Werte mit dem Flag retain=true senden – das speichert den Wert im Broker, und wir können ihn jederzeit abrufen, selbst nach einem Neustart von Home Assistant. Ich habe sofort stĂŒndliche und tĂ€gliche ZĂ€hler erstellt.

- platform: mqtt
  state_topic: "test/water/hour"
  name: water_hour
  unit_of_measurement: l

- platform: mqtt
  state_topic: "test/water/hour_begin"
  name: water_hour_begin
  unit_of_measurement: l

- platform: mqtt
  state_topic: "test/water/day"
  name: water_day
  unit_of_measurement: l

- platform: mqtt
  state_topic: "test/water/day_begin"
  name: water_day_begin
  unit_of_measurement: l

Die gesamte Magie findet in der Automatisierung statt, die jeweils jede Stunde und jede Nacht ausgefĂŒhrt wird.

- id: water_new_hour
  alias: water_new_hour
  initial_state: true
  trigger:
    - platform: time_pattern
      minutes: 0
  action:
    - service: mqtt.publish
      data:
        topic: "test/water/hour"
        payload_template: >
          {{ (states.sensor.water_meter_cold.state|int) - (states.sensor.water_hour_begin.state|int) }}
        retain: true
    - service: mqtt.publish
      data:
        topic: "test/water/hour_begin"
        payload_template: >
          {{ states.sensor.water_meter_cold.state }}
        retain: true

- id: water_new_day
  alias: water_new_day
  initial_state: true
  trigger:
    - platform: time
      at: "00:00:00"
  action:
    - service: mqtt.publish
      data:
        topic: "test/water/day"
        payload_template: >
          {{ (states.sensor.water_meter_cold.state|int) - (states.sensor.water_day_begin.state|int) }}
        retain: true
    - service: mqtt.publish
      data:
        topic: "test/water/day_begin"
        payload_template: >
          {{ states.sensor.water_meter_cold.state }}
        retain: true

Beide Automatisierungen fĂŒhren zwei Aktionen durch:

  • Sie berechnen den Wert fĂŒr das Intervall als Differenz zwischen dem Anfangs- und Endwert.
  • Sie aktualisieren den Basiswert fĂŒr das nĂ€chste Intervall.

Die Erstellung von Diagrammen wird in diesem Fall durch einen normalen history-graph gelöst:

      - type: history-graph
        title: 'StĂŒndlicher Wasserverbrauch mit Variablen'
        hours_to_show: 48
        entities:
          - sensor.water_hour

      - type: history-graph
        title: 'TĂ€glicher Wasserverbrauch mit Variablen'
        hours_to_show: 360
        entities:
          - sensor.water_day

So sieht es aus:

Smart Home: Verbrauchsstatistiken fĂŒr Wasser und Strom in Home Assistant erstellen

Im Grunde ist dies bereits das, was benötigt wird. Ein Vorteil dieser Methode ist, dass die Daten einmal pro Intervall generiert werden. Das bedeutet insgesamt 24 DatensĂ€tze pro Tag fĂŒr das Stunden-Diagramm.

Leider löst dies das allgemeine Problem einer wachsenden Datenbasis nicht. Wenn ich einen monatlichen Verbrauchsbericht möchte, mĂŒsste ich die Daten mindestens ein Jahr lang speichern. Da der Home Assistant nur eine Einstellung fĂŒr die Speicherdauer fĂŒr die gesamte Datenbank bereitstellt, bedeutet das, dass ALLE Daten im System ein ganzes Jahr lang aufbewahrt werden mĂŒssen. Beispielsweise verbrauche ich im Jahr 200 Kubikmeter Wasser, was 200.000 DatensĂ€tzen in der Datenbank entspricht. Und wenn ich noch andere Sensoren hinzunehme, wird die Zahl wirklich unermesslich.

Ansatz 3

GlĂŒcklicherweise haben kluge Köpfe dieses Problem bereits gelöst, indem sie die InfluxDB-Datenbank entwickelt haben. Diese Datenbank ist speziell fĂŒr die Speicherung von zeitbasierten Daten optimiert und ideal fĂŒr die Aufbewahrung von Werten verschiedener Sensoren. Das System bietet auch eine SQL-Ă€hnliche Abfragesprache, mit der Werte aus der Datenbank extrahiert und auf verschiedene Weise aggregiert werden können. Schließlich können unterschiedliche Daten unterschiedlich lange gespeichert werden. Beispielsweise können hĂ€ufig wechselnde Werte wie Temperatur oder Luftfeuchtigkeit nur ein paar Wochen lang gespeichert werden, wĂ€hrend tĂ€gliche Verbrauchswerte ĂŒber ein ganzes Jahr aufbewahrt werden können.

Neben InfluxDB haben kluge Köpfe auch Grafana erfunden – ein System zur Visualisierung von Daten aus InfluxDB. Grafana kann verschiedene Arten von Diagrammen zeichnen, diese detailliert anpassen und, das Wichtigste, diese Diagramme können in die Lovelace-UI des Home Assistant integriert werden.

Inspiriert werden hier und hier. Die Artikel beschreiben ausfĂŒhrlich den Prozess der Installation und Anbindung von InfluxDB und Grafana an den Home Assistant. Ich konzentriere mich jedoch auf die Lösung meiner spezifischen Aufgabe.

Beginnen wir also damit, die ZĂ€hlerwerte in InfluxDB zu speichern. Hier ist ein Auszug aus der Konfiguration des Home Assistant (in diesem Beispiel werde ich mich nicht nur mit kaltem, sondern auch mit heißem Wasser beschĂ€ftigen):

influxdb:
  host: localhost
  max_retries: 3
  default_measurement: state
  database: homeassistant
  include:
    entities:
      - sensor.water_meter_hot
      - sensor.water_meter_cold

Wir deaktivieren die Speicherung dieser Daten in der internen Datenbank des Home Assistant, um sie nicht unnötig aufzublÀhen:

recorder:
  purge_keep_days: 10
  purge_interval: 1
  exclude:
    entities:
      - sensor.water_meter_hot
      - sensor.water_meter_cold

Jetzt gehen wir zur InfluxDB-Konsole und richten unsere Datenbank ein. Insbesondere mĂŒssen wir festlegen, wie lange verschiedene Daten aufbewahrt werden. Dies wird durch die sogenannte Retention Policy geregelt – sie Ă€hnelt Datenbanken innerhalb der Hauptdatenbank, wobei jede interne Datenbank eigene Einstellungen hat. StandardmĂ€ĂŸig werden alle Daten in der Retention Policy mit dem Namen autogen gespeichert, diese Daten werden eine Woche lang aufbewahrt. Ich möchte, dass stĂŒndliche Daten einen Monat, wöchentliche Daten ein Jahr und monatliche Daten ĂŒberhaupt niemals gelöscht werden. Lassen Sie uns die entsprechenden Retention Policies erstellen.

CREATE RETENTION POLICY "month" ON "homeassistant" DURATION 30d REPLICATION 1
CREATE RETENTION POLICY "year" ON "homeassistant" DURATION 52w REPLICATION 1
CREATE RETENTION POLICY "infinite" ON "homeassistant" DURATION INF REPLICATION 1

Nun kommt der Haupttrick – die Aggregation von Daten mittels Continuous Query. Dies ist ein Mechanismus, der automatisch einen Abfragebefehl in festgelegten ZeitabstĂ€nden ausfĂŒhrt, die Daten dieser Abfrage aggregiert und das Ergebnis in einen neuen Wert speichert. Lassen Sie uns das anhand eines Beispiels erlĂ€utern (ich schreibe vertikal zur besseren Lesbarkeit, aber in der Tat musste ich diesen Befehl in einer Zeile eingeben).

ERSTELLEN SIE EINE KONTINUIERLICHE ABFRAGE cq_water_hourly IN homeassistant 
BEGIN 
  WÄHLEN SIE max(value) ALS value 
  IN homeassistant.month.water_meter_hour 
  VON homeassistant.autogen.l 
  GRUPPIEREN SIE NACH time(1h), entity_id fĂŒlle(vorhergehend) 
END

Dieser Befehl:

  • Erstellt eine kontinuierliche Abfrage mit dem Namen cq_water_cold_hourly in der Datenbank homeassistant
  • Die Abfrage wird stĂŒndlich ausgefĂŒhrt (time(1h))
  • Die Abfrage wird alle Daten aus dem Messwert homeassistant.autogen.l (Liter) abrufen, einschließlich der Messwerte fĂŒr kaltes und warmes Wasser
  • Die aggregierten Daten werden nach entity_id gruppiert, was uns separate Werte fĂŒr kaltes und warmes Wasser gibt
  • Da der LiterzĂ€hler eine monoton wachsende Folge ist, muss innerhalb jeder Stunde der Maximalwert ermittelt werden. Daher erfolgt die Aggregation mit der Funktion max(value)
  • Der neue Wert wird in homeassistant.month.water_meter_hour gespeichert, wobei month der Name der Aufbewahrungspolitik mit einer Speicherdauer von einem Monat ist. Dabei werden die Daten fĂŒr kaltes und warmes Wasser in separaten EintrĂ€gen mit der entsprechenden entity_id und dem Wert im Feld value abgelegt

In der Nacht oder wenn niemand zu Hause ist, wird kein Wasser verbraucht, und dementsprechend gibt es auch keine neuen EintrĂ€ge in homeassistant.autogen.l. Um zu vermeiden, dass es LĂŒcken in den regulĂ€ren Abfragen gibt, kann man fill(previous) verwenden. Dies zwingt InfluxDB, den Wert der letzten Stunde zu nutzen.

Leider hat die continuous query eine Besonderheit: der Trick fill(previous) funktioniert nicht und EintrĂ€ge werden einfach nicht erstellt. Es handelt sich hierbei um ein unĂŒberwindbares Problem, das... ...schon seit mehreren Jahren diskutiert wird.Wir werden uns spĂ€ter mit diesem Problem befassen, und fill(previous) in der continuous query kann bleiben – es stört nicht.

ÜberprĂŒfen wir, was herausgekommen ist (natĂŒrlich mĂŒssen wir ein paar Stunden warten):

> select * from homeassistant.month.water_meter_hour group by entity_id
...
name: water_meter_hour
tags: entity_id=water_meter_cold
time                 value
----                 -----
...
2020-03-08T01:00:00Z 370511
2020-03-08T02:00:00Z 370513
2020-03-08T05:00:00Z 370527
2020-03-08T06:00:00Z 370605
2020-03-08T07:00:00Z 370635
2020-03-08T08:00:00Z 370699
2020-03-08T09:00:00Z 370761
2020-03-08T10:00:00Z 370767
2020-03-08T11:00:00Z 370810
2020-03-08T12:00:00Z 370818
2020-03-08T13:00:00Z 370827
2020-03-08T14:00:00Z 370849
2020-03-08T15:00:00Z 370921

Bitte beachten Sie, dass die Werte in der Datenbank in UTC gespeichert werden. Daher gibt es eine Differenz von 3 Stunden – die Werte fĂŒr 7 Uhr morgens in der InfluxDB-Ausgabe entsprechen den Werten fĂŒr 10 Uhr auf den obenstehenden Grafiken. Zudem beachten Sie bitte, dass zwischen 2 und 5 Uhr morgens einfach keine Aufzeichnungen vorhanden sind – das ist die besondere Eigenschaft der kontinuierlichen Abfrage.

Wie Sie sehen, ist der aggregierte Wert ebenfalls eine monoton wachsende Folge, nur dass die Aufzeichnungen seltener sind – einmal pro Stunde. Aber das ist kein Problem – wir können eine weitere Abfrage schreiben, die die richtigen Daten fĂŒr das Diagramm abruft.

SELECT difference(max(value)) 
FROM homeassistant.month.water_meter_hour 
WHERE entity_id='water_meter_cold' and time >= now() -24h 
GROUP BY time(1h), entity_id 
fill(previous)

Ich werde es entschlĂŒsseln:

  • Wir holen die Daten aus der Datenbank homeassistant.month.water_meter_hour fĂŒr entity_id='water_meter_cold' der letzten 24 Stunden (time >= now() -24h).
  • Wie ich bereits erwĂ€hnt habe, können in der Sequenz homeassistant.month.water_meter_hour einige Aufzeichnungen fehlen. Diese Daten werden wir neu generieren, indem wir die Abfrage mit GROUP BY time(1h) ausfĂŒhren. Diesmal wird fill(previous) wie gewĂŒnscht funktionieren und die fehlenden Daten generieren (die Funktion nimmt den vorherigen Wert).
  • Das Wichtigste an dieser Abfrage ist die Funktion difference, die den Unterschied zwischen den Zeitstempeln berechnet. Sie funktioniert jedoch nicht allein und benötigt eine aggregierende Funktion. Lassen Sie uns max() verwenden, die zuvor eingesetzt wurde.

Das Ergebnis der AusfĂŒhrung sieht so aus.

name: water_meter_hour
tags: entity_id=water_meter_cold
time                 difference
----                 ----------
...
2020-03-08T02:00:00Z 2
2020-03-08T03:00:00Z 0
2020-03-08T04:00:00Z 0
2020-03-08T05:00:00Z 14
2020-03-08T06:00:00Z 78
2020-03-08T07:00:00Z 30
2020-03-08T08:00:00Z 64
2020-03-08T09:00:00Z 62
2020-03-08T10:00:00Z 6
2020-03-08T11:00:00Z 43
2020-03-08T12:00:00Z 8
2020-03-08T13:00:00Z 9
2020-03-08T14:00:00Z 22
2020-03-08T15:00:00Z 72

Von 2 bis 5 Uhr morgens (UTC) gab es keinen Verbrauch. Dennoch wird die Abfrage denselben Verbrauchswert zurĂŒckgeben, dank fill(previous), und die Funktion difference wird diesen Wert von sich selbst abziehen, sodass wir 0 erhalten, was genau das ist, was benötigt wird.

Jetzt bleibt nur noch, das Diagramm zu erstellen. Dazu öffnen wir Grafana, ein vorhandenes Dashboard (oder erstellen ein neues), und fĂŒgen ein neues Panel hinzu. Die Diagrammeinstellungen werden wie folgt sein.

Smart Home: Verbrauchsstatistiken fĂŒr Wasser und Strom in Home Assistant erstellen

Ich werde die Daten fĂŒr kaltes und warmes Wasser in einem Diagramm anzeigen. Die Abfrage ist genau die gleiche wie die oben beschriebene.

Die Anzeigeparameter werden wie folgt festgelegt. In meinem Fall handelt es sich um ein Liniendiagramm (lines), das stufenweise (stairs) verlÀuft. Den Parameter Stack werde ich gleich nÀher erlÀutern. Weiter unten gibt es noch einige Anzeigeneinstellungen, die aber weniger interessant sind.

Smart Home: Verbrauchsstatistiken fĂŒr Wasser und Strom in Home Assistant erstellen

Um das erhaltene Diagramm in Home Assistant hinzuzufĂŒgen, mĂŒssen Sie:

  • aus dem Bearbeitungsmodus des Diagramms herausgehen. Aus irgendeinem Grund werden die richtigen Einstellungen zum Teilen von Diagrammen nur von der Dashboard-Seite angeboten.
  • Auf den kleinen Pfeil neben dem Diagrammnamen klicken und im MenĂŒ 'share' auswĂ€hlen.
  • Im sich öffnenden Fenster zur Registerkarte 'embed' wechseln.
  • Das HĂ€kchen bei 'current time range' entfernen — den Zeitbereich legen wir ĂŒber die URL fest.
  • Das gewĂŒnschte Thema auswĂ€hlen. In meinem Fall ist es hell (light).
  • Die erhaltene URL in die Konfiguration des Lovelace-UI einfĂŒgen.

      - type: iframe
        id: graf_water_hourly
        url: "http://192.168.10.200:3000/d-solo/rZARemQWk/water?orgId=1&panelId=2&from=now-2d&to=now&theme=light"

Bitte beachten Sie, dass der Zeitbereich (letzte 2 Tage) genau hier festgelegt wird und nicht in den Dashboard-Einstellungen.

So sieht das Diagramm aus. In den letzten 2 Tagen habe ich kein heißes Wasser genutzt, daher wird nur das Diagramm fĂŒr kaltes Wasser angezeigt.

Smart Home: Verbrauchsstatistiken fĂŒr Wasser und Strom in Home Assistant erstellen

Ich habe fĂŒr mich selbst noch nicht entschieden, welches Diagramm ich besser finde: das Stufendiagramm oder die tatsĂ€chlichen SĂ€ulen. Daher fĂŒhre ich einfach ein Beispiel eines Tagesverbrauchsdiagramms an, diesmal jedoch in Form von SĂ€ulen. Die Anfragen werden Ă€hnlich wie zuvor beschrieben erstellt. Die Anzeigeparameter sind folgende:

Smart Home: Verbrauchsstatistiken fĂŒr Wasser und Strom in Home Assistant erstellen

So sieht dieses Diagramm aus:

Smart Home: Verbrauchsstatistiken fĂŒr Wasser und Strom in Home Assistant erstellen

Nun zum Parameter Stack. In diesem Diagramm wird die kalte WassersĂ€ule ĂŒber der heißen WassersĂ€ule gezeichnet. Die Gesamthöhe entspricht dem Gesamtverbrauch von kaltem und heißem Wasser ĂŒber den Zeitraum.

Alle gezeigten Diagramme sind dynamisch. Man kann mit der Maus ĂŒber einen interessanten Punkt fahren, um Details und Werte an diesem spezifischen Punkt zu sehen.

Leider ging es nicht ohne eine kleine Portion Pech. Im SĂ€ulendiagramm (im Gegensatz zum Stufendiagramm) befindet sich die Mitte der SĂ€ule nicht in der Mitte des Tages, sondern um 00:00 Uhr. Das heißt, die linke HĂ€lfte der SĂ€ule wird an der Stelle des vorherigen Tages gezeichnet. Die Diagramme fĂŒr Samstag und Sonntag sind also etwas weiter links als die blĂ€uliche Zone. Bisher habe ich noch keine Lösung dafĂŒr gefunden.

Ein weiteres Problem besteht darin, dass es nicht möglich ist, mit monatlichen Intervallen korrekt zu arbeiten. Der Grund ist, dass die Dauer von Stunde/Tag/Woche fixiert ist, wĂ€hrend die Dauer eines Monats jedes Mal anders ist. InfluxDB kann nur mit einheitlichen Intervallen arbeiten. Bisher hatte ich die Idee, ein fixes Intervall von 30 Tagen festzulegen. Ja, die Grafik wird im Laufe des Jahres ein wenig verzerrt sein, und die SĂ€ulen werden nicht ganz genau mit den Monaten ĂŒbereinstimmen. Aber da ich daran interessiert bin, es einfach als MessgerĂ€t zu nutzen, ist das fĂŒr mich in Ordnung.

Ich sehe mindestens zwei Lösungen:

  • Monatliche Grafiken vernachlĂ€ssigen und sich auf wöchentliche beschrĂ€nken. 52 wöchentliche SĂ€ulen pro Jahr sehen durchaus gut aus.
  • Den monatlichen Verbrauch als Methode Nr. 2 berechnen und Grafana nur fĂŒr ansprechende Grafiken verwenden. Das wird ein ziemlich genaues Ergebnis liefern. Man könnte sogar die Grafiken des letzten Jahres zum Vergleich ĂŒberlagern - Grafana kann sowas.

Fazit

Ich weiß nicht, warum, aber ich bin ein großer Fan solcher Grafiken. Sie zeigen, dass das Leben pulsierend ist und sich stĂ€ndig verĂ€ndert. Gestern gab es viel, heute wenig, und morgen wird es irgendwie wieder anders sein. Ich muss noch mit den Familienmitgliedern ĂŒber den Verbrauch sprechen. Aber selbst bei den aktuellen BedĂŒrfnissen verwandelt sich die große und unklare Zahl auf der Rechnung bereits in ein ziemlich klares Bild des Verbrauchs.

Trotz meiner fast 20-jĂ€hrigen Karriere als Programmierer hatte ich kaum mit Datenbanken zu tun. Daher schien mir die Einrichtung einer externen Datenbank etwas, das zu kompliziert und unverstĂ€ndlich war. Alles Ă€nderte sich durch den oben erwĂ€hnten Artikel — es stellte sich heraus, dass das Anbringen des passenden Werkzeugs mit ein paar Klicks erledigt ist, und mit einem spezialisierten Werkzeug wird die Erstellung von Grafiken etwas einfacher.

Im Titel habe ich den Stromverbrauch erwĂ€hnt. Leider kann ich im Moment keine Grafiken prĂ€sentieren. Ein SDM120 ZĂ€hler ist kaputt gegangen, und der andere hat beim Zugriff ĂŒber Modbus Probleme. Dennoch hat das keinen Einfluss auf das Thema dieses Artikels – die Grafiken werden auf die gleiche Weise erstellt wie die fĂŒr Wasser.

In diesem Artikel teile ich die AnsĂ€tze, die ich selbst ausprobiert habe. Sicherlich gibt es noch weitere Möglichkeiten zur Organisation der Datensammlung und -visualisierung, von denen ich nichts weiß. Lassen Sie es mich in den Kommentaren wissen, ich wĂŒrde mich sehr darĂŒber freuen. Konstruktive Kritik und neue Ideen sind immer willkommen. Ich hoffe, das Material hilft auch jemandem anderen.

Quelle: habr.com

ZuverlĂ€ssiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen đŸ”„ ZuverlĂ€ssiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen | ProHoster