Régler une valeur de couleur RGB avec un light template

Bonjour à tous !

Je me sers de l’API REST pour envoyer des commandes à un ESP pour un projet d’horloge murale (lien du GitHub : GitHub - Winston-Lu/ESP8266-LED-Shelf: A ESP8266 rewrite from the ground up of a 3D printable shelving system with a hidden giant clock in its shelves edges based off of the original project: https://github.com/DIY-Machines/DigitalClockSmartShelving)

J’ai construit l’horloge et je me suis rendu compte que je pouvais ajouter pas mal de commandes de l’horloge à Home Assistant via l’API REST. Jusqu’ici je suis super content. J’ai réussi à modifier, par exemple, la luminosité via ces commandes simples ajoutées dans le YAML :

rest_command:
  luminosite_horloge_jour:
    url: "http://192.168.1.15/brightness?value=170"
  luminosite_horloge_soir:
    url: "http://192.168.1.15/brightness?value=75"

Je les ai ajoutées dans des automatisations pour la journée et la soirée par exemple :slight_smile:

J’ai aussi ajouté un template light pour me permettre de l’allumer, l’éteindre et modifier la luminosité dans Lovelace :

  - platform: template
    lights:
      horloge_murale:
        turn_on:
          service: rest_command.allumer_horloge
        turn_off:
          service: rest_command.eteindre_horloge
        icon_template: mdi:clock-digital
        set_level:
          service: rest_command.modifier_luminosite
          data:
            luminosite_horloge: "{{ brightness }}"

Bref tout cela fonctionne parfaitement ! Maintenant, sur l’horloge, je peux modifier la couleur des chiffres à volonté. J’ai donc logiquement vu dans le template light (Template Light - Home Assistant) la possibilité d’une ligne « set color ». Lorsque je l’ajoute, la rosace de couleur apparaît bien dans Lovelace suite à appui long. CEPENDANT, cela renvoie des valeurs « hue et saturation » et je ne sais pas à quoi ça correspond.

Mon soucis est que pour changer la couleur, l’horloge attend un appel HTTP de ce type : http://192.168.1.15/h1color?value=0&red=255&green=255&blue=0 (la par exemple la couleur du premier chiffre sera jaune).

Ce qu’il faudrait que je fasse en appel de service est quelque chose de ce style :

rest_command:
  couleur_h1_horloge:
    url: "http://192.168.1.15/h1color?value=0&red={{ red_h1 }}&green={{ green_h1 }}&blue={{ blue_h1 }}"

La où les valeurs entre crochet sont situées entre 0 et 255.

Le problème, c’est que je ne sais pas récupérer de valeur de 0 à 255 à partir de la rosace de couleur. J’ai vu qu’à partir de set_color on peut mettre une action qui serait dans mon cas de récupérer ces chiffres, mais je ne m’y connait pas du tout en code pour faire ça…

C’est un peu complexe comme affaire mais je pense être très proche de la solution !

Merci à tous ceux qui s’y pencheront ! :smiley:

Salut.

Pas testé mais jete un oeil là dessus

J’ai vu le sujet et j’ai absolument rien compris haha.

Tu as un exemple de script (formule mathématique) pour transformer la valeur de la couleur HVS (Hue=H, Saturation=S, Lightness=L) en valeur RGB comme tu connais. La partie colors: >- de

movie_night_color:
  sequence:
    - service: script.set_color
      data_template:
        id: group.living_room_colored_lights
        colors: >-
          {%- set h = (range(0, 360)|random)/360 %}
          {%- set s = states.input_slider.movie_night_saturation.state|float %}
          {%- set v = states.input_slider.movie_night_brightness.state|float %}

          {%- set i = (h * 6)|int %}
          {%- set f = h * 6 - i %}
          {%- set p = v * (1 - s) %}
          {%- set q = v * (1 - f * s) %}
          {%- set t = v * (1 - (1 - f) * s) %}

          {%- if i % 6 == 0 %}
            {% set r = v %}
            {% set g = t %}
            {% set b = p %}
          {%- elif i % 6 == 1 %}
            {% set r = q %}
            {% set g = v %}
            {% set b = p %}
          {%- elif i % 6 == 2 %}
            {% set r = p %}
            {% set g = v %}
            {% set b = t %}
          {%- elif i % 6 == 3 %}
            {% set r = p %}
            {% set g = q %}
            {% set b = v %}
          {%- elif i % 6 == 4 %}
            {% set r = t %}
            {% set g = p %}
            {% set b = v %}
          {%- elif i % 6 == 5 %}
            {% set r = v %}
            {% set g = p %}
            {% set b = q %}
          {%- endif %}

          {{ (255*r)|round(0) }}, {{ (255*g)|round(0) }}, {{ (255*b)|round(0) }}, {{ (360*h)|int }}

        transition: "{{ states.input_slider.movie_night_transition.state|int }}"

Il gère ça à partir de valeurs fournies par 2 input_slider.movie_night_brightness et input_slider.movie_night_saturation et d’une valeur aléatoire pour H. Les variables (r,g,b,h) servent à recalculer les valeurs hexa RGB : là {{ (255*r)|round(0) }}, {{ (255*g)|round(0) }}, {{ (255*b)|round(0) }}, {{ (360*h)|int }}

Toi tu as à la place des inputs tu va te servir des valeurs de hue et saturation (issues de ton template light => je note ça xxxxxxxxx , yyyyyyyyyy , xxxxxxxxx ) et il faut donc tu ajoute la ‹ transformation › juste avant ton appel REST en reconstruisant les valeur de URL à l’aide des variables r g et b

rest_command:
  couleur_h1_horloge:
    url:  >-
          {%- set h =xxxxxxxxx %}
          {%- set s = yyyyyyyyyy %}
          {%- set v = xxxxxxxxx %}
          {%- set i = (h * 6)|int %}
          {%- set f = h * 6 - i %}
          {%- set p = v * (1 - s) %}
          {%- set q = v * (1 - f * s) %}
          {%- set t = v * (1 - (1 - f) * s) %}

          {%- if i % 6 == 0 %}
            {% set r = v %}
            {% set g = t %}
            {% set b = p %}
          {%- elif i % 6 == 1 %}
            {% set r = q %}
            {% set g = v %}
            {% set b = p %}
          {%- elif i % 6 == 2 %}
            {% set r = p %}
            {% set g = v %}
            {% set b = t %}
          {%- elif i % 6 == 3 %}
            {% set r = p %}
            {% set g = q %}
            {% set b = v %}
          {%- elif i % 6 == 4 %}
            {% set r = t %}
            {% set g = p %}
            {% set b = v %}
          {%- elif i % 6 == 5 %}
            {% set r = v %}
            {% set g = p %}
            {% set b = q %}
          {%- endif %}

        {%- set red_h1 = (255*r)|round(0) %}
        {%- set green_h1 = (255*g)|round(0) %}
        {%- set blue_h1 = (255*b)|round(0) %}

          http://192.168.1.15/h1color?value=0&red={{ red_h1 }}&green={{ green_h1 }}&blue={{ blue_h1 }}"

J’ai fait un copié/adapté/collé du code rapidos, c’est pas forcement parfait niveau syntaxe, mais l’idée est là

Alors je suis pas sur d’avoir tout compris mais je vais essayer de faire quelque chose avec ça. Je te tiens au courant. Merci !

Bon en fait il y a un truc que je comprends pas. La partie dans l’exemple « movie_night_color » c’est un script ? Si oui j’en ai jamais fait mais je pense qu’il suffit d’en créer un ?

Mais ensuite, comment faire le lien entre le template, le script et la commande rest ? Je ne comprends pas à ce niveau.

Regarde le dernier bloc de mon message précédent. C’est ton appel REST templatisé avec la formule…
En principe; pas besoin de script avec cette méthode : all in one
PAr contre il faut que récupère dedans les bonnes valeurs de ton template light. Moi j’ai pas les infos

Mais il y a quand même quelque chose que je ne comprends pas. Il récupère ses valeurs comme tu le dis à partir de 2 sliders. Or moi je n’ai aucun slider. J’ai juste le set color de mon light template. Voici le template :

  - platform: template
    lights:
      horloge_murale:
        turn_on:
          service: rest_command.allumer_horloge
        turn_off:
          service: rest_command.eteindre_horloge
        icon_template: mdi:clock-digital
        set_level:
          service: rest_command.modifier_luminosite
          data:
            luminosite_horloge: "{{ brightness }}"
        set_color:
          - service: input_number.set_value
            data:
              value: "{{ h }}"
              entity_id: input_number.h_input
          - service: input_number.set_value
            data:
              value: "{{ s }}"
              entity_id: input_number.s_input

Pour l’instant j’ai juste récupéré l’exemple de la page d’aide tel quel. Lorsque dans son script il récupère ses " states.input_slider.movie_night_saturation.state" et « states.input_slider.movie_night_brightness.state », cela vient de ses 2 sliders personnalisés. Moi j’ai aucun slider à part la rosace RGB de Lovelace comme tu le dis très bien dans ton message. Pour remplacer les xxxxx et yyyyy il faudrait que je sache ce que renvoie la rosace lorsque je change la couleur.

Je viens de bidouiller ça :

sequence:
  - service: couleur_h1_horloge
    data_template:
        id: horloge
        colors: >-
          {%- set h = input_number.h_input|float %}
          {%- set s = input_number.s_input|float %}
          {%- set v = input_number.h_input|float %}

          {%- set i = (h * 6)|int %}
          {%- set f = h * 6 - i %}
          {%- set p = v * (1 - s) %}
          {%- set q = v * (1 - f * s) %}
          {%- set t = v * (1 - (1 - f) * s) %}

          {%- if i % 6 == 0 %}
            {% set r = v %}
            {% set g = t %}
            {% set b = p %}
          {%- elif i % 6 == 1 %}
            {% set r = q %}
            {% set g = v %}
            {% set b = p %}
          {%- elif i % 6 == 2 %}
            {% set r = p %}
            {% set g = v %}
            {% set b = t %}
          {%- elif i % 6 == 3 %}
            {% set r = p %}
            {% set g = q %}
            {% set b = v %}
          {%- elif i % 6 == 4 %}
            {% set r = t %}
            {% set g = p %}
            {% set b = v %}
          {%- elif i % 6 == 5 %}
            {% set r = v %}
            {% set g = p %}
            {% set b = q %}
          {%- endif %}

          {{ (255*r)|round(0) }}, {{ (255*g)|round(0) }}, {{ (255*b)|round(0) }}, {{ (360*h)|int }}

Je pense que ça peut être juste mais le script ne veut pas s’enregistrer. J’ai une erreur « Message malformed: Unable to determine action @ data[‹ sequence ›][0] »
De plus, j’ai la détermination de H et S mais pas de V. En suivant ton exemple, j’ai mis l’input de h dans v également.

Je commence à me dire que je touche à quelque chose de très complexe et que je devrais peut être abandonner haha.

Si tu pars pas de mon exemple pourquoi pas… mais ne prendre qu’une partie du sien, ça marche moins bien… Son code commence pas par sequence mais par un nom movie_night_color (et est probablement dans un fichier dédié aux scripts), donc ton code n’est syntaxiquement pas bon. La structure Yaml est importante, ce sont les bases HA

Oui il faut adapter. Techniquement ça marche mais je suis pas sur que ce soit la meilleure option de mettre h (hue) dans v (value)

Ok j’ai modifié le script. Je passais par l’éditeur d’où mon code incomplet. J’ai fini par le faire rentrer et ça donne ça :

'1647094450968':
  alias: Changement couleur dizaine heures horloge
  sequence:
  - service: rest_command.couleur_h1_horloge
    data_template:
        id: horloge
        colors: >-
          {%- set h = input_number.h_input|float %}
          {%- set s = input_number.s_input|float %}
          {%- set v = input_number.h_input|float %}

          {%- set i = (h * 6)|int %}
          {%- set f = h * 6 - i %}
          {%- set p = v * (1 - s) %}
          {%- set q = v * (1 - f * s) %}
          {%- set t = v * (1 - (1 - f) * s) %}

          {%- if i % 6 == 0 %}
            {% set r = v %}
            {% set g = t %}
            {% set b = p %}
          {%- elif i % 6 == 1 %}
            {% set r = q %}
            {% set g = v %}
            {% set b = p %}
          {%- elif i % 6 == 2 %}
            {% set r = p %}
            {% set g = v %}
            {% set b = t %}
          {%- elif i % 6 == 3 %}
            {% set r = p %}
            {% set g = q %}
            {% set b = v %}
          {%- elif i % 6 == 4 %}
            {% set r = t %}
            {% set g = p %}
            {% set b = v %}
          {%- elif i % 6 == 5 %}
            {% set r = v %}
            {% set g = p %}
            {% set b = q %}
          {%- endif %}

          {{ (255*r)|round(0) }}, {{ (255*g)|round(0) }}, {{ (255*b)|round(0) }}, {{ (360*h)|int }}
  mode: single

Donc la si tout va bien, la conversion se fait. Maintenant, question peut être bête mais dans quelles variables vont les valeurs des couleurs ? Parce que si je ne me trompe pas, je n’ai plus qu’à les mettre dans l’URL de ma commande REST à la place de red_h1, blue_h1 et green_h1 ? Parce que la si je ne m’abuse ça retourne par exemple 255,125,25 mais pas de variables que je peux reporter.

Ensuite, le template détermine les valeurs de H et S, mais où est ce que je détermine V ? Je n’avais jamais vu cette façon de déterminer une couleur et c’est très contre intuitif !

Re reprends mes messages… j’ai déjà fait le boulot…

Tu détermines V comme tu veux. Une valeur fixe, un slider que tu ajoutes… Ou alors il faut retrouver comment ça se recalcule avec une formule plus compléte…
Quant au fait que ce soit contre-intuitif, possible, c’est juste une norme utilisée dans les softs graphique.
De mon coté, je ne suis pas persuadé que le commun des mortels soient bien au fait de construire une couleur à partir de ses 3 composantes primaires… A l’inverse, si tu regarde le « cone », c’est quand même assez simple de visualiser que ta couleur est plus proche du rouge que du vert, et plus ou moins lumineuse en fonctionne de la hauteur…

Oui excuse moi, je n’avais pas C/C la partie avec l’URL. Maintenant voici le résultat (je verrai pour changer la valeur de V une fois que ça fonctionnera). J’ai remis de l’ordre dans mes idées et ça donne ça :
Dans configuration.yaml on a ça :

  - platform: template
    lights:
      horloge_murale:
        turn_on:
          service: rest_command.allumer_horloge
        turn_off:
          service: rest_command.eteindre_horloge
        icon_template: mdi:clock-digital
        set_level:
          service: rest_command.modifier_luminosite
          data:
            luminosite_horloge: "{{ brightness }}"
        set_color:
          - service: input_number.set_value
            data:
              value: "{{ h }}"
              entity_id: input_number.h_input
          - service: input_number.set_value
            data:
              value: "{{ s }}"
              entity_id: input_number.s_input

Entre temps, on a le script qui doit s’enclencher :

changement_couleur_dizaines_heures:
  alias: Changement couleur dizaine heures horloge
  sequence:
  - service: rest_command.couleur_h1_horloge
    data_template:
        id: horloge
        colors: >-
          {%- set h = input_number.h_input|float %}
          {%- set s = input_number.s_input|float %}
          {%- set v = input_number.h_input|float %}

          {%- set i = (h * 6)|int %}
          {%- set f = h * 6 - i %}
          {%- set p = v * (1 - s) %}
          {%- set q = v * (1 - f * s) %}
          {%- set t = v * (1 - (1 - f) * s) %}

          {%- if i % 6 == 0 %}
            {% set r = v %}
            {% set g = t %}
            {% set b = p %}
          {%- elif i % 6 == 1 %}
            {% set r = q %}
            {% set g = v %}
            {% set b = p %}
          {%- elif i % 6 == 2 %}
            {% set r = p %}
            {% set g = v %}
            {% set b = t %}
          {%- elif i % 6 == 3 %}
            {% set r = p %}
            {% set g = q %}
            {% set b = v %}
          {%- elif i % 6 == 4 %}
            {% set r = t %}
            {% set g = p %}
            {% set b = v %}
          {%- elif i % 6 == 5 %}
            {% set r = v %}
            {% set g = p %}
            {% set b = q %}
          {%- endif %}

            {%- set red_h1 = (255*r)|round(0) %}
            {%- set green_h1 = (255*g)|round(0) %}
            {%- set blue_h1 = (255*b)|round(0) %}
  mode: single

Donc le script est sensé mettre dans les variables les valeurs RGB.

Pour finir, de nouveau dans configuration.yaml on a ça :

rest_command:
  couleur_h1_horloge:
    url: "http://192.168.1.15/h1color?value=0&red={{ red_h1 }}&green={{ green_h1 }}&blue={{ blue_h1 }}"

Et il doit y avoir quelque chose qui ne va pas parce que ça ne donne rien lorsque je change la couleur…

Pourquoi tu veux absolument passer par un script ?
Tu peux mettre le template directement dans le REST (comme mon exemple)

Ok je mets le template dans le REST. Donc on a ça :

rest_command:
  couleur_h1_horloge:
    url:  >-
          {%- set h = input_number.h_input|float %}
          {%- set s = input_number.s_input|float %}
          {%- set v = input_number.h_input|float %}
          {%- set i = (h * 6)|int %}
          {%- set f = h * 6 - i %}
          {%- set p = v * (1 - s) %}
          {%- set q = v * (1 - f * s) %}
          {%- set t = v * (1 - (1 - f) * s) %}

          {%- if i % 6 == 0 %}
            {% set r = v %}
            {% set g = t %}
            {% set b = p %}
          {%- elif i % 6 == 1 %}
            {% set r = q %}
            {% set g = v %}
            {% set b = p %}
          {%- elif i % 6 == 2 %}
            {% set r = p %}
            {% set g = v %}
            {% set b = t %}
          {%- elif i % 6 == 3 %}
            {% set r = p %}
            {% set g = q %}
            {% set b = v %}
          {%- elif i % 6 == 4 %}
            {% set r = t %}
            {% set g = p %}
            {% set b = v %}
          {%- elif i % 6 == 5 %}
            {% set r = v %}
            {% set g = p %}
            {% set b = q %}
          {%- endif %}

            {%- set red_h1 = (255*r)|round(0) %}
            {%- set green_h1 = (255*g)|round(0) %}
            {%- set blue_h1 = (255*b)|round(0) %}

          "http://192.168.1.15/h1color?value=0&red={{ red_h1 }}&green={{ green_h1 }}&blue={{ blue_h1 }}"

Et j’ai supprimé le script.
Mais ça ne fonctionne malheureusement pas mieux…

Comment tu testes ?

  • Modification des sliders
  • Puis déclenchement du service REST sur couleur_h1_horloge

Sur la dernière ligne http à voir si c’est de " " ou des {{ }}

Regarde rapidement ce que j’ai

Mes sliders (qui existent pour autre chose) ont des valeurs pas compatibles (ça fait plus que 255 au final) mais le principe est là

Ha merci pour l’éditeur de modèles dont je ne me sers jamais. En effet il y avait une erreur. Il manquait le states devant les inputs… Maintenant ça renvoie bien l’URL correctement. MAIS ça ne marche toujours pas haha ! J’essaie de bidouiller le light template.

Je n’arrive pas à le faire fonctionner. Dans l’éditeur de modèles il est bien noté :

Type de résultat: string

« http://192.168.1.15/h1color?value=0&red=0&green=0&blue=0 »

Ce modèle écoute les événements de changement d’état suivants:

  • Entité: input_number.h_input
  • Entité: input_number.s_input

Donc c’est comme si les entités ne renvoyaient rien.

Vérifie ce que ça contient

Les input_number n’apparaissent pas dedans, ce qui me semble plutot logique vu que c’est des entités « internes » qui ne sont pas ajoutables à Lovelace. J’ai essayé de créer un slider pour voir si ça réagissait et ça ne fait rien. Quand on regarde le template :

  - platform: template
    lights:
      horloge_murale:
        turn_on:
          service: rest_command.allumer_horloge
        turn_off:
          service: rest_command.eteindre_horloge
        icon_template: mdi:clock-digital
        set_level:
          service: rest_command.modifier_luminosite
          data:
            luminosite_horloge: "{{ brightness }}"
        set_color:
          - service: input_number.set_value
            data:
              value: "{{ h }}"
              entity_id: input_number.h_input
          - service: input_number.set_value
            data:
              value: "{{ s }}"
              entity_id: input_number.s_input

On peut voir que pour chaque changement de paramètre, le service correspondant de REST est appelé. Comme on fait actuellement, on appelle JAMAIS le service de changement de couleur. Le problème doit venir de la non ?

Enfin je dis ça mais même sans parler du service, les valeurs ne remontent pas non plus dans l’éditeur de modèles…

Tu conclues ça sur la quelle base ? Il y a pas d’entités internes ou externes.
Si tu déclares pas tes sliders ça existe nul part, et utilisable nul part non plus dans ton config, comme dans ton lovelace

Tu es partie loin… H, S ça existe pas non plus …

Non, c’est plus parce que ça n’a pas de sens pour HA pour l’instant.

Donc pour tester :

  1. Tu créer tes 3 inputs H, S et V en yaml
  2. Tu trouves les bornes associés
  3. Tu les ajoutes dans lovelace
  4. Tu regarde ce que ça fait dans les outils de dev (pour vérifier que ça donne des trucs cohérents sur l’url

On verra le reste après

J’ai créé les 3 sliders et je les ai ajoutés à Lovelace. Lorsque je modifie leur valeur, l’éditeur de modèles réagit bien. Cependant, aucun effet sur l’horloge. L’URL n’est pas envoyée.

Déclenche l’appel REST avec les outils dev dans un premier temps