ste-ta
(ste-ta)
October 29, 2025, 5:54pm
1
Hi everyone!
With Halloween coming up, I wanted to share:
A comprehensive Home Assistant script that creates various spooky lighting effects for Halloween. Optimized for reliability with older smart bulbs.
Script Parameters:
lights (required): Single entity ID or list of light entity IDs
effect (required): One of: hell, lightning, graveyard, halloween, stop
Compatibility:
Home Assistant 2023.x and newer
Any RGB lights supporting light.turn_on with rgb_color and brightness
What It Does
This script provides 5 different Halloween effects for your RGB lights:
Hell - Flickering red and orange flames
Lightning - Dramatic white flashes with darkness (lightning strikes traveling across rooms)
Graveyard - Eerie green-blue fog with very low brightness
Halloween - Classic orange, purple, and green color transitions
Stop - Cleanly resets all lights
Key Features
Individual light control - each light gets random variations for organic effects
Restart mode - automatically stops previous effect when starting new one
Error tolerant - continues running even if individual lights fail
Smooth transitions - adjustable timing from 2-10 seconds depending on effect
Easy to customize - modify colors, brightness, and timing
Installation
GitHub Repository:
A comprehensive Home Assistant script that creates various spooky lighting effects for Halloween. Optimized for reliability with older smart bulbs.
Quick Install:
Copy the script from the repository
Go to Settings → Automations & Scenes → Scripts → Add Script
Edit in YAML and paste
Save!
Usage:
service: script.halloween_atmosphere
data:
lights:
- light.living_room
- light.kitchen
effect: hell # or: lightning, graveyard, halloween, stop
Technical Details
Works with ANY Home Assistant light entity that supports RGB (not limited to specific brands!)
Sequential execution with proper delays (not parallel) for maximum compatibility
100-150ms delays between commands prevents Zigbee congestion
If your light supports light.turn_on with rgb_color and brightness parameters, it will work!
Dashboard Integration
You can easily add buttons to your dashboard:
type: button
name: "🔥 Hell Fire"
tap_action:
action: call-service
service: script.halloween_atmosphere
data:
lights:
- light.living_room
effect: hell
Perfect For
Halloween parties
Haunted house setups
Movie nights (horror genre)
Spooky ambiance all October
Scaring trick-or-treaters
Known Issues / Limitations
Very old bulbs (pre-2015) may occasionally miss a command
Recommended maximum of 10 lights per call for best performance
Effects loop indefinitely until you call stop
Feedback Welcome!
I’d love to hear your thoughts and see how you use it! Feel free to:
Suggest new effects
Report issues
Share your modifications
Happy Halloween!
13 Likes
santiniuk
(Santiniuk)
October 29, 2025, 7:40pm
2
Thanks for sharing.
Works great!
2 Likes
Yoinkz
October 30, 2025, 11:19am
3
Amazing work!
One thing I’m not sure about is the lightning effect. Where is it I need to adjust if I want the “flashing” effect to happen more rapidly?
Gav_in
(Gavin)
October 30, 2025, 12:52pm
4
check out the notes on the GitHub page…some details there on changing the effect speed
A comprehensive Home Assistant script that creates various spooky lighting effects for Halloween. Optimized for reliability with older smart bulbs.
Excellent work! I have a bunch of lights in the script, all of them change colors, but they change at the same time and stay synced as far as color. Is it possible to randomize? My yaml skills are rusty. I’m using the Halloween effect. Thank you!
koconut
October 30, 2025, 10:45pm
7
These effects are awesome. My lights appear to be random, even if I target them in a group so I’m not sure why yours are synced.
I do have another issue, when my automation runs it doesn’t run any steps after calling the script (it is supposed to call the effect, wait 10 sec, then call stop effect). Similarly, when clicking “Perform action” in dev tools, the spinning circle stays there so the screen is locked up. I have to refresh the page to be able to call it again.
EDIT: I guess this is just a limitation that when there is a running script, home assistant will not go to the next step, maybe possible to do a parallel action I’m not sure. I had ChatGPT modify the script to add a “duration” variable and also create/apply a scene before/after running the script to restore the lights to previous state.
alias: 🎃 Halloween Atmosphere duration scene
description: >-
Creates spooky lighting effects with automatic scene capture and restore.
(v1.4)
mode: restart
max_exceeded: silent
fields:
lights:
description: List of light entity IDs
example: light.living_room, light.hallway, light.kitchen
selector:
entity:
multiple: true
domain: light
effect:
description: Which effect to play
example: lightning
selector:
select:
options:
- hell
- lightning
- graveyard
- halloween
- blood
- stop
duration:
description: How long the effect should run (seconds)
example: 10
selector:
number:
min: 1
max: 300
unit_of_measurement: seconds
mode: box
variables:
lights_list: |
{{ lights if lights is iterable and lights is not string else [lights] }}
effect_duration: "{{ duration | default(5) }}"
start_time: "{{ now() }}"
sequence:
- action: scene.create
data:
scene_id: halloween_restore
snapshot_entities: "{{ lights_list }}"
- delay:
milliseconds: 400
- choose:
- conditions:
- condition: template
value_template: "{{ effect == 'stop' }}"
sequence:
- repeat:
for_each: "{{ lights_list }}"
sequence:
- target:
entity_id: "{{ repeat.item }}"
data:
brightness: 255
xy_color:
- 0.3227
- 0.329
transition: 2
action: light.turn_on
- stop: Halloween effect stopped
- conditions:
- condition: template
value_template: "{{ effect == 'hell' }}"
sequence:
- repeat:
for_each: "{{ lights_list }}"
sequence:
- target:
entity_id: "{{ repeat.item }}"
data:
brightness: 200
xy_color:
- 0.6736
- 0.3221
action: light.turn_on
- delay:
milliseconds: 100
- delay:
milliseconds: 1000
- repeat:
until:
- condition: template
value_template: "{{ (now() - start_time).total_seconds() > effect_duration }}"
sequence:
- choose:
- conditions:
- condition: template
value_template: >-
{{ (now() - start_time).total_seconds() >
effect_duration }}
sequence:
- stop: >-
Hell effect stopped after {{ effect_duration }}
seconds
- repeat:
for_each: "{{ lights_list }}"
sequence:
- variables:
colors:
- - 0.7006
- 0.2993
- - 0.6736
- 0.3221
- - 0.6389
- 0.3548
- - 0.675
- 0.322
brightness_levels:
- 255
- 200
- 150
- 100
- target:
entity_id: "{{ repeat.item }}"
data:
xy_color: "{{ colors | random }}"
brightness: "{{ brightness_levels | random }}"
transition: "{{ range(2,4) | random }}"
action: light.turn_on
- delay:
milliseconds: 150
- delay:
seconds: "{{ range(4,7) | random }}"
- conditions:
- condition: template
value_template: "{{ effect == 'lightning' }}"
sequence:
- repeat:
for_each: "{{ lights_list }}"
sequence:
- target:
entity_id: "{{ repeat.item }}"
data:
brightness: 5
xy_color:
- 0.3127
- 0.329
action: light.turn_on
- delay:
milliseconds: 100
- delay:
milliseconds: 1000
- repeat:
until:
- condition: template
value_template: "{{ (now() - start_time).total_seconds() > effect_duration }}"
sequence:
- choose:
- conditions:
- condition: template
value_template: >-
{{ (now() - start_time).total_seconds() >
effect_duration }}
sequence:
- stop: >-
Lightning effect stopped after {{ effect_duration }}
seconds
- variables:
lightning_wait_time: "{{ range(2,4) | random }}"
lightning_count: "{{ range(4,10) | random }}"
- repeat:
for_each: "{{ lights_list }}"
sequence:
- target:
entity_id: "{{ repeat.item }}"
data:
brightness: "{{ range(2,10) | random }}"
xy_color:
- 0.3127
- 0.329
transition: 1
action: light.turn_on
- delay:
milliseconds: 50
- delay:
seconds: "{{ lightning_wait_time }}"
- repeat:
count: "{{ lightning_count }}"
sequence:
- choose:
- conditions:
- condition: template
value_template: >-
{{ (now() - start_time).total_seconds() >
effect_duration }}
sequence:
- stop: >-
Lightning effect stopped after {{
effect_duration }} seconds
- repeat:
for_each: "{{ lights_list }}"
sequence:
- target:
entity_id: "{{ repeat.item }}"
data:
brightness: 255
xy_color:
- 0.3227
- 0.329
transition: 0
action: light.turn_on
- delay:
milliseconds: 50
- delay:
milliseconds: "{{ range(20,200) | random }}"
- repeat:
for_each: "{{ lights_list }}"
sequence:
- target:
entity_id: "{{ repeat.item }}"
data:
brightness: "{{ range(3,10) | random }}"
xy_color:
- 0.3127
- 0.329
transition: 0
action: light.turn_on
- delay:
milliseconds: 100
- delay:
milliseconds: "{{ range(200,600) | random }}"
- conditions:
- condition: template
value_template: "{{ effect == 'graveyard' }}"
sequence:
- repeat:
for_each: "{{ lights_list }}"
sequence:
- target:
entity_id: "{{ repeat.item }}"
data:
brightness: 40
xy_color:
- 0.2039
- 0.4443
action: light.turn_on
- delay:
milliseconds: 100
- delay:
milliseconds: 1000
- repeat:
until:
- condition: template
value_template: "{{ (now() - start_time).total_seconds() > effect_duration }}"
sequence:
- choose:
- conditions:
- condition: template
value_template: >-
{{ (now() - start_time).total_seconds() >
effect_duration }}
sequence:
- stop: >-
Graveyard effect stopped after {{ effect_duration }}
seconds
- repeat:
for_each: "{{ lights_list }}"
sequence:
- variables:
colors:
- - 0.1724
- 0.6531
- - 0.2039
- 0.4443
- - 0.1607
- 0.2218
- - 0.2182
- 0.6225
- - 0.1649
- 0.5703
- - 0.2127
- 0.3608
- - 0.1532
- 0.2947
- - 0.194
- 0.4953
- - 0.1781
- 0.2843
- - 0.2458
- 0.5841
brightness_levels:
- 30
- 35
- 40
- 45
- 50
- 60
- target:
entity_id: "{{ repeat.item }}"
data:
xy_color: "{{ colors | random }}"
brightness: "{{ brightness_levels | random }}"
transition: "{{ range(5,10) | random }}"
action: light.turn_on
- delay:
milliseconds: 200
- delay:
seconds: "{{ range(6,14) | random }}"
- conditions:
- condition: template
value_template: "{{ effect == 'halloween' }}"
sequence:
- repeat:
for_each: "{{ lights_list }}"
sequence:
- target:
entity_id: "{{ repeat.item }}"
data:
brightness: 200
xy_color:
- 0.6389
- 0.3548
action: light.turn_on
- delay:
milliseconds: 100
- delay:
milliseconds: 1000
- repeat:
until:
- condition: template
value_template: "{{ (now() - start_time).total_seconds() > effect_duration }}"
sequence:
- choose:
- conditions:
- condition: template
value_template: >-
{{ (now() - start_time).total_seconds() >
effect_duration }}
sequence:
- stop: >-
Halloween effect stopped after {{ effect_duration }}
seconds
- repeat:
for_each: "{{ lights_list }}"
sequence:
- variables:
colors:
- - 0.6389
- 0.3548
- - 0.3645
- 0.1765
- - 0.3833
- 0.1591
- - 0.5801
- 0.3959
- - 0.2138
- 0.7097
- - 0.2679
- 0.6616
brightness_levels:
- 150
- 180
- 200
- 220
- target:
entity_id: "{{ repeat.item }}"
data:
xy_color: "{{ colors | random }}"
brightness: "{{ brightness_levels | random }}"
transition: "{{ range(3,6) | random }}"
action: light.turn_on
- delay:
milliseconds: 150
- delay:
seconds: "{{ range(4,9) | random }}"
- conditions:
- condition: template
value_template: "{{ effect == 'blood' }}"
sequence:
- repeat:
for_each: "{{ lights_list }}"
sequence:
- target:
entity_id: "{{ repeat.item }}"
data:
brightness: 10
xy_color:
- 0.675
- 0.322
action: light.turn_on
- delay:
milliseconds: 100
- delay:
milliseconds: 1000
- repeat:
until:
- condition: template
value_template: "{{ (now() - start_time).total_seconds() > effect_duration }}"
sequence:
- choose:
- conditions:
- condition: template
value_template: >-
{{ (now() - start_time).total_seconds() >
effect_duration }}
sequence:
- stop: >-
Blood effect stopped after {{ effect_duration }}
seconds
- repeat:
for_each: "{{ lights_list }}"
sequence:
- variables:
colors:
- - 0.675
- 0.322
- - 0.7006
- 0.2993
- - 0.685
- 0.3088
- target:
entity_id: "{{ repeat.item }}"
data:
xy_color: "{{ colors | random }}"
brightness: "{{ range(150,200) | random }}"
transition: 0.3
action: light.turn_on
- delay:
milliseconds: 200
- repeat:
for_each: "{{ lights_list }}"
sequence:
- target:
entity_id: "{{ repeat.item }}"
data:
brightness: "{{ range(20,40) | random }}"
transition: 0.4
action: light.turn_on
- delay:
milliseconds: 150
- repeat:
for_each: "{{ lights_list }}"
sequence:
- target:
entity_id: "{{ repeat.item }}"
data:
brightness: "{{ range(120,160) | random }}"
transition: 0.3
action: light.turn_on
- delay:
milliseconds: 200
- repeat:
for_each: "{{ lights_list }}"
sequence:
- target:
entity_id: "{{ repeat.item }}"
data:
brightness: "{{ range(5,15) | random }}"
transition: 0.8
action: light.turn_on
- delay:
seconds: "{{ range(2,4) | random }}"
- target:
entity_id: "scene.halloween_restore"
action: scene.turn_on
- data:
entity_id: "scene.halloween_restore"
action: scene.delete
1 Like
Thanks for sharing. It helps me a lot.
With this script it was so easy to set up my Hallowen Scene.
I love the BLOOD PULSE and the Lightning effect most.
1 Like
ste-ta
(ste-ta)
October 31, 2025, 11:02am
9
Hey,
haven’t tested but should be possible usingscript.turn_on
See Scripts - Home Assistant
script:
script_1:
sequence:
- action: script.turn_on
target:
entity_id: script.script_2
# Perform some other steps here while second script runs...
# Now wait for called script to complete.
- wait_template: "{{ is_state('script.script_2', 'off') }}"
# Now do some other things...
script_2:
sequence:
# Do some things at the same time as the first script...
Regards
This is awesome - thank you!!
Can we hold our breath for a Christmas version since I missed Halloween?
1 Like
obbekjaer
(Brian Jensen)
November 7, 2025, 8:07pm
12
This is awesome! I was just about to write that the stop command/scene on V1 gave me an error (but stopped the script nonetheless). V2 works without a hitch, stops like it should and sets the lights at a nice level. Top work!
Sidenote: Lightning works when you’re listening to KI/KI on a Friday night too!
Edit: Okay, it seems that if I cycle through several effects, the stop effect goes to a Graveyard-ish setup instead of warm white. Ah, I get it. On the github, you mention that stop defaults to a warm white. But in the script, you actually make a backup of the previous settings, so if you shift from one effect to the next without stopping first, the previous effect is now the backup. Maybe have two options? One that resets to a hardcoded state (warm white) and one that uses the backup method?
k981
November 9, 2025, 11:00am
13
@ste-ta I just wanted to take a moment to thank you! We setup the script last minute for Halloween, and the kids, family and neighbours absolutely loved it! Not to mention the SPAF at record highs!
So thank very much for your efforts and work put into this for the community.
I echo @OvalZyre can we hold out some hope for a Christmas version?