Open Joshfindit opened 5 years ago
I guess HS support could be added to HS, yes - the HS->RGB algorithm would just need to be implemented.
Would like to be able to call call.set_hs(hue, 100); where hue is 0-360 repeating.
What do you mean by "repeating"? If you mean that the call would cycle through colors over time, no, that would be an effect's responsibility.
Side note: I'm not sure if a while loop will lock up the device so this may be a wild goose chase
Everything is executed in a single thread (with some exceptions), so yes an endless loop will lock up the device. See also how other effects handle it.
Would be great to have hs support so I could use a binary sensor to control hue value and which is 0-360 (angles of a circle) and keeps repeating i.e. when it reaches 360 = 0 and loops again, in terms of endless loop it would not run code non-stop but rather the code allows the value to perform a second revolution by reseting to 0 at 360 degrees.
what else would be required to help add this feature?
I too would like to see this - it looks like all that needs to happen is to hoist ESPHSVColor::to_rgb()
out of the addressable light class and make it part of the light class.
I've currently got a nasty implementation as a lambda, repeated for every effect that needs to do an HSV-to-RGB conversion, but it'd be so much nicer if I could say call.set_hsv(hue, 1.0, 1.0)
:
- lambda:
name: Color Fade (10s)
update_interval: 500ms
lambda: |-
static int hue = 0, step = 20;
float red = 0, green = 0, blue = 0;
const float saturation = 1, value = 1;
float c = saturation * value;
float x = c * (1.0 - fabsf( fmodf((float(hue) / 60.0), 2.0) - 1.0));
if (hue < 60){
red = c;
green = x;
blue = 0;
} else if (hue < 120){
red = x;
green = c;
blue = 0;
} else if (hue < 180){
red = 0;
green = c;
blue = x;
} else if (hue < 240){
red = 0; green = x; blue = c;
} else if (hue < 300) {
red = x; green = 0; blue = c;
} else { // if (hue <= 360) {
red = c; green = 0; blue = x;
}
ESP_LOGI("colorcycle", "hue:%d x:%.3f r:%.3f g:%.3f b:%.3f", hue, x, red, green, blue);
hue = (hue + step) % 360;
auto call = id(${devname}_rgb).turn_on();
call.set_transition_length(500);
call.set_brightness(1.0);
call.set_rgb(red, green, blue);
call.perform();
I guess HS support could be added to HS, yes - the HS->RGB algorithm would just need to be implemented.
Would like to be able to call call.set_hs(hue, 100); where hue is 0-360 repeating.
What do you mean by "repeating"? If you mean that the call would cycle through colors over time, no, that would be an effect's responsibility.
Sorry, I see how that was unclear and I missed the question until now. @ashp8i used better wording. I just mean that like the angles: 360 is the same hue as 0 so that slowly going from 0-360, resetting back to 0 then continuing to 360 would produce a single smooth transition.
In that case, set_hs(hue, 100)
would be called 720 times. (More or less, depending on if the range was 0-360, 1-360, or 0-359)
Here's a slightly less terrible implementation. Or maybe it's terrible in different ways, eg. the use of globals.
# My RGB Light YAML
esphome:
name: ${devname}
platform: ESP8266
board: d1_mini
includes:
- ./custom_includes/hsv2rgb.h
# other stuff...
light:
- platform: rgb
name: ${friendlyname} RGB
id: ${devname}_rgb
red: ${devname}_output_r
green: ${devname}_output_g
blue: ${devname}_output_b
effects:
- lambda:
name: Color Fade (1m)
update_interval: 1s
lambda: |-
int step = 6, trans = 1000;
auto call = id(${devname}_rgb).turn_on();
hsv_to_rgb(gHue, 1.0, 1.0, call, trans);
gHue = (gHue + step) % 360;
- lambda:
name: Color Fade (2m)
update_interval: 1s
lambda: |-
int step = 3, trans = 1000;
auto call = id(${devname}_rgb).turn_on();
hsv_to_rgb(gHue, 1.0, 1.0, call, trans);
gHue = (gHue + step) % 360;
// hsv2rgb.h
#include "esphome.h"
using namespace esphome;
using namespace light;
// so I can share this between effects
uint16_t gHue = 0;
void hsv_to_rgb(uint16_t hue, float sat, float val, LightCall led, int transition){
float c = sat * val;
float x = c * (1.0 - fabsf( fmodf((float(hue) / 60.0), 2.0) - 1.0));
float red = 0, green = 0, blue = 0;
switch (hue/60) {
case 0:
red = c;
green = x;
blue = 0;
break;
case 1:
red = x;
green = c;
blue = 0;
break;
case 2:
red = 0;
green = c;
blue = x;
break;
case 3:
red = 0;
green = x;
blue = c;
break;
case 4:
red = x;
green = 0;
blue = c;
break;
case 5:
red = c;
green = 0;
blue = x;
break;
default:
break;
}
led.set_brightness(1.0);
led.set_transition_length(transition);
led.set_rgb(red, green, blue);
led.perform();
}
Describe the problem you have/What new integration you would like
Would like to be able to call
call.set_hs(hue, 100);
where hue is 0-360 repeating. Side note: I'm not sure if a while loop will lock up the device so this may be a wild goose chasePlease describe your use case for this integration and alternatives you've tried:
Working on a "non-addressable RGB" rainbow effect using lambda.
Additional context
https://esphome.io/components/light/rgb.html https://esphome.io/components/light/index.html https://esphome.io/api/classesphome_1_1light_1_1_light_call.html