Filtrage de valeurs farfelues et template

Bonjour,

Ayant parfois dans les données de mes capteurs des valeurs hors norme, j’ai tenté de filtrer avec les moyens de HA (filter, outlier). Après plusieurs semaines d’essais, je constate qu’aucun de ces filtres n’écarte ‘réellement’ des valeurs farfelues.

J’envisage donc de réaliser ce filtrage par moi-même via de l’amortissement.

Ce que je souhaite faire :
If Nlle_donnée > (ancienne_valeur + 20) then ancienne_valeur + 5
If Nlle_donnée < (ancienne_valeur – 20) then ancienne valeur – 5
Else ancienne_valeur = Nlle_donnée

Ainsi, si la nouvelle donnée reste dans la plage + ou – 20 points, la valeur résultat (ancienne_valeur) prend la valeur de la nouvelle donnée.
Si celle-ci est hors limite, la valeur résultat suit la tendance, mais ne s’incrémente ou ne se décrémente que de 5 points.

J’ai bien regardé du côté des templates, mais je ne comprends pas vraiment comment faire.

Pourriez-vous m’aider ou me montrer comment l’écrire ?

Oui tu dois bien utiliser les templates, mais la dernière valeur ne sera pas dispo directement. Tu peux la stocker dans un input_number et réutiliser. Mais l’alternative plus propre est d’utiliser la fonction trend, tester si la tendance est trop forte, et si oui, « amortir » la valeur.

Trend - Home Assistant (home-assistant.io)

Désolé, je n’ai pas eu le temps de faire le code jinja2.

Bonjour,

Voilà ce que j’ai réussi à pondre de mieux pour le moment.
Ça fonctionne, c’est en test…

- platform: template
    sensors:
      tension_filtre_reserve_eau_pluie:
        friendly_name: "Tension filtree sonde cuve Eau pluie"
        device_class: voltage
        unit_of_measurement: V
        value_template: >
          {% if states('sensor.shelly_cuve_pluie_adc') | float (0) >  (states('sensor.tension_filtre_reserve_eau_pluie') | float(0)  +  0.5) %}
            {{ (states('sensor.tension_filtre_reserve_eau_pluie') | float(0)) + 0.05}}
          {%- else -%}
            {% if states('sensor.shelly_cuve_pluie_adc') | float(0) < (states('sensor.tension_filtre_reserve_eau_pluie') | float(0)  - 0.5 ) %}
              {{ (states('sensor.tension_filtre_reserve_eau_pluie') | float(0)) - 0.05 }}
            {%- else -%}
              {{ states('sensor.shelly_cuve_pluie_adc') | float(0)  }}
            {%- endif %}
          {%- endif %}   

Bon, en fait, çà ne fonctionne pas.
La valeur ‹ sensor.tension_filtre_reserve_eau_pluie › prend la valeur du Shelly tant que celle-ci reste dans les bornes des if (+/- 0.5)
Dès que la valeur s’en écarte et rentre dans l’un des premiers cas, la valeur du sensor n’est pas incrémentée (ou décrémentée).
Je dois très certainement mal écrire ces lignes :

 {{ (states('sensor.tension_filtre_reserve_eau_pluie') | float(0)) + 0.05}}
 {{ (states('sensor.tension_filtre_reserve_eau_pluie') | float(0)) - 0.05 }}

Sans doute lié à çà :

Ou autre chose !! ?

J’avance…
Il m’a fallu créer un premier template pour mémoriser l’ancienne valeur

        
  - platform: template
    sensors:
      memoire_tension:     
        unit_of_measurement: V
        friendly_name: Memoire tension sonde
        device_class: voltage
        value_template: >
          {% set memoire = states('sensor.tension_filtre_reserve_eau_pluie') | float(0) %}
          {{ memoire }}
 

Puis utiliser ce sensor dans le template de tests :


  - platform: template
    sensors:
      tension_filtre_reserve_eau_pluie:
        friendly_name: "Volume cuve Eau pluie"
        device_class: voltage
        unit_of_measurement: V
        value_template: >
          {% if states('sensor.shelly_cuve_pluie_adc') | float(0) >  (states('sensor.memoire_tension') | float(0)  +  0.5) %}
            {{ (states('sensor.memoire_tension') | float(0)) + 0.05}}
          {%- else -%}
            {% if states('sensor.shelly_cuve_pluie_adc') | float(0) < (states('sensor.memoire_tension') | float(0)  - 0.5 ) %}
              {{ (states('sensor.memoire_tension') | float(0)) - 0.05 }}
            {%- else -%}
              {{ states('sensor.shelly_cuve_pluie_adc') | float(0)  }}
            {%- endif %}
          {%- endif %}  

Maintenant, j’ai bien une prise en compte du test et une incrémentation par pas de 0.05 V.
Sauf que le template fonctionne en boucle et incrémente la variable jusqu’à rejoindre la tension du capteur. (En moins d’une seconde)
Il faudrait que l’incrémentation n’ait lieu qu’une seule fois, après chaque remontée d’information du capteur.

Bonjour une petite question, est-ce lorsque vous réinitialisez les templates, la valeur est concernée ?

{%- else -%}
{{ states(‹ sensor.shelly_cuve_pluie_adc ›) | float(0) }}

ou est-elle réinitialisée à 0 car si le sensor n’est pas disponible la valeur devient 0 ?

J’imagine qu’en rechargeant le fichier config, tous les templates qui y sont inscrits sont réinitialisés.
Dans ce cas, après essai, le sensor tension_filtre_reserve_eau_pluie repasse à 0 et se réincrémente à toute vitesse jusqu’à la valeur du sensor.shelly_cuve_pluie_adc.

Le temps est passé sur cette affaire. J’avais trouvé une solution fonctionnelle à partir de deux automations.

Automation A : si valeur supérieure de 0.1 V à ancienne valeur => incrémentation de 0.001V
Automation B : Si valeur inférieure de 0.1 V à l’ancienne valeur => décrémentation de 0.001V

Ainsi, la variable est traitée une fois à chaque acquisition de nouvelle valeur (toutes les 30 ’ environ’). Pas de risque de modification rapide. C’est pour le moment le meilleur moyen que j’ai trouvé pour filtrer les valeurs de mes sondes de niveau (tension 0/5V)

Ce qui donne ceci :

- id: 'augmentation input.number tension filtree sonde cuve pluie'   
  description: "Augmentation progressive tension sonde cuve pluie "
  mode: single
  trigger:
    - platform: state
      entity_id: sensor.shelly_cuve_pluie_adc
      
  condition:
     - condition: template
       value_template:  "{{ (states('sensor.shelly_cuve_pluie_adc')| float) > ((states('input_number.tension_filtree_reserve_eau_pluie')| float) + 0.1) }}"
      
  action:
    - service: input_number.set_value
      data:
        entity_id: input_number.tension_filtree_reserve_eau_pluie
        value: "{{ (states('sensor.shelly_cuve_pluie_adc') | float + 0.001) }}"
        

   
- id: 'diminution input.number tension filtree sonde cuve pluie'   
  description: "Diminution progressive tension sonde cuve pluie "
  mode: single
  trigger:
    - platform: state
      entity_id: sensor.shelly_cuve_pluie_adc
      
  condition:
     - condition: template
       value_template:  "{{ (states('sensor.shelly_cuve_pluie_adc')| float) < ((states('input_number.tension_filtree_reserve_eau_pluie') | float) - 0.1) }}"
      
  action:
    - service: input_number.set_value
      data:
        entity_id: input_number.tension_filtree_reserve_eau_pluie
        value: "{{ (states('sensor.shelly_cuve_pluie_adc') | float - 0.001) }}"
  
   
    

Cela fonctionne ainsi; mais en jetant un œil dans les log, je retrouve ces erreurs qui me laissent penser que j’ai mal traité mes variables. Le float semble inapproprié. Mais si je l’enlève, j’ai des erreurs et l’automation ne fonctionne plus.

2023-12-30 15:00:13.644 WARNING (MainThread) [homeassistant.components.automation] Error evaluating condition in 'automation 20':
In 'condition':
  In 'template' condition: ValueError: Template error: float got invalid input 'unavailable' when rendering template '{{ (states('sensor.shelly_cuve_pluie_adc')| float) > ((states('input_number.tension_filtree_reserve_eau_pluie')| float) + 0.1) }}' but no default was specified
2023-12-30 15:00:13.646 WARNING (MainThread) [homeassistant.components.automation] Error evaluating condition in 'automation 21':
In 'condition':
  In 'template' condition: ValueError: Template error: float got invalid input 'unavailable' when rendering template '{{ (states('sensor.shelly_cuve_pluie_adc')| float) < ((states('input_number.tension_filtree_reserve_eau_pluie') | float) - 0.1) }}' but no default was specified

Avez-vous une idée pour faire disparaitre ce soucis ?

Je vois que ma requête est tombée… déjà bien loin. :face_with_peeking_eye:

Quelqu’un pour m’aider à corriger mon template (in condition) ?