Template light limit maximum and minimum brightness of light

Hi, so firstly I know this is a super janky, but I’m out of ideas…

I have Aurora Aone Zigbee Rotary dimmers, and my LED bulbs flicker intermittently when above 65% (166) brightness.

I’ve tried using different bulbs, various dimmer bypass devices. I’ve considered a dummy load resistor but they’re just too large. Basically i haven’t found a practical hardware solution and it’s not for a lack of trying.

I already have an automation to limit the brightness to 65% which prevents the flickering. Now what I’d like to do is create a template light so that the sliders I use to control my lights in Lovelace and in Homekit run to 100% rather than being capped at 65%.
Hope that makes sense, I can’t find any practical examples of this.

light:
  - platform: template
    lights:
      hallway_pendant:
        value_template: >-
          {% if is_state('light.hallway_pendant_deconz', 'on') %}
            on
          {% elif is_state('light.hallway_pendant_deconz', 'off') %}
            off
          {% else %}
            unknown
          {% endif %}
        turn_on:
          service: light.turn_on
          data:
            entity_id: light.hallway_pendant_deconz
        turn_off:
          service: light.turn_off
          data:
            entity_id: light.hallway_pendant_deconz
        level_template: >-
???
1 Like

You actually want to constrain the set_level, not the light_template.

Your level_template simply grabs the level from the other light. This method truncates at 65% but the light range is still 0 to 100%. You just can’t set it above 65%.

level_template: "{{ state_attr('light.hallway_pendant_deconz', 'brightness') }}"
set_level:
  service: light.turn_on
  data_template:
    brightness: "{{ brightness if brightness < 0.65*255 else 0.65*255 }}"

EDIT: Unless you want 65% to be 100% on your fake light…

This method translates the range 0 to 65% of the original light to 0 to 100% on the fake light.

level_template: "{{ state_attr('light.hallway_pendant_deconz', 'brightness') | float / 0.65 }}"
set_level:
  service: light.turn_on
  data_template:
    brightness: "{{ brightness * 0.65 }}"
2 Likes

Yes that’s exactly what I’m looking to do. I want 65% to be 100% on the fake light.

Here’s the code that I have now:

- platform: template
  lights:
    hallway_pendant:
      value_template: >-
        {% if is_state('light.hallway_pendant_deconz', 'on') %}
          on
        {% elif is_state('light.hallway_pendant_deconz', 'off') %}
          off
        {% else %}
          unknown
        {% endif %}
      turn_on:
        service: light.turn_on
        data:
          entity_id: light.hallway_pendant_deconz
      turn_off:
        service: light.turn_off
        data:
          entity_id: light.hallway_pendant_deconz
      level_template: "{{ state_attr('light.hallway_pendant_deconz', 'brightness') | float / 0.65 }}"
      set_level:
        service: light.turn_on
        data_template:
          brightness: "{{ brightness * 0.65 }}"

I also tried:

      set_level:
        service: light.turn_on
        data_template:
          entity_id: light.hallway_pendant_deconz
          brightness: "{{ brightness * 0.65 }}"

I can turn the fake template light on and off (and this turns the real light on and off) however the fake light isn’t correctly showing the level and the level cannot be set using the fake light.

Here are the errors I’m getting:

Logger: homeassistant.helpers.script.hallway_pendant
Source: helpers/script.py:1122 
First occurred: 13:45:33 (10 occurrences) 
Last logged: 13:48:15

hallway_pendant: Error executing script. Invalid data for call_service at pos 1: expected int for dictionary value @ data['brightness']


Logger: homeassistant.components.websocket_api.http.connection.547449866560
Source: core.py:1402 
Integration: Home Assistant WebSocket API ([documentation](https://www.home-assistant.io/integrations/websocket_api), [issues](https://github.com/home-assistant/home-assistant/issues?q=is%3Aissue+is%3Aopen+label%3A%22integration%3A+websocket_api%22)) 
First occurred: 13:45:33 (8 occurrences) 
Last logged: 13:45:48

expected int for dictionary value @ data['brightness']

Traceback (most recent call last): File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 135, in handle_call_service await hass.services.async_call( File "/usr/src/homeassistant/homeassistant/core.py", line 1448, in async_call task.result() File "/usr/src/homeassistant/homeassistant/core.py", line 1483, in _execute_service await handler.job.target(service_call) File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 204, in handle_service await self.hass.helpers.service.entity_service_call( File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 482, in entity_service_call future.result() # pop exception if have File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 664, in async_request_call await coro File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 519, in _handle_entity_call await result File "/usr/src/homeassistant/homeassistant/components/light/__init__.py", line 249, in async_handle_light_on_service await light.async_turn_on(**params) File "/usr/src/homeassistant/homeassistant/components/template/light.py", line 332, in async_turn_on await self._level_script.async_run( File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1010, in async_run await asyncio.shield(run.async_run()) File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 245, in async_run await self._async_step(log_exceptions=False) File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 253, in _async_step await getattr( File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 460, in _async_call_service_step await service_task File "/usr/src/homeassistant/homeassistant/core.py", line 1402, in async_call processed_data = handler.schema(service_data) File "/usr/local/lib/python3.8/site-packages/voluptuous/validators.py", line 218, in __call__ return self._exec((Schema(val) for val in self.validators), v) File "/usr/local/lib/python3.8/site-packages/voluptuous/validators.py", line 340, in _exec raise e if self.msg is None else AllInvalid(self.msg, path=path) File "/usr/local/lib/python3.8/site-packages/voluptuous/validators.py", line 336, in _exec v = func(v) File "/usr/local/lib/python3.8/site-packages/voluptuous/schema_builder.py", line 272, in __call__ return self._compiled([], data) File "/usr/local/lib/python3.8/site-packages/voluptuous/validators.py", line 215, in _run return self._exec(self._compiled, value, path) File "/usr/local/lib/python3.8/site-packages/voluptuous/validators.py", line 340, in _exec raise e if self.msg is None else AllInvalid(self.msg, path=path) File "/usr/local/lib/python3.8/site-packages/voluptuous/validators.py", line 338, in _exec v = func(path, v) File "/usr/local/lib/python3.8/site-packages/voluptuous/schema_builder.py", line 817, in validate_callable return schema(data) File "/usr/local/lib/python3.8/site-packages/voluptuous/schema_builder.py", line 272, in __call__ return self._compiled([], data) File "/usr/local/lib/python3.8/site-packages/voluptuous/schema_builder.py", line 594, in validate_dict return base_validate(path, iteritems(data), out) File "/usr/local/lib/python3.8/site-packages/voluptuous/schema_builder.py", line 432, in validate_mapping raise er.MultipleInvalid(errors) voluptuous.error.MultipleInvalid: expected int for dictionary value @ data['brightness']

might need to cast it as an int and if that doesn’t work, make a separate script.

      set_level:
        service: light.turn_on
        data_template:
          entity_id: light.hallway_pendant_deconz
          brightness: "{{ (brightness * 0.65) | int }}"

Thanks, that worked!

However I’ve noticed two problems. If I change the light level using the rotary dimmer knob, the fake light does not update to show the correct level/brightness.

Also when I restart Home Assistant (and the lights are on) the fake lights show up as on, but they have a level/brightness of 0.

does the light.hallway_pendant_deconz have a brightness attribute?

Really appreciate your help with this, sorry for taking up so much of your time.

Yes light.hallway_pendant_deconz does have a brightness attribute, and weirdly light.hallway_pendant does not.


Here’s my full yaml for the fake light, just in case there’s something wrong here:

- platform: template
  lights:

# Hallway
    hallway_pendant:
      value_template: >-
        {% if is_state('light.hallway_pendant_deconz', 'on') %}
          on
        {% elif is_state('light.hallway_pendant_deconz', 'off') %}
          off
        {% else %}
          unknown
        {% endif %}
      level_template: "{{ state_attr('light.hallway_pendant_deconz', 'brightness') | float / 0.65 }}"
      turn_on:
        service: light.turn_on
        data:
          entity_id: light.hallway_pendant_deconz
      turn_off:
        service: light.turn_off
        data:
          entity_id: light.hallway_pendant_deconz
      set_level:
        service: light.turn_on
        data_template:
          entity_id: light.hallway_pendant_deconz
          brightness: "{{ (brightness * 0.65) | int }}"

I also spotted this error in the logs:

Logger: homeassistant.components.template.light
Source: components/template/light.py:369 
Integration: template (documentation, issues) 
First occurred: 21:11:31 (4 occurrences) 
Last logged: 21:11:31

Template must supply an integer brightness from 0-255, or 'None'
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/template/light.py", line 369, in _update_brightness
    if 0 <= int(brightness) <= 255:
ValueError: invalid literal for int() with base 10: '165.0'

change the template to

      level_template: "{{ (state_attr('light.hallway_pendant_deconz', 'brightness') | float / 0.65) | int }}"

Sorry to bug you again, and please let me know if I should start a new thread for this.
So as I said the fake light works as it should.

100% brightness on the fake light is 65% brightness on the real light which has resolved the flickering issue.

I’ve since noticed that the real light only actually comes on when the brightness is at 30%. On the fake light this equates to around 50%.

We curtailed the maximum brightness on the fake light, how would adjust the template to make 30% on the real light 0% on the fake light?

You have to make an equation.

      level_template: >
        {% set b = state_attr('light.hallway_pendant_deconz', 'brightness') | float %}
        {{ (2.85714286 * b - 218.57142857) | int }}
      set_level:
        service: light.turn_on
        data_template:
          entity_id: light.hallway_pendant_deconz
          brightness: "{{ ((brightness + 218.57142857) / 2.85714286) | int }}"
1 Like

Great, and I’m sure this will work and I’ll test it out - but in the meantime I’d like to understand, how did you arrive at the figures:

2.85714286 and 218.57142857

…and what do they represent? I know that lights run from 0-255 in terms of brightness and I thought that they might represent 30% and 65% brightness on the real light?

30% of 255 is ~76.5
65% of 255 is ~165.75

So you want

  • 76.5 on your hardware to be 0 on your fake light
  • 165.75 on your hardware to be 255 on your fake light

That ends us with 2 points:

y x
0 76.5
255 165.75

So, fitting a line to that dataset (you can use any software, I used python but you can do it with a trendline in Excel). You end up with an equation

y = 2.85714286 * x - 218.57142857

where Y is the brightness on your fake light, and X is the brightness on your hardware.

That equation is used for the level_template. For setting the level, you need to reverse the equation in terms of X.

x  = (y + 218.57142857) / 2.85714286

Great, thank you. Appreciate you taking the time to explain this, I used this tool to rerun your math and calculate the trendline.

Great work here. I have exactly the same problem. When I change brightness with hardware button the brightness slider on a template changes to N/A. Did you found a solution for this?

Your light template is incorrect.

  - platform: template
    lights:
      salon_1:
        value_template: >-
          {% if is_state('light.salon_swiatlo1', 'on') %}
            on
          {% elif is_state('light.salon_swiatlo1', 'off') %}
            off
          {% else %}
            unknown
          {% endif %}
        turn_on:
          service: light.turn_on
          data:
            entity_id: light.salon_swiatlo1
        turn_off:
          service: light.turn_off
          data:
            entity_id: light.salon_swiatlo1
        level_template: >
          {% set b = state_attr('light.salon_swiatlo1', 'brightness') | float %}
          {{ (6.375 * b - 382.5) | int }}
        set_level:
          service: light.turn_on
          data_template:
            entity_id: light.salon_swiatlo1
            brightness: "{{ ((brightness + 382.5) / 6.375) | int }}"

I get this errors:

Logger: homeassistant.components.template.light
Source: components/template/light.py:520
Integration: Template (documentation, issues)
First occurred: 24 października 2021, 07:36:59 (72 occurrences)
Last logged: 24 października 2021, 20:39:49

  • Received invalid brightness : -76. Expected: 0-255
  • Received invalid brightness : -121. Expected: 0-255
  • Received invalid brightness : -57. Expected: 0-255
  • Received invalid brightness : 280. Expected: 0-255
  • Received invalid brightness : -382. Expected: 0-255

I updated my message with proper code.
Please let me know what is wrong.

The equation you’re using is returning the wrong value, that’s what the error is saying. So your equation is wrong, use a correct equation. And before you reply, I will not know the correct equation, that depends on your hardware.

Just wanted to provide one more bit of guidance on this issue as I had been struggling with it for a while in getting the proper equation. I have some zooz dimmers where in the zwave settings I set a min and max range, but it would not remap to a 0-100 scale in HA, so I needed to do everything in this thread to create a new light template. However, the Zooz lights do not necessarily utilize the simple math above. Instead of doing your own calculation of what is 30% of 255, go to developer tools–>template and plug in while setting your light to its min and its max, and use those values in the tool that @circa1665 links to.

{{state_attr('light.living_room_lights', 'brightness') | float(0.00)}}

Doing it this way for zooz lights ensured I was able to set the created light to 100% whereas utilizing what I thought was 65% of 255 would max out at 98% or something.

I find it hard to believe that Zooz has this problem in Zwave JS. Are you still using the old Zwave 1.4?