
Ogni volta che ricevo la bolletta per l'elettricità e l'acqua mi sorprendo: la mia famiglia consuma così tanto? Certo, abbiamo il riscaldamento a pavimento e un boiler in bagno, ma non è che vadano a pieno regime tutto il tempo. Cerchiamo di risparmiare acqua (anche se ci piace fare un bel bagno). Negli ultimi anni ho già e alla casa intelligente, ma l'analisi del consumo si è fermata lì. Solo ora mi sono dedicato a questo, e infatti, ecco l'articolo.
Di recente sono passato a Home Assistant come sistema di casa intelligente. Una delle ragioni è stata proprio la possibilità di raccogliere grandi quantità di dati con l'opzione di creare vari grafici in modo comodo.
Le informazioni descritte in questo articolo non sono nuove; tutte queste cose sono già state descritte in vari modi su Internet. Tuttavia, ogni articolo di solito affronta solo un approccio o un aspetto specifico. Ho dovuto confrontare tutti questi approcci e scegliere quello più adatto. L'articolo non offre informazioni esaustive sulla raccolta dei dati, ma è una sorta di riassunto di come ho proceduto. Quindi, si accettano critiche costruttive e suggerimenti per miglioramenti.
Definizione del compito
Quindi, l'obiettivo di questo esercizio è ottenere grafici belli sul consumo di acqua ed elettricità:
- Orario per 2 giorni
- Giornaliere per 2 settimane
- (opzionale) settimanali e mensili
Qui ci troviamo di fronte a alcune difficoltà:
- I componenti standard dei grafici sono generalmente piuttosto scadenti. Al massimo, si può costruire un grafico a linee basato su punti.
Se si cerca bene, è possibile trovare componenti di terze parti che ampliano le capacità del grafico standard. Per home assistant, c'è un componente abbastanza buono e bello chiamato , ma anche questo ha alcune limitazioni:
- È difficile impostare i parametri del grafico a barre su intervalli ampi (la larghezza della barra è impostata in frazioni di ora, quindi intervalli più lunghi di un'ora saranno rappresentati con numeri decimali)
- Non è possibile aggiungere diverse entità a un unico grafico (ad esempio, temperatura e umidità, o combinare un grafico a barre con una linea)
- Non solo Home Assistant utilizza di default il database SQLite più semplice, ma i dati sono anche conservati in modo non ottimale. Ad esempio, ad ogni modifica di ogni singolo parametro numerico, viene salvato un enorme JSON di circa un kilobyte nel database.
{"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}}}Ho un bel po' di sensori (sensori di temperatura in ogni stanza, contatori d'acqua e di elettricità), e alcuni di essi generano anche un sacco di dati. Ad esempio, solo il contatore elettrico SDM220 genera circa una decina di valori ogni 10-15 secondi, e vorrei installarne circa 8. Ci sono anche una serie di parametri che vengono calcolati sulla base di altri sensori. Di conseguenza, tutti questi valori possono facilmente gonfiare il database di 100-200 MB al giorno. Dopo una settimana, il sistema sarà praticamente ingolfato, e dopo un mese la memoria flash smetterà di funzionare (nel caso di una tipica installazione di Home Assistant su Raspberry Pi), e nemmeno si può parlare di conservare i dati per un intero anno.
- Se sei fortunato, il tuo contatore è in grado di calcolare autonomamente il consumo. Puoi rivolgersi al contatore in qualsiasi momento e chiedere quale sia il valore accumulato. Di solito, tutti i contatori di elettricità che hanno un'interfaccia digitale (RS232/RS485/Modbus/Zigbee) offrono questa possibilità.
È problematico se un dispositivo può semplicemente misurare un certo parametro istantaneo (ad esempio, potenza istantanea o corrente), o semplicemente generare impulsi ogni X watt-ora o litri. In tal caso, è necessario riflettere su come e con cosa integrare questi dati e dove conservare il valore. C'è il rischio di saltare un report per qualche motivo, ed anche l'accuratezza complessiva del sistema solleva delle domande. Certo, si potrebbe affidare tutto a un sistema di smart home come Home Assistant, ma il punto riguardo al numero di registrazioni nel database non può essere ignorato, e non è possibile interrogare i sensori più frequentemente di una volta al secondo (limitazione dell'architettura di Home Assistant).
Approccio 1
Iniziamo a vedere cosa offre Home Assistant di default. La misurazione del consumo su un periodo è una funzionalità molto richiesta. Naturalmente, è stata implementata da tempo come componente specializzato: utility_meter.
Il concetto principale del componente è che al suo interno crea una variabile chiamata valore_totale_attuale e la resetta al termine di un periodo specifico (ora/settimana/mese). Il componente monitora autonomamente la variabile in ingresso (il valore di un sensore) e si iscrive ai cambiamenti di valore — tu ricevi semplicemente il risultato finale. Questa cosa è descritta in poche righe nel file di configurazione.
utility_meter:
water_cold_hour_um:
source: sensor.water_meter_cold
cycle: hourly
water_cold_day_um:
source: sensor.water_meter_cold
cycle: daily
Qui sensor.water_meter_cold rappresenta l'attuale lettura del contatore in litri, che ricevo via mqtt. La costruzione crea 2 nuovi sensori water_cold_hour_um e water_cold_day_um, che accumulano i dati orari e giornalieri, azzerandoli al termine del periodo. Ecco il grafico dell'accumulatore orario per mezza giornata.

Il codice per i grafici orari e giornalieri per lovelace-UI è il seguente:
- type: history-graph
title: 'Consumo d'acqua orario usando variabili'
hours_to_show: 48
entities:
- sensor.water_hour
- type: history-graph
title: 'Consumo d'acqua giornaliero usando variabili'
hours_to_show: 360
entities:
- sensor.water_day
In questo algoritmo risiede il problema di questo approccio. Come ho già accennato, per ogni valore in ingresso (la lettura attuale del contatore per ogni litro successivo) viene generato 1 KB di registrazione nel database. Ogni utility meter genera anche un nuovo valore, che viene aggiunto al database. Se voglio raccogliere letture orarie/giornaliere/settimanali/mensili, oltre a diversi gruppi di contatori dell'acqua, aggiungendo anche una serie di contatori elettrici, ci saranno davvero moltissimi dati. In effetti, i dati non sono tanti, ma poiché home assistant scrive una quantità enorme di informazioni nel database, la dimensione del database crescerà in modo esponenziale. Ho paura anche solo di ipotizzare la dimensione del database per grafici settimanali e mensili.
In aggiunta, l'utility meter di per sé non risolve il compito assegnato. Il grafico dei valori forniti dall'utility meter è una funzione monotonamente crescente, che si azzera ogni ora. Ciò di cui abbiamo bisogno è un grafico di consumo comprensibile per l'utente, che mostri quanti litri sono stati consumati durante un periodo. Il componente standard history-graph non riesce a farlo, ma possiamo utilizzare il componente esterno mini-graph-card.
Ecco il codice della scheda per lovelace-UI:
- aggregate_func: max
entities:
- color: var(--primary-color)
entity: sensor.water_cold_hour_um
group_by: hour
hours_to_show: 48
name: "Consumo orario d'acqua aggregato per contatore utility"
points_per_hour: 1
show:
graph: bar
type: 'custom:mini-graph-card'Oltre alle impostazioni standard come il nome del sensore, il tipo di grafico, il colore (l'arancione standard non mi piace), qui è importante notare 3 impostazioni:
- group_by:hour — il grafico verrà generato allineando le barre all'inizio dell'ora
- points_per_hour: 1 — una barra per ogni ora
- E la cosa più importante, aggregate_func: max — prendere il valore massimo all'interno di ogni ora. Questo parametro trasforma il grafico a zigzag in barre.

Non preoccupatevi delle barre a sinistra — è il comportamento standard del componente se non ci sono dati. E non c'erano dati — ho appena attivato la raccolta dati dal contatore utility solo per questo articolo (condividerò il mio approccio attuale più avanti).
In questa immagine volevo mostrare che a volte la visualizzazione dei dati funziona effettivamente, e le colonne riflettono i valori corretti. Solo che non sono del tutto accurate. La colonna evidenziata per l'intervallo dalle 11 alle 12 di mattina mostra per qualche motivo 19 litri, mentre nel grafico a zigzag un po' più in alto per lo stesso periodo e dallo stesso sensore vediamo un consumo di 62 litri. O è un bug, o sono stati fatti errori nella registrazione. Non ho ancora capito perché i dati siano mancanti a destra — il consumo lì era nella norma, come mostrato anche dal grafico a zigzag.
In generale, non sono riuscito a ottenere credibilità con questo approccio: il grafico mostra quasi sempre qualcosa di assurdo.
Codice analogo per il sensore giornaliero.
- aggregate_func: max
entities:
- color: var(--primary-color)
entity: sensor.water_cold_day_um
group_by: interval
hours_to_show: 360
name: "Consumo giornaliero d'acqua aggregato per contatore"
points_per_hour: 0.0416666666
show:
graph: bar
type: 'custom:mini-graph-card'
Si prega di notare che il parametro group_by è impostato sul valore interval, e controlla il parametro points_per_hour. Qui si presenta un altro problema di questo componente: points_per_hour funziona bene su grafici di un'ora o meno, ma è scadente su intervalli più lunghi. Pertanto, per ottenere una colonna per un giorno, è stato necessario impostare il valore 1/24=0,04166666. Non parlo nemmeno dei grafici settimanali e mensili.
Approccio 2
Mentre mi abituo a Home Assistant, ho trovato questo video:

Un amico raccoglie dati sul consumo da diversi tipi di prese Xiaomi. Il suo compito è un po' più semplice: deve solo visualizzare il valore del consumo per oggi, ieri e per il mese. Non sono necessari grafici.
Lasciamo da parte le considerazioni sull'integrazione manuale dei valori istantanei di potenza: sulla “precisione” di questo approccio ne ho già scritto sopra. Non è chiaro perché non abbia utilizzato i valori accumulati di consumo, già raccolti dalla stessa presa. A mio avviso, l'integrazione all'interno del dispositivo funzionerebbe meglio.
Dal video prenderemo l'idea di un conteggio manuale del consumo durante un periodo. L'uomo considera solo i valori di oggi e di ieri, ma noi andremo oltre e cercheremo di tracciare un grafico. L'essenza del metodo proposto nel mio caso è la seguente.
Definiremo una variabile valore_all_inizio_dell_ora, in cui registreremo le letture attuali del contatore.
A fine ora (o all'inizio della successiva), calcoleremo la differenza tra la lettura attuale e quella memorizzata all'inizio dell'ora. Questa differenza sarà il consumo dell'ora corrente — salveremo il valore nel sensore e in futuro costruiremo un grafico basato su questo valore.
Dobbiamo anche "azzerare" la variabile valore_all_inizio_dell_ora registrando il valore attuale del contatore.
Tutto questo può essere fatto tramite gli strumenti stessi di home assistant.
Il codice richiederà un po' più di scrittura rispetto all'approccio precedente. Iniziamo a definire queste "variabili". Non abbiamo un'entità "variabile" pronta all'uso, ma possiamo avvalerci dei servizi di un broker MQTT. Invieremo i valori con il flag retain=true — questo salverà il valore all'interno del broker, e potrà essere estratto in qualsiasi momento, anche dopo il riavvio di Home Assistant. Ho creato contatori orari e giornalieri.
- 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: lTutta la magia avviene nell'automazione, che si attiva ogni ora e ogni notte di conseguenza.
- 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: trueEntrambe le automazioni eseguono 2 azioni:
- Calcolano il valore per l'intervallo come differenza tra il valore iniziale e quello finale
- Aggiornano il valore di base per il prossimo intervallo
La costruzione dei grafici in questo caso si risolve in un normale history-graph:
- type: history-graph
title: 'Consumo d'acqua orario usando variabili'
hours_to_show: 48
entities:
- sensor.water_hour
- type: history-graph
title: 'Consumo d'acqua giornaliero usando variabili'
hours_to_show: 360
entities:
- sensor.water_daySi presenta così:

In linea di principio, questo è già ciò di cui hai bisogno. Il vantaggio di questo metodo è che i dati vengono generati una sola volta per intervallo. Cioè, solo 24 registrazioni al giorno per un grafico orario.
Sfortunatamente, questo non risolve il problema generale di una crescente base di dati. Se volessi un grafico del consumo mensile, dovrei conservare i dati per almeno un anno. E poiché l'home assistant fornisce solo un'impostazione della durata di archiviazione per l'intera base, ciò significa che TUTTI i dati nel sistema dovranno essere conservati per un intero anno. Ad esempio, in un anno consumo 200 metri cubi d'acqua, il che significa 200.000 registrazioni nella base. E se consideriamo anche altri sensori, il numero diventa davvero inappropriato.
Approccio 3
Fortunatamente, persone intelligenti hanno già risolto questo problema scrivendo il database InfluxDB. Questo database è appositamente ottimizzato per la conservazione di dati basati sul tempo ed è perfetto per l'archiviazione dei valori dei vari sensori. Il sistema offre inoltre un linguaggio di query simile a SQL, che permette di estrarre valori dal database e poi aggregarli in vari modi. Infine, dati diversi possono essere conservati per tempi diversi. Ad esempio, letture che cambiano frequentemente come temperatura o umidità possono essere conservate per sole due settimane, mentre i dati quotidiani sul consumo d'acqua possono essere conservati per un intero anno.
Oltre a InfluxDB, persone intelligenti hanno anche inventato Grafana, un sistema per la creazione di grafici basato su dati di InfluxDB. Grafana è in grado di disegnare diversi tipi di grafici, personalizzandoli in dettaglio e, cosa più importante, questi grafici possono essere "inseriti" nell'interfaccia lovelace di Home Assistant.
Ispirarsi e . Gli articoli descrivono dettagliatamente il processo di installazione e connessione di InfluxDB e Grafana a Home Assistant. Io mi concentrerò sulla risoluzione del mio compito specifico.
Quindi, per prima cosa iniziamo a registrare il valore del contatore in InfluxDB. Ecco un pezzo di configurazione di Home Assistant (in questo esempio mi divertirò non solo con l'acqua fredda, ma anche con quella calda):
influxdb:
host: localhost
max_retries: 3
default_measurement: state
database: homeassistant
include:
entities:
- sensor.water_meter_hot
- sensor.water_meter_coldDisabilitiamo il salvataggio di questi stessi dati nel database interno di Home Assistant, per non gonfiarlo ulteriormente:
recorder:
purge_keep_days: 10
purge_interval: 1
exclude:
entities:
- sensor.water_meter_hot
- sensor.water_meter_coldOra passiamo alla console di InfluxDB e configuriamo il nostro database. In particolare, dobbiamo impostare per quanto tempo verranno memorizzati determinati dati. Questo è regolato dalla cosiddetta retention policy — è simile a database all'interno del database principale, con ogni database interno che ha le proprie impostazioni. Per impostazione predefinita, tutti i dati vengono memorizzati nella retention policy chiamata autogen, e questi dati verranno conservati per una settimana. Vorrei che i dati orari venissero conservati per un mese, quelli settimanali per un anno e quelli mensili non venissero mai eliminati. Creiamo le relative retention policy.
CREATE RETENTION POLICY "month" ON "homeassistant" DURATION 30d REPLICATION 1
CREATE RETENTION POLICY "year" ON "homeassistant" DURATION 52w REPLICATION 1
CREATE RETENTION POLICY "infinite" ON "homeassistant" DURATION INF REPLICATION 1Ora, in effetti, il trucco principale è l'aggregazione dei dati tramite una query continua. Questo è un meccanismo che esegue automaticamente una query a intervalli di tempo specificati, aggrega i dati in base a questa query e memorizza il risultato in un nuovo valore. Analizziamo attraverso un esempio (scrivo in colonna per facilitarne la lettura, ma in realtà ho dovuto inserire questo comando in un'unica riga).
CREA QUERY CONTINUA cq_water_hourly SU homeassistant
INIZIA
SELEZIONA max(value) COME valore
IN homeassistant.month.water_meter_hour
DA homeassistant.autogen.l
GRUPPA PER time(1h), entity_id fill(previous)
FINEQuesto comando:
- Crea una query continua di nome cq_water_cold_hourly nel database homeassistant
- La query verrà eseguita ogni ora (time(1h))
- La query estrarrà tutti i dati dalla misurazione homeassistant.autogen.l (litri), incluse le letture di acqua fredda e calda
- I dati aggregati verranno raggruppati per entity_id, creando così valori separati per acqua fredda e calda
- Dato che il contatore dei litri è una sequenza monotonicamente crescente, per ogni ora dovremo prendere il valore massimo, quindi l'aggregazione verrà effettuata attraverso la funzione max(value)
- Il nuovo valore verrà registrato in homeassistant.month.water_meter_hour, dove month è il nome della retention policy con un periodo di conservazione mensile. I dati sull'acqua fredda e calda verranno distribuiti in voci separate con il corrispondente entity_id e valore nel campo value
Di notte o quando non c'è nessuno a casa, il consumo d'acqua è assente, e di conseguenza non ci sono nuovi record in homeassistant.autogen.l. Per evitare che ci siano valori mancanti nelle normali query, è possibile utilizzare fill(previous). Questo forzerà InfluxDB a usare il valore dell'ora precedente.
Purtroppo, la query continua presenta una particolarità: il trucco fill(previous) non funziona e i record semplicemente non vengono creati. Inoltre, è una questione che Affronteremo questo problema in un secondo momento, mentre fill(previous) nella query continua può restare — non crea ingombri.
Controlliamo cosa siamo riusciti a ottenere (ovviamente, bisogna aspettare un paio d'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
Si prega di notare che i valori nel database sono salvati in UTC, quindi in questo elenco ci sono differenze di 3 ore — i valori delle 7 del mattino nell'output di InfluxDB corrispondono ai valori delle 10 del mattino nei grafici sopra. Inoltre, si prega di notare che tra le 2 e le 5 del mattino non ci sono registrazioni — questa è la caratteristica delle query continue.
Come potete vedere, il valore aggregato è anch'esso una sequenza monotonamente crescente, solo che le registrazioni sono meno frequenti — una volta all'ora. Ma non è un problema — possiamo scrivere un'altra query che estrarrà i dati corretti per il grafico.
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)Spiegherò:
- Estrarremo i dati dal database homeassistant.month.water_meter_hour per entity_id='water_meter_cold' nelle ultime 24 ore (time >= now() -24h).
- Come ho già menzionato, nella sequenza homeassistant.month.water_meter_hour potrebbero mancare alcune registrazioni. Questi dati li genereremo nuovamente eseguendo una query con GROUP BY time(1h). Questa volta fill(previous) funzionerà come previsto, generando i dati mancanti (la funzione prenderà il valore precedente).
- La cosa più importante in questa richiesta è la funzione difference, che calcola la differenza tra i timestamp. Di per sé non funziona e richiede una funzione di aggregazione. Lasciamo che sia max() a essere utilizzato in precedenza.
Il risultato dell'esecuzione appare così
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 72Dalle 2 alle 5 del mattino (UTC) non c'è stato consumo. Tuttavia, la richiesta restituirà lo stesso valore di consumo grazie a fill(previous), e la funzione difference sottrarrà questo valore da se stesso, ottenendo quindi 0, che è esattamente ciò che serve.
Ora resta da fare una cosa semplice: costruire un grafico. Per farlo, apriamo Grafana, apriamo un dashboard esistente (o creiamo uno nuovo) e creiamo un nuovo pannello. Le impostazioni del grafico saranno queste.

Mostrerò i dati sull'acqua fredda e calda in un unico grafico. La richiesta è esattamente quella che ho descritto sopra.
Le impostazioni di visualizzazione sono configurate in questo modo. Per me sarà un grafico a linee (lines) che segue una forma a gradini (stairs). Spiegherò il parametro Stack più avanti. Ci sono ulteriori parametri di visualizzazione sotto, ma non sono così interessanti.

Per aggiungere il grafico ottenuto in Home Assistant, è necessario:
- uscire dalla modalità di modifica del grafico. Stranamente, le impostazioni corrette per la condivisione dei grafici sono disponibili solo dalla pagina del dashboard.
- Clicca sul triangolo accanto al nome del grafico, nel menu seleziona share.
- Nella finestra aperta, vai alla scheda embed.
- Disattiva la casella current time range — il range temporale lo imposteremo tramite URL.
- Scegli il tema necessario. Nel mio caso, è light.
- Copia l'URL ottenuto nella scheda delle impostazioni 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"
Si noti che il range temporale (ultimi 2 giorni) è impostato esattamente qui, non nelle impostazioni del dashboard.
Il grafico appare così. Non ho utilizzato acqua calda negli ultimi 2 giorni, quindi viene visualizzato solo il grafico dell'acqua fredda.

Non ho ancora deciso quale grafico mi piace di più, quello a gradini o con veri e propri colonne. Pertanto, fornirò solo un esempio del grafico giornaliero dei consumi, questa volta utilizzando colonne. Le richieste sono costruite in modo simile a quanto descritto sopra. I parametri di visualizzazione sono i seguenti:

Questo è come appare il grafico:

Ecco il parametro Stack. In questo grafico, la colonna dell'acqua fredda è disegnata sopra quella dell'acqua calda. L'altezza totale corrisponde al consumo combinato di acqua fredda e calda per il periodo.
Tutti i grafici mostrati sono dinamici. Puoi posizionare il mouse su un punto di interesse per visualizzare i dettagli e il valore in un punto specifico.
Sfortunatamente, non è mancato un po' di catrame. Nel grafico a colonne (a differenza di quello a gradini), il centro della colonna non si trova a metà giornata, ma a mezzanotte. Cioè, la metà sinistra della colonna è disegnata al posto del giorno precedente. Quindi i grafici di sabato e domenica sono leggermente spostati a sinistra rispetto all'area bluastro. Finora non ho trovato un modo per risolvere questo.
Un altro problema è l'impossibilità di lavorare correttamente con gli intervalli mensili. Infatti, la durata di un'ora/giorno/settimana è fissa, mentre la durata di un mese cambia ogni volta. InfluxDB riesce a gestire solo intervalli costanti. Finora sono riuscito a impostare un intervallo fisso di 30 giorni. Sì, il grafico si discosterà leggermente nel corso dell'anno e le colonne non corrisponderanno perfettamente ai mesi. Ma poiché trovo questo strumento interessante come indicatore, va bene così.
Almeno due soluzioni mi vengono in mente:
- Ignorare i grafici mensili e limitarsi a quelli settimanali. 52 colonne settimanali in un anno si presentano bene.
- Calcolare il consumo mensile come secondo metodo e utilizzare Grafana solo per grafici esteticamente gradevoli. Risultato abbastanza preciso. È possibile sovrapporre i grafici dell'anno scorso per un confronto — Grafana è capace di farlo.
Conclusione
Non so perché, ma adoro questo tipo di grafici. Dimostrano che la vita è dinamica e tutto cambia. Ieri c'era tanto, oggi poco, domani sarà in un altro modo. Devo ancora lavorare con i miei familiari sul tema del consumo. Ma anche con le attuali abitudini, una grande e incomprensibile cifra nella bolletta si trasforma già in un quadro di consumo abbastanza chiaro.
Nonostante quasi 20 anni di carriera come programmatore, non ho mai avuto a che fare con i database. Quindi, l'installazione di un database esterno sembrava qualcosa di fin troppo complesso e astruso. Tutto è cambiato — si è scoperto che collegare lo strumento giusto è un'operazione di pochi clic, e con uno strumento specializzato, il compito di costruire grafici diventa un po' più semplice.
Nel titolo ho menzionato il consumo di elettricità. Sfortunatamente, al momento non posso mostrare alcun grafico. Un contatore SDM120 è andato in corto, e l'altro si blocca durante la comunicazione via Modbus. Tuttavia, questo non influisce sul contenuto di questo articolo: i grafici verranno costruiti nello stesso modo, come per l'acqua.
In questo articolo ho presentato gli approcci che ho provato personalmente. Sicuramente ci sono altri modi per organizzare la raccolta e la visualizzazione dei dati che non conosco. Raccontatemi nei commenti, mi piacerebbe molto saperlo. Sarò felice di ricevere critiche costruttive e nuove idee. Spero che il materiale presentato possa essere utile a qualcuno.
Fonte: habr.com
