Dynamic brightness based on lux reading from a sensor

Hi Forum,
I have a dynamic brightness control for my lights in my apartment which works by a script sequence that loops to change state every 30 seconds. But I get some minor errors in my log which is even though it still works:

Invalid service data for light.turn_on: expected float for dictionary value @ data[‘brightness_pct’]. Got ‘’

This is my automation and my script that is being used. Could someone see where the error is and or how to fix this?

automations.yaml

action:
  - service: script.turn_on
    data_template:
      entity_id: script.stue_vari_light
      variables:
        brightness1: >- ## Dinner table
          {%- set lux = states.sensor.stue_lux.state | float -%}
          {% if lux <= 6000 %}
            40
          {% else %}
            {%- set perc = (26000 - lux) / (26000 / 100) | float -%}
            {{ (((40 * perc) / 100) + 0.09) | float }}
          {% endif %}
          
        brightness2: >- ## Livingroom light
          {%- set lux = states.sensor.stue_lux.state | float -%}
          {% if lux <= 6000 %}
            35
          {% else %}
            {%- set perc = (22000 - lux) / (22000 / 100) | float -%}
            {{ (((35 * perc) / 100) + 0.1) | float }}
          {% endif %}

scripts.yaml

stue_vari_light:
  sequence:
    - service: script.turn_off
      data:
        entity_id: script.stue_vari_light_update
    - service: script.turn_on
      data:
        entity_id: script.stue_vari_light_update
        
    - service: light.turn_on
      data_template:
        entity_id: light.spisebord
        transition: 6
        brightness_pct: "{{ brightness1 }}"
    - service: light.turn_on
      data_template:
        entity_id: light.gulvlampe
        transition: 6
        brightness_pct: "{{ brightness2 }}"
    
stue_vari_light_update:
  sequence:
    - delay:
        seconds: 30
    - service: script.turn_on
      data:
        entity_id: script.stue_vari_light

Hope someone could see if it’s the script or the automation part which is missing something. :innocent::innocent::raised_hands:t4:

Try removing the comments from your templates. e.g. if lux <= 6000

Brightness1 will literally evaluate to :

## Dinner table 40

I discovered this the hard way.

Oh really? I will try that ASAP and see if the errors disappear.

Thinking about it I’m not 100% sure, as you have the comment in a different place than I did. I wouldn’t expect what you originally posted to work at all if this was the problem but you say it does.

I know… We had a nice discussion when developing the scripts and the automation, but it’s really nice during the daytime to see the lights vary in brightness according to the lux in the particular room. :sunglasses:

Unfortunately this does not solve the problem. Still receiving the same error in the log… :confused:

I think the problem stems from the fact that you’re invoking script.stue_vari_light from script.stue_vari_light_update, but script.stue_vari_light_update is not passing in values for the brightness1 and brightness2 variables.

I don’t understand why you even have script.stue_vari_light_update. You don’t show the whole automation, but isn’t it invoking script.stue_vari_light periodically and/or when necessary already? And, BTW, I don’t think you need to call script.stue_vari_light on a periodic basis. You really only need to call it when sensor.stue_lux changes.

Well. I didn’t thought that we be needed. My automation is basically only being triggering when my sensor sees motion and if the lux is below X Lux.

I have the two scripts in order to create a loop where it always receive the latest value from my variables. But was initially used to have the brightness to follow a change in the lux state, which I couldn’t get to work. Maybe I should just delete the loop and make it change every time it sees motion and maybe avoid the error by that?

I’m not sure I’m following you. You have one script (script.stue_vari_light) that adjusts the brightness of two lights based on two brightness variables passed in. That’s fine, but wherever you call it, you must pass in those two brightness values. You’re doing that from the automation, but you’re not doing that from the second script (script.stue_vari_light_update), which is what is causing the errors. (Effectively the 30 second loop is doing nothing.)

So you either have to calculate the values of the two brightness parameters in the second script and pass them to the first script, duplicating what the automation does, or you could move the calculations into the first script so the automation and second script can just call it without each having to do the calculations and pass the values in via variables.

Alternatively, you could simply get rid of the second script altogether and have the automation also trigger whenever the lights’ brightness should be adjusted, e.g., whenever the state of sensor.stue_lux changes (whether or not you move the calculations into the first script.) I would personally go with this option. I don’t see any value in calling a script every 30 seconds when most of the time it will effectively do nothing (besides waste CPU cycles.)

So, to summarize, I would have an automation that triggers whenever something changes that would require the brightness levels to be adjusted (when the motion sensor detects motion – presumably to turn the lights on initially – or when sensor.stue_lux’s state changes.) I would also have the automation contain a condition that lets the action run if it was triggered by the motion sensor, or if the light was already on. Then in the action it would just call the script, and the script would contain the calculations for brightness. I’d be happy to help you rewrite your existing automation and script to do this, but I’d need to see the entire automation as it is now.

Does this make sense?

1 Like

It totally make sense pnBruckner! What you just wrote there is the same thoughts and idea I had in the beginning. But I came up with this solution that seems to work.

I would appreciate your help rewriting the scripts and the automation - a lot actually.

Heres the full automation part:

- alias: 'Turn on livingroom if dark outside + motion + sunny day'
  trigger:
    - platform: state
      entity_id: sensor.stue_motion_sensor
      to: 'on'
    - platform: state ## From movie night to home alone state
      entity_id: input_select.home_preset
      from: 'Filmaften'
      to: 'Alene hjemme'
    - platform: state ## From eating to relaxing state
      entity_id: input_select.stue_status
      from: 'Spisning'
      to: 'Fri'
  condition:
    condition: and
    conditions:
     ## If home alone
      - condition: state
        entity_id: input_select.home_preset
        state: 'Alene hjemme'
      - condition: state
        entity_id: input_select.stue_status
        state: 'Fri'
      - condition: numeric_state
        entity_id: sensor.stue_lux
        below: '15000'
      - condition: or
        conditions:
          - condition: state
            entity_id: sensor.yr_symbol
            state: '1'
          - condition: state
            entity_id: sensor.yr_symbol
            state: '2'
  action:
    - service: script.turn_on
      data_template:
        entity_id: script.stue_vari_light
        variables:
          brightness1: >-
            {%- set lux = states.sensor.stue_lux.state | float -%}
            {% if lux <= 6000 %}
              40
            {% else %}
              {%- set perc = (26000 - lux) / (26000 / 100) | float -%}
              {{ (((40 * perc) / 100) + 0.09) | float }}
            {% endif %}
          brightness2: >-
            {%- set lux = states.sensor.stue_lux.state | float -%}
            {% if lux <= 6000 %}
              35
            {% else %}
              {%- set perc = (22000 - lux) / (22000 / 100) | float -%}
              {{ (((35 * perc) / 100) + 0.1) | float }}
            {% endif %}

New automation:

- alias: 'Turn on livingroom if dark outside + motion + sunny day'
  trigger:
    - platform: state
      entity_id: sensor.stue_motion_sensor
      to: 'on'
    - platform: state ## From movie night to home alone state
      entity_id: input_select.home_preset
      from: 'Filmaften'
      to: 'Alene hjemme'
    - platform: state ## From eating to relaxing state
      entity_id: input_select.stue_status
      from: 'Spisning'
      to: 'Fri'
    - platform: state
      entity_id: sensor.stue_lux
  condition:
   ## If home alone
    - condition: state
      entity_id: input_select.home_preset
      state: 'Alene hjemme'
    - condition: state
      entity_id: input_select.stue_status
      state: 'Fri'
    - condition: numeric_state
      entity_id: sensor.stue_lux
      below: 15000
    - condition: numeric_state
      entity_id: sensor.yr_symbol
      below: 3
    - condition: template
      value_template: >
        {{ trigger.entity_id != 'sensor.stue_lux' or
           is_state('light.spisebord', 'on') or
           is_state('light.gulvlampe', 'on') }}
  action:
    service: script.stue_vari_light

New script:

stue_vari_light:
  sequence:
    - service: light.turn_on
      data_template:
        entity_id: light.spisebord
        transition: 6
        brightness_pct: >
          {% set lux = states('sensor.stue_lux') | float %}
          {% if lux <= 6000 %}
            40
          {% else %}
            {{ 40 * (26000 - lux) / 26000 + 0.09 }}
          {% endif %}
    - service: light.turn_on
      data_template:
        entity_id: light.gulvlampe
        transition: 6
        brightness_pct: >
          {% set lux = states('sensor.stue_lux') | float %}
          {% if lux <= 6000 %}
            35
          {% else %}
            {{ 35 * (22000 - lux) / 22000 + 0.1 }}
          {% endif %}

script.stue_vari_light_update no longer needed.

3 Likes

Very nice job! I have inserted all the new lines in my system and will check it in the morning when the sun is up. If it works you’re the best. I’ll let you know! :vulcan_salute:t4::vulcan_salute:t4:

As far as I can see the automation and script do work just perfectly! I’ve added some variable meaning that I could use the same script in other rooms as well. But I have one question though. What does this mean {{ trigger.entity_id != 'sensor.stue_lux' }} Is it to make a change in the lux also triggering the brightness to change?

trigger.entity_id will hold the entity_id of the entity that caused the automation to trigger, at least for state triggers like you’re using here.

For the fourth trigger I added (lux changing), I assumed you only wanted that to cause the script to run if the lights were already on. (Otherwise, even if the lights were off, if the lux changed, the lights would get turned on.) So I added a condition – it will let the script run if the automation was trigger by one of the original triggers (i.e., not triggered by sensor.stue_lux, and of course, assuming all the other, original conditions are met), or (if the trigger was sensor.stue_lux then only) if one of the two lights are already on.

There are other ways to do this. E.g., the automation could turn on an input_boolean to record the fact that it initially turned on the lights, and then the condition could be testing against that instead of the lights being on. But then you’d probably have to add another automation that turns the input_boolean off when either of the lights gets turned off. Just depends on how you want it to work.

1 Like

Ah okay. No that is just what I wanted. I just had to be sure what it meant. Again, thank you for the help!

Hey guys, I’m interested in this automation but I’m not sure about some parameters.

Could someone please explain especially the brightness_pct part in the script to me so that I can customize it to my needs?

Regards!

1+ to try the automation.
if somebody could explain how to get it to work.
I have a lot to learn just started out with HA, iam using the Fibaro hc3 to controle my light and sensors that’s why its such a strange name for my light and sensor.
Get the following error:Message malformed: extra keys not allowed @ data[‘stue_vari_light’]

'alias: New Script
sequence:

  • device_id: ‘’
    domain: ‘’
    entity_id: ‘’
    mode: single
    stue_vari_light:
    sequence:
    • service: light.turn_on
      data_template:
      entity_id: sensor.woonkamer_woonkamer_lux_231
      transition: 6
      brightness_pct: >
      {% set lux = states(‘sensor.woonkamer_woonkamer_lux_231’) | float %}
      {% if lux <= 6000 %}
      40
      {% else %}
      {{ 40 * (26000 - lux) / 26000 + 0.09 }}
      {% endif %}