Automating lights (Tradfri) by time and colour

Hi folks. My lady and I have just hammered out how we’d like the lights for my daughter’s room to work - but I’m having real trouble wrapping my head around how to code it. Any advice would be greatly appreciated!

The brief:

  • One single button will control the light. (I’m already successfully catching the event this fires and running a test automation).
  • The “correct” (or default, rather) colour and brightness of the light is defined by time of day, e.g. 255,255,255 and 100% from 0700 to 1900. I have these defined as Scenes. There are currently three Scenes/times of day, but this might well expand to four/five.
  • If the light is off, or not the “correct” colour/brightness by time of day, pressing the button should turn it on and set it to the correct Scene.
  • If the light is on, AND already the correct colour+brightness/scene, turn it off.

My problem really is I’m not sure how to catch all these different scenarios without just writing a ton of different automations, which would be ugly, but worse, Wrong :wink:

I started trying to handle the different times/scenes in a template condition, but then I thought I probably can’t use properties of the light (e.g. rgb_color, brightness_pct), when the trigger itself is nothing to do with the light? (It’s platform: event)

Could I code a template sensor “Daughters light is correct colour” = true/false, and use the output of that in my conditions?

Am I way overcomplicating this, and it’s actually easy to do in a single automation if, well, you’re better at it than me?

Basically, how would you approach this problem? :slight_smile:

One automation with a service/data template will do it, and it’s not that complicated once you get your head around the logic.

Two questions to help me with the logic:

If the light is already on when you get to the next defined time, should it change color, or wait for the next button press?

How does the button press act as a trigger (you said event, so it’s it an event triggers or platform)?

Hey, thanks for helping! :slight_smile:

I have spent the time since that first post fiddling with templates, and I’m getting somewhere - maybe - but I could definitely use some hand holding.

If the light is already on when you get to the next defined time, should it change color, or wait for the next button press?

It should only change on a button press.

How does the button press act as a trigger (you said event, so it’s it an event triggers or platform)?

I’m using pydasher to fire a custom event - in this case “dash4aveeno”. The automation trigger looks like this:

- alias: 'Nightlight Toggle'
  trigger:
    platform: event
    event_type: dash4aveeno

(Currently it just sends me a notification for testing, which works as expected).

OK -

ENTITY = name of the light
DAY, EVENING, NIGHT, OVERNIGHT = name of your scenes for that part of the day. Presumes that day brightness is 100%, Evening is 70, night is 50, overnight 25 (set the numbers to match the brightness in your scene. If you have two scenes that have the same brightness literally add 1 or 2 to one of them, makes things loads simpler)

Day is 0700 - 1900, Evening is 1900 - 2100, Night is 2100 - midnight, Overnight takes you back to 7am…

alias: Kids light cycle
trigger:
  platform: event
  event_type: das4aveeno
action:
  service_template: >
    {% if ((now().hour >= 7) and (now().hour < 19))
	  and is_state ('states.light.ENTITY.attributes.brightness' , '100') %}
	    light.turn_off
	{% elif ((now().hour >= 19) and (now().hour < 21))
	   and is_state ('states.light.ENTITY.attributes.brightness' , '70') %}
	   light.turn_off
	{% elif (now().hour >= 21) 
	   and is_state ('states.light.ENTITY.attributes.brightness' , '50') %}
	   light.turn_off
    {% elif ((now().hour >= 0) and (now().hour < 7))
	   and is_state ('states.light.ENTITY.attributes.brightness' , '25') %}
	   light.turn_off	   	   
	{% else %}   
	   scene.turn_on
	   
  data_template:
    entity_id: >
      {% if ((now().hour >= 7) and (now().hour < 19))
	    and not is_state ('states.light.ENTITY.attributes.brightness' , '100') %}
	      scene.DAY
       	{% elif ((now().hour >= 19) and (now().hour < 21))
	     and not is_state ('states.light.ENTITY.attributes.brightness' , '70') %}
	     scene.EVENING
	  {% elif (now().hour >= 21) 
	     and not is_state ('states.light.ENTITY.attributes.brightness' , '50') %}
	     scene.NIGHT
      {% elif ((now().hour >= 0) and (now().hour < 7))
	     and not is_state ('states.light.ENTITY.attributes.brightness' , '25') %}
	     scene.OVERNIGHT	   	   
	  {% else %}   
	     light.ENTITY

So, when the button is pressed, the template checks the time and if the light is on checks the brightness. If the brightness is correct for the time of day, the service template is light.turn_off, if it’s not it the service is scene.turn_on.

Then the data_template looks at the times, and says if it’s NOT in the right scene (so scene.turn_on was called), then this is the scene to pass. If they all ring false (so light.turn_off was called) then the entity_id is your light.

It’s like 2.30 in the morning here, so God knows if that will work on the first pass, but it’s a start.

Hope it helps :+1:

1 Like

Wow, yeah, that’s a way more elegant way of doing it than I was working toward, very nice!

I just had to add {% endif %} to both templates to get it to parse.

After a bit of fiddling, definitely getting somewhere. (I’ve started three or four descriptions of problems here, before cracking them myself as I was forced to think it through :slight_smile: ).

So, where I am now: If I set the colour to something different, say green, and manually triggering the automation, I see the light switch to red (i.e. the night scene is activated), but triggering again does not turn the light off - it then appears to do nothing. (In other words, I believe the automation is always activating the appropriate scene for the time of day).

So I’d say the test for whether current brightness = the correct value is failing. (I’ve checked in the Configuration → States tool, and the brightness values reported there are the expected ones). I guess it could be the time condition, but that looks pretty straightforward, and it comes out correctly in the template tool.

Or could it be referring to the light itself incorrectly? It’s only the turn_off that’s actually using the entity_id of the light itself, rather than firing a scene? Hmm, I wonder if firing a dark scene would work…

EDIT: Ugh, giving up for the night. Sooo close though!
I’m pretty sure, from testing with the template tool, that I want

is_state_attr(‘light.ENTITY’,‘brightness’,15)

as the condition rather than

is_state (‘states.light.ENTITY.attributes.brightness’ , ‘15’)

  • the latter I can’t get anything out of in the template tool (having replaced ENTITY with the actual name of the light, of course).

But it’s still not working, and I’m out of ideas for this evening :confused:

Yeah the is_state_attr sounds better, it’s just about making sure that the template passes the conditions properly to get to the right service, so it’s going to be some head scratching with the template tool I’m afraid.

In fairness, if it’s selecting the right scene for the time of day in the data template, the conditions can’t be far off for the service template.

Also, check the logs when you fire the automation, see if there’s any errors like ‘can’t find service light/turn_off’ or ‘template can’t pass number’ or whatever, should help you narrow it down.

In fairness, if it’s selecting the right scene for the time of day in the data template, the conditions can’t be far off for the service template.

No, it’s really close, I can almost smell it :slight_smile:

Also, check the logs when you fire the automation, see if there’s any errors like ‘can’t find service light/turn_off’ or ‘template can’t pass number’ or whatever, should help you narrow it down.

No, no error at all in the logs. That’s my problem really - lack of information, can’t see where it’s going wrong.

I think I’ll copy the automation but change the action to notify, have it feed me what it thinks it’s doing.

Anyway, thanks so much for your help - you’ve definitely steered me on to the right path :slight_smile:

1 Like

wow!
this is exactly where i was working on.
Did you get it to work?
I have something now and it is working.
It works with a button click and changes the color temp and brightness of light.
I would like to change the scene if the light is still on, so without click and starts automaticly next scene.
I hope you get it to work?

- alias: "Kleuren Kleine Tafel"
  trigger:
    - platform: state
      entity_id: light.kleine_tafel    
      from: 'off'
      to: 'on' 
  action:
    - service: light.turn_on
      data_template:
        entity_id: light.kleine_tafel
        color_temp: >
          {%- if now().strftime('%H')| int >= 20 %}
            463
          {%- elif now().strftime('%H')| int < 9 %}
            400
          {%- elif now().strftime('%H')| int >= 9 %}
            325
          {%- endif %}
    - service: light.turn_on
      data_template:
        entity_id: light.kleine_tafel
        brightness: >
          {%- if now().strftime('%H')| int >= 20 %}
            150
          {%- elif now().strftime('%H')| int < 9 %}
            190
          {%- elif now().strftime('%H')| int >= 9 %}
            230
          {%- endif %}

Hi Wesley

I haven’t had a chance to go back to it really. I found that my Dash button setup wasn’t really satisfactory - not generating events reliably/repeatably enough - so unless I find an alternative, I think I’ll just have one button “Set to correct mood for time of day” and a second to turn off (which happens to “solve” the problem I still have with the automation :smiley: ).

The method/code proposed by mf_social above definitely should work though (for my problem, I mean). I just didn’t get around to debugging the last niggles I mentioned in my previous post.

The approach I took to a similar problem was to add a short delay (e.g. Ten seconds) and then set a boolean (e.g. a input_boolean.auto_lights) to on for my automation that detected the button press. I then created another automation that looked for any state changes on that light, and turned off the boolean if it detected one. That way I could check if the lights had been changed from the original scene at all. This doesn’t completely handle your automation needs, but it might help.