Automatisation de la Pompe de Filtration de Piscine en Fonction de la Température

Bonjour à tous,

Je souhaite partager avec vous une solution que j’ai mise en place pour l’automatisation de la pompe de filtration de ma piscine en fonction de la température de l’eau. Cette solution utilise des blueprints pour Home Assistant et intègre la gestion des événements dans un calendrier pour une automatisation complète et dynamique.

Screenshot 2024-05-15 224925

Fonctionnalités :

  • Calcul dynamique de la durée de filtration en fonction de la température de l’eau.
  • Planification automatique des périodes de filtration dans un calendrier.
  • Activation et désactivation automatique de la pompe de filtration selon les événements du calendrier.
  • Possibilité de déclenchement manuel des automatisations pour ajuster les périodes de filtration si nécessaire.

1. Blueprints

Blueprint pour la filtration dynamique ajustée de la piscine : Ce blueprint calcule la durée de filtration à 8h, programme un 1/3 de filtration avant l’heure pivot et recalcul après l’heure pivot en fonction de la nouvelle température de l’eau pour les 2/3 de filtration restant.

blueprint:
  name: Programmation pompe filtration piscine
  description: Calcule la durée de filtration à 8h, programme un tiers avant l'heure pivot et recalcul après l'heure pivot en fonction de la nouvelle température de l'eau.
  domain: automation
  input:
    sensor_temperature_piscine:
      name: Capteur de température de la piscine
      description: Entité du capteur de température de la piscine.
      selector:
        entity:
          domain: sensor
    calendar_id:
      name: ID de Calendrier
      description: Identifiant du calendrier pour enregistrer les événements de filtration.
      selector:
        entity:
          domain: calendar
    input_number_total_filtration:
      name: Nombre total d'heures de filtration
      description: Entité pour stocker le nombre total d'heures de filtration.
      selector:
        entity:
          domain: input_number
    input_number_temps_filtration_avant_15:
      name: Temps de Filtration avant heure pivot
      description: Entité pour stocker le temps de filtration avant l'heure pivot.
      selector:
        entity:
          domain: input_number
    input_text_filtration_debut_matin:
      name: Entité pour stocker l'heure de début de la filtration matin
      description: Entité pour stocker l'heure de début de la filtration du matin.
      selector:
        entity:
          domain: input_text
    input_text_filtration_fin_apres_midi:
      name: Entité pour stocker l'heure de fin de la filtration après-midi
      description: Entité pour stocker l'heure de fin de la filtration de l'après-midi.
      selector:
        entity:
          domain: input_text
    pivot_hour:
      name: Heure pivot
      description: Sélectionnez l'heure pivot pour la filtration.
      selector:
        time: {}

trigger:
  - platform: time
    at: "08:00:00"
  - platform: time
    at: !input pivot_hour
  - platform: event
    event_type: 'MANUAL_TRIGGER'

action:
  - variables:
      pivot_hour: !input pivot_hour

  - choose:
      - conditions:
          - condition: template
            value_template: >
              {{ now().hour == 8 or (trigger.event.event_type == 'MANUAL_TRIGGER' and trigger.event.data.get('manual_trigger_time') == 'morning') }}
        sequence:
          - variables:
              sensor_temperature_piscine: !input sensor_temperature_piscine
              calendar_id: !input calendar_id
              input_number_total_filtration: !input input_number_total_filtration
              input_number_temps_filtration_avant_15: !input input_number_temps_filtration_avant_15
              input_text_filtration_debut_matin: !input input_text_filtration_debut_matin
              temperature_eau_matin: >
                {{ states(sensor_temperature_piscine) | float if states(sensor_temperature_piscine) not in ['unknown', 'unavailable', None] else 0 }}
              pivot_hour: !input pivot_hour
              pivot_timestamp: "{{ as_timestamp(now().replace(hour=(pivot_hour.split(':')[0] | int), minute=(pivot_hour.split(':')[1] | int), second=0)) }}"
          - variables:
              temps_filtration_total_matin: >
                {% if temperature_eau_matin < 10 %}
                  0
                {% elif 10 <= temperature_eau_matin <= 14 %}
                  {{ temperature_eau_matin / 3 }}
                {% elif 14 < temperature_eau_matin <= 30 %}
                  {{ temperature_eau_matin / 2 }}
                {% else %}
                  24
                {% endif %}
              temps_filtration_avant_pivot: "{{ (temps_filtration_total_matin / 3) | round(2) | float }}"
              start_time_matin: "{{ (pivot_timestamp - (temps_filtration_avant_pivot * 3600)) | timestamp_custom('%Y-%m-%d %H:%M:%S', True) }}"
              end_time_matin: "{{ pivot_timestamp | timestamp_custom('%Y-%m-%d %H:%M:%S', True) }}"
          - service: input_number.set_value
            target:
              entity_id: "{{ input_number_total_filtration }}"
            data:
              value: "{{ temps_filtration_total_matin }}"
          - service: input_number.set_value
            target:
              entity_id: "{{ input_number_temps_filtration_avant_15 }}"
            data:
              value: "{{ temps_filtration_avant_pivot }}"
          - service: calendar.create_event
            target:
              entity_id: "{{ calendar_id }}"
            data:
              summary: "Filtration piscine matin (avant heure pivot)"
              start_date_time: "{{ start_time_matin }}"
              end_date_time: "{{ end_time_matin }}"
          - service: input_text.set_value
            target:
              entity_id: "{{ input_text_filtration_debut_matin }}"
            data:
              value: "{{ start_time_matin }}"
      - conditions:
          - condition: template
            value_template: >
              {{ now().hour == (pivot_hour.split(':')[0] | int) and now().minute == (pivot_hour.split(':')[1] | int) or (trigger.event.event_type == 'MANUAL_TRIGGER' and trigger.event.data.get('manual_trigger_time') == 'afternoon') }}
        sequence:
          - variables:
              sensor_temperature_piscine: !input sensor_temperature_piscine
              calendar_id: !input calendar_id
              input_number_total_filtration: !input input_number_total_filtration
              input_number_temps_filtration_avant_15: !input input_number_temps_filtration_avant_15
              input_text_filtration_fin_apres_midi: !input input_text_filtration_fin_apres_midi
              temperature_eau_apres_midi: >
                {{ states(sensor_temperature_piscine) | float if states(sensor_temperature_piscine) not in ['unknown', 'unavailable', None] else 0 }}
              pivot_hour: !input pivot_hour
              pivot_timestamp: "{{ as_timestamp(now().replace(hour=(pivot_hour.split(':')[0] | int), minute=(pivot_hour.split(':')[1] | int), second=0)) }}"
          - variables:
              temps_filtration_total_matin: >
                {{ states('input_number.total_filtration') | float if states('input_number.total_filtration') not in ['unknown', 'unavailable', None] else 0 }}
              temps_filtration_avant_pivot: >
                {{ states('input_number.temps_filtration_avant_15') | float if states('input_number.temps_filtration_avant_15') not in ['unknown', 'unavailable', None] else 0 }}
          - variables:
              temps_filtration_total_apres_midi: >
                {% if temperature_eau_apres_midi < 10 %}
                  0
                {% elif 10 <= temperature_eau_apres_midi <= 14 %}
                  {{ temperature_eau_apres_midi / 3 }}
                {% elif 14 < temperature_eau_apres_midi <= 30 %}
                  {{ temperature_eau_apres_midi / 2 }}
                {% else %}
                  24
                {% endif %}
              temps_filtration_apres_pivot: "{{ max((temps_filtration_total_apres_midi | float) - (temps_filtration_avant_pivot | float), 0) | round(2) }}"
              end_time_apres_midi: "{{ (pivot_timestamp + (temps_filtration_apres_pivot * 3600)) | timestamp_custom('%Y-%m-%d %H:%M:%S', True) }}"
          - service: input_number.set_value
            target:
              entity_id: "{{ input_number_total_filtration }}"
            data:
              value: "{{ temps_filtration_total_apres_midi }}"
          - service: calendar.create_event
            target:
              entity_id: "{{ calendar_id }}"
            data:
              summary: "Filtration piscine après-midi (après heure pivot)"
              start_date_time: "{{ pivot_timestamp | timestamp_custom('%Y-%m-%d %H:%M:%S', True) }}"
              end_date_time: "{{ end_time_apres_midi }}"
          - service: input_text.set_value
            target:
              entity_id: "{{ input_text_filtration_fin_apres_midi }}"
            data:
              value: "{{ end_time_apres_midi }}"

Blueprint pour le contrôle de la pompe de filtration : Ce blueprint active ou désactive la pompe de filtration de la piscine selon les événements du calendrier.

blueprint:
  name: Contrôle de la pompe de filtration de piscine
  description: Active ou désactive la pompe de filtration de la piscine selon les événements du calendrier.
  domain: automation
  input:
    calendar_entity:
      name: Entité du calendrier
      description: Entité du calendrier pour suivre les événements de filtration.
      selector:
        entity:
          domain: calendar
    switch_pompe_filtration:
      name: Entité de la pompe de filtration
      description: Entité contrôlant la pompe de filtration.
      selector:
        entity:
          domain: switch

trigger:
  - platform: state
    entity_id: !input calendar_entity

action:
  - variables:
      calendar_entity: !input calendar_entity
      switch_pompe_filtration: !input switch_pompe_filtration
  - choose:
      - conditions:
          - condition: template
            value_template: "{{ is_state(calendar_entity, 'on') }}"
        sequence:
          - service: switch.turn_on
            target:
              entity_id: "{{ switch_pompe_filtration }}"
      - conditions:
          - condition: template
            value_template: "{{ is_state(calendar_entity, 'off') }}"
        sequence:
          - service: switch.turn_off
            target:
              entity_id: "{{ switch_pompe_filtration }}"

2. Sensors

Ces sensors permettent de récupérer les horaires de début et de fin de filtration ainsi que le temps total de filtration.

- platform: template
  sensors:
      filtration_debut_matin:
        friendly_name: "Filtration Début Matin"
        value_template: >
          {% set time = states('input_text.filtration_debut_matin') %}
          {% if time != 'unknown' and time != 'unavailable' %}
            {{ as_timestamp(time) | timestamp_custom('%H:%M', true) }}
          {% else %}
            N/A
          {% endif %}
      filtration_fin_apres_midi:
        friendly_name: "Filtration Fin Après-Midi"
        value_template: >
          {% set time = states('input_text.filtration_fin_apres_midi') %}
          {% if time != 'unknown' and time != 'unavailable' %}
            {{ as_timestamp(time) | timestamp_custom('%H:%M', true) }}
          {% else %}
            N/A
          {% endif %}
      filtration_total:
        friendly_name: "Temps de Filtration Total"
        value_template: >
          {% set total = states('input_number.total_filtration') | float %}
          {% set hours = total // 1 %}
          {% set minutes = ((total - hours) * 60) | round(0) %}
          {{ '%02d:%02d' | format(hours, minutes) }}

3. Input Numbers et Input Texts

Ces entités sont utilisées pour stocker les valeurs calculées pour les temps de filtration.

temps_filtration_avant_15:
    name: Temps Filtration Avant 15h
    min: 0
    max: 24
    step: 0.01
    unit_of_measurement: 'hours'

total_filtration:
    name: Nombre total d'heures de filtration
    min: 0
    max: 48
    step: 0.01
    unit_of_measurement: 'hours'
filtration_debut_matin:
    name: Filtration Début Matin
filtration_fin_apres_midi:
    name: Filtration Fin Après-Midi

4. Scripts pour le déclenchement manuel

Ces scripts permettent de déclencher manuellement les automatisations de filtration.

manual_filtration_trigger_morning:
    alias: Déclencheur manuel de filtration (matin)
    sequence:
      - event: MANUAL_TRIGGER
        event_data:
          manual_trigger_time: "morning"
          
manual_filtration_trigger_afternoon:
    alias: Déclencheur manuel de filtration (après-midi)
    sequence:
      - event: MANUAL_TRIGGER
        event_data:
          manual_trigger_time: "afternoon"

5. Carte du Dashboard

Voici la carte du dashboard Home Assistant pour gérer et visualiser l’état de la piscine.

type: vertical-stack
cards:
  - type: horizontal-stack
    cards:
      - type: custom:mini-graph-card
        entities:
          - sensor.temperature_piscine
        name: Température de la piscine
        align_state: center
        align_icon: left
        line_color: '#3498db'
        line_width: 3
        hours_to_show: 24
        points_per_hour: 0.5
        color_thresholds:
          - value: 25
            color: '#0acdff'
          - value: 30
            color: '#40f99b'
          - value: 40
            color: '#E76D83'
      - type: custom:button-card
        entity: switch.pompe_piscine
        name: Pompe de la Piscine
        icon: mdi:water-pump
        show_state: true
        state:
          - value: 'on'
            color: '#3498db'
            icon: mdi:water-pump
            name: En Fonctionnement
          - value: 'off'
            color: '#e74c3c'
            icon: mdi:water-pump-off
            name: Arrêtée
        styles:
          card:
            - height: 165px
          name:
            - font-size: 16px
          state:
            - font-size: 0px
          icon:
            - width: 50px
            - height: 50px
            - color: var(--primary-color)
        tap_action:
          action: toggle
  - type: entities
    title: Gestion de la Piscine
    entities:
      - entity: sensor.filtration_debut_matin
        name: Début Filtration
      - entity: sensor.filtration_fin_apres_midi
        name: Fin Filtration
      - entity: sensor.filtration_total
        name: Temps Total de Filtration

J’espère que cela vous sera utile ! N’hésitez pas à poser des questions ou à partager vos retours.

EDIT le 22/05/2024 :

Maj du Blueprint principal pour permettre de choisir l’heure « pivot » auparavant à 15h.

12 « J'aime »

Bonjour,
Un grand merci pour ce partage, qui est exactement ce que je cherchais.
Est-ce qu’il vous serait possible d’ajouter pour chaque élément une petite ligne descriptive expliquant ou le placer (ajout dans un fichier particulier, ou création de fichier et emplacement de celui-ci) ?
Merci pour votre aide…
Patrice

1 « J'aime »

J’ai dans mon fichier configuration.yaml ces lignes :
input_number: !include input_numbers.yaml
input_text: !include input_text.yaml
sensor: !include sensor.yaml
scripts: !include scripts.yaml

C’est dans ces fichiers que tu vas mettre tous les sensors input et scripts

Pour ce qui est des blueprints il faut les mettre dans /blueprints/automation/

2 « J'aime »

Bonjour, quelle sonde de température utilises-tu?

Celle ci :
Owon

J’en avais acheté une l’année dernière, elle a très bien fonctionné, mais j’ai voulu la réappairer pour cette saison et je n’ai plus de remonter de température.

Je t’avoue que je viens de l’acheter pour l’instant cela fonctionne parfaitement.

Pour une autre solution il y a ça:

Ce n’est pas tout a fait la même chose car il faut un shelly pour le mettre en place, mais ça a l’avantage ( entre autre) de pouvoir fonctionner même si HA est down ( ou les sondes). Le but est d’avoir un truc autonome, mais avec des remontés et un piltage dans HA

Merci, j’ai pu compléter la configuration sans trop de souci.
Il me manquait l’intégration button-card, installée sans trop de souci via HACS.
Il faut aussi l’intégration calendar. Peut être pouvez vous ajouter les dépendances pour être complet.
Un dernier souci : je ne vois pas ou se raccroche le Blueprint à la valeur de la sonde de température.
Côté UI j’ai modifié la carte pour récupérer la valeur de ma sonde (sensor.pool_temp) pour la courbe; c’est OK.
Par contre les valeurs calculées restent à N/A ou 00:00. Je suppose que c’est bien la température qui n’est pas récupérée de façon correcte.
Lors de l’utilisation du Blueprint, on doit spécifier le Calendar & le switch de la pompe, mais pas vu la sonde de température.
Merci pour votre aide…
Cordialement

Seul 1 des 2 blueprint utilise la température de la sonde, le deuxième sert juste à récupérer les valeurs horaire pour déclencher la pompe.

Mais bien sûr, suis-je bête… Il faut configurer les 2 Blueprints !!!
Il faut aussi adapter la carte avec le bon identifiant du switch de la pompe.
Pour finir, et voir le résultat, lancer les deux scripts.
Et voila, ça tourne !!
Merci encore pour ce partage…

Merci Maxime.

Peux-tu nous en dire un peu plus sur l’équipement matériel de ce système ?
Type de moteurs, type relais, protocoles…

J’ai seulement une prise IKEA connecté où est branché ma pompe, et un capteur de température dans ma piscine c’est tout

1 « J'aime »

Chapeau @Maxime_SALTET !

Simple et efficace, en plus tout avec des composants standards.

J’ai une automation beaucoup plus complexe basée sur python, mais je pense que je vais bientôt basculer sur la tienne.

Merci !

Luis

1 « J'aime »

EDIT le 22/05/2024 :

Maj du Blueprint principal pour permettre de choisir l’heure « pivot » auparavant à 15h.

1 « J'aime »

Bonjour, @Maxime_SALTET merci beaucoup pour cette gestion de la pompe piscine :slight_smile:
j’ai reçu hier mon thermomètre bluetooth pour ma piscine INKBIRD, tout est bien remonté de ce coté, seulement je but un peu pour mettre votre gestion en place sur mon instance home assistant :grimacing:
j’ai du mal à voir ce qu’il faut que je modifies dans les blueprints afin que cela fonctionne ? si vous pouvez me dire ce serait top de votre part.
@Patrice_Becquet , parle aussi d’intégration calendar, je ne le trouve pas sur mon instance, j’utilise le calendrier local, est-ce suffisant ?

Merci d’avance pour vos réponses .

C’est bien le calendrier local que j’utilise, il faut créer son calendrier pour la piscine.

Il n’y a rien à modifier dans le blueprint, seulement l’importer. Ensuite à la création de l’automatisation il faudra sélectionner les bons sensors.

1 « J'aime »

Merci beaucoup pour votre réponse, en créant les 2 automatisations, ensuite en exécutant les 2 scripts, tout s’affiche bien sur la carte, un grand merci à vous :slight_smile:

j’ai ajouter dans sensors.yaml un « unique_id » afin de pouvoir modifié l’icône sur la carte, petite contribution dérisoire :sweat_smile:

  - platform: template
    sensors:
        filtration_debut_matin:
          friendly_name: "Filtration Début Matin"
          unique_id: sensor.filtration_debut_matin
          value_template: >
            {% set time = states('input_text.filtration_debut_matin') %}
            {% if time != 'unknown' and time != 'unavailable' %}
              {{ as_timestamp(time) | timestamp_custom('%H:%M', true) }}
            {% else %}
              N/A
            {% endif %}
        filtration_fin_apres_midi:
          friendly_name: "Filtration Fin Après-Midi"
          unique_id: sensor.filtration_fin_apres_midi
          value_template: >
            {% set time = states('input_text.filtration_fin_apres_midi') %}
            {% if time != 'unknown' and time != 'unavailable' %}
              {{ as_timestamp(time) | timestamp_custom('%H:%M', true) }}
            {% else %}
              N/A
            {% endif %}
        filtration_total:
          friendly_name: "Temps de Filtration Total"
          unique_id: sensor.filtration_total
          value_template: >
            {% set total = states('input_number.total_filtration') | float %}
            {% set hours = total // 1 %}
            {% set minutes = ((total - hours) * 60) | round(0) %}
            {{ '%02d:%02d' | format(hours, minutes) }}

Bonjour, j’ai lu le sujet entier et essayé par moi-même de trouver une solution, mais sans succès.
Je ne peux pas importer le blueprint car il me faut une adresse github ou une adresse.
Tu dis qu’il ne faut rien modifier dans le blueprint mais juste l’importer et modifier les sensors dans l’automatisation.
Merci pour ton travail en tout cas.

Tu peux copier le blueprint dans un fichier dans ton dossier de blueprint directement dans home assistant