Okos otthon: Víz- és villanyfogyasztási grafikonok építése a Home Assistantban

Okos otthon: Víz- és villanyfogyasztási grafikonok építése a Home Assistantban
Mindig meglepődöm, amikor megkapom a villany- és vízszámlát – tényleg ennyit fogyaszt a családom? Igen, van a fürdőszobában padlófűtés és bojler, de ezek nem működnek folyamatosan. Úgy tűnik, hogy a vízhasználatot is spóroljuk (bár szeretek a fürdőkádban pancsolni). Pár évvel ezelőtt már bekötöttem a vízmérőket és áramot okosotthonhoz, de ezen a téren eddig megakadt a dolog. Csak most jutottam el a fogyasztás elemzéséhez, ami miatt íródott ez a cikk.

Nemrég áttértem a Home Assistant-ra, mint okosotthon rendszere. Az egyik ok az volt, hogy lehetőséget adjon rengeteg adat gyűjtésére, lehetővé téve különféle diagramok kényelmes elkészítését.

Az ebben a cikkben leírt információk nem újak, ezek a dolgok már különböző köntösben megjelentek az interneten. De minden cikk jellemzően csak egy megközelítést vagy szempontot ír le. Összehasonlítani ezeket a megközelítéseket és kiválasztani a legmegfelelőbbet nekem kellett. A cikk így sem nyújt kimerítő információt az adatgyűjtésről, de egyfajta vázlat arról, hogyan csináltam én. Tehát a konstruktív kritikát és a fejlesztési javaslatokat szívesen fogadom.

Lépjünk át a kitűzött feladatra: írjunk egy XDP mechanizmust SYN cookie-kkal.

Tehát a mai gyakorlat célja, hogy szép diagramokat készítsünk a víz- és áramfogyasztásról:

  • Órás az elmúlt 2 napra
  • Napi az elmúlt 2 hétre
  • (opcionálisan) heti és havi

Ebben néhány nehézség vár ránk:

  • A standard diagramkomponensek általában meglehetősen szegényesek. A legjobb esetben csak pontok alapján lehet vonaldiagramot készíteni.

    Ha alaposan keresünk, találhatunk harmadik fél komponenst, ami bővíti a standard diagram lehetőségeit. A home assistant-hoz a mini-graph-cardrelatíve jó és szép komponens, de ennek is vannak korlátai:

    • Nehéz beállítani a oszlopdiagram paramétereit nagyobb intervallumoknál (az oszlop szélessége órákban van megadva, így a hosszabb intervallumokat tört számokkal kell megadni)
    • Nem lehet egy diagramra különböző entitásokat hozzáadni (például hőmérsékletet és páratartalmat, vagy oszlopdiagramot vonaldiagrammal összekapcsolni)
  • Nemcsak az a probléma, hogy a home assistant alapértelmezetten a legprimitívebb SQLite adatbázist használja (én pedig, ügyetlen kezű, nem tudtam telepíteni a MySQL-t vagy a Postgres-t), hanem az adatok tárolása sem optimális módon történik. Például minden egyes apró digitális paraméter módosításakor egy hatalmas, körülbelül egy kilobájtos json kerül az adatbázisba.
    {"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}}}

    Elég sok érzékelőm van (hőmérséklet-érzékelők minden szobában, víz- és árammérők), és néhány ezek közül elég sok adatot generál. Például a SDM220 elektromos mérő körülbelül tucatnyi értéket generál 10-15 másodpercenként, és ebből nyolcat szeretnék telepíteni. Ezenkívül van egy csomó olyan paraméter, amely más érzékelők alapján számítódik. Így ezek az értékek könnyedén megnövelhetik az adatbázist naponta 100-200 MB-mal. Egy hét múlva a rendszer alig fog működni, egy hónap múlva pedig tönkremegy a flash memória (a home assistant tipikus raspberry PI telepítése esetén), márpedig egy évnyi adat tárolására szó sem lehet.

  • Ha szerencséd van, a mérőd képes saját magától számítani a fogyasztást. Bármikor kérhetsz tőle információt az összegyűjtött fogyasztási értékről. Általában azok az elektromos mérők, amelyek digitális interfésszel rendelkeznek (RS232/RS485/Modbus/Zigbee), kínálják ezt a lehetőséget.

    Rosszabb, ha az eszköz csak egy adott pillanatnyi paramétert (például pillanatnyi teljesítményt vagy áramot) tud mérni, vagy csak impulzusokat generál X wattóránként vagy literenként. Akkor el kell gondolkodni, hogy mivel és hogyan integrálják, valamint hol tárolják az értéket. Van kockázata annak, hogy egy újabb jelentést elmulasztanak valamilyen okból, és a rendszer általános pontosságával kapcsolatban is felmerülnek kérdések. Persze mindezt rábízhatjuk egy okosotthon rendszerre, mint a home assistant, de a bázis-recordok mennyiségéről szóló pontot senki sem törölte, és a szenzorok lekérdezését gyakrabban mint másodpercenként nem tudjuk megtenni (a home assistant architektúrájának korlátozása).

1. megközelítés

Először nézzük meg, mit kínál a home assistant dobozból. A fogyasztás időszakos mérésére nagy igény van. Természetesen ezt már régen megvalósították egy speciális komponensként — utility_meter néven.

A komponens lényege, hogy belül létrehoz egy változót, a current_accumulated_value-t, és ezt nullázza egy adott időszak (óra/hét/hónap) leteltével. A komponens önállóan figyeli a bejövő változót (valamelyik érzékelő értékét), önállóan iratkozik fel az értékének változásaira — Ön csak a kész eredményt kapja. Ezt a dolgot mindössze néhány sorban lehet leírni a konfigurációs fájlban.

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

Itt a sensor.water_meter_cold az aktuális érték a vízmérőből literben, amit kapok közvetlenül az eszköztől mqtt-n keresztül. A szerkezet létrehoz 2 új érzékelőt, a water_cold_hour_um és a water_cold_day_um, amelyek az órás és napi értékeket gyűjtik, és azokat nullázza az időszak végén. Íme, a fél napos órás akkumulátor grafikona.

Okos otthon: Víz- és villanyfogyasztási grafikonok építése a Home Assistantban

A lovelace-UI órás és napi grafikáinak kódja így néz ki:

      - type: history-graph
        title: 'Óránkénti vízfogyasztás változókkal'
        hours_to_show: 48
        entities:
          - sensor.water_hour

      - type: history-graph
        title: 'Napi vízfogyasztás változókkal'
        hours_to_show: 360
        entities:
          - sensor.water_day

Valójában ebben az algoritmusban rejlik a megközelítés problémája. Ahogy már említettem, minden egyes bemeneti értékhez (a számláló aktuális értéke minden egyes következő liter esetén) 1 kB rekord generálódik az adatbázisban. Minden egyes utility meter szintén generál egy új értéket, ami szintén belekerül az adatbázisba. Ha órás, napi, heti vagy havi méréseket akarok gyűjteni, több vízvezetékhez, és még néhány villanyszámlálót is hozzáadok - ez nagyon sok adatot jelent. Nos, pontosabban az adatok nem sokan vannak, de mivel a home assistant rengeteg felesleges információt ír az adatbázisba, az adatbázis mérete olyan gyorsan fog nőni, mint az élesztő. Félek még kalkulálni az adatbázis méretét a heti és havi grafikonokhoz.

Ezen kívül a utility meter önmagában nem oldja meg a kitűzött feladatot. A utility meter által kiadott értékek grafikonja monoton növekvő függvény, amelyet minden órában 0-ra állítanak vissza. Nekünk egy felhasználó számára érthető grafikonra van szükségünk, ami megmutatja, hogy mennyi liter fogyott el az adott időszak alatt. A standard history-graph komponens ezt nem tudja, de a külső mini-graph-card komponens segítségünkre lehet.

Ez a kód a lovelace-UI kártyához:

      - aggregate_func: max
        entities:
          - color: var(--primary-color)
            entity: sensor.water_cold_hour_um
        group_by: hour
        hours_to_show: 48
        name: "Óránkénti vízfogyasztás aggregálva a utility meter által"
        points_per_hour: 1
        show:
          graph: bar
        type: 'custom:mini-graph-card'

A standard beállításokon kívül, mint a szenzor neve, a grafikon típusa, a szín (a hagyományos narancssárga nem tetszik) itt három beállítást fontos megemlíteni:

  • group_by:hour - a grafikon a lécet az óra elejére igazítva lesz generálva
  • points_per_hour: 1 - egy oszlop minden egyes órára
  • És a legfontosabb, aggregate_func: max - a maximális érték figyelembevétele minden egyes órán belül. Ez az paraméter alakítja át a fűrészfogas grafikont oszlopokká.

Okos otthon: Víz- és villanyfogyasztási grafikonok építése a Home Assistantban

A bal oldalon lévő oszlopokra ne figyeljetek - ez a komponens standard viselkedése, ha nincsenek adatok. Pedig adatok nem voltak - csak néhány órával ezelőtt kezdtem el gyűjteni az adatokat a utility meter segítségével csak ezért a cikkért (a jelenlegi megközelítésemet kicsit később elmondom).

Ez a képen azt szerettem volna megmutatni, hogy néha a data megjelenítése tényleg működik, és az oszlopok valóban a helyes értékeket tükrözik. Csak éppen nem minden esetben. Az emelt oszlop az időintervallum alatt 11-től 12-ig reggel valamiért 19 litert mutat, holott a csipkés grafikonon, ami kicsit fent van, ugyanarra az időszakra ugyanazzal az érzékelővel 62 literes fogyasztás látható. Vagy bug, vagy ügyetlen a kivitelezés. Azt viszont nem értem, hogy miért törtek el az adatok jobbra — a fogyasztás ott a normál határokon belül volt, ami a csipkés grafikonon is látható.

A megközelítés hitelességét nem tudtam elérni - a grafikon szinte mindig valami ostobaságot mutat.

Hasonló kód a napi érzékelőhöz.

      - aggregate_func: max
        entities:
          - color: var(--primary-color)
            entity: sensor.water_cold_day_um
        group_by: interval
        hours_to_show: 360
        name: "Napi vízfogyasztás aggregálva a közüzemi mérő által"
        points_per_hour: 0.0416666666
        show:
          graph: bar
        type: 'custom:mini-graph-card'

Figyeljen arra, hogy a group_by paraméter az interval értékre van állítva, és a points_per_hour paraméter szabályoz mindent. Itt rejlik a komponenst érintő másik probléma — a points_per_hour jól működik az órás vagy annál kisebb grafikonokon, de szörnyen a hosszabb időszakokban. Tehát ahhoz, hogy egy oszlopot kapjunk egy napra, be kellett írni az értéket 1/24=0.04166666. Már nem is beszélek a heti és havi grafikonokról.

Megközelítés 2

Még a Home Assistant-tel való ismerkedés közben bukkantam erre a videóra:

Videó lejátszása

Egy barát adatokat gyűjt többféle Xiaomi aljzatról. Az ő feladata kicsit egyszerűbb - egyszerűen csak a mai, a tegnapi és a havi fogyasztás értékét kell kiírnia. Nincsenek grafikonok szükségesek.

Hagyjuk figyelmen kívül az azonnali teljesítményértékek kézi integrálásáról való érvelést — a „pontosság” ilyen megközelítése már fentebb említve lett. Nem világos, miért nem használt felhalmozott fogyasztási értékeket, amelyekből az aljzata már gyűjt adatokat. Véleményem szerint a hardveres integrálás jobban fog működni.

A videóból átvesszük az ötletet a fogyasztás időszakonkénti kézi számításáról. A fickónál csak a mai és a tegnapi értékek számítanak, de mi továbbmegyünk, és megpróbálunk egy grafikont rajzolni. A javasolt módszer lényege az én esetemben a következő.

Létrehozunk egy változót, aminek a neve _érték_a_óra_kezdete, és ebbe rögzítjük a jelenlegi mérőállást.
A órák végén (vagy a következő óra elején) kiszámítjuk a különbséget a jelenlegi olvasat és az óra elején eltárolt érték között. Ez a különbség lesz az aktuális óra fogyasztása — elmentjük az értéket az érzékelőbe, és a jövőben ezt az értéket fogjuk grafikonon ábrázolni.
Ezen kívül "nullázni" kell a változó érték_az_óra_kezdete_változót, és bele kell írni a számláló aktuális értékét.

Mindezt a home assistant saját eszközeivel lehet lebonyolítani.

Több kódot kell írni, mint az előző megközelítésben. Először is, be kell vezetnünk ezeket a "változókat". Alapértelmezésben nincs "változó" entitásunk, de használhatjuk az mqtt broker szolgáltatásait. Az értékeket a retain=true jelzővel fogjuk küldeni — ez megőrzi az értéket a brokerben, és azt bármikor előhívhatjuk, még a home assistant újraindítása után is. Készítettem egy órás és egy napi számlálót is.

- 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

Az összes varázslat az automatizálásban zajlik, amely óránként és minden éjszaka elindul.

- 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

Mindkét automatizálás 2 műveletet végez:

  • Kiszámítják az intervallum értékét az alap és végérték közötti különbségként
  • Frissítik az alapértéket a következő intervallumhoz

A grafikonok elkészítése ebben az esetben a hagyományos history-graph segítségével valósítható meg:

      - type: history-graph
        title: 'Óránkénti vízfogyasztás változókkal'
        hours_to_show: 48
        entities:
          - sensor.water_hour

      - type: history-graph
        title: 'Napi vízfogyasztás változókkal'
        hours_to_show: 360
        entities:
          - sensor.water_day

Ez így néz ki:

Okos otthon: Víz- és villanyfogyasztási grafikonok építése a Home Assistantban

Elvileg ez már mindaz, amire szükség van. A módszer előnye, hogy az adatok egyszer keletkeznek az intervallum alatt. Tehát összesen 24 rekord lesz egy nap alatt az órás grafikonhoz.

Sajnálatos módon ez nem oldja meg a növekvő adatbázis általános problémáját. Ha havi fogyasztási grafikont szeretnék, akkor legalább egy évig kell tárolnom az adatokat. Mivel a home assistant csak egy tárolási időszakot kínál az egész adatbázisra, ez azt jelenti, hogy MINDEN adatot egy egész évig kell tárolni a rendszerben. Például egy év alatt 200 köbméter vizet fogyasztok, ami 200000 bejegyzést jelent az adatbázisban. Ha figyelembe vesszük a többi érzékelőt is, akkor a szám valóban hihetetlenül nagy lesz.

3. megközelítés

Szerencsére az okos emberek már megoldották ezt a problémát az InfluxDB adatbázis megírásával. Ez az adatbázis kifejezetten időalapú adatok tárolására van optimalizálva, és tökéletesen alkalmas különböző érzékelők értékeinek tárolására. A rendszer emellett SQL-szerű lekérdező nyelvet is biztosít, amely lehetővé teszi az adatok kinyerését és különböző módokon való aggregálását. Végül, különböző adatokat eltérő időtartamon keresztül lehet tárolni. Például a gyakran változó mérések, mint a hőmérséklet vagy a páratartalom, csak pár hétig tárolhatók, míg a napi vízfogyasztási adatok egy egész évig tárolhatók.

Az InfluxDB mellett az okos emberek feltalálták a Grafanát is — egy rendszert az InfluxDB-ből származó adatok grafikonokkal való megjelenítésére. A Grafana különböző típusú grafikonokat tud rajzolni, részletesen testre szabni őket, és ami a legfontosabb, ezeket a grafikonokat "be lehet illeszteni" a home assistant lovelace-UI-jába.

Inspirálódni itt és itt. A cikkek részletesen leírják az InfluxDB és Grafana telepítési és csatlakoztatási folyamatát a home assistant-hoz. Én a saját konkrét feladatom megoldására összpontosítok.

Tehát először kezdjük a számláló értékének tárolását az InfluxDB-ben. A home assistant konfigurációjának egy részlete (ebben a példában nemcsak hideg, hanem meleg vízzel is fogok játszani):

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

Kapcsoljuk ki az ezen adatok home assistant belső adatbázisába való mentését, hogy ne növeljük feleslegesen:

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

Mostramos agora o console do InfluxDB e configuramos nosso banco de dados. Em particular, precisamos definir quanto tempo os dados serão mantidos. Isso é regulado pela chamada retention policy — é semelhante a bancos de dados dentro do banco de dados principal, sendo que cada banco interno possui suas próprias configurações. Por padrão, todos os dados são armazenados na retention policy chamada autogen, e esses dados serão mantidos por uma semana. Eu gostaria que os dados horários fossem armazenados por um mês, os semanais por um ano e os mensais nunca fossem excluídos. Vamos criar as retention policies correspondentes.

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

Agora, na verdade, o principal truque — agregação de dados através de uma consulta contínua. Este é um mecanismo que executa automaticamente uma consulta em intervalos definidos, agrega dados com base nessa consulta e armazena o resultado em um novo valor. Vamos analisar com um exemplo (escrevo em uma coluna para melhor legibilidade, mas na verdade precisei inserir este comando em uma única linha).

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

Este comando:

  • Cria uma consulta contínua chamada cq_water_cold_hourly no banco de dados homeassistant.
  • A consulta será executada a cada hora (time(1h)).
  • A consulta irá extrair todos os dados da medida homeassistant.autogen.l (litros), incluindo as leituras de água fria e quente.
  • Os dados agregados serão agrupados por entity_id, o que nos dará valores separados para água fria e quente.
  • Como o medidor de litros é uma sequência monotonamente crescente, dentro de cada hora precisaremos pegar o valor máximo, portanto, a agregação será feita pela função max(value).
  • O novo valor será armazenado em homeassistant.month.water_meter_hour, onde month é o nome da retention policy com um período de armazenamento de um mês. Os dados de água fria e quente serão distribuídos em registros separados com o respectivo entity_id e valor no campo value.

Durante a noite ou quando não há ninguém em casa, não há consumo de água, e, portanto, não há novos registros em homeassistant.autogen.l. Para evitar lacunas nos valores nas consultas normais, pode-se usar fill(previous). Isso fará com que o InfluxDB use o valor da hora anterior.

Sajnos a folyamatos lekérdezésnek van egy sajátossága: a fill(previous) trükk nem működik, és a bejegyzések egyszerűen nem jönnek létre. Ez egyfajta leküzdhetetlen probléma, amely már nem egy éve téma.Ezzel a problémával később foglalkozunk, a fill(previous) a folyamatos lekérdezésben maradhat — nem zavar.

Nézzük meg, mi készült el (természetesen érdemes várni pár órát):

> 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

Vegye figyelembe, hogy az értékek az adatbázisban UTC-ben vannak tárolva, ezért ezen a listán 3 órával eltérnek — a 7 órás értékek az InfluxDB kimenetében a fenti grafikonok 10 órás értékeinek felelnek meg. Emellett vegye figyelembe, hogy 2 és 5 óra között egyszerűen nincsenek bejegyzések — ez a folyamatos lekérdezés sajátossága.

Ahogy látható, az aggregált érték szintén monoton növekvő sorozat, csak a bejegyzések ritkábban érkeznek — óránként. De ez nem probléma — írhatunk még egy lekérdezést, ami a megfelelő adatokat hozza el a grafikonhoz.

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)

Kifejtem:

  • Az homeassistant.month.water_meter_hour adatbázisból lekérjük az entity_id='water_meter_cold' adatokat az utolsó 24 órára (time >= now() -24h).
  • Ahogy már említettem, a homeassistant.month.water_meter_hour sorozatban hiányozhatnak egyes bejegyzések. Ezeket az adatokat újra generáljuk, ha az GROUP BY time(1h) lekérdezést futtatjuk. Ezúttal a fill(previous) úgy fog működni, ahogyan kell, generálva a hiányzó adatokat (a függvény az előző értéket fogja venni)
  • A legfontosabb dolog ebben a lekérdezésben a difference függvény, amely kiszámítja a különbséget az óránkénti jelölések között. Önmagában nem működik, és aggregáló függvényt igényel. Legyen ez a max(), amit korábban használtunk.

A végrehajtás eredménye így néz ki

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

Hajnali 2 és 5 óra között (UTC) nem volt fogyasztás. Ennek ellenére a lekérdezés ugyanazt a fogyasztási értéket fogja visszaadni a fill(previous) funkciónak köszönhetően, és a difference funkció ezt az értéket vonja ki saját magából, így a kimenet 0 lesz, ami végül is szükséges.

Most már csak annyi a teendő, hogy létrehozzuk a grafikon. Ehhez nyissuk meg a Grafanát, nyissunk meg egy létező (vagy hozzunk létre egy újat) műszerfalat, és hozzunk létre egy új panelt. A grafikon beállításai a következők lesznek.

Okos otthon: Víz- és villanyfogyasztási grafikonok építése a Home Assistantban

A hideg és a meleg víz adatait egy grafikonon fogom megjeleníteni. A lekérdezés pontosan olyan, mint ahogy fentebb leírtam.

A megjelenítési paraméterek így vannak beállítva. Ez nálam egy lépcsőzetes (stairs) vonalas grafikon lesz. A Stack paramétert lentebb fogom magyarázni. Még van néhány megjelenítési paraméter, de ezek nem annyira érdekesek.

Okos otthon: Víz- és villanyfogyasztási grafikonok építése a Home Assistantban

A beszerzett grafikont a home assistant-be így lehet hozzáadni:

  • kilépni a grafikon szerkesztési módjából. Valamiért a grafikonok megosztásának helyes beállításait csak a műszerfal oldaláról ajánlják fel.
  • Kattintson a grafikon neve mellett található háromszögre, majd a menüben válassza a share-t.
  • A megnyíló ablakban válassza az embed lapot.
  • Eltávolítani a current time range jelölőnégyzetet — az időtartamot az URL-en keresztül fogjuk beállítani.
  • Válassza ki a szükséges témát. Az én esetemben ez a light.
  • Másolja a kapott URL-t a lovelace-UI beállítási kártyába.

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

Figyeljen arra, hogy az időtartam (az utolsó 2 nap) itt van beállítva, és nem a műszerfal beállításaiban.

A grafikon így néz ki. Az utolsó 2 napban nem használtam melegvizet, ezért csak a hideg víz grafikonja látható.

Okos otthon: Víz- és villanyfogyasztási grafikonok építése a Home Assistantban

Nem döntöttem el, hogy melyik grafikon tetszik jobban, a lépcsőzetes vonal vagy a valós oszlopok. Ezért csak bemutatok egy példát a napi fogyasztás grafikonra, de ezúttal oszlopokkal. A lekérdezések hasonlóan épülnek fel, mint az előbbivel. A megjelenítési paraméterek a következők:

Okos otthon: Víz- és villanyfogyasztási grafikonok építése a Home Assistantban

Ez a grafikon így néz ki:

Okos otthon: Víz- és villanyfogyasztási grafikonok építése a Home Assistantban

Szóval, a Stack paraméterről. Ezen a grafikonon a hideg víz oszlopa a meleg víz oszlopa fölött jelenik meg. A teljes magasság a hideg és meleg víz összfogyasztását fejezi ki az időszak alatt.

Az összes bemutatott grafikon dinamikus. Az egérrel rá lehet húzni az érdekes pontra, és meg lehet nézni a részleteket és az értéket egy adott pontban.

Sajnos, egy kis keserűség nélkül nem lehetett megúszni. Az oszlopdiagramon (ellentétben a lépcsős vonaldiagrammal) az oszlop közepe nem a nap közepén van, hanem 00:00-kor. Vagyis az oszlop bal fele az előző nap helyén van. Az szombati és vasárnapi grafikonok kicsit balra vannak rajzolva, mint a kékeszöld zóna. Még nem találtam ki, hogyan lehetne ezt megoldani.

A másik probléma a hónapok közötti intervallumokkal való helyes munkavégzés lehetetlenségéből fakad. Az a helyzet, hogy az óra/nappal/hét hossza fix, míg a hónap hossza minden alkalommal más. Az InfluxDB csak az azonos intervallumokkal képes dolgozni. Jelenleg annyira elég az eszem, hogy 30 napos fix intervallumot állítsak be. Igen, a grafikon az év során kicsit el fog csúszni, és az oszlopok nem egészen pontosan fogják tükrözni a hónapokat. De mivel számomra ez a dolog csak mint bemutató szerepel, ezért elfogadom.

Két lehetséges megoldást látok:

  • Elhagyni a havi grafikonokat, és korlátozni magunkat a heti grafikonokra. Évente 52 heti oszlop már egészen jól néz ki.
  • A havi fogyasztást a második módszer szerint számolni, míg a grafanát csak a szép grafikonok használatára. Ez egy elég pontos megoldás lesz. Még a tavalyi év grafikonjait is rá lehet fektetni az összehasonlítás érdekében — a grafana ezt is tudja.

Zárás

Nem tudom, miért, de nagyon élvezem az ilyen típusú grafikonokat. Megmutatják, hogy az élet pezseg, és minden változik. Tegnap sok volt, ma kevés, holnap megint másképp lesz. Még a családtagokkal kell dolgoznom a fogyasztásról. De még a jelenlegi étvágy mellett is, egy nagy és érthetetlen szám a számlán már egy elég világos képet alkot a fogyasztásról.

Annak ellenére, hogy közel 20 éves programozói karrierem van, szinte soha nem találkoztam adatbázisokkal. Ezért a külső adatbázis telepítése valami meghökkentően és érthetetlennek tűnt. Minden megváltozott az említett cikk — kiderült, hogy a megfelelő eszköz csatlakoztatása pár kattintásból megoldható, és a szakosodott eszközzel a grafikonok építése kicsit egyszerűbbé válik.

A címben említettem az áramfogyasztást. Sajnos jelenleg nem tudok bemutatni egyetlen grafikont sem. Az SDM120 mérőm elromlott, a másik pedig problémás a Modbus kapcsolaton. Ezen kívül a cikk témájára ez nincs hatással — a grafikont ugyanúgy fogjuk felépíteni, mint a vízfogyasztási adatok esetében.

Ebben a cikkben azokat a megközelítéseket mutattam be, amelyeket magam is kipróbáltam. Bizonyára léteznek más módszerek az adatok gyűjtésére és vizualizálására, amikről nem tudok. Kérlek, meséljetek nekem erről a megjegyzésekben, nagyon érdekelne. Örömmel fogadom a konstruktív kritikát és az új ötleteket. Remélem, hogy a bemutatott anyag másoknak is segítséget nyújt.

Forrás: habr.com

Megbízható hosting vásárlása weboldalak számára, DDoS védelemmel, VPS VDS szerverek. 🔥 Megbízható webtárhely vásárlása DDoS védelemmel, VPS VDS szerverek | ProHoster