But du projet
Afficher dans un tableau les appareils à forte consommation électrique de la maison. Disposant de panneaux solaires, l'objectif est de faire ressortir distinctement le coût en valeur brute (consommation totale de l'appareil) et en valeur réelle (coût facturé par EDF après déduction de l'autoconsommation).
Prérequis
Disposer de l'intégration Tarif EDF (ou un capteur donnant le prix du kWh actuel, par exemple via Tempo).
🛠️ Étape 1 : Récupérer la puissance (W) de l'appareil
Deux possibilités s'offrent à vous :
Option A : Vous possédez une prise ou un module connecté qui remonte déjà la puissance en Watts. Vous pouvez passer directement à l'étape 2.
Option B : L'appareil n'a pas de capteur physique mais sa puissance est fixe et connue (ex: un radiateur piloté par fil pilote). On crée alors un capteur de puissance virtuel.
Dans configuration.yaml (ou votre fichier de templates) :
template:
- sensor:
- name: "Radiateur parents puissance"
unique_id: my_radiateur_parents_puissance
unit_of_measurement: "W"
device_class: power
state: "{{ 750 if is_state('switch.radiateur_parent', 'on') else 0 }}"
📈 Étape 2 : Convertir la puissance en Énergie (kWh)
Pour obtenir des kWh à partir de la puissance, on utilise l'intégration Intégrale de Riemann directement depuis l'interface de Home Assistant :
Allez dans Paramètres > Appareils et services > Entrées > Créer une entrée.
Choisissez Intégrale de Riemann (Integration - Riemann sum integral).
Remplissez le formulaire :
Nom : Radiateur parents énergie
Capteur d'entrée : sensor.radiateur_parents_puissance
Méthode d'intégration : Trapezoidal
Préfixe métrique : k (kilo)
Unité de temps : Heures
Cliquez sur Soumettre (cela crée l'entité sensor.radiateur_parents_energy).
📅 Étape 3 : Découper l'énergie par période (Jour / Mois / Année)
Pour suivre l'évolution, on utilise les index de compteurs (utility_meter).
Dans votre configuration.yaml, assurez-vous d'avoir :
utility_meter: !include utility_meter.yaml
Puis dans votre fichier utility_meter.yaml, créez les trois cycles :
radiateur_parents_energie_jour:
source: sensor.radiateur_parents_energie
cycle: daily
radiateur_parents_energie_mois:
source: sensor.radiateur_parents_energie
cycle: monthly
radiateur_parents_energie_annee:
source: sensor.radiateur_parents_energie
cycle: yearly
(Si vous aviez opté pour l'Option A à l'étape 1 avec une prise connectée, remplacez simplement la ligne source: par l'entité d'énergie native de votre prise).
💰 Étape 4 : Calculer les coûts BRUTS (€)
On croise nos index d'énergie avec le tarif actuel d'EDF pour obtenir le coût théorique de l'appareil. Dans votre fichier de templates YAML :
template:
- sensor:
- name: "Radiateur parents cout jour"
unique_id: cost_rad_parents_jour
unit_of_measurement: "€"
state_class: total
state: "{{ (states('sensor.radiateur_parents_energie_jour') | float(0) * states('sensor.tarif_edf_tempo_12kva_tarif_actuel_tempo_12kva_ttc') | float(0)) | round(2) }}"
- name: "Radiateur parents cout mois"
unique_id: cost_rad_parents_mois
unit_of_measurement: "€"
state_class: total
state: "{{ (states('sensor.radiateur_parents_energie_mois') | float(0) * states('sensor.tarif_edf_tempo_12kva_tarif_actuel_tempo_12kva_ttc') | float(0)) | round(2) }}"
- name: "Radiateur parents cout annee"
unique_id: cost_rad_parents_annee
unit_of_measurement: "€"
state_class: total
state: "{{ (states('sensor.radiateur_parents_energie_annee') | float(0) * states('sensor.tarif_edf_tempo_12kva_tarif_actuel_tempo_12kva_ttc') | float(0)) | round(2) }}"
Étape 5 : Calculer la part REELLE (en intégrant le solaire)
Pour connaître le coût réel (ce qui est ponctionné du réseau), nous calculons d'abord le Ratio d'Import Réseau (la part d'énergie achetée par rapport à la consommation globale de la maison).
5.1. Création du capteur de Ratio
Dans votre fichier de templates YAML :
template:
- sensor:
- name: "Ratio Import Réseau"
unique_id: ratio_import_reseau
unit_of_measurement: "%"
state: >
{% set import = (states('sensor.puissance_edf') | float(0) * 1000) %}
{% set conso_totale = states('sensor.puissance_totale_maison') | float(0) %}
{% if import <= 0 %}
0
{% elif conso_totale > 0 %}
{{ [((import / conso_totale) * 100) | round(1), 100] | min }}
{% else %}
0
{% endif %}
5.2. Puissance Réelle de l'appareil
On applique ce ratio à la puissance de notre appareil :
- name: "Radiateur Parents Puissance Reseau"
unique_id: radiateur_parents_puissance_reseau
unit_of_measurement: "W"
device_class: power
state: "{{ (states('sensor.radiateur_parents_puissance') | float(0) * states('sensor.ratio_import_reseau') | float(0) / 100) | round(1) }}"
5.3. Énergie Réelle via Riemann
Retournez dans l'interface de Home Assistant (Entrées) pour créer une nouvelle Intégrale de Riemann :
Nom : Radiateur Parents Énergie Réseau
Capteur d'entrée : sensor.radiateur_parents_puissance_reseau
Méthode : Trapezoidal
Préfixe : k (kilo)
5.4. Cycles de l'Énergie Réelle
Dans votre fichier utility_meter.yaml :
radiateur_parents_energie_reseau_jour:
source: sensor.radiateur_parents_energie_reseau
cycle: daily
radiateur_parents_energie_reseau_mois:
source: sensor.radiateur_parents_energie_reseau
cycle: monthly
radiateur_parents_energie_reseau_annee:
source: sensor.radiateur_parents_energie_reseau
cycle: yearly
5.5. Coûts Réels (€)
Enfin, on calcule les coûts financiers réels dans les templates YAML :
template:
- sensor:
- name: "Radiateur Parents Coût Réel Jour"
unique_id: cost_rad_parents_reel_jour
unit_of_measurement: "€"
state_class: total
state: "{{ (states('sensor.radiateur_parents_energie_reseau_jour') | float(0) * states('sensor.tarif_edf_tempo_12kva_tarif_actuel_tempo_12kva_ttc') | float(0)) | round(2) }}"
- name: "Radiateur Parents Coût Réel Mois"
unique_id: cost_rad_parents_reel_mois
unit_of_measurement: "€"
state_class: total
state: "{{ (states('sensor.radiateur_parents_energie_reseau_mois') | float(0) * states('sensor.tarif_edf_tempo_12kva_tarif_actuel_tempo_12kva_ttc') | float(0)) | round(2) }}"
- name: "Radiateur Parents Coût Réel Année"
unique_id: cost_rad_parents_reel_annee
unit_of_measurement: "€"
state_class: total
state: "{{ (states('sensor.radiateur_parents_energie_reseau_annee') | float(0) * states('sensor.tarif_edf_tempo_12kva_tarif_actuel_tempo_12kva_ttc') | float(0)) | round(2) }}"
📊 Étape 6 : La Carte Dashboard (Tableau 6 colonnes)
Créez d'abord une entrée Liste déroulante (input_select.tri_consommation) avec trois options : jour, mois et année.
Ajoutez une carte Markdown sur votre tableau de bord et collez le code suivant :
type: markdown
content: >
{% set tri = states('input_select.tri_consommation') %}
{% set mapping = {'jour': 'j', 'mois': 'm', 'année': 'a'} %}
{% set tri_key = mapping.get(tri, 'j') %}
### 📊 Top consommateurs (Tri : {{ tri }})
{% set appareils = [
{
'n': '🔥 Rad. Parents',
'j': states('sensor.radiateur_parents_cout_jour')|float(0), 'jr': states('sensor.radiateur_parents_cout_reel_jour')|float(0),
'm': states('sensor.radiateur_parents_cout_mois')|float(0), 'mr': states('sensor.radiateur_parents_cout_reel_mois')|float(0),
'a': states('sensor.radiateur_parents_cout_annee')|float(0), 'ar': states('sensor.radiateur_parents_cout_reel_annee')|float(0)
},
{
'n': '🌊 Piscine Pompe',
'j': states('sensor.piscine_pompe_cout_jour')|float(0), 'jr': states('sensor.piscine_pompe_cout_reel_jour')|float(0),
'm': states('sensor.piscine_pompe_cout_mois')|float(0), 'mr': states('sensor.piscine_pompe_cout_reel_mois')|float(0),
'a': states('sensor.piscine_pompe_cout_annee')|float(0), 'ar': states('sensor.piscine_pompe_cout_reel_annee')|float(0)
}
] %}
<table style="width: 100%; border-collapse: collapse; font-size: 0.95em;">
<thead>
<tr style="border-bottom: 1px solid rgba(0,0,0,0.15);">
<th rowspan="2" style="text-align: left; padding: 6px 4px; vertical-align: middle; border-right: 1px solid rgba(0,0,0,0.15);">Appareil</th>
<th colspan="3" style="text-align: center; padding: 6px 4px; background-color: rgba(0,0,0,0.03); border-right: 1px solid rgba(0,0,0,0.15);">Brut</th>
<th colspan="3" style="text-align: center; padding: 6px 4px; color: #4caf50; background-color: rgba(76,175,80,0.03);">Réelle</th>
</tr>
<tr style="border-bottom: 2px solid rgba(0,0,0,0.15);">
<th style="text-align: center; padding: 4px; font-size: 0.9em; background-color: rgba(0,0,0,0.03);">½ Jour</th>
<th style="text-align: center; padding: 4px; font-size: 0.9em; background-color: rgba(0,0,0,0.03);">Mois</th>
<th style="text-align: center; padding: 4px; font-size: 0.9em; background-color: rgba(0,0,0,0.03); border-right: 1px solid rgba(0,0,0,0.15);">Année</th>
<th style="text-align: center; padding: 4px; font-size: 0.9em; color: #4caf50; background-color: rgba(76,175,80,0.03);">Jour</th>
<th style="text-align: center; padding: 4px; font-size: 0.9em; color: #4caf50; background-color: rgba(76,175,80,0.03);">Mois</th>
<th style="text-align: center; padding: 4px; font-size: 0.9em; color: #4caf50; background-color: rgba(76,175,80,0.03);">Année</th>
</tr>
</thead>
<tbody>
{%- for app in appareils | sort(attribute=tri_key, reverse=True) %}
<tr style="border-bottom: 1px solid rgba(0,0,0,0.08);">
<td style="padding: 6px 4px; text-align: left; font-weight: 500; border-right: 1px solid rgba(0,0,0,0.08);">{{ app.n }}</td>
<td style="text-align: center; padding: 6px 4px; background-color: rgba(0,0,0,0.01);">{{ app.j | round(2) }}€</td>
<td style="text-align: center; padding: 6px 4px; background-color: rgba(0,0,0,0.01);">{{ app.m | round(2) }}€</td>
<td style="text-align: center; padding: 6px 4px; background-color: rgba(0,0,0,0.01); border-right: 1px solid rgba(0,0,0,0.08);">{{ app.a | round(2) }}€</td>
<td style="text-align: center; padding: 6px 4px; font-weight: bold; color: #4caf50; background-color: rgba(76,175,80,0.005);">{{ app.jr | round(2) }}€</td>
<td style="text-align: center; padding: 6px 4px; font-weight: bold; color: #4caf50; background-color: rgba(76,175,80,0.005);">{{ app.mr | round(2) }}€</td>
<td style="text-align: center; padding: 6px 4px; font-weight: bold; color: #4caf50; background-color: rgba(76,175,80,0.005);">{{ app.ar | round(2) }}€</td>
</tr>
{%- endfor %}
</tbody>
</table>
il y a certainement des choses à améliorer ! je ne suis pas un grand codeur, même pas du tout, j'avoue que sans Gemini je n'aurais pas réussi!
N'hésitez pas si vous avez des questions!
Jérémy
