Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jsnfwlr/daea88b43982c0f08ed0d094493500e2 to your computer and use it in GitHub Desktop.
Save jsnfwlr/daea88b43982c0f08ed0d094493500e2 to your computer and use it in GitHub Desktop.
ESPHome configuration example to create an animated clock using the Neopixel 60 LED ring
esphome:
# [...]
on_boot:
priority: -10
then:
# enable clock effect after boot
- light.turn_on:
id: light_ring
brightness: 100%
effect: Clock
globals:
- id: clock_brightness
type: int
restore_value: yes
initial_value: '255'
- id: clock_indicators_enabled
type: bool
restore_value: yes
initial_value: 'true'
switch:
- platform: template
name: "Clock Indicators"
lambda: !lambda |-
return id(clock_indicators_enabled);
turn_on_action:
globals.set:
id: clock_indicators_enabled
value: 'true'
turn_off_action:
globals.set:
id: clock_indicators_enabled
value: 'false'
light:
- id: light_ring
internal: False
platform: neopixelbus
type: GRB
variant: SK6812 # WS2812X
pin: RX #GPIO23
num_leds: 60
method: ESP8266_DMA
name: "NeoPixel Light"
color_correct: [50%, 50%, 50%]
effects:
- addressable_lambda:
name: "Clock"
update_interval: 32ms
lambda: |-
static boolean initialized;
static ESPColor clock_ring_colors [60];
if (initialized == false) {
std::fill_n(clock_ring_colors, it.size(), ESPColor::BLACK);
initialized = true;
}
auto time = id(sntp_time).now();
if (!time.is_valid()) {
return;
}
// calculate led indices
int second_idx = (int) (time.second * (it.size() / 60));
int minute_idx = (int) (time.minute * (it.size() / 60));
int hour_idx = (int) ((time.hour % 12) * (it.size() / 12));
int hour_inc_min_idx = hour_idx + (int) (((float) time.minute / 12) * (it.size() / 60));
// fade out old colors
for (int i = 0; i < it.size(); i++) {
ESPColor old_color = clock_ring_colors[i];
// fade out color
int amount = 5;
int red = old_color.red;
int green = old_color.green;
int blue = old_color.blue;
int white = old_color.white;
if (red < amount) { red = 0; } else { red -= amount; }
if (green < amount) { green = 0; } else { green -= amount; }
if (blue < amount) { blue = 0; } else { blue -= amount; }
ESPColor new_color = ESPColor(red, green, blue, 0);
clock_ring_colors[i] = new_color;
}
int indicator_brightness = id(clock_brightness) / 3;
ESPColor indicator_color = ESPColor(indicator_brightness, indicator_brightness, indicator_brightness);
// calculate colors
ESPColor second_color = ESPColor(id(clock_brightness), 0, 0);
ESPColor minute_color = ESPColor(0, id(clock_brightness), 0);
if (minute_idx == second_idx) {
minute_color += second_color;
}
ESPColor hour_color = ESPColor(0, 0, id(clock_brightness));
if (hour_inc_min_idx == minute_idx) {
// if seconds are also the same this will already contain the second color
hour_color += minute_color;
} else if (hour_inc_min_idx == second_idx) {
hour_color += second_color;
}
if (id(clock_indicators_enabled)) {
for (int i = 0; i < it.size(); i += (int) ((float) it.size() / 12)) {
clock_ring_colors[i] = indicator_color;
}
}
// set colors
clock_ring_colors[second_idx] = second_color;
clock_ring_colors[minute_idx] = minute_color;
clock_ring_colors[hour_inc_min_idx] = hour_color;
// apply colors to light
for (int i = 0; i < it.size(); i++) {
it[i] = clock_ring_colors[i];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment