I came here looking for light effects but didnāt find what I wanted, so I used an LLM to create some. These are wave related addressable effects, and they dynamically change color based on what the strip is set to using id(light_id).current_values.
Disclaimer: These are generated using AI with my guidance/correction. They all work, but might not be written the greatest.
For all effects, you can change update_interval for speed, x for the width of the wave and y for the spacing between waves. You must update ālight_idā with the ID of your light (and it must be defined if it isnāt already).
A simple repeating wave. The wave starts at max brightness and has a fading tail. Has the color that the strip is set to.
- addressable_lambda:
name: "Wave"
update_interval: 40ms
lambda: |-
static float wave_position = 0.0;
const int x = 10; // Width of the wave peak
const int y = 20; // Spacing between wave peaks
const float wave_speed = 0.5; // Speed of the wave progression
wave_position += wave_speed;
if (wave_position >= (x + y)) {
wave_position -= (x + y);
}
// Fetch the globally set color and use it
auto call = id(light_id).current_values;
Color selected_color(call.get_red() * 255, call.get_green() * 255, call.get_blue() * 255);
for (int i = 0; i < it.size(); i++) {
// Calculate brightness for the wave
float position_in_wave = fmod(i + wave_position, x + y);
float brightness = 0.0;
if (position_in_wave < x) {
brightness = 1.0 - (position_in_wave / x);
}
// Scale the selected color by the calculated brightness
uint8_t r = std::min(255, static_cast<int>(selected_color.red * brightness));
uint8_t g = std::min(255, static_cast<int>(selected_color.green * brightness));
uint8_t b = std::min(255, static_cast<int>(selected_color.blue * brightness));
it[i] = Color(r, g, b);
}
Same as above, but the wave is faded on both ends (like a hump)
- addressable_lambda
name: "Wave Fade"
update_interval: 40ms
lambda: |-
static float wave_position = 0.0;
const int x = 10; // Width of the wave peak
const int y = 20; // Spacing between wave peaks
const float wave_speed = 0.5; // Speed of the wave progression
wave_position += wave_speed;
if (wave_position >= (x + y)) {
wave_position -= (x + y);
}
// Fetch the globally set color and use it
auto call = id(light_id).current_values;
Color selected_color(call.get_red() * 255, call.get_green() * 255, call.get_blue() * 255);
for (int i = 0; i < it.size(); i++) {
// Calculate brightness for the wave
float position_in_wave = fmod(i + wave_position, x + y);
float brightness = 0.0;
if (position_in_wave < x) {
brightness = (1.0 - fabs((position_in_wave / x) * 2.0 - 1.0)); // Linear fade in and out
}
// Scale the selected color by the calculated brightness
uint8_t r = std::min(255, static_cast<int>(selected_color.red * brightness));
uint8_t g = std::min(255, static_cast<int>(selected_color.green * brightness));
uint8_t b = std::min(255, static_cast<int>(selected_color.blue * brightness));
it[i] = Color(r, g, b);
}
Similar to the first, but there is a second wave traveling of the opposite direction. The color of the second wave is the compliment (180 degrees hue rotated) of the first, and when they collide, the colors are added.
- addressable_lambda:
name: "Wave Comp"
update_interval: 75ms
lambda: |-
static float wave_position = 0.0;
const int x = 10; // Width of the wave peak
const int y = 20; // Spacing between wave peaks
const float wave_speed = 0.5; // Speed of the wave progression
wave_position += wave_speed;
if (wave_position >= (x + y)) {
wave_position -= (x + y);
}
// Fetch the globally set color and use it
auto call = id(light_id).current_values;
Color rgb1(call.get_red() * 255, call.get_green() * 255, call.get_blue() * 255);
// Calculate the complementary color
Color rgb2(255 - rgb1.red, 255 - rgb1.green, 255 - rgb1.blue);
wave_position += wave_speed;
if (wave_position >= (x + y)) {
wave_position -= (x + y);
}
for (int i = 0; i < it.size(); i++) {
// Calculate brightness for the forward wave
float forward_position_in_wave = fmod(i + wave_position, x + y);
float forward_brightness = 0.0;
if (forward_position_in_wave < x) {
forward_brightness = 1.0 - (forward_position_in_wave / x);
}
// Calculate brightness for the backward wave
float backward_position_in_wave = fmod(it.size() - 1 - i + wave_position, x + y);
float backward_brightness = 0.0;
if (backward_position_in_wave < x) {
backward_brightness = 1.0 - (backward_position_in_wave / x);
}
// Add the two colors and clamp the result
uint8_t r = std::min(255, static_cast<int>((rgb1.red * forward_brightness) + (rgb2.red * backward_brightness)));
uint8_t g = std::min(255, static_cast<int>((rgb1.green * forward_brightness) + (rgb2.green * backward_brightness)));
uint8_t b = std::min(255, static_cast<int>((rgb1.blue * forward_brightness) + (rgb2.blue * backward_brightness)));
it[i] = Color(r, g, b);
}
Same as above but the waves are faded on both ends (like humps)
- addressable_lambda:
name: "Wave Comp Fade"
update_interval: 75ms
lambda: |-
static float wave_position = 0.0;
const int x = 10; // Width of the wave peak
const int y = 20; // Spacing between wave peaks
const float wave_speed = 0.5; // Speed of the wave progression
wave_position += wave_speed;
if (wave_position >= (x + y)) {
wave_position -= (x + y);
}
// Fetch the globally set color and use it
auto call = id(light_id).current_values;
Color rgb1(call.get_red() * 255, call.get_green() * 255, call.get_blue() * 255);
// Calculate the complementary color
Color rgb2(255 - rgb1.red, 255 - rgb1.green, 255 - rgb1.blue);
for (int i = 0; i < it.size(); i++) {
// Calculate brightness for the forward wave
float forward_position_in_wave = fmod(i + wave_position, x + y);
float forward_brightness = 0.0;
if (forward_position_in_wave < x) {
forward_brightness = (1.0 - fabs((forward_position_in_wave / x) * 2.0 - 1.0)); // Linear fade in/out
}
// Calculate brightness for the backward wave
float backward_position_in_wave = fmod(it.size() - 1 - i + wave_position, x + y);
float backward_brightness = 0.0;
if (backward_position_in_wave < x) {
backward_brightness = (1.0 - fabs((backward_position_in_wave / x) * 2.0 - 1.0)); // Linear fade in/out
}
// Add the two colors and clamp the result
uint8_t r = std::min(255, static_cast<int>((rgb1.red * forward_brightness) + (rgb2.red * backward_brightness)));
uint8_t g = std::min(255, static_cast<int>((rgb1.green * forward_brightness) + (rgb2.green * backward_brightness)));
uint8_t b = std::min(255, static_cast<int>((rgb1.blue * forward_brightness) + (rgb2.blue * backward_brightness)));
it[i] = Color(r, g, b);
}
Same as the above two, but the second color is 120 degrees rotated. (Or you can change the number in the code too).
- addressable_lambda:
name: "Wave Rotate"
update_interval: 75ms
lambda: |-
static float wave_position = 0.0;
const int x = 10; // Width of the wave peak
const int y = 20; // Spacing between wave peaks
const float wave_speed = 0.5; // Speed of the wave progression
wave_position += wave_speed;
if (wave_position >= (x + y)) {
wave_position -= (x + y);
}
// Fetch the globally set color and use it
auto call = id(fairy).current_values;
Color rgb1(call.get_red() * 255, call.get_green() * 255, call.get_blue() * 255);
// Manually rotate the hue by 120 degrees
auto rotate_hue = [](Color color, float angle) -> Color {
float r = color.red / 255.0;
float g = color.green / 255.0;
float b = color.blue / 255.0;
// Convert RGB to the maximum of R, G, B
float max_val = std::max({r, g, b});
float min_val = std::min({r, g, b});
float delta = max_val - min_val;
float hue = 0.0;
if (delta > 0.0) {
if (max_val == r) {
hue = (g - b) / delta;
} else if (max_val == g) {
hue = 2.0 + (b - r) / delta;
} else {
hue = 4.0 + (r - g) / delta;
}
hue /= 6.0;
if (hue < 0) hue += 1.0;
}
// Rotate the hue by the specified angle
hue = fmod(hue + angle / 360.0, 1.0);
// Convert back to RGB
float p, q, t, h1, r_out, g_out, b_out;
if (delta == 0) {
r_out = g_out = b_out = max_val;
} else {
h1 = hue * 6;
p = max_val * (1.0 - delta);
q = max_val * (1.0 - delta * h1);
t = max_val * (1.0 - delta * (1.0 - h1));
if (h1 < 1) {
r_out = max_val;
g_out = t;
b_out = p;
} else if (h1 < 2) {
r_out = q;
g_out = max_val;
b_out = p;
} else if (h1 < 3) {
r_out = p;
g_out = max_val;
b_out = t;
} else if (h1 < 4) {
r_out = p;
g_out = q;
b_out = max_val;
} else if (h1 < 5) {
r_out = t;
g_out = p;
b_out = max_val;
} else {
r_out = max_val;
g_out = p;
b_out = q;
}
}
return Color(r_out * 255, g_out * 255, b_out * 255);
};
// Rotate the selected color by 120 degrees
Color rgb2 = rotate_hue(rgb1, 120.0);
wave_position += wave_speed;
if (wave_position >= (x + y)) {
wave_position -= (x + y);
}
for (int i = 0; i < it.size(); i++) {
// Calculate brightness for the forward wave
float forward_position_in_wave = fmod(i + wave_position, x + y);
float forward_brightness = 0.0;
if (forward_position_in_wave < x) {
forward_brightness = 1.0 - (forward_position_in_wave / x);
}
// Calculate brightness for the backward wave
float backward_position_in_wave = fmod(it.size() - 1 - i + wave_position, x + y);
float backward_brightness = 0.0;
if (backward_position_in_wave < x) {
backward_brightness = 1.0 - (backward_position_in_wave / x);
}
// Add the two colors and clamp the result
uint8_t r = std::min(255, static_cast<int>((rgb1.red * forward_brightness) + (rgb2.red * backward_brightness)));
uint8_t g = std::min(255, static_cast<int>((rgb1.green * forward_brightness) + (rgb2.green * backward_brightness)));
uint8_t b = std::min(255, static_cast<int>((rgb1.blue * forward_brightness) + (rgb2.blue * backward_brightness)));
it[i] = Color(r, g, b);
}
Same as above not the waves are faded on both sides (like humps)
- addressable_lambda:
name: "Wave Rotate Fade"
update_interval: 75ms
lambda: |-
static float wave_position = 0.0;
const int x = 10; // Width of the wave peak
const int y = 20; // Spacing between wave peaks
const float wave_speed = 0.5; // Speed of the wave progression
wave_position += wave_speed;
if (wave_position >= (x + y)) {
wave_position -= (x + y);
}
// Fetch the globally set color and use it
auto call = id(fairy).current_values;
Color rgb1(call.get_red() * 255, call.get_green() * 255, call.get_blue() * 255);
// Manually rotate the hue by 120 degrees
auto rotate_hue = [](Color color, float angle) -> Color {
float r = color.red / 255.0;
float g = color.green / 255.0;
float b = color.blue / 255.0;
// Convert RGB to the maximum of R, G, B
float max_val = std::max({r, g, b});
float min_val = std::min({r, g, b});
float delta = max_val - min_val;
float hue = 0.0;
if (delta > 0.0) {
if (max_val == r) {
hue = (g - b) / delta;
} else if (max_val == g) {
hue = 2.0 + (b - r) / delta;
} else {
hue = 4.0 + (r - g) / delta;
}
hue /= 6.0;
if (hue < 0) hue += 1.0;
}
// Rotate the hue by the specified angle
hue = fmod(hue + angle / 360.0, 1.0);
// Convert back to RGB
float p, q, t, h1, r_out, g_out, b_out;
if (delta == 0) {
r_out = g_out = b_out = max_val;
} else {
h1 = hue * 6;
p = max_val * (1.0 - delta);
q = max_val * (1.0 - delta * h1);
t = max_val * (1.0 - delta * (1.0 - h1));
if (h1 < 1) {
r_out = max_val;
g_out = t;
b_out = p;
} else if (h1 < 2) {
r_out = q;
g_out = max_val;
b_out = p;
} else if (h1 < 3) {
r_out = p;
g_out = max_val;
b_out = t;
} else if (h1 < 4) {
r_out = p;
g_out = q;
b_out = max_val;
} else if (h1 < 5) {
r_out = t;
g_out = p;
b_out = max_val;
} else {
r_out = max_val;
g_out = p;
b_out = q;
}
}
return Color(r_out * 255, g_out * 255, b_out * 255);
};
// Rotate the selected color by 120 degrees
Color rgb2 = rotate_hue(rgb1, 120.0);
wave_position += wave_speed;
if (wave_position >= (x + y)) {
wave_position -= (x + y);
}
for (int i = 0; i < it.size(); i++) {
// Calculate brightness for the forward wave
float forward_position_in_wave = fmod(i + wave_position, x + y);
float forward_brightness = 0.0;
if (forward_position_in_wave < x) {
forward_brightness = (1.0 - fabs((forward_position_in_wave / x) * 2.0 - 1.0)); // Linear fade in/out
}
// Calculate brightness for the backward wave
float backward_position_in_wave = fmod(it.size() - 1 - i + wave_position, x + y);
float backward_brightness = 0.0;
if (backward_position_in_wave < x) {
backward_brightness = (1.0 - fabs((backward_position_in_wave / x) * 2.0 - 1.0)); // Linear fade in/out
}
// Add the two colors and clamp the result
uint8_t r = std::min(255, static_cast<int>((rgb1.red * forward_brightness) + (rgb2.red * backward_brightness)));
uint8_t g = std::min(255, static_cast<int>((rgb1.green * forward_brightness) + (rgb2.green * backward_brightness)));
uint8_t b = std::min(255, static_cast<int>((rgb1.blue * forward_brightness) + (rgb2.blue * backward_brightness)));
it[i] = Color(r, g, b);
}