Skip to content

Instantly share code, notes, and snippets.

@gaetanars
Forked from mbo18/gestion_piscine_advanced.yaml
Last active December 6, 2025 18:29
Show Gist options
  • Select an option

  • Save gaetanars/bd53f2275c39e39bd7ba77be224e7bf2 to your computer and use it in GitHub Desktop.

Select an option

Save gaetanars/bd53f2275c39e39bd7ba77be224e7bf2 to your computer and use it in GitHub Desktop.
Gestion filtration piscine (avancé)
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