Level adjustment curves for dimmers

This is the first entry that comes up on Google when searching for how to change the dimming curve in Home Assistant, and yes, using a Template Light this is possible, so if anyone is interested here is some actual code.

  1. You need to be able to edit the configuration files, so have the VSCode add-on, or the SSH add-on or something else ready that allows you to do this.

  2. Make sure you add this line to your configuration.yaml:

    light: !include lights.yaml
    

    (Note: light is singular at the start, plural at the end)

  3. Create a new file called lights.yaml in the same folder as configuration.yaml, with the following content. You will need to replace some values with real ones first however:

    • TECHNICAL_NAME: your entity name in technical format (lowercase only, use underscores instead of space, etc)
    • FRIENDLY_NAME: your entity’s name in nice format
    • UNIQUE_ID: a random ID. You can use any online GUID generator, and remove the hyphens
    • ENTITY_NAME: the original light that you want to change the dimming curve on
    • MINIMUM_VALUE: the minimum brightness you want to allow. This will be mapped to the 1% setting. This value is between 1-255, so if you have a percentage, multiply it by 2.55. For example if the minimum brightness you want is 15%, put 15*2.55 = 38 here
    • EXPONENT: the steepness of the dimming curve. Larger values mean slower ramp-up, so the lower percentage values will be used more tha higher this number is. Use something between 1.5 and 5, with 3 giving a fairly okay result in my opinion.

    (Make sure to replace all of the occurences in the template below, before adding it to Home Assistant’s config. Also make sure you do a case sensitive search&replace)

    - platform: template
      lights:
        TECHNICAL_NAME:
          friendly_name: FRIENDLY_NAME
          unique_id: UNIQUE_ID
          value_template: "{{ is_state('ENTITY_NAME', 'on') }}"
          level_template: >
            {{
              min(255, max(3,
              (
                (
                  max(0, (
                    state_attr(
                    'ENTITY_NAME',
                    'brightness'
                    ) - MINIMUM_VALUE
                  ) / (255-MINIMUM_VALUE))
                ) ** (1 / EXPONENT)
              ) * 255
              )) | int
            }}
          turn_on:
            action: light.turn_on
            target:
              entity_id: ENTITY_NAME
          turn_off:
            action: light.turn_off
            target:
              entity_id: ENTITY_NAME
          set_level:
            action: light.turn_on
            target:
              entity_id: ENTITY_NAME
            data:
              brightness: >
                {{
                  min(255,
                    max(3,
                      MINIMUM_VALUE + (
                        (brightness / 255) ** EXPONENT
                      ) * (255-MINIMUM_VALUE)
                    )
                  ) | int
                }}
    

Here is a specific example:

  1. Updated the configuration.yaml. It now looks something like in the middle:

    automation: !include automations.yaml
    script: !include scripts.yaml
    scene: !include scenes.yaml
    light: !include lights.yaml
    
  2. Going to change the variables with the following substitutions:

    TECHNICAL_NAME: living_room_dimmed_light
    FRIENDLY_NAME: Living Room Light
    UNIQUE_ID: 9bea201bb2014901a66de1762942d0ac
    ENTITY_NAME: light.shelly_dimmer_living_room_light_0
    MINIMUM_VALUE: 100
    EXPONENT: 3
    
  3. The result is the following lights.yaml file:

    - platform: template
      lights:
        living_room_dimmed_light:
          friendly_name: Living Room Light
          unique_id: 9bea201bb2014901a66de1762942d0ac
          value_template: "{{ is_state('light.shelly_dimmer_living_room_light_0', 'on') }}"
          level_template: >
            {{
              min(255, max(3,
              (
                (
                  max(0, (
                    state_attr(
                    'light.shelly_dimmer_living_room_light_0',
                    'brightness'
                    ) - 100
                  ) / (255-100))
                ) ** (1 / 3)
              ) * 255
              )) | int
            }}
          turn_on:
            action: light.turn_on
            target:
              entity_id: light.shelly_dimmer_living_room_light_0
          turn_off:
            action: light.turn_off
            target:
              entity_id: light.shelly_dimmer_living_room_light_0
          set_level:
            action: light.turn_on
            target:
              entity_id: light.shelly_dimmer_living_room_light_0
            data:
              brightness: >
                {{
                  min(255,
                    max(3,
                      100 + (
                        (brightness / 255) ** 3
                      ) * (255-100)
                    )
                  ) | int
                }}
    
  4. Once this is setup I can use entity light.living_room_dimmed_light to control the original light (light.shelly_dimmer_living_room_light_0 with a proper dimming curve)

1 Like