Casă inteligentă: Construim graficele consumului de apă și electricitate în Home Assistant

Casă inteligentă: Construim graficele consumului de apă și electricitate în Home Assistant
De fiecare dată când primesc factura pentru electricitate și apă, mă mir — oare familia mea consumă atât de mult? Da, în baie am instalat un sistem de încălzire prin pardoseală și un boiler, dar acestea nu funcționează constant. Se pare că și economisim apă (deși ne plac băile relaxante). Acum câțiva ani, am conectat contoarele de apă și electricitate la casa inteligentă, dar de atunci nu am avansat mai departe. Analiza consumului mi-a venit în minte abia acum, ceea ce reprezintă, de fapt, subiectul acestui articol.

Recent, am trecut la Home Assistant ca sistem de casă inteligentă. Una dintre motive a fost exact posibilitatea de a organiza colectarea unei cantități mari de date, cu opțiunea de a crea diverse tipuri de grafice.

Informațiile descrise în acest articol nu sunt noi, aceste concepte au fost deja prezentate online sub diverse forme. Dar fiecare articol descrie, de obicei, doar o abordare sau un aspect. A trebuit să compar toate aceste abordări și să aleg pe cea mai potrivită. Articolul nu oferă o informație completă despre colectarea datelor, dar reprezintă o sinteză a modului în care am procedat eu. Deci, critica constructivă și sugestiile de îmbunătățire sunt binevenite.

Formularea problemei

Deci, scopul exercițiului de astăzi este de a obține grafice frumoase pentru consumul de apă și electricitate:

  • Pe ore pentru 2 zile
  • Pe zile pentru 2 săptămâni
  • (opțional) pe săptămâni și pe luni

În această demers, ne așteaptă câteva dificultăți:

  • Componentele standard ale graficelor sunt, de obicei, destul de limitate. În cel mai bun caz, se poate construi un grafic liniar pe puncte.

    Dacă cauți bine, poți găsi componente terțe care extind capacitățile graficului standard. Pentru home assistant, componentul mini-graph-card, este decent și frumos, dar și acesta are unele limitări:

    • Este dificil să setezi parametrii pentru graficele cu bare pe intervale mari (lățimea barei este setată în fracțiuni de oră, astfel că intervalele mai lungi de o oră vor fi exprimate prin numere fracționare)
    • Nu poți adăuga diferite entități pe un singur grafic (de exemplu, temperatura și umiditatea, sau să îmbini un grafic cu bare cu unul liniar)
  • Nu doar că home assistant folosește în mod implicit cea mai primitivă bază de date SQLite (iar eu, neîndemânatic, nu am reușit să instalez MySQL sau Postgres), dar datele sunt stocate într-un mod nu tocmai optim. De exemplu, la fiecare modificare a oricărui parametru digital, indiferent cât de mic ar fi, se scrie în bază un json uriaș de aproximativ un kilobyte.
    {"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}}}

    Am destul de multe senzori (senzori de temperatură în fiecare cameră, contoare de apă și electricitate), iar unii dintre aceștia generează destul de multe date. De exemplu, contorul de electricitate SDM220 generează aproximativ zece valori la fiecare 10-15 secunde, iar eu aș dori să instalez vreo 8 astfel de contoare. Și mai sunt o mulțime de parametri care sunt calculați pe baza altor senzori. Astfel, toate aceste valori pot duce la o creștere a bazei cu 100-200 MB zilnic. După o săptămână, sistemul va funcționa cu dificultate, iar după o lună, flash-ul se va strica (în cazul unei instalări tipice home assistant pe Raspberry PI), iar despre stocarea datelor timp de un an nu poate fi vorba.

  • Dacă ai noroc, contorul tău poate să își numere singur consumul. Poți oricând să te adresezi contorului și să întrebi care este valoarea acumulată a consumului. De obicei, toate contoarele de electricitate care au o interfață digitală (RS232/RS485/Modbus/Zigbee) oferă această posibilitate.

    Mai rău este dacă dispozitivul poate măsura doar un anumit parametru instantaneu (de exemplu, puterea instantanee sau curentul) sau pur și simplu generează impulsuri la fiecare X watt-oră sau litri. Atunci trebuie să ne gândim cum și cu ce să integrăm aceste date și unde să acumulăm valoarea. Există riscul de a pierde o raportare din diverse motive, iar precizia sistemului, în ansamblu, ridică întrebări. Desigur, toate acestea pot fi delegate unui sistem de automatizare a locuinței, precum home assistant, dar aspectul legat de cantitatea de înregistrări în baza de date nu poate fi ignorat, iar interogarea senzorilor mai des decât o dată pe secundă nu este posibilă (din cauza limitărilor arhitecturii home assistant).

Abordare 1

În primul rând, să vedem ce oferă home assistant din cutie. Măsurarea consumului pe o anumită perioadă este o funcționalitate foarte solicitată. Desigur, aceasta a fost implementată de mult timp sub forma unui component specializat – utility_meter.

Esenta componentului constă în faptul că acesta creează o variabilă numită current_accumulated_value, și o resetează la sfârșitul unei perioade stabilite (oră/săptămână/lună). Componentul monitorizează singur variabila de intrare (valoarea unui senzor anume), se abonează la modificările de valoare – iar tu obții rezultatul final fără alte intervenții. Această funcționalitate poate fi descrisă în doar câteva linii în fișierul de configurare.

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

Aici, sensor.water_meter_cold reprezintă valoarea curentă a contorului în litri, pe care o primesc direct de la dispozitiv prin mqtt. Structura creează 2 senzori noi, water_cold_hour_um și water_cold_day_um, care acumulează citirile pe oră și pe zi, resetându-le la sfârșitul perioadei. Iată un grafic al acumulării pe oră pentru o jumătate de zi.

Casă inteligentă: Construim graficele consumului de apă și electricitate în Home Assistant

Codul pentru graficul orar și zilnic pentru lovelace-UI arată astfel:

      - type: history-graph
        title: 'Consum orar de apă folosind variabile'
        hours_to_show: 48
        entities:
          - sensor.water_hour

      - type: history-graph
        title: 'Consum zilnic de apă folosind variabile'
        hours_to_show: 360
        entities:
          - sensor.water_day

În acest algoritm se află, de fapt, problema acestui tip de abordare. Așa cum am menționat, pentru fiecare valoare de intrare (citirea curentă a contorului pentru fiecare litru următor) se generează câte 1kB de înregistrare în bază. Fiecare utility meter generează, de asemenea, o nouă valoare, care se adaugă în bază. Dacă vreau să colectez citiri orare/zonale/săptămânale/lunare, și pentru câteva coloane de apă, și să adaug încă un pachet de contoare de electricitate — vor fi foarte multe date. De fapt, datele nu sunt multe, dar fiindcă home assistant scrie o mulțime de informații inutile în bază, dimensiunea bazei va crește rapid. Mă tem să estimez dimensiunea bazei pentru graficele săptămânale și lunare.

În plus, utility meter-ul în sine nu rezolvă problema pusă. Graficele valorilor pe care le oferă utility meter sunt o funcție monoton crescătoare, care resetează la 0 în fiecare oră. Avem nevoie de un grafic care să fie ușor de înțeles pentru utilizator, care să arate câte litri au fost consumați pe o anumită perioadă. Componenta standard history-graph nu poate face asta, dar ne poate ajuta o componentă externă mini-graph-card.

Acesta este codul pentru cardul lovelace-UI:

      - aggregate_func: max
        entities:
          - color: var(--primary-color)
            entity: sensor.water_cold_hour_um
        group_by: hour
        hours_to_show: 48
        name: "Consum de apă pe oră agregat de utility meter"
        points_per_hour: 1
        show:
          graph: bar
        type: 'custom:mini-graph-card'

Pe lângă setările standard, cum ar fi numele senzorului, tipul graficului, culoarea (portocaliul standard nu mi-a plăcut), este important să menționez 3 setări:

  • group_by:hour — graficul va fi generat cu alinierea coloanelor la începutul fiecărei ore
  • points_per_hour: 1 — o coloană pentru fiecare oră
  • Și cel mai important, aggregate_func: max — se va lua valoarea maximă în cadrul fiecărei ore. Acest parametru transformă graficul în formă de dinte de ferăstrău în coloane

Casă inteligentă: Construim graficele consumului de apă și electricitate în Home Assistant

Ignorați coloanele din stânga — acesta este comportamentul standard al componentei dacă nu există date. Și nu au fost date — abia acum câteva ore am activat colectarea datelor prin utility meter doar pentru acest articol (metoda mea actuală o voi prezenta puțin mai jos).

În această imagine am vrut să arăt că, uneori, afișarea datelor chiar funcționează, iar coloanele reflectă cu adevărat valorile corecte. Doar că nu toate. Coloana evidențiată pentru intervalul dintre 11 și 12 dimineața arată inexplicabil 19 litri, în timp ce pe graficul dentat puțin mai sus, pentru aceeași perioadă și de la același senzor, vedem un consum de 62 de litri. Fie este un bug, fie oamenii nu știu ce fac. Însă nu am înțeles de ce datele de pe dreapta au fost deranjate — consumul acolo a fost normal, lucru vizibil și pe graficul dentat.

În general, nu am reușit să obțin credibilitate cu această abordare — graficul arată aproape întotdeauna o nebunie.

Cod similar pentru senzorul zilnic.

      - aggregate_func: max
        entities:
          - color: var(--primary-color)
            entity: sensor.water_cold_day_um
        group_by: interval
        hours_to_show: 360
        name: "Consum zilnic de apă agregat pe metru de utilitate"
        points_per_hour: 0.0416666666
        show:
          graph: bar
        type: 'custom:mini-graph-card'

Rețineți că parametrul group_by este setat pe interval, iar parametrul points_per_hour controlează totul. Și aici se află o altă problemă a acestui component — points_per_hour funcționează bine pe grafice de o oră sau mai puțin, dar funcționează prost pe intervale mai mari. Astfel, pentru a obține o coloană pentru o zi, a trebuit să inscriu valoarea 1/24=0.0416666. Nu mai vorbesc despre graficele săptămânale și lunare.

Abordarea 2

Încă explorând Home Assistant, am dat peste acest videoclip:

Redați video

Camaradul adună date de consum de la mai multe tipuri de prize Xiaomi. Sarcina lui este ceva mai simplă — doar să afișeze valoarea consumului pentru astăzi, ieri și pentru o lună. Niciun grafic nu este necesar.

Să lăsăm deoparte discuțiile despre integrarea manuală a valorilor instantanee de putere — despre „precizia” acestui abordări am scris deja mai sus. Nu este clar de ce nu a ales să folosească valorile de consum acumulate, care sunt deja colectate de aceeași priză. În opinia mea, integrarea în interiorul echipamentului va funcționa mai bine.

Din videoclip vom prelua ideea de a calcula manual consumul pe o perioadă. Omul calculează doar valorile pentru astăzi și ieri, dar noi vom merge mai departe și vom încerca să desenăm un grafic. Esența metodei propuse în cazul meu este următoarea.

Vom crea o variabilă numită valoare_la_inceputul_orelei, în care vom înregistra valorile curente ale contorului.
La sfârșitul orei (sau la începutul orei următoare), vom calcula diferența dintre citirea curentă și cea memorată la începutul orei. Această diferență va reprezenta consumul pentru ora curentă — vom salva valoarea într-un senzor, iar în viitor, vom construi un grafic pe baza acestei valori.
De asemenea, trebuie să „resetăm” variabila valoare_la_început_ore, stocând acolo valoarea curentă a contorului.

Toate acestea pot fi realizate prin intermediul… mijloacelor Home Assistant.

Vor fi necesare câteva linii mai multe de cod decât în abordarea anterioară. La început, vom crea aceste „variabile”. În mod implicit, nu avem entitatea „variabilă”, dar putem folosi serviciile brokerului MQTT. Vom trimite acolo valori cu flagul retain=true — aceasta va păstra valoarea în broker și poate fi preluată oricând, chiar și după o repornire a Home Assistant. Am realizat în mod direct contoare orare și zilnice.

- 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

Toată magia se desfășoară în automatizări, care se activează la fiecare oră și în fiecare noapte, respectiv.

- 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

Ambele automatizări efectuează 2 acțiuni:

  • Calculul valorii pentru interval ca diferență între valoarea inițială și cea finală
  • Actualizează valoarea de bază pentru intervalul următor

Construirea graficelor în acest caz se rezolvă prin history-graph obișnuit:

      - type: history-graph
        title: 'Consum orar de apă folosind variabile'
        hours_to_show: 48
        entities:
          - sensor.water_hour

      - type: history-graph
        title: 'Consum zilnic de apă folosind variabile'
        hours_to_show: 360
        entities:
          - sensor.water_day

Arată astfel:

Casă inteligentă: Construim graficele consumului de apă și electricitate în Home Assistant

În principiu, aceasta este deja ceea ce este necesar. Avantajul acestei metode este că datele sunt generate o singură dată pe interval. Adică, vor fi doar 24 de înregistrări pe zi pentru graficul orar.

Din păcate, aceasta nu rezolvă problema generală a bazei de date în creștere. Dacă vreau un grafic al consumului lunar, va trebui să stochez datele de cel puțin un an. Și cum asistentul de acasă oferă doar o setare a duratei de stocare pentru întreaga bază de date, asta înseamnă că TOATE datele din sistem trebuie păstrate timp de un an. De exemplu, într-un an consum 200 de metri cubi de apă, ceea ce înseamnă 200000 de înregistrări în bază. Și dacă luăm în considerare și altele senzori, cifra devine înfricoșătoare.

Metoda 3

Din fericire, oameni inteligenți au rezolvat deja această problemă prin scrierea bazei de date InfluxDB. Această bază este optimizată special pentru stocarea datelor bazate pe timp și se potrivește perfect pentru stocarea valorilor diferitelor senzori. Sistemul oferă de asemenea un limbaj de interogare similar cu SQL, care permite extragerea valorilor din bază și apoi agregarea acestora în diverse moduri. În cele din urmă, datele diferite pot fi stocate timpuri diferite. De exemplu, măsurătorile frecvent schimbătoare, cum ar fi temperatura sau umiditatea, pot fi stocate doar câteva săptămâni, în timp ce măsurătorile zilnice ale consumului de apă pot fi păstrate timp de un an.

În plus față de InfluxDB, persoanele inteligente au inventat și Grafana — un sistem de generare a graficelor pe baza datelor din InfluxDB. Grafana poate crea diferite tipuri de grafice, le poate personaliza detaliat și, cel mai important, aceste grafice pot fi "încărcate" în UI-ul lovelace al asistentului de acasă.

Inspirație aici și aici. Articolele detaliază procesul de instalare și conectare a InfluxDB și Grafana la asistentul de acasă. Eu mă voi concentra pe soluționarea problemei mele specifice.

Așadar, întâi vom începe să adunăm valorile contoarelor în influxDB. Un exemplu de configurație pentru asistentul de acasă (în acest exemplu, mă voi distra nu doar cu apa rece, ci și cu cea caldă):

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

Vom dezactiva salvarea acestor date în baza internă a asistentului de acasă, pentru a nu o umfla inutil:

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

Acum să trecem la consola InfluxDB și să configurăm baza noastră de date. În special, trebuie să stabilim cât timp vor fi păstrate anumite date. Acest lucru se reglează prin așa-numitul retention policy — este similar cu bazele de date din cadrul bazei de date principale, fiecare dintre acestea având propriile setări. Implicit, toate datele sunt stocate în retention policy numită autogen, iar aceste date vor fi păstrate o săptămână. Aș dori ca datele pe oră să fie păstrate o lună, cele săptămânale — un an, iar cele lunare să nu fie șterse niciodată. Vom crea retention policy corespunzătoare.

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

Acum, de fapt, trucul principal — agregarea datelor folosind continuous query. Acesta este un mecanism care execută automat o interogare la intervale de timp determinate, agregând datele conform acelei interogări, iar rezultatul îl stochează într-o valoare nouă. Să luăm un exemplu (scriu pe verticală pentru a fi mai ușor de citit, dar în realitate, a trebuit să introduc această comandă pe o linie).

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

Această comandă:

  • Crează continuous query numită cq_water_cold_hourly în baza homeassistant.
  • Interogarea va fi executată în fiecare oră (time(1h)).
  • Interogarea va extrage toate datele din measurement-ul homeassistant.autogen.l (litri), incluzând citirile pentru apă rece și apă caldă.
  • Datele agregate vor fi grupate după entity_id, ceea ce ne va crea valori separate pentru apă rece și apă caldă.
  • Având în vedere că contorul de litri este o secvență monoton crescătoare, în cadrul fiecărei ore va trebui să luăm valoarea maximă, astfel încât agregarea se va face prin funcția max(value).
  • Noua valoare va fi înregistrată în homeassistant.month.water_meter_hour, unde month este numele retention policy cu termen de păstrare de o lună. De asemenea, datele pentru apă rece și apă caldă vor fi distribuite în înregistrări separate cu entity_id corespunzător și valoarea în câmpul value.

Noaptea sau când nu este nimeni acasă, nu există consum de apă, iar prin urmare nu există înregistrări noi în homeassistant.autogen.l. Pentru a evita absența valorilor în interogările obișnuite, se poate folosi fill(previous). Acest lucru va determina InfluxDB să folosească valoarea de la ora precedentă.

Din păcate, interogările continue au o particularitate: trucul fill(previous) nu funcționează și înregistrările pur și simplu nu se creează. Este o problemă insurmontabilă care este discutată de câțiva ani. Ne vom ocupa de această problemă mai târziu, iar fill(previous) în interogările continue să rămână — nu deranjează.

Să vedem ce a ieșit (desigur, trebuie să așteptăm câteva ore):

> 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

Observați că valorile din bază sunt salvate în UTC, așa că, în această listă, ele diferă cu 3 ore — valorile de la ora 7 dimineața din outputul InfluxDB corespund valorilor de la ora 10 dimineața de pe graficele de mai sus. De asemenea, rețineți că între orele 2 și 5 dimineața nu există înregistrări — aceasta este particularitatea interogării continue.

După cum vedeți, valoarea agregată este de asemenea o secvență monoton crescătoare, doar că înregistrările sunt mai rare — o dată pe oră. Dar nu este o problemă — putem scrie o nouă interogare care va extrage datele corecte pentru grafic.

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)

Începem cu deslușirea:

  • Din baza homeassistant.month.water_meter_hour extragem date pentru entity_id='water_meter_cold' din ultimele 24 de ore (time >= now() -24h).
  • După cum am menționat, în secvența homeassistant.month.water_meter_hour pot lipsi unele înregistrări. Aceste date le vom genera din nou, rulând interogarea cu GROUP BY time(1h). De data aceasta, fill(previous) va funcționa corect, generând datele lipsă (funcția va lua valoarea anterioară)
  • Cel mai important în această interogare este funcția difference, care va calcula diferența dintre marcajele orare. Ea nu funcționează de la sine și necesită o funcție de agregare. Să zicem că va fi max() utilizată anterior.

Rezultatul execuției arată așa

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

Între 2 și 5 dimineața (UTC) nu a fost consum. Cu toate acestea, cererea va returna aceeași valoare a consumului datorită fill(previous), iar funcția difference va scădea această valoare din ea însăși, obținând astfel 0, ceea ce este cerut de fapt.

Acum rămâne doar să construim graficul. Pentru aceasta, deschidem Grafana, deschidem un panou existent (sau creăm unul nou), și creăm un nou grafic. Setările grafice vor fi următoarele.

Casă inteligentă: Construim graficele consumului de apă și electricitate în Home Assistant

Voi afișa datele pentru apa rece și caldă pe același grafic. Cererea este exact aceeași pe care am descris-o mai sus.

Parametrii de afișare sunt setați astfel. Pentru mine va fi un grafic cu linii (lines), care merge în trepte (stairs). Voi explica parametrul Stack mai jos. Acolo mai sunt câțiva parametri de afișare, dar nu sunt atât de interesanți.

Casă inteligentă: Construim graficele consumului de apă și electricitate în Home Assistant

Pentru a adăuga graficul obținut în home assistant, trebuie să:

  • ies din modul de editare a graficului. De ceva timp, setările corecte de partajare a graficelor sunt oferite doar de pe pagina tabloului de bord.
  • Faceți clic pe triunghiul de lângă numele graficului, din meniu selectați share.
  • În fereastra deschisă, treceți la tab-ul embed.
  • Debifați opțiunea current time range — intervalul de timp va fi setat prin URL.
  • Selectați tema necesară. În cazul meu, aceasta este light.
  • Copiați URL-ul obținut în cartea de setări 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"

Rețineți că intervalul de timp (ultimele 2 zile) este setat aici, nu în setările tabloului de bord.

Graficul arată astfel. Nu am folosit apă caldă în ultimele 2 zile, prin urmare graficul apei reci este singurul afișat.

Casă inteligentă: Construim graficele consumului de apă și electricitate în Home Assistant

Astfel, nu am ajuns la o decizie cu privire la care grafic îmi place mai mult, cel cu linii în trepte sau coloanele reale. Așa că, voi prezenta doar un exemplu de grafic zilnic de consum, de data aceasta cu coloane. Cererile sunt construite similar celor descrise mai sus. Parametrii de afișare sunt:

Casă inteligentă: Construim graficele consumului de apă și electricitate în Home Assistant

Acest grafic arată astfel:

Casă inteligentă: Construim graficele consumului de apă și electricitate în Home Assistant

Așadar, despre parametrul Stack. În acest grafic, coloana de apă rece este desenată deasupra coloanei de apă caldă. Înălțimea totală corespunde consumului total de apă rece și caldă pe perioada respectivă.

Toate graficele prezentate sunt dinamice. Puteți să mutați mouse-ul peste punctul de interes și să vedeți detaliile și valoarea din acel punct specific.

Din păcate, nu a fost lipsit de câteva probleme. În graficul cu bare (spre deosebire de graficul cu linii în trepte), mijlocul barei nu se află în mijlocul zilei, ci la 00:00. Adică, partea stângă a barei este desenată pe locul zilei precedente. Așadar, graficele pentru sâmbătă și duminică sunt desenate puțin mai în stânga zonei albăstrii. Deocamdată nu am găsit o soluție pentru a depăși această problemă.

O altă problemă este imposibilitatea de a lucra corect cu intervalele lunare. Problema este că lungimea orei/zilei/săptămânii este fixă, în timp ce lungimea lunii este variabilă. InfluxDB poate lucra doar cu intervale uniforme. Până acum, am reușit să stabilesc un interval fix de 30 de zile. Da, graficul pe parcursul anului se va deplasa puțin și barele nu vor corespunde exact lunilor. Dar, având în vedere că această informație îmi este utilă doar ca un indicator, sunt de acord cu asta.

Văd cel puțin două soluții:

  • Să renunț la graficele lunare și să mă limitez la cele săptămânale. 52 de bare săptămânale pe an arată destul de bine.
  • Să consider consumul lunar ca pe o metodă nr. 2 și să folosesc Grafana doar pentru grafice atractive. Va fi o soluție destul de precisă. Chiar se pot suprapune graficele din anul trecut pentru comparație — Grafana știe să facă și asta.

Concluzie

Nu știu de ce, dar îmi plac acest tip de grafice. Ele arată că viața este în plină desfășurare și totul se schimbă. Ieri a fost mult, azi e puțin, mâine va fi altfel. Mai trebuie să lucrez cu cei din familie privind consumul. Dar chiar și cu obiceiurile actuale, o sumă mare și confuză pe factură devine o imagine destul de clară a consumului.

În ciuda unei cariere de aproape 20 de ani ca programator, nu prea am avut de-a face cu baze de date. Așa că instalarea unei baze de date externe părea ceva complicat și neclar. Totul s-a schimbat articolul menționat mai sus — s-a dovedit că integrarea unui instrument potrivit se face în câteva clicuri, iar cu un instrument specializat, sarcina de a construi grafice devine ceva mai ușoară.

În titlu am menționat consumul de electricitate. Din păcate, în acest moment nu pot prezenta niciun grafic. Un contor SDM120 s-a stricat, iar celălalt are probleme când este accesat prin Modbus. Totuși, acest lucru nu influențează în niciun fel subiectul articolului – graficele vor fi realizate în același mod ca pentru apă.

În acest articol am prezentat metodele pe care le-am testat eu personal. Cu siguranță există și alte modalități de organizare a colectării și vizualizării datelor, despre care nu știu. Spuneți-mi despre acestea în comentarii, mi-ar plăcea foarte mult. Aș fi bucuros să primesc critici constructive și idei noi. Sper ca materialul prezentat să fie de ajutor și pentru alții.

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster