Shtëpia e mençur: Ndërtojmë grafikët e konsumit të ujit dhe energjisë elektrike në Home Assistant

Shtëpia e mençur: Ndërtojmë grafikët e konsumit të ujit dhe energjisë elektrike në Home Assistant
Çdo herë që merr faturën për elektricitetin dhe ujë, çuditem - vallë, familja ime konsumon kaq shumë? Po, në banjë kemi ngrohje të dyshemesë dhe një bojler, por ato nuk punojnë nonstop. Edhe për ujë duket se e kursejmë (pavarësisht se na pëlqen të bëjmë një banjë). Para disa vitesh, kam instaluar matësit e ujit dhe elektricitetit në shtëpinë time inteligjente, por puna ndaloi atje. Analiza e konsumit arriti vetëm tani, për të cilën, në fakt, është kjo artikull.

Së fundmi kam kaluar në Home Assistant si sistemin tim të shtëpisë inteligjente. Një nga arsyet ishte pikërisht mundësia për të organizuar mbledhjen e një sasie të madhe të të dhënave me mundësinë e ndërtimit të grafikeve të ndryshme.

Informacioni i përshkruar në këtë artikull nuk është i ri, të gjitha këto gjëra në forma të ndryshme janë përshkruar tashmë në internet. Por çdo artikull, në përgjithësi, përshkruan vetëm një qasje ose aspekt. Krahasimi i të gjitha këtyre qasjeve dhe zgjedhja e më të përshtatshmes është detyra ime. Artikulli gjithsesi nuk ofron informacion të plotë mbi mbledhjen e të dhënave, por është një lloj përmbledhjeje të asaj që kam bërë. Pra, kritika konstruktive dhe propozime për përmirësim janë të mirëpritura.

Vendosja e detyrës

Prandaj, qëllimi i ushtrimit të sotëm është të merret grafika e bukur e konsumit të ujit dhe energjisë elektrike:

  • Për çdo orë gjatë 2 ditëve
  • Për çdo ditë gjatë 2 javëve
  • (opsionale) për çdo javë dhe për çdo muaj

Në këtë na presin disa vështirësi:

  • Komponentët standardë të grafikëve, në përgjithësi, janë mjaft të varfër. Në rastin më të mirë, mund të ndërtohet një grafik linear mbi pika.

    Nëse kërkoni mirë, mund të gjeni komponentë të jashtëm që zgjasin mundësitë e grafikëve standardë. Për home assistant, në thelb, është një komponent i mirë dhe i bukur mini-graph-card, por edhe ai është disi i kufizuar:

    • Është e vështirë të vendosësh parametrat e grafikëve me kolona në intervale të mëdha (gjerësia e kolonave vendoset në pjesë orësh, që do të thotë se intervalet më të gjata se një orë do të vendosen si numra decimalë)
    • Nuk mund të shtosh entitete të ndryshme në një grafik (p.sh. temperaturën dhe lagështinë, ose të kombinosh grafikun me kolona me një vijë)
  • Jo vetëm që Home Assistant për default përdor bazën e të dhënave më primitive SQLite (dhe unë, i pafuqishëm, nuk arrita të instaloja MySQL ose Postgres), por edhe të dhënat ruhen në një mënyrë që nuk është optimale. Për shembull, me çdo ndryshim të çdo parametri edhe më të vogël në numra, në bazë shkruhet një JSON i madh me një madhësi prej rreth kilobajtësh.
    {"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}}}

    Kam kam shumë sensorë (sensorë temperaturës në çdo dhomë, matës uji dhe elektriciteti), dhe disa madje gjenerojnë shumë të dhëna. Për shembull, vetëm matësi i elektricitetit SDM220 gjeneron rreth një duzinë vlerash çdo 10-15 sekonda, dhe unë do të doja të instaloj rreth 8 prej këtyre matësve. Gjithashtu ka një grup të madh parametrash që llogariten në bazë të sensorëve të tjerë. Të gjitha këto vlera lehtësisht mund ta fryjnë bazën e të dhënave me 100-200 MB çdo ditë. Pas një jave, sistemi do të ketë vështirësi të funksionojë, dhe pas një muaji, plaka USB do të dështojë (në rastin e instalimit tipik të home assistant në raspberry PI), dhe nuk bëhet fjalë për ruajtjen e të dhënave për një vit të tërë.

  • Nëse keni fat, matësi juaj mund të llogarisë vetë konsumimin. Në çdo moment mund të drejtoheni te matësi dhe të pyesni se cila është vlera akumuluese e konsumit. Në përgjithësi, të gjithë matësit e energjisë elektrike që kanë një ndërfaqe digjitale (RS232/RS485/Modbus/Zigbee) ofrojnë një mundësi të tillë.

    Është më keq nëse pajisja mund thjesht të masë një parametër të menjëhershëm (p.sh., fuqinë ose rrymën e menjëhershme), ose thjesht të gjenerojë impulset çdo X vat-orë ose litra. Atëherë duhet të mendojmë se si dhe me çfarë ta integrojmë dhe ku ta ruajmë vlerën. Ka rrezik të humbasim raportin e radhës për ndonjë arsye, madje dhe saktesia e sistemit në tërësi ngre pyetje. Sigurisht, mund ta ngarkojmë tërë këtë sistemit të shtëpisë inteligjente si home assistant, por pika mbi numrin e regjistrimeve në bazë nuk është anuluar, dhe as nuk do të arrijmë të anketojmë sensorët më shpesh se një herë në sekondë (kufizimi i arkitekturës së home assistant).

Qasja 1

Së pari, le të shohim se çfarë ofron home assistant direkt. Matja e konsumit për një periudhë — është një funksionalitet shumë i kërkuar. Sigurisht, kjo është realizuar prej kohësh në formën e një komponente të specializuar — utility_meter.

The essence of the component is that it internally initializes a variable called current_accumulated_value, and resets it after a specified period (hour/week/month). The component independently monitors the input variable (value from some sensor), subscribes to changes in the value itself — you simply receive the final result. This is described in just a few lines in the configuration file.

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

Here, sensor.water_meter_cold is the current value of the meter in liters, which I receive. directly from the device. via mqtt. The structure creates two new sensors water_cold_hour_um and water_cold_day_um, which accumulate hourly and daily readings, resetting them at the end of the period. Here’s the hourly accumulator graph for half a day.

Shtëpia e mençur: Ndërtojmë grafikët e konsumit të ujit dhe energjisë elektrike në Home Assistant

The code for the hourly and daily graphs for the lovelace-UI looks like this:

      - 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

Në këtë algoritëm qëndron problemi i këtij qasje. Siç e përmenda, për çdo vlerë hyrëse (leximi aktual i matësit për çdo litër të ardhshëm) gjenerohet 1 kB regjistrimi në bazë. Çdo matës gjithashtu gjeneron një vlerë të re që gjithashtu regjistrohet në bazë. Nëse dua të mbledh lexime orëshe / ditorë / javore / mujore, po për disa matës për ujin, dhe gjithashtu të shtoj një paketë matësish të energjisë elektrike - do të jetë shumë të dhëna. Në të vërtetë, të dhënat nuk janë shumë, por pasi home assistant shkruan në bazë shumë informacion të panevojshëm, madhësia e bazës do të rritet si maja e drogës. Frikohem të bëj llogaritjet për madhësinë e bazës për grafikët javore dhe mujore.

Përveç kësaj, utility meter vetë nuk zgjidh problemin e caktuar. Grafiku i vlerave që jep utility meter është një funksion monotonik në rritje, i cili reset gabimin në 0 çdo orë. Na nevojitet një grafik i qartë për përdoruesin se sa litra janë konsumuar gjatë një periudhe. Komponenti standard history-graph nuk e bën këtë, por një komponent i jashtëm mini-graph-card mund të na ndihmojë.

Ky është kodi i kartës për lovelace-UI:

      - aggregate_func: max
        entities:
          - color: var(--primary-color)
            entity: sensor.water_cold_hour_um
        group_by: hour
        hours_to_show: 48
        name: "Konsumimi orar i ujit i agreguar nga matësi i utilitetit"
        points_per_hour: 1
        show:
          graph: bar
        type: 'custom:mini-graph-card'

Përveç cilësimeve standarde si emri i sensorit, lloji i grafikut, ngjyra (portokalli standard nuk më pëlqeu), është e rëndësishme të theksohen 3 cilësime:

  • group_by:hour — grafiku do të gjenerohet me rreshtimin e kolonave në fillim të orës
  • points_per_hour: 1 — një kolone për çdo orë
  • Dhe më e rëndësishmja, aggregate_func: max — të merret vlera maksimale brenda çdo ore. Ky parametër e kthen grafikun zigzag në kolona.

Shtëpia e mençur: Ndërtojmë grafikët e konsumit të ujit dhe energjisë elektrike në Home Assistant

Mos u shqetësoni për disa kolona në të majtë — kjo është sjellja standarde e komponentit nëse nuk ka të dhëna. Dhe nuk kishte të dhëna — aktivizova mbledhjen e të dhënave për matësin e utilitetit vetëm për këtë artikull (qasja ime aktuale do ta diskutoj pak më poshtë).

Në këtë imazh doja të tregoja se ndonjëherë shfaqja e të dhënave funksionon, dhe kolonat vërtet reflektojnë vlera të sakta. Por jo të gjitha. Kolona e veçantë për intervalin nga 11 deri në 12 të mëngjesit për çfarëdo arsye tregon 19 litra, ndërsa në grafikun me dhëmbë pak më lart për këtë periudhë nga i njëjti sensor shohim konsumimin prej 62 litrave. Ose është një gabim, ose ka diçka të keqe me konfigurimin. Sa i përket pse të dhënat në anën e djathtë mungojnë, nuk e kam kuptuar ende — konsumimi atje ishte normal, gjë që është e dukshme edhe nga grafiku me dhëmbë.

Në përgjithësi, nuk arrita të arrij besueshmërinë e këtij qasje — grafiku pothuajse gjithmonë tregon ndonjë gjë të çuditshme.

Kodi i ngjashëm për sensorin ditor.

      - aggregate_func: max
        entities:
          - color: var(--primary-color)
            entity: sensor.water_cold_day_um
        group_by: interval
        hours_to_show: 360
        name: "Konsumi ditor i ujit i agreguar nga një matës utilitar"
        points_per_hour: 0.0416666666
        show:
          graph: bar
        type: 'custom:mini-graph-card'

Vëreni se që parameteri group_by është vendosur në vlerën interval, dhe rregullon të gjithë parametrin points_per_hour. Kjo është një tjetër problem i këtij komponenti — points_per_hour funksionon mirë në grafikët për një orë ose më pak, por keq për periudha më të gjata. Për të marrë një kolonë për një ditë, duhej të shkruaja vlerën 1/24=0.04166666. Nuk po flas për grafikët javore dhe mujore.

Qasja 2

Duke u njohur me home assistant, kam hasur këtë video:

Luaj videon

Shoku mbledh të dhënat e konsumit nga disa lloje prizash Xiaomi. Detyra e tij është pak më e thjeshtë — thjesht të tregojë vlerën e konsumit për sot, dje dhe për muajin. Nuk kërkohen grafikë.

Do ta lëmë mënjanë diskutimin mbi integimin manual të vlerave momentale të fuqisë — mbi 'saktësinë' e këtij qasjeje kam shkruar më sipër. Nuk është e qartë pse ai nuk përdori vlerat akumuluese të konsumit, të cilat tashmë mblidhen nga e njëjta prizë. Në opinonin tim, integimi brenda pajisjes do të punojë më mirë.

Nga video do të marrim idenë e numërimit manual të konsumit për një periudhë. Fakti që llogariten vetëm vlerat për sot dhe dje është një fillim, por ne do të shkojmë më tej dhe do të përpiqemi të vizatojmë një grafik. Thelbi i metodës së propozuar në rastin tim përfshin këtë.

Do të krijojmë një variabël vlera_në_fillim_të_orës, në të cilin do të regjistrojmë leximet aktuale të matësit.
Në fund të orës (ose në fillim të ardhshme), do të llogarisim diferencën midis leximit aktual dhe atij të regjistruar në fillim të orës. Kjo diferencë do të jetë konsumimi për orën aktuale — do ta ruajmë këtë vlerë në sensor dhe në të ardhmen do të ndërtojmë grafikun për këtë vlerë.
Gjithashtu, nevojitet që të "zerojmë" variablin vlera_në_fillim_të_orës duke regjistruar aty vlerën aktuale të matësit.

E gjithë kjo mund të bëhet përmes mjeteve të vetë home assistant.

Do t'nahet më shumë kod se në qasjen e mëparshme. Fillimisht do të krijojmë këto “variabla”. Nga kutia nuk kemi një entitet “variabël”, por mund të shfrytëzojmë shërbimet e brokerit mqtt. Do të dërgojmë atje vlera me flagun retain=true — kjo do ta ruajë vlerën brenda brokerit, dhe mund ta nxjerrim në çdo moment, edhe pas rinisjes së home assistant. Kam bërë menjëherë numëruesit orarë dhe ditorë.

- 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

E gjithë magia ndodh në automatizimin, i cili aktivizohet çdo orë dhe çdo natë përkatësisht.

- 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

Të dy automatikat kryejnë 2 veprime:

  • Llogarisin vlerën për intervalin si diferencë midis vlerës fillestare dhe asaj përfundimtare
  • Përditësojnë vlerën bazë për intervalin tjetër

Ndërtimi i grafikëve në këtë rast zgjidhet me një history-graph të zakonshëm:

      - 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

Duket kështu:

Shtëpia e mençur: Ndërtojmë grafikët e konsumit të ujit dhe energjisë elektrike në Home Assistant

Në princip, kjo është ajo që nevojitet. Avantazhi i këtij metode është se të dhënat gjenerohen një herë për intervalin. Pra, gjithsej 24 regjistrime për ditë për grafikun orar.

Fatkeqësisht, kjo nuk zgjidh problemin e përgjithshëm të rritjes së bazës. Nëse dua një grafik të konsumit mujor, do të duhet të ruaj të dhënat për të paktën një vit. Dhe pasi që home assistant ofron vetëm një cilësim të kohëzgjatjes së ruajtjes për të gjithë bazën, kjo do të thotë që të DHENAT e GJITHA në sistem do të duhet të ruhen për një vit. Për shembull, për një vit konsumoj 200 metra kub ujë, kjo do të thotë 200000 regjistrime në bazë. E nëse marrim parasysh edhe sensorët e tjerë, numri bëhet vërtet i papëlqyeshëm.

Qasja 3

Fatmirësisht, njerëzit e mençur kanë zgjidhur këtë problem duke shkruar bazën e të dhënave InfluxDB. Kjo bazë është optimizuar posaçërisht për ruajtjen e të dhënave të bazuara në kohë dhe është ideale për ruajtjen e vlerave të sensorëve të ndryshëm. Sistemi gjithashtu ofron një gjuhë kërkimesh të ngjashme me SQL, e cila lejon nxjerrjen e vlerave nga baza dhe më pas agregimin e tyre në mënyra të ndryshme. Së fundi, të dhënat e ndryshme mund të ruhen për kohë të ndryshme. Për shembull, leximet që ndihen shpesh si temperatura apo lagështira mund të ruhen për vetëm disa javë, ndërsa leximet ditore të konsumit të ujit mund të ruhen për një vit tërë.

Përveç InfluxDB, njerëz të mençur gjithashtu shpikën Grafana — një sistem për vizatimin e grafikëve nga të dhënat e InfluxDB. Grafana mund të vizatojë lloje të ndryshme grafikësh, t’i personalizojë ato në detaje dhe, më e rëndësishmja, këta grafikë mund të “integrohen” në lovelace-UI të asistentit të shtëpisë.

Të frymëzohesh këtu dhe këtu. Artikujt përshkruajnë në detaje procesin e instalimit dhe lidhjes së InfluxDB dhe Grafana me asistentin e shtëpisë. Unë do të përqendrohem në zgjidhjen e detyrës sime specifike.

Pra, gjëja e parë është të fillojmë me ruajtjen e vlerës së numëruesit në influxDB. Një pjesë e konfigurimit të asistentit të shtëpisë (në këtë shembull do të argëtohem jo vetëm me ujë të ftohtë, por edhe me ujë të ngrohtë):

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

Do të çaktivizojmë ruajtjen e këtyre të dhënave në bazën e të dhënave të brendshme të asistentit të shtëpisë, për të mos e fryrë atë pa nevojë:

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

Tani tani kalojmë në konsolën InfluxDB dhe konfigurojmë bazën tonë. Në veçanti, duhet të përcaktojmë sa kohë do të ruhen të dhënat e ndryshme. Kjo rregullohet nga politika e ruajtjes e njohur si retention policy — kjo është si bazat e të dhënave brenda një baze të dhënash kryesore, ku çdo bazë e brendshme ka parametrat e saj të konfiguruar. Në mënyrë të paracaktuar, të gjitha të dhënat vendosen në retention policy me emrin autogen, këto të dhëna do të ruhen për një javë. Do të doja që të dhënat për orët të ruhen për një muaj, ato javore për një vit dhe ato mujore të mos fshihen kurrë. Të krijojmë politikat përkatëse të ruajtjes.

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

Tani, truku kryesor — agregimi i të dhënave përmes kërkesës continue. Ky është një mekanizëm që aktivizon automatikisht një kërkesë në intervale të caktuara, agregon të dhënat sipas kësaj kërkese, dhe rezultati ruhet si një vlerë e re. Le të shohim me një shembull (po e shkruaj në kolonë për lehtësi leximi, por në të vërtetë do të duhet ta futja këtë komandë në një rresht)

KRIJO KËRKESËN E CONTINUAR cq_water_hourly NË homeassistant 
BEGIN 
  ZGJIDH max(value) SI vlera 
  NË homeassistant.month.water_meter_hour 
  NGA homeassistant.autogen.l 
  GRUPO NË kohë(1h), entity_id mbush(para) 
END

Kjo komandë:

  • Krijon një kërkesë të vazhdueshme me emrin cq_water_cold_hourly në databazën homeassistant
  • Kërkesa do të ekzekutohet çdo orë (kohë(1h))
  • Kërkesa do të nxjerrë të gjitha të dhënat nga matja homeassistant.autogen.l (litra), duke përfshirë leximet e ujit të ftohtë dhe të nxehtë
  • Të dhënat e agreguara do të grupohen sipas entity_id, që do të krijojë vlera të veçanta për ujin e ftohtë dhe të nxehtë
  • Duke qenë se matësi i litrit është një sekuencë që rritet monotone brenda çdo ore, do të merret vlera maksimale, prandaj agregimi do të kryhet nga funksioni max(value)
  • Vlera e re do të shkruhet në homeassistant.month.water_meter_hour, ku month është emri i politikës së mbajtjes me një afat ruajtjeje prej një muaji. Të dhënat për ujin e ftohtë dhe të nxehtë do të shpërndahen në regjistrime të veçanta me entity_id përkatës dhe vlera në fushën value

Në natë ose kur nuk ka askënd në shtëpi, konsumi i ujit nuk është, dhe për pasojë nuk ka regjistrime të reja në homeassistant.autogen.l. Për të shmangur boshllëqe në vlerat e kërkesave të zakonshme mund të përdorni fill(previous). Kjo do ta detyrojë InfluxDB të përdorë vlerën e orës së kaluar.

Fatkeqësisht, ka një veçori për pyetjen e vazhdueshme: truku fill(previous) nuk funksionon dhe regjistrimet thjesht nuk krijohen. Kjo është një problem që duket se është i pakalueshëm, dhe po diskutohet tashmë për një kohë të gjatë.Me këtë problem do të merremi më vonë, ndërsa fill(previous) në pyetjen e vazhdueshme le të qendrojë — nuk dëmton.

Le të shohim se çfarë kemi arritur (sigurisht, duhet të presim disa orë):

> 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

Ju kujdes, se vlerat në bazë ruajten në UTC, prandaj në këtë listë ndryshojnë me 3 orë — vlerat për nëntë mëngjesi në daljen InfluxDB përputhen me vlerat për dymbëdhjetë në grafikët më sipër. Gjithashtu, ju lutemi vini re se nga ora dy deri në pesë mëngjesi thjesht nuk ka shenja — kjo është veçoria e kërkesës continue.

Siç e shihni, vlera e grumbulluar gjithashtu është një sekuencë monotone në rritje, vetëm se shënimet ndryshojnë më rrallë — çdo orë. Por kjo nuk është problem — ne mund të shkruajmë një kërkesë tjetër që do të nxjerrë të dhënat e sakta për grafikun.

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)

Le të shpjegoj:

  • Nga baza homeassistant.month.water_meter_hour do të nxjerrim të dhëna për entity_id=’water_meter_cold’ për 24 orët e fundit (time >= now() -24h).
  • Siç e përmenda më parë, në sekvencën homeassistant.month.water_meter_hour mund të mungojnë disa shënime. Ne do t'i gjenerojmë këto të dhëna përsëri, duke ekzekutuar një kërkesë me GROUP BY time(1h). Këtë herë fill(previous) do të funksionojë siç duhet, duke gjeneruar të dhënat mungesë (funksioni do të marrë vlerën e mëparshme).
  • E rëndësishme në këtë kërkesë është funksioni difference, i cili do të llogarisë ndryshimin midis shënimeve të orës. Ai vetë nuk funksionon dhe kërkon një funksion agregues. Le të jetë max() që është përdorur më parë.

Rezultati i ekzekutimit duket kështu

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

Nga ora 2 deri në 5 të mëngjesit (UTC) nuk pati konsum. Megjithatë, kërkesa do të kthejë të njëjtin vlerë të konsumit falë fill(previous), ndërsa funksioni difference do ta heqë këtë vlerë nga vetvetja dhe në dalje do të kemi 0, që është në fakt ajo që ne kërkojmë.

Tani mbetet vetëm të ndërtosh grafikun. Për këtë, do të hapim Grafana, do të hapim një tabela ekzistuese (ose do të krijojmë një të re), do të krijojmë një panel të ri. Cilësimet e grafikëve do të jenë të tilla.

Shtëpia e mençur: Ndërtojmë grafikët e konsumit të ujit dhe energjisë elektrike në Home Assistant

Unë do të tregoj të dhënat për ujë të ftohtë dhe të ngrohtë në një grafik. Kërkesa është pikërisht ajo që e përshkrova më sipër.

Parametrat e shfaqjes caktohen kështu. Në rastin tim do të kem një grafik me linja (lines), i cili do të jetë me hapa (stairs). Parametri Stack do ta shpjegoj pak më poshtë. Ka disa parametra të tjerë shfaqjeje më poshtë, por ato nuk janë aq interesante.

Shtëpia e mençur: Ndërtojmë grafikët e konsumit të ujit dhe energjisë elektrike në Home Assistant

Për të shtuar grafikun e marrë në home assistant duhet:

  • të dalësh nga moda e redaktimit të grafikëve. për një arsye të panjohur, caktimet e sakta të ndarjes së grafikëve ofrohen vetëm nga faqja e panelit.
  • Të klikosh në trekëndëshin pranë emrit të grafikët, në menu të zgjedhësh share.
  • Në dritaren e hapur të kalosh në tab-in embed.
  • Të hiqni shenjën aktuale të gamës së kohës — gamën e kohës do ta caktojmë përmes URL-së.
  • Të zgjedhësh temën e nevojshme. Në rastin tim kjo është light.
  • Të kopjosh URL-në e atëhershme në kartelën e cilësimeve 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"

Vini re se gamë e kohës (dy ditët e fundit) caktohet pikërisht këtu, e jo në cilësimet e panelit.

Grafiku duket kështu. Unë nuk kam përdorur ujë të nxehtë për dy ditët e fundit, prandaj çizmet vetëm grafikun e ujit të ftohtë.

Shtëpia e mençur: Ndërtojmë grafikët e konsumit të ujit dhe energjisë elektrike në Home Assistant

Nuk e kam vendosur ende se cilin grafik e preferoj më shumë, atë me vijë të shkallëzuar ose me shtylla reale. Prandaj, thjesht do të sjell një shembull grafik të përditshëm të konsumit, këtë herë me shtylla. Kërkesat ndërtohen njësoj siç përshkruheshin më sipër. Parametrat e shfaqjes janë të tillë:

Shtëpia e mençur: Ndërtojmë grafikët e konsumit të ujit dhe energjisë elektrike në Home Assistant

Ky grafik duket kështu:

Shtëpia e mençur: Ndërtojmë grafikët e konsumit të ujit dhe energjisë elektrike në Home Assistant

Ky është parametri Stack. Në këtë grafik, shtylla e ujit të ftohtë vizatohet mbi shtyllën e ujit të ngrohtë. Në total, lartësia përfaqëson konsum total të ujit të ftohtë dhe të ngrohtë për periudhën.

Të gjithë grafiket e paraqitur janë dinamikë. Mund të kaloni me miun mbi pikën e interesit dhe të shihni detajet dhe vlerën në pikën specifike.

Fatkeqësisht, pa disa pika të hidhura nuk do të ndodhte. Në grafikun me shtylla (ndryshe nga ai me vijë të shkallëzuar), mesi i shtyllës nuk qëndron në mes të ditës, por në orën 00:00. Pra, gjysma e majtë e shtyllës është vizatuar në vendin e ditës së kaluar. Pra, grafiket për të shtunën dhe të dielën janë vizatuar pak majtas nga zona bluese. Deri tani nuk kam gjetur një mënyrë si ta zgjidh këtë problem.

Një problem tjetër është pamundësia për të punuar siç duhet me intervalet mujore. Çështja është se gjatësi e orës/ditës/java është fiks, ndërsa gjatësi e muajit është çdo herë e ndryshme. InfluxDB është në gjendje të punojë vetëm me intervale të njëjta. Aktualisht kam arritur të caktoj një interval të fikst 30 ditësh. Po, grafiku gjatë vitit do të ketë disa shpërqendrime dhe kolonat nuk do të përputhen saktësisht me muajt. Por, pasi që kjo është interesante për mua si një matës, do ta pranoj këtë.

Shikoj të paktën dy zgjidhje:

  • Të nënvleftësoj grafiku mujore dhe të kufizohem me ato javore. 52 kolona javore në vit duken mjaft mirë.
  • Të llogaris konsumimin mujor si metodë e dytë dhe të përdor grafana vetëm për grafika të bukura. Do të rezultojë një zgjidhje mjaft e saktë. Mund të mbivendos grafikat nga viti i kaluar për krahasim — grafana e bën këtë gjithashtu.

Përfundimi

Nuk e di pse, por më pëlqen shumë ky lloj grafiku. Ato tregojnë se jeta është dinamike dhe gjithçka po ndryshon. Dje kishte shumë, sot ka pak, nesër do të jetë ndryshe. Mbetet të punoj me anëtarët e familjes mbi temën e konsumit. Por përderisa kërkesat aktuale janë kështu, thjesht një numër i madh dhe i paqartë në faturë tashmë shndërrohet në një pamje mjaft të qartë të konsumit.

Pavarësisht një karriere gati 20-vjeçare si programues, kam pasur pak përvojë me bazat e të dhënave. Prandaj, instalimi i një baze të dhënash të jashtme më dukej si diçka shumë komplekse dhe e paqartë. Gjithçka ndryshoi artikulli i përmendur më sipër – duke u treguar se lidhja e një instrumenti të përshtatshëm bëhet me disa klikime, dhe me një instrument të specializuar, detyra e ndërtimit të grafikëve bëhet pak më e lehtë.

Në titullin kam përmendur konsumimin e energjisë elektrike. Fatkeqësisht, në këtë moment nuk mund të sjell asnjë grafik. Një matës SDM120 më ka ndalur, ndërsa tjetri ka probleme kur i qaset nëpërmjet Modbus. Megjithatë, kjo nuk ndikon aspak në temën e këtij artikulli – grafikët do të ndërtohen në të njëjtën mënyrë si për ujin.

Në këtë artikull kam sjellë qasjet që kam provuar vetë. Sigurisht, ka edhe metoda të tjera për organizimin e mbledhjes dhe vizualizimit të të dhënave, për të cilat nuk kam dijeni. Më tregoni për to në komentet, do të më interesonte shumë. Do të isha i lumtur për kritikat konstruktive dhe idetë e reja. Shpresoj se materiali i shpjeguar do t'i ndihmojë gjithashtu dikujt.

Burimi: habr.com

Bleni hostim të besueshëm për faqe me mbrojtje nga DDoS, serverë VPS VDS 🔥 Bleni hostim të besueshëm për faqe me mbrojtje nga DDoS, serverë VPS VDS | ProHoster