HA-Gestion Piscine-1_Filtration avec AppDaemon

Intro

Dans un article précédent, je détaillais la méthode utilisée permettant de calculer le temps de filtration de la piscine, basée sur le module HACS « Pool Pump Manager », qui fonctionne très bien mais bien trop figé à mon gout. En effet nous ne pouvons pas, par exemple, modifier la répartition du temps de filtration autour de l’heure pivot figée sur 1/3 avant et 2/3 après, paramétrer l’heure pivot, changer de méthode de calcul du temps basée uniquement sur l’abaque Abacus, choisir un mode hiver.

Je vous invite quand même à le parcourir, tout n’est pas à jeter.

Pour toutes ces raisons, et ayant récemment découvert l’addon « AppDaemon », voir mon article sur ce sujet , je me suis lancé dans un développement personnel de la gestion du temps de filtration en Python.

Je n’ai pas la prétention de me déclarer « expert » en programmation et en python. C’est en fouillant sur le net que j’ai pu arriver à mes fins et aboutir à un fonctionnement satisfaisant. Il est évident que ce programme sans prétention est largement perfectible. Tous les axes d’amélioration ou d’optimisation du code seront les bienvenus en commentaire.

Mises à Jour:

Du 24/02/2022:

  • Ajout d’une entité Arrêt_Forcé: Si = On cette entité force la pompe à l’arrêt quelque soit le mode. Dans mon cas je m’en sert pour délester la consommation.

Du 17/02/2022

  • Ajout niveau de journalisation
  • Ajout H_Pivot dans l’affichage tranche horaire « été »
  • Ajout tempo (« tempo_eau ») de prise en compte de la température après demarrage de la pompe: Dans le cas d’une mesure de température en ligne, cette temporisation permet de brasser l’eau du bassin avant de prendre en compte sa température. Avant la fin de la tempo, la mesure prise en compte dans le calcul est celle de la veille (mémorisée dans « mem_temp ») . Ce temps peut être mis à 0 si la prise de mesure est effectuée directement dans l’eau du bassin, quoique brasser l’eau quelques minutes avant de commencer le prise en compte de la T° permet de mélange les eaux de surface et de fond.

Pré requis

Mes fichiers « .yaml » sont regroupés dans un dossier « config/packages ». J’utilise la directive « !include_dir_named packages » dans mon « configuration.yaml » très pratique pour organiser son HA.

Ci après un extrait du « configuration. yaml » dont la version à jour est disponible ici.


homeassistant:
  name: Crochon
  latitude: !secret latitude
  longitude: !secret longitude
  unit_system: metric
  packages: !include_dir_named packages
  external_url: !secret external-url
  internal_url: !secret internal-url

Cahier des charges

Mon cahier des charges est le suivant:

  • Traitement des 4 modes de fonctionnement suivant:
    • Été: Temps de calcul fonction de la température de l’eau
    • Hiver: temps de filtration basé sur une heure de départ et une durée
    • Ma F: Force la pompe en marche
    • At F: Force la pompe à l’arrêt
  • En mode Été:
    • choix du modèle de calcul du temps de filtration:
      • Mode abaque Abacus
      • Mode classique: Température divisée par 2
    • Répartition du temps de filtration autour de l’heure Pivot: 50% avant et 50% après.
    • Possibilité de choisir son heure pivot entre 11:00 et 14:00 (butées modifiables dans l’application)
    • Possibilité de minorer ou majorer par un coefficient le temps de filtration (entre 60 et 140%: c’est un choix personnel basé sur mon retour d’expérience)
    • Limiter l’heure de fin à 23:59:59.
    • Temporisation de prise en compte de la température après demarrage de la pompe
  • Forçage à l’arrêt de la pompe quelque soit le mode de fonctionnement
  • Affichage de la plage de filtration dans HA
  • Enfin, avoir la main mise totale sur le programme, maîtriser les modifications et l’améliorer à ma convenance.

L’heure pivot représente selon moi le zénith du soleil, elle sert de de référence horaire dans ma programmation.

Abaque du mode Abacus

Le temps filtration est calculé suivant la courbe bleue avec un coefficient de 100%, la rouge avec un coefficient de 60% et la verte avec un coefficient de 140%. Cette formule, utilisée par Pool Pump Manager et le pluging Jeedom a été récupérée dans https://github.com/scadinot/pool.

La courbe bleue représente la valeur 100%, la courbe verte 140% et la courbe rouge 60%.

Déclaration des entités

Les entités HA utilisées dans ce fichier doivent avoir été au préalable déclarées dans HA. Dans mon cas, elle sont regroupées dans un fichier « piscine.yaml » dont le code est disponible au téléchargement ici.

####################################################
#                                                  #
#                   PISCINE                        #
#                                                  #
####################################################

utility_meter:
# usage jour  
  energy_pisc_usage_daily:
    source: sensor.pzem_pisc_energy
    cycle: daily
    tariffs:
      - hp
      - hc
# usage semaine
  energy_pisc_usage_weekly:
    source: sensor.pzem_pisc_energy
    cycle: weekly
    tariffs:
      - hp
      - hc
# usage mois
  energy_pisc_usage_monthly:
    source: sensor.pzem_pisc_energy
    cycle: monthly
    tariffs:
      - hp
      - hc
#usage an
  energy_pisc_usage_yearly:
    source: sensor.pzem_pisc_energy
    cycle: yearly
    tariffs:
      - hp
      - hc
input_number:
  # utilisé pour simuler la température de l'eau pendant les tests
  temp_piscine:
    name: Temp Eau Simul
    min: -2
    max: 35
    unit_of_measurement: °C
    icon: mdi:thermometer

# temperature de l'eau avant arret ppe
  mem_temp_piscine:
    name: Temp Eau avant arret
    min: -5
    max: 50
    unit_of_measurement: °C
    step: 0.1
    icon: mdi:thermometer
    mode: box

# temperature de l'eau avant arret ppe
  test_mem_temp_piscine:
    name: Temp Eau avant arret Test
    min: -5
    max: 50
    unit_of_measurement: °C
    step: 0.1
    icon: mdi:thermometer
    mode: box

# tempo avant prise en compte de la température de l'eau suite à demarrage marche pompe
  tempo_circulation_eau:
    name: Tempo Circulation Eau
    min: 0
    max: 3600
    unit_of_measurement: s
    step: 0.1
    icon: mdi:timer
    mode: box

# temps utilisation cartouche chlore
  temps_cartouche_chlore:
    name: Temps cartouche Chlore
    min: 0
    max: 3600
    unit_of_measurement: h
    step: 0.1
    icon: mdi:clock
    mode: box

# Seuil 1 inferieur temperature Hors gel
  hors_gel_inf_seuil1:
    name: Temp Inf Hors-Gel Seuil 1
    min: -5
    max: 0
    unit_of_measurement: °C
    icon: mdi:thermometer
# Seuil 2 inferieur temperature Hors gel
  hors_gel_inf_seuil2:
    name: Temp Inf Hors-Gel Seuil 2
    min: -10
    max: 0
    unit_of_measurement: °C
    icon: mdi:thermometer

# Durée de filtration max en hiver
  duree_filtration_max_mode_hiver:
    name: Durée filtration en Hiver
    min: 0
    max: 15
    unit_of_measurement: h
    step: 0.1
    icon: mdi:clock
    mode: box

# Durée de filtration max en hiver
  filtration_coeff_abaque:
    name: Coeff filtration Piscine Abaque
    min: 60
    max: 140
    unit_of_measurement: "%"
    step: 1.0
    icon: mdi:percent
    mode: box

input_datetime:
  heure_pivot_pisc:
    name: Heure Pivot
    has_date: false
    has_time: true

  heure_ouv_volet_pisc:
    name: Heure Ouv Volet Auto
    has_date: false
    has_time: true

  heure_ferm_volet_pisc:
    name: Heure Ferm Volet Auto
    has_date: false
    has_time: true

  heure_ma_pump_pisc_hiv:
    name: Heure Ma Pompe Pisc Hiv
    has_date: false
    has_time: true

input_boolean:
  # Force la Ppe de filtration à l’arrêt
  piscine_arret_force:
    name: Piscine Arret Forcé
    icon: mdi:head-snowflake

  # EV appoint Piscine en mode automatique
  ev_eau_piscine:
    name: Ev Piscine
    icon: mdi:water
  
  # Volet Piscine en mode automatique
  volet_piscine_auto:
    name: Volet Piscine (Auto=1)
    icon: mdi:garage

  #cde eclairage piscine
  eclairage_piscine:
    name: Eclairage piscine
    icon: mdi:car-light-high

  # Calcul du hors gel- Mémoire de mise en hors gel
  hors_gel_valid:
    name: Valid Hors Gel Piscine (si=1)
    icon: mdi:snowflake-alert

  # Calcul du temps de filtration selon Abaque Abacus sinon mode classique
  calcul_mode_abaque:
    name: Cacul mode Abaque (si=1)
    icon: mdi:chart-bar

# selection du mode de fonctionnement de la filtration
input_select:

  mode_fonctionnement_piscine:
    name: Mode Fonct Piscine
    options:
      - "Ete"
      - "Hiver"
      - "Ma F"
      - "At F"
    icon: mdi:pool
# sert aux tests AppDaemon
  mode_fonctionnement_piscine_test:
    name: Mode Fonct Piscine
    options:
      - "Ete"
      - "Hiver"
      - "Ma F"
      - "At F"
    icon: mdi:pool
############################  Input text    
input_text:
  # Affiche la periode de Filtration
  piscine_periode_filtration:   
    name: Periode Filtration
  test_piscine_periode_filtration:   
    name: Test Periode Filtration
  
############################  Sensor
sensor:
  # Affichage du temps de fonctionnement de la pompe ce jour
  - platform: history_stats
    name: Ma Ppe Piscine Jour
    entity_id: binary_sensor.ppe_piscine_en_marche
    state: "on"
    type: time
    start: "{{ now().replace(hour=0).replace(minute=0).replace(second=0) }}"
    end: "{{ now() }}"

  # Affichage du temps de fonctionnement de l'électrovanne appoint d'eau ce jour
  - platform: history_stats
    name: Ev Eau tps ouverture jour
    entity_id: switch.cde_ev_eau
    state: "on"
    type: time
    start: "{{ now().replace(hour=0).replace(minute=0).replace(second=0) }}"
    end: "{{ now() }}"
    
  # Affichage du temps de fonctionnement de l'électrovanne appoint d'eau sur 7 jours
  - platform: history_stats
    name: Ev eau sur 7j
    entity_id: switch.cde_ev_eau
    state: 'on'
    type: time
    end: "{{ now().replace(hour=0, minute=0, second=0) }}"
    duration:
      days: 7
    
template:
  - sensor:
    - name: "Heure pivot Soleil"
      unique_id: "heure_pivot_soleil"
      state: >
        {{ as_timestamp(state_attr("sun.sun", "next_noon")) | timestamp_custom('%H %M')}}
      icon: mdi:weather-sunset

    - name: "Energie Piscine Jour"
      unique_id: "energy_pisc_daily" 
      state: >-
        {% set p = states('sensor.energy_pisc_usage_daily_hp') | float(default=0) | round(2) %}
        {% set o = states('sensor.energy_pisc_usage_daily_hc') | float(default=0) | round(2) %}
        {{ (o + p) | round(2) }}
      unit_of_measurement: "kWh"
      device_class: "energy"
      state_class: "total"  

    - name: "energy_pisc_weekly"
      state: >-
        {% set p = states('sensor.energy_pisc_usage_weekly_hp') | float(default=0) | round(2) %}
        {% set o = states('sensor.energy_pisc_usage_weekly_hc') | float(default=0) | round(2) %}
        {{ (o + p) | round(2) }}
      unit_of_measurement: "kWh"
      device_class: "energy"
      state_class: "total"  

    - name: "energy_pisc_monthly"
      state: >-
        {% set p = states('sensor.energy_pisc_usage_monthly_hp') | float(default=0) | round(2) %}
        {% set o = states('sensor.energy_pisc_usage_monthly_hc') | float(default=0) | round(2) %}
        {{ (o + p) | round(2) }}
      unit_of_measurement: "kWh"
      device_class: "energy"
      state_class: "total"  

    - name: "energy_pisc_yearly"
      state: >-
        {% set p = states('sensor.energy_pisc_usage_yearly_hp') | float(default=0) | round(2) %}
        {% set o = states('sensor.energy_pisc_usage_yearly_hc') | float(default=0) | round(2) %}
        {{ (o + p) | round(2) }}
      unit_of_measurement: "kWh"
      device_class: "energy"
      state_class: "total"  

  # Recopie pression filtre lu dans esphome dans un template
    - name: "pression_piscine_p"
      state: '{{ states("sensor.pression_filtre") |float(default=0) | round(2) }}'
      unit_of_measurement: "Bars"

  - binary_sensor:
    # Si la puissance electrique est superieure à 500w, on considere que la pompe est en fonctionnement
    # ou tester le switch de la ppe de filtration si pas de mesure de puissance
    # {{ is_state('switch.ppe_filtration', 'on') }}
    - name: "ppe_piscine_en_marche"
      state: >-
        {{states.sensor.pzem_pisc_puissance.state | float(default=0) > 500}}

  # Calcul en fonction de la position du soleil
  # Sun Azimtuh est calculé dans Meteo
    - name: "soleil_volet_piscine"
      state: >-
        {% set a=states('sensor.sun_azimuth_2')|float(default=0) %}
        {{ (a>97) and (a<290) }}

# Commande du volet roulant via un Cover

cover:
  - platform: template
    covers:
      volet_piscine:
        device_class: garage
        friendly_name: "Piscine"
        value_template: >-
          {% if is_state('binary_sensor.volet_piscine_ferme', 'on') %}
            closed
          else:
            open
          {% endif %}        
        open_cover:
          - service: script.volet_piscine_ouverture
        close_cover:
          - service: script.volet_piscine_fermeture   
        icon_template: >-
          {% if is_state('binary_sensor.volet_piscine_ferme', 'on') %}
            mdi:garage
          {% else %} 
            mdi:garage-open
          {% endif %}

Addon Appdaemon

Cet Addon, pour ceux qui ne connaissent pas, permet d’écrire des programmes en Python très élaborés, je décrit son installation dans cet article.

Vous trouverez ci après les fichiers « .yaml » et « .py » à installer dans « votre AppDaemon. »

Code de « filtration_piscine.yaml »

La dernier version du fichier « filtration_piscine.yaml » est téléchargeable ici.

# Version du 24/02/2022
Piscine:
  class: FiltrationPiscine
  module: filtration_piscine
# Capteurs
  temperature_eau: sensor.temp_piscine
# Selection du mode fonctionnement de la filtration
  mode_de_fonctionnement: input_select.mode_fonctionnement_piscine
# Heure pivot autour de laquelle le temps de filtration est réparti (50/50)
  h_pivot: input_datetime.heure_pivot_pisc
# Heure de début de filtration en hiver
  h_debut_hiver: input_datetime.heure_ma_pump_pisc_hiv
# Durée de la filtration en hiver
  duree_hiver: input_number.duree_filtration_max_mode_hiver
# Coefficient du temps de filtration entre 60 et 140%
  coef: input_number.filtration_coeff_abaque
# Validation de mode de calcul avec Abaque sinon c'est la méthode classique (T°/2)
  mode_calcul: input_boolean.calcul_mode_abaque
# Temps circulation de l'eau avant prise en compte mesure température
# dans le cas où la mesure de température de l'eau se trouve sur le circuit de pompage
  tempo_eau: input_number.tempo_circulation_eau
# Memoire de la temperature de l'eau avant arret
  mem_temp: input_number.mem_temp_piscine
# Arret forcé filtration- Bloque la filtration si = 1
  #arret_force: input_boolean.piscine_arret_force # à utiliser par défaut
  arret_force: input_boolean.mem_delestage


# Actionneurs
  # Switch de commande de la pompe
  cde_pompe: switch.cde_pompe_filtration
  # Affichage dans HA des horaires filtration
  periode_filtration: input_text.piscine_periode_filtration

Code de « filtration_piscine.py »

La dernière version du fichier « filtration_piscine.py » est téléchargeable ici.

# Version du 24/02/2022
import hassapi as hass
import datetime
from datetime import timedelta
import time

# Variables globales
# Saisir ici les memes modes que dans HA 
TAB_MODE = ["Ete", "Hiver", "At F", "Ma F"]
# Niveau de JOURNALISATION (log): 0=rien ou 1 =info ou 2=debug 
JOURNAL=2 
# RAZ du flag fin_tempo
FIN_TEMPO = 0

# Fonction de calcul du temps de filtration selon Abaque Abacus 
def duree_abaque(Temperature_eau):
    #Advanced calculation method using an abacus.
    #D = a*T^3 + b*T^2 + c*T +d
    #T est forçèe a 10°C minimum
    #Formule découverte dans: https://github.com/scadinot/pool
    #Filtration en heures
    temperature_min: float = max(float(Temperature_eau), 10)
    duree = (
            0.00335 * temperature_min ** 3
            - 0.14953 * temperature_min ** 2
            + 2.43489 * temperature_min
            - 10.72859
    )
    return duree

# Fonction de calcul du temps de filtration "Classique" 
def duree_classique(Temperature_eau):
    #Methode classique temperature / 2
    temperature_min: float = max(float(Temperature_eau), 10)
    duree = temperature_min / 2
    duree_m = min(float(duree), 23)
    return duree

# Fonction de Convertion Int en heure "HH:MM:SS"
def en_heure(t):
    h = int(t)
    # On retire les heures pour ne garder que les minutes.
    t = (t - h) * 60 # 0.24 * 60 = temps_restant en minutes.
    m = int(t)
    # On retire les minutes pour ne garder que les secondes.
    t = (t - m) * 60
    s = int(t)
    return "{:02d}:{:02d}:{:02d}".format(h, m, s)

########## Programme principal ###################
class FiltrationPiscine(hass.Hass): 
    def initialize(self):
        global JOURNAL, DUREE_TEMPO, FIN_TEMPO
        message_notification= "Initialisation AppDaemon Filtration Piscine."
        self.notification(message_notification,0)
        self.log(message_notification, log="error_log")
        self.notification("Journal Notif niveau:"+str(JOURNAL),0)
        self.listen_state(self.change_temp,self.args["temperature_eau"])
        self.listen_state(self.change_mode,self.args["mode_de_fonctionnement"])
        self.listen_state(self.change_coef,self.args["coef"])
        self.listen_state(self.ecretage_h_pivot,self.args["h_pivot"])
        self.listen_state(self.change_mode_calcul,self.args["mode_calcul"])
        self.listen_state(self.change_etat_pompe,self.args["cde_pompe"])
        self.listen_state(self.change_arret_force,self.args["arret_force"])
        self.run_every(self.touteslesxminutes, "now", 5 * 60)
        
        # initialisation de la temporisation avant recopie temperature
        DUREE_TEMPO=float(self.get_state(self.args["tempo_eau"]))
        self.notification("Duree tempo:"+str(DUREE_TEMPO),2)
        nom_entité=self.args["cde_pompe"]
        self.tempo=self.run_in(self.fin_temporisation_mesure_temp, DUREE_TEMPO,entité=nom_entité)
        # Arret de la pompe sur initalisation
        self.turn_off(self.args["cde_pompe"])

# Appelé sur changement de temperature
    def change_temp(self, entity, attribute, old, new, kwargs):
        global JOURNAL
        if new!= "unavailable":
            self.notification('Appel traitement changement Temp.',2)
            self.traitement(kwargs)
# Appelé sur changement de mode de fonctionnement
    def change_mode(self, entity, attribute, old, new, kwargs):
        global JOURNAL, FIN_TEMPO
        FIN_TEMPO = 0
        self.notification('Appel traitement changement Mode.',2)
        self.traitement(kwargs)
# Appelé sur changement de coefficient
    def change_coef(self, entity, attribute, old, new, kwargs):
        global JOURNAL
        self.notification('Appel traitement changement Coef.',2)
        self.traitement(kwargs)
# Appelé sur changement de mode de calcul
    def change_mode_calcul(self, entity, attribute, old, new, kwargs):
        global JOURNAL
        self.notification('Appel traitement changement mode de calcul.',2)
        self.traitement(kwargs)
# Appelé sur changement arret forcé
    def change_arret_force(self, entity, attribute, old, new, kwargs):
        global JOURNAL
        self.notification('Appel traitement sur arret force.',2)
        self.traitement(kwargs)
# Appelé sur changement d'état de la pompe de filtrage
    def change_etat_pompe(self, entity, attribute, old, new, kwargs):
        global JOURNAL, FIN_TEMPO ,DUREE_TEMPO
        nom_entité=self.args["cde_pompe"]
        FIN_TEMPO = 0
        if new=="on":
            self.tempo=self.run_in(self.fin_temporisation_mesure_temp, DUREE_TEMPO,entité=nom_entité)
        else:
            cle_tempo = self.tempo
            if cle_tempo != None:
                cle_tempo = self.tempo
                self.tempo = self.cancel_timer(cle_tempo)

        self.notification('Appel traitement changement etat pompe.',2)
        self.traitement(kwargs)
# Appelé sur fin temporisation suit à demarrage de la pompe
    def fin_temporisation_mesure_temp(self,kwargs):
        global JOURNAL, FIN_TEMPO 
        FIN_TEMPO = 1
        self.notification('Fin temporisation circulation eau.',2)
        self.traitement(kwargs)

# Ecretage Heure pivot entre h_pivot_min et h_pivot_max
    def ecretage_h_pivot(self, entity, attribute, old, new, kwargs):
        h_pivot= new
        h_pivot_max="14:00:00"
        h_pivot_min="11:00:00"
        if h_pivot>h_pivot_max:
            self.set_state(self.args["h_pivot"], state = h_pivot_max)
        if h_pivot<h_pivot_min:
            self.set_state(self.args["h_pivot"], state = h_pivot_min)
        self.traitement(kwargs)

# Appelé toutes les x minutes
    def touteslesxminutes(self, kwargs):
        global JOURNAL
        self.notification('Appel traitement toutes les x mn.',2)
        self.traitement(kwargs)

    def traitement(self, kwargs):
        global JOURNAL, FIN_TEMPO
        h_locale=time.strftime('%H:%M:%S', time.localtime())
        Mesure_temperature_eau = float(self.get_state(self.args["temperature_eau"]))
        Mem_temperature_eau = float(self.get_state(self.args["mem_temp"]))
        mode_de_fonctionnement = self.get_state(self.args["mode_de_fonctionnement"])
        arret_force = self.get_state(self.args["arret_force"])
        pompe = self.args["cde_pompe"]
        pivot= self.get_state(self.args["h_pivot"])
        coef=float(self.get_state(self.args["coef"]))/100
        mode_calcul= self.get_state(self.args["mode_calcul"])
        periode_filtration=self.args["periode_filtration"]

        # Flag FIN_TEMPO
        self.notification("Flag fin tempo= "+str(FIN_TEMPO),2)

        #  Mode Ete
        if mode_de_fonctionnement == TAB_MODE[0]:
            # Temporisation avant prise en compte de la mesure de la temperature
            # sinon on travaille avec la memoire de la temperature avant arret de la pompe
            # mémorise la température eau de la veille.
            if FIN_TEMPO == 1:
                Temperature_eau=Mesure_temperature_eau
                self.set_value(self.args["mem_temp"], Mesure_temperature_eau)
            else:
                Temperature_eau=Mem_temperature_eau

            if mode_calcul == "on": # Calcul selon Abaque
                temps_filtration = (duree_abaque(Temperature_eau)) * coef
                nb_h_avant = en_heure(float(temps_filtration / 2))
                nb_h_apres = en_heure(float(temps_filtration / 2))
                # nb_h_avant = en_heure(float(temps_filtration / 3)) Répartition 1/3-2/3
                # nb_h_apres = en_heure(float(temps_filtration / 3*2))
                nb_h_total = en_heure(float(temps_filtration))
                self.notification("Duree Filtration Mode Abaque: "+ str(temps_filtration)[:6]+" h",2)
            
            else: # Calcul selon méthode classique
                temps_filtration = (duree_classique(Temperature_eau))*coef
                nb_h_avant = en_heure(float(temps_filtration / 2))
                nb_h_apres = en_heure(float(temps_filtration / 2))
                nb_h_total = en_heure(float(temps_filtration))
                self.notification("Duree Filtration Mode Classique: "+ str(temps_filtration)[:6]+" h",2)

            # Calcul des heures de début et fin filtration en fontion
            # du temps de filtration avant et apres l'heure pivot
            # Adapte l'heure de début de filtration à l'heure actuelle
            # Limitation de la fin de filtration à 23:59:59
            h_maintenant = timedelta(hours=int(h_locale[:2]), minutes=int(h_locale[3:5]), seconds=int(h_locale[6:8]))
            h_pivot = timedelta(hours=int(pivot[:2]), minutes=int(pivot[3:5]))
            h_avant_t = timedelta(hours=int(nb_h_avant[:2]), minutes=int(nb_h_avant[3:5]), seconds=int(nb_h_avant[6:8]))
            h_apres_t = timedelta(hours=int(nb_h_apres[:2]), minutes=int(nb_h_apres[3:5]), seconds=int(nb_h_apres[6:8]))
            h_total_t = timedelta(hours=int(nb_h_total[:2]), minutes=int(nb_h_total[3:5]), seconds=int(nb_h_total[6:8]))
            h_max_t = timedelta(hours=23, minutes=59, seconds=59)

            h_debut = h_pivot - h_avant_t
            h_fin= h_pivot + h_apres_t

#            if h_debut<h_maintenant:
#                h_debut=h_maintenant
#                h_fin=h_maintenant+h_total_t
#                h_fin= min(h_fin,h_max_t)
            h_fin= min(h_fin,h_max_t)
            message_notification= "Nb h_avant_t: "+str(h_avant_t)+"/Nb h_apres_t: "+str(h_apres_t)+"/Nb h_total_t: "+str(h_total_t)
            self.notification(message_notification,1)
            message_notification="h_debut: "+str(h_debut)+"/h_pivot: "+str(h_pivot)+"/h_fin: "+str(h_fin) 
            self.notification(message_notification,1)
            # Affichage plage horaire
            affichage_texte =str(h_debut)[:5]+"/"+str(h_pivot)[:5]+"/"+str(h_fin)[:5]
            self.set_textvalue(periode_filtration,affichage_texte)

            # Marche pompe si dans plage horaire sinon Arret
            if self.now_is_between(str(h_debut),str(h_fin)):
                ma_ppe=1
            else:
                ma_ppe=0

# Notifications de debug
            message_notification="Mode de fonctionnement: "+mode_de_fonctionnement
            self.notification(message_notification,2)
            message_notification=" Temp Eau= "+str(Temperature_eau)
            self.notification(message_notification,2)
            message_notification="h_pivot= "+str(pivot)
            self.notification(message_notification,2)
            message_notification="coef= "+str(coef)
            self.notification(message_notification,2)

        #  Mode hiver Heure de Début + Une durée en h 
        elif mode_de_fonctionnement == TAB_MODE[1]:
            h_debut_h= self.get_state(self.args["h_debut_hiver"])
            duree= self.get_state(self.args["duree_hiver"])
            duree_h=en_heure(float(duree))
            h_debut_t = timedelta(hours=int(h_debut_h[:2]), minutes=int(h_debut_h[3:5]), seconds=int(h_debut_h[6:8]))
            duree_t = timedelta(hours=int(duree_h[:2]), minutes=int(duree_h[3:5]))
            h_fin_f = h_debut_t + duree_t
            # Affichage plage horaire
            affichage_texte =str(h_debut_h)[:5]+"/"+str(h_fin_f)[:5]
            self.set_textvalue(periode_filtration,affichage_texte)

            message_notification="h_debut_h"+str(h_debut_h)+"-Duree H:"+str(duree_h)+"-H fin:"+str(h_fin_f)
            self.notification(message_notification,2)
            # Marche pompe si dans plage horaire sinon Arret
            if self.now_is_between(str(h_debut_h),str(h_fin_f)):
                ma_ppe=1
            else:
                ma_ppe=0

        # Mode Arret Forcé
        elif mode_de_fonctionnement == TAB_MODE[2]:
            ma_ppe=0
            text_affichage = "At manuel"
            self.set_textvalue(periode_filtration,text_affichage)

        # Mode Marche Forcée
        elif mode_de_fonctionnement == TAB_MODE[3]:
            ma_ppe=1
            text_affichage = "Ma manuel"
            self.set_textvalue(periode_filtration,text_affichage)
            
        # Mode Inconnu: revoir le contenu de Input_select.mode_de_fonctionnement
        else:
            message_notification="Mode de fonctionnement Piscine Inconnu: "+mode_de_fonctionnement
            self.notification(message_notification,0)

        # Calcul sortie commande pompe filtration
        # Arret pompe sur arret forcé
        if arret_force=="on":
            self.turn_off(pompe) 
            self.notification("Att sur Delestage",1)
            text_affichage = "At delestage"
            self.set_textvalue(periode_filtration,text_affichage)
        else:
            if ma_ppe==1:
                self.turn_on(pompe)
                self.notification("Ma Pompe",1)
            else:
                self.turn_off(pompe)
                self.notification("Arret Pompe",1)

    # Fonction Notification
    # message =  Texte à afficher
    # niveau = niveau de journalisation 0,1,2
    def notification(self,message,niveau):
        global JOURNAL
        heure = str(self.time())[:8]
        if niveau <= JOURNAL:
            message_notification= format(heure)+": "+ message
            self.log(message_notification, log="piscine_log")
            #self.call_service('notify/telegram', message=message_notification)
            #self.call_service('persistent_notification/create', message=message_notification)

Interfaces

Interface simplifiée

Le minimum syndical vous permettant d’effectuer des essais.

type: entities
entities:
  - entity: input_select.mode_fonctionnement_piscine
  - entity: sensor.temp_piscine
  - entity: input_number.mem_temp_piscine
  - entity: input_datetime.heure_pivot_pisc
  - entity: input_boolean.calcul_mode_abaque
  - entity: input_number.filtration_coeff_abaque
  - entity: input_number.tempo_circulation_eau
  - entity: switch.cde_pompe_filtration
  - entity: input_text.piscine_periode_filtration
  - entity: input_datetime.heure_ma_pump_pisc_hiv
  - entity: input_number.duree_filtration_max_mode_hiver
  - entity: binary_sensor.ppe_piscine_en_marche
  - entity: sensor.pzem_pisc_puissance
  - entity: sensor.ma_ppe_piscine_jour
title: Piscine
show_header_toggle: false
state_color: true

Dwain Lovelace

Personnellement, j’utilisé l’intégration HACS « Dwain lovelace », voir mon article sur cette excellente intégration HACS.

La dernière version est disponible au téléchargement ici. Vous pouvez adapter les cartes à votre environnement.

Et Pool_pump-Manager?

Et bien si vous aviez suivi mon article https://domo.rem81.com/home-assistant-gestion-piscine-filtration-poolpump/ et migré vers ce mode de gestion du temps de filtration avc AppDaemon, vous pouvez supprimer:

  • le HACS Pool_Pump_Manager
  • Les automatimes « « calcul fonctionnement pompe » et « mémorisation température avant arret »
  • Prendre la dernière version de l’automatisme « hors_gel »

Conclusion

Cet article va surement évolué dans le temps, il reste quelques améliorations ou évolutions à apporter.

N’hésitez pas à me laisser en commentaire, des critiques négatives ou positives constructrices sur le sujet.

Liste des publications en lien avec cet article:

  1. Filtration avec « AppDaemon » ou avec « Pool Pump Manager« 
  2. Mesure de puissance électrique
  3. Mise à niveau automatique
  4. Mesure du pH
  5. Régulation du Ph
  6. Mise Hors Gel
  7. Mesure de pression

35 Comments on “HA-Gestion Piscine-1_Filtration avec AppDaemon”

  1. Bravo pour tous ces outils sur HA pour gérer la piscine : c’est EXACTEMENT ce que je cherchais …

    Je pense que je vais y aller petit-à-petit: d’abord le contrôle de la pompe, puis l’hors-gel, et ensuite, je prend un grand souffle pour attaquer le Ph 🙂

    J’ai deux petites questoins, si ça ne vous dérange pas:
    – Qu’est-ce que vous appelez « l’heure pivot » ?
    – Quid de la stabilité de HA avec ce cette solution basée AppDeamon ? Pas d’impact lors de fréquentes mises-à-jour de HA ?

    Merci de votre aide et chapeau encore une fois!

    1. Merci pour ton retour, c’est sympa de ta part. C’est autour de l’heure pivot qu’est répartie la durée de filtration, elle correspond en général au zénith du soleil. par ex pour hp=13:00 si 120 mn de durée de filtration, début à 12:00, fin à 14:00. Dans mon appli la répartition est 50/50, dans l’appli pool manager que j’utilisais avant c’était 1/3 2/3. Concernant la stabilité de APPDaemon et mes MàJ, je n’ai pas de problème, c’est stable. A te lire quand tu aura avancé sur le sujet. Bon courage

  2. Tout d’abord un grand merci et bravo rem81 pour tous ces tutos forts utiles!
    J’avoue que je patauge un peu, mes connaissances sur HA et yaml étant un peu limitées, j’aurais bien besoin d’un coup de main..
    J’ai d’abord commencé par appliquer ton tuto avec Pool Pump Manager et je m’en suis sorti. Puis j’ai vu ce que tu as fait avec appdaemon et la possibilité de pouvoir régler le coeff de filtration, de la balle! C’est exactement ce que je cherchais.
    Par contre je suis un peu perdu là.. j’ai installé Appdaemon, j’ai configuré appdaemon.yaml, j’ai copié et adapté les filtration_piscine.py et .yaml dans le dossier apps. J’ai aussi configuré le piscine.yaml déclaré dans HA.
    Du coup il faut que désinstalle pool pump manager?
    Et les 3 automatisations piscine-hors-gel + calcul fonctionnement pompe + mémorisation température avant arrêt, il faut les garder ou c’est plus utile?
    Autre chose dans error.log il bloque sur « INFO Piscine: Initialisation AppDaemon Filtration Piscine » c’est normal?
    Merci encore!

    1. Bonjour merci pour ton retour. Alors oui tu peux désinstaller « pool pump manager » et supprimer les automatismes « calcul fonctionnement pompe » et « mémorisation température avant arret », ces deux fonctions étant assurées maintenant par « filtration_piscine.py ». L’atuomatisme « hors gel » est à conserver pour l’instant) mais il faut prendre la version de l’article « https://domo.rem81.com/ha-gestion-piscine-6_mode-hors-gel/ » car il agit sur le « input_select.mode_fonctionnement_piscine » ‘si tu as pris les mêmes entités)
      Pour le log « error.log » oui c’est normal par contre vérifie bien que le niveau de journalisation est egale à 2 (ligne 11 « filtration_piscine.py »: JOURNAL=2), tu dois avoir des informations dans le « piscine_log » comme expliquer au chapitre « AppDaemon.yaml » de mon article « https://domo.rem81.com/ha-addon-appdaemon-programme-python/ ».
      Voila, normalement cela doit fonctionner. Tiens moi informé
      PS: Je vais compléter l’article avec tes remarques sur les automatismes.

      1. Ah c’est vraiment sympa de répondre aussi vite!
        J’ai suivi ce que tu m’a écris et tout est ok, et j’ai bien le niveau de journalisation à 2. Tout à l’air de fonctionner, top!
        Petite question : finalement l’heure pivot tu la choisie manuellement ou tu la règle en fonction du zénith du soleil? je me dit que si je la règle automatiquement sur le zénith et qu’en plein été, l’heure pivot se fixe à 12h, pour 10 heures de filtration, ça donnerait 7h/12h/17h. C’est pas mieux de régler manuellement l’heure pivot genre sur 14h non?

        1. Bonjour, bonne nouvelle puisque ça fonctionne. Concernant l’heure pivot tu peux l’adapter à ta convenance par rapport au zenith du soleil, l’année dernière c’etait vers les 13:30 de mémoire d’ailleurs c’est un attribut de l’intégration « sun », tu peux te créer un template du genre:

          - name: "Heure pivot Soleil"
          unique_id: "heure_pivot_soleil"
          state: >
          {{ as_timestamp(states.sun.sun.attributes.next_noon) | timestamp_custom(' %H %M')}}
          icon: mdi:weather-sunset

          Je viens de l’ajouter dans le « piscine.yaml »

          Sinon pour la répartition de la filtration autour de l’heure pivot, tu peux modifier facilement dans « filtration_piscine.py » en remplacant /2 par /3 et 2/3
          if mode_calcul == "on": # Calcul selon Abaque
          temps_filtration = (duree_abaque(Temperature_eau)) * coef
          nb_h_avant = en_heure(float(temps_filtration / 2)) <-- /3 nb_h_apres = en_heure(float(temps_filtration / 2)) <-- /3*2 nb_h_total = en_heure(float(temps_filtration)) self.notification("Duree Filtration Mode Abaque: "+ str(temps_filtration)[:6]+" h",2)

          Encore merci pour ton retour d’expérience, c’est toujours intéressant d’avoir un avis extérieur, d’ailleurs si tu vois des axes d’amélioration, n’hésites pas à m’en faire part, je verrai ce que je peux faire..

          1. Merci pour ces infos. Oui j’avais testé avec l’intégration sun c’est pas mal, mais finalement je crois que je vais garder l’heure pivot en saisie manuelle c’est aussi bien.
            Il y a quelques coquilles dans les fichiers yaml.. je t’en fais part si tu veux les corriger (et si je ne me trompe pas;-)):
            – dans filtration_piscine.yaml : le input_boolean.mem_delestage n’est pas déclaré sous ce nom dans le piscine.yaml mais sous le nom input_boolean.piscine_arret_force
            – dans piscine.yaml : le commentaire dans cet input_boolean.piscine_arret_force n’est pas bon (« # EV appoint Piscine en mode automatique »).

            Petit proposition : dans piscine.yaml : binary_sensor.ppe_piscine_en_marche : pour ceux qui comme moi ne peuvent pas tester la consommation électrique de leur pompe, leur proposer de mettre : state: « {{ states.switch.pool_pump_switch.state == ‘on’ }} »

            Merci et encore bravo pour ce travail extraordinaire et pour le partage!

          2. Merci pour ces info.
            1)Dans mon cas je bloque la filtration si ma production photovoltaïque me permet de faire fonctionner un autre équipement, d’où l’entité « input_boolean.mem_delestage », mais la remarque est judicieuse j’ai commenté le « filtration_piscine.yaml »
            2)J’ai mis à jour le commentaire de input_boolean.piscine_arret_force
            3)Proposition prise en compte
            Encore merci

  3. Salut ,

    Bravo pour ton Taff , chapeau !!

    Venant du monde de Jeedom , je suis en train de monter en charge mon HomeAssistant … gentiment ..:)
    J ‘utilise le super Plugin Jeedom Piscine qui est vraiment Top .

    Crois qu’il est possible de le proposer en automation ou blueprint à importer ?

    Merci par avance ,

    Minos

    1. Bonjour et merci pour ton retour
      Vu les fonctions traitées, un automatisme ou blueprint serait long et compliqué ou alors faire beaucoup plus simple avec des plages horaire de début et arret pompe par exemple.

  4. Salut rem81 !
    Venant tout juste de terminer la construction de ma piscine. je viens de me pencher sur l’automatisation de la filtration et suis tombé sur ton blog !
    En effet ton amélioration de pool pump manager est vraiment la bienvenue, donc merci pour ton travail et surtout ton partage.
    Je viens d’implémenter ton système et je confirme que tout fonctionne parfaitement bien pour ma part.
    J’aimerai savoir ce que tu as comme sonde de température ?
    J’ai pour ma part suivi ce tuto : https://faire-ca-soi-meme.fr/domotique/2020/05/11/detournement-xiaomi-aqara-temperature-exterieure-piscine/
    Et ça marche plutot pas mal, j’ai mis la sonde dans le skimmer et le boitier est positionné à côté sous la terrasse en bois (donc caché…) mais l’idée d’avoir une sonde directement sur la plomberie dans le local via un porte sonde comme la sonde pour le micro doseur de PH me parait beaucoup plus propre.
    Merci encore pour le travail !

    1. J’oubliais un petit détail, heure_pivot_soleil est « undefined » chez moi..
      Pour corriger, il faut remplacer :
      heure_pivot_soleil:
      friendly_name: « Heure pivot Soleil »
      #icon: mdi:weather-sunset
      value_template: >
      {{ as_timestamp(value_templates.sun.sun.attributes.next_noon) | timestamp_custom(‘ %H %M’)}}

      par ça :
      heure_pivot_soleil:
      friendly_name: « Heure pivot Soleil »
      #icon: mdi:weather-sunset
      value_template: >
      {{ as_timestamp(state_attr(« sun.sun », « next_noon »)) | timestamp_custom(‘ %H %M’) | timestamp_custom(‘ %H %M’)}}

    2. Bonjour merci pour ton retour, ça fait plaisir. Concernant la Température j’utilise une sonde pt100 relié à un système wago 750 communiquant en modbus c’est de l’industriel mais, à moindre coût peux utiliser une sonde ds18b20 qui se connecte facilement à un esp😉

  5. Hello,

    je suis en train de mettre en place cette methode et suis encore novice sur HA…

    les deux fichiers filtration_piscine.py et filtration_piscine .yaml sont à mettre dans quels dossiers ?
    config/appdaemon/ ou config/appdaemon/apps …?

    J ai placé le piscine.yaml dans config/packages

    Par contre concernant les entités à changer , il y en a combien à changer ?:

    commande pompe
    commande éclairage
    consommation pompe

    désolé de poser des questions si basiques ..

    Merci par avance ,

    Minos

    1. complément infos :

      Pour les fichiers , je les ai mis sous config/appdaemon/apps , je pense que c ‘est bon ?

      par contre j ai la période de filtration qui reste à unknown ..

      1. Bonjour , et merci de ton retour ,

        Dans le fichier piscine.yaml : il y a ça à modifier aussi ?

        source: sensor.pzem_pisc_energy => est à changer par le sensor conso de mon entité

        sous filtration_piscine.yaml :

        il y en a que 2 je pense :

        # Capteurs
        temperature_eau: sensor.sondes_temperatures_circuit_eau_piscine

        # Actionneurs
        # Switch de commande de la pompe
        cde_pompe: switch.pompe_piscine

        Merci par avance ,

        Minos

        1. Pfff , bon ben c ‘est un échec , rien ne fonctionne ..lol

          Aucune valeur ne remonte dans « période de filtration »

          aucune action lorsque je passe en mode « Ma F »

          Minos

          1. Dans appDaemon :

            J ‘ai ça:

            app.Piscine initialize_error 10/04/2022, 19:31:23
            {« totalcallbacks »: « 0 », « instancecallbacks »: « 0 »
            }

          2. te décourage pas, il faut y aller progressivement, dans le piscine.yaml, garde que les entités nécessaire au fonctionnement de l’appdaemon piscine, celle du fichier  » filtration_piscine.yaml « ,il y en une dizaine, commence par le faire fonctionner après tu ajoutera petit à petit les autres entités si tu en a besoin,la mesure de puissance, etc..

    1. Si tu as suivi ma procédure d’installation de « appdaemon », tu devrai retrouver tes fichiers log dans « /config/log », tu y a accès aussi depuis l’interface utilisateur, via le port de « 5050 » de HA (par exemple http://192.168.0.37:5050/). le port « 5050 » est celui déclaré dans la configuration de l’Addon. Les deux entités importantes à déclarer hors ‘piscine.yaml » sont le sensor mesure de température et le switch de la pompe, les huit autres peuvent sont dans « piscine.yaml »

      1. Salut ,

        Dans les journaux AppDaemon :

        piscine_log n ‘est pas trouvé a priori:

        2022-04-11 19:10:42.036519 INFO HASS: Connected to Home Assistant 2022.4.1
        2022-04-11 19:10:42.113612 INFO AppDaemon: App ‘hello_world’ added
        2022-04-11 19:10:42.116399 INFO AppDaemon: App ‘Piscine’ added
        2022-04-11 19:10:42.117358 INFO AppDaemon: Found 2 total apps
        2022-04-11 19:10:42.117831 INFO AppDaemon: Starting Apps with 2 workers and 2 pins
        2022-04-11 19:10:42.119204 INFO AppDaemon: Running on port 5050
        2022-04-11 19:10:42.253434 INFO HASS: Evaluating startup conditions
        2022-04-11 19:10:42.270764 INFO HASS: Startup condition met: hass state=RUNNING
        2022-04-11 19:10:42.271224 INFO HASS: All startup conditions met
        2022-04-11 19:10:42.315380 INFO AppDaemon: Got initial state from namespace default
        2022-04-11 19:10:42.883986 INFO AppDaemon: New client Admin Client connected
        2022-04-11 19:10:44.136105 INFO AppDaemon: Scheduler running in realtime
        2022-04-11 19:10:44.149860 INFO AppDaemon: Adding /config/appdaemon/apps to module import path
        2022-04-11 19:10:44.156082 INFO AppDaemon: Loading App Module: /config/appdaemon/apps/filtration_piscine.py
        2022-04-11 19:10:44.170857 INFO AppDaemon: Loading App Module: /config/appdaemon/apps/hello.py
        2022-04-11 19:10:44.179618 INFO AppDaemon: Initializing app hello_world using class HelloWorld from module hello
        2022-04-11 19:10:44.187049 INFO AppDaemon: Initializing app Piscine using class FiltrationPiscine from module filtration_piscine
        2022-04-11 19:10:44.366770 INFO hello_world: Hello from AppDaemon
        2022-04-11 19:10:44.368556 INFO hello_world: You are now ready to run Apps!
        2022-04-11 19:10:44.375553 ERROR Piscine: User defined log piscine_log not found
        2022-04-11 19:10:44.379370 WARNING Piscine: ————————————————————
        2022-04-11 19:10:44.379742 WARNING Piscine: Unexpected error running initialize() for Piscine
        2022-04-11 19:10:44.380303 WARNING Piscine: ————————————————————
        2022-04-11 19:10:44.385637 WARNING Piscine: Traceback (most recent call last):
        File « /usr/lib/python3.9/site-packages/appdaemon/app_management.py », line 165, in initialize_app
        await utils.run_in_executor(self, init)
        File « /usr/lib/python3.9/site-packages/appdaemon/utils.py », line 337, in run_in_executor
        response = future.result()
        File « /usr/lib/python3.9/concurrent/futures/thread.py », line 52, in run
        result = self.fn(*self.args, **self.kwargs)
        File « /config/appdaemon/apps/filtration_piscine.py », line 55, in initialize
        self.notification(message_notification,0)
        File « /config/appdaemon/apps/filtration_piscine.py », line 287, in notification
        self.log(message_notification, log= »piscine_log »)
        File « /usr/lib/python3.9/site-packages/appdaemon/adapi.py », line 155, in log
        self._log(logger, msg, *args, **kwargs)
        File « /usr/lib/python3.9/site-packages/appdaemon/adapi.py », line 96, in _log
        logger.log(self._logging.log_levels[level], msg, *args, **kwargs)
        AttributeError: ‘NoneType’ object has no attribute ‘log’
        2022-04-11 19:10:44.386030 WARNING Piscine: ————————————————————
        2022-04-11 19:10:44.389488 INFO AppDaemon: App initialization complete

        1. Bon ben j ‘ai honte ….Piou …

          j ‘ai trouvé mon erreur de NAZE !!

          voici mon chemin : /config/appdaemon/log/piscine.log

          et non pas /config/log/piscine.log

          c ‘est nettement mieux …;

          j ‘avance ….

          A suivre

          1. Salut ,

            Bon c ‘est en place , et ça tourne !!

            A voir à l’usage avec la montée des températures .

            Tu crois que c’est possible d’avoir l’info du temps de filtration en visuel ?

            et un suivi chronologique de la temperature eau air et période de filtration ?

            un peu comme le plugin piscine de Jeedom .

            En tout cas merci à toi ..

            Minos

  6. Bon , je me suis fais une carte avec une chronologie et les températures

    je partage :

    type: vertical-stack
    cards:
    – show_state: true
    show_name: true
    camera_view: auto
    type: picture-entity
    image: >-
    https://www.piscines-ibiza.com/content/uploads/2020/09/review-641-0-600×450-c-center.jpeg
    entity: sensor.ble_conductivity_kevin
    name: Piscine
    – square: false
    columns: 3
    type: grid
    cards:
    – type: custom:mini-graph-card
    name: T° Eau
    entities:
    – entity: sensor.temp_piscine
    name: Température
    color: ‘#A62F03’
    hours_to_show: 96
    – type: custom:mini-graph-card
    name: T° Air
    entities:
    – entity: sensor.netatmo_netatmo_indoor_exterieure_temperature
    name: Humidité
    color: ‘#44B0E7’
    hours_to_show: 96
    – type: custom:mini-graph-card
    name: Conso Pompe
    entities:
    – entity: sensor.pzem_pisc_energy
    name: Luminosité
    color: ‘#FFBF00’
    hours_to_show: 12
    – type: sensor
    entity: sensor.energie_piscine_jour
    graph: line
    – type: custom:mini-graph-card
    entities:
    – entity: sensor.netatmo_netatmo_indoor_exterieure_temperature
    unit: °C
    color: ‘#df6366’
    name: T° Extérieure
    – entity: sensor.temp_piscine
    unit: °C
    color: ‘#4e91d8’
    name: T° Eau
    – entity: sensor.sondes_temperatures_air_temperature_5
    unit: °C
    color: ‘#9c54b3’
    name: T° Skimmer
    – entity: switch.ppe_filtration
    color: ‘#FFFF00’
    y_axis: secondary
    smoothing: false
    aggregate_func: min
    show_state: true
    show_line: false
    show_points: true
    state_map:
    – value: ‘off’
    label: Eteinte
    – value: ‘on’
    label: En Marche
    height: 250
    hours_to_show: 48
    line_width: 2
    name: null
    points_per_hour: 2
    view_layout:
    position: main
    view_layout:
    position: sidebar

    ————–

    Minos

    1. Bonjour
      J’en déduit que tu as réussi à le faire fonctionner, content pour toi! Peux tu faire une copie d’écran de ta carte ce sera plus simple à visualiser?
      Slts

        1. C’est pas grave, je créerai la carte. J’ai vu un sensor.ble_conductivity_kevin, c’est quel type, il sert à mesurer la conductivité, donc le niveau de désinfection?

  7. Non lol, c ‘est une coquille dans la carte , c ‘est un sensor utilisé pour ma Mi Flora …lol

    Mais effectivement , ça aurait pu être la désinfection…

  8. Dis moi tu sais comment il serait possible de récupérer le temps de filtration calculé , en fait la période de filtration sur la carte ?

    Merci par avance,

    Minos

    1. Il faut insérer dans la carte l’entité que tu as déclaré à la dernière ligne dans le piscine_filtration.yaml.
      # Affichage dans HA des horaires filtration
      periode_filtration: input_text.piscine_periode_filtration

      J’ai reproduit ta carte c’est sympa et la photo donne envie!

      1. Salut ,

        Merci pour la carte !

        oui periode_filtration: input_text.piscine_periode_filtration je l’ai deja dans la carte ça remonte bien les horaires autour de l’heure pivot .

        ce que j’évoque c ‘est le nombre total d’ heures de filtration par ex:

        si la période est 11:00/12:00/12:30 soit 1h30 j aimerai pouvoir afficher ce résultat 1h30 dans la carte .

        Minos

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.