Tableau de consommation par appareils

:bullseye: 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).

:clipboard: 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) }}"

:sun: É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

Salut

J'ai bien compris ton calcul de ratio, Tu divise import/conso_totale

Quels sont les équipements qui te donne ces sensor et comment tu les récupères

Import : sensor.puissance_edf

conso_total : sensor.puissance_totale_maison

mes onduleurs sont du enphase, du coup c'est l'integration qui me donne tout ca!

si tu as pas ca, il va fallaoir mettre des pinces de courant

Salut

Utilises la méthode left pour tes calculs d'intégrales tu auras un résultat plus précis pour des appareils qui ne fonctionnent pas en permanence.