Estimation de la Température du ballon d'eau chaude

Bonjour,

Voici une réalisation que j’ai faite pour savoir, de façon pas parfaite : Quelle est la Température du ballon d’eau.

Prérequis:

  • Avoir un appareil de mesure de la puissance du ballon
  • Et idéalement il faut aussi avoir un compte d’eau pour savoir combien d’eau on a utiliser.
  • Aussi une sonde de Température où est situer le ballon est un plus (surtout pour les variations été/hiver) mais on peut hard-coder une valeur si on a pas cette sonde.
  • Connaître la capacité et la taille du ballon ( Hauteur, diamètre, épaisseur isolant, … de façon relativement précise est un plus)

Limite

La température de l’eau dans un ballon n’est pas homogène, surtout si il chauffe de manière très sporadique, donc mon estimation que le ballon est chaud (a la température de consigne) dès que le ballon d’eau ne consomme plus d’électricité est un raccourci un peut trompeur

URL Utile

J’ai pas inventer la formule, j’ai pris les infos de ce site que je remercie au passage car intéressent et bien documenté :

Méthode Utiliser

Je considère le ballon comme une batterie (c’est une réserver d’énergie),
Avec cette « formule » de base : il faut 1,162 wattheure pour élever de un degré un litre d’eau

1/ Quand le ballon d’eau chaude est allumer mais ne consomme plus de courant, une automatisation positionne la température de l’eau a la température de consigne (55° chez moi)
Celle-ci est primordial car c’est ma seul façon de faire le « calibrage » de la T° de l’eau, un peut comme une batterie LiFePo4 et le reset 100%

2/ au fil du temps, de l’eau chaude est utiliser, refroidissant le ballon, un compteur enregistrer la quantité d’eau utiliser, voir la variable perte_Eau plus bas
3/ au fil du temps, l’eau du ballon se refroidi car son isolation n’est pas parfaite, un calcul de cette perte est utiliser, voir la variable perte_Wh plus bas
4/ si il chauffe, un calcul sur la chaleur rajouter au ballon est calculer, voir la variable chauffer plus bas

« Helpers/variables » utiliser/crée

Dans Paramètres / Appareils et services / Entrées , j’ai crée ces entrées :

  • sensor.consommation_eau_chaude_depuis_super_chaud via Compteur de service sur le compteur d’eau chaude utiliser
    « Juste » utiliser dans le dashboard pour savoir combien d’eau a était utiliser depuis qu’il a était chaud
  • sensor.consommation_eau_chaude_hourly via Compteur de service sur le compteur d’eau chaude utiliser.
    Utiliser par les automatisation pour savoir le refroidissement du ballon via aux tirages d’eau

le nommage hourly est mal choisi car on peut faire ça toute les heure ou toutes les 15minutes ou …

  • sensor.ballon_eau_en_fonctionnement de type template
    Afin de savoir si le ballon est en cours de chauffage d’eau
    ( j’ai modifier mon ballon pour n’utiliser qu’une résistance des 3 présentes, utilisant ainsi que 1kW au lieu des 3kW et l’unité utiliser est en kW et non des W pour cette appareil chez moi)
        {% if states('sensor.ballon_d_eau_chaude_power') | float (default=0) >= 0.8 %}
          on
        {% else %}
          off
        {% endif %}
  • sensor.ballon_super_chaud de type template :
    Afin de savoir si le ballon d’eau a arrêter de chauffer
        {% if states('switch.ballon_d_eau_chaude') == 'on' and states('sensor.ballon_eau_en_fonctionnement') == 'off' %}
          on 
        {% else %}
          off 
        {% endif %}

  • input_number.ballon_tdeg_estimer de type nombre, qui sera la température du ballon estimer, notre « sésame » tant recherché
  • sensor.ballon_eau_temps_chauffe_depuis_super_chaud de type History Stats (moi je l’ai crée via sensor.yaml ) :
# Ballon d'eau chaude temps reel en chauffe depuis la derniere fois qu'il était super-chaud
- platform: history_stats
  name: Ballon eau temps chauffe Depuis Super Chaud
  unique_id: Ballon Eau Temps Chauffe Depuis Super Chaude
  entity_id: sensor.ballon_eau_en_fonctionnement
  state: "on"
  type: time
  start: "{{ states('input_datetime.ballon_last_time_super_chaud') | as_datetime | as_local }}"
  end: "{{ now() }}"

Automatisation

1/ « Calibrage » du ballon à la température de consigne

alias: >-
  Définition de quand il a était la dernier fois chaud
description: Définition de quand il à était la dernier fois chaud
triggers:
  - trigger: state
    entity_id:
      - sensor.ballon_super_chaud
    to: "on"
    from: "off"
  - trigger: state
    entity_id:
      - sensor.ballon_super_chaud
    from: "on"
    to: "off"
conditions: []
actions:
  - action: input_datetime.set_datetime
    metadata: {}
    data:
      datetime: "{{ now().strftime('%Y-%m-%d %H:%M:%S') }}"
    target:
      entity_id: input_datetime.ballon_last_time_super_chaud
  - data:
      value: "0"
    target:
      entity_id: sensor.consommation_eau_chaude_hourly
    action: utility_meter.calibrate
    alias: Remize a 0L sensor.consommation_eau_chaude_depuis_super_chaud
  - action: input_number.set_value
    metadata: {}
    data:
      value: 55
    target:
      entity_id: input_number.ballon_tdeg_estimer
mode: single

2/ Mise a jour de la température de l’eau via le temps qui passe et l’eau utiliser et énergie injecter

Note1 : On peut changer le time_pattern, il faut juste penser dans ce cas a mettre a jour la variable perte_Wh en conséquance
Moi, j’utilise toutes les 15mm donc on divise par 4

Note 2: Mon ballon a une capacité de 200L, hauteur de 1.32m 44cm de Diamètre interne, 5cm d’isolant:
Volume calculé 1.32 × (0,44÷2)² × 3.14 × 1000 == 200L
Surface = 2,3349 = (3.14 × 1,32 × (0,44+0,05)) + (2 × 3.14 × 0,44²/4)
P = Perte en Wh = (Ts – Ta) x (Ci / E) x S = (55-25 x (0.033 / 0.05) x 2.3349 = 46.2 Wh
( cf URL plus haut)
si vous voulez, vous pouvez simplifier et faire une approximation sans faire ce calcul « compliqué », exemple « habituelle » perte_Wh = 100w par heure soit 25wh pour 15mm

Note 3 : mon ballon a une consommation (on devrait plutôt dire production dans notre cas) d’environ 1kW de chaleur si chez vous c’est différent multiplier en conséquence dans la variable chauffer

Note 4 : je n’ai pas de sensor sur la T° de l’eau froide, j’ai hard-coder 15 ° dans la variable perte_Eau, si vous avez ce sensor, le résultat n’en sera que plus fiable.

alias: Ballon T° Estimer Mise a jour /15mm
description: ""
triggers:
  - trigger: time_pattern
    minutes: /15
conditions: []
actions:
  - variables:
      perte_Wh: >-
        {{ ( ( states('input_number.ballon_tdeg_estimer') | float (default=0) -
        states('sensor.piece_ballon') | float (default=0) ) *
        (0.033 / 0.05) * ( (3.14 * 1.32 * (0.44+ 0.05) ) + (2 * 3.14 * 0.44 *
        0.44 / 4) ) /4 )| round (2,"ceil") }}
      perte_Eau: >-
        {{ 1.162 * ( states('input_number.ballon_tdeg_estimer')  | float
        (default=0) - ( states('input_number.ballon_tdeg_estimer')  | float
        (default=0) * ( 200 - states('sensor.consommation_eau_chaude_hourly') |
        float(default=0) | round (1) ) +
        states('sensor.consommation_eau_chaude_hourly') | float(default=0) |
        round (1) * 15 ) / 200 ) * 200 }}
      chauffer: >-
        {{ states('sensor.ballon_eau_temps_chauffe_depuis_super_chaud') |
        float(default=0) * 900 }}
      delta_t: "{{ ( perte_Wh + perte_Eau - chauffer ) / 200 / 1.162  }}"
      temp: >-
        {{ min(55,( states('input_number.ballon_tdeg_estimer') | float
        (default=0) - delta_t) | round (2) )}}
  - action: input_number.set_value
    metadata: {}
    data:
      value: "{{ temp }}"
    target:
      entity_id: input_number.ballon_tdeg_estimer
  - data:
      value: "0"
    target:
      entity_id: sensor.consommation_eau_chaude_hourly
    action: utility_meter.calibrate
mode: single

Exemple/Vérification sur une nuit

Ce matin là , le ballon était chaud a 11h40 alors que l’estimation l’estimé a 53.8° a 11h30 et en chauffe entre 11h30-11h40, donc la prédiction est très proche de la réalité.

Badge

J’utilise de façon synthétique un badge pour avoir les informations les plus usuelles :

Code utiliser pour custom:mushroom-template-badge
type: custom:mushroom-template-badge
content: >-
  {% if states('sensor.ballon_eau_temps_chauffe_depuis_super_chaud') |
  int(default=0) >= 1 %}
    {% set temps = states('sensor.ballon_eau_temps_chauffe_depuis_super_chaud') | float(default=0) | round(0, "floor") | string + 'h' + ( states('sensor.ballon_eau_temps_chauffe_depuis_super_chaud') | float(default=0) % 1 ) | multiply(60) | round (0,"floor") | string + 'm' %}
  {% elif states('
![Capture d’écran du 2025-08-08 13-53-10|180x49](upload://gJ8L00ItcULFbWYT3JccWSaJLKV.png)
') |
  float(default=0) |
  multiply(60) >= 1 %}
    {% set temps = states('sensor.ballon_eau_temps_chauffe_depuis_super_chaud') | multiply(60) | round (0,"floor") | string + 'm' %}
  {% else %}
    {% set temps = '0m' %}
  {% endif %}
  {{ states('input_number.ballon_tdeg_estimer') }}°C Ballon {% if
  states('sensor.consommation_eau_chaude_depuis_super_chaud') | float(default=0)
  | round(1) > 0.1 or temps != "0m" %}({% if
  states('sensor.consommation_eau_chaude_depuis_super_chaud') | float(default=0)
  | round(1) > 0.1%}-{{
  states('sensor.consommation_eau_chaude_depuis_super_chaud') | float(default=0)
  | round (1) }}L + {% endif %}{% if temps != "0m" %}{{ temps }} Chauffé{% endif
  %}){% endif %}
icon: mdi:water-boiler
color: >-
  {% if states('switch.ballon_d_eau_chaude') == 'on' %} red {% elif
  states('switch.ballon_d_eau_chaude') == 'off' and
  states('switch.enable_solar_optimizer_ballon_d_eau_chaude') == 'on' %} green
  {% else %} gray {% endif %}
label: >-
  {% from 'easy_time.jinja' import easy_time %} @{{
  easy_time('input_datetime.ballon_last_time_super_chaud', language='fr') }}
tap_action:
  action: more-info
entity: input_number.ballon_tdeg_estimer

4 exemples de la visu :

Capture d’écran du 2025-08-08 12-23-23Capture d’écran du 2025-08-08 13-53-10Capture d’écran du 2025-08-08 20-07-45Capture d’écran du 2025-08-09 11-16-15

5 « J'aime »