mirror of
https://github.com/esphome/esphome.git
synced 2024-11-10 09:17:46 +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),
|
cv.has_at_least_one_key(CONF_TARGET_TEMPERATURE_DATAPOINT, CONF_SWITCH_DATAPOINT),
|
||||||
validate_temperature_multipliers,
|
validate_temperature_multipliers,
|
||||||
validate_cooling_values,
|
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):
|
if switch_datapoint := config.get(CONF_SWITCH_DATAPOINT):
|
||||||
cg.add(var.set_switch_id(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):
|
if active_state_config := config.get(CONF_ACTIVE_STATE):
|
||||||
cg.add(var.set_active_state_id(active_state_config.get(CONF_DATAPOINT)))
|
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:
|
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))
|
cg.add(var.set_active_state_drying_value(drying_value))
|
||||||
if (fanonly_value := active_state_config.get(CONF_FANONLY_VALUE)) is not None:
|
if (fanonly_value := active_state_config.get(CONF_FANONLY_VALUE)) is not None:
|
||||||
cg.add(var.set_active_state_fanonly_value(fanonly_value))
|
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):
|
if target_temperature_datapoint := config.get(CONF_TARGET_TEMPERATURE_DATAPOINT):
|
||||||
cg.add(var.set_target_temperature_id(target_temperature_datapoint))
|
cg.add(var.set_target_temperature_id(target_temperature_datapoint))
|
||||||
|
|
|
@ -24,14 +24,6 @@ void TuyaClimate::setup() {
|
||||||
this->publish_state();
|
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) {
|
if (this->heating_state_pin_ != nullptr) {
|
||||||
this->heating_state_pin_->setup();
|
this->heating_state_pin_->setup();
|
||||||
this->heating_state_ = this->heating_state_pin_->digital_read();
|
this->heating_state_ = this->heating_state_pin_->digital_read();
|
||||||
|
@ -40,6 +32,13 @@ void TuyaClimate::setup() {
|
||||||
this->cooling_state_pin_->setup();
|
this->cooling_state_pin_->setup();
|
||||||
this->cooling_state_ = this->cooling_state_pin_->digital_read();
|
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()) {
|
if (this->target_temperature_id_.has_value()) {
|
||||||
this->parent_->register_listener(*this->target_temperature_id_, [this](const TuyaDatapoint &datapoint) {
|
this->parent_->register_listener(*this->target_temperature_id_, [this](const TuyaDatapoint &datapoint) {
|
||||||
|
@ -113,9 +112,6 @@ void TuyaClimate::setup() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TuyaClimate::loop() {
|
void TuyaClimate::loop() {
|
||||||
if (this->active_state_id_.has_value())
|
|
||||||
return;
|
|
||||||
|
|
||||||
bool state_changed = false;
|
bool state_changed = false;
|
||||||
if (this->heating_state_pin_ != nullptr) {
|
if (this->heating_state_pin_ != nullptr) {
|
||||||
bool heating_state = this->heating_state_pin_->digital_read();
|
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);
|
this->parent_->set_boolean_datapoint_value(*this->switch_id_, switch_state);
|
||||||
const climate::ClimateMode new_mode = *call.get_mode();
|
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_) {
|
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_);
|
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_) {
|
} 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()) {
|
} 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_);
|
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);
|
control_swing_mode_(call);
|
||||||
|
@ -422,7 +422,32 @@ void TuyaClimate::compute_state_() {
|
||||||
}
|
}
|
||||||
|
|
||||||
climate::ClimateAction target_action = climate::CLIMATE_ACTION_IDLE;
|
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()) {
|
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
|
// Use state from MCU datapoint
|
||||||
if (this->supports_heat_ && this->active_state_heating_value_.has_value() &&
|
if (this->supports_heat_ && this->active_state_heating_value_.has_value() &&
|
||||||
this->active_state_ == this->active_state_heating_value_) {
|
this->active_state_ == this->active_state_heating_value_) {
|
||||||
|
@ -441,15 +466,6 @@ void TuyaClimate::compute_state_() {
|
||||||
target_action = climate::CLIMATE_ACTION_FAN;
|
target_action = climate::CLIMATE_ACTION_FAN;
|
||||||
this->mode = climate::CLIMATE_MODE_FAN_ONLY;
|
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 {
|
} else {
|
||||||
// Fallback to active state calc based on temp and hysteresis
|
// Fallback to active state calc based on temp and hysteresis
|
||||||
const float temp_diff = this->target_temperature - this->current_temperature;
|
const float temp_diff = this->target_temperature - this->current_temperature;
|
||||||
|
|
Loading…
Reference in a new issue