Bonjour à tous,
A l’heure où l’hiver arrive, je viens partager ma dernière idée concernant une carte permettant les économies d’énergie. Voir également ici: Analysis of electricity consumption compared with the previous year · dbuezas/lovelace-plotly-graph-card · Discussion #334 · GitHub
L’idée principale est la suivante:
Comment se compare ma consommation actuelle en temps réel par rapport à l’année précédente ?
On pourrait penser que la fonction Compare du dashboard energy fait cette fonction, mais comparer le mois de septembre par rapport au mois d’août n’a aucun sens.
Mon idée dans le détail:
- On compare le mois de septembre par rapport au mois de septembre de l’année précédente
- Les habitudes ne sont pas les mêmes le dimanche et le lundi , on compare donc des jours identiques, un dimanche par rapport à un dimanche, il faut pour cela décaler d’un jour (deux pour les années bissextiles le 1er mars 2024) pour synchroniser les mêmes jours de l’année avec l’année N-1
- On affiche également les températures extérieures N et N-1 pour comprendre les écarts de consommation
- On fait du temps réel quasi temps réel (à l’heure près en fait) pour pouvoir comparer à un instant donné la situation et l’ajuster si nécessaire.
- On affiche les prévisions de température pour la semaine à venir et les projections de l’année précédente.
Les prérequis:
- Avoir un suivi historique de la consommation électrique (avec remise à zéro chaque jour pour l’instant) type Linky de plus d’un an
- Avoir un suivi historique de la température extérieure supérieure à un an
- Avoir installé Plotly et la carte qui va avec
- Avoir installé OpenweatherMap pour les prévisions
Le résultat:
En plus gros:
Pour chaque jour, heure par heure:
- En jaune sombre, la consommation de l’année précédente
- En jaune , la consommation de l’année en cours
Remarque: Dans l’exemple affiché, je consomme plus que l’année précédente, mais les températures sont plus basses.
Comment lire ?
Quand le jaune dépasse le jaune sombre, on consomme plus que l’année précédente
Sinon, c’est le contraire.
- En vert la température extérieure
- En rouge la température intérieure
- La zone grisée entre les deux, affiche l’écart de température (et donc l’energie nécessaire)
En vert pointillé, la température extérieure année N-1 et rouge pointillé (assez peu visible) la température intérieure N-1
Sur la droite, la barre verticale bleu pointillée donne l’instant présent et la ligne verte donne les prévisions openweathermap pour la semaine à venir.
En déplçant à droite, on a l’affichage des données de l’année N-1:
On peut dezoomer au niveau de la journée:
Note: Je n’ai qu’un peu plus d’un an de données historiques, ce qui explique qu’il manque les barres jaunes sombres sur la majorité du graphique.
On peut dezoomer au niveau de la semaine:
On peut dezoomer au niveau d’une année:
Plotly étant dynamique (zooms heure, jour,semaine, mois), transitions, déplacements dans le temps, affichage/masque d’indicateurs), il y a enormément de possibilités d’analyses sur le même graphique !
Et dans l’utilisation, tout est dynamique et fluide !
Et le code de la carte Lovelace qui change tous les jours, parce que Plotly pour Home Assistant est complexe, assez peu documenté et que je ne suis pas un développeur:
type: custom:plotly-graph
layout:
barmode: overlay
margin:
r: 100
xaxis:
rangeselector:
'y': 1.3
buttons:
- count: 1
step: day
- count: 7
step: day
- count: 14
step: day
- count: 1
step: month
- count: 3
step: month
- count: 6
step: month
- count: 16
step: month
centered: false
yaxis:
visible: true
fixedrange: true
autorange_after_scroll: true
yaxis2:
visible: true
fixedrange: true
autorange_after_scroll: true
rangegmode: tozero
rangemode: nonnegative
yaxis5:
visible: false
fixedrange: true
autorange_after_scroll: true
rangegmode: tozero
rangemode: nonnegative
yaxis7:
visible: false
fixedrange: true
autorange_after_scroll: true
rangegmode: tozero
rangemode: nonnegative
yaxis9:
visible: false
fixedrange: true
autorange_after_scroll: true
entities:
- entity: ''
yaxis: y9
name: Now
showlegend: false
line:
width: 1
dash: dot
color: deepskyblue
x: $ex [Date.now(), Date.now()]
'y':
- 0
- 1
- entity: sensor.humidite_station_meteo
autorange_after_scroll: true
yaxis: y5
base: 0
connectgaps: true
statistic: mean
line:
shape: spline
width: 1
dash: none
color: rgba(120, 120, 240, 1)
period:
0m: hour
1M: day
3M: week
6M: week
time_offset: +0d
name: Humidité
show_value: true
opacity: 0.4
fill: tozeroy
fillcolor: rgba(168, 216, 234, 0)
- entity: sensor.humidite_station_meteo
autorange_after_scroll: true
yaxis: y5
base: 0
connectgaps: true
statistic: mean
line:
shape: spline
width: 1
dash: dot
color: rgba(120, 120, 240, 0.5)
period:
0m: hour
1M: day
3M: week
6M: week
time_offset: +364d
name: Humidité A-1
show_value: true
opacity: 0.4
fill: tozeroy
fillcolor: rgba(168, 216, 234, 0)
- entity: sensor.temperature_station_meteo
autorange_after_scroll: true
yaxis: y2
base: 0
connectgaps: true
statistic: mean
line:
shape: spline
width: 1
dash: dot
color: rgba(40, 240, 40, 1)
period:
0m: hour
1M: day
3M: week
6M: month
time_offset: +364d
name: Température Ext. A-1
show_value: true
opacity: 0.4
fill: none
fillcolor: rgba(168, 216, 234, 0.1)
- entity: sensor.openweathermap_temperature
autorange_after_scroll: true
legendgroup: 2
yaxis: y2
base: 0
name: 🌡 Temperature
internal: true
filters:
- store_var: temperature
fill: none
fillcolor: rgba(214, 39, 40,0)
line:
color: rgba(214, 39, 40, 0)
- entity: weather.openweathermap
autorange_after_scroll: true
legendgroup: 2
yaxis: y2
base: 0
showlegend: true
show_value: true
name: Température Ext. Prév.
fill: none
fillcolor: rgba(214, 39, 40, .3)
line:
dash: none
shape: spline
color: rgba(50,205,50, 1)
width: 1
unit_of_measurement: °C
filters:
- fn: |-
({ meta, vars }) => ({
xs: [vars.temperature.xs.slice(-1)[0],...meta.forecast.map(({ datetime }) => new Date(datetime))],
ys: [vars.temperature.ys.slice(-1)[0],...meta.forecast.map(({ temperature }) => temperature)],
})
- entity: sensor.temperature_station_meteo
autorange_after_scroll: true
yaxis: y2
base: 0
statistic: mean
line:
shape: spline
color: rgba(50,205,50, 1)
width: 1
period:
0m: hour
1M: day
3M: week
6M: month
time_offset: +0d
name: Température Ext.
show_value: true
opacity: 0.4
fill: tozeroy
fillcolor: rgba(168, 216, 234, 0)
- entity: sensor.temperature_interieure_climatisation_salon
autorange_after_scroll: true
yaxis: y2
base: 0
statistic: mean
line:
shape: spline
color: rgba(178,34,34, 1)
width: 1
period:
0m: hour
1M: day
3M: week
6M: month
time_offset: +0d
name: Température Int.
show_value: true
opacity: 1
fill: tonexty
fillcolor: rgba(168, 216, 234, 0.05)
- entity: sensor.temperature_interieure_climatisation_salon
autorange_after_scroll: true
yaxis: y2
statistic: mean
base: 0
line:
shape: spline
color: rgba(178,34,34, 1)
width: 1
dash: dot
period:
0m: hour
1M: day
3M: week
6M: month
time_offset: +364d
name: Température Int. A-1
show_value: true
opacity: 0.4
fill: none
fillcolor: rgba(168, 216, 234, 0.05)
- entity: sensor.openweathermap_rain
autorange_after_scroll: true
base: 0
yaxis: y7
fillcolor: rgba(31, 119, 180,.3)
line:
color: rgba(31, 119, 180, 1)
legendgroup: 1
name: 🌧 Précipitation 1
visible: legendonly
show_value: true
filters:
- store_var: precipitation
fill: tozeroy
- entity: sensor.wupws_precipitation_rate
visible: legendonly
autorange_after_scroll: true
base: 0
yaxis: y7
fillcolor: rgba(31, 119, 180,.3)
line:
color: rgba(31, 119, 180, 1)
legendgroup: 4
name: 🌧 Précipitation 2
show_value: true
fill: tozeroy
unit_of_measurement: mm/h
- entity: weather.openweathermap
show_value: true
autorange_after_scroll: true
base: 0
legendgroup: 1
showlegend: false
visible: legendonly
name: Précipitation
fill: tozeroy
fillcolor: rgba(31, 119, 180,.1)
line:
color: rgba(31, 119, 180, 1)
dash: dot
unit_of_measurement: mm
filters:
- fn: |-
({ meta, vars }) => ({
xs: [vars.precipitation.xs.slice(-1)[0],...meta.forecast.map(({ datetime }) => new Date(datetime))],
ys: [vars.precipitation.ys.slice(-1)[0],...meta.forecast.map(({ precipitation }) => precipitation)],
})
- entity: sensor.energy_eau_chaude
autorange_after_scroll: true
display: hide
defaults:
yaxes:
fixedrange: true
type: bar
marker:
color: rgba(220, 80, 80, 0.5)
yaxis: 'y'
base: 0
statistic: state
period:
0m: hour
1M: day
3M: month
6M: month
time_offset: +0.0d
unit_of_measurement: kWh
name: Consommation Eau Chaude
texttemplate: '%{y:0.1f} kWh'
connectgaps: false
fill: tozeroy
show_value: false
filters:
- filter: i>0
- delta
- filter: y<250
- filter: y>=0
- map_y_numbers: 'y'
- entity: sensor.consommation_journaliere_edf
autorange_after_scroll: true
defaults:
yaxes:
fixedrange: true
type: line
line:
shape: hvh
width: 1
dash: none
color: rgba(200, 200, 200, 0.6)
fill: tozeroy
fillcolor: rgba(20,20,20, 0.4)
yaxis: 'y'
base: 0
statistic: state
period:
0m: hour
1M: day
3M: day
6M: day
time_offset: +364.0d
unit_of_measurement: kWh
name: Consommation A-1
texttemplate: '%{y:0.1f} kWh'
show_value: false
filters:
- filter: i>0
- filter: y<150000
- map_y_numbers: y / 1000
- entity: sensor.consommation_journaliere_edf
autorange_after_scroll: true
defaults:
yaxes:
fixedrange: true
type: bar
marker:
color: rgba(255, 215, 0, 0.5)
yaxis: 'y'
base: 0
statistic: state
period:
0m: hour
1M: day
3M: day
6M: day
time_offset: +0.0d
unit_of_measurement: kWh
name: Consommation Année
texttemplate: '%{y:0.1f} kWh'
connectgaps: false
fill: tozeroy
show_value: false
filters:
- filter: i>0
- filter: y<150000
- map_y_numbers: y / 1000
- entity: sensor.consommation_edf
visible: true
autorange_after_scroll: true
defaults:
yaxes:
fixedrange: true
type: bar
barmode: overlay
marker:
color: rgba(200, 255, 200, 0.4)
yaxis: 'y'
base: 0
statistic: state
period:
0m: hour
1M: day
3M: month
6M: month
time_offset: +364.0d
unit_of_measurement: kWh
name: Consommation période - 1
texttemplate: '%{y:0.1f} kWh'
connectgaps: false
fill: tozeroy
show_value: false
filters:
- filter: i>0
- delta
- filter: y<15000000
- map_y_numbers: y / 1000
- entity: sensor.consommation_edf
visible: true
autorange_after_scroll: true
defaults:
yaxes:
fixedrange: true
type: bar
barmode: overlay
marker:
color: rgba(255, 255, 100, 0.4)
yaxis: 'y'
base: 0
statistic: state
period:
0m: hour
1M: day
3M: month
6M: month
time_offset: +0.0d
unit_of_measurement: kWh
name: Consommation période
texttemplate: '%{y:0.1f} kWh'
connectgaps: false
fill: tozeroy
show_value: false
filters:
- filter: i>0
- delta
- filter: y<15000000
- map_y_numbers: y / 1000
autorange_after_scroll: true
hours_to_show: 168
time_offset: 1d
refresh_interval: 1800
Références:
De mémoire le sensor.consommation_journaliere_edf a été créé de la façon suivante: