[résolu] Ajout thermomètre virtuel

bonjour , mon sujet est de créer un thermomètre qui va recueillir la température en provenance d’une autre box.

pour le dialogue entre les box j’utilises les webhook
et la box qui héberge le vrai thermomètre va envoyer un ordre de mise à jour à chaque changement de valeur du thermomètre (delta > 0.5°C) via l’ordre
http://ip_ha:8123/api/webhook/temperature_portail?temperature_portail=20

dans HA j’ai créé un automate qui va recevoir l’info

- id: '1704559851170'
  alias: reçois température portail
  description: ''
  trigger:
  - platform: webhook
    allowed_methods:
    - POST
    - PUT
    - GET
    local_only: true
    webhook_id: temperature_portail
  condition: []
  action:
  - service: input_number.set_value
    data_template:
      entity_id: sensor.temp_portail
      measurement: '{{ (trigger.query.temperature_portail | float) }}'
  mode: single

j’ai créé un thermomètre virtuel
dans sensors.yaml

  - platform: template
    sensors:
      temp_portail:
        friendly_name: "temp_portail"
        unique_id: "temp_portail"
        unit_of_measurement: '°C'
        device_class: temperature
        value_template: "14.6"

j’ai 2 point que je n’arrive pas à voir

dans mon sensor , je ne sais pas trop quoi mettre dans le value_template
dans mon automate : dans la partie action , j’ai mis input_number.set_value,mais je ne sais pas non plus quoi mettre pour mettre à jour mon sensor ?

il n’y a pas en standard de service pour forcer une mise à jour d’un sensor, la solution est d’utiliser un développement python_script

une fois installé

  • créer le répertoire config/python_scripts
  • ajouter dans configuration.yaml une ligne
    python_script:
  • relancer la configuration yaml

de créer un service qui s’appelle python_script.set_state
je recopie ici le .py qu’il faut ajouter dans le repertoire python_scripts

#==================================================================================================
#  python_scripts/set_state.py 
#==================================================================================================

#--------------------------------------------------------------------------------------------------
# Set the state or other attributes for the entity specified in the Automation Action
#--------------------------------------------------------------------------------------------------

inputEntity = data.get('entity_id')
if inputEntity is None:
    logger.warning("===== entity_id is required if you want to set something.")
else:    
    inputStateObject = hass.states.get(inputEntity)
    inputState = inputStateObject.state
    inputAttributesObject = inputStateObject.attributes.copy()

    for item in data:
        newAttribute = data.get(item)
        logger.debug("===== item = {0}; value = {1}".format(item,newAttribute))
        if item == 'entity_id':
            continue            # already handled
        elif item == 'state':
            inputState = newAttribute
        else:
            inputAttributesObject[item] = newAttribute
        
    hass.states.set(inputEntity, inputState, inputAttributesObject)

pour prendre en compte ce service

  • dans outils de developpement/services
    appeler le service : Python Scripts: Recharger (reload)

pour plus d’info suivre ce post:

le service python_script.set_state est maintenant disponible

créer un sensor: je l’ai mis dans template.yaml mais j’aurais pu le mettre dans sensors.yaml
donc dans template.yaml,
edit: on peut aussi créer le sensor via l’UI : paramètres/appareils et services/entrées/template/modéliser un capteur et on mets les mêmes infos que ce que j’ai mis dans le yaml, mettre {{ « 13 »}} dans modèle d’entité

  - sensor:
        - name: "temp_portail_input"
           unique_id: "temp_portail_input01"
           unit_of_measurement: "°C"
           device_class: temperature
           state_class: measurement
           state: >
               {{ "13"}}

le 13 c’est juste pour voir si c’est OK dans lovelace

ensuite créer un automate avec le webhook: temperature_portail, le service python_script.set_state, le sensor créé

- id: '1704584692313'
  alias: recois temperature portail
  description: ''
  trigger:
  - platform: webhook
    allowed_methods:
    - POST
    - PUT
    - GET
    local_only: true
    webhook_id: temperature_portail
  condition: []
  action:
  - service: python_script.set_state
    data_template:
      entity_id: sensor.temp_portail_input
      state: '{{ (trigger.query.temperature_portail | float) }}'
  mode: single

relancer HA (ou les parties nécessaires)

l’appel depuis le déclencheur externe est lui à automatiser et utilise le webhook de HA avec la syntaxe:
http://IP_HA:8123/api/webhook/temperature_portail?temperature_portail=21.5

je me permet, maintenant que j’ai la solution, de dire que HA c’est bien mais qu’est-ce que c’est compliqué pour faire des choses simples

dans mes autres box, il m’a fallu environ 5 minutes, 1 ligne de commande sur l’émetteur utilisant l’API cible (la ligne de commande est générée dans la simulation de l’usage de l’API d’entrée du récepteur) et la création d’un capteur d’entrée disponible immédiatement sur catalogue graphique, avec le choix température.

Bonjour,
il existe un service pour actualiser une entité, homeassistant.update_entity.

ah oui, c’est maintenant que tu me le dis, ça va être de ma faute !! :joy:
toute référence à un pub étant fortuite :innocent:

@WarC0zes merci , ça fonctionne avec les sensors ?

oui.
Je l’utilise pour actualiser les sensors de system monitor, car par défaut c’est toutes le 15sec et je suis passer a 30sec avec ce service.

exemple de mon automatisation:

alias: System Monitor Scan interval
description: ""
trigger:
  - platform: time_pattern
    seconds: /30
condition: []
action:
  - service: homeassistant.update_entity
    target:
      entity_id:
        - sensor.disk_free
        - sensor.disk_use_percent
        - sensor.memory_free
        - sensor.memory_use_percent
        - sensor.network_in_end0
        - sensor.network_out_end0
        - sensor.network_throughput_in_end0
        - sensor.network_throughput_out_end0
        - sensor.processor_temperature
        - sensor.processor_use
    data: {}
mode: single

je viens de tester avec le webhook ça marche pas , mais peut-être que j’ai une erreur dans mon automate

- id: '1704620695254'
  alias: reçois mise à jour température au portail
  description: ''
  trigger:
  - platform: webhook
    allowed_methods:
    - POST
    - PUT
    - GET
    local_only: true
    webhook_id: reçois_temperature_portail
  condition: []
  action:
  - service: homeassistant.update_entity
    data_template:
      entity_id: sensor.temperature_au_portail
      state: '{{ (trigger.query.temperature_portail | float) }}'
  mode: single

l’automate se plante avec une erreur sur :
extra keys not allowed @ data[‹ state ›]

Tu as mis data_template au lieu de data sur ton service !

j’ai essayé avec data, ça marche pas au niveau syntaxe puisque j’ai du template , je suis jeté directement au moment d’enregistrer

edit:
j’ai l’impression que le update_entity ne supporte pas que l’on cible un attribut, mais doit faire un reload de l’entité complète, si celle-ci à du template dans ses attributs alors c’est OK, les mises à jour se font, si maintenant c’est du template au niveau de l’action alors il y a erreur

Ouais en relisant la Doc ça force une remise à jour de l’entité sans en fixer une valeur arbitraire

Tu pourrais sinon faire un input number que tu update avec le service input_number.set_value et ensuite un sensor template qui récupère la valeur de cet input_number.

Pas de python…

Edit : tu peux même faire un input number et lui mettre une unité en fait …

malheureusement déjà essayé , le input_number fonctionne pas avec le service input_number.set et les webhook qui cible aussi un paramètre state, j’ai la même erreur au niveau @ data[‹ state ›]

Et ça ? C’est pas mal…

ah oui, en passant par les event et pas par les services, effectivement ça décortique l’event, pour ensuite cibler directement les attributs et forcer l’attribut state à la valeur qui a été extraite du message, ça oblige aussi à revoir la commande avec le webhook, pour la forcer en put et ajouter toutes les entêtes + toutes les data dans le payload.

donc effectivement ça doit marcher :exploding_head: :hot_face:

mais c’est quand même tiré par les cheveux cette histoire , z’aurais pas pu mettre un service de type :
sensor.value_set (ce qui se fait dans le python_script)