9 static const char *
const TAG =
"light";
11 static const LogString *color_mode_to_human(
ColorMode color_mode) {
13 return LOG_STR(
"Unknown");
15 return LOG_STR(
"White");
17 return LOG_STR(
"Color temperature");
19 return LOG_STR(
"Cold/warm white");
21 return LOG_STR(
"RGB");
23 return LOG_STR(
"RGBW");
25 return LOG_STR(
"RGB + cold/warm white");
27 return LOG_STR(
"RGB + color temperature");
36 ESP_LOGD(TAG,
"'%s' Setting:", name);
41 ESP_LOGD(TAG,
" Color mode: %s", LOG_STR_ARG(color_mode_to_human(v.
get_color_mode())));
47 ESP_LOGD(TAG,
" State: %s", ONOFF(v.
is_on()));
58 ESP_LOGD(TAG,
" Red: %.0f%%, Green: %.0f%%, Blue: %.0f%%", v.
get_red() * 100.0f, v.
get_green() * 100.0f,
63 ESP_LOGD(TAG,
" White: %.0f%%", v.
get_white() * 100.0f);
70 ESP_LOGD(TAG,
" Cold white: %.0f%%, warm white: %.0f%%", v.
get_cold_white() * 100.0f,
78 ESP_LOGD(TAG,
" Flash length: %.1fs", *this->
flash_length_ / 1e3f);
91 ESP_LOGD(TAG,
" Effect: 'None'");
101 const char *effect_s;
109 ESP_LOGD(TAG,
" Effect: '%s'", effect_s);
139 ESP_LOGW(TAG,
"'%s' - This light does not support color mode %s!",
name,
155 ESP_LOGW(TAG,
"'%s' - This light does not support setting brightness!",
name);
162 ESP_LOGW(TAG,
"'%s' - This light does not support transitions!",
name);
168 ESP_LOGW(TAG,
"'%s' - This color mode does not support setting RGB brightness!",
name);
176 ESP_LOGW(TAG,
"'%s' - This color mode does not support setting RGB color!",
name);
186 ESP_LOGW(TAG,
"'%s' - This color mode does not support setting white value!",
name);
193 ESP_LOGW(TAG,
"'%s' - This color mode does not support setting color temperature!",
name);
201 ESP_LOGW(TAG,
"'%s' - This color mode does not support setting cold/warm white value!",
name);
207 #define VALIDATE_RANGE_(name_, upper_name, min, max) \ 208 if (name_##_.has_value()) { \ 209 auto val = *name_##_; \ 210 if (val < (min) || val > (max)) { \ 211 ESP_LOGW(TAG, "'%s' - %s value %.2f is out of range [%.1f - %.1f]!", name, LOG_STR_LITERAL(upper_name), val, \ 213 name_##_ = clamp(val, (min), (max)); \ 216 #define VALIDATE_RANGE(name, upper_name) VALIDATE_RANGE_(name, upper_name, 0.0f, 1.0f) 219 VALIDATE_RANGE(brightness,
"Brightness")
220 VALIDATE_RANGE(color_brightness,
"Color brightness")
221 VALIDATE_RANGE(red,
"Red")
222 VALIDATE_RANGE(green,
"Green")
223 VALIDATE_RANGE(blue,
"Blue")
224 VALIDATE_RANGE(white,
"White")
225 VALIDATE_RANGE(cold_white,
"Cold white")
226 VALIDATE_RANGE(warm_white,
"Warm white")
227 VALIDATE_RANGE_(color_temperature,
"Color temperature", traits.get_min_mireds(), traits.get_max_mireds())
249 v.set_state(*this->state_);
251 v.set_brightness(*this->brightness_);
253 v.set_color_brightness(*this->color_brightness_);
255 v.set_red(*this->red_);
257 v.set_green(*this->green_);
259 v.set_blue(*this->blue_);
261 v.set_white(*this->white_);
263 v.set_color_temperature(*this->color_temperature_);
265 v.set_cold_white(*this->cold_white_);
267 v.set_warm_white(*this->warm_white_);
273 ESP_LOGW(TAG,
"'%s' - Flash length must be greater than zero!",
name);
287 ESP_LOGW(TAG,
"'%s' - Invalid effect index %" PRIu32
"!",
name, *this->
effect_);
292 ESP_LOGW(TAG,
"'%s' - Effect cannot be used together with transition/flash!",
name);
298 ESP_LOGW(TAG,
"'%s' - Flash cannot be used together with transition!",
name);
303 supports_transition) {
314 ESP_LOGW(TAG,
"'%s' - Light does not support transitions!",
name);
323 ESP_LOGW(TAG,
"'%s' - Cannot start an effect when turning off!",
name);
350 traits.get_min_mireds() > 0.0f && traits.get_max_mireds() > 0.0f) {
351 ESP_LOGD(TAG,
"'%s' - Setting cold/warm white channels using white/color temperature values.",
355 const float ww_fraction =
356 (color_temp - traits.get_min_mireds()) / (traits.get_max_mireds() - traits.get_min_mireds());
357 const float cw_fraction = 1.0f - ww_fraction;
358 const float max_cw_ww = std::max(ww_fraction, cw_fraction);
369 int supported_count = supported_modes.size();
372 if (supported_count == 0)
376 if (supported_count == 1)
377 return *supported_modes.begin();
390 if (suitable_modes.count(current_mode) > 0) {
391 ESP_LOGI(TAG,
"'%s' - Keeping current color mode %s for call without color mode.",
397 for (
auto mode : suitable_modes) {
398 if (supported_modes.count(
mode) == 0)
401 ESP_LOGI(TAG,
"'%s' - Using color mode %s for call without color mode.", this->
parent_->
get_name().
c_str(),
402 LOG_STR_ARG(color_mode_to_human(
mode)));
408 auto color_mode = current_mode !=
ColorMode::UNKNOWN ? current_mode : *supported_modes.begin();
409 ESP_LOGW(TAG,
"'%s' - No color mode suitable for this call supported, defaulting to %s!",
421 #define KEY(white, ct, cwww, rgb) ((white) << 0 | (ct) << 1 | (cwww) << 2 | (rgb) << 3) 422 #define ENTRY(white, ct, cwww, rgb, ...) \ 423 std::make_tuple<uint8_t, std::set<ColorMode>>(KEY(white, ct, cwww, rgb), __VA_ARGS__) 426 std::array<std::tuple<uint8_t, std::set<ColorMode>>, 10> lookup_table{
427 ENTRY(
true,
false,
false,
false,
430 ENTRY(
false,
true,
false,
false,
433 ENTRY(
true,
true,
false,
false,
436 ENTRY(
false,
false,
false,
false,
439 ENTRY(
true,
false,
false,
true,
444 ENTRY(
false,
false,
false,
true,
448 auto key = KEY(has_white, has_ct, has_cwww, has_rgb);
449 for (
auto &item : lookup_table) {
450 if (std::get<0>(item) == key)
451 return std::get<1>(item);
459 if (strcasecmp(effect.c_str(),
"none") == 0) {
468 if (strcasecmp(effect.c_str(), e->
get_name().c_str()) == 0) {
684 this->
set_rgb(red, green, blue);
value_type const & value() const
LightCall & set_save(bool save)
Set whether this light call should trigger a save state to recover them at startup..
ColorMode
Color modes are a combination of color capabilities that can be used at the same time.
LightCall & set_color_brightness(optional< float > brightness)
Set the color brightness of the light from 0.0 (no color) to 1.0 (fully on)
float get_warm_white() const
Get the warm white property of these light color values. In range 0.0 to 1.0.
void publish_state()
Publish the currently active state to the frontend.
void set_immediately_(const LightColorValues &target, bool set_remote_values)
Internal method to set the color values to target immediately (with no transition).
LightCall & set_publish(bool publish)
Set whether this light call should trigger a publish state.
bool is_on() const
Get the binary true/false state of these light color values.
LightCall & set_red(optional< float > red)
Set the red RGB value of the light from 0.0 to 1.0.
uint32_t default_transition_length_
Default transition length for all transitions in ms.
LightCall & set_color_temperature(optional< float > color_temperature)
Set the color temperature of the light in mireds for CWWW or RGBWW lights.
LightCall & set_green_if_supported(float green)
Set the green property if the light supports RGB.
optional< float > warm_white_
LightCall & set_cold_white(optional< float > cold_white)
Set the cold white value of the light from 0.0 to 1.0.
optional< uint32_t > effect_
void start_transition_(const LightColorValues &target, uint32_t length, bool set_remote_values)
Internal method to start a transition to the target color with the given length.
float get_gamma_correct() const
float get_cold_white() const
Get the cold white property of these light color values. In range 0.0 to 1.0.
void start_effect_(uint32_t effect_index)
Internal method to start an effect with the given index.
RGB color output and a separate white output.
void start_flash_(const LightColorValues &target, uint32_t length, bool set_remote_values)
Internal method to start a flash for the specified amount of time.
float get_red() const
Get the red property of these light color values. In range 0.0 to 1.0.
LightCall & set_rgb(float red, float green, float blue)
Set the RGB color of the light by RGB values.
LightCall & set_color_brightness_if_supported(float brightness)
Set the color brightness property if the light supports RGBW.
Color temperature can be controlled.
optional< float > color_brightness_
optional< float > cold_white_
LightCall & set_color_mode(optional< ColorMode > color_mode)
Set the color mode of the light.
LightColorValues validate_()
Validate all properties and return the target light color values.
LightCall & set_transition_length(optional< uint32_t > transition_length)
Set the transition length of this call in milliseconds.
void set_color_mode(ColorMode color_mode)
Set the color mode of these light color values.
constexpr const T & clamp(const T &v, const T &lo, const T &hi, Compare comp)
LightCall & set_warm_white_if_supported(float warm_white)
Set the warm white property if the light supports cold white output.
float get_blue() const
Get the blue property of these light color values. In range 0.0 to 1.0.
RGB color output, and separate cold and warm white outputs.
LightCall & from_light_color_values(const LightColorValues &values)
optional< float > brightness_
optional< float > color_temperature_
This class represents the color state for a light object.
ColorMode get_active_color_mode_()
Get the currently targeted, or active if none set, color mode.
ColorMode compute_color_mode_()
Brightness of cold and warm white output can be controlled.
float get_white() const
Get the white property of these light color values. In range 0.0 to 1.0.
float get_color_temperature() const
Get the color temperature property of these light color values in mired.
Brightness of white channel can be controlled separately from other channels.
const std::set< ColorMode > & get_supported_color_modes() const
BedjetMode mode
BedJet operating mode.
LightCall & set_transition_length_if_supported(uint32_t transition_length)
Set the transition length property if the light supports transitions.
LightCall & set_color_temperature_if_supported(float color_temperature)
Set the color_temperature property if the light supports color temperature.
LightCall & set_color_mode_if_supported(ColorMode color_mode)
Set the color mode of the light, if this mode is supported.
RGB color output and a separate white output with controllable color temperature. ...
This class represents a requested change in a light state.
ColorMode get_color_mode() const
Get the color mode of these light color values.
LightCall & set_state(optional< bool > state)
Set the binary ON/OFF state of the light.
std::vector< LightEffect * > effects_
List of effects for this light.
Master brightness of the light can be controlled.
White output only (use only if the light also has another color mode such as RGB).
void transform_parameters_()
Some color modes also can be set using non-native parameters, transform those calls.
LightCall & set_warm_white(optional< float > warm_white)
Set the warm white value of the light from 0.0 to 1.0.
const std::string & get_name()
No color mode configured (cannot be a supported mode, only active when light is off).
constexpr const char * c_str() const
bool supports_color_mode(ColorMode color_mode) const
LightCall & set_effect(optional< std::string > effect)
Set the effect of the light by its name.
LightCall & set_cold_white_if_supported(float cold_white)
Set the cold white property if the light supports cold white output.
optional< ColorMode > color_mode_
std::set< ColorMode > get_suitable_color_modes_()
Get potential color modes for this light call.
LightCall & set_rgbw(float red, float green, float blue, float white)
Set the RGBW color of the light by RGB values.
optional< uint32_t > flash_length_
void save_remote_values_()
Internal method to save the current remote_values to the preferences.
LightCall & set_flash_length(optional< uint32_t > flash_length)
Start and set the flash length of this call in milliseconds.
LightCall & set_green(optional< float > green)
Set the green RGB value of the light from 0.0 to 1.0.
CallbackManager< void()> target_state_reached_callback_
Callback to call when the state of current_values and remote_values are equal This should be called o...
Implementation of SPI Controller mode.
uint32_t active_effect_index_
Value for storing the index of the currently active effect. 0 if no effect is active.
Color can be controlled using RGB format (includes a brightness control for the color).
LightColorValues remote_values
The remote color values reported to the frontend.
float get_color_brightness() const
Get the color brightness property of these light color values. In range 0.0 to 1.0.
optional< uint32_t > transition_length_
LightCall & set_brightness_if_supported(float brightness)
Set the brightness property if the light supports brightness.
LightCall & set_white(optional< float > white)
Set the white value value of the light from 0.0 to 1.0 for RGBW[W] lights.
LightCall & set_brightness(optional< float > brightness)
Set the target brightness of the light from 0.0 (fully off) to 1.0 (fully on)
LightCall & set_blue_if_supported(float blue)
Set the blue property if the light supports RGB.
LightCall & set_white_if_supported(float white)
Set the white property if the light supports RGB.
LightCall & set_blue(optional< float > blue)
Set the blue RGB value of the light from 0.0 to 1.0.
void stop_effect_()
Internal method to stop the current effect (if one is active).
value_type value_or(U const &v) const
float get_green() const
Get the green property of these light color values. In range 0.0 to 1.0.
const StringRef & get_name() const
float get_brightness() const
Get the brightness property of these light color values. In range 0.0 to 1.0.
LightCall & set_red_if_supported(float red)
Set the red property if the light supports RGB.
float gamma_uncorrect(float value, float gamma)
Reverts gamma correction of gamma to value.