# ESP8266 connections: # D8 -> speaker + # RX -> neopixel leds data pin # D0 -> switch # A0 -> voltage divider between VCC and ground (VCC->10kΩ->A0->10kΩ->GND) # Please see the complete elecric scheme esphome: name: luna-hexagon on_boot: - priority: 600 # Initial status initialization then: - light.turn_on: hexagon_sections - priority: -100 # When all is set up. Start the show. then: - script.execute: game_ready_animation # Variables globals: - id: game_selected_section type: int restore_value: no initial_value: '0' web_server: port: 80 version: 3 log: False ota: False esp8266: board: d1_mini_lite # Enable logging (for development) # logger: api: reboot_timeout: 0s ota: - platform: esphome password: "" wifi: reboot_timeout: 0s networks: # Normal connection, for use with home assistant - ssid: !secret wifi_ssid_1 password: !secret wifi_password_1 # Static IP connection, to use with browser: # in the following example, head to http://192.168.0.42 to see the control interface. # Modify according to your home wifi configuration. - ssid: !secret wifi_ssid_2 password: !secret wifi_password_2 manual_ip: static_ip: 192.168.0.42 gateway: 192.168.0.1 subnet: 255.255.255.0 button: - platform: template name: Color wheel id: color_wheel_button icon: "mdi:hexagon-slice-6" on_press: - script.execute: game_ready_animation binary_sensor: # Buttons (connect to a button that shorts to 3v3) - platform: gpio pin: number: D0 mode: input: true pulldown: true id: "pull_cord" internal: True # Debouncing filters: - settle: 10ms - autorepeat: time_off: 100ms time_on: 100ms on_press: then: - script.execute: game_advance_section on_release: then: - script.execute: game_play_section sensor: # Battery level sensor: 500 is less than 4.0v (battery flat), 850 is 5,4v (battery full) # Check with your batteries and change the values accordingly - platform: adc pin: A0 name: "Battery level" icon: 'mdi:battery' update_interval: 1min unit_of_measurement: "%" raw: true filters: - clamp: min_value: 500.0 max_value: 850.0 - calibrate_linear: - 500.0 -> 0.0 - 850.0 -> 100.0 - min: send_first_at: 3 output: - platform: esp8266_pwm pin: D8 id: speaker light: - platform: neopixelbus variant: WS2812 method: type: esp8266_dma pin: GPIO3 # "RX" pin: see https://github.com/Makuna/NeoPixelBus/wiki/ESP8266-NeoMethods#dma-i2s on why this does not break serial logging num_leds: 12 name: "Hexagon Sections" id: hexagon_sections # Component to play Ring Tone Text Transfer Language # (Nokia ringtone format) on a digital pin rtttl: output: speaker on_finished_playback: # - script.execute: game_ready_animation - script.execute: id: set_section_color section: !lambda return id(game_selected_section); r: 1.0 g: 1.0 b: 1.0 # ---- Scripts ---- script: # Set section color. Section is 0-5 - id: set_section_color parameters: section: int r: float g: float b: float then: - light.addressable_set: id: hexagon_sections range_from: !lambda return section * 2; range_to: !lambda return section * 2 + 1; red: !lambda return r; green: !lambda return g; blue: !lambda return b; #transition_length: 1s; - id: game_ready_animation then: - script.execute: id: set_section_color section: 0 r: 1.0 g: 0.0 b: 0.0 - delay: 200ms - script.execute: id: set_section_color section: 1 r: 0.0 g: 1.0 b: 0.0 - delay: 200ms - script.execute: id: set_section_color section: 2 r: 0.0 g: 0.0 b: 1.0 - delay: 200ms - script.execute: id: set_section_color section: 3 r: 1.0 g: 1.0 b: 0.0 - delay: 200ms - script.execute: id: set_section_color section: 4 r: 1.0 g: 0.0 b: 1.0 - delay: 200ms - script.execute: id: set_section_color section: 5 r: 0.0 g: 1.0 b: 1.0 - delay: 200ms - id: game_advance_section then: # Stop playback - rtttl.stop # Turn off all sections - repeat: count: 6 then: lambda: |- id(set_section_color).execute(iteration, 0, 0, 0); # Increment section counter - lambda: if (id(game_selected_section) >= 5) id(game_selected_section) = 0; else id(game_selected_section) += 1; # Turn on corresponding section - script.execute: id: set_section_color section: !lambda return id(game_selected_section); r: !lambda if (id(game_selected_section) < 3) return 0.0; else return 1.0; g: !lambda if (id(game_selected_section) == 0 || id(game_selected_section) == 3 || id(game_selected_section) == 4) return 0.0; else return 1.0; b: !lambda if (id(game_selected_section) % 2 == 0) return 1.0; else return 0.0; - logger.log: format: "Selected section %d" args: [ 'id(game_selected_section)' ] - id: game_play_section then: - rtttl.play: rtttl: !lambda |- switch(id(game_selected_section)) { case 0: return "BabyElep:d=8,o=6,b=125:f.,16a5,c,f,a,g,f,d,b5,c,2p.,f.,16a5,c,f,a,g,f,d,2c.,d,1g#5,d,g#5,f5"; case 1: return "Moonligt:d=4,o=6,b=160:f.,16p,8f,8f,8g,8f,8e,d.,8p,d.,8p,8e,8e,8f,g.,32p,8f,8g,a,a,8g,8c.,16p,f.,16p,8f,8f,8g,8f,8e,d.,8p,8p,8e,8e,8f,g.,32p,8f,8g,a,a,8g,8c."; case 2: return "Smurfs:d=32,o=5,b=200:4c#6,16p,4f#6,p,16c#6,p,8d#6,p,8b,p,4g#,16p,4c#6,p,16a#,p,8f#,p,8a#,p,4g#,4p,g#,p,a#,p,b,p,c6,p,4c#6,16p,4f#6,p,16c#6,p,8d#6,p,8b,p,4g#,16p,4c#6,p,16a#,p,8b,p,8f,p,4f#"; case 3: return "SecretOf:d=4,o=5,b=180:8e6,8p,8e6,8g6,8f#6,8e6,d6,2e6,8p,8d6,8p,8d6,8c6,8b,8d6,8c6,8p,8c6,8p,b,p,8e6,8p,e.6,8g6,8f#6,8e6,d6,2e6,8p,8f#6,8g6,8p,8g6,8p,a6,p,f#6,8p,8g6,8f#6,8e6,8d6,8f#6,8g6,8p,8g6,8p,f#6"; case 4: return "PinkPanther:d=4,o=5,b=160:8d#,8e,2p,8f#,8g,2p,8d#,8e,16p,8f#,8g,16p,8c6,8b,16p,8d#,8e,16p,8b,2a#,2p,16a,16g,16e,16d,2e"; case 5: default: return "mario:d=4,o=5,b=100:16e6,16e6,32p,8e6,16c6,8e6,8g6,8p,8g,8p,8c6,16p,8g,16p,8e,16p,8a,8b,16a#,8a,16g.,16e6,16g6,8a6,16f6,8g6,8e6,16c6,16d6,8b,16p,8c6,16p,8g,16p,8e,16p,8a,8b,16a#,8a,16g.,16e6,16g6,8a6,16f6,8g6,8e6,16c6,16d6,8b,8p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16g#,16a,16c6,16p,16a,16c6,16d6,8p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16c7,16p,16c7,16c7,p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16g#,16a,16c6,16p,16a,16c6,16d6,8p,16d#6,8p,16d6,8p,16c6"; }