mirror of
https://github.com/esphome/esphome.git
synced 2024-11-22 06:58:11 +01:00
[Tuya Climate] Support both datapoint and pins for active state (#6789)
This commit is contained in:
parent
c52d5c0279
commit
cc217d8a83
2 changed files with 52 additions and 39 deletions
|
@ -189,8 +189,6 @@ CONFIG_SCHEMA = cv.All(
|
|||
cv.has_at_least_one_key(CONF_TARGET_TEMPERATURE_DATAPOINT, CONF_SWITCH_DATAPOINT),
|
||||
validate_temperature_multipliers,
|
||||
validate_cooling_values,
|
||||
cv.has_at_most_one_key(CONF_ACTIVE_STATE, CONF_HEATING_STATE_PIN),
|
||||
cv.has_at_most_one_key(CONF_ACTIVE_STATE, CONF_COOLING_STATE_PIN),
|
||||
)
|
||||
|
||||
|
||||
|
@ -207,6 +205,12 @@ async def to_code(config):
|
|||
if switch_datapoint := config.get(CONF_SWITCH_DATAPOINT):
|
||||
cg.add(var.set_switch_id(switch_datapoint))
|
||||
|
||||
if heating_state_pin_config := config.get(CONF_HEATING_STATE_PIN):
|
||||
heating_state_pin = await cg.gpio_pin_expression(heating_state_pin_config)
|
||||
cg.add(var.set_heating_state_pin(heating_state_pin))
|
||||
if cooling_state_pin_config := config.get(CONF_COOLING_STATE_PIN):
|
||||
cooling_state_pin = await cg.gpio_pin_expression(cooling_state_pin_config)
|
||||
cg.add(var.set_cooling_state_pin(cooling_state_pin))
|
||||
if active_state_config := config.get(CONF_ACTIVE_STATE):
|
||||
cg.add(var.set_active_state_id(active_state_config.get(CONF_DATAPOINT)))
|
||||
if (heating_value := active_state_config.get(CONF_HEATING_VALUE)) is not None:
|
||||
|
@ -217,13 +221,6 @@ async def to_code(config):
|
|||
cg.add(var.set_active_state_drying_value(drying_value))
|
||||
if (fanonly_value := active_state_config.get(CONF_FANONLY_VALUE)) is not None:
|
||||
cg.add(var.set_active_state_fanonly_value(fanonly_value))
|
||||
else:
|
||||
if heating_state_pin_config := config.get(CONF_HEATING_STATE_PIN):
|
||||
heating_state_pin = await cg.gpio_pin_expression(heating_state_pin_config)
|
||||
cg.add(var.set_heating_state_pin(heating_state_pin))
|
||||
if cooling_state_pin_config := config.get(CONF_COOLING_STATE_PIN):
|
||||
cooling_state_pin = await cg.gpio_pin_expression(cooling_state_pin_config)
|
||||
cg.add(var.set_cooling_state_pin(cooling_state_pin))
|
||||
|
||||
if target_temperature_datapoint := config.get(CONF_TARGET_TEMPERATURE_DATAPOINT):
|
||||
cg.add(var.set_target_temperature_id(target_temperature_datapoint))
|
||||
|
|
|
@ -24,14 +24,6 @@ void TuyaClimate::setup() {
|
|||
this->publish_state();
|
||||
});
|
||||
}
|
||||
if (this->active_state_id_.has_value()) {
|
||||
this->parent_->register_listener(*this->active_state_id_, [this](const TuyaDatapoint &datapoint) {
|
||||
ESP_LOGV(TAG, "MCU reported active state is: %u", datapoint.value_enum);
|
||||
this->active_state_ = datapoint.value_enum;
|
||||
this->compute_state_();
|
||||
this->publish_state();
|
||||
});
|
||||
} else {
|
||||
if (this->heating_state_pin_ != nullptr) {
|
||||
this->heating_state_pin_->setup();
|
||||
this->heating_state_ = this->heating_state_pin_->digital_read();
|
||||
|
@ -40,6 +32,13 @@ void TuyaClimate::setup() {
|
|||
this->cooling_state_pin_->setup();
|
||||
this->cooling_state_ = this->cooling_state_pin_->digital_read();
|
||||
}
|
||||
if (this->active_state_id_.has_value()) {
|
||||
this->parent_->register_listener(*this->active_state_id_, [this](const TuyaDatapoint &datapoint) {
|
||||
ESP_LOGV(TAG, "MCU reported active state is: %u", datapoint.value_enum);
|
||||
this->active_state_ = datapoint.value_enum;
|
||||
this->compute_state_();
|
||||
this->publish_state();
|
||||
});
|
||||
}
|
||||
if (this->target_temperature_id_.has_value()) {
|
||||
this->parent_->register_listener(*this->target_temperature_id_, [this](const TuyaDatapoint &datapoint) {
|
||||
|
@ -113,9 +112,6 @@ void TuyaClimate::setup() {
|
|||
}
|
||||
|
||||
void TuyaClimate::loop() {
|
||||
if (this->active_state_id_.has_value())
|
||||
return;
|
||||
|
||||
bool state_changed = false;
|
||||
if (this->heating_state_pin_ != nullptr) {
|
||||
bool heating_state = this->heating_state_pin_->digital_read();
|
||||
|
@ -147,6 +143,7 @@ void TuyaClimate::control(const climate::ClimateCall &call) {
|
|||
this->parent_->set_boolean_datapoint_value(*this->switch_id_, switch_state);
|
||||
const climate::ClimateMode new_mode = *call.get_mode();
|
||||
|
||||
if (this->active_state_id_.has_value()) {
|
||||
if (new_mode == climate::CLIMATE_MODE_HEAT && this->supports_heat_) {
|
||||
this->parent_->set_enum_datapoint_value(*this->active_state_id_, *this->active_state_heating_value_);
|
||||
} else if (new_mode == climate::CLIMATE_MODE_COOL && this->supports_cool_) {
|
||||
|
@ -156,6 +153,9 @@ void TuyaClimate::control(const climate::ClimateCall &call) {
|
|||
} else if (new_mode == climate::CLIMATE_MODE_FAN_ONLY && this->active_state_fanonly_value_.has_value()) {
|
||||
this->parent_->set_enum_datapoint_value(*this->active_state_id_, *this->active_state_fanonly_value_);
|
||||
}
|
||||
} else {
|
||||
ESP_LOGW(TAG, "Active state (mode) datapoint not configured");
|
||||
}
|
||||
}
|
||||
|
||||
control_swing_mode_(call);
|
||||
|
@ -422,7 +422,32 @@ void TuyaClimate::compute_state_() {
|
|||
}
|
||||
|
||||
climate::ClimateAction target_action = climate::CLIMATE_ACTION_IDLE;
|
||||
if (this->heating_state_pin_ != nullptr || this->cooling_state_pin_ != nullptr) {
|
||||
// Use state from input pins
|
||||
if (this->heating_state_) {
|
||||
target_action = climate::CLIMATE_ACTION_HEATING;
|
||||
this->mode = climate::CLIMATE_MODE_HEAT;
|
||||
} else if (this->cooling_state_) {
|
||||
target_action = climate::CLIMATE_ACTION_COOLING;
|
||||
this->mode = climate::CLIMATE_MODE_COOL;
|
||||
}
|
||||
if (this->active_state_id_.has_value()) {
|
||||
// Both are available, use MCU datapoint as mode
|
||||
if (this->supports_heat_ && this->active_state_heating_value_.has_value() &&
|
||||
this->active_state_ == this->active_state_heating_value_) {
|
||||
this->mode = climate::CLIMATE_MODE_HEAT;
|
||||
} else if (this->supports_cool_ && this->active_state_cooling_value_.has_value() &&
|
||||
this->active_state_ == this->active_state_cooling_value_) {
|
||||
this->mode = climate::CLIMATE_MODE_COOL;
|
||||
} else if (this->active_state_drying_value_.has_value() &&
|
||||
this->active_state_ == this->active_state_drying_value_) {
|
||||
this->mode = climate::CLIMATE_MODE_DRY;
|
||||
} else if (this->active_state_fanonly_value_.has_value() &&
|
||||
this->active_state_ == this->active_state_fanonly_value_) {
|
||||
this->mode = climate::CLIMATE_MODE_FAN_ONLY;
|
||||
}
|
||||
}
|
||||
} else if (this->active_state_id_.has_value()) {
|
||||
// Use state from MCU datapoint
|
||||
if (this->supports_heat_ && this->active_state_heating_value_.has_value() &&
|
||||
this->active_state_ == this->active_state_heating_value_) {
|
||||
|
@ -441,15 +466,6 @@ void TuyaClimate::compute_state_() {
|
|||
target_action = climate::CLIMATE_ACTION_FAN;
|
||||
this->mode = climate::CLIMATE_MODE_FAN_ONLY;
|
||||
}
|
||||
} else if (this->heating_state_pin_ != nullptr || this->cooling_state_pin_ != nullptr) {
|
||||
// Use state from input pins
|
||||
if (this->heating_state_) {
|
||||
target_action = climate::CLIMATE_ACTION_HEATING;
|
||||
this->mode = climate::CLIMATE_MODE_HEAT;
|
||||
} else if (this->cooling_state_) {
|
||||
target_action = climate::CLIMATE_ACTION_COOLING;
|
||||
this->mode = climate::CLIMATE_MODE_COOL;
|
||||
}
|
||||
} else {
|
||||
// Fallback to active state calc based on temp and hysteresis
|
||||
const float temp_diff = this->target_temperature - this->current_temperature;
|
||||
|
|
Loading…
Reference in a new issue