Smart home: We bouwen grafieken van het water- en elektriciteitsverbruik in Home Assistant

Smart home: We bouwen grafieken van het water- en elektriciteitsverbruik in Home Assistant
Elke keer dat ik een betaling ontvang voor elektriciteit en water, ben ik verrast: verbruikt mijn gezin echt zoveel? Nou ja, de badkamer heeft vloerverwarming en een boiler, maar ze branden niet altijd in brand. We lijken ook water te besparen (al spetteren we ook graag in de badkamer). Een aantal jaren geleden heb ik al aangesloten watermeters и elektriciteit naar een slim huis, maar daar liepen de zaken vast. We zijn nu pas begonnen met het analyseren van het verbruik, en daar gaat dit artikel eigenlijk over.

Ik ben onlangs overgestapt op Home Assistant als mijn smart home-systeem. Een van de redenen was juist de mogelijkheid om het verzamelen van een grote hoeveelheid gegevens te organiseren met de mogelijkheid om gemakkelijk verschillende soorten grafieken te construeren.

De informatie die in dit artikel wordt beschreven is niet nieuw; al deze dingen onder verschillende sauzen zijn al op internet beschreven. Maar elk artikel beschrijft doorgaans slechts één benadering of aspect. Ik moest al deze benaderingen vergelijken en zelf de meest geschikte kiezen. Het artikel geeft nog steeds geen uitgebreide informatie over het verzamelen van gegevens, maar is een soort samenvatting van hoe ik het heb gedaan. Constructieve kritiek en suggesties voor verbetering zijn dus welkom.

Formulering van het probleem

Het doel van de oefening van vandaag is dus om mooie grafieken te krijgen van het water- en elektriciteitsverbruik:

  • Per uur gedurende 2 dagen
  • Dagelijks gedurende 2 weken
  • (optioneel) wekelijks en maandelijks

Hierbij zijn enkele moeilijkheden:

  • De standaardkaartcomponenten zijn doorgaans behoorlijk slecht. In het beste geval kunt u een lijngrafiek opbouwen met punten.

    Als u goed zoekt, kunt u componenten van derden vinden die de mogelijkheden van het standaarddiagram uitbreiden. Voor een thuisassistent is dit in principe een goed en mooi onderdeel mini-grafiekkaart, maar het is ook enigszins beperkt:

    • Het is moeilijk om de parameters van een staafdiagram over grote intervallen in te stellen (de breedte van de staaf wordt ingesteld in fracties van een uur, wat betekent dat intervallen langer dan een uur in fracties worden ingesteld)
    • U kunt geen verschillende entiteiten aan één grafiek toevoegen (bijvoorbeeld temperatuur en vochtigheid, of een staafdiagram combineren met een lijn)
  • Niet alleen gebruikt de thuisassistent standaard de meest primitieve SQLite-database (en ik, een klusjesman, kon het installeren van MySQL of Postgres niet aan), maar de gegevens worden ook niet op de meest optimale manier opgeslagen. Dus elke keer dat u bijvoorbeeld zelfs de kleinste digitale parameter van een parameter wijzigt, wordt er een enorme json van ongeveer een kilobyte groot naar de database geschreven
    {"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}}}

    Ik heb behoorlijk veel sensoren (temperatuursensoren in elke kamer, water- en elektriciteitsmeters), en sommige genereren ook behoorlijk veel gegevens. De elektriciteitsmeter SDM220 alleen al genereert bijvoorbeeld elke 10-15 seconden ongeveer een dozijn waarden, en ik zou graag ongeveer 8 van dergelijke meters willen installeren.Er zijn ook een hele reeks parameters die worden berekend op basis van andere sensoren. Dat. al deze waarden kunnen de database gemakkelijk dagelijks met 100-200 MB opblazen. Binnen een week zal het systeem nauwelijks bewegen, en binnen een maand zal de flashdrive het begeven (in het geval van een typische thuisassistent-installatie op een Raspberry PI), en het opslaan van gegevens gedurende een heel jaar is uitgesloten.

  • Als u geluk heeft, kan uw meter het verbruik zelf tellen. U kunt op elk moment naar de meter gaan en vragen hoe laat de opgetelde verbruikswaarde is. In de regel bieden alle elektriciteitsmeters die over een digitale interface (RS232/RS485/Modbus/Zigbee) beschikken deze mogelijkheid.

    Het is nog erger als het apparaat eenvoudigweg een momentane parameter kan meten (bijvoorbeeld onmiddellijk vermogen of stroom), of eenvoudigweg elke X wattuur of liter pulsen kan genereren. Dan moet je nadenken over hoe en waarmee je het moet integreren en waar je waarde kunt accumuleren. Het risico bestaat dat u om welke reden dan ook het volgende rapport mist, en de nauwkeurigheid van het systeem als geheel roept vragen op. Je kunt dit alles natuurlijk toevertrouwen aan een smart home-systeem als Home Assistant, maar niemand heeft het punt over het aantal records in de database geannuleerd en het zal niet mogelijk zijn om sensoren vaker dan één keer per seconde te ondervragen (een beperking van de thuisassistent-architectuur).

Benadering 1

Laten we eerst eens kijken wat de thuisassistent standaard biedt. Het meten van het verbruik over een periode is een zeer gewilde functionaliteit. Het is natuurlijk al lang geleden geïmplementeerd in de vorm van een gespecialiseerd onderdeel: utility_meter.

De essentie van de component is dat deze intern een variabele huidige_geaccumuleerde_waarde creëert en deze na een bepaalde periode (uur/week/maand) opnieuw instelt. De component zelf bewaakt de invoervariabele (de waarde van een of andere sensor), onderschrijft zichzelf op veranderingen in de waarde - u krijgt gewoon het eindresultaat. Dit ding wordt in slechts een paar regels in het configuratiebestand beschreven

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

Hier is sensor.water_meter_cold de huidige meterwaarde in liters die ik ontvang rechtstreeks uit het stuk ijzer door mqtt. Het ontwerp creëert twee nieuwe sensoren water_cold_hour_um en water_cold_day_um, die uur- en dagwaarden verzamelen en deze na het verstrijken van de periode op nul zetten. Hier is een grafiek van de batterij per uur voor een halve dag.

Smart home: We bouwen grafieken van het water- en elektriciteitsverbruik in Home Assistant

De code voor uur- en daggrafieken voor lovelace-UI ziet er als volgt uit:

      - 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

Eigenlijk ligt het probleem met deze aanpak in dit algoritme. Zoals ik al zei, wordt voor elke invoerwaarde (huidige meterstand voor elke volgende liter) 1 kb aan records gegenereerd in de database. Elke energiemeter genereert ook een nieuwe waarde, die ook aan de basis wordt toegevoegd. Als ik de gegevens per uur/dag/week/maand wil verzamelen, en voor meerdere waterstijgleidingen, en een pakket elektrische meters wil toevoegen, zal dat een hoop gegevens zijn. Om precies te zijn: er zijn niet veel gegevens, maar omdat de thuisassistent een heleboel onnodige informatie naar de database schrijft, zal de omvang van de database met grote sprongen groeien. Ik ben bang om zelfs maar de omvang van de basis voor wekelijkse en maandelijkse grafieken te schatten.

Bovendien lost de energiemeter op zichzelf het probleem niet op. De grafiek van de waarden die door de nutsmeter worden geproduceerd, is een monotoon stijgende functie die elk uur op 0 wordt gereset. We hebben een verbruiksgrafiek nodig die begrijpelijk is voor de gebruiker en die laat zien hoeveel liter er gedurende de periode is verbruikt. De standaard component van de geschiedenisgrafiek kan dit niet doen, maar de externe component van de minigrafiekkaart kan ons helpen.

Dit is de kaartcode voor 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'

Naast standaardinstellingen zoals sensornaam, grafiektype, kleur (ik vond het standaard oranje niet leuk), is het belangrijk om 3 instellingen te noteren:

  • group_by:hour — de grafiek wordt gegenereerd met de balken uitgelijnd op het begin van het uur
  • points_per_hour: 1 - één balk voor elk uur
  • En het allerbelangrijkste: aggregate_func: max - neem de maximale waarde binnen elk uur. Het is deze parameter die de zaagtandgrafiek in staven verandert

Smart home: We bouwen grafieken van het water- en elektriciteitsverbruik in Home Assistant

Let niet op de rij kolommen aan de linkerkant: dit is het standaardgedrag van de component als er geen gegevens zijn. Maar er waren geen gegevens - ik heb de gegevensverzameling met behulp van de nutsmeter pas een paar uur geleden ingeschakeld, alleen ter wille van dit artikel (ik zal mijn huidige aanpak iets lager beschrijven).

Op deze foto wilde ik laten zien dat de gegevensweergave soms zelfs werkt en dat de balken daadwerkelijk de juiste waarden weergeven. Maar dat is niet alles. Om de een of andere reden geeft de geselecteerde kolom voor de periode van 11 tot 12 uur 's ochtends 19 liter weer, hoewel we op de toothy grafiek iets hoger voor dezelfde periode van dezelfde sensor een verbruik van 62 liter zien. Of er zit een bug in, of de handen zijn krom. Maar ik begrijp nog steeds niet waarom de gegevens aan de rechterkant zijn afgebroken - het verbruik was daar normaal, wat ook zichtbaar is in de brede grafiek.

Over het algemeen kon ik de plausibiliteit van deze benadering niet onderkennen - de grafiek vertoont bijna altijd een vorm van ketterij.

Soortgelijke code voor de dagsensor.

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

Houd er rekening mee dat de parameter group_by is ingesteld op interval en dat de parameter points_per_hour alles regelt. En dit is een ander probleem met dit onderdeel: points_per_hour werken goed op grafieken van een uur of minder, maar walgelijk op grotere intervallen. Om dus één kolom op één dag te krijgen, moest ik de waarde 1/24=0.04166666 invoeren. Ik heb het niet over wekelijkse en maandelijkse grafieken.

Benadering 2

Terwijl ik nog bezig was met het uitzoeken van de thuisassistent, kwam ik deze video tegen:


De kameraad verzamelt verbruiksgegevens van verschillende soorten Xiaomi-stopcontacten. Zijn taak is iets eenvoudiger: geef gewoon de waarde van het verbruik weer voor vandaag, gisteren en voor de maand. Geen grafieken vereist.

Laten we de discussies over de handmatige integratie van momentane machtswaarden buiten beschouwing laten - ik schreef hierboven al over de "nauwkeurigheid" van deze aanpak. Het is niet duidelijk waarom hij geen gebruik heeft gemaakt van de verzamelde verbruikswaarden, die al door hetzelfde verkooppunt zijn verzameld. Naar mijn mening zal integratie binnen de hardware beter werken.

Uit de video zullen we het idee overnemen om het verbruik gedurende een bepaalde periode handmatig te tellen. Voor een man worden alleen de waarden voor vandaag en gisteren in aanmerking genomen, maar we gaan verder en proberen een grafiek te tekenen. De essentie van de voorgestelde methode in mijn geval is als volgt.

Laten we een variabele waarde_op_het_begin_van_uur maken, waarin we de huidige meterstanden registreren
Met behulp van de timer berekenen we aan het einde van het uur (of aan het begin van het volgende) het verschil tussen de huidige meting en de waarde die aan het begin van het uur is opgeslagen. Dit verschil is het verbruik voor het huidige uur - we slaan de waarde op in de sensor en in de toekomst zullen we een grafiek bouwen op basis van deze waarde.
U moet ook de variabele waarde_at_beginning_of_hour “resetten” door de huidige waarde van de teller daar te schrijven.

Dit alles kan goed gedaan worden... door middel van de thuisassistent zelf.

Je zult iets meer code moeten schrijven dan bij de vorige aanpak. Laten we eerst dezelfde “variabelen” maken. Out of the box hebben we niet de “variabele” entiteit, maar we kunnen gebruik maken van de diensten van de mqtt-makelaar. We sturen daar waarden naartoe met de vlag 'retain=true' - hierdoor wordt de waarde in de makelaar opgeslagen en kan deze daar op elk moment weer uit worden gehaald, zelfs als de thuisassistent opnieuw wordt opgestart. Ik maakte uur- en dagtellers tegelijk.

- 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

Alle magie gebeurt in de automatisering, die respectievelijk elk uur en elke nacht draait.

- 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

Beide automatiseringen voeren 2 acties uit:

  • Bereken de waarde per interval als het verschil tussen de start- en eindwaarde
  • Werk de basiswaarde bij voor het volgende interval

De constructie van grafieken wordt in dit geval opgelost door de gebruikelijke geschiedenisgrafiek:

      - 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

Het ziet er zo uit:

Smart home: We bouwen grafieken van het water- en elektriciteitsverbruik in Home Assistant

In principe is dit al wat je nodig hebt. Het voordeel van deze methode is dat de gegevens één keer per interval worden gegenereerd. Die. in totaal 24 vermeldingen per dag voor de uurgrafiek.

Helaas lost dit nog steeds niet het algemene probleem van een groeiende basis op. Als ik een maandelijkse verbruiksgrafiek wil, dan moet ik gegevens minimaal een jaar bewaren. En aangezien de Home Assistant slechts één instelling voor de opslagduur voor de hele database biedt, betekent dit dat ALLE gegevens in het systeem een ​​heel jaar bewaard moeten blijven. In een jaar verbruik ik bijvoorbeeld 200 kubieke meter water, wat neerkomt op 200000 vermeldingen in de database. En als je rekening houdt met andere sensoren, wordt het cijfer over het algemeen onfatsoenlijk.

Benadering 3

Gelukkig hebben slimme mensen dit probleem al opgelost door de InfluxDB-database te schrijven. Deze database is speciaal geoptimaliseerd voor het opslaan van tijdgebaseerde gegevens en is ideaal voor het opslaan van waarden van verschillende sensoren. Het systeem biedt ook een SQL-achtige querytaal waarmee u waarden uit de database kunt extraheren en deze vervolgens op verschillende manieren kunt aggregeren. Ten slotte kunnen verschillende gegevens voor verschillende tijdstippen worden opgeslagen. Vaak veranderende metingen zoals temperatuur of vochtigheid kunnen bijvoorbeeld slechts een paar weken worden opgeslagen, terwijl metingen van het dagelijkse waterverbruik een heel jaar kunnen worden bewaard.

Naast InfluxDB hebben slimme mensen ook Grafana uitgevonden, een systeem om grafieken te tekenen uit gegevens uit InfluxDB. Grafana kan verschillende soorten diagrammen tekenen, ze tot in detail aanpassen, en, belangrijker nog, deze diagrammen kunnen worden “ingeplugd” in de lovelace-UI-thuisassistent.

geinspireerd zijn hier и hier. De artikelen beschrijven in detail het proces van het installeren en verbinden van InfluxDB en Grafana met de thuisassistent. Ik zal mij concentreren op het oplossen van mijn specifieke probleem.

Laten we dus eerst beginnen met het toevoegen van de tegenwaarde in influxDB. Een stukje van de thuisassistent-configuratie (in dit voorbeeld zal ik me niet alleen vermaken met koud, maar ook met warm water):

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

Laten we het opslaan van dezelfde gegevens in de interne database van de thuisassistent uitschakelen om deze niet nogmaals te vergroten:

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

Laten we nu naar de InfluxDB-console gaan en onze database instellen. In het bijzonder moet u configureren hoe lang bepaalde gegevens worden bewaard. Dit wordt geregeld door de zgn. bewaarbeleid - dit is vergelijkbaar met databases in de hoofddatabase, waarbij elke interne database zijn eigen instellingen heeft. Standaard worden alle gegevens toegevoegd aan het bewaarbeleid genaamd autogen, deze gegevens worden een week bewaard. Ik wil dat de gegevens per uur een maand lang worden bewaard, de wekelijkse gegevens een jaar lang en dat de maandgegevens helemaal nooit worden verwijderd. Wij zullen een passend retentiebeleid opstellen

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

In feite is de belangrijkste truc het verzamelen van gegevens met behulp van continue query's. Dit is een mechanisme dat automatisch met gespecificeerde intervallen een query start, de gegevens voor deze query samenvoegt en het resultaat aan een nieuwe waarde toevoegt. Laten we naar een voorbeeld kijken (ik schrijf in een kolom voor de leesbaarheid, maar in werkelijkheid moest ik deze opdracht op één regel invoeren)

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

Deze opdracht:

  • Creëert een doorlopende zoekopdracht met de naam cq_water_cold_hourly in de homeassistant-database
  • De query wordt elk uur uitgevoerd (time(1h))
  • Het verzoek haalt alle gegevens uit de meting 'homeassistant.autogen.l' (liters), inclusief koud- en warmwatermetingen
  • De verzamelde gegevens worden gegroepeerd op entiteit_id, waardoor we afzonderlijke waarden krijgen voor koud en warm water
  • Omdat de literteller binnen elk uur een monotoon stijgende reeks is, zal het nodig zijn om de maximale waarde te nemen, dus de aggregatie wordt uitgevoerd door de functie max(waarde)
  • De nieuwe waarde wordt geschreven naar homeassistant.month.water_meter_hour, waarbij maand de naam is van het bewaarbeleid met een bewaartermijn van één maand. Bovendien worden gegevens over koud en warm water verspreid over afzonderlijke records met de bijbehorende entiteit_id en waarde in het waardeveld

's Nachts of als er niemand thuis is, is er geen waterverbruik en zijn er dus geen nieuwe vermeldingen in homeassistant.autogen.l. Om te voorkomen dat er waarden ontbreken in reguliere zoekopdrachten, kun je fill(vorige) gebruiken. Hierdoor wordt InfluxDB gedwongen de waarde van het afgelopen uur te gebruiken.

Helaas heeft continu zoeken een eigenaardigheid: de fill(vorige)-truc werkt niet en er worden eenvoudigweg geen records gemaakt. Bovendien is dit een onoverkomelijk probleem wordt al enkele jaren besproken. We zullen dit probleem later behandelen, en het invullen (vorige) in de continue query laten staan ​​- het interfereert niet.

Laten we eens kijken wat er is gebeurd (je moet natuurlijk een paar uur wachten):

> 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

Houd er rekening mee dat de waarden in de database in UTC worden opgeslagen, dus deze lijst verschilt 3 uur - de 7am-waarden in de InfluxDB-uitvoer komen overeen met de 10am-waarden in de bovenstaande grafieken. Houd er ook rekening mee dat er tussen 2 en 5 uur simpelweg geen gegevens zijn - dit is hetzelfde kenmerk van continue zoekopdrachten.

Zoals u kunt zien, is de geaggregeerde waarde ook een monotoon stijgende reeks, alleen zijn de invoeren minder frequent: één keer per uur. Maar dit is geen probleem: we kunnen nog een query schrijven die de juiste gegevens voor het diagram extraheert.

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)

ik zal ontcijferen:

  • Uit de homeassistant.month.water_meter_hour database halen we gegevens op voor entiteit_id='water_meter_cold' voor de laatste dag (tijd >= nu() -24u).
  • Zoals ik al zei, ontbreken mogelijk enkele vermeldingen in de reeks homeassistant.month.water_meter_hour. We zullen deze gegevens opnieuw genereren door de query uit te voeren met GROUP BY time(1h). Deze keer zal fill(previous) correct werken en de ontbrekende gegevens genereren (de functie zal de vorige waarde aannemen)
  • Het belangrijkste in deze query is de verschilfunctie, die het verschil tussen de uurmarkeringen berekent. Op zichzelf werkt het niet en vereist het een aggregatiefunctie. Laat dit de max() zijn die eerder werd gebruikt.

Het uitvoeringsresultaat ziet er als volgt uit

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

Van 2 tot 5 uur (UTC) was er geen consumptie. Niettemin zal de query dezelfde verbruikswaarde retourneren dankzij fill(previous), en de verschilfunctie zal deze waarde van zichzelf aftrekken en de uitvoer zal 0 zijn, wat precies is wat nodig is.

Het enige dat u nog hoeft te doen, is een grafiek maken. Om dit te doen, opent u Grafana, opent u een bestaand (of maakt u een nieuw) dashboard en maakt u een nieuw paneel. De kaartinstellingen zijn als volgt.

Smart home: We bouwen grafieken van het water- en elektriciteitsverbruik in Home Assistant

Ik zal gegevens over koud en warm water in dezelfde grafiek weergeven. Het verzoek is precies hetzelfde als ik hierboven heb beschreven.

Weergaveparameters worden als volgt ingesteld. Voor mij wordt het een grafiek met lijnen (lijnen), die in stappen (trappen) gaat. De Stack-parameter zal hieronder worden uitgelegd. Er zijn hieronder nog een paar weergaveopties, maar deze zijn niet zo interessant.

Smart home: We bouwen grafieken van het water- en elektriciteitsverbruik in Home Assistant

Om het resulterende diagram aan de Home Assistant toe te voegen, moet je:

  • verlaat de kaartbewerkingsmodus. Om de een of andere reden worden de juiste instellingen voor het delen van diagrammen alleen aangeboden vanaf de dashboardpagina
  • Klik op het driehoekje naast de naam van het diagram en selecteer delen in het menu
  • Ga in het geopende venster naar het tabblad Insluiten
  • Schakel het huidige tijdsbereik uit - we zullen het tijdsbereik instellen via de URL
  • Selecteer het gewenste onderwerp. In mijn geval is het licht
  • Kopieer de resulterende URL naar de lovelace-UI-instellingenkaart

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

Houd er rekening mee dat het tijdsbereik (laatste 2 dagen) hier wordt ingesteld, en niet in de dashboardinstellingen.

De grafiek ziet er als volgt uit. Ik heb de afgelopen 2 dagen geen warm water gebruikt, dus alleen de koudwatergrafiek wordt getekend.

Smart home: We bouwen grafieken van het water- en elektriciteitsverbruik in Home Assistant

Ik heb nog steeds niet voor mezelf besloten welke grafiek ik leuker vind: een lijnstap of echte balken. Daarom zal ik eenvoudigweg een voorbeeld geven van een dagelijkse consumptiegrafiek, alleen deze keer in staven. Zoekvragen worden op dezelfde manier opgebouwd als de zoekvragen die hierboven zijn beschreven. De weergaveopties zijn:

Smart home: We bouwen grafieken van het water- en elektriciteitsverbruik in Home Assistant

Deze grafiek ziet er als volgt uit:

Smart home: We bouwen grafieken van het water- en elektriciteitsverbruik in Home Assistant

Dus over de Stack-parameter. In deze grafiek wordt een kolom met koud water bovenop een kolom met heet water getekend. De totale hoogte komt overeen met het totale verbruik van koud en warm water voor de periode.

Alle getoonde grafieken zijn dynamisch. U kunt de muis over het interessante punt bewegen en de details en waarde op een bepaald punt bekijken.

Helaas ging dit niet zonder enige vlieg in de zalf. Bij een staafdiagram (in tegenstelling tot de grafiek met staplijnen) ligt het midden van de staaf niet midden op de dag, maar om 00:00 uur. Die. de linkerhelft van de balk wordt op de plaats van de vorige dag getekend. De kaarten voor zaterdag en zondag zijn dus iets links van de blauwachtige zone getekend. Totdat ik erachter kwam hoe ik hem kon winnen.

Een ander probleem is het onvermogen om maandelijks goed te werken. Feit is dat de lengte van het uur/dag/week vast ligt, maar de lengte van de maand is elke keer anders. InfluxDB kan alleen met gelijke intervallen werken. Tot nu toe zijn mijn hersenen voldoende geweest om een ​​vast interval van 30 dagen in te stellen. Ja, de grafiek zal het hele jaar door een beetje zweven en de balken komen niet precies overeen met de maanden. Maar aangezien ik in dit ding geïnteresseerd ben, simpelweg als weergavemeter, vind ik het prima.

Ik zie minstens twee oplossingen:

  • Om te scoren op maandelijkse grafieken en uzelf te beperken tot wekelijkse grafieken. 52 wekelijkse repen per jaar zien er redelijk goed uit
  • Beschouw het maandelijkse verbruik zelf als methode nr. 2, en gebruik grafana alleen voor mooie grafieken. Het zal een vrij nauwkeurige oplossing zijn. Je kunt zelfs grafieken van het afgelopen jaar over elkaar heen leggen ter vergelijking. Grafana kan dat ook.

Conclusie

Ik weet niet waarom, maar ik hou van dit soort grafieken. Ze laten zien dat het leven in volle gang is en dat alles verandert. Gisteren was er veel, vandaag is er weinig, morgen zal er iets anders zijn. Er moet nog met huishoudens worden samengewerkt op het gebied van consumptie. Maar zelfs met de huidige eetlust verandert slechts een groot en onbegrijpelijk cijfer op de rekening al in een redelijk begrijpelijk beeld van de consumptie.

Ondanks mijn bijna twintigjarige carrière als programmeur had ik vrijwel geen contact met databases. Daarom leek het installeren van een externe database zoiets duisters en onbegrijpelijks. Alles veranderd het bovenstaande artikel - het bleek dat het vastschroeven van een geschikt gereedschap met een paar klikken gebeurt, en met een gespecialiseerd gereedschap wordt de taak van het plotten een beetje eenvoudiger.

In de titel vermeldde ik het elektriciteitsverbruik. Helaas kan ik op dit moment geen grafieken verstrekken. Eén SDM120-meter stierf voor mij, en de andere haperde bij toegang via Modbus. Dit heeft echter op geen enkele manier invloed op het onderwerp van dit artikel - de grafieken zullen op dezelfde manier worden opgebouwd als voor water.

In dit artikel presenteerde ik de benaderingen die ik zelf probeerde. Er zijn vast nog een aantal andere manieren om het verzamelen en visualiseren van gegevens te organiseren waar ik niets vanaf weet. Vertel me erover in de reacties, ik ben erg geïnteresseerd. Ik zal blij zijn met opbouwende kritiek en nieuwe ideeën. Ik hoop dat het gepresenteerde materiaal ook iemand zal helpen.

Bron: www.habr.com

Voeg een reactie