Skip to content

Instantly share code, notes, and snippets.

@WarriorRocker
Created December 23, 2024 19:00
Show Gist options
  • Save WarriorRocker/79e0c1ae2168159fdc7b843499fb4303 to your computer and use it in GitHub Desktop.
Save WarriorRocker/79e0c1ae2168159fdc7b843499fb4303 to your computer and use it in GitHub Desktop.
esphome:
name: jukebox
friendly_name: jukebox
esp32:
board: esp32dev
framework:
type: arduino
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: !secret jukebox_enc_key
services:
- service: dfplayer_play
variables:
file: int
then:
- lambda: 'id(current_file) = file;'
- dfplayer.play: !lambda 'return file;'
- service: dfplayer_play_loop
variables:
file: int
loop_: bool
then:
- lambda: 'id(current_file) = file;'
- dfplayer.play:
file: !lambda 'return file;'
loop: !lambda 'return loop_;'
- service: dfplayer_set_volume
variables:
volume: int
then:
- dfplayer.set_volume: !lambda 'return volume;'
- service: dfplayer_reset
then:
- lambda: 'id(current_file) = 0;'
- dfplayer.reset
- service: dfplayer_stop
then:
- lambda: 'id(current_file) = 0;'
- dfplayer.stop
ota:
password: !secret ota_password
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: 'Jukebox Fallback Hotspot'
password: !secret cap_password
# Enable Captive Portal for fallback hotspot
captive_portal:
# Enable web server interface
web_server:
substitutions:
devicename: 'Jukebox'
esp32_ble_tracker:
bluetooth_proxy:
active: true
globals:
- id: current_file
type: int
restore_value: no
status_led:
pin:
number: GPIO2
inverted: true
# Set up mp3 module pins
uart:
tx_pin: GPIO17
rx_pin: GPIO16
baud_rate: 9600
# Enable DFPlayer Mini
dfplayer:
id: dfplayermini
on_finished_playback:
then:
- lambda: 'id(current_file) = 0;'
- logger.log: 'Playback finished'
binary_sensor:
- platform: status
id: esp_status
name: '${devicename} Status'
- platform: gpio
name: '${devicename} Button 1'
pin:
number: GPIO13
inverted: true
mode:
input: true
pullup: true
filters:
- delayed_off: 10ms
on_press:
then:
- if:
condition:
lambda: 'return id(current_file) != 1;'
then:
- lambda: 'id(current_file) = 1;'
- dfplayer.play: 1
else:
- lambda: 'id(current_file) = 0;'
- dfplayer.stop
- platform: gpio
name: '${devicename} Button 2'
pin:
number: GPIO14
inverted: true
mode:
input: true
pullup: true
filters:
- delayed_off: 10ms
on_press:
then:
- if:
condition:
lambda: 'return id(current_file) != 2;'
then:
- lambda: 'id(current_file) = 2;'
- dfplayer.play: 2
else:
- lambda: 'id(current_file) = 0;'
- dfplayer.stop
- platform: gpio
name: '${devicename} Button 3'
pin:
number: GPIO27
inverted: true
mode:
input: true
pullup: true
filters:
- delayed_off: 10ms
on_press:
then:
- if:
condition:
lambda: 'return id(current_file) != 3;'
then:
- lambda: 'id(current_file) = 3;'
- dfplayer.play: 3
else:
- lambda: 'id(current_file) = 0;'
- dfplayer.stop
- platform: gpio
name: '${devicename} Button 4'
pin:
number: GPIO26
inverted: true
mode:
input: true
pullup: true
filters:
- delayed_off: 10ms
on_press:
then:
- if:
condition:
lambda: 'return id(current_file) != 4;'
then:
- lambda: 'id(current_file) = 4;'
- dfplayer.play: 4
else:
- lambda: 'id(current_file) = 0;'
- dfplayer.stop
- platform: gpio
name: '${devicename} Button 5'
pin:
number: GPIO25
inverted: true
mode:
input: true
pullup: true
filters:
- delayed_off: 10ms
# on_press:
# then:
# - if:
# condition:
# lambda: 'return id(current_file) != 5;'
# then:
# - lambda: 'id(current_file) = 5;'
# - dfplayer.play: 5
# else:
# - lambda: 'id(current_file) = 0;'
# - dfplayer.stop
- platform: gpio
name: '${devicename} Button 6'
pin:
number: GPIO33
inverted: true
mode:
input: true
pullup: true
filters:
- delayed_off: 10ms
# on_press:
# then:
# - if:
# condition:
# lambda: 'return id(current_file) != 6;'
# then:
# - lambda: 'id(current_file) = 6;'
# - dfplayer.play: 6
# else:
# - lambda: 'id(current_file) = 0;'
# - dfplayer.stop
- platform: gpio
name: '${devicename} Button 7'
pin:
number: GPIO32
inverted: true
mode:
input: true
pullup: true
filters:
- delayed_off: 10ms
# on_press:
# then:
# - if:
# condition:
# lambda: 'return id(current_file) != 7;'
# then:
# - lambda: 'id(current_file) = 7;'
# - dfplayer.play: 7
# else:
# - lambda: 'id(current_file) = 0;'
# - dfplayer.stop
- platform: gpio
name: '${devicename} Button 8'
pin:
number: GPIO23
inverted: true
mode:
input: true
pullup: true
filters:
- delayed_off: 10ms
# on_press:
# then:
# - if:
# condition:
# lambda: 'return id(current_file) != 8;'
# then:
# - lambda: 'id(current_file) = 8;'
# - dfplayer.play: 8
# else:
# - lambda: 'id(current_file) = 0;'
# - dfplayer.stop
- platform: gpio
name: '${devicename} Button 9'
pin:
number: GPIO18
inverted: true
mode:
input: true
pullup: true
filters:
- delayed_off: 10ms
on_press:
then:
- dfplayer.volume_down
- platform: gpio
name: '${devicename} Button 10'
pin:
number: GPIO19
inverted: true
mode:
input: true
pullup: true
filters:
- delayed_off: 10ms
on_press:
then:
- dfplayer.volume_up
- platform: gpio
name: '${devicename} Switch 1'
pin:
number: GPIO22
inverted: true
mode:
input: true
pullup: true
- platform: gpio
name: '${devicename} Switch 2'
pin:
number: GPIO21
inverted: true
mode:
input: true
pullup: true
- platform: gpio
name: '${devicename} Switch 3'
pin:
number: GPIO5
inverted: true
mode:
input: true
pullup: true
sensor:
- platform: uptime
name: '${devicename} Uptime Sec'
id: uptime_sec
internal: true
- platform: wifi_signal
id: esp_signal
name: '${devicename} WiFi Signal'
update_interval: 5s
internal: true
accuracy_decimals: 0
- platform: template
id: 'signal_level'
name: '${devicename} WiFi Signal Level'
internal: true
update_interval: 5s
unit_of_measurement: '%'
accuracy_decimals: 0
lambda: return min(max(2 * ((int)id(esp_signal).state + 100), 0), 100);
light:
- platform: neopixelbus
variant: WS2811
pin: GPIO4
num_leds: 15
type: GRB
name: '${devicename} Lights'
restore_mode: RESTORE_DEFAULT_ON
effects:
- addressable_rainbow:
name: 'Rainbow'
speed: 7
width: 10
- addressable_lambda:
name: 'Color Demo'
update_interval: 1s
lambda: |-
// Reset the leds
if (initial_run) {
it.all() = Color::BLACK;
}
// Define possible colors
Color color_red = Color(255, 0, 0); // red
Color color_green = Color(0, 255, 0); // green
Color color_blue = Color(0, 0, 255); // blue
Color color_white = Color(255, 255, 255); // white
// Left Bottom
it[0] = color_red;
it[1] = color_green;
it[2] = color_blue;
// Right Bottom
it[3] = color_red;
it[4] = color_green;
it[5] = color_blue;
// Left Top
it[6] = color_red;
it[7] = color_green;
it[8] = color_blue;
// Right Top
it[9] = color_red;
it[10] = color_green;
it[11] = color_blue;
// Bottom
it[12] = color_white;
it[13] = color_white;
// Top
it[14] = color_white;
- addressable_lambda:
name: 'Status'
update_interval: 1s
lambda: |-
// Vars
Color color;
// Reset the leds
if (initial_run) {
it.all() = Color::BLACK;
}
// Gather dynamic inputs
bool connected = id(esp_status).state;
int signal = (int)id(signal_level).state;
// Define possible colors
Color wifi_good_color = Color(0, 132, 80); // green
Color wifi_okay_color = Color(239, 183, 0); // yellow
Color wifi_poor_color = Color(184, 29, 19); // red
Color wifi_alert_color = Color(215, 3, 252); // purple
// Determine new color and status
if (!connected) {
color = wifi_alert_color;
}
else if (signal > 80) {
color = wifi_good_color;
}
else if (signal > 50) {
color = wifi_okay_color;
}
else {
color = wifi_poor_color;
}
// Set leds color
it.all() = color;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment