[SOLVED] Python script, need to build a for loop to turn on a random number of lights

Hey guys, im trying to learn some stuff i templating so im fiddling around in the template editor but i need some guidance please.

My current project is as follows:
My living room has 8 spotlights (named livingroom_1 - livingroom_8).
I want to build a script to turn on a random number of spotlights on command
I want it to be at least 2 and max 7 (any number between them)
So i was thinking something like:

{% set number_of_lights_to_open= 
 (range(2, 7)|random)
 %}
  • Then say this gives us the random value X.
  • I want a template to select X random different numbers from 1 to 8 and have them stored as random_lights.light_number (?)
  • Then iterate X times to turn on each switch.livingroom_{{random_lights.light_number}}

How would i go about writing something like this?
Also am i thinking this right? or is there some better way to do it?
Thanks in advance

There’s probably a way to do this with templating, but there’s a much easier way using a python_script. This should do it:

lights = []
for i in range(1,9):
    lights.append('switch.livingroom_{}'.format(i))
turn_on = random.sample(lights, random.randint(2,7))
hass.services.call('switch', 'turn_on', {'entity_id': turn_on})

If you haven’t used a HA python_script before, and need help with the details, just let me know.

2 Likes

First time ill fiddle with this but i have some minimal experience with python. I guess it was about time to try it on HA too. Will go study and come back with any questions. Thank you!

Works like a charm, thank you!
BTW, the (1,9) was not intentional right? as i only have 8 lights?

To expose it to alexa I created a HA script to call it, like this:

script:
  some_lights:
    sequence:
      - service: python_script.random_lr_lights

It was intentional. The range function produces a sequence that starts with the first number, and ends with the last number minus one. So, range(1,9) produces [1,2,3,4,5,6,7,8].

And while we’re on the topic, random.randint produces a random number between the first and second numbers, inclusive.

Thanks for clearing it up :slight_smile:

1 Like

Could you give me an example of the code that would also turn off the rest of the switches non selected by the random?

ie. if 3,4,5 are chosen from the range 1-8, it should also run switch.turn_off for 1,2,6,7,8.

I’ve tried to figure it out but my python knowledge is non-existant.
Thanks in advance :slight_smile:

You don’t need a fancy script for that. Just call the switch.turn_off service and pass it a list of the switches:

- service: switch.turn_off
  entity_id:
    - switch.livingroom_1
    - switch.livingroom_2
    ...
    - switch.livingroom_8

Or create a group containing all the desired switches – say group.livingroomswitches – and then:

- service: homeassistant.turn_off
  entity_id: group.livingroomswitches

That’s not what i mean:

I would like the upper code you gave me, to turn on a random set of switches, and at the same time turn off the rest (not selected by the random)

This way i could run the script even if all the lights are on and end up with a random group set to on. Or repeat the script if i dont like the result untill i get some nice set.

Sorry, misread it the first time. Sure…

lights = []
for i in range(1,9):
    lights.append('switch.livingroom_{}'.format(i))
turn_on = random.sample(lights, random.randint(2,7))
turn_off = lights.copy()
for light in turn_on:
    turn_off.remove(light)
hass.services.call('switch', 'turn_on', {'entity_id': turn_on})
hass.services.call('switch', 'turn_off', {'entity_id': turn_off})

Thanks a ton!.
I can read code and appreciate it but in no case could i write something like that :slight_smile:
Wish i had gotten into the game younger…

Hey there, cominig back for some more help after 3 years :slight_smile:

How would i edit this block of code to work on an already set group of lights?
In this case we actually “build” the group right? by selecting similar entities with different numbers at the end

lights = []
for i in range(1,9):
    lights.append('switch.livingroom_{}'.format(i))

How can i make it work on a group called light.dn_lr_lights?
something that would work like this:

lights = [light.dn_lr_lights]

Home i am making sense :slight_smile:
Thanks in advance!

How did you create that group of lights? Can you show me its attributes from the STATES page? Unless it has an attribute that lists the lights in the group, I don’t think there is a way.

Hey thanks for the reply :slight_smile:

The group is created by UI, through the helpers menu.
Here are the contents and it seems like it includes the entities under entity_id attribute.

Thing is that it’s contents are two other light groups (that contain the actual switch and light entities).
I could remake the group in order to include all the individual entities in it, or could we get the names from the attributes of the sub-groups?

You might try the expand function. See:

I know you’re asking about Python Scripts, but I bet you can do what you want now using templates & “regular” scripts.