Casă inteligentă: construim grafice ale consumului de apă și electricitate în Home Assistant

Casă inteligentă: construim grafice ale consumului de apă și electricitate în Home Assistant
De fiecare dată când primesc o plată pentru energie electrică și apă, sunt surprins – chiar consumă familia mea atât de mult? Ei bine, da, baia are o pardoseală încălzită și un cazan, dar nu ard foc tot timpul. De asemenea, se pare că economisim apă (deși ne place și să ne stropim în baie). Acum câțiva ani, deja apometre conectate и electricitate la o casă inteligentă, dar acolo lucrurile s-au blocat. Abia acum am ajuns să analizăm consumul, despre care este vorba de fapt în acest articol.

Am trecut recent la Home Assistant ca sistem de acasă inteligent. Unul dintre motive a fost tocmai oportunitatea de a organiza colectarea unei cantități mari de date cu capacitatea de a construi în mod convenabil diverse tipuri de grafice.

Informațiile descrise în acest articol nu sunt noi; toate aceste lucruri sub diferite sosuri au fost deja descrise pe Internet. Dar fiecare articol descrie de obicei doar o abordare sau un aspect. A trebuit să compar toate aceste abordări și să o aleg chiar pe cea mai potrivită. Articolul încă nu oferă informații complete despre colectarea datelor, dar este un fel de rezumat al modului în care am făcut-o. Prin urmare, criticile constructive și sugestiile de îmbunătățire sunt binevenite.

Declarație de problemă

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

  • Din oră timp de 2 zile
  • Zilnic timp de 2 săptămâni
  • (opțional) săptămânal și lunar

Există câteva dificultăți în acest sens:

  • Componentele grafice standard sunt de obicei destul de slabe. În cel mai bun caz, puteți construi un grafic linie punct cu punct.

    Dacă te uiți suficient de bine, poți găsi componente terțe care extind capacitățile diagramei standard. Pentru un asistent acasă, în principiu, aceasta este o componentă bună și frumoasă mini-card grafic, dar este și oarecum limitată:

    • Este dificil să setați parametrii unei diagrame cu bare pe intervale mari (lățimea barei este setată în fracțiuni de oră, ceea ce înseamnă că intervalele mai mari de o oră vor fi setate în numere fracționale)
    • Nu puteți adăuga diferite entități la un grafic (de exemplu, temperatura și umiditatea sau combinați un grafic cu bare cu o linie)
  • Nu numai că asistentul de acasă folosește în mod implicit cea mai primitivă bază de date SQLite (și eu, un om de mână, nu m-am putut descurca cu instalarea MySQL sau Postgres), dar datele nu sunt stocate în cel mai optim mod. Deci, de exemplu, de fiecare dată când modificați chiar și cel mai mic parametru digital al unui parametru, în baza de date este scris un json imens de aproximativ un kilooctet.
    {"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 mulți senzori (senzori de temperatură în fiecare cameră, contoare de apă și electricitate), iar unii generează și destul de multe date. De exemplu, contorul de energie electrică SDM220 singur generează aproximativ o duzină de valori la fiecare 10-15 secunde și aș dori să instalez aproximativ 8 astfel de contoare. Există, de asemenea, o mulțime de parametri care sunt calculați pe baza altor senzori. Acea. toate aceste valori pot umfla cu ușurință baza de date cu 100-200 MB zilnic. Într-o săptămână sistemul abia se va mișca, iar într-o lună unitatea flash va muri (în cazul unei instalări tipice de asistent acasă pe un Raspberry PI), iar stocarea datelor pentru un an întreg este exclusă.

  • Dacă ai noroc, contorul tău poate număra singur consumul. Puteți să apelați oricând la contor și să întrebați la ce oră este valoarea consumului acumulat. De regulă, toate contoarele de energie electrică care au o interfață digitală (RS232/RS485/Modbus/Zigbee) oferă această oportunitate.

    Este mai rău dacă dispozitivul poate măsura pur și simplu un parametru instantaneu (de exemplu, puterea instantanee sau curentul) sau pur și simplu poate genera impulsuri la fiecare X wați-oră sau litri. Apoi trebuie să te gândești cum și cu ce să-l integrezi și unde să acumulezi valoare. Există riscul de a rata următorul raport din orice motiv, iar acuratețea sistemului în ansamblu ridică semne de întrebare. Puteți, desigur, să încredințați toate acestea unui sistem de casă inteligentă precum asistentul de acasă, dar nimeni nu a anulat punctul despre numărul de înregistrări din baza de date și nu va fi posibil să sondați senzorii mai mult de o dată pe secundă (un limitarea arhitecturii asistentului acasă).

Abordarea 1

Mai întâi, să vedem ce oferă asistentul de acasă din cutie. Măsurarea consumului pe o perioadă este o funcționalitate foarte căutată. Desigur, a fost implementat cu mult timp în urmă sub forma unei componente specializate - utility_meter.

Esența componentei este că creează intern o variabilă current_accumulated_value și o resetează după o perioadă specificată (oră/săptămână/lună). Componenta în sine monitorizează variabila de intrare (valoarea unui senzor), se abonează la modificări ale valorii - doar obțineți rezultatul final. Acest lucru este descris în doar câteva rânduri î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 este valoarea curentă a contorului în litri pe care o primesc direct din bucata de fier de mqtt. Designul creează 2 noi senzori water_cold_hour_um și water_cold_day_um, care acumulează citiri orare și zilnice, resetându-le la zero după expirarea perioadei. Iată un grafic al bateriei pe oră pentru o jumătate de zi.

Casă inteligentă: construim grafice ale consumului de apă și electricitate în Home Assistant

Codul pentru diagramele orare și zilnice pentru lovelace-UI arată astfel:

      - type: history-graph
        title: 'Hourly water consumption using vars'
        hours_to_show: 48
        entities:
          - sensor.water_hour

      - type: history-graph
        title: 'Daily water consumption using vars'
        hours_to_show: 360
        entities:
          - sensor.water_day

De fapt, problema cu această abordare constă în acest algoritm. După cum am menționat deja, pentru fiecare valoare de intrare (citirea curentă a contorului pentru fiecare litru următor) sunt generate 1 kb de înregistrări în baza de date. Fiecare contor de utilitate generează și o nouă valoare, care se adaugă și la bază. Dacă vreau să colectez citiri orare/zile/săptămânale/lunare și pentru mai multe ridicătoare de apă și să adaug un pachet de contoare electrice, vor fi o mulțime de date. Ei bine, mai precis, nu există multe date, dar din moment ce asistentul acasă scrie o grămadă de informații inutile în baza de date, dimensiunea bazei de date va crește treptat. Mi-e teamă să estimez chiar și dimensiunea bazei pentru diagramele săptămânale și lunare.

În plus, contorul de utilitate în sine nu rezolvă problema. Graficul valorilor produse de contorul de utilitate este o funcție crescătoare monotonă care se resetează la 0 în fiecare oră. Avem nevoie de o diagramă de consum pe înțelesul utilizatorului, care să arate câți litri au fost consumați în perioada respectivă. Componenta standard istoric-grafic nu poate face acest lucru, dar componenta externă mini-card grafic ne poate ajuta.

Acesta este codul cardului pentru lovelace-UI:

      - aggregate_func: max
        entities:
          - color: var(--primary-color)
            entity: sensor.water_cold_hour_um
        group_by: hour
        hours_to_show: 48
        name: "Hourly water consumption aggregated by 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 (nu mi-a plăcut portocaliul standard), este important să rețineți 3 setări:

  • group_by:hour — graficul va fi generat cu barele aliniate la începutul orei
  • points_per_hour: 1 - o bară pentru fiecare oră
  • Și cel mai important, aggregate_func: max - luați valoarea maximă în fiecare oră. Acesta este parametrul care transformă graficul dinți de ferăstrău în bare

Casă inteligentă: construim grafice ale consumului de apă și electricitate în Home Assistant

Nu acordați atenție rândului de coloane din stânga - acesta este comportamentul standard al componentei dacă nu există date. Dar nu au existat date - am activat doar colectarea datelor contoarelor de utilitate în urmă cu câteva ore doar de dragul acestui articol (voi descrie abordarea mea actuală mai jos).

În această imagine am vrut să arăt că uneori chiar și afișarea datelor funcționează și barele reflectă de fapt valorile corecte. Dar asta nu este tot. Din anumite motive, coloana selectată pentru perioada de la 11 la 12 dimineața afișează 19 litri, deși pe graficul cu dinți puțin mai mare pentru aceeași perioadă de la același senzor vedem un consum de 62 de litri. Fie există un bug, fie mâinile sunt strâmbe. Dar încă nu înțeleg de ce s-au rupt datele din dreapta - consumul acolo a fost normal, ceea ce este vizibil și din graficul cu dinți.

În general, nu am reușit să obțin plauzibilitatea acestei abordări - graficul arată aproape întotdeauna un fel de erezie.

Cod similar pentru senzorul de zi.

      - aggregate_func: max
        entities:
          - color: var(--primary-color)
            entity: sensor.water_cold_day_um
        group_by: interval
        hours_to_show: 360
        name: "Daily water consumption aggregated by utility meter"
        points_per_hour: 0.0416666666
        show:
          graph: bar
        type: 'custom:mini-graph-card'

Vă rugăm să rețineți că parametrul group_by este setat la interval, iar parametrul points_per_hour reglează totul. Și aici constă o altă problemă cu această componentă - points_per_hour funcționează bine pe diagrame de o oră sau mai puțin, dar este dezamăgitor la intervale mai mari. Deci, pentru a obține o coloană într-o zi, a trebuit să introduc valoarea 1/24=0.04166666. Nici măcar nu vorbesc de grafice săptămânale și lunare.

Abordarea 2

În timp ce încă înțeleg asistentul acasă, am dat peste acest videoclip:


Un prieten colectează date de consum de la mai multe tipuri de prize Xiaomi. Sarcina lui este puțin mai simplă - pur și simplu afișați valoarea consumului pentru azi, ieri și pentru lună. Nu sunt necesare programe.

Să lăsăm deoparte discuțiile despre integrarea manuală a valorilor de putere instantanee - am scris deja mai sus despre „acuratețea” acestei abordări. Nu este clar de ce nu a folosit valorile de consum acumulate, care sunt deja colectate de aceeasi priza. În opinia mea, integrarea în interiorul hardware-ului va funcționa mai bine.

Din videoclip vom prelua ideea de a număra manual consumul pe o perioadă. Tipul numără doar valorile pentru azi și ieri, dar vom merge mai departe și vom încerca să desenăm un grafic. Esența metodei propuse în cazul meu este următoarea.

Să creăm o variabilă value_at_the_beginning_of_hour, în care vom înregistra citirile curente ale contorului
Cu ajutorul cronometrului, la sfârșitul orei (sau la începutul următoarei) calculăm diferența dintre citirea curentă și cea stocată la începutul orei. Această diferență va fi consumul pentru ora curentă - vom salva valoarea în senzor, iar în viitor vom construi un grafic pe baza acestei valori.
De asemenea, trebuie să „resetați” variabila value_at_beginning_of_hour scriind acolo valoarea curentă a contorului.

Toate acestea se pot face prin intermediul asistentului acasă însuși.

Va trebui să scrieți puțin mai mult cod decât în ​​abordarea anterioară. Mai întâi, să creăm aceleași „variabile”. Din cutie nu avem entitatea „variabilă”, dar putem folosi serviciile brokerului mqtt. Vom trimite valori acolo cu steag retain=true - aceasta va salva valoarea din interiorul brokerului și poate fi scoasă de acolo oricând, chiar și atunci când asistentul de acasă este repornit. Am făcut contoare orare și zilnice deodată.

- 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 întâmplă în automatizarea, care rulează în fiecare oră și, respectiv, în fiecare noapte.

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

  • Calculați valoarea pentru un interval ca diferență între valorile de început și de sfârșit
  • Actualizați valoarea de bază pentru următorul interval

Construcția graficelor în acest caz este rezolvată prin graficul istoric obișnuit:

      - type: history-graph
        title: 'Hourly water consumption using vars'
        hours_to_show: 48
        entities:
          - sensor.water_hour

      - type: history-graph
        title: 'Daily water consumption using vars'
        hours_to_show: 360
        entities:
          - sensor.water_day

Arată astfel:

Casă inteligentă: construim grafice ale consumului de apă și electricitate în Home Assistant

În principiu, acesta este deja ceea ce este necesar. Avantajul acestei metode este că datele sunt generate o dată pe interval. Acestea. doar 24 de înregistrări pe zi pentru o diagramă orară.

Din păcate, acest lucru încă nu rezolvă problema generală a unei baze în creștere. Dacă vreau un grafic de consum lunar, va trebui să stochez date cel puțin un an. Și deoarece Home Assistant oferă o singură setare de durată de stocare pentru întreaga bază de date, aceasta înseamnă că TOATE datele din sistem vor trebui stocate pentru un an întreg. De exemplu, într-un an consum 200 de metri cubi de apă, ceea ce înseamnă că asta înseamnă 200000 de intrări în baza de date. Și dacă țineți cont de alți senzori, atunci cifra devine în general indecentă.

Abordarea 3

Din fericire, oamenii inteligenți au rezolvat deja această problemă scriind baza de date InfluxDB. Această bază de date este optimizată special pentru stocarea datelor bazate pe timp și este ideală pentru stocarea valorilor diferiților senzori. Sistemul oferă, de asemenea, un limbaj de interogare asemănător SQL, care vă permite să extrageți valori din baza de date și apoi să le agregați în diferite moduri. În cele din urmă, diferite date pot fi stocate pentru momente diferite. De exemplu, citirile care se schimbă frecvent, cum ar fi temperatura sau umiditatea, pot fi stocate doar pentru câteva săptămâni, în timp ce citirile consumului zilnic de apă pot fi stocate pentru un an întreg.

Pe lângă InfluxDB, oamenii deștepți au inventat și Grafana, un sistem de desenare a graficelor bazat pe datele din InfluxDB. Grafana poate desena diferite tipuri de grafice, le poate personaliza în detaliu și, cel mai important, aceste grafice pot fi „conectate” la asistentul de acasă lovelace-UI.

A fi inspirat aici и aici. Articolele descriu în detaliu procesul de instalare și conectare a InfluxDB și Grafana la asistentul de acasă. Mă voi concentra pe rezolvarea problemei mele specifice.

Deci, în primul rând, să începem să adăugăm valoarea contorului în influxDB. O parte din configurația asistentului acasă (în acest exemplu mă voi distra nu doar cu apă rece, ci și cu apă caldă):

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

Să dezactivăm salvarea acelorași date în baza de date internă a asistentului acasă, pentru a nu o umfla din nou:

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

Să mergem acum la consola InfluxDB și să ne configurem baza de date. În special, trebuie să configurați cât timp vor fi stocate anumite date. Acest lucru este reglementat de așa-numitul. politica de reținere - aceasta este similară cu bazele de date dintr-o bază de date principală, fiecare bază de date internă având propriile setări. În mod implicit, toate datele sunt stocate într-o politică de păstrare numită autogen; aceste date vor fi stocate timp de o săptămână. Aș dori ca datele orare să fie păstrate timp de o lună, datele săptămânale să fie păstrate timp de un an și datele lunare să nu fie șterse niciodată. Să creăm politica de păstrare adecvată

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 este agregarea datelor folosind interogare continuă. Acesta este un mecanism care rulează automat o interogare la intervale specificate, cumulează datele pentru această interogare și adaugă rezultatul într-o nouă valoare. Să ne uităm la un exemplu (scriu într-o coloană pentru lizibilitate, dar în realitate a trebuit să introduc această comandă într-o singură 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ă:

  • Creează o interogare continuă denumită cq_water_cold_hourly în baza de date a asistentului de acasă
  • Solicitarea va fi executată la fiecare oră (timp(1h))
  • Solicitarea va răzui toate datele de la măsurarea homeassistant.autogen.l (litri), inclusiv citirile de apă rece și caldă
  • Datele agregate vor fi grupate după entity_id, ceea ce ne va oferi valori separate pentru apa rece și cea caldă
  • Deoarece contorul de litri este o secvență care crește monoton în fiecare oră, va fi necesar să se ia valoarea maximă, astfel încât agregarea va fi efectuată de funcția max(valoare)
  • Noua valoare va fi scrisă în homeassistant.month.water_meter_hour, unde luna este numele politicii de păstrare cu o perioadă de păstrare de o lună. Mai mult, datele despre apa rece și caldă vor fi împrăștiate în înregistrări separate cu entity_id și valoarea corespunzătoare în câmpul de valoare

Noaptea sau când nimeni nu este acasă, nu există consum de apă și, prin urmare, nu există noi înregistrări în homeassistant.autogen.l. Pentru a evita valorile lipsă în interogările obișnuite, puteți utiliza umplere (anterior). Acest lucru va forța InfluxDB să folosească valoarea ultimei ore.

Din păcate, interogarea continuă are o particularitate: trucul de umplere (anterior) nu funcționează și înregistrările pur și simplu nu sunt create. Mai mult, aceasta este un fel de problemă insurmontabilă care se discută de câțiva ani. Ne vom ocupa de această problemă mai târziu, dar lăsați umplerea (anterior) să fie în interogarea continuă - nu interferează.

Să verificăm ce s-a întâmplat (desigur, trebuie să așteptați 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

Rețineți că valorile din baza de date sunt stocate în UTC, deci această listă diferă cu 3 ore - valorile de la 7:10 din ieșirea InfluxDB corespund valorilor de la 2:5 din graficele de mai sus. De asemenea, rețineți că între XNUMX și XNUMX am pur și simplu nu există înregistrări - aceasta este aceeași caracteristică a interogării continue.

După cum puteți vedea, valoarea agregată este, de asemenea, o secvență în creștere monotonică, doar intrările apar mai rar - o dată pe oră. Dar aceasta nu este o problemă - putem scrie o altă interogare care va prelua 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)

voi descifra:

  • Din baza de date homeassistant.month.water_meter_hour vom extrage date pentru entity_id='water_meter_cold' pentru ultima zi (time >= now() -24h).
  • După cum am menționat deja, unele intrări pot lipsi din secvența homeassistant.month.water_meter_hour. Vom regenera aceste date rulând o interogare cu GROUP BY timp (1h). Această umplere de timp (anterior) va funcționa conform așteptărilor, generând datele lipsă (funcția va lua valoarea anterioară)
  • Cel mai important lucru în această solicitare este funcția de diferență, care va calcula diferența dintre marcajele orare. Nu funcționează singur și necesită o funcție de agregare. Fie acesta să fie max() folosit înainte.

Rezultatul execuției arată astfel

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

De la 2 la 5 am (UTC) nu a fost consum. Cu toate acestea, interogarea va returna aceeași valoare de consum datorită umplerii (anterior), iar funcția de diferență va scădea această valoare din ea însăși și rezultatul va fi 0, care este exact ceea ce este necesar.

Tot ce rămâne este să construiești un grafic. Pentru a face acest lucru, deschideți Grafana, deschideți un tablou de bord existent (sau creați un nou) și creați un nou panou. Setările diagramei vor fi așa.

Casă inteligentă: construim grafice ale consumului de apă și electricitate în Home Assistant

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

Parametrii de afișare sunt setați după cum urmează. Pentru mine va fi un grafic cu linii, care merge în trepte (scări). Voi explica mai jos parametrul Stack. Mai sunt câteva opțiuni de afișare mai jos, dar nu sunt atât de interesante.

Casă inteligentă: construim grafice ale consumului de apă și electricitate în Home Assistant

Pentru a adăuga diagrama rezultată la Home Assistant, trebuie să:

  • ieși din modul de editare a graficului. Din anumite motive, setările corecte de partajare a diagramelor sunt oferite numai din pagina tabloului de bord
  • Faceți clic pe triunghiul de lângă numele diagramei și selectați Partajare din meniu
  • În fereastra care se deschide, accesați fila încorporare
  • Debifați intervalul de timp actual - vom seta intervalul de timp prin URL
  • Selectați subiectul dorit. In cazul meu este lumina
  • Copiați URL-ul rezultat pe cardul 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"

Vă rugăm să rețineți că intervalul de timp (ultimele 2 zile) este setat aici și nu în setările tabloului de bord.

Graficul arată așa. Nu am folosit apă caldă în ultimele 2 zile, așa că este trasat doar graficul cu apă rece.

Casă inteligentă: construim grafice ale consumului de apă și electricitate în Home Assistant

Încă nu m-am hotărât singur care grafic îmi place mai mult, un pas de linie sau bare reale. Prin urmare, voi da pur și simplu un exemplu de diagramă de consum zilnic, doar de data aceasta în bare. Interogările sunt construite în mod similar celor descrise mai sus. Opțiunile de afișare sunt:

Casă inteligentă: construim grafice ale consumului de apă și electricitate în Home Assistant

Acest grafic arată astfel:

Casă inteligentă: construim grafice ale consumului de apă și electricitate în Home Assistant

Deci despre parametrul Stack. În acest grafic, o coloană de apă rece este desenată deasupra unei coloane de apă caldă. Înălțimea totală corespunde consumului total de apă rece și caldă pentru perioada respectivă.

Toate graficele afișate sunt dinamice. Puteți trece mouse-ul peste punctul de interes și puteți vedea detaliile și valoarea la un anumit punct.

Din păcate, în unguent erau câteva muște. Pe o diagramă cu bare (spre deosebire de o diagramă cu linii de pas), mijlocul barei nu este în mijlocul zilei, ci la 00:00. Acestea. jumătatea stângă a coloanei este desenată în locul zilei precedente. Deci graficele pentru sâmbătă și duminică sunt desenate ușor în stânga zonei albăstrui. Până mi-am dat seama cum să-l înving.

O altă problemă este incapacitatea de a lucra corespunzător la intervale lunare. Cert este că durata orei/zilei/săptămânii este fixă, dar durata lunii este diferită de fiecare dată. InfluxDB poate funcționa numai la intervale egale. Până acum creierul meu a fost suficient pentru a stabili un interval fix de 30 de zile. Da, graficul va pluti puțin pe tot parcursul anului și barele nu vor corespunde exact lunilor. Dar, deoarece sunt interesat de acest lucru pur și simplu ca un contor de afișare, sunt de acord cu el.

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

  • Renunță la graficele lunare și limitează-te la cele săptămânale. 52 de batoane săptămânale pentru anul arată destul de bine
  • Luați în considerare consumul lunar în sine ca metoda nr. 2 și folosiți grafana numai pentru grafice frumoase. Va fi o soluție destul de precisă. Puteți chiar să suprapuneți grafice pentru ultimul an pentru comparație - și grafana poate face asta.

Concluzie

Nu știu de ce, dar sunt obsedat de astfel 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 altceva. Rămâne doar să lucrăm cu membrii gospodăriei pe tema consumului. Dar chiar și cu poftele actuale, doar o cifră mare și de neînțeles pe bonul de plată se transformă deja într-o imagine destul de înțeleasă a consumului.

În ciuda carierei mele de aproape 20 de ani ca programator, practic nu am avut niciun contact cu bazele de date. Prin urmare, instalarea unei baze de date externe părea ceva atât de abstrus și de neînțeles. A schimbat totul articolul de mai sus — s-a dovedit că atașarea unui instrument adecvat se face în câteva clicuri, iar cu un instrument specializat, sarcina de a trasa diagrame devine puțin mai ușoară.

În titlu am menționat consumul de energie electrică. Din păcate, în acest moment nu pot oferi niciun grafic. Un contor SDM120 a murit pentru mine, iar celălalt este eronat când este accesat prin Modbus. Cu toate acestea, acest lucru nu afectează în niciun fel subiectul acestui articol - graficele vor fi construite în același mod ca și pentru apă.

În acest articol am prezentat abordările pe care le-am încercat chiar eu. Cu siguranță există și alte moduri de a organiza colectarea și vizualizarea datelor despre care nu știu. Povestește-mi despre asta în comentarii, voi fi foarte interesat. Voi fi bucuros de critici constructive și idei noi. Sper că materialul prezentat va ajuta pe cineva.

Sursa: www.habr.com

Adauga un comentariu