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, Cash piscine pour moi.
- 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 Injection »
Fonctionnement
Trois modes de fonctionnement sélectable par un « input_select.mode_fonct_regulation_ph » déclaré dans « /config/helpers »:
- Automatique
- Marche forcée
- Arret forcée
Trois Options déclarées dans l’automatisme:
Option 1: Mode Automatique
- Calcul du volume à injecter recopié dans « input_number.ph_vol_ph_moins_a_injecter » avec:
- me, ve et va sont des données constructeurs, j’utilise le pH moins liquide Cash Piscine:
- me= Montant du produit (0,2 Litre)
- ve= Valeur de l’effet du produit (0.1 à 0.2)
- va= Volume d’eau affecté par le produit (10 m3)
- vb= volume du bassin (50m3 pour moi)
- coef: coefficient d’ajustement en % « input_number.ph_coefficient_injection_ph_moins »
- q=((m-c)/ve*(vb/va)*mp*coef/100)
- me, ve et va sont des données constructeurs, j’utilise le pH moins liquide Cash Piscine:
- Calcul du temps d’injection en fonction du débit de la pompe de (en L/h) et de la quantité (q) précédemment calculée:
- recopie dans input_number.ph_duree_inject_s et input_number.ph_duree_inject_mn
- Minutes: q*3600/de, on garde la partie entière de la division par 60 ((r//60).
- Secondes: Même calcul que pour les minutes, mais le résultat est le reste de la division par 60 ((r%60))
- recopie dans input_number.ph_duree_inject_s et input_number.ph_duree_inject_mn
- Notification telegram
- Marche pompe ph
- Délai en fonction de « input_number.ph_duree_inject_mn:input_number.ph_duree_inject_s »
- Arret pompe ph
- Notification telegram
Option 2: Marche Forcée
Marche forcée de la pompe de dosage pH (pas de régulation)
Option 3: Arrêt Forcé
Arrêt forcé de la pompe de dosage pH (pas de régulation)
ou arrêt de la pompe de filtration
Codage
alias: 3_2_2 Piscine-pH Injection V2
description: Injection pH v2
trigger:
- platform: state
entity_id:
- input_select.mode_fonct_regulation_ph
- platform: time
at: "11:00:00"
id: 11h
- platform: time
at: "15:00:00"
id: 15h
- platform: state
entity_id:
- binary_sensor.esp137_ppe_en_fonctionnement
from: "on"
to: "off"
id: at_filtration
condition: []
action:
- choose:
- conditions:
- condition: state
entity_id: input_select.mode_fonct_regulation_ph
state: Auto
- condition: template
value_template: |-
{% set m=states('sensor.ph_piscine_ph') | float %}
{% set c=states('input_number.ph_cible') | float %}
{{ m > c }}
- condition: numeric_state
entity_id: sensor.ph_piscine_ph
above: "0"
- condition: state
state: "on"
entity_id: binary_sensor.esp137_ppe_en_fonctionnement
for:
hours: 0
minutes: 15
seconds: 0
- condition: trigger
id:
- 11h
- 15h
sequence:
- target:
entity_id: input_number.ph_vol_ph_moins_a_injecter
data_template:
value: >-
{% set m=states('sensor.ph_piscine_ph') | float(default=0) %} {%
set x=states('input_number.simul_ph') | float(default=0) %} {%
set c=states('input_number.ph_cible') | float(default=0) %} {%
set mp=0.2 %} {% set ve=0.2 %} {% set va=10 %} {% set vb=50 %}
{% set de=states('input_number.ph_debit_ppe') | float(default=0)
%} {% set
coef=states('input_number.ph_coefficient_injection_ph_moins') |
float(default=0) %} {% set
q=((m-c)/ve*(vb/va)*mp*coef/100)|round(2) %} {% if q < 0 %} {{ 0
}} {% else %} {{ (q) }} {% endif %}
action: input_number.set_value
- target:
entity_id: input_number.ph_duree_inject_s
data_template:
value: >-
{% set q=states('input_number.ph_vol_ph_moins_a_injecter') |
float(default=0) %} {% set
de=states('input_number.ph_debit_ppe') | float(default=0) %} {%
set tps=(q*3600/de)|round(2) %} {% if tps < 0 %} {{ 0 }} {% else
%} {{ (tps%60)|round(0)|int(default=0) }} {% endif %}
action: input_number.set_value
- target:
entity_id: input_number.ph_duree_inject_mn
data_template:
value: >-
{% set q=states('input_number.ph_vol_ph_moins_a_injecter') |
float(default=0) %} {% set
de=states('input_number.ph_debit_ppe') | float(default=0) %} {%
set tps=(q*3600/de)|round(2) %} {% if tps < 0 %} {{ 0 }} {% else
%} {{ (tps//60)|round(0)|int(default=0) }} {% endif %}
action: input_number.set_value
- data:
message: >-
{{states("sensor.date_time") }}{{-"\n"-}} pH sonde=
{{states('sensor.ph_piscine_ph')}} {{-"\n"-}} Cible pH=
{{states('input_number.ph_cible')}} {{-"\n"-}} Vol à
Injecter={{states('input_number.ph_vol_ph_moins_a_injecter')}}l
{{-"\n"-}} Durée injection=
{{states('input_number.ph_duree_inject_mn')}}mn-{{states('input_number.ph_duree_inject_s')}}s
{{-"\n"-}} Poids du bidon=
{{states('sensor.esp129_poids_ph_moins')}}kg
title: Piscine Début injection pH !!!
action: notify.telegram
- target:
entity_id:
- switch.ppe_ph
data: {}
action: switch.turn_on
- delay: >-
00:{{ states('input_number.ph_duree_inject_mn')|int}}:{{
states('input_number.ph_duree_inject_s') | int }}
- target:
entity_id: switch.ppe_ph
data: {}
action: switch.turn_off
- data:
message: >-
pH sonde= {{states('sensor.ph_piscine_ph')}} {{-"\n"-}} Poids du
bidon= {{states('sensor.esp129_poids_ph_moins')}}kg {{-"\n"-}}
{{states("sensor.date_time") }}
title: Piscine Fin injection pH !!!
action: notify.telegram
- conditions:
- condition: state
entity_id: input_select.mode_fonct_regulation_ph
state: Ma Forcée
sequence:
- target:
entity_id:
- switch.ppe_ph
data: {}
action: switch.turn_on
- conditions:
- condition: or
conditions:
- condition: state
entity_id: input_select.mode_fonct_regulation_ph
state: At Forcé
- condition: trigger
id:
- at_filtration
sequence:
- target:
entity_id: switch.ppe_ph
data: {}
action: switch.turn_off
mode: single
Automatisme « Piscine Notifications pH »
Déclencheurs:
Code
alias: 3_2_3 Piscine-pH Notifications
description: Notifie Ph bas, haut, anormal, bidon bas
trigger:
- platform: numeric_state
entity_id: sensor.ph_stat_median
below: "6.8"
above: "0"
id: ph_bas
for:
hours: 0
minutes: 1
seconds: 0
- platform: numeric_state
entity_id: sensor.ph_stat_median
id: ph_haut
above: "7.8"
for:
hours: 0
minutes: 1
seconds: 0
- platform: numeric_state
entity_id: sensor.ph_stat_standard_deviation
id: ph_mauvais
above: "0.1"
for:
hours: 0
minutes: 1
seconds: 0
- platform: state
entity_id:
- binary_sensor.ph_niveau_bas_bidon
id: niv_bas_bidon
to: "on"
for:
hours: 0
minutes: 1
seconds: 0
condition:
- condition: state
entity_id: switch.ppe_ph
state: "on"
action:
- choose:
- conditions:
- condition: trigger
id: ph_bas
sequence:
- data:
message: >-
Ph Bas = {{states('sensor.ph_stat_median')
}}{{-"\n"-}}{{states("sensor.date_time") }}
title: Piscine Alerte pH !!!
action: notify.telegram
- conditions:
- condition: trigger
id: ph_haut
sequence:
- data:
message: >-
Ph Haut = {{states('sensor.ph_stat_median')
}}{{-"\n"-}}{{states("sensor.date_time") }}
title: Piscine Alerte pH !!!
action: notify.telegram
- conditions:
- condition: trigger
id: ph_mauvais
sequence:
- 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 !!!
action: notify.telegram
- conditions:
- condition: trigger
id: niv_bas_bidon
sequence:
- 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 !!!
action: notify.telegram
default: []
mode: single
Déclaration des entités
Les déclarations des entités sont pour certaines, disponibles dans le fichier ph.yaml à télécharger, d’autre sont à déclarer dans /config/helpers.
Interface lovelace (pour info)
type: vertical-stack
cards:
- type: history-graph
entities:
- entity: switch.ppe_filtration
name: Ppe filtre
- entity: switch.ev_eau
name: Ev Eau
- entity: switch.ppe_ph
name: Ppe pH
hours_to_show: 72
refresh_interval: 0
title: <- 3 jours
- type: custom:button-card
name: PARAMETRES
styles:
card:
- text-transform: uppercase
- font-size: 125%
- border-radius: 50
- font-weight: bold
- letter-spacing: 10px
- type: entities
entities:
- entity: input_select.mode_fonctionnement_piscine
name: Mode de Fonctionnement
- entity: input_select.mode_fonct_regulation_ph
name: Mode Régul pH
- entities:
- entity: sensor.pression_filtre
name: Pression
- entity: input_number.mem_temp_piscine
name: T Eau
- entity: sensor.vp2_temp_out
name: T Ext
entity: sensor.pression_filtre
icon: mdi:chart-bell-curve
name: Mesures
show_state: false
type: custom:multiple-entity-row
- entities:
- entity: sensor.ph_piscine_ph
name: pH
- entity: sensor.esp125_ph_median
name: ph_md
- entity: switch.ppe_ph
name: Ppe
- entity: input_number.ph_cible
name: Cible
unit: false
- entity: sensor.esp129_poids_ph_moins
name: Pds Bid
unit: false
entity: input_boolean.regul_ph
icon: mdi:ph
name: Ph
show_state: false
type: custom:multiple-entity-row
- entities:
- entity: input_number.temps_cartouche_chlore
name: Tps Cartouche
unit: false
- entity: input_number.chlore_seuil_max_utilisation
name: Tps Max
entity: input_number.temps_cartouche_chlore
icon: mdi:chart-bell-curve
name: Chlore cart
show_state: false
type: custom:multiple-entity-row
- entities:
- entity: input_number.filtration_coeff_abaque
name: Coeff
- entity: input_number.affichage_duree_filtration_piscine
name: Durée
- entity: input_text.piscine_periode_filtration
name: Tranch Hor
entity: input_text.piscine_periode_filtration
icon: mdi:clock
name: Tps Filtration
show_state: false
type: custom:multiple-entity-row
- entities:
- entity: input_datetime.heure_ma_ppe_pisc_mode_horaire
name: h_MaPpe
- entity: input_number.duree_filtration_mode_horaire
name: Tps F
entity: input_boolean.hors_gel_valid
icon: mdi:clock
name: Mode Horaire
show_state: false
type: custom:multiple-entity-row
- entities:
- entity: input_number.hors_gel_inf_seuil1
name: T°Inf S1
- entity: input_number.hors_gel_inf_seuil2
name: T°Inf S2
- entity: input_boolean.hors_gel_valid
name: HG Valid
entity: input_boolean.hors_gel_valid
name: Hors Gel
icon: mdi:snowflake-alert
show_state: false
type: custom:multiple-entity-row
- entities:
- entity: input_boolean.piscine_arret_force
name: Forc 0
- entity: binary_sensor.esp137_ppe_en_fonctionnement
name: Etat
- entity: sensor.ma_ppe_piscine_jour
name: Fonct. Jour
entity: input_text.piscine_periode_filtration
icon: mdi:pump
name: Pompe Filtration
show_state: false
type: custom:multiple-entity-row
- entities:
- entity: sensor.energie_piscine_jour
name: Conso J
- entity: sensor.pzem_pisc_puissance
name: Puissance
- entity: sensor.pzem_pisc_courant
name: Intensité
entity: sensor.pzem_pisc_puissance
icon: mdi:flash
name: Conso Elec
show_state: false
type: custom:multiple-entity-row
- entities:
- entity: switch.ev_eau
name: Cde EV
- entity: binary_sensor.niveau_haut_piscine
name: NH
- entity: binary_sensor.niveau_inter_piscine
name: NI
- entity: binary_sensor.niveau_bas_piscine
name: NB
entity: input_boolean.ev_eau_piscine
name: Appoint Eau
show_state: false
type: custom:multiple-entity-row
- entities:
- label: Hiver
type: section
- entity: input_number.hors_gel_inf_seuil1
name: T°Inf S1
- entity: input_number.hors_gel_inf_seuil2
name: T°Inf S2
- label: Filtration
type: section
- entity: input_number.filtration_coeff_abaque
name: Coef
- entity: input_number.tempo_circulation_eau
name: Tempo Circulation
- entity: input_datetime.heure_pivot_pisc
name: Heure pivot
- entity: sensor.heure_pivot_soleil
name: H Pivot Sun
- label: Appoint Eau
type: section
- entity: automation.piscine_ev_appoint_eau
name: Automs
- entity: sensor.ev_eau_sur_7j
name: 7J
- entity: sensor.ev_eau_tps_ouverture_jour
name: 1J
- label: pH
type: section
- entity: sensor.ph_ezo
name: pH Ezo
- entity: sensor.ph_piscine_ph
name: pH filtré
- entity: sensor.ph_stat_median
name: pH Median
- entity: sensor.ph_stat_standard_deviation
name: pH Standard Deviation
- entity: input_boolean.regul_ph
- entity: input_number.ph_cible
- entity: input_number.ph_debit_ppe
- entity: input_number.ph_coefficient_injection_ph_moins
- entity: input_number.ph_vol_ph_moins_a_injecter
- entity: input_number.ph_duree_inject_mn
- entity: input_number.ph_duree_inject_s
- entity: input_number.ph_seuil_bas_bidon
- entity: binary_sensor.ph_niveau_bas_bidon
- label: Commutateurs
type: section
- entity: cover.volet_piscine
name: Couverture flottante
- entity: input_boolean.eclairage_piscine
name: Eclairage
- entity: input_boolean.ev_eau_piscine
name: EV Eau appoint en auto si actif
- entity: automation.piscine_ev_appoint_eau
head:
label: PARAMETRES
type: section
padding: 0
show_state: false
type: custom:fold-entity-row
- entities:
- entity: switch.ppe_filtration
name: Relais Pompe Filtre
- entity: switch.ppe_ph
name: Relais pH
- entity: switch.ppe_chlore
name: Relais Chlore
- entity: switch.cde_ouv_volet_piscine
name: Relais Ouverture Volet
- entity: switch.cde_ferm_volet_piscine
name: Relais fermeture Volet
- entity: switch.cde_ecl_piscine
name: Relais Eclairage
- entity: switch.ev_eau
name: EV Eau
head:
label: COMMANDES DIRECTES
type: section
padding: 0
show_state: false
type: custom:fold-entity-row
how_header_toggle: false
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.
Liste des publications en lien avec cet article:
- Filtration avec « AppDaemon » ou avec « Pool Pump Manager«
- Mesure de puissance électrique
- Mise à niveau automatique
- Mesure du pH
- Régulation du Ph
- Mise Hors Gel
- Mesure de pression
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