Stepwise dimming macros

It might be different in the US but here in Europe there are no in-wall rotary controllers available, so I’m resorting to up/down wall switches.

On each button press it will switch to the next brightness level. To simplify my automations, I have created some helpful macros:

Macros
{% macro brightness_pct(entity) %}
  {{ ((state_attr(entity, 'brightness') if is_state(entity, 'on') else 0) / 255 * 100)|round() }}
{% endmacro %}

{% macro next_multiple(input, step, direction) %}
  {% if direction == 'up' %}
    {{ ((input + 1) / step)|round(0, 'ceil') * step }}
  {% endif %}
  {% if direction == 'down' %}
    {{ ((input - 1) / step)|round(0, 'floor') * step }}
  {% endif %}
{% endmacro %}

{% macro next_step(input, steps, direction) %}
  {% if direction == 'up' %}
    {% set end = steps|max %}
    {% set steps = steps|sort(reverse=false)|select("greaterthan", input)|list %}
  {% endif %}
  {% if direction == 'down' %}
  {% set end = steps|min %}
    {% set steps = steps|sort(reverse=true)|select("lessthan", input)|list %}
  {% endif %}
  {{ steps|first if steps|length > 0 else end }}
{% endmacro %}

Installation

Copy the macros to a file in your custom templates directory, like config/custom_templates/stepwise_dimming.jinja, then restart Home Assistant.

Usage

Create an automation that is triggered by the up/down buttons. You can use this action as a starting point:

Complete example action
choose:
  - conditions:
      - condition: trigger
        id:
          - up
    sequence:
      - service: light.turn_on
        data:
          brightness_pct: >-
            {% from 'stepwise_dimming.jinja' import brightness_pct, next_step %}
            {{ next_step(brightness_pct('light.bulb_office_andre')|int, [0, 25,75, 100], 'up') }}
        target:
          entity_id: light.bulb_office_andre
  - conditions:
      - condition: trigger
        id:
          - down
    sequence:
      - service: light.turn_on
        data:
          brightness_pct: >-
            {% from 'stepwise_dimming.jinja' import brightness_pct, next_step %}
            {{ next_step(brightness_pct('light.bulb_office_andre')|int, [0, 25, 75, 100], 'down') }}
        target:
          entity_id: light.bulb_office_andre

Then set brightness_pct according to these examples:

Fixed steps
To set the available brightness levels to 0, 25, 75 and 100 %, use:

{% from 'stepwise_dimming.jinja' import brightness_pct, next_step %}
{{ next_step(brightness_pct('light.bulb_office_andre')|int, [0, 25, 75, 100], 'up') }}

Regular steps (multiples of 10)
To set the available brightness levels to 0, 10, 20, …, 90, 100 %, use:

{% from 'stepwise_dimming.jinja' import brightness_pct, next_multiple %}
{{ next_multiple(brightness_pct('light.bulb_office_andre')|int, 10, 'up') }}

Piecewise regular steps
To set the available brightness levels to 0, 5, 10, 20, 30, 40, 50, 60, 80, 100 %, use:

{% from 'stepwise_dimming.jinja' import next_multiple %}
{% set input_pct = brightness_pct('light.virtual_bedroom_light')|int %}
{% if input_pct >= 60 %} {{ next_multiple(input_pct, 20, 'up') }}
{% elif input_pct >= 10 %} {{ next_multiple(input_pct, 10, 'up') }}
{% else %} {{ next_multiple(input_pct, 5, 'up') }}
{% endif %}
2 Likes

This looks awesome.
Did you know you can put custom templates into HACS now? Check out the experimental mode…

I did not. I considered making a custom component like Lightener but it seemed too much work given that copying a couple of lines isn’t too bad as installation procedure. But if a custom template is easier, I might just do that.

Those are custom templates. I have 3 in the links below my message as examples and they are distributed thru HACS templates in experimental mode. Experimental mode will soon be the default mode, BTW…