Updating input_number after physical dimmer use

I am using a bunch of GE Z-Wave Plus dimmers like I have seen so many others use on here but I am having a problem configuring the UI properly for some reason. Right now I have a switch in the UI to turn the light on or off. I also have an input_number that I can use to set the brightness of the light and that runs on a scale of 0-100% instead of the normal 0-255. This all works great but if you physically use the dimmer, the input_number in the UI isn’t updated. I created an automation to do this but later realized that if you just click the dimmer to turn it off, it dims instead of just going out. This causes my input number to update -10% from what it was, then the input number change updates the state of the light and stops it from turning off. You have to click down on the switch until brightness=0% then it shuts off, or click and hold so it dims off. How has everyone handled updating the slider state with their dimmers?

My code:
input_number.yaml

main_light_slider:
  min: 0
  max:100
  step: 5

sensors.yaml

- platform: template
  sensors:
    main_light_level:
      value_template: '{{ states.light.main_lights_17.attributes.brightness | int / 2.55 }}'
      unit_of_measurement: '%'

fr_automations.yaml

- alias: 'Adjust lights on input'
  hide_entity: True
  trigger:
    - platform: state
      entity_id: input_number.main_light_slider
  action:
    - service: light.turn_on
      data_template:
        entity_id: light.main_lights_17
        brightness_pct: '{{ trigger.to_state.state }}'

- alias: 'Update light slider status'
  trigger:
    - platform: state
      entity_id: light.main_lights_17
  action:
    - service: input_number.set_value
      data_template:
      entity_id: input_number.main_light_slider
      value: '{{ states.sensor.main_light_level.state }}'

I know exactly why manually clicking the switch isn’t working, I am just not able to wrap my head around how to make this work when the switch dims as it turns off. Basically when you turn it on it just resumes the previous brightness, thats great. If I turn it off it dims to off instead of turning off. This causes it to report continually changing brightness numbers until the lights are actually off which triggers my update automation, which then triggers my “input_number has changed vale, let the light know!” automation which halts the dim to off process. Thanks!

Without digging into all those details, my gut reaction is, why go through all this trouble? The UI already has a slider to set the brightness of the dimmer:

image

1 Like

The reason I was going through the trouble is because I didn’t want to click on the entity and wait for the popup to load. Some of the devices I use have very small screens so the icon is all that shows other than the button, making clicking one and not the other very difficult :frowning:

Ok, fair enough.

So, when you say you "have a switch in the UI to turn the light on or off’, do you mean light.main_lights_17 itself? Or do you mean you have an input_boolean? I’ll assume the former for the rest of this reply. Let me know if I assumed incorrectly.

Let’s start with updating input_number.main_light_slider. I think this might work for you:

- alias: Update slider per light
  trigger:
    platform: state
    entity_id: light.main_lights_17
  action:
    service: input_number.set_value
    entity_id: input_number.main_light_slider
    date_template:
      value: >
        {% if trigger.to_state.state == 'on' %}
          {{ (trigger.to_state.attributes.brightness / 12.75) | round * 5 }}
        {% else %}
          0
        {% endif %}

Note that I’m forcing the input_number’s value to be multiples of 5 (i.e., rounding to the nearest 5%), to match the step value you have configured for the input_number.

Now, let’s look at going the other way. One issue you have is the input_number can go all the way to zero, and many (if not all) lights don’t like being turned “on” to a brightness of zero. So if the input_number goes to zero, you really should be turning the light off. This is probably most easily done with two automations:

- alias: Update light per slider above zero
  trigger:
    platform: numeric_state
    entity_id: input_number.main_light_slider
    above: 0
  action:
    service: light.turn_on
    entity_id: light.main_lights_17
    data_template:
      brightness_pct: "{{ trigger.to_state.state }}"
- alias: Update light per slider at zero
  trigger:
    platform: template
    value_template: "{{ states('input_number.main_light_slider') | int == 0 }}"
  action:
    service: light.turn_off
    entity_id: light.main_lights_17

Note that the docs for the numeric_state trigger says that it will only trigger when the entity’s value “crosses the threshold” - i.e., for above, it only triggers when the value goes from the specified value or below to above the specified value. This is not how it works.When specifying an above value, it will trigger whenever the entity’s state changes and it’s new value is above the value specified, even if it was above that value before. (I actually just figured this out today.)

Anyway, for the second automation, I use a template trigger to check when the input_number has gone all the way to zero. In theory I could have used another numeric_state trigger, say, with below: 5, but I thought this would be more robust.

Lastly, since you have a closed loop, you have to worry about feedback - i.e., you change input_number via the UI, which updates the light, which then updates the input_number. If this isn’t written correctly, it’s possible these automations can cause an infinite loop. I don’t think that will happen here, but if it does, you might need to tweak them a bit.

Another caveat: I’m not sure if the first automation (updating the slider per light) will actually work when the light is turned off. Even though in that case the template shouldn’t try to use the light’s brightness attribute, it’s possible the template rendering code might not be that smart. If this causes errors, let me know and I can turn it into two automations that are sure to work.

Alright, so I just pasted everything in to replace my current code, and I still have the same problem I had before… a bit of additional background though:

The “Light switch” I have is the light.entityname and not some input boolean or something else. In my groups.yaml file I have (pseudocode, definitely wouldnt work)

family room:
  - light.main_lights_17
  - input_number.main_light_slider

The way these switches work, they turn off by setting the brightness to ‘0’. When you click the off button in the vera or the HASS UI you can watch the brightness go to 0, I don’t see an attribute in my vera controller for on/off, just for brightness and some other settings I don’t use. This means that when I set the slider in the homeassistant UI to 0 the lights “virtual switch” changes to off in home assistant.

Another thing to note, the way my automatons were set up that I included above, if you set the minimum value of input_number to anything above 0, when you turn off the light and the HASS interface updates, the input_number forces the ‘0’ value to its minimum and turns the light back on making it impossible to turn off without actually physically cutting power to it.

What works perfectly:
Turning on physically at the switch
Increasing brightness at the switch by holding up
Decreasing brightness at the switch by holding down
Turning the light on and off in the HASS interface
Adjusting the brightness using the HASS interface

What is broken:
Turning off the light using the physical switch

Why is this happening:
When you turn the lights off using the physical switch you get a race condition as follows (assuming the brightness is 100% when you click down to turn off). The switch decreases brightness a value of 5 (0-255) at a time over 3 seconds until brightness reaches 0.

(the same numbers below would happen concurrently)

Switch (actually at the vera but same dfference):

  1. decrease to 250 from 255
  2. decrease 5 more to 245
  3. decreases 5 more to 240
  4. Received brightness=250 from HASS and sets that as new value, canceling lights turning off by dimming out (this is nonconfigurable, they will ALWAYS dim to off).

HASS:

  1. Waiting for brightness change to update input_number
  2. sees 250 from 255 and updates input_number (Update slider per light in your code or Update light slider status in mine)
  3. sees 245 from 255 and updates input_number again, all while triggering “Adjust lights on input” from my code or “Update light per slider above zero” from your code because step 2 above changed the input_number to 250 from 255. This sets the lights back to 250 again.
  4. sees 250 from light, which matches slider and stops executing again.

Each time you click the off button on the switch, the lights dim by 10 to 20, depending on the network latency, homeassistant then sets ot 5 below the starting point, so the lights “dip” as they try to turn off, then come back up one brightness level below where they started. If you keep clicking off they will eventually turn off, but thats wrong. Dimming to off by holding it works fine though. So yours handles several issues that I should probably be cleaner about, but has the same flaw as my code…

Well, that’s basically the feedback I was talking about, except I didn’t consider the exact mechanism you explained now in more detail.

FWIW, I also have GE Z-Wave Dimmers (both plug-ins, one the newer Z-Wave Plus, and the other is older and not Z-Wave Plus.) But in my case I’m using an Aeotec Z-wave controller, so I guess in my case there’s a more direct connection between HA and the dimmers.

In any case, you need a way to break the feedback loop. One possibility is to use a timer and an input_boolean. E.g., when one of the automations triggers, the first thing it does is to start the timer and set the input_boolean. (The input_boolean will basically indicate which “direction” we’re going - light to slider, or slider to light.) Then all the automations will have a condition that only let’s them fire if the timer is idle, or the input_boolean is in the “same” direction. So, e.g., you physically change the dimmer. That causes a “light to slider” automation to run (because the timer is idle.) That automation starts the timer and sets the input_boolean in the “light to slider” direction. It then updates the slider. Normally that would trigger the “slider to light” automation, but now, with the added condition, that automation won’t run. Eventually the light stops changing, and the timer finishes and becomes idle. Now you change the slider. Basically the same happens, but now the input_boolean is the “other way.”

Haven’t really tried any of that, but I suppose it has the potential to ultimately resolve the problem.

Now, having said all that, honestly, I’d skip the whole thing and only use the input_number to update the actual light, and not bother with the feedback in the other direction. Sure, you won’t (easily) be able to see the brightness level from HA, but do you really need to? You could just use the template sensor you had originally defined for that. Worst trade-off then would be you update the input_number to change the light brightness and since the input_number hadn’t been updated, the light brightness might “jump.”

BTW, I stand corrected. I was under the impression that you couldn’t “turn on” a light to zero. Apparently you can, which effectively turns it off. I still think, though, that some lights won’t accept that, but if it works for z-wave dimmers, then that’s all that matters in this case.

Warming up this old question: I have a similar problem. Did you guys ever solve it?

Main goal: have the physical switch return the dimmer to the previous dim level instead of turning on at 100%, so:

  • on = old dim level of x
  • off = dim level of 0

As a bonus, this would work the same on the interface, i.e. toggle on would not be 100% but x