Skip to content

Instantly share code, notes, and snippets.

@Twanne
Last active March 20, 2025 23:13
Show Gist options
  • Save Twanne/fe33ab8466f9a4e94b3f8e21f745a377 to your computer and use it in GitHub Desktop.
Save Twanne/fe33ab8466f9a4e94b3f8e21f745a377 to your computer and use it in GitHub Desktop.
Home Assistant Blueprint: Party Lights
blueprint:
name: Party Lights
author: AntonH
description: |
**Version 3.1**
Lights go to party mode (color loops or fade-in-and-out)
⚠️ **NOTE:** ⚠️
*This automation is triggered by the status of a switch or an input_boolean entity.*
*You can create this input_boolean by going to Settings > Devices & services > Helpers*
*There you click on 'Create helper and choose 'Toggle'.*
source_url: https://gist.github.com/Twanne/fe33ab8466f9a4e94b3f8e21f745a377
domain: automation
input:
#Select input_boolean
party_mode_trigger:
name: Party mode trigger
description: |
The trigger you want to use to turn the party mode on.
The automation will keep running until this is turned off.
Supported entity types:
- input_boolean
- switch
default: []
selector:
entity:
filter:
- domain:
- input_boolean
- switch
#Target lights
target_lights:
name: Target lights
description: Which lights do you want to control?
selector:
entity:
multiple: true
filter:
domain: light
#Synchronize or not
sync_lights:
name: Synchronize lights
description: |
If more than 1 target light is selected, choose if they will all change to the same state or if they each get their own random values.
**NOTE:**
*Light groups will be seen an a single entity.*
default: true
selector:
boolean:
#Time between changes
time_between_changes:
name: Time between changes
description: Change the lights setting after this duration
default:
hours: 0
minutes: 0
seconds: 0
milliseconds: 0
selector:
duration:
enable_millisecond: true
#Transition
transition_time:
name: Transition time
description: |
The time it takes for the light to transition to the assigned value when it's triggered.
WARNING!:
This value should not be greater than the time between changes
default: 0
selector:
number:
min: 0
max: 300
step: 1
unit_of_measurement: s
mode: slider
#Select color mode
color_mode:
name: Color mode
description: |
Select how the lights need to change
1. ⬛ **NO COLOR CHANGE:**
Don't change colors.
2. 🔀 **RANDOM COLOR MODE:**
Change all RGB values randomly.
3. 🌈 **SATURATED COLOR MODE**
Random, but deeply saturated, colors only.
4. 🎄 **CHRISTMAS COLORS:**
Change only between Christmas colors.
3. 🟥 **REDS ONLY MODE:**
Change only red value randomly.
4. 🟩 **GREENS ONLY MODE:**
Change only green value randomly.
5. 🟦 **BLUES ONLY MODE:**
Change only blue value randomly.
6. 🟦 **TEALS ONLY MODE:**
Change only teal shades randomly.
7. 🌸 **PINKS ONLY MODE:**
Change only pink shades randomly.
8. 🟨 **YELLOWS ONLY MODE:**
Change only yellow shades randomly.
default: no_color_change
selector:
select:
mode: dropdown
options:
- label: NO COLOR CHANGE
value: no_color_change
- label: RANDOM COLOR MODE
value: random
- label: SATURATED COLOR MODE
value: deep
- label: CHRISTMAS COLORS
value: christmas
- label: REDS ONLY MODE
value: red
- label: GREENS ONLY MODE
value: green
- label: BLUES ONLY MODE
value: blue
- label: TEALS ONLY MODE
value: teal
- label: PINKS ONLY MODE
value: pink
- label: YELLOWS ONLY MODE
value: yellow
#Select brightness mode
brightness_mode:
name: Brightness mode
description: |
Select how the lights need to change
1. **RANDOM BRIGHTNESS:**
Change the brightness randomly within a set range
2. **FIXED BRIGHTNESS:**
Keep the light at a user defined brightness
default: random
selector:
select:
mode: dropdown
options:
- label: RANDOM BRIGHTNESS
value: random
- label: FIXED BRIGHTNESS
value: fixed
#Min Brightness percentage
min_brightness_pct:
name: Minimum brightness (RANDOM BRIGHTNESS MODE)
description: Don't set the brightness of the light below this value
default: 0
selector:
number:
min: 0
max: 100
step: 1
mode: slider
unit_of_measurement: "%"
#Max brightness percentage
max_brightness_pct:
name: Maximum brightness (RANDOM BRIGHTNESS MODE)
description: Don't set the brightness of the light above this value
default: 100
selector:
number:
min: 0
max: 100
step: 1
mode: slider
unit_of_measurement: "%"
#Fixed brightness percentage
fixed_brightness_pct:
name: Brightness (FIXED BRIGHTNESS MODE)
description: Keep the light at this percentage (color changes might affect this somewhat)
default: 0
selector:
number:
min: 0
max: 100
step: 1
mode: slider
unit_of_measurement: "%"
#Light effects
light_effect:
name: Effects (All modes)
description: |
Which light effect do you want to run?
**NOTE:**
it's recommended to set the time between changes long enough for the effects to loop at least once.
default: ''
selector:
text:
#After party state
after_party_state:
name: After party state
description: |
What state should the lights have when the party mode is turned off.
1. **NO CHANGE:**
Keep the lights in the state they are at the end of the party.
2. **TURN OFF:**
Turn the lights off.
3. **RETURN TO PREVIOUS STATE:**
Return the lights to the state they were before the party began.
4. **USER DEFINED SCENE:**
Activate a scene that determines the state of the lights after the party.
5. **SCENE THEN OFF**
Set the lights to a specific setting by activating the user defined scene, then turn them off.
default: return_to_previous
selector:
select:
mode: dropdown
options:
- label: NO CHANGE
value: no_change
- label: LIGHTS OFF
value: lights_off
- label: RETURN TO PREVIOUS STATE
value: return_to_previous
- label: USER DEFINED SCENE
value: user_defined_scene
- label: SCENE THEN OFF
value: scene_then_off
#After party scene
after_party_scene:
name: After party scene
description: |
User defined scene that can be activated after the party mode is turned off.
default: []
selector:
entity:
filter:
- domain: scene
#Turn off delay
turn_off_delay:
name: Turn off delay
description: |
The time to wait before the lights are turned off.
**NOTE:**
This option is only active when the after party state is 'LIGHTS OFF' or 'SCENE THEN OFF'.
default:
hours: 0
minutes: 0
seconds: 0
selector:
duration:
#Mode
mode: restart
#Variables
variables:
party_mode_trigger: !input party_mode_trigger
target_lights: !input target_lights
sync_lights: !input sync_lights
time_between_changes: !input time_between_changes
transition_time: !input transition_time
color_mode: !input color_mode
brightness_mode: !input brightness_mode
min_brightness_pct: !input min_brightness_pct
max_brightness_pct: !input max_brightness_pct
fixed_brightness_pct: !input fixed_brightness_pct
light_effect: !input light_effect
after_party_state: !input after_party_state
after_party_scene: !input after_party_scene
turn_off_delay: !input turn_off_delay
#Trigger
triggers:
- trigger: state
entity_id: !input party_mode_trigger
to: "on"
#Actions:
actions:
#Create before state
- action: scene.create
metadata: {}
data:
scene_id: before_state
snapshot_entities: '{{ target_lights }}'
#Go through the light changes
- repeat:
sequence:
- choose:
#Synchronized lights
- conditions: '{{ sync_lights is true }}'
sequence:
#Define the brightness and rgb values
- variables:
brightness_value: >
{% if brightness_mode == "random" %}
{{ range(min_brightness_pct, max_brightness_pct) | random }}
{% else %}
{{ fixed_brightness_pct }}
{% endif %}
rgb_value: >
{% if color_mode == "random" %}
{{ range(256) | random, range(256) | random, range(256) | random }}
{% elif color_mode == "deep" %}
{% set r = range(256) |random %}
{% set g = range(256) |random %}
{% set b = range(256) |random %}
{# check if all values aren't too high. This will mute the colors as they will go towards white. #}
{% if ( r >= 200 and g >= 200 and b >= 200) %}
{% set rgb_changer = range(3) | random %}
{% if rgb_changer == 0 %}
{{ (r - 100), g, b }}
{% elif rgb_changer == 1 %}
{{ r, (g - 100), b }}
{% elif rgb_changer == 2 %}
{{ r, g, (b - 100) }}
{% endif %}
{# check if all values aren't too close together. This will mute the colors because they will form a grey color. #}
{% elif ( (r - g)|abs <= 100 and (g - b)|abs <= 100 and (b - r)|abs <= 100 ) %}
{% set rgb_changer = range(3) | random %}
{% if rgb_changer == 0 %}
{{ (r / 2)|int , g, b }}
{% elif rgb_changer == 1 %}
{{ r, (g / 2)|int, b }}
{% elif rgb_changer == 2 %}
{{ r, g, (b / 2)|int }}
{% endif %}
{% else %}
{{ r, g, b }}
{% endif %}
{% elif color_mode == "christmas" %}
{% macro random_rgb_component(max) %}
{{ range(256) | random }}
{% endmacro %}
{% macro get_color(color_key) %}
{% if color_key == 1 %}
[{{ random_rgb_component(256) }}, 0, 0]
{% elif color_key == 2 %}
[0, {{ random_rgb_component(256) }}, 0]
{% elif color_key == 3 %}
[0, 0, {{ random_rgb_component(256) }}]
{% elif color_key == 4 %}
[255, 255, {{ random_rgb_component(50) }}]
{% endif %}
{% endmacro %}
{% set color_key = range(1, 5) | random %}
{% set random_color = get_color(color_key) %}
{{ random_color }}
{% elif color_mode == "red" %}
{{ range(256) | random, 0, 0 }}
{% elif color_mode == "green" %}
{{ 0, range(256) | random, 0 }}
{% elif color_mode == "blue" %}
{{ 0, 0, range(256) | random }}
{% elif color_mode == "teal" %}
{{ range(256) | random, 255, 255 }}
{% elif color_mode == "pink" %}
{{ 255, range(256) | random, 255 }}
{% elif color_mode == "yellow" %}
{{ 255, 255, range(256) | random }}
{% else %}
{{ 255, 255, 255 }}
{% endif %}
#Call the lights
- action: light.turn_on
data: >
{% if light_effect == "" %}
{% if color_mode == "no_color_change" %}
{{ { "transition": transition_time, "brightness_pct": brightness_value } }}
{% else %}
{{ { "transition": transition_time, "brightness_pct": brightness_value, "rgb_color": rgb_value } }}
{% endif %}
{% else %}
{% if color_mode == "no_color_change" %}
{{ { "transition": transition_time, "brightness_pct": brightness_value, "effect": light_effect } }}
{% else %}
{{ { "transition": transition_time, "brightness_pct": brightness_value, "rgb_color": rgb_value, "effect": light_effect } }}
{% endif %}
{% endif %}
target:
entity_id: '{{ target_lights }}'
#Unsynchronized lights
- conditions: '{{ sync_lights is false }}'
sequence:
- repeat:
for_each: '{{ target_lights }}'
sequence:
- variables:
brightness_value: >
{% if brightness_mode == "random" %}
{{ range(min_brightness_pct, max_brightness_pct) | random }}
{% else %}
{{ fixed_brightness_pct }}
{% endif %}
rgb_value: >
{% if color_mode == "random" %}
{{ range(256) | random, range(256) | random, range(256) | random }}
{% elif color_mode == "deep" %}
{% set r = range(256) |random %}
{% set g = range(256) |random %}
{% set b = range(256) |random %}
{# check if all values aren't too high. This will mute the colors as they will go towards white. #}
{% if ( r >= 200 and g >= 200 and b >= 200) %}
{% set rgb_changer = range(3) | random %}
{% if rgb_changer == 0 %}
{{ (r - 100), g, b }}
{% elif rgb_changer == 1 %}
{{ r, (g - 100), b }}
{% elif rgb_changer == 2 %}
{{ r, g, (b - 100) }}
{% endif %}
{# check if all values aren't too close together. This will mute the colors because they will form a grey color. #}
{% elif ( (r - g)|abs <= 100 and (g - b)|abs <= 100 and (b - r)|abs <= 100 ) %}
{% set rgb_changer = range(3) | random %}
{% if rgb_changer == 0 %}
{{ (r / 2)|int , g, b }}
{% elif rgb_changer == 1 %}
{{ r, (g / 2)|int, b }}
{% elif rgb_changer == 2 %}
{{ r, g, (b / 2)|int }}
{% endif %}
{% else %}
{{ r, g, b }}
{% endif %}
{% elif color_mode == "christmas" %}
{% macro random_rgb_component(max) %}
{{ range(0, max) | random }}
{% endmacro %}
{% macro get_color(color_key) %}
{% if color_key == 1 %}
[{{ random_rgb_component(256) }}, 0, 0]
{% elif color_key == 2 %}
[0, {{ random_rgb_component(256) }}, 0]
{% elif color_key == 3 %}
[0, 0, {{ random_rgb_component(256) }}]
{% elif color_key == 4 %}
[255, 255, {{ random_rgb_component(50) }}]
{% endif %}
{% endmacro %}
{% set color_key = range(1, 5) | random %}
{% set random_color = get_color(color_key) %}
{{ random_color }}
{% elif color_mode == "red" %}
{{ range(256) | random, 0, 0 }}
{% elif color_mode == "green" %}
{{ 0, range(256) | random, 0 }}
{% elif color_mode == "blue" %}
{{ 0, 0, range(256) | random }}
{% elif color_mode == "teal" %}
{{ range(256) | random, 255, 255 }}
{% elif color_mode == "pink" %}
{{ 255, range(256) | random, 255 }}
{% elif color_mode == "yellow" %}
{{ 255, 255, range(256) | random }}
{% else %}
{{ 255, 255, 255 }}
{% endif %}
#Call the lights
- action: light.turn_on
data: >
{% if light_effect == "" %}
{% if color_mode == "no_color_change" %}
{{ { "transition": transition_time, "brightness_pct": brightness_value } }}
{% else %}
{{ { "transition": transition_time, "brightness_pct": brightness_value, "rgb_color": rgb_value } }}
{% endif %}
{% else %}
{% if color_mode == "no_color_change" %}
{{ { "transition": transition_time, "brightness_pct": brightness_value, "effect": light_effect } }}
{% else %}
{{ { "transition": transition_time, "brightness_pct": brightness_value, "rgb_color": rgb_value, "effect": light_effect } }}
{% endif %}
{% endif %}
target:
entity_id: '{{ repeat.item }}'
#Wait until the next change
- delay: !input time_between_changes
until:
- condition: state
entity_id: !input party_mode_trigger
state: "off"
#Turn off state
- choose:
#Turn the lights off
- conditions: '{{ "lights_off" in after_party_state }}'
sequence:
- delay: !input turn_off_delay
- action: light.turn_off
target:
entity_id: '{{ target_lights }}'
#Return to previous state
- conditions: '{{ "return_to_previous" in after_party_state }}'
sequence:
- action: scene.turn_on
metadata: {}
target:
entity_id: scene.before_state
#User defined scene
- conditions: '{{ "user_defined_scene" in after_party_state }}'
sequence:
- action: scene.turn_on
metadata: {}
target:
entity_id: '{{ after_party_scene }}'
#Scene then off
- conditions: '{{ "scene_then_off" in after_party_state }}'
sequence:
- action: scene.turn_on
metadata: {}
target:
entity_id: '{{ after_party_scene }}'
- delay: !input turn_off_delay
- action: light.turn_off
target:
entity_id: '{{ target_lights }}'
@juicejuice
Copy link

@Twanne this is pretty cool, however I did find a bug in "deep" colour mode. When my lights are off the "rgb_color" attribute of the light is null. This produces an error in the automation trace:
Error: UndefinedError: None has no element 0

It seems that a default value fixes this, e.g.,
{% set current_rgb = state_attr(target_lights | first, 'rgb_color') | default([0,0,0], true) %}

@CrazyBavarian
Copy link

@Twanne i have the problem when i turn off your party light then i need to wait the time between the changes before the lights chnage back to previous state. Can you help me what i need todo that it chnage back directly? thanks for your help

@Twanne
Copy link
Author

Twanne commented Jan 29, 2025

@Twanne this is pretty cool, however I did find a bug in "deep" colour mode. When my lights are off the "rgb_color" attribute of the light is null. This produces an error in the automation trace: Error: UndefinedError: None has no element 0

It seems that a default value fixes this, e.g., {% set current_rgb = state_attr(target_lights | first, 'rgb_color') | default([0,0,0], true) %}

This is fixed in the newer versions. Re-importing the Blueprint will update it to the latest version.

@Twanne
Copy link
Author

Twanne commented Jan 29, 2025

@Twanne i have the problem when i turn off your party light then i need to wait the time between the changes before the lights chnage back to previous state. Can you help me what i need todo that it chnage back directly? thanks for your help

The loop will first check whether the Party Mode trigger is turned on and then it goes through the loop (including the delay). This is part of how this works.
You cannot change this unless you check the trigger between each step, which I will not implement as that introduces unnecessary complexity.

@Ccueue
Copy link

Ccueue commented Feb 17, 2025

Could you add an option to turn off lights during party mode and then these lamps will turn back to their last state after party mode?

@Twanne
Copy link
Author

Twanne commented Feb 17, 2025

Could you add an option to turn off lights during party mode and then these lamps will turn back to their last state after party mode?

The 3rd turn off mode is "RETURN TO PREVIOUS STATE", which will turn the lights to their state from before the party mode.

@Ccueue
Copy link

Ccueue commented Feb 17, 2025

Okay but I mean an option which switches off lamps when the party mode is active. And then these lamps should also return to their last state after the party but should not be involved in the party but just switch off and return back to there last state after.

@Twanne
Copy link
Author

Twanne commented Feb 17, 2025

Okay but I mean an option which switches off lamps when the party mode is active. And then these lamps should also return to their last state after the party but should not be involved in the party but just switch off and return back to there last state after.

It's not possible to turn off lights that are included in the loop. Well, you can, but when the loop iterates it will change their state again.
Including such a feature is not possible in the current Blueprint scheme.

@Ccueue
Copy link

Ccueue commented Feb 17, 2025

And what if the lamps are not included in the loop but are simply switched off at start and then on again afterwards? These lamps would then be selected in the blueprint, in a new category but in the same way as the party lights, but they would have a different function than the party lights because they would simply switch off at the start and on at the end. Is this possible?

@Twanne
Copy link
Author

Twanne commented Feb 17, 2025

And what if the lamps are not included in the loop but are simply switched off at start and then on again afterwards? These lamps would then be selected in the blueprint, in a new category but in the same way as the party lights, but they would have a different function than the party lights because they would simply switch off at the start and on at the end. Is this possible?

It's best to create a seperate automation for this.
Simply turn them off when the party mode trigger is turned on and back on to their previous state when the party mode trigger is turned off again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment