
Ogni volta che ricevo la bolletta per l'elettricità e l'acqua mi chiedo: la mia famiglia consuma davvero così tanto? Sì, in bagno abbiamo il riscaldamento a pavimento e un boiler, ma non è che stiano sempre funzionando. Anche l'acqua la stiamo risparmiando (anche se ci piace farci un bel bagno). Qualche anno fa ho già e , ma poi tutto si è arenato. Solo ora ho finalmente trovato il tempo di analizzare il consumo, e questa è, in effetti, l'oggetto di questo articolo.
Recentemente sono passato a Home Assistant come sistema di smart home. Una delle ragioni era proprio la possibilità di raccogliere un grande numero di dati e creare vari tipi di grafici.
Le informazioni descritte in questo articolo non sono nuove, tutte queste cose sono state già trattate online in vari modi. Ma ogni articolo, di solito, tratta solo un approccio o un aspetto. Ho dovuto confrontare tutti questi approcci e scegliere quello più adatto per me. Anche se l'articolo non offre informazioni esaustive sulla raccolta dei dati, è in qualche modo un riassunto di come ho fatto io. Pertanto, sono ben accette critiche costruttive e suggerimenti per migliorare.
Definizione del compito
Quindi, l'obiettivo di questo esercizio è ottenere grafici dell'uso di acqua ed elettricità:
- Orari per 2 giorni
- Giornalieri per 2 settimane
- (opzionale) settimanali e mensili
In questo ci sono alcune complicazioni:
- I componenti standard dei grafici sono generalmente abbastanza poveri. Al meglio si può costruire un grafico a linee con i punti.
Se si cerca bene, si possono trovare componenti di terze parti che ampliano le possibilità del grafico standard. Per Home Assistant, in linea di massima, è buono e bello il componente , ma anche questo ha alcune limitazioni:
- È difficile impostare i parametri del grafico a barre su intervalli grandi (la larghezza della barra è impostata in frazioni d'ora, e quindi intervalli più lunghi di un'ora devono essere impostati con numeri decimali)
- Non puoi aggiungere entità diverse su un unico grafico (ad esempio, temperatura e umidità, o combinare un grafico a barre con una linea)
- Non solo l'home assistant utilizza per default il database SQLite più primitivo (e io, mani di gomma, non sono riuscito a installare MySQL o Postgres), ma i dati non vengono memorizzati in modo ottimale. Ad esempio, ad ogni modifica di ogni minimo parametro numerico, viene registrato 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 molti sensori (sensori di temperatura in ogni stanza, contatori d’acqua ed elettricità), e alcuni di questi generano una quantità considerevole di dati. Ad esempio, solo il contatore di elettricità SDM220 genera circa dieci valori ogni 10-15 secondi, e io vorrei installarne circa 8. Inoltre, ci sono un sacco di parametri calcolati sulla base di altri sensori. Pertanto, tutti questi valori possono facilmente gonfiare il database di 100-200 MB al giorno. Dopo una settimana, il sistema faticherà a funzionare, e dopo un mese la chiavetta USB si guasterà (nel caso di un'installazione tipica dell'home assistant su Raspberry PI), e nemmeno si può parlare di conservare i dati per un anno intero.
- Se sei fortunato, il tuo contatore è in grado di calcolare autonomamente i consumi. Puoi consultare il contatore in qualsiasi momento e chiedergli quale sia il valore accumulato di consumo. Di solito, tutti i contatori elettrici che hanno un'interfaccia digitale (RS232/RS485/Modbus/Zigbee) offrono questa possibilità.
Peggio se il dispositivo può semplicemente misurare un qualche parametro istantaneo (ad esempio, potenza istantanea o corrente), o semplicemente generare impulsi ogni X watt-ora o litri. Allora bisogna pensare a come e con cosa integrare e dove accumulare il valore. C'è il rischio di perdere un rapporto per qualche motivo, e anche la precisione del sistema in generale solleva interrogativi. Certo, si può affidare tutto questo a un sistema di smart home come home assistant, ma la questione del numero di registrazioni nel database rimane, 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 in forma di componente specializzato: utility_meter.
Il principio del componente è che al suo interno crea una variabile valore_accumulato_corrente e la azzera al termine di un periodo definito (ora/settimana/mese). Il componente monitora autonomamente la variabile in ingresso (il valore di un sensore) e si sottoscrive alle modifiche di valore: il risultato è pronto per te. Questa cosa si descrive 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 è il valore attuale del contatore in litri che ricevo tramite mqtt. La struttura crea 2 nuovi sensori water_cold_hour_um e water_cold_day_um, che accumulano le letture orarie e quotidiane, azzerandole al termine del periodo. Ecco il grafico dell'accumulatore orario per mezza giornata.

Il codice dei grafici orari e giornalieri per lovelace-UI appare così:
- 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 realtà, 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 un record di 1kB nel database. Ogni utility meter genera anche un nuovo valore che viene anch'esso aggiunto al database. Se voglio raccogliere letture orarie/giornaliere/settiminali/mensili, per diversi gruppi di acqua, e aggiungere anche una serie di contatori elettrici, si tratterà di un'enorme quantità di dati. Anzi, i dati non sono molti, ma poiché il home assistant scrive un sacco di informazioni superflue nel database, la dimensione del database crescerà esponenzialmente. Temo persino di dover calcolare la dimensione del database per i grafici settimanali e mensili.
Oltre a ciò, l'utility meter da solo non risolve il compito assegnato. Il grafico dei valori forniti dall'utility meter è una funzione monotonicamente crescente, che si azzera ogni ora. Noi abbiamo bisogno di un grafico comprensibile per l'utente che mostri quanti litri sono stati consumati in un determinato periodo. Il componente standard history-graph non ha questa funzionalità, ma il componente esterno mini-graph-card può aiutarci.
Questo è 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 di acqua aggregato per utility meter"
points_per_hour: 1
show:
graph: bar
type: 'custom:mini-graph-card'Oltre alle impostazioni standard come nome del sensore, tipo di grafico, colore (l'arancione standard non mi piaceva), è importante notare 3 impostazioni:
- group_by:hour — il grafico verrà generato allineando le colonne all'inizio dell'ora
- points_per_hour: 1 — una colonna per ogni ora
- E la cosa più importante, aggregate_func: max — prendere il valore massimo in ciascuna ora. Questo parametro trasforma il grafico a zig-zag in colonne.

Non badate ai vari colonne di sinistra: è il comportamento standard del componente se non ci sono dati. E dati non ce ne sono — ho appena attivato la raccolta dati dall'utility meter solo per questo articolo (il mio approccio attuale lo descriverò più avanti).
In questa immagine volevo dimostrare che a volte la visualizzazione dei dati funziona realmente e le colonne riflettono valori corretti. Solo che non tutti. La colonna evidenziata per l'intervallo dalle 11 alle 12 di mattina mostra 19 litri, anche se nel grafico dentato poco sopra per lo stesso periodo dallo stesso sensore vediamo un consumo di 62 litri. O è un bug, o le mani sono imprecise. E non ho ancora capito perché manchino dati a destra: il consumo lì era nella norma, come è visibile anche dal grafico dentato.
In generale, non sono riuscito a ottenere credibilità da questo approccio: il grafico mostra quasi sempre qualche assurdità.
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 noti che il parametro group_by è impostato su interval, e controlla tutto il parametro points_per_hour. E qui sta un altro problema di questo componente: points_per_hour funziona bene sui grafici di un'ora o meno, ma malissimo su intervalli maggiori. Pertanto, per ottenere una colonna per un giorno, ho dovuto scrivere il valore 1/24=0.04166666. Non parlo nemmeno dei grafici settimanali e mensili.
Approccio 2
Solo iniziando a esplorare home assistant mi sono imbattuto in questo video:

Un compagno raccoglie dati di consumo da diversi tipi di prese Xiaomi. Il suo compito è un po' più semplice: mostrare semplicemente il valore di consumo di oggi, ieri e del mese. Non sono richiesti grafici.
Lasciamo da parte le considerazioni sull'integrazione manuale dei valori istantanei di potenza: sulla "precisione" di questo approccio ho già scritto sopra. Non è chiaro perché non abbia utilizzato i valori accumulati di consumo, che già vengono raccolti dalla stessa presa. A mio avviso, l'integrazione all'interno del dispositivo funzionerebbe meglio.
Dallo video prenderemo l'idea del conteggio manuale del consumo per periodo. L'uomo considera solo i valori di oggi e di ieri, ma noi andremo oltre e proveremo a disegnare un grafico. L'essenza del metodo proposto nel mio caso è la seguente.
Creeremo una variabile valore_all_inizio_dell_ora, in cui registreremo i dati attuali del contatore.
Alla fine dell'ora (o all'inizio della successiva) conteremo la differenza tra la lettura attuale e quella memorizzata all'inizio dell'ora. Questa differenza sarà il consumo per l'ora corrente: salveremo il valore nel sensore e in futuro utilizzeremo questo valore per costruire il grafico.
È anche necessario "azzerare" la variabile valore_in_inizio_ora scrivendo il valore attuale del contatore.
Tutto questo può essere fatto tramite gli strumenti stessi di home assistant.
Il codice da scrivere sarà leggermente più lungo rispetto all'approccio precedente. Iniziamo a creare queste "variabili". Non abbiamo un'entità "variabile" predefinita, ma possiamo avvalerci dei servizi del broker mqtt. Invieremo là i valori con il flag retain=true: questo conserverà il valore all'interno del broker e potrà essere recuperato in qualsiasi momento, anche dopo il riavvio di home assistant. Ho creato direttamente 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.
- 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 viene realizzata con un semplice 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_dayAppare così:

In pratica, questo è già ciò di cui abbiamo bisogno. Il vantaggio di questo metodo è che i dati vengono generati una sola volta per intervallo. Cioè, solo 24 registrazioni al giorno per il grafico orario.
Sfortunatamente, questo non risolve comunque il problema generale della crescente base. Se voglio un grafico del consumo mensile, devo conservare i dati per almeno un anno. E poiché Home Assistant fornisce solo una impostazione della durata di conservazione per l'intero database, questo significa che TUTTI i dati nel sistema dovranno essere conservati per un anno intero. Ad esempio, in un anno consumo 200 metri cubi d'acqua, il che significa 200.000 registrazioni nel database. E se considero anche altri sensori, il numero diventa davvero imbarazzante.
Approccio 3
Fortunatamente, persone ingeniose hanno già risolto questo problema scrivendo il database InfluxDB. Questo database è ottimizzato in modo speciale per la conservazione di dati time-based ed è perfetto per memorizzare i valori di diversi sensori. Il sistema fornisce anche un linguaggio di query simile a SQL, che permette di estrarre valori dal database e poi aggregarli in vari modi. Infine, è possibile conservare dati diversi per periodi di tempo diversi. Ad esempio, le letture frequentemente variabili come temperatura o umidità possono essere conservate solo per un paio di settimane, mentre le letture giornaliere del consumo d'acqua possono essere conservate per un anno intero.
Oltre a InfluxDB, persone ingegnose hanno anche inventato Grafana — un sistema per la visualizzazione grafica dei dati di InfluxDB. Grafana è in grado di disegnare diversi tipi di grafici, personalizzarli in dettaglio e, cosa più importante, questi grafici possono essere "inseriti" nell'interfaccia lovelace di Home Assistant.
Ispirarsi e . Negli articoli viene descritto nel dettaglio il processo di installazione e collegamento di InfluxDB e Grafana a Home Assistant. Io mi concentrerò sulla soluzione del mio specifico problema.
Quindi, per prima cosa iniziamo a memorizzare i valori del contatore in InfluxDB. Ecco un pezzo di configurazione di Home Assistant (in questo esempio mi divertirò sia con l'acqua fredda che con quella calda):
influxdb:
host: localhost
max_retries: 3
default_measurement: state
database: homeassistant
include:
entities:
- sensor.water_meter_hot
- sensor.water_meter_coldDisattiveremo il salvataggio di questi stessi dati nel database interno di Home Assistant, per non gonfiarlo inutilmente:
recorder:
purge_keep_days: 10
purge_interval: 1
exclude:
entities:
- sensor.water_meter_hot
- sensor.water_meter_coldPassiamo ora alla console di InfluxDB e configuriamo il nostro database. In particolare, dobbiamo impostare quanto tempo verranno conservati determinati dati. Questo è regolato dalla cosiddetta retention policy — è simile a database all'interno del database principale, e ogni database interno ha le proprie impostazioni. Per impostazione predefinita, tutti i dati vengono collocati nella retention policy chiamata autogen, questi dati verranno conservati per una settimana. Vorrei che i dati orari venissero conservati per un mese, quelli settimanali per un anno e che quelli mensili non venissero mai eliminati. Creiamo le corrispondenti 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, veniamo al trucco principale — l'aggregazione dei dati tramite una continuous query. Questo è un meccanismo che esegue automaticamente una query a intervalli di tempo prestabiliti, aggrega i dati in base a quella query e memorizza il risultato in un nuovo valore. Spieghiamolo con un esempio (scrivo in colonna per facilitare la lettura, ma in realtà ho dovuto inserire questo comando in un'unica riga).
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)
ENDQuesto comando:
- Crea una continuous query chiamata cq_water_cold_hourly nel database homeassistant.
- La query verrà eseguita ogni ora (time(1h)).
- La query preleverà tutti i dati dalla misurazione homeassistant.autogen.l (litri), inclusi i dati sull'acqua fredda e calda.
- I dati aggregati verranno raggruppati per entity_id, creando valori separati per acqua fredda e calda.
- Poiché il contatore dei litri è una sequenza monotonicamente crescente, all'interno di ogni ora bisogna prendere il valore massimo, quindi l'aggregazione verrà eseguita con 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 di un mese. Inoltre, 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 in casa, non c'è consumo d'acqua e quindi non ci sono nuovi registri in homeassistant.autogen.l. Per evitare lacune nei valori delle query ordinarie, si può utilizzare fill(previous). Questo farà in modo che InfluxDB usi il valore dell'ora precedente.
Sfortunatamente, la query continua ha una peculiarità: il trucco fill(previous) non funziona e le registrazioni semplicemente non vengono create. Inoltre, è un problema insormontabile che . Ci occuperemo di questo problema più tardi, e fill(previous) nella query continua può rimanere — non dà fastidio.
Verifichiamo cosa abbiamo ottenuto (naturalmente è necessario 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 differiscono 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 noti che tra le 2 e le 5 del mattino non ci sono registrazioni: questa è la stessa peculiarità della query continua.
Come vedete, il valore aggregato è anch'esso una sequenza monotonicamente crescente, solo che le registrazioni avvengono meno frequentemente — 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)Decrittazione:
- 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 possono mancare alcune registrazioni. Questi dati li genereremo nuovamente, eseguendo la query con GROUP BY time(1h). Questa volta fill(previous) funzionerà come previsto, generando i dati mancanti (la funzione utilizzerà il valore precedente)
- La cosa più importante in questa query è la funzione difference, che calcolerà la differenza tra i timestamp orari. Essa da sola non funziona e richiede una funzione aggregante. Lasciamola essere max() come utilizzato in precedenza.
L'output 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 ci sono stati consumi. Tuttavia, la richiesta restituirà lo stesso valore di consumo grazie a fill(previous), e la funzione difference sottrarrà questo valore da se stesso, producendo come risultato 0, che è esattamente ciò che ci serve.
Ora resta solo da fare una cosa: costruire il grafico. Per questo apriremo Grafana, apriremo un cruscotto esistente (o ne creeremo uno nuovo), e creeremo un nuovo pannello. Le impostazioni dei grafici saranno le seguenti.

Visualizzerò i dati sull'acqua fredda e calda nello stesso grafico. La richiesta è esattamente la stessa che ho descritto sopra.
Le impostazioni di visualizzazione sono stabilite in questo modo. Per me sarà un grafico a linee (lines), che prosegue a gradini (stairs). Spiegherò il parametro Stack poco più avanti. Ci sono anche altri parametri di visualizzazione, ma non sono così interessanti.

Per aggiungere il grafico ottenuto in Home Assistant, è necessario:
- uscire dalla modalità di modifica del grafico. Per qualche motivo, le impostazioni corrette per la condivisione dei grafici sono disponibili solo dalla pagina del cruscotto.
- Cliccare sul triangolo vicino al nome del grafico, nel menu selezionare share.
- Nella finestra che si apre, andare alla scheda embed.
- Deselezionare l'opzione current time range — il range temporale lo imposteremo tramite URL.
- Selezionare il tema richiesto. Nel mio caso, è light.
- Copiare 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 prega di notare che l'intervallo di tempo (ultimi 2 giorni) è impostato proprio qui, e non nelle impostazioni del cruscotto.
Il grafico appare così. Non ho usato acqua calda negli ultimi 2 giorni, quindi viene visualizzato solo il grafico dell'acqua fredda.

Non ho ancora deciso quale grafico mi piaccia di più, quello a gradini o i veri e propri bastoncini. Pertanto, fornirò semplicemente un esempio del grafico giornaliero dei consumi, ma questa volta a colonne. Le richieste si costruiscono in modo simile a quanto descritto sopra. Le impostazioni di visualizzazione sono le seguenti:

Questo grafico appare così:

Ecco riguardo al parametro Stack. In questo grafico, la colonna dell'acqua fredda si sovrappone alla colonna dell'acqua calda. L'altezza totale corrisponde al consumo totale di acqua fredda e calda per il periodo.
Tutti i grafici mostrati sono dinamici. È possibile posizionare il cursore su un punto di interesse e vedere i dettagli e il valore in quel punto specifico.
Purtroppo non è stato possibile evitare un po' di fango. Nel grafico a barre (a differenza del grafico a linee scalari) il centro della barra non si trova a metà giornata, ma a 00:00. Cioè, la metà sinistra della barra è disegnata sul posto del giorno precedente. Così, i grafici del sabato e della domenica sono disegnati un po' più a sinistra rispetto alla zona bluastro. Finora non ho trovato un modo per risolvere questo problema.
Un altro problema riguarda l'impossibilità di lavorare correttamente con le intervalli mensili. Infatti, la lunghezza di un'ora/giorno/settimana è fissa, ma la lunghezza di un mese varia ogni volta. InfluxDB può lavorare solo con intervalli identici. Finora la mia mente è riuscita a impostare un intervallo fisso di 30 giorni. Sì, il grafico nel corso dell'anno si discosterà leggermente e le barre non corrisponderanno esattamente ai mesi. Ma poiché trovo interessante questa cosa come indicatore, va bene così.
Vedo almeno due soluzioni:
- Ignorare i grafici mensili e limitarsi a quelli settimanali. 52 barre settimanali all'anno si presentano piuttosto bene.
- Considerare il consumo mensile come metodo n. 2 e utilizzare Grafana solo per grafici esteticamente belli. Sarà una soluzione sufficientemente precisa. Si possono anche sovrapporre i grafici dell'anno scorso per il confronto—Grafana può fare anche questo.
Conclusione
Non so perché, ma trovo affascinanti questo tipo di grafici. Mostrano che la vita è in movimento e tutto cambia. Ieri era molto, oggi è poco, domani sarà diversamente. Devo ancora lavorare con i miei familiari sul tema del consumo. Ma anche con le attuali spese, semplicemente una cifra grande e poco chiara nella bolletta si trasforma già in una rappresentazione piuttosto chiara dei consumi.
Nonostante quasi 20 anni di carriera come programmatore, non ho praticamente mai avuto a che fare con database. Pertanto, l'installazione di un database esterno sembrava qualcosa di astruso e incomprensibile. Tutto è cambiato — si è scoperto che aggiungere lo strumento appropriato si fa in 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 fornire alcun grafico. Un contatore SDM120 è morto, mentre l'altro presenta malfunzionamenti quando si utilizza Modbus. Tuttavia, questo non influisce sul tema di questo articolo: i grafici verranno realizzati nello stesso modo di quelli per l'acqua.
In questo articolo ho presentato i metodi che ho sperimentato personalmente. Sicuramente ci sono altri modi per organizzare la raccolta e la visualizzazione dei dati di cui non sono a conoscenza. Raccontatemi nei commenti, mi interesserà molto. Sarò felice di ricevere critiche costruttive e nuove idee. Spero che il materiale presentato possa essere utile a qualcuno.
Fonte: habr.com
