Lovelace: Custom Hue Slider

THIS: image

I’ve just begun buying RGB LED bulbs for my HA installation and have ZHA up and running with my Conbee II dongle and several Philips Hue bulbs (and a Go). Having never used scenes, I considered several approaches over the period of a few days to figure out how I wanted to control them. I put two in my living room and wanted to control them both individually and as a group. I played with creating scenes. Then tried using scripts triggered by buttons on the UI to toggle the lights with the correct parameters. I tried using Button cards and Custom-Button cards, but they behaved differently depending upon whether I used the tap-action to call a script or a service, like scene.apply. I tried activating pre-created scenes, but also tried putting everything in the card itself as service-data to the on-the-fly scene.apply service call, trying to find what felt right.

After getting several approaches to work, I set out to create a card that allowed me to set a Warm and a Cool scene using buttons that didn’t toggle the lights on/off. I also wanted a separate switch that could be used just turn the group off or on. Then I thought it would be nice to be able to define a color scene on-the-fly where I would define the Hue, Saturation, and Brightness through inputs, and press a button to set a scene based upon those inputs.

The card I came up with is shown below. All four icons (i.e., the three buttons, and the icon for the switch), all match the current color. When the lights are off, the icons change to the -outline version of the icon.

image

I soon realized that setting the Hue was not trivial unless I memorized the numbers for the primary and secondary colors from the color wheel to determine the color I wanted. I thought that a Hue Slider which has a background that was color-number accurate representation of the color wheel would be a really cool feature So I set out to find one. Hmm… nothing.

I began thinking about how I could set a background on the slider using a GIF I created in Photoshop. Then I discovered that CSS has a background-image tag that lets you apply a linear gradient and define the colors! The trick, then, would be to get Lovelace to put it where I wanted it. That process took several days, but I FINALLY was able to do it using Thomas Loven’s Card-Mod. It took me a while to finally get the right selectors figured out, but the resulting code is surgical in its effect and extremely brief. The following code added to the entity row in the entities card for the Hue slider created just the effect I was looking for:

card_mod:
  style: 
    "ha-slider$ paper-progress$": |
        div#progressContainer {
          background-image: linear-gradient(to right,red,yellow,green,cyan,blue,magenta,red);
          --paper-progress-active-color: none;
        }

This changes the previous Hue Slider to that shown below. Gotta love Home Assistant and all the cool, smart people who make creating things like this so easy! Of course, this could break with any future UI update, but it would now be trivial to figure out how to change the above to make it work again. I can live with that!

image

4 Likes

Awesome, i will use this on my new dashboard :slight_smile:

So, I’ve expanded this after realizing that, in my excitement, I limited myself to only setting color via the Hue/Saturation mode, and not by Color Temperature. So I added another slider with a custom background to match the Color Temp slider in the standard light entity card, along with an input_boolean to determine which input to use.

It works perfectly, except that I could not figure out how to do it all within the Button Card itself, so had to move the logic to a Script and call the Script instead when clicking the Custom button at bottom right.

I also combined my individual Hue lights into this v-stack, and moved it along with my other light stack to its own tab in the UI. The new card looks like this:

I wish we could format number values in standard entity rows on the entity card, so I may try to replace these with Thomas Loven’s Slider Entity Row to gain more control over formatting.

.

Well, HECK! That was easy! I added the following line to every slider-input entity row in the v-stack (the topmost entities card), and got exactly what I wanted, with an even LONGER slider, and the numbers were automagically formatted as one would typically expect them to be.

- type: custom:slider-entity-row

image

Thanks AGAIN, @thomasloven !

1 Like

Hi GrizzlyAK,

Great job!
Just wondering how you get the actual settings for the bulb hue/sat/bri into the entity to the right?
And then how each slider changes the specific setting.

Is it the input_number.light_entity_goes_here ?
Can´t figure it out.

Thanks!

I think you mean the flag "hide_state: false/true.

        - type: custom:slider-entity-row
          entity: light.living_room
          name: custom name
          toggle: false
          full-row: true
          hide_state: true

For actually changing the values, I use an automation which detects a state change of the slider and then applies the right color/brightness to the light.

An example on how to change the actual color with an automation:
This is the input slider (in input_number.yaml) for the hue (color)

light_livingroom_color:
  name: "Color Light Living Room"
  min: 0
  max: 360
  step: 5
  icon: mdi:palette
  mode: slider

See here: Light in Home Assistant
I’ll be using the hs_color value for the light (0-360)

In the automation (automations.yaml):

- alias: change_color_livingroom
  trigger:
    - platform: state
      entity_id: input_number.light_livingroom_color
  action:
    - service: light.turn_on
      data_template:
        entity_id: light.livingroom
        hs_color: ["{{ trigger.to_state.state | int }}", "{{ state_attr('light.livingroom', 'hs_color')[1]}}"]

In this case, the automation will change the color of the light, but keep the current saturation: ‘hs_color’)[1] refers to the second number in the hs_color attribute which is saturation. The first one is color.
You do exactly the same for the saturation slider but instead of [1] you use [0] to get the current value of color and you only change the saturation to the new value that was chosen (and which triggered the automation).

Hi, yes, they are input_numbers as defined in configuration.yaml as below:

  lr_accent_hue_in:
    name: Living Room Accent Hue (IN)
    mode: slider
    min: 0
    max: 360
    step: 1

  lr_accent_saturation_in:
    name: Living Room Accent Saturation (IN)
    mode: slider
    min: 0
    max: 100
    step: 1

  lr_accent_brightness_in:
    name: Living Room Accent Brightness (IN)
    mode: slider
    min: 0
    max: 100
    step: 1
 
  lr_accent_color_temp_in:  # unit_of_measurement: "mireds"
    name: Living Room Accent Color Temperature (IN)
    mode: slider
    min: 153
    max: 500
    step: 1

Note that I changed the Brightness to use brightness_pct instead of brightness, allowing me to use the more easily-used 0-100% range vs 0-255. I also added a slider control that sets the transition time for color changes.

I’ve also made a few other changes to this feature to allow me to define and activate a custom color loop. The Hue default is much too fast and colors are not under your control. I wanted something that I could control as well as how fast it ran. This is done with a switch and an input_select to select the color set to use in the loop. This is done in an automation (still working out the finer details). Maybe I’ll do another post on the entire setup once I get it finalized (whatever THAT means in HA!). The automation utilizes the Saturation, Brightness and Transition values set in the sliders above (dual use!). Here’s the current card:
image

The code for the card itself is pretty straightforward. Note the use of both card-mod and slider-entity-row.

type: entities
entities:
  - type: custom:slider-entity-row
    entity: input_number.lr_accent_hue_in
    name: Hue
    card_mod:
      style:
        ha-slider$ paper-progress$: |
          div#progressContainer {
            background-image: linear-gradient(to right,red,yellow,green,cyan,blue,magenta,red);
            --paper-progress-active-color: none;
          }
  - type: custom:slider-entity-row
    entity: input_number.lr_accent_saturation_in
    name: Saturation
  - type: custom:slider-entity-row
    entity: input_number.lr_accent_brightness_in
    name: Brightness
  - type: custom:slider-entity-row
    entity: input_number.lr_accent_color_temp_in
    name: Color Temp
    card_mod:
      style:
        ha-slider$ paper-progress$: |
          div#progressContainer {
            background-image: linear-gradient(to right,rgb(100,180,255),rgb(255,255,255),rgb(255,136,13));
            --paper-progress-active-color: none;
          }
  - entity: input_boolean.enable_color_temp_ib
    name: Use Color Temp
  - entity: input_number.hue_light_transition_time_in
    name: Transition Time (s)
  - entity: input_select.hue_color_loop_is
  - entity: input_boolean.hue_color_loop_ib
title: Custom Settings
show_header_toggle: false

Here is the script called by the big Custom button shown at bottom right in the original post image which uses the values from the sliders (i.e., input_numbers) and input_boolean.

   # Set Custom Hue Light parameters
  set_custom_hue_light_params_scr:
    alias: Set Custom Hue Light Parameters (SCR)
    mode: queued
    sequence:
      - choose:
          conditions: "{{ is_state('input_boolean.enable_color_temp_ib', 'on') }}"
          sequence:
            - alias: Color Temp Mode
              service: scene.apply
              data:
                entities:
                  light.hue_lr_lights_lgrp:
                    brightness_pct: "{{ states('input_number.lr_accent_brightness_in') | float }}"
                    color_temp: "{{ states('input_number.lr_accent_color_temp_in') | float }}"
                    state: 'on'
                    transition: "{{ states('input_number.hue_light_transition_time_in') }}"
        default:
          - alias: HS Mode
            service: scene.apply
            data:
              entities:
                light.hue_lr_lights_lgrp:
                  brightness_pct: "{{ states('input_number.lr_accent_brightness_in') | float }}"
                  hs_color:
                    - "{{ states('input_number.lr_accent_hue_in') | float }}"
                    - "{{ states('input_number.lr_accent_saturation_in') | float }}"
                  state: 'on'
                  transition: "{{ states('input_number.hue_light_transition_time_in') }}"

Note that I do get a warning in the logs that both transition and brightness_pct are deprecated. I’m trying to sort that out, since this is a scene.apply service call, but the data is for a light entity, where these two values are perfectly legal atm.

Hope that helps!

Hmm… That’s an interesting approach. You’ve eliminated the need to press a button. Although you could potentially miss a trigger if you change things too quickly with different sliders if your network is sluggish. Adding a mode: queued to your automation would remedy that, tho, I think.

I’ve also added a button that sets the custom sliders to whatever values the current light group has at the time. This way, I can use the built-in color wheel or color temperature popup to play with hue, saturation, brightness, and once I get it where I want it, I can press this button and the sliders are all set to those values, and can be read off for easy reference (something you can’t do with the color-wheel, unless you look at the state in Dev Tools), or use with the Custom button. That script is here and works whether you use the color-wheel or the color temp option in the built-in color popup:

  # Set Custom Input to Current Color
  set_custom_input_to_current_color_scr:
    alias: Set Custom Input to Current Color (SCR)
    mode: single
    sequence:
      - service: input_number.set_value
        entity_id: input_number.lr_accent_hue_in
        data:
          value: "{{ states.light.hue_lr_lights_lgrp.attributes.hs_color[0] | int }}"
      - service: input_number.set_value
        entity_id: input_number.lr_accent_saturation_in
        data:
          value: "{{ states.light.hue_lr_lights_lgrp.attributes.hs_color[1] | int }}"
      - service: input_number.set_value
        entity_id: input_number.lr_accent_brightness_in
        data:
          value: "{{ ((states.light.hue_lr_lights_lgrp.attributes.brightness)*100/255) | int }}"
      - choose:
          conditions: "{{ state_attr('light.hue_lr_lights_lgrp','color_temp') != None }}"
          sequence:
            - service: input_number.set_value
              entity_id: input_number.lr_accent_color_temp_in
              data:
                value: "{{ states.light.hue_lr_lights_lgrp.attributes.color_temp | int }}"
            - service: homeassistant.turn_on
              entity_id: input_boolean.enable_color_temp_ib
        default:
          - service: homeassistant.turn_off
            entity_id: input_boolean.enable_color_temp_ib

Thank you @GrizzlyAK , very interesting idea. I haven’t encountered any issues yet, but as soon as I see this happening I already know where to look! :ok_hand:

Very minor observation: For the colour temperature, at least for my Phillips Hue white ambiance lights, the gradient Home Assistant uses in its UI (when you long-tap the light) was slightly different to yours. I took your idea but used the same colours as Home Assistant does:

background-image: linear-gradient(to right,rgb(166,209,255),rgb(255,255,255),rgb(255,160,0));

The difference is subtle


vs

(yours is the top one; it’s slightly more blue at the start of the range and slightly more orange at the end of the range)

1 Like

Nice! I was eyeballing it, but I will go back and add your values to my setup. Thanks!

I know it’s an old topic, but has anyone done this with a custom:slider-entity-row that is a custom field inside a custom:button-card? I’ve been staring at my web inspector for hours and tried a bunch of different iterations and nothing ever happens.
Thanks in advance!

  - type: custom:button-card
    icon: mdi:knob
    size: 35%
    template: vol_slider
    custom_fields:
      slider:
        card:
          full_row: true
          hide_state: true
          type: custom:slider-entity-row
          entity: input_number.mini_vol_slider
          card_mod:
            style:
              ha-slider$ paper-progress$: |
                div#progressContainer {
                  background-image: linear-gradient(to right,red,yellow,green,cyan,blue,magenta,red);
                  --paper-progress-active-color: none;
                }

This card mod seems to be broken? Per today I noticed the background bar is white again, without the gradient. Anyone else having this issue?

I just checked mine (still on 2023.10.3) and it is OK. I’ll update and see if it breaks. May have to update the select if something changed.

Did you ever get this to work? I’ll take a look at it if you didn’t.

You are correct. This is now broken in 2023.11. I’ll see if I can determine the cause.

@thomasloven, I just updated the card-mod.js file on my system with the latest, hoping that would solve the issue here, but no joy. It appears the code used to generate these sliders has changed in the HA frontend which has broken this particular card-mod instance (replacing a background image on a slider). I was hoping just the select was wrong, which may still be the case. Would you have any off-the-cuff ideas where to start looking to track this down to repair it, or has changes to the front end made this change impossible? I think I’m going to revert to 2023.10.3 and study the code to see if I can find the changes. Greatly appreciate any help. Cheers.

OK, so it looks like some serious changes were made to the FrontEnd in 2023.11. I’ve made some progress fixing the hue slider to work in this version. The only thing I notice is if you shrink the browser page horizontally, these card-modded sliders don’t scale exactly the same as the default ones do,

However, NONE of the custom-slider-entity-row elements work on the iOS HA app anymore. Is anybody using this custom element any more or has the default HA improved and everyone started using it?

Here is the Hue slider change I found that works. It’s a hack at this point. Perhaps Thomas knows why this no longer works on iOS and has any ideas on how to make my card-mod hack better.

NOTE: Substitute the last line for the background-image for the Color Temp slider version (if you use it).

        card_mod:
          style:
            ha-slider$: |
              div.track::after {
                background: none; 
              }
              div.track::before {
                background: none;
              }
              div.track {
                background-image: linear-gradient(to right,red,yellow,green,cyan,blue,magenta,red);
                height: 10%;
                width: 80%;
                margin-left: 18px;
                margin-top: 18px;
              }

                background-image: linear-gradient(to right,rgb(100,180,255),rgb(255,255,255),rgb(255,136,13));

With some apologies for my late answer.
Thanks a lot for jumping into this matter. Yes I did had it working and use it (in Chrome and on android app).

I did a quick check, but did not manage to got it working? I will check on later when I can spent some more time on it…

(…)

With @GrizzlyAK’s hint I could not make it work as I would like to. Nevertheless with tweaking (and I don’t know whether I’m doing anything correct or wrong here (to noob for my own good)) in the Inspecion window I can manage to recreate the color gradient. In div.track::before. But I am not able (too short knowledge, I’m sorry) to get this back into the card-mod.

Hi, I haven’t tested it again since I reverted back until it gets sorted. It has been worked, and perhaps resolved completely. Also, I think Thomas may have added this gradient background natively in his slider-entity-row a while back. Please see this post for more information. It may help. I’ll probably upgrade soon and see how things go. Cheers.