Forked from mbo18/gestion_piscine_advanced.yaml
Last active
December 6, 2025 18:29
-
-
Save gaetanars/bd53f2275c39e39bd7ba77be224e7bf2 to your computer and use it in GitHub Desktop.
Gestion filtration piscine (avancé)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| blueprint: | |
| name: "Gestion filtration piscine (avancé)" | |
| description: "Gestion automatique de la filtration/pompe de la piscine" | |
| domain: automation | |
| homeassistant: | |
| min_version: 2024.6.0 | |
| input: | |
| temperature_piscine: | |
| name: "Capteur de température de la piscine" | |
| description: "La température permet de calculer la durée de filtration" | |
| selector: | |
| entity: | |
| filter: | |
| domain: sensor | |
| device_class: temperature | |
| multiple: false | |
| switch_pompe: | |
| name: "Entité de contrôle de la pompe" | |
| description: "Pour pouvoir allumer et éteindre la pompe selon les heures calculées de début et fin de filtration" | |
| selector: | |
| entity: | |
| filter: | |
| domain: | |
| - switch | |
| - light | |
| - input_boolean | |
| multiple: true | |
| bouton_reset: | |
| name: "Bouton de reset du temps de filtration" | |
| description: "Permet de (re)lancer le calcul de la durée et des horaires de filtration" | |
| selector: | |
| entity: | |
| filter: | |
| domain: input_button | |
| multiple: false | |
| parametres_generaux: | |
| name: "Paramètres généraux" | |
| icon: mdi:cog | |
| input: | |
| mode_filtration: | |
| name: "Mode de filtration de la piscine" | |
| description: > | |
| Courbe : Calcul de la durée selon une courbe en fonction de la température de la piscine | |
| Hivernage : Fait marcher la pompe 3h par jour si la température de l'eau est inférieure ou égale 10°C, 24h si la température est en dessous de la température hors gel et le mode hors gel est activé. Au dessus de 10°C, le temps de filtration est égal à la température de l'eau divisée par 3. | |
| Automatique : Combine le mode Courbe et le mode Hivernage afin de ne pas avoir à changer de mode au cours de l'année. Le mode hivernage s'active dès que l'eau passe en dessous de la température configurée | |
| Forcé : Force le fonctionnement de la pompe | |
| Inactif : Coupe la pompe et la gestion de la filtration | |
| selector: | |
| entity: | |
| filter: | |
| domain: input_select | |
| multiple: false | |
| ajustement: | |
| name: "Coefficient d'ajustement du temps de filtration" | |
| description: "Permet d'influer à la baisse ou à la hausse le temps de filtration pour l'adapter à vos besoins" | |
| selector: | |
| entity: | |
| filter: | |
| domain: input_number | |
| multiple: false | |
| parametres_mode_courbe: | |
| name: "Paramètres du mode Courbe" | |
| icon: mdi:refresh-auto | |
| input: | |
| heure_pivot: | |
| name: "Heure pivot de filtration" | |
| description: "Heure autour de laquelle les horaires de filtration sont calculés" | |
| selector: | |
| entity: | |
| filter: | |
| domain: sensor | |
| device_class: timestamp | |
| multiple: false | |
| duree_coupure: | |
| name: "Durée de coupure de la filtration" | |
| description: "Permet de définir une pause dans la filtration autour de l'heure pivot" | |
| selector: | |
| entity: | |
| filter: | |
| domain: input_number | |
| multiple: false | |
| parametres_mode_hiver: | |
| name: "Paramètres du mode Hivernage" | |
| icon: mdi:snowflake | |
| input: | |
| temps_filtration_hiver_min: | |
| name: "Temps de filtration minimum" | |
| description: "Durée de filtration (en heures) si la température est inférieure à 10°C." | |
| default: 3 | |
| selector: | |
| number: | |
| min: 0 | |
| max: 12 | |
| step: 0.5 | |
| unit_of_measurement: h | |
| mode: slider | |
| facteur_division_hiver: | |
| name: "Facteur de division" | |
| description: "Diviseur pour le calcul du temps de filtration si la température est supérieure à 10°C (temp / facteur)." | |
| default: 3 | |
| selector: | |
| number: | |
| min: 1 | |
| max: 5 | |
| step: 0.1 | |
| mode: slider | |
| heure_hivernage: | |
| name: "Heure pivot de filtration en hivernage" | |
| description: "Heure autour de laquelle les horaires de filtration sont calculés en hivernage" | |
| selector: | |
| entity: | |
| filter: | |
| domain: sensor | |
| device_class: timestamp | |
| multiple: false | |
| duree_coupure_hiver: | |
| name: "Durée de coupure de la filtration" | |
| description: "Permet de définir une pause dans la filtration autour de l'heure pivot" | |
| selector: | |
| entity: | |
| filter: | |
| domain: input_number | |
| multiple: false | |
| activation_hors_gel: | |
| name: "Mode hors gel" | |
| description: "En mode hors gel, la filtration est permanente si la température de la piscine est en dessous de la température hors gel" | |
| default: "Activé" | |
| selector: | |
| select: | |
| options: | |
| - "Activé" | |
| - "Désactivé" | |
| temperature_hors_gel: | |
| name: "Température hors gel" | |
| description: "En dessous de cette température la filtration est permanente" | |
| default: 1 | |
| selector: | |
| number: | |
| min: -5 | |
| max: 5 | |
| step: 1 | |
| unit_of_measurement: °C | |
| mode: slider | |
| parametres_mode_automatique: | |
| name: "Paramètres du mode Automatique" | |
| icon: mdi:refresh-auto | |
| input: | |
| temp_passage_hiver: | |
| name: "Température de déclenchement du mode Hivernage" | |
| description: "En dessous de cette température, activation du mode Hivernage" | |
| default: 15 | |
| selector: | |
| number: | |
| min: 0 | |
| max: 20 | |
| step: 1 | |
| unit_of_measurement: °C | |
| mode: slider | |
| entites_pour_calcul: | |
| name: "Entités pour stocker les données du calcul" | |
| icon: mdi:database | |
| input: | |
| duree_filtration: | |
| name: "Durée de filtration de la piscine" | |
| selector: | |
| entity: | |
| filter: | |
| domain: input_number | |
| multiple: false | |
| heure_debut_filtration_1_piscine: | |
| name: "Heure début 1ère période de filtration" | |
| selector: | |
| entity: | |
| filter: | |
| domain: input_datetime | |
| multiple: false | |
| heure_fin_filtration_1_piscine: | |
| name: "Heure fin 1ère période de filtration" | |
| selector: | |
| entity: | |
| filter: | |
| domain: input_datetime | |
| multiple: false | |
| heure_debut_filtration_2_piscine: | |
| name: "Heure début 2ième période de filtration" | |
| selector: | |
| entity: | |
| filter: | |
| domain: input_datetime | |
| multiple: false | |
| heure_fin_filtration_2_piscine: | |
| name: "Heure fin 2ième période de filtration" | |
| selector: | |
| entity: | |
| filter: | |
| domain: input_datetime | |
| multiple: false | |
| mode: single | |
| max_exceeded: silent | |
| variables: | |
| temp_piscine: !input temperature_piscine | |
| mode_filtration: !input mode_filtration | |
| coef: !input ajustement | |
| activation_hors_gel: !input activation_hors_gel | |
| temp_hors_gel: !input temperature_hors_gel | |
| duree_coupure: !input duree_coupure | |
| duree_coupure_hiver: !input duree_coupure_hiver | |
| heure_p: !input heure_pivot | |
| heure_pivot: "{{ states(heure_p) | as_timestamp | timestamp_custom('%H:%M:%S') }}" | |
| heure_p_h: !input heure_hivernage | |
| heure_pivot_hiver: "{{ states(heure_p_h) | as_timestamp | timestamp_custom('%H:%M:%S') }}" | |
| temp_passage_hiver: !input temp_passage_hiver | |
| temps_filtration_hiver_min: !input temps_filtration_hiver_min | |
| facteur_division_hiver: !input facteur_division_hiver | |
| duree_filtration_calculee: >- | |
| {% set temp = states(temp_piscine)|float(10) %} | |
| {% set max_duree = 1440 %} | |
| {# Logique pour le mode Courbe #} | |
| {% macro calc_courbe(temp_piscine, coef) %} | |
| {% set temp_calc = max(temp_piscine, 10) %} | |
| {% set a = 0.00335 * coef / 100 %} | |
| {% set b = -0.14953 * coef / 100 %} | |
| {% set c = 2.43489 * coef / 100 %} | |
| {% set d = -10.72859 * coef / 100 %} | |
| {% set hours = (a * temp_calc**3) + (b * temp_calc**2) + (c * temp_calc) + d %} | |
| {{ min((hours * 60)|round(0), 1440) }} | |
| {% endmacro %} | |
| {# Logique pour le mode Hivernage #} | |
| {% macro calc_hivernage(temp_piscine, temp_hors_gel, activation_hg, temps_min, facteur_div) %} | |
| {% if activation_hg == 'Activé' and temp_piscine <= temp_hors_gel %} | |
| {{ max_duree }} | |
| {% elif temp_piscine < 10 %} | |
| {{ (temps_min * 60)|round(0) }} | |
| {% else %} | |
| {{ ((temp_piscine / facteur_div) * 60)|round(0) }} | |
| {% endif %} | |
| {% endmacro %} | |
| {# Choix en fonction du mode #} | |
| {% if states(mode_filtration) == 'Courbe' %} | |
| {{ calc_courbe(temp, states(coef)|float) }} | |
| {% elif states(mode_filtration) == 'Hivernage' %} | |
| {{ calc_hivernage(temp, temp_hors_gel, activation_hors_gel, temps_filtration_hiver_min|float(3), facteur_division_hiver|float(3)) }} | |
| {% elif states(mode_filtration) == 'Automatique' %} | |
| {% if temp < temp_passage_hiver %} | |
| {{ calc_hivernage(temp, temp_hors_gel, activation_hors_gel, temps_filtration_hiver_min|float(3), facteur_division_hiver|float(3)) }} | |
| {% else %} | |
| {{ calc_courbe(temp, states(coef)|float) }} | |
| {% endif %} | |
| {% elif states(mode_filtration) == 'Forcé' %} | |
| 1440 | |
| {% else %} | |
| 0 | |
| {% endif %} | |
| triggers: | |
| - trigger: time | |
| at: !input heure_debut_filtration_1_piscine | |
| id: "filtration_1_debut" | |
| - trigger: time | |
| at: !input heure_fin_filtration_1_piscine | |
| id: "filtration_1_fin" | |
| - trigger: time | |
| at: !input heure_debut_filtration_2_piscine | |
| id: "filtration_2_debut" | |
| - trigger: time | |
| at: !input heure_fin_filtration_2_piscine | |
| id: "filtration_2_fin" | |
| - trigger: state | |
| entity_id: !input bouton_reset | |
| id: "reset_appui" | |
| - trigger: state | |
| entity_id: !input mode_filtration | |
| id: "changement_mode" | |
| - trigger: state | |
| entity_id: !input switch_pompe | |
| id: "etat_pompe_change" | |
| - trigger: state | |
| entity_id: !input heure_pivot | |
| id: "maj_heure_pivot" | |
| - trigger: state | |
| entity_id: !input duree_coupure | |
| id: "maj_duree_coupure" | |
| - trigger: state | |
| entity_id: !input ajustement | |
| id: "param_change" | |
| - trigger: state | |
| entity_id: !input heure_hivernage | |
| id: "param_change" | |
| - trigger: state | |
| entity_id: !input duree_coupure_hiver | |
| id: "param_change" | |
| actions: | |
| # Calcul des heures de début et fin des périodes | |
| - if: | |
| - or: | |
| - condition: trigger # Si fin de la 2nd période | |
| id: "filtration_2_fin" | |
| - condition: trigger # Si reset | |
| id: "reset_appui" | |
| - condition: trigger # Si changement de mode | |
| id: "changement_mode" | |
| - condition: trigger # Si changement heure pivot | |
| id: "maj_heure_pivot" | |
| - condition: trigger # Si changement durée de coupure | |
| id: "maj_duree_coupure" | |
| - condition: trigger | |
| id: "param_change" | |
| then: | |
| - variables: | |
| duree: "{{ duree_filtration_calculee }}" | |
| h_pivot: >- | |
| {% if states(mode_filtration) == 'Automatique' and states(temp_piscine)|float < temp_passage_hiver %} | |
| {{ heure_pivot_hiver }} | |
| {% elif states(mode_filtration) == 'Hivernage' %} | |
| {{ heure_pivot_hiver }} | |
| {% else %} | |
| {{ heure_pivot }} | |
| {% endif %} | |
| d_coupure: >- | |
| {% if states(mode_filtration) == 'Automatique' and states(temp_piscine)|float < temp_passage_hiver %} | |
| {{ states(duree_coupure_hiver)|int }} | |
| {% elif states(mode_filtration) == 'Hivernage' %} | |
| {{ states(duree_coupure_hiver)|int }} | |
| {% else %} | |
| {{ states(duree_coupure)|int }} | |
| {% endif %} | |
| start_1: "{{ today_at(h_pivot) - timedelta(minutes=duree/2) - timedelta(minutes=d_coupure/2) }}" | |
| end_1: "{{ today_at(h_pivot) - timedelta(minutes=d_coupure/2) }}" | |
| start_2: "{{ today_at(h_pivot) + timedelta(minutes=d_coupure/2) }}" | |
| end_2: "{{ today_at(h_pivot) + timedelta(minutes=duree/2) + timedelta(minutes=d_coupure/2) }}" | |
| pas_de_coupure: "{{ end_1 | as_datetime > start_2 | as_datetime }}" | |
| - choose: | |
| # mode Forcé | |
| - conditions: | |
| - "{{ states(mode_filtration) == 'Forcé' }}" | |
| sequence: | |
| - action: input_number.set_value | |
| target: | |
| entity_id: !input duree_filtration | |
| data: | |
| value: 1440 | |
| - action: input_datetime.set_datetime | |
| target: | |
| entity_id: | |
| - !input heure_debut_filtration_1_piscine | |
| - !input heure_fin_filtration_1_piscine | |
| - !input heure_debut_filtration_2_piscine | |
| - !input heure_fin_filtration_2_piscine | |
| data: | |
| time: "00:00:00" | |
| - action: homeassistant.turn_on | |
| target: | |
| entity_id: !input switch_pompe | |
| # mode Inactif | |
| - conditions: | |
| - "{{ states(mode_filtration) == 'Inactif' }}" | |
| sequence: | |
| - action: input_number.set_value | |
| target: | |
| entity_id: !input duree_filtration | |
| data: | |
| value: 0 | |
| - action: input_datetime.set_datetime | |
| target: | |
| entity_id: | |
| - !input heure_debut_filtration_1_piscine | |
| - !input heure_fin_filtration_1_piscine | |
| - !input heure_debut_filtration_2_piscine | |
| - !input heure_fin_filtration_2_piscine | |
| data: | |
| time: "00:00:00" | |
| - action: homeassistant.turn_off | |
| target: | |
| entity_id: !input switch_pompe | |
| # Mode Courbe, Automatique et Hivernage | |
| default: | |
| - service: input_number.set_value | |
| target: | |
| entity_id: !input duree_filtration | |
| data: | |
| value: "{{ duree }}" | |
| - service: input_datetime.set_datetime | |
| target: | |
| entity_id: !input heure_debut_filtration_1_piscine | |
| data: | |
| datetime: "{{ [today_at('00:00:00'), start_1 | as_datetime]|max if duree < 1440 else today_at('00:00:00') }}" | |
| - service: input_datetime.set_datetime | |
| target: | |
| entity_id: !input heure_fin_filtration_1_piscine | |
| data: | |
| datetime: "{{ end_2 if pas_de_coupure else end_1 }}" | |
| - service: input_datetime.set_datetime | |
| target: | |
| entity_id: !input heure_debut_filtration_2_piscine | |
| data: | |
| datetime: "{{ end_2 if pas_de_coupure else start_2 }}" | |
| - service: input_datetime.set_datetime | |
| target: | |
| entity_id: !input heure_fin_filtration_2_piscine | |
| data: | |
| datetime: "{{ [today_at('23:59:00'), end_2 | as_datetime]|min }}" | |
| - if: | |
| - "{{ states(mode_filtration) not in ['Forcé', 'Inactif'] }}" | |
| then: | |
| - choose: | |
| # Demarrage de la pompe en debut de periode | |
| - conditions: | |
| - condition: trigger | |
| id: "filtration_1_debut" | |
| sequence: | |
| - action: homeassistant.turn_on | |
| target: | |
| entity_id: !input switch_pompe | |
| - conditions: | |
| - condition: trigger | |
| id: "filtration_2_debut" | |
| - "{{ states(duree_coupure)|int > 0 }}" | |
| sequence: | |
| - action: homeassistant.turn_on | |
| target: | |
| entity_id: !input switch_pompe | |
| # Arrêt de la pompe en fin de periode | |
| - conditions: | |
| - condition: trigger | |
| id: "filtration_1_fin" | |
| - "{{ states(duree_coupure)|int > 0 }}" | |
| sequence: | |
| - action: homeassistant.turn_off | |
| target: | |
| entity_id: !input switch_pompe | |
| - conditions: | |
| - condition: trigger | |
| id: "filtration_2_fin" | |
| sequence: | |
| - action: homeassistant.turn_off | |
| target: | |
| entity_id: !input switch_pompe | |
| # Si changement de mode ou d'état de la pompe | |
| - conditions: | |
| - or: | |
| - condition: trigger # Changement de mode | |
| id: "changement_mode" | |
| - condition: trigger # Changement d'état de la pompe | |
| id: "etat_pompe_change" | |
| sequence: | |
| - if: | |
| - or: | |
| - condition: time | |
| after: !input heure_debut_filtration_1_piscine | |
| before: !input heure_fin_filtration_1_piscine | |
| - condition: time | |
| after: !input heure_debut_filtration_2_piscine | |
| before: !input heure_fin_filtration_2_piscine | |
| then: | |
| - action: homeassistant.turn_on | |
| target: | |
| entity_id: !input switch_pompe | |
| else: | |
| - action: homeassistant.turn_off | |
| target: | |
| entity_id: !input switch_pompe |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment