Randomized Lighting in Home Assistant

I recently did a video on how to setup randomized lighting to simulate human presence over on my YouTube channel. If you haven’t checked that out, you should watch it first.

In this post I walk you through how I set up this randomized lighting effect in more detail. There are other ways to do this using third-party add-ons or integrations, but I wanted to show that you could do all of it in native Home Assistant.

Because this gets into some advance topics it can be intimidating for those new to Home Assistant, but I think you will find it easier than you expect. Either way though, by the end of this article you will have a basic automation to randomize lighting in your house. 

Project Overview

We are going to create an automation that grabs a random light or switch from a group and turn it on. Then after a delay of time between 5 and 59 minutes we will turn it off. And we will repeat that pattern until we cancel the automation, or the sunrises.

The Entities

The first step is to create a list of lights and switches to use. For this we are going to use a group.

To define a group we are going to have to edit the config files. I like using the File Editor add-on in home assistant for this. If you don’t already have that setup check out this video ()

I used the name vacation lights for my group.

Where you define this group will be based on your setup. If you have not setup a groups.yaml file, then you can define in your configuration.yaml like this:

  vacation lights:
    - light.front_door_lamp
    - light.living_room_lamp
    - light.living_room_tower_lamp
    - switch.fireplace_lights
    - switch.croft_light
    - light.skylars_dresser_lamp

If you are using the groups.yaml then the setup will look like:

vacation lights:
  - light.front_door_lamp
  - light.living_room_lamp
  - light.living_room_tower_lamp
  - switch.fireplace_lights
  - switch.croft_light
  - light.skylars_dresser_lamp

Just add a – (dash) before each entity you want to include. And don’t worry about mixing lights and switches. We haver a solution for that.

Once you have your group defined, save your changes, and then either restart Home Assistant, or head to configuration > server controls, and reload groups by selecting “Groups, Group Entities, and Notify Services”


After that we need to define a couple of helpers.

For that head to Configuration > Helpers

The first Helper will be called Vacation Mode, and we will use this as a condition to ensure our lightning effect only happens when we are gone, and to cancel the effect if we happen to come while it’s running.

Click “Add Helper” and choose toggle, and give it our name, and click create

After that we need to create a text helper to store our chosen entity. This will be used as a variable to ensure that during this process the automation doesn’t get confused about which light or switch it should be automating.

So click Text from the list of Helpers and then give it a name. I am using Current Random Light

Once done click create.

Scripting the Effect

For the main part of this automation we are going to use a script. Using a script will give us an easier way to start and stop the effect over using just an automation.

So head to Configuration then Scripts and click “Add Script” in the lower right.

I named this script “randomize vacation lights”

Since we are going to be using templates in this script we are going to end up writing this in YAML, so under Sequence go a head and click the three dots in the upper right and choose “Edit in YAML”

Now your Script Editor will look like:

Don’t worry, since you are here you can just copy and past the next part.  Just replace the default YAML with this:

    - condition: sun
      after: sunrise
    - service: input_text.set_value
        entity_id: input_text.current_random_light
        value: '{{ state_attr(''group.vacation_lights'',''entity_id'') | random }}'
    - service: homeassistant.turn_on
        entity_id: '{{ states(''input_text.current_random_light'') }}'
    - delay:
        minutes: '{{ range(5,59) | random | int }}'
    - service: homeassistant.turn_off
        entity_id: '{{ states(''input_text.current_random_light'') }}'
    - service: input_text.set_value
        entity_id: input_text.current_random_light
        value: None

And your script should now look like:

And if you named everything as I have so far then you should be good. If not, you will need to update the entities in the script with the names you used.

Now that we have that let’s talk through what it is doing.

Lines 1 – 4 tell the script to repeat until sunrise.

Line 5 starts the sequence we want to repeat.

Lines 6 – 10 define our first action. We are calling the input text set value service to update our current random light text helper. Then for value we are using a template to get the value of a specific attribute. The stateattr function takes two arguments. The name of an entity, in this case our group.vacationlights, and the name of an attribute, entityid. Then we use  | random to pick just one. 

Lines 11 – 13 turns on our chosen entity.  Since the entity could be a light or a switch, we are going to call the homeassistant.turnon service which will turn on any entity that has that capability. For entityid, we are going to use another template, but this time we will call the states function and pass it the name of our text helper to get the entity id of our current light.

Lines 14 – 15 delays our script for a random number of minutes. To do that we are going to use yet another template.  This one will use the range function to get a list of numbers between 5 and 59. Then we use | random to pick just one from the list. And lastly | int to ensure what returns is an integer since delay expects a number.

Lines 16 – 18 turns off our chosen entity. We call the homeassistant.turnoff service and use the same template from the action where we turned on the device.

Lines 19 – 22 just resets the value of our text helper to ‘None’ which isn’t really needed. But you could add it to your Lovelace UI if you want to see what entity this script chose as it is running.

Now if you are interested in using multiple lights you could replace replace action between 6-10 with this:

- service: input_text.set_value
        entity_id: input_text.current_random_light
        value: >
            {% set light_count = state_attr('group.vacation_lights', 'entity_id') | count %}
            {% set lower_limit = light_count - 1 %}
            {{ state_attr('group.vacation_lights', 'entity_id')[range(0,lower_limit) | random :light_count] |join(',') }}

What this will do is pick a random range of entities from the list and create a comma delimited list of random entities that you could pass to your turn on and off service.

I haven’t tested how well that will work other than making sure that bit of jinja grabs a random list of entities from the group and creates a comma delimited list. But if you would rather have multiple entities involved, I hope it gives you a head start on a solution.

After you have your script defined, save it.

Automating This Thing

Next up is automating this whole thing. 

So head to Configuration > Automations and click the “Add Automation” button in the lower right.

I called this automation “run vacation lights”

And I included three triggers.

The first trigger is when the sun goes down, since during the say the lights wont be all that noticeable.  So trigger type is sun and event is sunset.  And I gave it a trigger id of sundown which will come in handy in the choose action we are going to use.

The second trigger is sunrise. So trigger type is sun, and event is sunrise, and for trigger id I called it sunup.

And the third trigger is when vacation mode is turned off. This is for those times in which we come home while the effect is running.

So trigger type is state, entity id is our vacation mode input boolean, and we are looking for times when it goes from on to off. And we set trigger id to cancel

For actions we are going to use the choose action so we can either turn on our lighting script or turn it off.

So action type will be choose.

And for Option 1 we will look at two conditions.

1:  the trigger = sundown

2: vacation mode = on

Then if both of those conditions are met we turn on our lighting script:

Then for Option 2 we will like for one of two different conditions. So we set condition type to Or then add our two conditions:

  1. Trigger = sunup
  2. trigger = cancel

Then for actions under this option we turn off our lighting script:

The YAML for this automation looks like:

- id: '1627174942201'
  alias: run vacation lights
  description: ''
  - platform: sun
    event: sunset
    id: sundown
  - platform: sun
    event: sunrise
    id: sunup
  - platform: state
    entity_id: input_boolean.vacation_mode
    id: cancel
    from: 'off'
    to: 'on'
  condition: []
  - choose:
    - conditions:
      - condition: trigger
        id: sundown
      - condition: state
        entity_id: input_boolean.vacation_mode
        state: 'on'
      - service: script.turn_on
          entity_id: script.randomize_vacation_lights
    - conditions:
      - condition: or
        - condition: trigger
          id: sunup
        - condition: trigger
          id: cancel
      - service: script.turn_off
          entity_id: script.randomize_vacation_lights
    default: []
  mode: single

Once you have your automation set, save it, and you are ready to start using your randomized lighting effect.

Hopefully that gives you a good starting point for building a simulating human presence automation for your smart home. I have some other ideas for how to make this better by including multiple devices instead of one, some media players to make the presence more audible, and perhaps spreading the effect out over 24 hours.

If you haven’t subscribed to my YouTube channel be sure to do that so you wont miss the next video. And reach out to me on twitter @thejeffreystone and let me know what changes you make to this setup.

Until next time, Go Automate the Boring Stuff.

28 thoughts on “Randomized Lighting in Home Assistant”

  1. Hey Jeff, I commented on the YT video and I’m having trouble with the “repeat” function. It doesn’t appear to be working. Pretty quickly I went directly to copying your code for the automation and making sure all my stuff was named the same. The automation fires once, and then never again. After the first 5-59 minute random light turn on, no other lights turn on for that day. Is that happening as intended? I thought it would keep doing that (turning on a different random light every 5-59 min, for 5-59 min)? The code in your yaml example says mode: single at the end. Maybe that’s suppose to be something else? I can paste my yaml but I think it’s the same as yours.

    any help would be appreciated (though not expected of course!).

    1. hmm. Yeah, once the script kicks off it should just repeat until sunrise. Did it get started prior to sundown? Not that I am thinking about it, if the script starts prior to sundown it may only do it once, and since the sun is technically up it may need to be more specific.

    2. Oh, and if you wanted a quick fix prior to your vacation you could just switch to a count.

      count: 10

      Instead of the repeat until. You might want to adjust your random time between off to maybe 30 and 59. That way at least it will do the effect for 5 hours, and at most 10 hours.

    3. You could also try using the state and see if it makes a difference

      – condition: state
      entity_id: sun.sun
      state: ‘above_horizon’

      instead of the

      – condition: sun
      after: sunrise

  2. Jeff,
    Also how can I get the routine to turn off during the night instead of at sunrise? I tried using 22:00:00 instead of sunup but that got an error.

      1. Please excuse my lack of knowledge. I am still learning the syntax of yaml. Where will the text you sent go?

        – condition: sun
        after: sunrise

        Thanks so much for your enthusiasm and help!!

  3. ummm. Thats what I get for trying to help prior to be caffinated…

    So instead of this

    – condition: sun
    after: sunrise

    You would have

    – condition: time
    at: ’22:00:00″

  4. Hi
    Good job
    I had the same problem mentioned above and was able to fix it with the “above_horizon”
    But I found another problem and I can’t think of how to solve it …. if the “automation trigger” triggers the “script.turn_off” because the cancellation or sunup condition is met, and the lights were on, they stay like this throughout the day since the script is canceled and does not allow the “homeassistant.turn_off” statement to be executed
    Any idea how to avoid it?

  5. Thank you for this great video and tutorial however has something changed in the yaml as I had to change a couple of things in the groups to make it allow me to add the lights etc as shown below

    vacation lights:
    name: vacation lights
    – light.kitchen_lamp etc

    Also in the script which I copied the code above and I checked that I used the names you used but if i try to save the script I get an error

    Message malformed: extra keys not allowed @ data[‘repeat’]

    I then tried adding

    – repeat:

    but I still get a similar error

    Message malformed: expected a dictionary for dictionary value @ data[‘sequence’][0][‘repeat’]

    Not sure what i am doing wrong as new to yaml and HA as used to use smartthings

    1. Sorry, I forgot to respond to this.

      I’m not sure without seeing the rest of the script. But that error problem means something is not indented correctly. After the – repeat line the one under should be indented at least 2 spaces in from – repeat

  6. Thank you so much for sharing. I have learned much from you and I like your approach. My question may be slightly off-topic but we’re talking vacations, right?

    I have Home Assistant running at home in an apartment and I can access it from afar.
    – Fibaro Smoke detector – ZWave. There is a sensor for alarm, sensor for battery detector. The smoke detector works independently from the network. All working great.

    I left for a three week absence and all was well. Unfortunately it turned into a three *month* absence. A neighbor contacted me. He could hear the smoke detector chirping. Yes, I could see the battery was very low 1%. Fibaro does not seem to have an alarm turn-off. Do you have any thoughts about dis-arming a battery powered smoke detector alarm if warranted? Are there other devices or solutions instead of Fibaro?

    Thanks much.

    1. I’m not sure of any way to disable the battery chirp remotely. I suspect from a safety stand point they probably won’t let people disbale the battery chirp so I am not sure there will be a solution like that.

  7. Hey Jeff, thanks for this. I have a bunch of Wemo switches I have candle lights plugged into for the holidays. I have them simply automated to turn on when it gets a certain amount of dark, and turn off at sunrise. I was hoping your post here would help me figure out how to do something similar with the switches, but I’m not sure how to do it. I think a script would have to work something like this:

    1) Grab the entity names of all the switches in my Holiday Lights area
    2) Use your randomized idea to grab one of their names
    3) Turn on that switch
    4) Wait a random number of seconds
    5) Grab another name and check whether the light is already on. If it is, pull another name. If it’s not, turn it on.

    Repeat 4 and 5 until all of the switches are turned on.

    Obviously the basic automation works fine, but I feel like randomized switching on and off would look more natural, and maybe even make people think someone is actually home.

    Any thoughts on how to get started on this?

    1. Ok, so I was thinking about this.

      I think I would do a modified version of the vacation lights thing. And it might even been simpler. Especially since you are not turning them off.

      AS long as all your candle lights are in a group, you can use some jinja to get the list of entities in that group that are off, and pick a random one. And then in theory when the script repeats it will grab one of the entities that are off and turn it on. Just update the repeat count to match the number of entities in your group so that it only repeated as needed.

      So the script could look like this (formatting is bad…sorry):

      Properly formatted: https://gist.github.com/thejeffreystone/6bc41eb103094318795353ab2885abf3

      alias: randomize lights
      – repeat:
      count: ‘8’
      – service: homeassistant.turn_on
      entity_id: “{{ expand(‘group.livingroom’) | selectattr(‘state’, ‘eq’, ‘off’) | map(attribute=’entity_id’) | list | random }}”
      – delay:
      seconds: ‘{{ range(2,5) | random | int }}’

  8. Hi! Excelent tutorial and video. I am trying to setup this randomized light script and I have copied step by step and when I hit on the Lovelace button to turn on “input_boolean.vacation_mode” nothing happens.

    I have set timer from 5,59 to 1,2 to be able to try it out.

  9. Hi, I really lliked this tutorial and video.

    I have followed step by step and copied the yaml for every step. I modified 5,59 to 1,2 so I can try this out. I created a button to “input_boolean.vacation_mode” and when I hit ON, nothing happens.

    I went to Scripts and manually hit PLAY and it is working.

    So basically I can turn it on manually on scripts but not from lovelace button. And now I cant turn it off!!!

    1. Oh no! You can turn off a script in a couple of ways.
      Easiest might be to head to developer tools and states. Search for script, then in the line for state that says on. Type off and then save that.

      1. Thanks, I got this figures out. My main problem is when hitting the button on Lovelace “input_boolean.vacation_mode” and when I hit ON, nothing happens.

      2. That sounds like the automation that turns on the script isn’t registering the input boolean change. I would check the automation that triggers with that input boolean. It could be as simple as a misspelled script name or something like that. I do that all the time.

        The home-assistant.log might have point out to the problem as well.

        Oh, and you can always go into the developer menu, under services, and choose automation: trigger and then pick your automation that should trigger with the input boolean turning on. Make sure you check the ignore conditions box. That way you can rule out conditions like the sun position or anything else you might have added as a condition.

  10. This is great stuff, but i havethe script to run when last person leaves the house AND sun is below horizon OR sun is below horizon AND no one is home and until anyone in the family comes back OR sun is above horizon. I have added the first conditions as trigger combination in the automation that turns on the script and the “until” ones in the script itself. All this is working but how do i add that the random light(s) turn off when the script is stopped upon arriving home? If my random time is (2,59) the light might stay on for additional 59 minutes after arriving.I guess there is no way to do this other than to move the “Until” conditions to an automation that turns off the script AND turn off the lights in the text.helper at the same time. Do you have any other solution to this?

  11. Hi when trying to paste the script I am getting this:

    Message malformed: extra keys not allowed @ data[‘repeat’]

    Any ideas? I’m literally copying and pasting your script.

  12. I’m also getting “Message malformed: extra keys not allowed @ data[‘repeat’]” I’m assuming the syntax changed in the latest version for HA. I wonder if restart would work.

  13. Hi Jeff, thanks for your inspiration for this automation. I was looking to create random lights while we’re out of the house in the evening and I’d like to share a few things I enhanced:
    1) I triggered it on arming our alarm (which we do when we leave the house) or on sunset or on time being after 7am. Conditions are alarm on and it’s dark and it’s after 7am (to avoid lights continuing between midnight and 7am, which would be a little unnatural).
    2) I used your idea of a light group (great idea BTW!), and then just toggle a random light each iteration of the loop, which means that over time you get multiple lights on at the same time (also more realistic). I don’t need to remember which light was last switched either. The loop exits if it’s not between 7am and midnight.
    3) When the alarm is disarmed (when we get home), it turns off the randomization script. And I have an automation that triggers on the script stopping (state of script going to “off”), which simply does a light.turn_off on the light group to turn off any lights that are still on.

Leave a Reply to thejeffreystone Cancel reply