🎃 Halloween Atmosphere Script - 5 Spooky Lighting Effects for Your Smart Home

Hi everyone! :ghost:

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

:clapper: What It Does

This script provides 5 different Halloween effects for your RGB lights:

  • :fire: Hell - Flickering red and orange flames
  • :zap: Lightning - Dramatic white flashes with darkness (lightning strikes traveling across rooms)
  • :headstone: Graveyard - Eerie green-blue fog with very low brightness
  • :jack_o_lantern: Halloween - Classic orange, purple, and green color transitions
  • :stop_sign: Stop - Cleanly resets all lights

:sparkles: 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

:package: Installation

GitHub Repository:

Quick Install:

  1. Copy the script from the repository
  2. Go to Settings → Automations & Scenes → Scripts → Add Script
  3. Edit in YAML and paste
  4. Save!

Usage:

service: script.halloween_atmosphere
data:
  lights:
    - light.living_room
    - light.kitchen
  effect: hell  # or: lightning, graveyard, halloween, stop

:hammer_and_wrench: 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!

:bulb: 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

:jack_o_lantern: Perfect For

  • Halloween parties
  • Haunted house setups
  • Movie nights (horror genre)
  • Spooky ambiance all October
  • Scaring trick-or-treaters

:bug: 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

:handshake: 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! :jack_o_lantern::ghost:

13 Likes

Thanks for sharing.
Works great!

2 Likes

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?

check out the notes on the GitHub page…some details there on changing the effect speed

Change those lines:

sequence:
        - variables:
         # Random wait time until next lightning
         lightning_wait_time: "{{ range(2, 6) | random }}"
         # Number of flashes in this sequence
         lightning_count: "{{ range(2, 4) | random }}"

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!

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 :drop_of_blood: BLOOD PULSE and the :zap: Lightning effect most.

1 Like

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? :stuck_out_tongue:

1 Like

WIP:

2 Likes

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! :smiley:

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?

@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?