Inteligentní dům: Vytváříme grafy spotřeby vody a elektřiny v Home Assistant

Inteligentní dům: Vytváříme grafy spotřeby vody a elektřiny v Home Assistant
Každý měsíc, když dostávám vyúčtování za elektřinu a vodu, se divím – opravdu naše rodina tolik spotřebovává? No jo, na koupelně máme podlahové topení a bojler, ale přece jenom nepoužívají neustále. Vodu také vypadá, že šetříme (i když si rádi zaplaveme ve vaně). Před několika lety jsem už připojil měřiče vody a elektřiny k chytré domácnosti, ale tím to všechno skončilo. K analýze spotřeby jsem se dostal až teď, o čemž vlastně je tento článek.

Nedávno jsem přešel na Home Assistant jako systém chytré domácnosti. Jedním z důvodů byla právě možnost sbírat velké množství dat s možností pohodlně vytvářet různé grafy.

Informace popsané v tomto článku nejsou nové, všechny tyto věci pod různými záminkami již byly popsány na internetu. Ale každý článek obvykle popisuje pouze jeden přístup nebo aspekt. Srovnávat všechny tyto přístupy a vybrat ten nejvhodnější jsem musel sám. Článek i přesto neposkytuje vyčerpávající informace o sběru dat, ale představuje jakýsi souhrn toho, jak jsem to udělal. Takže konstruktivní kritika a návrhy na zlepšení jsou vítány.

Formulace úkolu

Cílem dnešního cvičení je získat krásné grafy spotřeby vody a elektřiny:

  • Hodinový graf za 2 dny
  • Denní graf za 2 týdny
  • (volitelně) týdenní a měsíční

Zde nás čekají určité obtíže:

  • Standardní grafové komponenty jsou obvykle velmi chudé. V tom lepším případě lze vytvořit jen liniový graf podle bodů.

    Pokud se dobře podíváte, můžete najít externí komponenty, které rozšiřují možnosti standardního grafu. Pro home assistant není špatný a hezký komponent mini-graph-card, ale i ten má některá omezení:

    • Je obtížné nastavovat parametry sloupcového grafu na dlouhých intervalech (šířka sloupce je nastavena v zlomcích hodiny, což znamená, že intervaly delší než hodina budou nastavovány jako desetinná čísla)
    • Není možné na jeden graf přidávat různé entity (např. teplotu a vlhkost nebo sloupcový graf zkombinovat s linií)
  • Není to jen tak, že home assistant ve výchozím nastavení používá nejjednodušší databázi SQLite (a já, nešika, nezvládl instalaci MySQL nebo Postgres), ale také data nejsou uchovávána tím nejoptimálnějším způsobem. Například při každé změně každého, i toho nejmenšího, digitálního parametru se do databáze zapisuje obrovský JSON o velikosti kolem jednoho kilobajtu.
    {"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}}}

    Mám poměrně mnoho senzorů (teplotní senzory v každé místnosti, měřiče vody a elektřiny), a někteří také generují poměrně velké množství dat. Například pouze měřič elektřiny SDM220 generuje kolem deseti hodnot každých 10-15 sekund, a takových měřičů bych chtěl nainstalovat asi 8. A navíc je zde celá škála parametrů, které se vypočítávají na základě jiných senzorů. Tím pádem mohou všechny tyto hodnoty snadno nafouknout databázi o 100-200 MB denně. Po týdnu bude systém sotva fungovat, a po měsíci zemře flash disk (v případě typické instalace home assistant na Raspberry PI), a o uchovávání dat po celý rok nemůže být ani řeč.

  • Pokud máte štěstí, váš měřič umí sám počítat spotřebu. Můžete se kdykoli obrátit na měřič a zjistit, jaká je akumulovaná hodnota spotřeby. Obecně všechny měřiče elektřiny, které mají digitální rozhraní (RS232/RS485/Modbus/Zigbee), tuto možnost poskytují.

    Hůře je, pokud zařízení může měřit pouze nějaký okamžitý parametr (například okamžitý výkon nebo proud), nebo prostě generovat impulsy každé X watthodin nebo litru. Pak je potřeba přemýšlet, jak a čím to integrovat a kde hodnotu uchovávat. Existuje riziko, že některý report bude zmeškán z nějakého důvodu, a také přesnost systému jako celku vyvolává otázky. Samozřejmě, že to všechno můžete svěřit systému inteligentní domácnosti, jako je home assistant, ale bod ohledně počtu záznamů v databázi nikdo nezrušil a dotazování senzorů častěji než jednou za sekundu nebude možné (omezení architektury home assistant).

Přístup 1

Nejprve se podíváme, co home assistant nabízí přímo z krabice. Měření spotřeby za období – velmi žádaná funkčnost. Samozřejmě, že byla dávno implementována jako specializovaná komponenta – utility_meter.

Podstata komponenty spočívá v tom, že uvnitř zavádí proměnnou current_accumulated_value a resetuje ji na konci zadaného období (hodina/týden/měsíc). Komponenta sama monitoruje přicházející proměnnou (hodnota nějakého senzoru), sama se přihlašuje na změny hodnoty – vy prostě dostanete hotový výsledek. Toto zařízení je popsáno pouhými několika řádky v konfiguračním souboru.

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

Zde sensor.water_meter_cold představuje aktuální hodnotu měřiče v litrech, kterou dostávám přímo z železa přes mqtt. Konstrukce vytváří 2 nové sensory water_cold_hour_um a water_cold_day_um, které uchovávají hodinové a denní ukazatele a nulují je na konci období. Zde je graf hodinového akumulátoru za půl dne.

Inteligentní dům: Vytváříme grafy spotřeby vody a elektřiny v Home Assistant

Kód hodinových a denních grafů pro lovelace-UI vypadá takto:

      - type: history-graph
        title: 'Hodinová spotřeba vody pomocí proměnných'
        hours_to_show: 48
        entities:
          - sensor.water_hour

      - type: history-graph
        title: 'Denní spotřeba vody pomocí proměnných'
        hours_to_show: 360
        entities:
          - sensor.water_day

Ve skutečnosti je v tomto algoritmu skryta problématika tohoto přístupu. Jak jsem již zmínil, pro každou vstupní hodnotu (aktuální hodnota měřiče pro každý další litr) se generuje 1 kB záznamu v databázi. Každý utility meter také generuje novou hodnotu, která se rovněž ukládá do databáze. Pokud chci sbírat hodinové, denní, týdenní nebo měsíční hodnoty, a to z několika vodovodních stojanů a ještě přidat pár elektrických měřičů — to bude opravdu hodně dat. No, přesněji řečeno, dat není mnoho, ale protože home assistant do databáze zapisuje spoustu zbytečných informací, velikost databáze poroste jako houbami po dešti. Obávám se i odhadovat velikost databáze pro týdenní a měsíční grafy.

Kromě toho utility meter sám o sobě neřeší stanovený úkol. Graf hodnot, které poskytuje utility meter, je monotonní rostoucí funkce, která se každý hodinu resetuje na 0. Potřebujeme přehledný graf spotřeby pro uživatele, kolik litrů bylo spotřebováno za dané období. Standardní komponenta history-graph to neumí, ale může nám pomoci externí komponenta mini-graph-card.

Toto je kód karty pro lovelace-UI:

      - aggregate_func: max
        entities:
          - color: var(--primary-color)
            entity: sensor.water_cold_hour_um
        group_by: hour
        hours_to_show: 48
        name: "Hodinová spotřeba vody agregována podle utility meter"
        points_per_hour: 1
        show:
          graph: bar
        type: 'custom:mini-graph-card'

Kromě standardních nastavení jako je jméno senzoru, typ grafu, barva (standardní oranžová se mi nelíbila) je důležité zmínit 3 nastavení:

  • group_by:hour — graf bude generován s vyrovnáním sloupečků na začátek hodiny
  • points_per_hour: 1 — jeden sloupeček na každou hodinu
  • A nejdůležitější, aggregate_func: max — brát maximální hodnotu v rámci každé hodiny. Tento parametr právě proměňuje pilový graf na sloupečky.

Inteligentní dům: Vytváříme grafy spotřeby vody a elektřiny v Home Assistant

Na řadu sloupečků vlevo neberte ohled — to je standardní chování komponenty, pokud nejsou žádná data. A dat nebylo — jen pár hodin zpět jsem aktivoval sběr dat podle utility meter jen kvůli tomuto článku (svůj aktuální přístup popíši o něco níže).

Na tomto obrázku jsem chtěl ukázat, že někdy zobrazení dat opravdu funguje a sloupce skutečně odrážejí správné hodnoty. Ale ne všechny. Vymezený sloupec za období od 11 do 12 hodin zobrazuje 19 litrů, přestože na zubatém grafu výše za stejný časový úsek ze stejného senzoru vidíme spotřebu 62 litrů. Buď je to chyba, nebo je problém jinde. A zatím mi není jasné, proč jsou data napravo zlomená — spotřeba tam byla v normě, jak je také vidět podle zubatého grafu.

Obecně se mi nepodařilo dosáhnout důvěryhodnosti tohoto přístupu — graf téměř vždy ukazuje nějaké nesmysly.

Analogový kód pro denní senzor.

      - aggregate_func: max
        entities:
          - color: var(--primary-color)
            entity: sensor.water_cold_day_um
        group_by: interval
        hours_to_show: 360
        name: "Denní spotřeba vody agregovaná podle utility meter"
        points_per_hour: 0.0416666666
        show:
          graph: bar
        type: 'custom:mini-graph-card'

Všimněte si, že parametr group_by je nastaven na hodnotu interval, a ovládá ho celý parametr points_per_hour. A v tom spočívá další problém tohoto komponentu — points_per_hour funguje dobře na grafech za hodinu nebo méně, ale špatně na delších intervalech. Takže abych získal jeden sloupec za jeden den, musel jsem napsat hodnotu 1/24=0.04166666. Už nemluvím o týdenních a měsíčních grafech.

Přístup 2

Ještě když se teprve seznamuji s Home Assistant, narazil jsem na toto video:

Přehrát video

Kolega shromažďuje údaje o spotřebě z několika typů zásuvek Xiaomi. Jeho úkol je o něco jednodušší — jen zobrazit hodnotu spotřeby za dnešek, včerejšek a za měsíc. Žádné grafy nejsou potřeba.

Odpusťme si úvahy o ručním integraci okamžitých hodnot výkonu — o "přesnosti" tohoto přístupu jsem již psal výše. Není jasné, proč nepoužil akumulované hodnoty spotřeby, které již shromažďuje stejná zásuvka. Podle mého názoru bude integrace uvnitř zařízení fungovat lépe.

Z videa si vezmeme myšlenku ručního počítání spotřeby za období. Člověk počítá pouze hodnoty za dnešek a včerejšek, ale my půjdeme dál a pokusíme se vykreslit graf. Podstata navrhované metody v mém případě spočívá v následujícím.

Vytvoříme proměnnou hodnota_na_začátku_hodiny, do které zapíšeme aktuální měření počítadla.
Na konci hodiny (nebo na začátku následující) spočítáme rozdíl mezi aktuálním měřením a uloženým na začátku hodiny. Tento rozdíl bude spotřebou za aktuální hodinu - uložíme hodnotu do senzoru a v budoucnu budeme podle této hodnoty vytvářet graf.
Je také potřeba „resetovat“ proměnnou hodnota_na_zacatku_hodiny tím, že do ní zapíšeme aktuální hodnotu čítače.

To vše lze provést prostřednictvím… pomocí samotného home assistant.

Kód bude třeba napsat o něco více než v předchozím přístupu. Nejprve si vytvoříme tyto „proměnné“. Z boxu nemáme entitu „proměnná“, ale můžeme využít služby mqtt brokera. Budeme tam posílat hodnoty s flagem retain=true - to uloží hodnotu uvnitř brokera, a kdykoli ji můžeme vyzvednout, i při restartu home assistant. Vytvořil jsem ihned hodinové a denní čítače.

- 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

Veškerá magie se odehrává v automatizaci, která se spouští každou hodinu a každou noc.

- 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

Obě automatizace vykonávají 2 akce:

  • Vypočítávají hodnotu za interval jako rozdíl mezi počáteční a koncovou hodnotou
  • Aktualizují základní hodnotu pro další interval

Vytváření grafů je v tomto případě řešeno pomocí běžného history-graph:

      - type: history-graph
        title: 'Hodinová spotřeba vody pomocí proměnných'
        hours_to_show: 48
        entities:
          - sensor.water_hour

      - type: history-graph
        title: 'Denní spotřeba vody pomocí proměnných'
        hours_to_show: 360
        entities:
          - sensor.water_day

Vypadá to takto:

Inteligentní dům: Vytváříme grafy spotřeby vody a elektřiny v Home Assistant

V podstatě je to už to, co potřebujete. Výhodou této metody je, že data se generují jednou za interval. Tedy celkem 24 záznamů za den pro hodinový graf.

Bohužel to stále neřeší celkový problém rostoucí databáze. Pokud budu chtít graf měsíční spotřeby, budu muset uchovávat data alespoň za rok. A protože Home Assistant poskytuje pouze jedno nastavení doby uchovávání pro celou databázi, znamená to, že VŠECHNA data v systému budou muset být uchovávána celý rok. Například za rok spotřebuji 200 kubíků vody, což představuje 200000 záznamů v databázi. A pokud také zohledním další senzory, číslo se stane opravdu nepřijatelným.

Přístup 3

Naštěstí chytří lidé už tento problém vyřešili vytvořením databáze InfluxDB. Tato databáze je speciálně optimalizována pro uchovávání časově závislých dat a je ideální pro uchovávání hodnot různých senzorů. Systém také poskytuje SQL-podobný jazyk dotazů, který umožňuje vybírat hodnoty z databáze a poté je agregovat různými způsoby. Nakonec lze uchovávat různé údaje různě dlouhou dobu. Například často se měnící údaje jako teplota nebo vlhkost je možné uchovávat pouze pár týdnů, zatímco denní údaje o spotřebě vody lze uchovávat celý rok.

Kromě InfluxDB chytrí lidé také vynalezli Grafanu — systém pro kreslení grafů na základě dat z InfluxDB. Grafana umí kreslit různé typy grafů, detailně je přizpůsobovat a, co je nejdůležitější, tyto grafy lze „vložit“ do uživatelského rozhraní lovelace Home Assistant.

Inspirovat se tady a tady. V článcích je podrobně popsán proces instalace a připojení InfluxDB a Grafany k Home Assistant. Já se soustředím na řešení své konkrétní úlohy.

Takže začneme tím, že začneme ukládat hodnotu měřiče do InfluxDB. Kousek konfigurace Home Assistant (v tomto příkladu se budu bavit nejen s studenou, ale i s horkou vodou):

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

Vypneme uchovávání těchto stejných dat v interní databázi Home Assistant, abychom ji zbytečně nenafukovali:

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

Přejdeme nyní do konzole InfluxDB a nastavíme naši databázi. Konkrétně je třeba nastavit, jak dlouho budou různé údaje uchovávány. To se reguluje tzv. retention policy — to je něco jako databáze uvnitř hlavní databáze, přičemž každá vnitřní databáze má své vlastní nastavení. Ve výchozím nastavení se všechny údaje shromažďují v retention policy s názvem autogen, tyto údaje budou uchovávány po dobu jednoho týdne. Chtěl bych, aby hodinové údaje byly uchovávány měsíc, týdenní - rok, a měsíční údaje nikdy nebyly smazány. Vytvoříme odpovídající retention policy.

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

Nyní vlastně hlavní trik — agregace údajů pomocí continuous query. To je mechanismus, který automaticky spouští dotaz v určených intervalech, agreguje údaje podle tohoto dotazu a uloží výsledky do nové hodnoty. Probereme si to na příkladu (píši to ve sloupcích pro přehlednost, ale ve skutečnosti jsem musel zadat tento příkaz jako jeden řádek).

CREATE CONTINUOUS QUERY cq_water_hourly ON homeassistant 
BEGIN 
  SELECT max(value) AS value 
  INTO homeassistant.month.water_meter_hour 
  FROM homeassistant.autogen.l 
  GROUP BY time(1h), entity_id fill(previous) 
END

Tento příkaz:

  • Vytváří continuous query s názvem cq_water_cold_hourly v databázi homeassistant.
  • Dotaz se bude vykonávat každou hodinu (time(1h)).
  • Dotaz bude vybírat všechny údaje z measurementu homeassistant.autogen.l (litry), včetně měření studené a teplé vody.
  • Agregované údaje budou seskupeny podle entity_id, což nám vytvoří samostatné hodnoty pro studenou a teplou vodu.
  • Jelikož je měřič litrů monotonně rostoucí sekvence, v rámci každé hodiny bude třeba brát maximální hodnotu, proto agregace bude provedena funkcí max(value).
  • Nová hodnota bude zapsána do homeassistant.month.water_meter_hour, kde month je název retention policy s dobou uchovávání v měsíci. Přičemž údaje o studené a teplé vodě budou rozptýleny v samostatných záznamech s odpovídajícím entity_id a hodnotou v poli value.

V noci nebo když nikdo není doma, není spotřeba vody, a tedy také neexistují nové záznamy v homeassistant.autogen.l. Aby v běžných dotazech nedocházelo k výpadkům hodnot, lze použít fill(previous). To způsobí, že InfluxDB použije hodnotu z předchozí hodiny.

Bohužel má continuous query zvláštnost: trik fill(previous) nefunguje a záznamy se jednoduše nevytváří. A to je nějaký nezdolný problém, který se diskutuje už několik let. S tímto problémem se vyřešíme později, a fill(previous) ve continuous query ať zůstane — nevadí to.

Podíváme se, co jsme získali (samozřejmě je třeba počkat pár hodin):

> 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

Všimněte si, že hodnoty v databázi se ukládají v UTC, takže v tomto seznamu se liší o 3 hodiny — hodnoty za 7 hodin ráno ve výstupu InfluxDB odpovídají hodnotám za 10 hodin ráno na grafech výše. Také si dejte pozor, že mezi 2 a 5 hodinou ráno záznamy prostě nejsou — to je ta zvláštnost continuous query.

Jak vidíte, agregovaná hodnota je také monotónně rostoucí posloupnost, jenom záznamy jsou řídké — jednou za hodinu. Ale to není problém — můžeme napsat další dotaz, který vytáhne správná data pro graf.

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)

Vysvětlím:

  • Z databáze homeassistant.month.water_meter_hour vytáhneme data pro entity_id=’water_meter_cold’ za posledních 24 hodin (time >= now() -24h).
  • Jak jsem už zmínil, v sekvenci homeassistant.month.water_meter_hour mohou chybět některé záznamy. Tato data vygenerujeme znovu spuštěním dotazu s GROUP BY time(1h). Tentokrát fill(previous) bude fungovat, jak má, a vygeneruje chybějící data (funkce vezme předchozí hodnotu)
  • Nejdůležitější věcí v tomto dotazu je funkce difference, která spočítá rozdíl mezi hodinovými značkami. Sama o sobě nefunguje a vyžaduje agregační funkci. Ať to je max() použité předtím.

Výsledek provedení vypadá takto

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

Od 2 do 5 hodin ráno (UTC) nebyla spotřeba. Nicméně dotaz vrátí stejné hodnoty spotřeby díky možnosti fill(previous), a funkce difference tuto hodnotu odečte sama od sebe, což povede k výsledku 0, což je vlastně to, co potřebujeme.

Teď už zbývá jen postavit graf. K tomu otevřeme Grafanu, otevřeme nějaký existující (nebo vytvoříme nový) dashboard a vytvoříme novou panel. Nastavení grafů bude takovéto.

Inteligentní dům: Vytváříme grafy spotřeby vody a elektřiny v Home Assistant

Budu zobrazovat data o studené a teplé vodě na jednom grafu. Dotaz je přesně takový, jak jsem popsal výše.

Parametry zobrazení jsou nastaveny takto. Bude to graf s liniemi (lines), který jde po krocích (stairs). Parametr Stack vysvětlím níže. Dole je ještě pár dalších parametrov zobrazení, ale ty nejsou tak zajímavé.

Inteligentní dům: Vytváříme grafy spotřeby vody a elektřiny v Home Assistant

Abychom přidali získaný graf do home assistenta, je třeba:

  • vystoupit z režimu úpravy grafu. Z nějakého důvodu jsou správná nastavení sdílení grafů nabízena jen ze stránky dashboardu.
  • Klepněte na trojúhelník vedle názvu grafu a v menu vyberte sdílet (share).
  • V otevřeném okně přejděte na záložku embed.
  • Zrušte zaškrtnutí u current time range — časový rozsah budeme určovat pomocí URL.
  • Vyberte potřebné téma. V mém případě je to light.
  • Zkopírujte získanou URL do karty nastavení lovelace-UI.

      - 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"

Všimněte si, že časový rozsah (poslední 2 dny) se nastavuje právě zde, nikoli v nastavení dashboardu.

Graf vypadá takto. Teplou vodu jsem za poslední 2 dny nepoužíval, proto se vykresluje pouze graf studené vody.

Inteligentní dům: Vytváříme grafy spotřeby vody a elektřiny v Home Assistant

Ještě jsem se nerozhodl, který graf se mi více líbí, zda stupňový nebo skutečné sloupce. Proto jen uvedu příklad denního grafu spotřeby, tentokrát ale ve sloupcích. Dotazy se tvoří analogicky tomu, co bylo popsáno výše. Parametry zobrazení jsou následující:

Inteligentní dům: Vytváříme grafy spotřeby vody a elektřiny v Home Assistant

Tento graf vypadá takto:

Inteligentní dům: Vytváříme grafy spotřeby vody a elektřiny v Home Assistant

Tak, a teď k parametru Stack. V tomto grafu je sloupec studené vody zakreslen nad sloupcem teplé vody. Celková výška odpovídá součtu spotřeby studené a teplé vody za období.

Všechny zobrazené grafy jsou dynamické. Můžete přejít myší na zajímavý bod a zobrazit podrobnosti a hodnotu v konkrétním bodě.

Bohužel, ani bez pár lžiček dehtu se to neobešlo. Na sloupcovém grafu (na rozdíl od grafu s krokovými čarami) se střed sloupce nenachází uprostřed dne, ale ve 00:00. Tedy levá polovina sloupce je nakreslena na místě předchozího dne. Takže grafy za sobotu a neděli jsou nakresleny o něco nalevo od modravé zóny. Zatím jsem nepřišel na to, jak to vyřešit.

Další problém spočívá v nemožnosti správně pracovat s měsíčními intervaly. Důvodem je, že délka hodiny/dne/týdne je fixní, zatímco délka měsíce je pokaždé jiná. InfluxDB umí pracovat pouze s jednotkovými intervaly. Zatím mi stačilo na to, abych nastavil fixní interval na 30 dní. Ano, graf během roku se trochu posune a sloupce nebudou přesně odpovídat měsícům. Ale protože mě tato záležitost zajímá jen jako ukazatel, tak s tím souhlasím.

Vidím minimálně dvě řešení:

  • Zasypat měsíční grafy a omezit se na týdenní. 52 týdenních sloupců za rok vypadá docela dobře.
  • Měsíční spotřebu vypočítávat jako metodu č. 2 a grafanu používat jen na krásné grafy. Přesné řešení se dostane. Můžete dokonce překrýt grafy z minulého roku pro srovnání – grafana to umí také.

Závěr

Nevím proč, ale opravdu mě baví tento typ grafů. Ukazují, že život vře a všechno se mění. Včera bylo hodně, dnes málo, zítra to bude zase jinak. Ještě zbývá probrat to s domácími ohledně spotřeby. Ale i při současných apetitech se prostě velké a nejasné číslo na faktuře stává docela pochopitelným obrazem spotřeby.

Navzdory téměř 20leté kariéře programátora jsem se s databázemi prakticky nesetkal. Proto mi instalace externí databáze připadala jako něco tak nepochopitelného. Všechno se změnilo, výše zmíněný článek, – ukázalo se, že přidání vhodného nástroje se provádí ve dvou kliknutích, a se specializovaným nástrojem je úkol vytváření grafů o něco jednodušší.

V nadpisu jsem zmínil spotřebu elektrické energie. Bohužel momentálně nemohu poskytnout žádný graf. Jedno měřidlo SDM120 mi odešlo a druhé má problémy při komunikaci přes Modbus. Nicméně to na téma tohoto článku nemá žádný vliv — grafy budou vytvořeny stejným způsobem jako pro vodu.

V tomto článku jsem uvedl přístupy, které jsem sám vyzkoušel. Určitě existují i další způsoby organizace sběru a vizualizace dat, o kterých nevím. Podělte se se mnou o to v komentářích, budu velmi rád. Budu rád za konstruktivní kritiku a nové nápady. Doufám, že předložený materiál také někomu pomůže.

Zdroj: habr.com

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster