mirror of
https://github.com/esphome/esphome.git
synced 2025-03-24 11:38:23 +00:00
The Tuya MCU keeps its own internal minimum brightness setting. This value may not match the minimum brightness setting for ESPHome, leading to some issues: 1. Dimming is limited--on some devices the default minimum is as high as 10%, meaning the dimmest ESPHome will go is still quite bright. 2. HA will allow a user to set a value below the MCU minimum, but the MCU will reject it and keep the previous setting, so the UI is confusing. This PR adds a setting to configure the datapoint for setting the MCU minimum brightness. If the setting is set, then ESPHome will synchronize the MCU's minimum brightness with the one configured for ESPHome on startup.
93 lines
2.8 KiB
C++
93 lines
2.8 KiB
C++
#include "esphome/core/log.h"
|
|
#include "tuya_light.h"
|
|
|
|
namespace esphome {
|
|
namespace tuya {
|
|
|
|
static const char *TAG = "tuya.light";
|
|
|
|
void TuyaLight::setup() {
|
|
if (this->dimmer_id_.has_value()) {
|
|
this->parent_->register_listener(*this->dimmer_id_, [this](TuyaDatapoint datapoint) {
|
|
auto call = this->state_->make_call();
|
|
call.set_brightness(float(datapoint.value_uint) / this->max_value_);
|
|
call.perform();
|
|
});
|
|
}
|
|
if (switch_id_.has_value()) {
|
|
this->parent_->register_listener(*this->switch_id_, [this](TuyaDatapoint datapoint) {
|
|
auto call = this->state_->make_call();
|
|
call.set_state(datapoint.value_bool);
|
|
call.perform();
|
|
});
|
|
}
|
|
if (min_value_datapoint_id_.has_value()) {
|
|
TuyaDatapoint datapoint{};
|
|
datapoint.id = *this->min_value_datapoint_id_;
|
|
datapoint.type = TuyaDatapointType::INTEGER;
|
|
datapoint.value_int = this->min_value_;
|
|
parent_->set_datapoint_value(datapoint);
|
|
}
|
|
}
|
|
|
|
void TuyaLight::dump_config() {
|
|
ESP_LOGCONFIG(TAG, "Tuya Dimmer:");
|
|
if (this->dimmer_id_.has_value())
|
|
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_);
|
|
}
|
|
|
|
light::LightTraits TuyaLight::get_traits() {
|
|
auto traits = light::LightTraits();
|
|
traits.set_supports_brightness(this->dimmer_id_.has_value());
|
|
return 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);
|
|
|
|
if (brightness == 0.0f) {
|
|
// turning off, first try via switch (if exists), then dimmer
|
|
if (switch_id_.has_value()) {
|
|
TuyaDatapoint datapoint{};
|
|
datapoint.id = *this->switch_id_;
|
|
datapoint.type = TuyaDatapointType::BOOLEAN;
|
|
datapoint.value_bool = false;
|
|
|
|
parent_->set_datapoint_value(datapoint);
|
|
} else if (dimmer_id_.has_value()) {
|
|
TuyaDatapoint datapoint{};
|
|
datapoint.id = *this->dimmer_id_;
|
|
datapoint.type = TuyaDatapointType::INTEGER;
|
|
datapoint.value_int = 0;
|
|
parent_->set_datapoint_value(datapoint);
|
|
}
|
|
return;
|
|
}
|
|
|
|
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()) {
|
|
TuyaDatapoint datapoint{};
|
|
datapoint.id = *this->dimmer_id_;
|
|
datapoint.type = TuyaDatapointType::INTEGER;
|
|
datapoint.value_int = brightness_int;
|
|
parent_->set_datapoint_value(datapoint);
|
|
}
|
|
if (this->switch_id_.has_value()) {
|
|
TuyaDatapoint datapoint{};
|
|
datapoint.id = *this->switch_id_;
|
|
datapoint.type = TuyaDatapointType::BOOLEAN;
|
|
datapoint.value_bool = true;
|
|
parent_->set_datapoint_value(datapoint);
|
|
}
|
|
}
|
|
|
|
} // namespace tuya
|
|
} // namespace esphome
|