Close

MAJOR UPDATE!!!

A project log for LEGO Saturn V and Lunar Module Come to Life

Add some interactivity to the LEGO Apollo sets! Includes exhaust plumes, audio, a countdown timer and warning lights.

ben-brooksBen Brooks 11/04/2024 at 20:370 Comments

Recently I decided to make a major update to this project, with the end result essentially being the same but all of the components and code being updated/replaced.

Why you might ask? Partly just-because, but also largely because my son has gotten old enough to be a big fan of LEGO and space (and I happened to have bought a second Saturn V a long time ago), so it made sense to redo mine and then have an easier way to duplicate it for him (as well as a variation for his younger sister). Major changes include:

I've updated the Thingiverse link with the new 3D models in case anyone wants to use them as well as uploaded the KiCAD files for the PCB. Here's the ESPHome YAML (mostly-done, but still a bit of a work-in-progress):

esphome:
  name: lego-apollo-11
  friendly_name: LEGO Apollo 11

esp32:
  board: esp32dev
  framework:
    type: arduino
#    type: esp-idf

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

ota:
  - platform: esphome
    password: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Lego-Apollo-11 Fallback Hotspot"
    password: "xxxxxxxxxxxxxx"

#Removed for Bluetooth Proxy feature
#captive_portal:

#bluetooth_proxy:
#  active: true

#esp32_ble_tracker:

status_led:
  pin:
    number: GPIO2
    inverted: true

button:
  - platform: restart
    name: Restart
  - platform: safe_mode
    name: Restart (Safe Mode)

  - platform: template
    name: "Launch"
    icon: mdi:rocket-launch
    on_press:
      - script.execute: sv_launch

  - platform: template
    name: "TLI"
    icon: mdi:rocket
    on_press:
      - script.execute: sv_tli

  - platform: template
    name: "Lunar Landing"
    icon: mdi:rocket-outline
    on_press:
      - script.execute: lunar_landing

  - platform: template
    name: "ABORT"
    icon: mdi:alert-octagon
    on_press:
      - dfplayer.stop
      - script.stop: sv_launch
      - script.stop: sv_tli
      - script.stop: lunar_landing
      - script.stop: timer_countdown
      - script.stop: timer_countup
      - script.stop: alarm_1202_1
      - script.stop: alarm_1202_2
      - script.stop: alarm_1201
      - switch.turn_off: saturn_v_exhaust_plume
      - switch.turn_off: lunar_lander_exhaust_plume
      - light.turn_off: saturn_v
      - light.turn_off: lunar_lander
      - light.turn_off: alarm_1201_LED
      - light.turn_off: alarm_1202_LED
      - light.turn_off: fuel_led
      - light.turn_off: saturn_v_section_1_leds
      - light.turn_off: saturn_v_section_2_leds
      - light.turn_off: saturn_v_section_3_leds
      - light.turn_off: saturn_v_section_4_leds
      - light.turn_off: saturn_v_section_5_leds
      - light.turn_off: saturn_v_section_6_leds
      - light.turn_off: lunar_lander_section_1_leds
      - light.turn_off: lunar_lander_section_2_leds
      - light.turn_off: lunar_lander_section_3_leds
      - light.turn_off: lunar_lander_section_4_leds
      - light.turn_off: lunar_lander_section_5_leds
      - light.turn_off: lunar_lander_section_6_leds

text_sensor:
  - platform: wifi_info
    ip_address:
      name: IP Address

sensor:
  - platform: wifi_signal
    name: WiFi Strength
    update_interval: 60s
    disabled_by_default: true
  - platform: uptime
    name: Uptime
    disabled_by_default: true

# Stuff for the clock display
globals:
  # Affects how the countdown/countup timers are displayed
  - id: clock_display
    type: int
    restore_value: no
    initial_value: '1'

  - id: minute_1
    type: int
    restore_value: no
    initial_value: '0'

  - id: minute_2
    type: int
    restore_value: no
    initial_value: '1'

  - id: second_1
    type: int
    restore_value: no
    initial_value: '2'

  - id: second_2
    type: int
    restore_value: no
    initial_value: '3'

time:
  - platform: sntp
    id: sntp_time

display:
    platform: tm1637
    id: tm1637_display
    clk_pin: GPIO16
    dio_pin: GPIO17
    length: 4
    update_interval: 100ms
    lambda: |-
      static int i = 0;
      if (id(sv_launch).is_running() or id(sv_tli).is_running() or id(lunar_landing).is_running()) {
        if (id(clock_display) == 0) {
          // Blank Display
          it.print("    ");
        } else if (id(clock_display) == 1) {
            // Display single minute & seconds with '-'
            it.print(0, "-");
            it.printf(1, "%i.", id(minute_2));
            it.printf(2, "%i", id(second_1));
            it.printf(3, "%i", id(second_2));
        } else if (id(clock_display) == 2) {
          // Display full minutes & seconds, but exclude first minute
            it.print(0, " ");;
            it.printf(1, "%i.", id(minute_2));
            it.printf(2, "%i", id(second_1));
            it.printf(3, "%i", id(second_2));
        } else if (id(clock_display) == 3) {
          // Display full minutes & seconds
            it.printf(0, "%i", id(minute_1));
            it.printf(1, "%i.", id(minute_2));
            it.printf(2, "%i", id(second_1));
            it.printf(3, "%i", id(second_2));
        } else {}
      }
      else {
        i++;
        if (i > 10)
          it.strftime("%H%M", id(sntp_time).now());
        else
          it.strftime("%H.%M", id(sntp_time).now());
        if (i == 20)
          i = 0;
      }

      if (id(lunar_landing).is_running() and (id(minute_1) == 0) and (id(minute_2) == 1) and (id(second_1) == 0) and ((id(second_2) == 0))) {
        id(fuel_led).turn_on().set_rgb(0.96, 1.0, 0.01).perform();
      } else if (id(lunar_landing).is_running() and (id(minute_1) == 0) and (id(minute_2) == 0) and (id(second_1) == 3) and ((id(second_2) == 0))) {
          id(fuel_led).turn_on().set_rgb(1.0, 0, 0.06).perform();
      } else {}


light:
  - platform: neopixelbus
    type: GRB            #GRBW  
    variant: WS2812      #WS2812 #SK6812 
    pin: GPIO04
    method:
      type: esp32_rmt
      channel: 0   

#  - platform: esp32_rmt_led_strip
#    rgb_order: GRB
#    pin: GPIO04
#    rmt_channel: 0
#    chipset: WS2812


    num_leds: 60
    restore_mode: ALWAYS_OFF
    name: "Saturn V"
    id: saturn_v
    icon: mdi:rocket
#    internal: true
    on_turn_on:
      - if:
          condition:
            - switch.is_on: saturn_v_exhaust_plume
          then:
      # Turn Off Entire Strip/Partitions
            - switch.turn_off: saturn_v_exhaust_plume
      # Turn the main strip back on
            - light.turn_on: saturn_v
 
  - platform: partition
    name: "Saturn V - Section 1 LEDs"
    id: saturn_v_section_1_leds
    icon: mdi:led-strip
    restore_mode: ALWAYS_OFF
#    internal: true
    segments:
      - id: saturn_v
        from: 50
        to: 59
    effects:
      - addressable_flicker:
          name: Flicker
          update_interval: 16ms
          intensity: 10%

  - platform: partition
    name: "Saturn V - Section 2 LEDs"
    id: saturn_v_section_2_leds
    icon: mdi:led-strip
    restore_mode: ALWAYS_OFF
#    internal: true
    segments:
      - id: saturn_v
        from: 40
        to: 49
    effects:
      - addressable_flicker:
          name: Flicker
          update_interval: 16ms
          intensity: 10%

  - platform: partition
    name: "Saturn V - Section 3 LEDs"
    id: saturn_v_section_3_leds
    icon: mdi:led-strip
    restore_mode: ALWAYS_OFF
#    internal: true
    segments:
      - id: saturn_v
        from: 30
        to: 39
    effects:
      - addressable_flicker:
          name: Flicker
          update_interval: 16ms
          intensity: 10%

  - platform: partition
    name: "Saturn V - Section 4 LEDs"
    id: saturn_v_section_4_leds
    icon: mdi:led-strip
    restore_mode: ALWAYS_OFF
#    internal: true
    segments:
      - id: saturn_v
        from: 20
        to: 29
    effects:
      - flicker:
          name: Flicker
          alpha: 95%
          intensity: 5%

  - platform: partition
    name: "Saturn V - Section 5 LEDs"
    id: saturn_v_section_5_leds
    icon: mdi:led-strip
    restore_mode: ALWAYS_OFF
#    internal: true
    segments:
      - id: saturn_v
        from: 10
        to: 19
    effects:
      - flicker:
          name: Flicker
          alpha: 95%
          intensity: 5%

  - platform: partition
    name: "Saturn V - Section 6 LEDs"
    id: saturn_v_section_6_leds
    icon: mdi:led-strip
    restore_mode: ALWAYS_OFF
#    internal: true
    segments:
      - id: saturn_v
        from: 0
        to: 9
    effects:
      - flicker:
          name: Flicker
          alpha: 95%
          intensity: 5%


  - platform: neopixelbus
    type: GRBW           #GRB    #GRBW
    variant: SK6812      #WS2812 #SK6812 
    pin: GPIO25
    method:
      type: esp32_rmt
      channel: 1       


#  - platform: esp32_rmt_led_strip
#    rgb_order: GRB
#    pin: GPIO25
#    rmt_channel: 1
#    chipset: WS2812


    num_leds: 6
    restore_mode: ALWAYS_OFF
    name: "Lunar Lander"
    id: lunar_lander
    icon: mdi:rocket
#    internal: true

  - platform: partition
    name: "Lunar Lander - Section 1 LEDs"
    id: lunar_lander_section_1_leds
    icon: mdi:led-strip
    restore_mode: ALWAYS_OFF
#    internal: true
    segments:
      - id: lunar_lander
        from: 0
        to: 0
    effects:
      - flicker:
          name: Flicker
          alpha: 95%
          intensity: 5%

  - platform: partition
    name: "Lunar Lander - Section 2 LEDs"
    id: lunar_lander_section_2_leds
    icon: mdi:led-strip
    restore_mode: ALWAYS_OFF
#    internal: true
    segments:
      - id: lunar_lander
        from: 1
        to: 1
    effects:
      - flicker:
          name: Flicker
          alpha: 95%
          intensity: 5%

  - platform: partition
    name: "Lunar Lander - Section 3 LEDs"
    id: lunar_lander_section_3_leds
    icon: mdi:led-strip
    restore_mode: ALWAYS_OFF
#    internal: true
    segments:
      - id: lunar_lander
        from: 2
        to: 2
    effects:
      - flicker:
          name: Flicker
          alpha: 95%
          intensity: 5%

  - platform: partition
    name: "Lunar Lander - Section 4 LEDs"
    id: lunar_lander_section_4_leds
    icon: mdi:led-strip
    restore_mode: ALWAYS_OFF
#    internal: true
    segments:
      - id: lunar_lander
        from: 3
        to: 3
    effects:
      - flicker:
          name: Flicker
          alpha: 95%
          intensity: 5%

  - platform: partition
    name: "Lunar Lander - Section 5 LEDs"
    id: lunar_lander_section_5_leds
    icon: mdi:led-strip
    restore_mode: ALWAYS_OFF
#    internal: true
    segments:
      - id: lunar_lander
        from: 4
        to: 4
    effects:
      - flicker:
          name: Flicker
          alpha: 95%
          intensity: 5%

  - platform: partition
    name: "Lunar Lander - Section 6 LEDs"
    id: lunar_lander_section_6_leds
    icon: mdi:led-strip
    restore_mode: ALWAYS_OFF
#    internal: true
    segments:
      - id: lunar_lander
        from: 5
        to: 5
    effects:
      - flicker:
          name: Flicker
          alpha: 95%
          intensity: 5%


  - platform: binary
    name: "Alarm 1201 LED"
    id: alarm_1201_LED
    output: output_1201_led
    icon: mdi:alarm-light
    restore_mode: ALWAYS_OFF

  - platform: binary
    name: "Alarm 1202 LED"
    id: alarm_1202_LED
    output: output_1202_led
    icon: mdi:alarm-light
    restore_mode: ALWAYS_OFF

  - platform: neopixelbus
    type: RGB                  #RGB            
    variant: WS2812             #SK6812     
    pin: GPIO23
    method:
      type: esp32_rmt
      channel: 2


#  - platform: esp32_rmt_led_strip
#    rgb_order: RGB
#    pin: GPIO23
#    rmt_channel: 2
#    chipset: WS2812

    num_leds: 1
    name: "Fuel LED"
    id: fuel_led
    icon: mdi:fuel
    restore_mode: ALWAYS_OFF
#    internal: true
    default_transition_length: 0s

switch:
# Saturn V Partition Effects Switch
  - platform: template
    name: Saturn V Exhaust Plume
    id: saturn_v_exhaust_plume
    icon: mdi:rocket-launch
    optimistic: true
    turn_on_action:
      - if:
          condition:
            or:
              - script.is_running: sv_launch
              - script.is_running: sv_tli
          then:
            # Do nothing
          else:
            - if:
                condition:
                  - light.is_on: saturn_v
                then:
                  - light.turn_off: saturn_v

            # Individual Partitions/sections
            - light.turn_on:
                id: saturn_v_section_1_leds
                brightness: 100%
                red: 100%
                green: 72%
                blue: 0%
                transition_length: 1.5s
            - light.turn_on:
                id: saturn_v_section_2_leds
                brightness: 100%
                red: 100%
                green: 60%
                blue: 0%
                transition_length: 1.5s
            - light.turn_on:
                id: saturn_v_section_3_leds
                brightness: 100%
                red: 100%
                green: 48%
                blue: 0%
                transition_length: 1.5s
            - light.turn_on:
                id: saturn_v_section_4_leds
                brightness: 100%
                red: 100%
                green: 36%
                blue: 0%
                transition_length: 1.5s
            - light.turn_on:
                id: saturn_v_section_5_leds
                brightness: 100%
                red: 100%
                green: 12%
                blue: 0%
                transition_length: 1.5s
            - light.turn_on:
                id: saturn_v_section_6_leds
                brightness: 100%
                red: 100%
                green: 0%
                blue: 0%
                transition_length: 1.5s

            - delay: 1.5s

            - light.turn_on:
                id: saturn_v_section_1_leds
                effect: Flicker
            - light.turn_on:
                id: saturn_v_section_2_leds
                effect: Flicker
            - light.turn_on:
                id: saturn_v_section_3_leds
                effect: Flicker
            - light.turn_on:
                id: saturn_v_section_4_leds
                effect: Flicker
            - light.turn_on:
                id: saturn_v_section_5_leds
                effect: Flicker
            - light.turn_on:
                id: saturn_v_section_6_leds
                effect: Flicker

    turn_off_action: 
      - light.turn_off: saturn_v_section_1_leds
      - light.turn_off: saturn_v_section_2_leds
      - light.turn_off: saturn_v_section_3_leds
      - light.turn_off: saturn_v_section_4_leds
      - light.turn_off: saturn_v_section_5_leds
      - light.turn_off: saturn_v_section_6_leds


# Lunar Lander Partition Effects Switch
  - platform: template
    name: Lunar Lander Exhaust Plume
    id: lunar_lander_exhaust_plume
    icon: mdi:rocket
    optimistic: true
    turn_on_action:
      - if:
          condition:
            - script.is_running: lunar_landing
          then:
            # Do nothing
          else:
            - if:
                condition:
                  - light.is_on: lunar_lander
                then:
                  - light.turn_off: lunar_lander

            # Individual Partitions/sections
            - light.turn_on:
                id: lunar_lander_section_1_leds
                brightness: 100%
                red: 100%
                green: 72%
                blue: 0%
                white: 0%
                transition_length: 1.5s
            - light.turn_on:
                id: lunar_lander_section_2_leds
                brightness: 100%
                red: 100%
                green: 60%
                blue: 0%
                white: 0%
                transition_length: 1.5s
            - light.turn_on:
                id: lunar_lander_section_3_leds
                brightness: 100%
                red: 100%
                green: 48%
                blue: 0%
                white: 0%
                transition_length: 1.5s
            - light.turn_on:
                id: lunar_lander_section_4_leds
                brightness: 100%
                red: 100%
                green: 36%
                blue: 0%
                white: 0%
                transition_length: 1.5s
            - light.turn_on:
                id: lunar_lander_section_5_leds
                brightness: 100%
                red: 100%
                green: 12%
                blue: 0%
                white: 0%
                transition_length: 1.5s
            - light.turn_on:
                id: lunar_lander_section_6_leds
                brightness: 100%
                red: 100%
                green: 0%
                blue: 0%
                white: 0%
                transition_length: 1.5s

            - delay: 1.5s

            - light.turn_on:
                id: lunar_lander_section_1_leds
                effect: Flicker
            - light.turn_on:
                id: lunar_lander_section_2_leds
                effect: Flicker
            - light.turn_on:
                id: lunar_lander_section_3_leds
                effect: Flicker
            - light.turn_on:
                id: lunar_lander_section_4_leds
                effect: Flicker
            - light.turn_on:
                id: lunar_lander_section_5_leds
                effect: Flicker
            - light.turn_on:
                id: lunar_lander_section_6_leds
                effect: Flicker

    turn_off_action: 
      - light.turn_off: lunar_lander_section_1_leds
      - light.turn_off: lunar_lander_section_2_leds
      - light.turn_off: lunar_lander_section_3_leds
      - light.turn_off: lunar_lander_section_4_leds
      - light.turn_off: lunar_lander_section_5_leds
      - light.turn_off: lunar_lander_section_6_leds


output:
  - platform: gpio
    pin: GPIO21
    id: output_1201_led
  - platform: gpio
    pin: GPIO22
    id: output_1202_led


uart:
  tx_pin: GPIO19 
  rx_pin: GPIO18
  baud_rate: 9600

dfplayer:


script:

  - id: sv_launch
    mode: single  
    then:
      - script.stop: sv_tli
      - script.stop: lunar_landing
      - script.stop: timer_countdown
      - script.stop: timer_countup
      - light.turn_off: saturn_v
      - light.turn_off: lunar_lander
      - switch.turn_off: saturn_v_exhaust_plume
      - switch.turn_off: lunar_lander_exhaust_plume
      - light.turn_off: alarm_1201_LED
      - light.turn_off: alarm_1202_LED
      - light.turn_off: fuel_led
      - dfplayer.play_folder:
          folder: 1
          file: 1

      # Start countdown timer
      - globals.set:
          id: clock_display
          value: '1'
      - globals.set:
          id: minute_1
          value: '0'
      - globals.set:
          id: minute_2
          value: '0'
      - globals.set:
          id: second_1
          value: '3'
      - globals.set:
          id: second_2
          value: '1'

      - script.execute: timer_countdown

      - delay: 22.5s

      - switch.turn_on: saturn_v_exhaust_plume
      
      - light.turn_on:
          id: saturn_v_section_1_leds
          brightness: 25%
          red: 100%
          green: 72%
          blue: 0%
          transition_length: 1.5s
      - light.turn_on:
          id: saturn_v_section_2_leds
          brightness: 25%
          red: 100%
          green: 60%
          blue: 0%
          transition_length: 1.5s
      - light.turn_on:
          id: saturn_v_section_3_leds
          brightness: 25%
          red: 100%
          green: 48%
          blue: 0%
          transition_length: 1.5s
      - light.turn_on:
          id: saturn_v_section_4_leds
          brightness: 25%
          red: 100%
          green: 36%
          blue: 0%
          transition_length: 1.5s
      - light.turn_on:
          id: saturn_v_section_5_leds
          brightness: 25%
          red: 100%
          green: 12%
          blue: 0%
          transition_length: 1.5s
      - light.turn_on:
          id: saturn_v_section_6_leds
          brightness: 25%
          red: 100%
          green: 0%
          blue: 0%
          transition_length: 1.5s

      - delay: 1.5s

      - light.turn_on:
          id: saturn_v_section_1_leds
          effect: Flicker
      - light.turn_on:
          id: saturn_v_section_2_leds
          effect: Flicker
      - light.turn_on:
          id: saturn_v_section_3_leds
          effect: Flicker
      - light.turn_on:
          id: saturn_v_section_4_leds
          effect: Flicker
      - light.turn_on:
          id: saturn_v_section_5_leds
          effect: Flicker
      - light.turn_on:
          id: saturn_v_section_6_leds
          effect: Flicker
      
      - delay: 7.5s

      - light.turn_on:
          id: saturn_v_section_1_leds
          brightness: 100%
      - light.turn_on:
          id: saturn_v_section_2_leds
          brightness: 100%
      - light.turn_on:
          id: saturn_v_section_3_leds
          brightness: 100%
      - light.turn_on:
          id: saturn_v_section_4_leds
          brightness: 100%
      - light.turn_on:
          id: saturn_v_section_5_leds
          brightness: 100%
      - light.turn_on:
          id: saturn_v_section_6_leds
          brightness: 100%
      
      # Keep script running until audio is done
      - delay: 30s

      # Keep script running so clock doesn't display until the countup would stop making sense
      - delay: 100minutes


  - id: sv_tli
    mode: single  
    then:
      - script.stop: sv_launch
      - script.stop: lunar_landing
      - script.stop: timer_countdown
      - script.stop: timer_countup
      - switch.turn_off: lunar_lander_exhaust_plume
      - light.turn_off: lunar_lander
      - light.turn_off: alarm_1201_LED
      - light.turn_off: alarm_1202_LED
      - light.turn_off: fuel_led
      - dfplayer.play_folder:
          folder: 1
          file: 2

      # Start countdown timer
      - globals.set:
          id: clock_display
          value: '3'
      - globals.set:
          id: minute_1
          value: '4'
      - globals.set:
          id: minute_2
          value: '9'
      - globals.set:
          id: second_1
          value: '4'
      - globals.set:
          id: second_2
          value: '5'

      - script.execute: timer_countup

# Added full SV startup here because using the normal startup with transition length messed things up (only added in case it's not already on)
      - switch.turn_on: saturn_v_exhaust_plume
      
      - light.turn_on:
          id: saturn_v_section_1_leds
          brightness: 100%
          red: 100%
          green: 72%
          blue: 0%
          transition_length: 0s
      - light.turn_on:
          id: saturn_v_section_2_leds
          brightness: 100%
          red: 100%
          green: 60%
          blue: 0%
          transition_length: 0s
      - light.turn_on:
          id: saturn_v_section_3_leds
          brightness: 100%
          red: 100%
          green: 48%
          blue: 0%
          transition_length: 0s
      - light.turn_on:
          id: saturn_v_section_4_leds
          brightness: 100%
          red: 100%
          green: 36%
          blue: 0%
          transition_length: 0s
      - light.turn_on:
          id: saturn_v_section_5_leds
          brightness: 100%
          red: 100%
          green: 12%
          blue: 0%
          transition_length: 0s
      - light.turn_on:
          id: saturn_v_section_6_leds
          brightness: 100%
          red: 100%
          green: 0%
          blue: 0%
          transition_length: 0s

      - light.turn_on:
          id: saturn_v_section_1_leds
          effect: Flicker
      - light.turn_on:
          id: saturn_v_section_2_leds
          effect: Flicker
      - light.turn_on:
          id: saturn_v_section_3_leds
          effect: Flicker
      - light.turn_on:
          id: saturn_v_section_4_leds
          effect: Flicker
      - light.turn_on:
          id: saturn_v_section_5_leds
          effect: Flicker
      - light.turn_on:
          id: saturn_v_section_6_leds
          effect: Flicker


      - delay: 20.7s

      - switch.turn_off: saturn_v_exhaust_plume

      # Keep script running until audio is done
      - delay: 35s

      # Keep script running so clock doesn't display until the countup would stop making sense
      - delay: 50minutes


  - id: lunar_landing
    mode: single  
    then:
      - script.stop: sv_launch
      - script.stop: sv_tli
      - script.stop: timer_countdown
      - script.stop: timer_countup
      - switch.turn_off: saturn_v_exhaust_plume
      - switch.turn_off: lunar_lander_exhaust_plume
      - light.turn_off: saturn_v
      - light.turn_off: lunar_lander
      - light.turn_off: alarm_1201_LED
      - light.turn_off: alarm_1202_LED
      - light.turn_off: fuel_led

      # Clear clock
      - globals.set:
          id: clock_display
          value: '0'

      - dfplayer.play_folder:
          folder: 1
          file: 3

      - delay: 33s

      - switch.turn_on: lunar_lander_exhaust_plume

      - light.turn_on:
          id: lunar_lander_section_1_leds
          brightness: 100%
          red: 100%
          green: 72%
          blue: 0%
          white: 0%
          transition_length: 1.5s

      - light.turn_on:
          id: lunar_lander_section_2_leds
          brightness: 100%
          red: 100%
          green: 60%
          blue: 0%
          white: 0%
          transition_length: 1.5s

      - light.turn_on:
          id: lunar_lander_section_3_leds
          brightness: 100%
          red: 100%
          green: 48%
          blue: 0%
          white: 0%
          transition_length: 1.5s

      - light.turn_on:
          id: lunar_lander_section_4_leds
          brightness: 100%
          red: 100%
          green: 36%
          blue: 0%
          white: 0%
          transition_length: 1.5s

      - light.turn_on:
          id: lunar_lander_section_5_leds
          brightness: 100%
          red: 100%
          green: 12%
          blue: 0%
          white: 0%
          transition_length: 1.5s

      - light.turn_on:
          id: lunar_lander_section_6_leds
          brightness: 100%
          red: 100%
          green: 0%
          blue: 0%
          white: 0%
          transition_length: 1.5s

      - delay: 1.5s

      - light.turn_on:
          id: fuel_led
          brightness: 100%
          red: 81%
          green: 96%
          blue: 100%

      # Start countdown timer
      - globals.set:
          id: clock_display
          value: '2'
      - globals.set:
          id: minute_1
          value: '0'
      - globals.set:
          id: minute_2
          value: '4'
      - globals.set:
          id: second_1
          value: '0'
      - globals.set:
          id: second_2
          value: '0'

      - script.execute: timer_countdown

      - light.turn_on:
          id: lunar_lander_section_1_leds
          effect: Flicker
      - light.turn_on:
          id: lunar_lander_section_2_leds
          effect: Flicker
      - light.turn_on:
          id: lunar_lander_section_3_leds
          effect: Flicker
      - light.turn_on:
          id: lunar_lander_section_4_leds
          effect: Flicker
      - light.turn_on:
          id: lunar_lander_section_5_leds
          effect: Flicker
      - light.turn_on:
          id: lunar_lander_section_6_leds
          effect: Flicker

      - delay: 90.75s

      # First 1202 alarm
      - script.execute: alarm_1202_1

      - delay: 30.75s

      # Second 1202 alarm
      - script.execute: alarm_1202_2
      
      - delay: 13s

      # Throttle Down
      - light.turn_on:
          id: lunar_lander_section_1_leds
          brightness: 50%
          transition_length: 1.5s

      - light.turn_on:
          id: lunar_lander_section_2_leds
          brightness: 50%
          transition_length: 1.5s

      - light.turn_on:
          id: lunar_lander_section_3_leds
          brightness: 50%
          transition_length: 1.5s

      - light.turn_on:
          id: lunar_lander_section_4_leds
          brightness: 50%
          transition_length: 1.5s

      - light.turn_on:
          id: lunar_lander_section_5_leds
          brightness: 50%
          transition_length: 1.5s

      - light.turn_on:
          id: lunar_lander_section_6_leds
          brightness: 50%
          transition_length: 1.5s

      - delay: 17.3s

      # 1201 alarm
      - script.execute: alarm_1201

      - delay: 28.7s

      - delay: 30s

      - delay: 14.5s

      # Engine shutdown
      - light.turn_off:
          id: lunar_lander_section_1_leds
          transition_length: 1.5s

      - light.turn_off:
          id: lunar_lander_section_2_leds
          transition_length: 1.5s

      - light.turn_off:
          id: lunar_lander_section_3_leds
          transition_length: 1.5s

      - light.turn_off:
          id: lunar_lander_section_4_leds
          transition_length: 1.5s

      - light.turn_off:
          id: lunar_lander_section_5_leds
          transition_length: 1.5s

      - light.turn_off:
          id: lunar_lander_section_6_leds
          transition_length: 1.5s

      - switch.turn_off: lunar_lander_exhaust_plume

      # Stop countdown
      - script.stop: timer_countdown

      - delay: 50.5s

      - light.turn_off: fuel_led


  - id: alarm_1202_1
    mode: single  
    then:
      - repeat:
          count: 16
          then:
            - light.turn_on:
                id: alarm_1202_LED
                effect: None
            - delay: 412ms
            - light.turn_off: alarm_1202_LED
            - delay: 412ms


  - id: alarm_1202_2
    mode: single  
    then:
      - repeat:
          count: 19
          then:
            - light.turn_on:
                id: alarm_1202_LED
                effect: None
            - delay: 412ms
            - light.turn_off: alarm_1202_LED
            - delay: 412ms


  - id: alarm_1201
    mode: single  
    then:
      - repeat:
          count: 17
          then:
            - light.turn_on:
                id: alarm_1201_LED
                effect: None
            - delay: 400ms # Changed from 412ms to try and get it to sync better. Needed to be faster
            - light.turn_off: alarm_1201_LED
            - delay: 400ms # Changed from 412ms to try and get it to sync better


  - id: timer_countdown
    mode: restart
    then:
      - delay: 1s

      - if:
          condition:
            and:
              - lambda: 'return id(second_2) == 0;'
              - lambda: 'return id(second_1) == 0;'
          then:
            - lambda: |-
                id(minute_2) -= 1;
                id(second_1) = 5;
                id(second_2) = 9;
          else:
            - if:
                condition:
                  - lambda: 'return id(second_2) == 0;'
                then:
                  - lambda: |-
                      id(second_1) -= 1;
                      id(second_2) = 9;
                else:
                  - lambda: |-
                      id(second_2) -= 1;
      - if:
          condition:
            and:
              - lambda: 'return id(second_2) == 0;'
              - lambda: 'return id(second_1) == 0;'
              - lambda: 'return id(minute_2) == 0;'
          then:
            - lambda: |-
                id(clock_display) = 2;
            - script.execute: timer_countup
          else:
            - script.execute: timer_countdown

  - id: timer_countup
    mode: restart
    then:
      - delay: 1s

      - if:
          condition:
            and:
              - lambda: 'return id(clock_display) == 2;'
              - lambda: 'return id(minute_1) != 0;'
          then:
            - lambda: |-
                id(clock_display) = 3;

      - if:
          condition:
            and:
              - lambda: 'return id(minute_2) == 9;'
              - lambda: 'return id(second_1) == 5;'
              - lambda: 'return id(second_2) == 9;'
          then:
            - lambda: |-
                id(minute_1) += 1;
                id(minute_2) = 0;
                id(second_1) = 0;
                id(second_2) = 0;
          else:
            - if:
                condition:
                  and:
                    - lambda: 'return id(second_1) == 5;'
                    - lambda: 'return id(second_2) == 9;'
                then:
                  - lambda: |-
                      id(minute_2) += 1;
                      id(second_1) = 0;
                      id(second_2) = 0;
                else:
                  - if:
                      condition:
                        - lambda: 'return id(second_2) == 9;'
                      then:
                        - lambda: |-
                            id(second_1) += 1;
                            id(second_2) = 0;
                      else:
                        - lambda: |-
                            id(second_2) += 1;
      - script.execute: timer_countup

Discussions