
Každý raz, keď dostanem účet za elektrinu a vodu, sa čudujem – naozaj moja rodina spotrebúva toľko? No áno, v kúpeľni je nainštalované podlahové kúrenie a bojler, ale veru nespália energie neustále. Vodu tiež akosi šetríme (hoci aj v kúpeľni si radi zaplávame). Pred niekoľkými rokmi som už a k inteligentnej domácnosti, ale tým sa to skončilo. K analýze spotreby som sa dostal až teraz, o čom vlastne je tento článok.
Nedávno som prešiel na Home Assistant ako systém inteligentnej domácnosti. Jedným z dôvodov bola práve možnosť organizovať zber veľkého množstva údajov s možnosťou pohodlného vytvárania rôznych druhov grafov.
Informácie opísané v tomto článku nie sú nové, všetky tieto veci už boli opisované na internete pod rôznymi zámienkami. Ale každý článok spravidla opisuje iba jeden prístup alebo aspekt. Porovnať všetky tieto prístupy a vybrať ten najvhodnejší som musel sám. Článok aj tak nedáva vyčerpávajúce informácie o zbieraní údajov, ale je akýmsi prehľadom toho, ako som to robil ja. Takže konstruktívna kritika a návrhy na zlepšenie sú vítané.
Stanovenie úlohy
A teda, cieľom dnešného cvičenia je získať pekné grafy spotreby vody a elektriny:
- Hodinový za 2 dni
- Denný za 2 týždne
- (voliteľne) týždenný a mesačný
V tom nás čakajú isté obtiaže:
- Štandardné komponenty grafov sú spravidla pomerne slabé. V tom najlepšom prípade je možné zostaviť lineárny graf podľa bodov.
Ak sa dobre hľadá, dá sa nájsť aj externé komponenty, ktoré rozširujú možnosti štandardného grafu. Pre Home Assistant je v podstate dobrý a pekný komponent , ale aj ten má niektoré obmedzenia:
- Je ťažké nastaviť parametre stĺpcového grafu na veľkých intervaloch (šírka stĺpca sa nastavuje v zlomkoch hodiny, takže intervaly dlhšie ako hodina sa budú nastavovať zlomkovými číslami)
- Nie je možné na jeden graf pridať rôzne entity (napríklad teplotu a vlhkosť, alebo skombinovať stĺpcový graf s čiarovým)
- Nielen, že home assistant predvolene používa najprimitívnejšiu databázu SQLite (a ja, zručný, som nezvládol inštaláciu MySQL alebo Postgres), ale aj dáta sú uložené najmenej optimálnym spôsobom. Napríklad pri každej zmene každého, aj toho najmenšieho digitálneho parametra, sa do databázy zapisuje obrovský json o veľkosti okolo jedného 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 pomerne veľa senzorov (teplotné senzory v každej miestnosti, meracie prístroje na vodu a elektrinu), a niektoré navyše generujú dosť veľa údajov. Napríklad iba merací prístroj elektriny SDM220 generuje približne desiatku hodnôt každých 10-15 sekúnd, a takých prístrojov by som chcel nainštalovať asi 8. A ešte je tu celá sada parametrov, ktoré sú počítané na základe iných senzorov. Tým pádom všetky tieto hodnoty môžu ľahko zväčšiť databázu o 100-200 MB denne. Po týždni bude systém ťažko fungovať a po mesiaci sa pamäťová karta (v prípade typickej inštalácie home assistant na raspberry PI) zhorší, a o uchovaní údajov po celý rok nemôže byť reč.
- Ak máte šťastie, váš merací prístroj vie sám počítať spotrebu. Kedykoľvek sa môžete obrátiť na merací prístroj a opýtať sa, aká je nahromadená hodnota spotreby. Zvyčajne všetky meracie prístroje na elektrinu, ktoré majú digitálne rozhranie (RS232/RS485/Modbus/Zigbee), poskytujú takúto možnosť.
Horšie je, ak zariadenie môže merať len nejaký okamžitý parameter (napríklad okamžitý výkon alebo prúd), alebo jednoducho generovať impulzy každých X watthodín alebo litrov. Potom je potrebné premýšľať, ako a čím to integrovať a kde uchovávať hodnotu. Existuje riziko, že zmeškáte ďalšiu správu z akéhokoľvek dôvodu a presnosť systému ako celku vyvoláva otázky. Môžete to samozrejme všetko zveriť systému inteligentnej domácnosti ako je home assistant, ale bod o počte záznamov v databáze nikto nezrušil, a ani dotazovanie senzorov častejšie ako raz za sekundu nie je možné (obmedzenie architektúry home assistant).
Prístup 1
Najprv sa pozrieme, čo poskytuje home assistant priamo z krabice. Meranie spotreby za obdobie je veľmi žiadaná funkcia. Samozrejme, už dávno ju implementovali vo forme špecializovanej súčasti — utility_meter.
Podstata súčasti spočíva v tom, že vo vnútri udržuje premennú aktuálne_nakumulované_hodnota a nulová ju po uplynutí zadaného obdobia (hodina/týždň/mesiac). Súčasť sama monitoruje vstupnú premennú (hodnotu nejakého senzora) a sama sa prihlasuje na zmeny hodnoty — vy jednoducho dostávate hotový výsledok. Táto funkcia sa popisuje len niekoľkými riadkami v konfiguračnom súbore.
utility_meter:
water_cold_hour_um:
source: sensor.water_meter_cold
cycle: hourly
water_cold_day_um:
source: sensor.water_meter_cold
cycle: daily
Tu sensor.water_meter_cold je aktuálna hodnota merača v litroch, ktorú získavam cez mqtt. Konštrukcia vytvára 2 nové senzory water_cold_hour_um a water_cold_day_um, ktoré akumulujú hodinové a denné ukazovatele a nulujú ich po uplynutí obdobia. Tu je graf hodinového akumulátora za pol dňa.

Kód hodinových a denných grafov pre lovelace-UI vyzerá takto:
- type: history-graph
title: 'Hodinová spotreba vody pomocou premenných'
hours_to_show: 48
entities:
- sensor.water_hour
- type: history-graph
title: 'Denná spotreba vody pomocou premenných'
hours_to_show: 360
entities:
- sensor.water_day
Problém tohto prístupu spočíva práve v tomto algoritmoch. Ako som už spomenul, pre každú vstupnú hodnotu (aktuálny údaj merača na každý ďalší liter) sa generuje 1 kB záznamu v databáze. Každý utility meter tiež generuje nové hodnoty, ktoré sa taktiež ukladajú do databázy. Ak chcem zbierať hodinové/deňné/týždenné/mesačné údaje, a to pre niekoľko stúpačiek vody, a ešte pridať nejaké elektromery — to bude veľmi veľa údajov. Presnejšie, tých údajov nebude veľa, ale pretože home assistant zapisuje do databázy množstvo zbytočných informácií, veľkosť databázy bude rásť ako po kvasení. Bojím sa aj len odhadovať veľkosť databázy pre týždenné a mesačné grafy.
Okrem toho utility meter sám osebe nerieši danú úlohu. Graf hodnôt, ktoré utility meter poskytuje, je monotónne rastúca funkcia, ktorá sa každú hodinu resetuje na 0. Potrebujeme prehľadný graf pre používateľa, ktorý ukazuje, koľko litrov bolo spotrebovaných v danom období. Štandardná súčasť history-graph to nedokáže, ale s externou súčasťou mini-graph-card nám môže pomôcť.
Toto je kód karty pre 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á spotreba vody agregovaná podľa utility meter"
points_per_hour: 1
show:
graph: bar
type: 'custom:mini-graph-card'Okrem štandardných nastavení ako je názov senzora, typ grafu, farba (štandardná oranžová sa mi nepáčila), je dôležité zdôrazniť 3 nastavenia:
- group_by:hour — graf bude generovaný so zarovnaním stĺpcov na začiatku hodiny
- points_per_hour: 1 — jeden stĺpec na každú hodinu
- A najdôležitejšie, aggregate_func: max — získať maximálnu hodnotu v rámci každej hodiny. Tento parameter premení zubato-krivkový graf na stĺpce.

Na niektoré stĺpce naľavo si nevšímajte — to je štandardné správanie komponentu, ak nie sú žiadne údaje. A údajov skutočne nebolo — len pred pár hodinami som zapol zbieranie údajov prostredníctvom utility meter len pre tento článok (svoj aktuálny prístup opíšem o niečo neskôr).
Na tomto obrázku som chcel ukázať, že niekedy zobrazenie údajov skutočne funguje a stĺpce naozaj odrážajú správne hodnoty. Lenže nie všetky. Vyzdvihnutý stĺpec za časový úsek od 11 do 12 hodiny ráno zobrazuje 19 litrov, hoci na zubatom grafe trošku vyššie za ten istý časový úsek z toho istého senzora vidíme spotrebu 62 litrov. Buď chyba, alebo nesprávne nastavenia. A zatiaľ som nepochopil, prečo sú údaje na pravej strane zlomené — spotreba tam bola normálna, čo je takisto viditeľné na zubatom grafe.
Celkovo sa mi na tomto prístupe nepodarilo dosiahnuť presvedčivosť — graf takmer vždy zobrazuje niečo nesprávne.
Analogický kód pre 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á agregovaná spotreba vody podľa merača"
points_per_hour: 0.0416666666
show:
graph: bar
type: 'custom:mini-graph-card'
Všimnite si, že parameter group_by je nastavený na hodnotu interval, a ovláda všetky parametre points_per_hour. A tu nastáva ďalší problém tohto komponentu — points_per_hour dobre funguje na grafoch za hodinu alebo menej, ale zle na väčších časových úsekoch. Tak aby som získal jeden stĺpec za jeden deň, musel som zadať hodnotu 1/24=0.04166666. O týždňových a mesačných grafoch ani nevravím.
Prístup 2
Ešte len sa zaoberám s home assistant a narazil som na toto video:

Kamarát zbiera údaje spotreby z viacerých typov zásuviek Xiaomi. Jeho úloha je o čosi jednoduchšia — jednoducho zobrazovať hodnotu spotreby za dnes, včera a za mesiac. Žiadne grafy nie sú potrebné.
Nechajme na strane úvahy o ručnom integrácii okamžitých hodnôt výkonu — o "presnosti" takého prístupu som už písal vyššie. Nie je jasné, prečo nezačal používať akumulované hodnoty spotreby, ktoré sú už zhromažďované tou istou zásuvkou. Podľa môjho názoru bude integrácia vo vnútri zariadenia fungovať lepšie.
Z videa preberieme nápad ručného počítania spotreby za obdobie. U frajera sa počítajú len hodnoty za dnes a za včera, ale my pôjdeme ďalej a pokúsime sa nakresliť graf. Podstata navrhnutého metódu v mojom prípade spočíva v nasledujúcom.
Zavedeme premennú hodnota_na_zaciatku_hodiny, do ktorej zapíšeme aktuálne údaje merača
Na konci hodiny (alebo na začiatku nasledujúcej) spočítame rozdiel medzi aktuálnym zobrazením a zapamätaným na začiatku hodiny. Tento rozdiel bude spotrebou za aktuálnu hodinu — uložíme hodnotu do senzora a v budúcnosti budeme na základe tejto hodnoty vytvárať graf.
Tiež je potrebné "resetovať" premennú hodnota_na_zaciatku_hodiny zapísaním aktuálnej hodnoty čítača.
Toto všetko je možné urobiť prostredníctvom samého home assistant.
Kódu bude treba napísať o čosi viac ako v predchádzajúcom prístupe. Na začiatok si vytvoríme tieto "premenné". Z krabice nemáme entitu "premenná", ale môžeme využiť služby mqtt brokera. Budeme tam posielať hodnoty s príkazom retain=true — to uloží hodnotu v brokeroch a bude ju možné kedykoľvek vytiahnuť, aj po reštarte home assistant. Hneď som vytvoril hodinové a denné počítadlá.
- 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: lCelá mágia prebieha v automatizácii, ktorá sa spúšťa každý hodinu a každú 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: trueObe automatizácie vykonávajú 2 činy:
- Vypočítavajú hodnotu za interval ako rozdiel medzi počiatočnou a konečnou hodnotou
- Aktualizujú základnú hodnotu pre nasledujúci interval
Vytváranie grafov sa v tomto prípade rieši bežným history-graph:
- type: history-graph
title: 'Hodinová spotreba vody pomocou premenných'
hours_to_show: 48
entities:
- sensor.water_hour
- type: history-graph
title: 'Denná spotreba vody pomocou premenných'
hours_to_show: 360
entities:
- sensor.water_dayVyzerá to takto:

V podstate je to už to, čo potrebujeme. Výhodou tejto metódy je, že údaje sa generujú len raz za interval. T.j. celkovo 24 záznamov za deň pre hodinový graf.
Žiaľ, tento všeobecný problém rastúcej databázy to stále nerieši. Ak chcem mesiacový graf spotreby, budem musieť uchovávať údaje aspoň za rok. A keďže home assistant poskytuje iba jedno nastavenie trvania uchovávania pre celú databázu, znamená to, že VŠETKY údaje v systéme budem musieť uchovávať celý rok. Napríklad za rok spotrebujem 200 kubických metrov vody, čo predstavuje 200000 záznamov v databáze. A ak zohľadním aj ďalšie senzory, číslo sa stáva naozaj neúmerným.
Prístup 3
Našťastie, múdri ľudia už tento problém vyriešili napísaním databázy InfluxDB. Táto databáza je špeciálne optimalizovaná na uchovávanie dát založených na čase a ideálne sa hodí na uchovávanie hodnôt rôznych senzorov. Systém taktiež poskytuje jazyk dotazov podobný SQL, ktorý umožňuje získavanie hodnôt z databázy a ich agregovanie rôznymi spôsobmi. Nakoniec, rôzne údaje môžu byť uchovávané rôznu dobu. Napríklad, často sa meniacie hodnoty ako teplota alebo vlhkosť môžu byť uchovávané iba pár týždňov, zatiaľ čo denné hodnoty spotreby vody môžu byť uchovávané celý rok.
Okrem InfluxDB múdri ľudia vynalezli aj Grafanu — systém na kreslenie grafov na základe dát z InfluxDB. Grafana dokáže kresliť rôzne typy grafov, podrobne ich prispôsobovať a, čo je najdôležitejšie, tieto grafy je možné „zasunúť“ do lovelace-UI home assistantu.
Inšpirovať sa a . V článkoch je podrobne popísaný proces inštalácie a pripojenia InfluxDB a Grafany k home assistantu. Ja sa však zameriam na riešenie svojej konkrétnej úlohy.
Takže, najskôr začneme ukladať hodnotu počítadla do InfluxDB. Kúsok konfigurácie home assistantu (v tomto príklade sa budem zabávať nielen s chladnou, ale aj teplou vodou):
influxdb:
host: localhost
max_retries: 3
default_measurement: state
database: homeassistant
include:
entities:
- sensor.water_meter_hot
- sensor.water_meter_coldVypneme uchovávanie týchto istých údajov v internej databáze home assistant, aby sme ju zbytočne nenafukovali:
recorder:
purge_keep_days: 10
purge_interval: 1
exclude:
entities:
- sensor.water_meter_hot
- sensor.water_meter_coldPrejdime teraz do konzoly InfluxDB a nastavme našu databázu. Konkrétne je potrebné nastaviť, ako dlho budú uchovávané konkrétne dáta. To sa reguluje tzv. retention policy — to je podobné databázam v rámci hlavnej databázy, pričom každá vnútorná databáza má svoje vlastné nastavenia. Predvolene sa všetky dáta ukladajú do retention policy s názvom autogen, tieto dáta budú uchovávané týždeň. Chcel by som, aby sa hodinové dáta uchovávali mesiac, týždenné — rok a mesačné sa nikdy neodstraňovali. Vytvorme zodpovedajúce 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 1Teraz, vlastne, hlavný trik — agregácia dát pomocou continuous query. Je to mechanizmus, ktorý automaticky spúšťa dotaz v zadaných intervaloch, agreguje dáta podľa tohto dotazu a výsledok ukladá do novej hodnoty. Prejdeme si to na príklade (píšem do stĺpca pre lepšiu čitateľnosť, ale v skutočnosti som túto príkaz zadával v jednej línii).
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)
ENDTento príkaz:
- Vytvára continuous query s názvom cq_water_cold_hourly v databáze homeassistant.
- Dotaz sa bude vykonávať každú hodinu (time(1h)).
- Dotaz vyberá všetky dáta z measurementu homeassistant.autogen.l (litre), vrátane ukazovateľov studenej a teplej vody.
- Agregované dáta sa budú skupinovať podľa entity_id, čo nám vytvorí samostatné hodnoty pre studenú a teplú vodu.
- Keďže merač litrov je monotónne rastúca sekvencia, v rámci každého zariadenia je potrebné brať maximálnu hodnotu, preto sa agregácia vykoná funkciou max(value).
- Nová hodnota sa zapíše do homeassistant.month.water_meter_hour, kde month je názov retention policy so skladovaním na mesiac. Navyše, dáta o studenej a teplej vode budú rozdelené do samostatných záznamov s príslušným entity_id a hodnotou v poli value.
V noci alebo keď nie je nikto doma, spotreba vody nie je, a teda v homeassistant.autogen.l tiež nie sú nové záznamy. Aby nedochádzalo k prázdnym hodnotám v bežných dotazoch, môžeme použiť fill(previous). To prinúti InfluxDB použiť hodnotu z predchádzajúcej hodiny.
Žiaľ, existuje zvláštnosť v kontinuálnych dopytoch: trik fill(previous) nefunguje a záznamy sa jednoducho nevytvárajú. Ide o neprekonateľný problém, ktorý S týmto problémom sa neskôr zaoberíme, kým necháme fill(previous) v kontinuálnom dopyte — neprekáža to.
Skontrolujeme, čo sme získali (samozrejme, musíme počkať pár hodín):
> 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šimnite si, že hodnoty v databáze sa ukladajú v UTC, takže v tomto zozname sa líšia o 3 hodiny — hodnoty za 7 hodín ráno vo výstupe InfluxDB zodpovedajú hodnotám za 10 hodín ráno na grafoch vyššie. Tiež si všimnite, že medzi 2 a 5 hodinou ráno nie sú žiadne záznamy — to je tá zvláštnosť kontinuálneho dopytu.
Ako vidíte, agregovaná hodnota je tiež monotónne rastúca sekvencia, len záznamy sa vytvárajú menej často — raz za hodinu. Ale to nie je problém — môžeme napísať ďalší dopyt, ktorý získa správne údaje pre 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)Rozlúštim:
- Z databázy homeassistant.month.water_meter_hour získame údaje pre entity_id='water_meter_cold' za posledných 24 hodín (time >= now() -24h).
- Ako som už spomenul, v sekvencii homeassistant.month.water_meter_hour môžu chýbať niektoré záznamy. Tieto údaje znovu vygenerujeme spustením dopytu s GROUP BY time(1h). Tentokrát fill(previous) bude fungovať ako sa patrí a vygeneruje chýbajúce údaje (funkcia vezme predchádzajúcu hodnotu).
- Najdôležitejšia časť tohoto dopytu je funkcia difference, ktorá spočíta rozdiel medzi hodinovými časovými značkami. Sama o sebe nefunguje a potrebujú agregujúcu funkciu. Nech je to max() použitá predtým.
Výsledok vykonania vyzerá 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 72Od 2 do 5 ráno (UTC) nebolo žiadne spotreba. Napriek tomu sa požiadavka vráti s rovnakou hodnotou spotreby vďaka fill(previous), a funkcia difference túto hodnotu odčíta sama od seba, takže na výstupe získame 0, čo vlastne potrebujeme.
Zostáva už len malá vec — postaviť graf. Na to otvoríme Grafanu, otvoríme nejaký existujúci (alebo vytvoríme nový) dashboard, a vytvoríme novú panely. Nastavenia grafov budú takéto.

Budeme zobrazovať dáta o studenej a teplej vode na jednom grafe. Dotaz je presne taký, ako som opísal vyššie.
Parametre zobrazenia sa nastavujú takto. U mňa to bude graf s čiarami (lines), ktorý ide stupňovito (stairs). Parameter Stack vysvetlím o chvíľu. Nižšie sú ešte ďalšie dva parametre zobrazenia, ale nie sú tak zaujímavé.

Aby sme pridali získaný graf do domácich asistentov, potrebujeme:
- vystúpiť z režimu úprav grafu. Z nejakého dôvodu sa správne nastavenia zdieľania grafov ponúkajú iba zo stránky dashboardu.
- Kliknúť na trojuholník vedľa názvu grafu, v menu vybrať share.
- V otvorenom okne prejsť na kartu embed.
- Odstrániť zaškrtnutie current time range — časový rozsah budeme zadávať cez URL.
- Vybrať potrebnú tému. V mojom prípade je to light.
- Skopírovať získaný 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šimnite si, že časový rozsah (posledné 2 dni) sa nastavuje práve tu, a nie v nastaveniach dashboardu.
Graf vyzerá takto. Teplú vodu som za posledné 2 dni nepoužíval, preto sa vykresľuje len graf studenej vody.

Tak som si nie úplne vyjasnil, ktorý graf sa mi viac páči, či stupňový, alebo skutočné stĺpce. Preto jednoducho uvediem príklad denného grafu spotreby, len tentoraz so stĺpcami. Dotazy sa zostavujú podobne ako vyššie uvedené. Parametre zobrazenia sú takéto:

Tento graf vyzerá takto:

Takto k parametru Stack. V tomto grafe je stĺpec studenej vody vykreslený nad stĺpcom teplej vody. Celková výška zodpovedá súhrnnej spotrebe studenej a teplej vody za dané obdobie.
Všetky zobrazené grafy sú dynamické. Môžete na ne nechať kurzor nad záujmovým bodom a pozrieť sa na detaily a hodnotu v konkrétnom bode.
Bohužiaľ, bez pár lyžičiek dechtu sa to nezaobišlo. Na stĺpcovom grafe (na rozdiel od grafu s krokovými čiarami) sa stred stĺpca nenachádza uprostred dňa, ale v 00:00. T.j. ľavá polovica stĺpca je zakreslená na mieste predchádzajúceho dňa. Takže grafy za sobotu a nedeľu sú zakreslené trocha viac doľava ako modrastá zóna. Zatiaľ som nevymyslel, ako to prekonať.
Ďalším problémom je nemožnosť správne pracovať s mesačnými intervalmi. Faktom je, že dĺžka hodiny/deňa/týždňa je fixná, ale dĺžka mesiaca je zakaždým iná. InfluxDB dokáže pracovať iba s rovnakými intervalmi. Zatiaľ mi stačili mozgové kapacity na to, aby som nastavil fixný interval na 30 dní. Áno, graf sa v priebehu roka trocha posunie a stĺpce nebudú presne zodpovedať mesiacom. Ale pretože ma táto vec zaujíma len ako ukazovateľ, tak mi to neprekáža.
Riešení vidím aspoň dve:
- Ignorovať mesačné grafy a obmedziť sa na týždenné. 52 týždenných stĺpcov za rok vyzerá celkom dobre.
- Samotnú mesačnú spotrebu počítať spôsobom č. 2 a Grafanu používať len na pekné grafy. Vyjde nám celkom presné riešenie. Môžeme dokonca superponovať grafy za minulý rok na porovnanie — Grafana to tiež zvláda.
Záver
Neviem prečo, ale ťahá ma to k takýmto grafom. Ukazujú, že život sa hemží a všetko sa mení. Včera bolo veľa, dnes málo, zajtra to bude akosi inak. Ešte treba pracovať s domácimi ohľadom spotreby. Ale aj pri súčasných apetítach sa z veľkého a nejasného čísla na faktúre stáva celkom zrozumiteľný obraz spotreby.
Napriek takmer 20-ročnej kariére programátora som sa s databázami prakticky nestretol. Preto sa mi inštalácia externej databázy zdala ako niečo zložitá a nepochopiteľné. Všetko zmenila — ukázalo sa, že pripojenie vhodného nástroja sa robí v pár kliknutiach, a so špecializovaným nástrojom je úloha budovania grafov o niečo jednoduchšia.
V nadpise som spomenul spotrebu elektriny. Žiaľ, momentálne nemám k dispozícii žiadny graf. Jeden merací prístroj SDM120 mi prestal fungovať a druhý má problémy pri prístupe cez Modbus. Na tému tohto článku to však nijako nemá vplyv — grafy sa budú vytvárať rovnakým spôsobom ako pre vodu.
V tomto článku som uviedol prístupy, ktoré som sám vyskúšal. Určite existujú aj iné spôsoby organizácie zberu a vizualizácie dát, o ktorých neviem. Povedzte mi o tom v komentároch, veľmi ma to zaujíma. Budem rád za konštruktívnu kritiku a nové nápady. Dúfam, že vypracovaný materiál tiež niekomu pomôže.
Zdroj: habr.com
