Contents
Intro
Avant de publier cet article, j’ai laissé passer un été de mise au point du process de régulation, c’est le temps que je me suis laissé pour obtenir un résultat fiable et publiable.
Puisque que le pH de ma piscine a tendance à augmenter de part la nature du traitement, il me faut donc injecter du pH-.
Je ne reviens pas sur la mesure de pH développé dans un article précédent, la mesure est considérée comme fiable.
La partie matérielle
La liste des courses se résume à:
- Une pompe péristaltique acheté chez AliExpress. Alimentation en 220 VCa, débit variable de 0 à 7.2 l/h avec une pression de 0.1 bar.
- Du liquide pH- disponible dans les boutiques spécialisées dans le traitement des piscines.
- Un module de pilotage avec un relais équipé d’un contact sec et intégrable dans HA ‘switch’. Dans mon cas j’utilise un automate WAGO série 750 communiquant en Modbus, équipé d’une carte d’entrées pt100, d’une carte d’entrées digitales et d’une carte de sortie relais.
Bien entendu, cet automate peut être remplacé par n’importe quel dispositif compatible HA, remplissant les mêmes fonctionnalités.
Cahier des charges
- Fonctionne en mode automatique
- Validation du mode automatique simple d’emploi.
- Les paramètres doivent être accessibles et modifiables
- Notification en cas de pH hors limite
- Notification du début et fin de cycle
- Notification du volume de pH- injecté et utilisé
La partie logicielle
Automatisme « Piscine pH Validation Automatismes »
Cet automatisme valide d’autres automatismes lorsque la pompe de filtration tourne depuis 15mn, le temps nécessaire à la stabilisation des mesures.
Descriptif fonctionnel

Code
- id: '1624083693650'
alias: 3_2_1 Piscine-pH Validation Automatismes
description: 'Valide les automations régulation pH au bout de 1 h de fonctionnement '
trigger:
- platform: state
entity_id: binary_sensor.pool_pump_running
for:
hours: 0
minutes: 15
seconds: 0
to: 'on'
from: 'off'
id: ma_pump
- platform: state
entity_id: binary_sensor.pool_pump_running
id: at_pump
from: 'on'
to: 'off'
for:
hours: 0
minutes: 0
seconds: 10
- platform: state
entity_id: input_boolean.regul_ph
id: regule_ph_off
from: 'on'
to: 'off'
condition: []
action:
- choose:
- conditions:
- condition: trigger
id: ma_pump
- condition: state
entity_id: input_boolean.regul_ph
state: 'on'
sequence:
- service: automation.turn_on
target:
entity_id:
- automation.piscine_injection_v2
- automation.piscine_notification_ph
- service: notify.telegram
data:
message: pH sonde= {{states('sensor.ph_piscine_ph')}} {{-"\n"-}}{{states("sensor.date_time")
}}
title: Piscine Activation Traitement pH !
- conditions:
- condition: trigger
id: at_pump
sequence:
- service: automation.turn_off
target:
entity_id:
- automation.piscine_injection_v2
- automation.piscine_notification_ph
- conditions:
- condition: trigger
id: regule_ph_off
sequence:
- service: automation.turn_off
target:
entity_id:
- automation.piscine_injection_v2
- automation.piscine_notification_ph
default: []
mode: single
Automatisme « Piscine pH Injection »
Ces deux templates sont utilisés dans l’automatisme « 3_2_2 Piscine-pH Injection ».
Fonctionnement
Toutes les heures:
- Si ph_piscine_ph > ph_cible et ph_piscine_ph>0
alors
Calcul basé sur l’écart entre la mesure et la cible (a-b), divisé par la concentration (en %) et le débit de la pompe (d en l/h), converti en secondes (*3600), et si supérieur à 0, le résultat est la partie entière de la division par 60 ((r//60)|int).
- Notification telegram
- Calcul du volume à injecter dans ph.yaml dans input_number.ph_duree_inject_s et input_number.ph_duree_inject_mn
- Minutes: Calcul basé sur l’écart entre la mesure et la cible (a-b), divisé par la concentration (e en %) et le débit de la pompe (d en l/h), converti en secondes (*3600), et si supérieur à 0, le résultat est la partie entière de la division par 60 ((r//60)|int).
- Secondes: Même calcul que pour les minutes, mais le résultat est le reste de la division par 60 ((r%60)|int)
- Marche pompe ph
- Délai input_number.ph_duree_inject_mn:input_number.ph_duree_inject_s
- Calcul du volume à injecter: {% set a=states(‘input_number.ph_vol_injecte’)|float %} {% set b=states(‘input_number.ph_debit_ppe’)|float %} {% set c=states(‘input_number.ph_duree_inject_s’)|float %} {% set d=states(‘input_number.ph_duree_inject_mn’)|float %} {{a+((b*((d*60)+c)/3600))|round(2) }}
- Arret pompe ph
- Notification
Codage
alias: 3_2_2 Piscine-pH Injection
description: 'Injection pH '
trigger:
- platform: time_pattern
hours: /1
condition:
- condition: template
value_template: |-
{% set a=states('sensor.ph_piscine_ph') | float %}
{% set b=states('input_number.ph_cible') | float %}
{{ a > b }}
- condition: numeric_state
entity_id: sensor.ph_piscine_ph
above: '0'
- condition: state
entity_id: input_boolean.regul_ph
state: 'on'
action:
- service: input_number.set_value
target:
entity_id: input_number.ph_duree_inject_s
data_template:
value: >-
{% set a=states('sensor.ph_piscine_ph') | float(default=0) %} {% set
x=states('input_number.simul_ph') | float(default=0) %} {% set
b=states('input_number.ph_cible') | float(default=0) %} {% set
d=states('input_number.ph_debit_ppe') | float(default=0) %} {% set
e=states('input_number.ph_concentration') | float(default=0) %} {% set
r=(((a-b)/(e/100))/d)*3600|round(2)|int(default=0) %} {% if r < 0 %} {{
0 }} {% else %} {{ (r%60)|int(default=0) }} {% endif %}
- service: input_number.set_value
target:
entity_id: input_number.ph_duree_inject_mn
data_template:
value: >-
{% set a=states('sensor.ph_piscine_ph') | float(default=0) %} {% set
x=states('input_number.simul_ph') | float(default=0) %} {% set
b=states('input_number.ph_cible') | float(default=0) %} {% set
d=states('input_number.ph_debit_ppe') | float(default=0) %} {% set
e=states('input_number.ph_concentration') | float(default=0) %} {% set
r=(((a-b)/(e/100))/d)*3600|round(2)|int(default=0) %}
{% if r < 0 %}
{{ 0 }}
{% else %}
{{ (r//60)|int(default=0) }}
{% endif %}
- service: switch.turn_on
target:
entity_id:
- switch.ppe_ph
data: {}
- service: notify.telegram
data:
message: >-
pH sonde= {{states('sensor.ph_piscine_ph')}}
{{-"\n"-}}{{states("sensor.date_time") }}
title: Piscine Début injection pH !!!
- delay: >-
00:{{ states('input_number.ph_duree_inject_mn')|int}}:{{
states('input_number.ph_duree_inject_s') | int }}
- service: input_number.set_value
data_template:
entity_id: input_number.ph_vol_injecte
value: >-
{% set a=states('input_number.ph_vol_injecte')|float %} {% set
b=states('input_number.ph_debit_ppe')|float %} {% set
c=states('input_number.ph_duree_inject_s')|float %} {% set
d=states('input_number.ph_duree_inject_mn')|float %} {{a+(
(b*((d*60)+c)/3600))|round(2) }}
- service: switch.turn_off
target:
entity_id: switch.ppe_ph
data: {}
- service: notify.telegram
data:
message: >-
pH sonde= {{states('sensor.ph_piscine_ph')}}{{-"\n"-}} Vol Injecté = {%
set b=states('input_number.ph_debit_ppe')|float %} {% set
c=states('input_number.ph_duree_inject_s')|float %} {% set
d=states('input_number.ph_duree_inject_mn')|float %}
{{(b*((d*60)+c)/3600)|round(2) }} l
{{-"\n"-}}{{states("sensor.date_time") }}
title: Piscine Fin injection pH !!!
mode: single
Automatisme « Piscine Notifications pH »
Descriptif Fonctionnel

Code
- id: '1634204887702'
alias: 3_2_3 Piscine-pH Notifications
description: Notifie Ph bas, haut, anormal, bidon bas
trigger:
- platform: numeric_state
entity_id: sensor.ph_piscine_ph
below: '6.8'
above: '0'
id: ph_bas
- platform: numeric_state
entity_id: sensor.ph_piscine_ph
id: ph_haut
above: '7.8'
- platform: numeric_state
entity_id: sensor.ph_stat_standard_deviation
id: ph_mauvais
above: '0.1'
- platform: state
entity_id: binary_sensor.ph_niveau_bas_bidon
id: niv_bas_bidon
to: 'on'
condition: []
action:
- choose:
- conditions:
- condition: trigger
id: ph_bas
sequence:
- service: notify.telegram
data:
message: Ph Bas = {{states('sensor.ph_piscine_ph') }}{{-"\n"-}}{{states("sensor.date_time")
}}
title: Piscine Alerte pH !!!
- conditions:
- condition: trigger
id: ph_haut
sequence:
- service: notify.telegram
data:
message: Ph Haut = {{states('sensor.ph_piscine_ph') }}{{-"\n"-}}{{states("sensor.date_time")
}}
title: Piscine Alerte pH !!!
- conditions:
- condition: trigger
id: ph_mauvais
sequence:
- service: notify.telegram
data:
message: pH Mauvais-sonde à calibrer??{{-"\n"-}} Median = {{states("sensor.ph_stat_median")}}{{-"\n"-}}
Deviation(S=0.01) = {{states("sensor.ph_stat_standard_deviation")}} {{-"\n"-}}{{states("sensor.date_time")
}}
title: Piscine Alerte pH !!!
- conditions:
- condition: trigger
id: niv_bas_bidon
sequence:
- service: notify.telegram
data:
message: Volume Restant = {{(states("sensor.ph_volume_restant_bidon"))|round(2)
}} l{{-"\n"-}}{{states("sensor.date_time") }}
title: Piscine Alerte niveau Bas Bidon pH !!!
default: []
mode: single
Calcul du niveau bas bidon pH
Niveau bas bidon = on si Volum_bidon-volume_injecté inferieur au seuil bas
- platform: template
sensors:
ph_niveau_bas_bidon:
value_template: >-
{% set a=states('input_number.ph_vol_bidon')|float %}
{% set b=states('input_number.ph_vol_injecte')|float %}
{% set c=states('input_number.ph_seuil_bas_bidon')|float %}
{{ (a-b) <= c }}
friendly_name: "pH Seuil Niveau Bas Bidon"
Déclaration des entités
Les déclarations des entités sont disponibles dans le fichier ph.yaml à télécharger.
Interface lovelace
Les interfaces ont été décrits dans l’article sur la filtration.

Conclusion
Une régulation de pH complète qui donne de bons résultats, cependant vous pouvez dans un premier temps supprimer les fonctionnalités qui vous semblent superflues.
Bonjour,
Je viens de mettre en place une partie de tes automation mais je me demande d’où sort ta formule pour le calcul du temps d’injection ?
Pourquoi le volume de la piscine n’est pas pris en compte ? Quel est le volume de ta piscine afin de faire un ratio pour l’adapter. Merci
Bonjour
J’ai un volume de bassin de 50 m3. C’est pour moi une constante, c’est dans le coefficient « input_number.ph_concentration » qui j’intègre ce volume ainsi que la concentration du pH bien sur.J’ai 50% à ce jour avec du « pH moins » liquide acheté chez « cash piscine », coeff que j’ai affiné au fil du temps (ça fait un an maintenant)
Bon courage