Add configurable color datapoint (#4383)

* Add configurable color datapoint

* Lint fixes

* Review comments

* Linting
This commit is contained in:
irtimaled
2023-02-19 13:50:46 -08:00
committed by GitHub
parent 5c49730cb9
commit f68d577986
3 changed files with 97 additions and 63 deletions
+65 -51
View File
@@ -50,38 +50,39 @@ 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<uint8_t>(datapoint.value_string.substr(0, 2));
auto green = parse_hex<uint8_t>(datapoint.value_string.substr(2, 2));
auto blue = parse_hex<uint8_t>(datapoint.value_string.substr(4, 2));
if (red.has_value() && green.has_value() && blue.has_value()) {
if (this->state_->current_values != this->state_->remote_values) {
ESP_LOGD(TAG, "Light is transitioning, datapoint change ignored");
return;
}
auto call = this->state_->make_call();
call.set_rgb(float(*red) / 255, float(*green) / 255, float(*blue) / 255);
call.perform();
if (color_id_.has_value()) {
this->parent_->register_listener(*this->color_id_, [this](const TuyaDatapoint &datapoint) {
if (this->state_->current_values != this->state_->remote_values) {
ESP_LOGD(TAG, "Light is transitioning, datapoint change ignored");
return;
}
});
} else if (hsv_id_.has_value()) {
this->parent_->register_listener(*this->hsv_id_, [this](const TuyaDatapoint &datapoint) {
auto hue = parse_hex<uint16_t>(datapoint.value_string.substr(0, 4));
auto saturation = parse_hex<uint16_t>(datapoint.value_string.substr(4, 4));
auto value = parse_hex<uint16_t>(datapoint.value_string.substr(8, 4));
if (hue.has_value() && saturation.has_value() && value.has_value()) {
if (this->state_->current_values != this->state_->remote_values) {
ESP_LOGD(TAG, "Light is transitioning, datapoint change ignored");
return;
}
float red, green, blue;
hsv_to_rgb(*hue, float(*saturation) / 1000, float(*value) / 1000, red, green, blue);
auto call = this->state_->make_call();
call.set_rgb(red, green, blue);
call.perform();
switch (*this->color_type_) {
case TuyaColorType::RGBHSV:
case TuyaColorType::RGB: {
auto red = parse_hex<uint8_t>(datapoint.value_string.substr(0, 2));
auto green = parse_hex<uint8_t>(datapoint.value_string.substr(2, 2));
auto blue = parse_hex<uint8_t>(datapoint.value_string.substr(4, 2));
if (red.has_value() && green.has_value() && blue.has_value()) {
auto rgb_call = this->state_->make_call();
rgb_call.set_rgb(float(*red) / 255, float(*green) / 255, float(*blue) / 255);
rgb_call.perform();
}
break;
}
case TuyaColorType::HSV: {
auto hue = parse_hex<uint16_t>(datapoint.value_string.substr(0, 4));
auto saturation = parse_hex<uint16_t>(datapoint.value_string.substr(4, 4));
auto value = parse_hex<uint16_t>(datapoint.value_string.substr(8, 4));
if (hue.has_value() && saturation.has_value() && value.has_value()) {
float red, green, blue;
hsv_to_rgb(*hue, float(*saturation) / 1000, float(*value) / 1000, red, green, blue);
auto rgb_call = this->state_->make_call();
rgb_call.set_rgb(red, green, blue);
rgb_call.perform();
}
break;
}
}
});
}
@@ -98,17 +99,15 @@ void TuyaLight::dump_config() {
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_);
} else if (this->hsv_id_.has_value()) {
ESP_LOGCONFIG(TAG, " HSV has datapoint ID %u", *this->hsv_id_);
if (this->color_id_.has_value()) {
ESP_LOGCONFIG(TAG, " Color has datapoint ID %u", *this->color_id_);
}
}
light::LightTraits TuyaLight::get_traits() {
auto traits = light::LightTraits();
if (this->color_temperature_id_.has_value() && this->dimmer_id_.has_value()) {
if (this->rgb_id_.has_value() || this->hsv_id_.has_value()) {
if (this->color_id_.has_value()) {
if (this->color_interlock_) {
traits.set_supported_color_modes({light::ColorMode::RGB, light::ColorMode::COLOR_TEMPERATURE});
} else {
@@ -119,7 +118,7 @@ light::LightTraits TuyaLight::get_traits() {
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() || this->hsv_id_.has_value()) {
} else if (this->color_id_.has_value()) {
if (this->dimmer_id_.has_value()) {
if (this->color_interlock_) {
traits.set_supported_color_modes({light::ColorMode::RGB, light::ColorMode::WHITE});
@@ -142,7 +141,7 @@ void TuyaLight::write_state(light::LightState *state) {
float red = 0.0f, green = 0.0f, blue = 0.0f;
float color_temperature = 0.0f, brightness = 0.0f;
if (this->rgb_id_.has_value() || this->hsv_id_.has_value()) {
if (this->color_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()) {
@@ -178,21 +177,36 @@ void TuyaLight::write_state(light::LightState *state) {
}
}
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 rgb_value = buffer;
this->parent_->set_string_datapoint_value(*this->rgb_id_, rgb_value);
} else if (this->hsv_id_.has_value()) {
int hue;
float saturation, value;
rgb_to_hsv(red, green, blue, hue, saturation, value);
char buffer[13];
sprintf(buffer, "%04X%04X%04X", hue, int(saturation * 1000), int(value * 1000));
std::string hsv_value = buffer;
this->parent_->set_string_datapoint_value(*this->hsv_id_, hsv_value);
if (this->color_id_.has_value() && (brightness == 0.0f || !color_interlock_)) {
std::string color_value;
switch (*this->color_type_) {
case TuyaColorType::RGB: {
char buffer[7];
sprintf(buffer, "%02X%02X%02X", int(red * 255), int(green * 255), int(blue * 255));
color_value = buffer;
break;
}
case TuyaColorType::HSV: {
int hue;
float saturation, value;
rgb_to_hsv(red, green, blue, hue, saturation, value);
char buffer[13];
sprintf(buffer, "%04X%04X%04X", hue, int(saturation * 1000), int(value * 1000));
color_value = buffer;
break;
}
case TuyaColorType::RGBHSV: {
int hue;
float saturation, value;
rgb_to_hsv(red, green, blue, hue, saturation, value);
char buffer[15];
sprintf(buffer, "%02X%02X%02X%04X%02X%02X", int(red * 255), int(green * 255), int(blue * 255), hue,
int(saturation * 255), int(value * 255));
color_value = buffer;
break;
}
}
this->parent_->set_string_datapoint_value(*this->color_id_, color_value);
}
if (this->switch_id_.has_value()) {