mirror of
https://github.com/Threnklyn/esphome-dev.git
synced 2026-06-01 02:28:28 +02:00
Tuya rgb support (#2278)
Co-authored-by: Oxan van Leeuwen <oxan@oxanvanleeuwen.nl> Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
#include "esphome/core/log.h"
|
||||
#include "tuya_light.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace tuya {
|
||||
@@ -34,6 +35,18 @@ void TuyaLight::setup() {
|
||||
call.perform();
|
||||
});
|
||||
}
|
||||
if (rgb_id_.has_value()) {
|
||||
this->parent_->register_listener(*this->rgb_id_, [this](const TuyaDatapoint &datapoint) {
|
||||
auto red = parse_hex(datapoint.value_string, 0, 2);
|
||||
auto green = parse_hex(datapoint.value_string, 2, 2);
|
||||
auto blue = parse_hex(datapoint.value_string, 4, 2);
|
||||
if (red.has_value() && green.has_value() && blue.has_value()) {
|
||||
auto call = this->state_->make_call();
|
||||
call.set_rgb(float(*red) / 255, float(*green) / 255, float(*blue) / 255);
|
||||
call.perform();
|
||||
}
|
||||
});
|
||||
}
|
||||
if (min_value_datapoint_id_.has_value()) {
|
||||
parent_->set_integer_datapoint_value(*this->min_value_datapoint_id_, this->min_value_);
|
||||
}
|
||||
@@ -45,14 +58,31 @@ void TuyaLight::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, " Dimmer has datapoint ID %u", *this->dimmer_id_);
|
||||
if (this->switch_id_.has_value())
|
||||
ESP_LOGCONFIG(TAG, " Switch has datapoint ID %u", *this->switch_id_);
|
||||
if (this->rgb_id_.has_value())
|
||||
ESP_LOGCONFIG(TAG, " RGB has datapoint ID %u", *this->rgb_id_);
|
||||
}
|
||||
|
||||
light::LightTraits TuyaLight::get_traits() {
|
||||
auto traits = light::LightTraits();
|
||||
if (this->color_temperature_id_.has_value() && this->dimmer_id_.has_value()) {
|
||||
traits.set_supported_color_modes({light::ColorMode::COLOR_TEMPERATURE});
|
||||
if (this->rgb_id_.has_value()) {
|
||||
if (this->color_interlock_)
|
||||
traits.set_supported_color_modes({light::ColorMode::RGB, light::ColorMode::COLOR_TEMPERATURE});
|
||||
else
|
||||
traits.set_supported_color_modes(
|
||||
{light::ColorMode::RGB_COLOR_TEMPERATURE, light::ColorMode::COLOR_TEMPERATURE});
|
||||
} else
|
||||
traits.set_supported_color_modes({light::ColorMode::COLOR_TEMPERATURE});
|
||||
traits.set_min_mireds(this->cold_white_temperature_);
|
||||
traits.set_max_mireds(this->warm_white_temperature_);
|
||||
} else if (this->rgb_id_.has_value()) {
|
||||
if (this->dimmer_id_.has_value()) {
|
||||
if (this->color_interlock_)
|
||||
traits.set_supported_color_modes({light::ColorMode::RGB, light::ColorMode::WHITE});
|
||||
else
|
||||
traits.set_supported_color_modes({light::ColorMode::RGB_WHITE});
|
||||
} else
|
||||
traits.set_supported_color_modes({light::ColorMode::RGB});
|
||||
} else if (this->dimmer_id_.has_value()) {
|
||||
traits.set_supported_color_modes({light::ColorMode::BRIGHTNESS});
|
||||
} else {
|
||||
@@ -64,38 +94,51 @@ light::LightTraits TuyaLight::get_traits() {
|
||||
void TuyaLight::setup_state(light::LightState *state) { state_ = state; }
|
||||
|
||||
void TuyaLight::write_state(light::LightState *state) {
|
||||
float brightness;
|
||||
state->current_values_as_brightness(&brightness);
|
||||
float red = 0.0f, green = 0.0f, blue = 0.0f;
|
||||
float color_temperature = 0.0f, brightness = 0.0f;
|
||||
|
||||
if (brightness == 0.0f) {
|
||||
// turning off, first try via switch (if exists), then dimmer
|
||||
if (switch_id_.has_value()) {
|
||||
parent_->set_boolean_datapoint_value(*this->switch_id_, false);
|
||||
} else if (dimmer_id_.has_value()) {
|
||||
parent_->set_integer_datapoint_value(*this->dimmer_id_, 0);
|
||||
if (this->rgb_id_.has_value()) {
|
||||
if (this->color_temperature_id_.has_value()) {
|
||||
state->current_values_as_rgbct(&red, &green, &blue, &color_temperature, &brightness);
|
||||
} else if (this->dimmer_id_.has_value()) {
|
||||
state->current_values_as_rgbw(&red, &green, &blue, &brightness);
|
||||
} else {
|
||||
state->current_values_as_rgb(&red, &green, &blue);
|
||||
}
|
||||
return;
|
||||
} else if (this->color_temperature_id_.has_value()) {
|
||||
state->current_values_as_ct(&color_temperature, &brightness);
|
||||
} else {
|
||||
state->current_values_as_brightness(&brightness);
|
||||
}
|
||||
|
||||
if (this->color_temperature_id_.has_value()) {
|
||||
uint32_t color_temp_int =
|
||||
static_cast<uint32_t>(this->color_temperature_max_value_ *
|
||||
(state->current_values.get_color_temperature() - this->cold_white_temperature_) /
|
||||
(this->warm_white_temperature_ - this->cold_white_temperature_));
|
||||
if (this->color_temperature_invert_) {
|
||||
color_temp_int = this->color_temperature_max_value_ - color_temp_int;
|
||||
if (brightness > 0.0f || !color_interlock_) {
|
||||
if (this->color_temperature_id_.has_value()) {
|
||||
uint32_t color_temp_int = static_cast<uint32_t>(color_temperature * this->color_temperature_max_value_);
|
||||
if (this->color_temperature_invert_) {
|
||||
color_temp_int = this->color_temperature_max_value_ - color_temp_int;
|
||||
}
|
||||
parent_->set_integer_datapoint_value(*this->color_temperature_id_, color_temp_int);
|
||||
}
|
||||
|
||||
if (this->dimmer_id_.has_value()) {
|
||||
auto brightness_int = static_cast<uint32_t>(brightness * this->max_value_);
|
||||
brightness_int = std::max(brightness_int, this->min_value_);
|
||||
|
||||
parent_->set_integer_datapoint_value(*this->dimmer_id_, brightness_int);
|
||||
}
|
||||
parent_->set_integer_datapoint_value(*this->color_temperature_id_, color_temp_int);
|
||||
}
|
||||
|
||||
auto brightness_int = static_cast<uint32_t>(brightness * this->max_value_);
|
||||
brightness_int = std::max(brightness_int, this->min_value_);
|
||||
|
||||
if (this->dimmer_id_.has_value()) {
|
||||
parent_->set_integer_datapoint_value(*this->dimmer_id_, brightness_int);
|
||||
if (brightness == 0.0f || !color_interlock_) {
|
||||
if (this->rgb_id_.has_value()) {
|
||||
char buffer[7];
|
||||
sprintf(buffer, "%02X%02X%02X", int(red * 255), int(green * 255), int(blue * 255));
|
||||
std::string value = buffer;
|
||||
this->parent_->set_string_datapoint_value(*this->rgb_id_, value);
|
||||
}
|
||||
}
|
||||
|
||||
if (this->switch_id_.has_value()) {
|
||||
parent_->set_boolean_datapoint_value(*this->switch_id_, true);
|
||||
parent_->set_boolean_datapoint_value(*this->switch_id_, state->current_values.is_on());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user