Cet article fait suite au précédent article :
J’ai souhaité remplacer un D1 Mini par un D1 mini V4 nouvelle version.

Le précédent était flashé avec Esp Easy, le nouveau, je l’ai flashé avec ESP Home.
Voici les deux tutos :
Une fois le D1 mini V4 flashé avec Esp Home, je poursuis la configuration.
Je profite du changement de D1Mini pour remplacer la résistance du pont diviseur entre A0 et GND, je mets une 51K. La valeur de cette résistance est calé sur la valeur de la thermorésistance à 25°C (à mesurer manuellement avant installation donc).
Pour mémoire, voici le schéma de câblage

Le câblage du D1 Mini est inchangé, je reproduis donc le schéma avec le D1 Mini V4.
Se référer à cette page pour plus d’explication :
Je réalise la configuration du fichier yaml du device ESP Home
Une fois le D1 mini V4 flashé, je vais dans ESPHome Builder et je trouve mon équipement :

Je clique sur EDIT et je modifie le fichier yaml, voici la configuration :
substitutions:
name: esphome-web-e586c5
friendly_name: ESPHome Eau Chaude
esphome:
name: ${name}
friendly_name: ${friendly_name}
min_version: 2024.6.0
name_add_mac_suffix: false
project:
name: esphome.web
version: dev
esp8266:
board: esp01_1m
# Activer la journalisation
logger:
# Activer l'API Home Assistant
api:
# Autoriser les mises à jour Over-The-Air
ota:
- platform: esphome
# Autoriser la configuration Wi-Fi via le port série
improv_serial:
wifi:
# Configurer un point d'accès Wi-Fi
ap: {}
# En combinaison avec l'option `ap`, cela permet à l'utilisateur
# de configurer les identifiants Wi-Fi via l'AP Wi-Fi.
captive_portal:
dashboard_import:
package_import_url: github://esphome/example-configs/esphome-web/esp8266.yaml@main
import_full_config: true
# Pour avoir une "URL suivante" pour improv_serial
web_server:
sensor:
- platform: ntc
sensor: temp_resistance
name: "Température"
unit_of_measurement: "°C"
accuracy_decimals: 2
calibration:
b_constant: 3950
reference_temperature: 25°C
reference_resistance: 50kOhm
- platform: resistance
id: temp_resistance
sensor: temp_voltage
configuration: DOWNSTREAM
resistor: 50kOhm
reference_voltage: 3.3V
- platform: adc
pin: A0
id: temp_voltage
# Capteur de turbine pour l'eau froide
- platform: pulse_meter
pin:
number: GPIO13
mode:
input: true
pullup: true
name: 'Débit Eau potable'
unit_of_measurement: 'L/min'
accuracy_decimals: 0
internal_filter: 100ms
timeout: 5s
filters:
- multiply: 0.013
total:
name: 'Total Eau potable'
unit_of_measurement: 'L'
id: total_eau_potable
accuracy_decimals: 2
filters:
- multiply: 0.013
# Capteur de turbine pour l'eau chaude
- platform: pulse_meter
pin:
number: GPIO14
mode:
input: true
pullup: true
name: 'Débit Eau chaude'
unit_of_measurement: 'L/min'
accuracy_decimals: 0
internal_filter: 100ms
timeout: 5s
filters:
- multiply: 0.013 # 1/77
total:
name: 'Total Conso Eau chaude'
unit_of_measurement: 'L'
id: total_eau_chaude
accuracy_decimals: 2
filters:
- multiply: 0.013 # 1/77
# Calculated sensor for net cold water consumption
- platform: template
name: "Total Conso Eau froide"
unit_of_measurement: "L"
accuracy_decimals: 2
lambda: |-
return id(total_eau_potable).state - id(total_eau_chaude).state;
En quelques lignes, voici l’explication :
Capteur de température (NTC) :
- Utilise un thermistor NTC
- Mesure en °C avec 2 décimales
- Configuration en cascade : ADC (A0) → resistance → ntc
- Calibré avec une constante B de 3950 et une référence à 25°C/50kΩ
Deux capteurs de débit d’eau (pulse_meter) :
- Eau potable sur GPIO13, Eau chaude sur GPIO14
- Configuration en mode input avec pullup activé
- Conversion : multiplie par 0.013 (calibré sur 77 impulsions/L)
- Timeout de 5s (retour à 0 si pas d’impulsions)
- Filtre interne de 100ms pour stabiliser la lecture
- Chacun dispose d’un compteur total en litres
- Précision : 0 décimale pour le débit, 2 pour le total
Un capteur calculé :
- Calcule la consommation d’eau froide
- Formule : Total eau potable – Total eau chaude
- Précision : 2 décimales
Je sélectionne les capteurs que je garde

Je vais garder les 4 derniers capteurs, je désactive les autres et je les renomme en :
- sensor.temperature_eau_chaude
- sensor.esphome_total_eau_potable
- sensor.esphome_total_eau_chaude
- sensor.esphome_total_eau_froide


J’ajoute 3 capteurs d’offset
Quand le D1 Mini V4 redémarre (coupure de jus par exemple), le comptage repart à zéro.
J’ai donc organisé le calcul du comptage total via un capteur qui me donne la somme d’un offset et de la valeur du comptage en cours.
J’ai donc ajouté 3 entités d’offset. Pour les puristes, seuls deux sont obligatoires, le 3eme peut être calculé.
Donc dans Paramètres/Appareils et Services/Entrées, j’ai ajouté une entrée

Puis Nombre


Cela me créé donc input_number.eau_froide_offset.
Je fais cela pour les deux autres offset

J’ai choisi d’utiliser « eau potable » pour tout ce qui passe dans le compteur eau potable donc le consommation totale : eau froide + eau chaude.
J’ajoute 3 automatisations pour gérer le Reset du compteur du D1 Mini
Le D1 Mini a un défaut de taille, il perd la valeur de ses compteurs en cas de reset, tout repart donc à zéro, cela ne me convient donc pas.
J’ai remarqué qu’au moment du reset, les capteurs passent à l’état « unavailable » avant de repasser à zéro.
Je vais donc affecté l’état précédent unavailable à un input_number qui me servira d’offset, c’est à dire de valeur de correction pour le comptage global.
Pour que ce soit plus simple, je fais 3 automatisations qui réalisent cela :
alias: Offset Eau Chaude sur Unavailable
triggers:
- entity_id: sensor.esphome_total_eau_chaude
to: unavailable
trigger: state
actions:
- target:
entity_id: input_number.eau_chaude_offset
data:
value: >-
{{ states('input_number.eau_chaude_offset') | float +
trigger.from_state.state | float }}
action: input_number.set_value
mode: single
alias: Offset Eau Froide sur Unavailable
triggers:
- entity_id: sensor.esphome_total_eau_froide
to: unavailable
trigger: state
actions:
- target:
entity_id: input_number.eau_froide_offset
data:
value: >-
{{ states('input_number.eau_froide_offset') | float +
trigger.from_state.state | float }}
action: input_number.set_value
mode: single
alias: Offset Eau Potable sur Unavailable
triggers:
- entity_id: sensor.esphome_total_eau_potable
to: unavailable
trigger: state
actions:
- target:
entity_id: input_number.eau_potable_offset
data:
value: >-
{{ states('input_number.eau_potable_offset') | float +
trigger.from_state.state | float }}
action: input_number.set_value
mode: single
Pour chaque type d’eau (chaude, froide, potable), quand le capteur devient indisponible (‘unavailable’) :
- L’automatisation capture la dernière valeur connue avant la déconnexion
- Cette valeur est ajoutée à un compteur d’offset stocké dans un input_number
- Cela permet de conserver le cumul total même après un redémarrage du capteur

Je déclare les capteurs finaux de consommation
Dans mon fichier templates.yaml, j’ajoute ces 3 capteurs :
- sensor:
- name: "Consommation Eau Potable"
unique_id: sensor.consommation_eau_potable
unit_of_measurement: "L"
device_class: water
state_class: total_increasing
state: >
{% set mesure_actuelle = states('sensor.esphome_total_eau_potable') | float %}
{% set total_offset = states('input_number.eau_potable_offset') | float %}
{{ total_offset + mesure_actuelle if states('sensor.esphome_total_eau_potable') != 'unavailable' else total_offset }}
- name: "Consommation Eau Froide"
unique_id: sensor.consommation_eau_froide
unit_of_measurement: "L"
device_class: water
state_class: total_increasing
state: >
{% set mesure_actuelle = states('sensor.esphome_total_eau_froide') | float %}
{% set total_offset = states('input_number.eau_froide_offset') | float %}
{{ total_offset + mesure_actuelle if states('sensor.esphome_total_eau_froide') != 'unavailable' else total_offset }}
- name: "Consommation Eau Chaude"
unique_id: sensor.consommation_eau_chaude
unit_of_measurement: "L"
device_class: water
state_class: total_increasing
state: >
{% set mesure_actuelle = states('sensor.esphome_total_eau_chaude') | float %}
{% set total_offset = states('input_number.eau_chaude_offset') | float %}
{{ total_offset + mesure_actuelle if states('sensor.esphome_total_eau_chaude') != 'unavailable' else total_offset }}
Ces capteurs sont des capteurs virtuels (templates) qui permettent de suivre la consommation d’eau de manière persistante. Analysons leur fonctionnement :
Sources des données :
- Capteurs physiques ESP Home (sensor.esphome_total_eau_*)
- Compteurs d’offset (input_number.eau_*_offset)
Types de mesures :
- Eau Potable : Total de l’eau entrante
- Eau Chaude : Consommation d’eau chaude
- Eau Froide : Consommation d’eau froide
Caractéristiques communes :
- state_class: total_increasing : Indique un compteur qui augmente continuellement
- unit_of_measurement: « L » : Mesure en litres
Logique de fonctionnement :
{% set mesure_actuelle = states(‘sensor.esphome_total_eau_*’) | float %}
{% set total_offset = states(‘input_number.eau_*_offset’) | float %}
{{ total_offset + mesure_actuelle if states(…) != ‘unavailable’ else total_offset }}
- Si le capteur ESP est disponible : Total = Offset + Mesure actuelle
- Si le capteur ESP est indisponible : Total = Offset uniquement
Je configure recorder
Il faut penser à garder ce dont on a besoin mais aussi à ne pas enregistrer ce qui n’est pas utile.
Ainsi dans la configuration de Recorder, je mets dans :
include:
entity_globs:
[...]
- input_number.eau_*
- sensor.consommation_eau_*
exclude:
entity_globs:
[...]
- sensor.esphome*
Je teste le reset du D1 Mini V4
Au final, j’ai donc
- 3 input_number qui servent d’offset,
- 3 sensors qui me donnent la valeur des compteurs actuels du D1 Mini
- 3 sensors calculés qui me donnent la valeur des compteurs permanents

A ce stade, le D1 ne s’est jamais relancé, donc les compteurs du D1 et les compteurs permanents sont identiques.
Je débranche et rebranche le D1 mini, les capteurs vont devenir indisponible le temps du reset puis repasser à 0.

A ce moment là, les Offset prennent les dernières valeurs des compteurs. Puis le D1 mini se reconnecte à Home assistant :

Les compteurs permanents reprennent la valeur des offset + valeur du compteur du D1 (0).
Je fais couler un peu d’eau chaude et un peu d’eau froide, les offset ne bougent pas mais les compteurs affichent les bonnes valeurs :

Je garde donc uniquement les 3 derniers compteurs pour mon Dashboard et pour les statistiques de conso.
Résultat



Si c’était à refaire (idées ou retour d’expérience)
- J’utiliserais une turbine avec capteur de température même pour l’eau froide, j’ai la curiosité de vouloir savoir la température surtout en hiver.

