Mqtt light dimming - Xiaomi button + ikea bulbs

Hi.

So, I’m having trouble figuring this out. have a Xiaomi switch (6-button) as a test device, and wanted to create a general dimming routine that I might copy in other places - but I’m having trouble getting it too 100% and staying above 0% in my calculations. And, also - I’m doubtful if my coding is the best way to do it (I’m betting it’s not).

So, in general - the Xiaomi switch reports button_x_action in general. IE. button_1_single for a single-press on the first button, starting from the top left, button_1_double for a doublepress, button_1_hold and button_1_release respectively for a button held and released.

So, I know what to listen for in mqtt and everything seems to be working - however, when it comes down to the math I would like it to input a maximum of 100% or a minimum of 1% brightness_pct. and I know my code doesn’t do that:


input_boolean:
  entre_occupancy_boolean:
    name: entre occupancy boolean
    icon: mdi:coat-rack

I use this boolean as a switch to tell whether there are people in the hallway (IE. entre in danish)

  brightness_dim:
    name: brightness dim

  brightness_bright:
    name: brightness bright

These two are switches to tell a loop in my automation to either continue brightening or dimming the lights.

template:
    - binary_sensor:
      - name: entre occupancy binary
        unique_id: entre_occupancy_binary
        state: >-
          {% set entre_occupancy_boolean = is_state('input_boolean.entre_occupancy_boolean','on') %}
          {{ entre_occupancy_boolean }}

I use this binary_sensor to generally allow various events to toggle whether there really is people in the hallway (IE. entre in danish). The general was to allow a movement_sensor or a switch or a door opening to turn the lights on/off. I’m sometimes making it more complicated than it should.


automation:
  - alias: entre turn on lights last state
    id: entre_turn_on_lights_last_state
    trigger:
      platform: state
      entity_id: sensor.foerste_lyskontakt_action
      to: 'button_1_single'
    action:
      - service: input_boolean.turn_on
        entity_id: input_boolean.entre_occupancy_boolean
      - service: light.turn_on
        data:
          entity_id: light.entre_lights

  - alias: entre turn on lights timeOfDay
    id: entre_turn_on_lights_timeOfDay
    trigger:
      platform: state
      entity_id: sensor.foerste_lyskontakt_action
      to: 'button_1_double'
    action:
      - service: input_boolean.turn_on
        entity_id: input_boolean.entre_occupancy_boolean
      - service: light.turn_on
        data:
          entity_id: light.entre_lights
          brightness_pct: >-
            {{ states('sensor.timeofday_desired_brightness') | int }}

fairly straight forward. I have two options - turn the light on, in it’s previous state - whatever the brightness-setting was. Or, set it to a specified brightness that changes depending on what time of day/night it is.



  - alias: entre lights turn off
    id: entre_lights_turn_off
    trigger:
      platform: state
      entity_id: sensor.foerste_lyskontakt_action
      to: 'button_2_single'
    action:
      - service: input_boolean.turn_off
        entity_id: input_boolean.entre_occupancy_boolean

The light turns off if the boolean-switch is toggled.

  - alias: entre light brightener on
    id: entre_light_brightener_on
    trigger:
      platform: state
      entity_id: sensor.foerste_lyskontakt_action
      to: 'button_1_hold'
    action:
      service: input_boolean.turn_on
      entity_id: input_boolean.brightness_bright

  - alias: entre light brightener off
    id: entre_light_brightener_off
    trigger:
      platform: state
      entity_id: sensor.foerste_lyskontakt_action
      to: 'button_1_release'
    action:
      service: input_boolean.turn_off
      entity_id: input_boolean.brightness_bright

  - alias: entre light dim on
    id: entre_light_dim_on
    trigger:
      platform: state
      entity_id: sensor.foerste_lyskontakt_action
      to: 'button_2_hold'
    action:
      service: input_boolean.turn_on
      entity_id: input_boolean.brightness_dim

  - alias: entre light dim off
    id: entre_light_dim_off
    trigger:
      platform: state
      entity_id: sensor.foerste_lyskontakt_action
      to: 'button_2_release'
    action:
      service: input_boolean.turn_off
      entity_id: input_boolean.brightness_dim

These for actions are basically to act upon the booleans for dimming or brightening

  - alias: entre brightness dimmer
    id: entre_brightness_dimmer
    trigger:
      platform: state
      entity_id: input_boolean.brightness_dim
      to: 'on'
    mode: single
    action:
      - alias: "Repeat the sequence UNTIL the conditions are true"
        repeat:
          sequence:
            - service: light.turn_on
              data_template:
                entity_id: light.entre_lights
                brightness_pct: '{{ (states.light.entre_frontdoor_light1.attributes.brightness / 2.55) | int | round(0) - 10 }}'
            - delay:
                milliseconds: 300
          until:
            - condition: state
              entity_id: input_boolean.brightness_dim
              state: "off"

  - alias: brightness brightener
    id: entre_brightness_brightener
    trigger:
      platform: state
      entity_id: input_boolean.brightness_bright
      to: 'on'
    mode: single
    action:
      - alias: "Repeat the sequence UNTIL the conditions are true"
        repeat:
          sequence:
            - service: light.turn_on
              data_template:
                entity_id: light.entre_lights
                brightness_pct: '{{ (states.light.entre_frontdoor_light1.attributes.brightness / 2.55) | int | round(0) + 10 }}'
            - delay:
                milliseconds: 300
          until:
            - condition: state
              entity_id: input_boolean.brightness_bright
              state: "off"

Specifically these two actions are what’s causing me issue.

I’ve made it so it should take of or add 10% brightness_pct in a loop while the button is held.

My questions is this:

  1. I don’t think it ever reaches 100% flat or 0% flat. If the start was for instance 55%, I feel it stops at 5% or 95%. It makes sense, the brightness_pct can’t be -5% or 105%. But, how do I sanitize the calculation making sure that anything equal to or smaller than 0% is left at 1% and vice-versa everything equal to or larger than 100% is left at 100%?
  2. I feel the loops, amount of automations and my idea of doing it is overly complicated and that something else could be done to simplify the code (in terms of moving parts/switches and codelines)?

Thanks in advance for any input!