mirror of
https://github.com/esphome/esphome.git
synced 2025-08-03 08:57:47 +00:00
light2
This commit is contained in:
parent
eec31846e1
commit
825f3eee70
@ -66,11 +66,17 @@ static const LogString *color_mode_to_human(ColorMode color_mode) {
|
|||||||
return LOG_STR("");
|
return LOG_STR("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper to log percentage values
|
||||||
|
static inline void log_percent(const char *name, const char *param, float value) {
|
||||||
|
ESP_LOGD(TAG, " %s: %.0f%%", param, value * 100.0f);
|
||||||
|
}
|
||||||
|
|
||||||
void LightCall::perform() {
|
void LightCall::perform() {
|
||||||
const char *name = this->parent_->get_name().c_str();
|
const char *name = this->parent_->get_name().c_str();
|
||||||
LightColorValues v = this->validate_();
|
LightColorValues v = this->validate_();
|
||||||
|
const bool publish = this->get_publish_();
|
||||||
|
|
||||||
if (this->get_publish_()) {
|
if (publish) {
|
||||||
ESP_LOGD(TAG, "'%s' Setting:", name);
|
ESP_LOGD(TAG, "'%s' Setting:", name);
|
||||||
|
|
||||||
// Only print color mode when it's being changed
|
// Only print color mode when it's being changed
|
||||||
@ -88,11 +94,11 @@ void LightCall::perform() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this->has_brightness()) {
|
if (this->has_brightness()) {
|
||||||
ESP_LOGD(TAG, " Brightness: %.0f%%", v.get_brightness() * 100.0f);
|
log_percent(name, "Brightness", v.get_brightness());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->has_color_brightness()) {
|
if (this->has_color_brightness()) {
|
||||||
ESP_LOGD(TAG, " Color brightness: %.0f%%", v.get_color_brightness() * 100.0f);
|
log_percent(name, "Color brightness", v.get_color_brightness());
|
||||||
}
|
}
|
||||||
if (this->has_red() || this->has_green() || this->has_blue()) {
|
if (this->has_red() || this->has_green() || this->has_blue()) {
|
||||||
ESP_LOGD(TAG, " Red: %.0f%%, Green: %.0f%%, Blue: %.0f%%", v.get_red() * 100.0f, v.get_green() * 100.0f,
|
ESP_LOGD(TAG, " Red: %.0f%%, Green: %.0f%%, Blue: %.0f%%", v.get_red() * 100.0f, v.get_green() * 100.0f,
|
||||||
@ -100,7 +106,7 @@ void LightCall::perform() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this->has_white()) {
|
if (this->has_white()) {
|
||||||
ESP_LOGD(TAG, " White: %.0f%%", v.get_white() * 100.0f);
|
log_percent(name, "White", v.get_white());
|
||||||
}
|
}
|
||||||
if (this->has_color_temperature()) {
|
if (this->has_color_temperature()) {
|
||||||
ESP_LOGD(TAG, " Color temperature: %.1f mireds", v.get_color_temperature());
|
ESP_LOGD(TAG, " Color temperature: %.1f mireds", v.get_color_temperature());
|
||||||
@ -114,26 +120,26 @@ void LightCall::perform() {
|
|||||||
|
|
||||||
if (this->has_flash_()) {
|
if (this->has_flash_()) {
|
||||||
// FLASH
|
// FLASH
|
||||||
if (this->get_publish_()) {
|
if (publish) {
|
||||||
ESP_LOGD(TAG, " Flash length: %.1fs", this->flash_length_ / 1e3f);
|
ESP_LOGD(TAG, " Flash length: %.1fs", this->flash_length_ / 1e3f);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->parent_->start_flash_(v, this->flash_length_, this->get_publish_());
|
this->parent_->start_flash_(v, this->flash_length_, publish);
|
||||||
} else if (this->has_transition_()) {
|
} else if (this->has_transition_()) {
|
||||||
// TRANSITION
|
// TRANSITION
|
||||||
if (this->get_publish_()) {
|
if (publish) {
|
||||||
ESP_LOGD(TAG, " Transition length: %.1fs", this->transition_length_ / 1e3f);
|
ESP_LOGD(TAG, " Transition length: %.1fs", this->transition_length_ / 1e3f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special case: Transition and effect can be set when turning off
|
// Special case: Transition and effect can be set when turning off
|
||||||
if (this->has_effect_()) {
|
if (this->has_effect_()) {
|
||||||
if (this->get_publish_()) {
|
if (publish) {
|
||||||
ESP_LOGD(TAG, " Effect: 'None'");
|
ESP_LOGD(TAG, " Effect: 'None'");
|
||||||
}
|
}
|
||||||
this->parent_->stop_effect_();
|
this->parent_->stop_effect_();
|
||||||
}
|
}
|
||||||
|
|
||||||
this->parent_->start_transition_(v, this->transition_length_, this->get_publish_());
|
this->parent_->start_transition_(v, this->transition_length_, publish);
|
||||||
|
|
||||||
} else if (this->has_effect_()) {
|
} else if (this->has_effect_()) {
|
||||||
// EFFECT
|
// EFFECT
|
||||||
@ -144,7 +150,7 @@ void LightCall::perform() {
|
|||||||
effect_s = this->parent_->effects_[this->effect_ - 1]->get_name().c_str();
|
effect_s = this->parent_->effects_[this->effect_ - 1]->get_name().c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->get_publish_()) {
|
if (publish) {
|
||||||
ESP_LOGD(TAG, " Effect: '%s'", effect_s);
|
ESP_LOGD(TAG, " Effect: '%s'", effect_s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,13 +161,13 @@ void LightCall::perform() {
|
|||||||
this->parent_->set_immediately_(v, true);
|
this->parent_->set_immediately_(v, true);
|
||||||
} else {
|
} else {
|
||||||
// INSTANT CHANGE
|
// INSTANT CHANGE
|
||||||
this->parent_->set_immediately_(v, this->get_publish_());
|
this->parent_->set_immediately_(v, publish);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this->has_transition_()) {
|
if (!this->has_transition_()) {
|
||||||
this->parent_->target_state_reached_callback_.call();
|
this->parent_->target_state_reached_callback_.call();
|
||||||
}
|
}
|
||||||
if (this->get_publish_()) {
|
if (publish) {
|
||||||
this->parent_->publish_state();
|
this->parent_->publish_state();
|
||||||
}
|
}
|
||||||
if (this->get_save_()) {
|
if (this->get_save_()) {
|
||||||
|
@ -8,6 +8,46 @@ namespace light {
|
|||||||
|
|
||||||
// See https://www.home-assistant.io/integrations/light.mqtt/#json-schema for documentation on the schema
|
// See https://www.home-assistant.io/integrations/light.mqtt/#json-schema for documentation on the schema
|
||||||
|
|
||||||
|
// Helper to convert float 0-1 to uint8_t 0-255
|
||||||
|
static inline uint8_t to_uint8_scaled(float value) { return uint8_t(value * 255); }
|
||||||
|
|
||||||
|
// Helper to parse color component from JSON
|
||||||
|
static float parse_color_component(JsonObject &color, const char *key, LightCall &call,
|
||||||
|
LightCall &(LightCall::*setter)(float) ) {
|
||||||
|
if (color[key].is<uint8_t>()) {
|
||||||
|
float val = float(color[key]) / 255.0f;
|
||||||
|
(call.*setter)(val);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lookup table for color mode strings
|
||||||
|
static const char *get_color_mode_json_str(ColorMode mode) {
|
||||||
|
switch (mode) {
|
||||||
|
case ColorMode::ON_OFF:
|
||||||
|
return "onoff";
|
||||||
|
case ColorMode::BRIGHTNESS:
|
||||||
|
return "brightness";
|
||||||
|
case ColorMode::WHITE:
|
||||||
|
return "white"; // not supported by HA in MQTT
|
||||||
|
case ColorMode::COLOR_TEMPERATURE:
|
||||||
|
return "color_temp";
|
||||||
|
case ColorMode::COLD_WARM_WHITE:
|
||||||
|
return "cwww"; // not supported by HA
|
||||||
|
case ColorMode::RGB:
|
||||||
|
return "rgb";
|
||||||
|
case ColorMode::RGB_WHITE:
|
||||||
|
return "rgbw";
|
||||||
|
case ColorMode::RGB_COLOR_TEMPERATURE:
|
||||||
|
return "rgbct"; // not supported by HA
|
||||||
|
case ColorMode::RGB_COLD_WARM_WHITE:
|
||||||
|
return "rgbww";
|
||||||
|
default:
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void LightJSONSchema::dump_json(LightState &state, JsonObject root) {
|
void LightJSONSchema::dump_json(LightState &state, JsonObject root) {
|
||||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||||
if (state.supports_effects())
|
if (state.supports_effects())
|
||||||
@ -16,60 +56,36 @@ void LightJSONSchema::dump_json(LightState &state, JsonObject root) {
|
|||||||
auto values = state.remote_values;
|
auto values = state.remote_values;
|
||||||
auto traits = state.get_output()->get_traits();
|
auto traits = state.get_output()->get_traits();
|
||||||
|
|
||||||
switch (values.get_color_mode()) {
|
const auto color_mode = values.get_color_mode();
|
||||||
case ColorMode::UNKNOWN: // don't need to set color mode if we don't know it
|
const char *mode_str = get_color_mode_json_str(color_mode);
|
||||||
break;
|
if (mode_str != nullptr) {
|
||||||
case ColorMode::ON_OFF:
|
root["color_mode"] = mode_str;
|
||||||
root["color_mode"] = "onoff";
|
|
||||||
break;
|
|
||||||
case ColorMode::BRIGHTNESS:
|
|
||||||
root["color_mode"] = "brightness";
|
|
||||||
break;
|
|
||||||
case ColorMode::WHITE: // not supported by HA in MQTT
|
|
||||||
root["color_mode"] = "white";
|
|
||||||
break;
|
|
||||||
case ColorMode::COLOR_TEMPERATURE:
|
|
||||||
root["color_mode"] = "color_temp";
|
|
||||||
break;
|
|
||||||
case ColorMode::COLD_WARM_WHITE: // not supported by HA
|
|
||||||
root["color_mode"] = "cwww";
|
|
||||||
break;
|
|
||||||
case ColorMode::RGB:
|
|
||||||
root["color_mode"] = "rgb";
|
|
||||||
break;
|
|
||||||
case ColorMode::RGB_WHITE:
|
|
||||||
root["color_mode"] = "rgbw";
|
|
||||||
break;
|
|
||||||
case ColorMode::RGB_COLOR_TEMPERATURE: // not supported by HA
|
|
||||||
root["color_mode"] = "rgbct";
|
|
||||||
break;
|
|
||||||
case ColorMode::RGB_COLD_WARM_WHITE:
|
|
||||||
root["color_mode"] = "rgbww";
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (values.get_color_mode() & ColorCapability::ON_OFF)
|
if (color_mode & ColorCapability::ON_OFF)
|
||||||
root["state"] = (values.get_state() != 0.0f) ? "ON" : "OFF";
|
root["state"] = (values.get_state() != 0.0f) ? "ON" : "OFF";
|
||||||
if (values.get_color_mode() & ColorCapability::BRIGHTNESS)
|
if (color_mode & ColorCapability::BRIGHTNESS)
|
||||||
root["brightness"] = uint8_t(values.get_brightness() * 255);
|
root["brightness"] = to_uint8_scaled(values.get_brightness());
|
||||||
|
|
||||||
JsonObject color = root["color"].to<JsonObject>();
|
JsonObject color = root["color"].to<JsonObject>();
|
||||||
if (values.get_color_mode() & ColorCapability::RGB) {
|
if (color_mode & ColorCapability::RGB) {
|
||||||
color["r"] = uint8_t(values.get_color_brightness() * values.get_red() * 255);
|
float color_brightness = values.get_color_brightness();
|
||||||
color["g"] = uint8_t(values.get_color_brightness() * values.get_green() * 255);
|
color["r"] = to_uint8_scaled(color_brightness * values.get_red());
|
||||||
color["b"] = uint8_t(values.get_color_brightness() * values.get_blue() * 255);
|
color["g"] = to_uint8_scaled(color_brightness * values.get_green());
|
||||||
|
color["b"] = to_uint8_scaled(color_brightness * values.get_blue());
|
||||||
}
|
}
|
||||||
if (values.get_color_mode() & ColorCapability::WHITE) {
|
if (color_mode & ColorCapability::WHITE) {
|
||||||
color["w"] = uint8_t(values.get_white() * 255);
|
uint8_t white_val = to_uint8_scaled(values.get_white());
|
||||||
root["white_value"] = uint8_t(values.get_white() * 255); // legacy API
|
color["w"] = white_val;
|
||||||
|
root["white_value"] = white_val; // legacy API
|
||||||
}
|
}
|
||||||
if (values.get_color_mode() & ColorCapability::COLOR_TEMPERATURE) {
|
if (color_mode & ColorCapability::COLOR_TEMPERATURE) {
|
||||||
// this one isn't under the color subkey for some reason
|
// this one isn't under the color subkey for some reason
|
||||||
root["color_temp"] = uint32_t(values.get_color_temperature());
|
root["color_temp"] = uint32_t(values.get_color_temperature());
|
||||||
}
|
}
|
||||||
if (values.get_color_mode() & ColorCapability::COLD_WARM_WHITE) {
|
if (color_mode & ColorCapability::COLD_WARM_WHITE) {
|
||||||
color["c"] = uint8_t(values.get_cold_white() * 255);
|
color["c"] = to_uint8_scaled(values.get_cold_white());
|
||||||
color["w"] = uint8_t(values.get_warm_white() * 255);
|
color["w"] = to_uint8_scaled(values.get_warm_white());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,22 +115,16 @@ void LightJSONSchema::parse_color_json(LightState &state, LightCall &call, JsonO
|
|||||||
JsonObject color = root["color"];
|
JsonObject color = root["color"];
|
||||||
// HA also encodes brightness information in the r, g, b values, so extract that and set it as color brightness.
|
// HA also encodes brightness information in the r, g, b values, so extract that and set it as color brightness.
|
||||||
float max_rgb = 0.0f;
|
float max_rgb = 0.0f;
|
||||||
if (color["r"].is<uint8_t>()) {
|
|
||||||
float r = float(color["r"]) / 255.0f;
|
float r = parse_color_component(color, "r", call, &LightCall::set_red);
|
||||||
max_rgb = fmaxf(max_rgb, r);
|
float g = parse_color_component(color, "g", call, &LightCall::set_green);
|
||||||
call.set_red(r);
|
float b = parse_color_component(color, "b", call, &LightCall::set_blue);
|
||||||
}
|
|
||||||
if (color["g"].is<uint8_t>()) {
|
max_rgb = fmaxf(max_rgb, r);
|
||||||
float g = float(color["g"]) / 255.0f;
|
max_rgb = fmaxf(max_rgb, g);
|
||||||
max_rgb = fmaxf(max_rgb, g);
|
max_rgb = fmaxf(max_rgb, b);
|
||||||
call.set_green(g);
|
|
||||||
}
|
if (max_rgb > 0.0f) {
|
||||||
if (color["b"].is<uint8_t>()) {
|
|
||||||
float b = float(color["b"]) / 255.0f;
|
|
||||||
max_rgb = fmaxf(max_rgb, b);
|
|
||||||
call.set_blue(b);
|
|
||||||
}
|
|
||||||
if (color["r"].is<uint8_t>() || color["g"].is<uint8_t>() || color["b"].is<uint8_t>()) {
|
|
||||||
call.set_color_brightness(max_rgb);
|
call.set_color_brightness(max_rgb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user