Déclencher requête HTTP après appui bouton via RESTful

Mon problème

Salut.

J’ai une pergola bioclimatique avec des bandeaux LEDs intégrés.

Je peux les allumer avec cette requête HTTP:

http://192.168.0.159/zns.cgi?cmd=l&o=64&p=255

Et les éteindre avec : http://192.168.0.159/zns.cgi?cmd=l&o=64&p=0

Ou les dimmer en faisant varier le p= entre 0 et 255 donc :wink:

Je me suis donc basé sur ce bout de doc pour écrire ces lignes dans mon configuration.yaml :

rest_command:
  pergola_light_on:
    url: "http://192.168.0.159/zns.cgi?cmd=l&o=64&p=255"
    method: put
    content_type: "application/x-www-form-urlencoded"
  pergola_light_off:
    url: "http://192.168.0.159/zns.cgi?cmd=l&o=64&p=0"
    method: put
    content_type: "application/x-www-form-urlencoded"

Au passage, j’ai voulu déplacer le code dans un fichier rest-command.yaml et faire :

rest_command: !include rest_command.yaml

Mais HA n’aime pas, est-ce normal ?

Bref, j’ai ensuite créé l’automatisation suivante :

- id: '1682451293801'
  alias: On_Light_Pergola
  description: ''
  trigger:
  - platform: device
    domain: mqtt
    device_id: 970372b336a659eeb5c93e30b257beee
    type: action
    subtype: single_left
    discovery_id: 0x00158d0001e0f746 action_single_left
  condition: []
  action:
    - service: rest_command.pergola_light_on
  mode: single

J’ai bien la tace de mon automatisation quand j’appuie sur mon interrupteur mais la pergola ne s’allume pas.

J’ai ça dans la trace :

Executed: April 25, 2023 at 21:52:13
Result:
params:
  domain: rest_command
  service: pergola_light_on
  service_data: {}
  target: {}
running_script: false
limit: 10

J’ai dû louper un truc important mais quoi ??

Merci de votre aide.

Ma configuration


[center]## System Information

version core-2023.4.6
installation_type Home Assistant Supervised
dev false
hassio true
docker true
user root
virtualenv false
python_version 3.10.10
os_name Linux
os_version 5.10.0-21-amd64
arch x86_64
timezone Europe/Paris
config_dir /config
Home Assistant Community Store
GitHub API ok
GitHub Content ok
GitHub Web ok
GitHub API Calls Remaining 4811
Installed Version 1.32.1
Stage running
Available Repositories 1269
Downloaded Repositories 9
Home Assistant Cloud
logged_in false
can_reach_cert_server ok
can_reach_cloud_auth ok
can_reach_cloud ok
Home Assistant Supervisor
host_os Debian GNU/Linux 11 (bullseye)
update_channel stable
supervisor_version supervisor-2023.04.1
agent_version 1.5.1
docker_version 23.0.4
disk_total 115.4 GB
disk_used 9.0 GB
healthy true
supported true
supervisor_api ok
version_api ok
installed_addons SSH & Web Terminal (13.1.0), Studio Code Server (5.5.7), Samba Backup (5.2.0), Z-Wave JS (0.1.79)
Dashboards
dashboards 2
resources 4
views 6
mode storage
Recorder
oldest_recorder_run April 16, 2023 at 15:33
current_recorder_run April 25, 2023 at 21:51
estimated_db_size 321.06 MiB
database_engine sqlite
database_version 3.38.5
[/center] ___

Hello

si tu peux ,

apres la modif redemarre ton HA pour que cela soit pris en compte .

ce qui va changé ensuite c’est le debut de ton fichier

  pergola_light_on:
    url: "http://192.168.0.159/zns.cgi?cmd=l&o=64&p=255"
    method: put
    content_type: "application/x-www-form-urlencoded"

  pergola_light_off:
    url: "http://192.168.0.159/zns.cgi?cmd=l&o=64&p=0"
    method: put
    content_type: "application/x-www-form-urlencoded"

Ne met surtout en haut du fichier ceci

rest_command:

sinon tu as une erreur

Merci pour la syntaxe, ça marche :wink:

J’ai aussi réussi à créer un sensor à partir d’une requête d’état de la pergola :

- platform: rest
  resource: "http://192.168.0.159/zns.cgi?cmd=d&p=o"
  name: light_pergola_white
  value_template: "{{ value_json['root']['gpo6'].split(';')[0] }}"

La requête renvoie ça :

<root>
   <ID>0</ID>
   <gpo0>0;0</gpo0>
   <gpo1>0;0</gpo1>
   <gpo2>0;0</gpo2>
   <gpo3>0;0</gpo3>
   <gpo4>0;0</gpo4>
   <gpo5>0;0</gpo5>
   <gpo6>0;0</gpo6>
   <gpo7>255;0</gpo7>
   <gpo8>255;0</gpo8>
   <gpo9>255;0</gpo9>
   <gpo10>255;0</gpo10>
   <gpo11>0;0</gpo11>
   <LPO>15</LPO>
   <retcode>200</retcode>
</root>

Et j’ai bien la valeur PWM qui remonte dans le sensor.

Reste donc à régler cette histoire d’automatisation :sweat_smile:

1 « J'aime »

Salut

Avec rest, ça ne peut pas fonctionner, ça ne gère pas le PUT.

Sinon essaie avec ça :

sensor:
  - platform: command_line
    command: "curl -X PUT 'http://192.168.0.159/zns.cgi?cmd=l&o=64&p=255'"
    name: pergola_light_on
    json_attributes:
      - body
      - body.root.gpo6
    value_template: "OK"
    scan_interval: 60

Je vais tester ta syntaxe mais j’ai mis PUT car j’ai copier/coller des bouts de codes.

Je teste un peu tout et n’importe quoi :sweat_smile:

SI ça se trouve, c’est pas du PUT mais du GET

Et on dirait que Rest gère aussi le PUT :

Attention, ne pas confondre:

et

Je te conseille de tester ton API avec Postman: https://www.postman.com/.
Ensuite en fonction des résultats, tu adaptes à HA.

Oui, donc pour récupérer l’état Allumé / Eteint de ma pergola, c’est un RESTful sensor et ça marche.
Pour commander l’allumage ou l’extinction, c’est du RESTful command pour pouvoir l’appeler en tant que service dans mon automatisation. Et le RESTful command, prend en charge le PUT.
Mais ai-je besoin d’être en PUT ?
Car je veux juste envoyer une requête HTTP, donc une méthode POST doit suffire, non ?
Je vais tester tout ça.

C’est puissant HA mais c’es quand même ardu :crazy_face:

Oui, ç’est un bon résumé.

Une requête HTTP supporte plusieurs method: HTTP request methods - HTTP | MDN

Mais Restful command ne supporte que celles-ci:
image

A toi de connaitre l’API de ta pergola :wink:

Idem

J’ai testé ton outil Postman et effectivement, ma requête ne supporte que les méthodes POST et GET

Donc, je vais modifier mon code et voir si ça fonctionne.

1 « J'aime »

Bon, j’avance !

- id: Light_On_Pergola
  alias: Light_On_Pergola
  description: Allumer la pergola
  trigger:
  - platform: device
    domain: mqtt
    device_id: 970372b336a659eeb5c93e30b257beee
    type: action
    subtype: single_left
    discovery_id: 0x00158d0001e0f746 action_single_left
  condition:
  action:
  - service: rest_command.pergola_light_on
    data: {}
  mode: single

Ca allume bien les lames de la pergola quand je clique sur mon interrupteur :ok_hand:

Mais le but du jeu, c’est d’allumer quand c’est éteint et inversement.

Dans un premier temps, j’ai donc dupliqué l’automatisation et gardé le même trigger.

Et j’ai rajouté une condition pour l’automatisation d’allumage :

  - condition: template
    value_template: '{{ state_attr(''sensor.light_pergola_white'', ''state'') == 0 }}'

Donc si le PWM des LEDs est à 0, c’est éteint et donc je veux allumer.

Et l’inverse pour l’automatisation d’extinction :

  - condition: template
    value_template: '{{ state_attr(''sensor.light_pergola_white'', ''state'') != 0 }}'

Sauf que quand je déclenche l’automatisation et que je regarde la trace, j’ai ça :

Result:
result: true
entities:
  - sensor.light_pergola_white

Quand il évalue la condition :

condition: template
value_template: '{{ state_attr(''sensor.light_pergola_white'', ''state'') != 0 }}'

Pour HA, le state n’est pas à 0 donc il éteint les LED

Et si j’allume les LED via la requête HTTP, l’automatisation éteint bien les LED.

Du coup, j’ai voulu caster le resultat du state_attr :

condition: template
value_template: '{{ (state_attr(''sensor.light_pergola_white'', ''state'')|int) != 0 }}'

Mais là, les automatisations ne se lancent plus, je suppose que c’est lié à une mauvaise syntaxe.

Quand je regarde l’état de l’entité, j’ai bien 0 dans son état :

https://imgur.com/Rp8wKVV

Essaie ça, ce sera plus simple qu’une automatisation:

Et tu fait une automatisation avec ton interrupteur pour appeller ce template.

light:
  - platform: template
    lights:
      light_pergola:
        friendly_name: "Lumière pergola"
        level_template: "{{ state_attr('sensor.light_pergola_white', 'state')|int }}"
        value_template: "{{ state_attr('sensor.light_pergola_white', 'state')|int > 0 }}"
        turn_on:
          service: rest_command.pergola_light_on
        turn_off:
          service: rest_command.pergola_light_off
#        set_level:
#          service: rest_command.pergola_light_on
#          data:
#            brightness: "{{ brightness }}"

Avec « set_level », tu peux gérer la variation, mais it faut un script.

Je teste ton light template mais déjà avec toi et Troon sur le forum US, j’arrive à un truc fonctionnel :

- id: Light_On_Pergola
  alias: Light_On_Pergola
  description: Allumer la pergola
  trigger:
  - platform: device
    domain: mqtt
    device_id: 970372b336a659eeb5c93e30b257beee
    type: action
    subtype: single_left
    discovery_id: 0x00158d0001e0f746 action_single_left
  condition:
  - condition: template
    value_template: '{{ states("sensor.light_pergola_white")|int(0) == 0 }}'
  action:
  - service: rest_command.pergola_light_on
    data: {}
  mode: single
- id: Light_Off_Pergola
  alias: Light_Off_Pergola
  description: Eteindre la pergola
  trigger:
  - platform: device
    domain: mqtt
    device_id: 970372b336a659eeb5c93e30b257beee
    type: action
    subtype: single_left
    discovery_id: 0x00158d0001e0f746 action_single_left
  condition:
  - condition: template
    value_template: '{{ states("sensor.light_pergola_white")|int(0) != 0 }}'
  action:
  - service: rest_command.pergola_light_off
    data: {}
  mode: single

De ce que j’ai compris mon sensor n’a pas d’attribut donc je dois passer par la fonction states et non state_attr.

Là, je peux allumer et éteindre mes LED mais ta solution proposée est plus propre et si en plus, ça permet la gestion de l’intensité (avec l’ajout d’un script), ça sera encore mieux.

Je teste ça dans l’après-midi

J’ai donc mis ce code :

light:
  - platform: template
    lights:
      light_pergola:
        friendly_name: "Lumière pergola"
        level_template: "{{ (states('light_pergola_white')|int) }}"
        value_template: "{{ (states('light_pergola_white')|int) > 0}}"
#        icon_template: >-
#          {% if (states('light_pergola_white')|int) == 0 %}
#            mdi:lightbulb-off
#          {% else %}
#            mdi:lightbulb-on
#          {% endif %}
        turn_on:
          service: rest_command.pergola_light_on
        turn_off:
          service: rest_command.pergola_light_off

J’ai ensuite créé une mashroom card light.

Quand je clique sur la card, la lumière s’allume, c’est un bon point MAIS c’est tout.

Dans les states, le sensor a bien sa valeur qui passe à 255 mais le light.light_pergola reste à off

En me basant sur ton lien, j’ai aussi essayé ça :

light:
  - platform: template
    lights:
      light_pergola:
        friendly_name: "Lumière pergola"
        level_template: "{{ states('sensor.light_pergola_white')|int(0) }}"
        value_template: >-
          {% if (states('sensor.light_pergola_white')|int(0)) == 0 %}
            off
          {% else %}
            on
          {% endif %}
        icon_template: >-
          {% if (states('light_pergola_white')|int) == 0 %}
            mdi:lightbulb-off
          {% else %}
            mdi:lightbulb-on
          {% endif %}
        turn_on:
          service: rest_command.pergola_light_on
        turn_off:
          service: rest_command.pergola_light_off

Et ça marche, y a juste un peu de latence pour que dans le dashboard, la lumière change d’icône.

Maintenant, la partie dimmable :smiley:

Rajoute scan_interval: 15 ça actualize le sensor toutes les 15 secondes

1 « J'aime »

Petite amélioration de la partie rest_command :

pergola_light:
  url: "http://192.168.0.159/zns.cgi?cmd=l&o=64&p={{ pwm }}"
  method: get

Et l’appel dans le light template :

        turn_on:
          service: rest_command.pergola_light
          data:
            pwm: 255
        turn_off:
          service: rest_command.pergola_light
          data:
            pwm: 0

Donc pour le dimmer, je pourrais faire un truc comme ça :

        set_level:
          service: rest_command.pergola_light
          data:
            pwm: {{ value }}

Mais il faudrait que je récupère la valeur du slider de la mashroom card pour savoir quelle intensité est choisie. Et si le slider travaille dans la plage 0-100 (ce qui serait logique), il faut faire une conversion dans la plage 0-255.

1 « J'aime »

tu peux utiliser 0-255 pour le slider, ce serait moins compliqué :smile:

Ca se modifie dans le code YAML de la mushroom card, je suppose ?

Et tu sais comment récupérer sa valeur pour la mettre en paramètre de l’appel de la commande RESTful ?

Non

Tu vas dans Paramètres → Apprareils et service → Entrées, et tu appuie sur Créer une entrée

Ensuite choisis Nombre, et tu remplis les champs.