[Tuya Climate] Support both datapoint and pins for active state (#6789)

This commit is contained in:
zry98 2024-06-05 10:11:19 +02:00 committed by GitHub
parent c52d5c0279
commit cc217d8a83
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 52 additions and 39 deletions

View file

@ -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))

View file

@ -24,6 +24,14 @@ void TuyaClimate::setup() {
this->publish_state(); this->publish_state();
}); });
} }
if (this->heating_state_pin_ != nullptr) {
this->heating_state_pin_->setup();
this->heating_state_ = this->heating_state_pin_->digital_read();
}
if (this->cooling_state_pin_ != nullptr) {
this->cooling_state_pin_->setup();
this->cooling_state_ = this->cooling_state_pin_->digital_read();
}
if (this->active_state_id_.has_value()) { if (this->active_state_id_.has_value()) {
this->parent_->register_listener(*this->active_state_id_, [this](const TuyaDatapoint &datapoint) { this->parent_->register_listener(*this->active_state_id_, [this](const TuyaDatapoint &datapoint) {
ESP_LOGV(TAG, "MCU reported active state is: %u", datapoint.value_enum); ESP_LOGV(TAG, "MCU reported active state is: %u", datapoint.value_enum);
@ -31,15 +39,6 @@ void TuyaClimate::setup() {
this->compute_state_(); this->compute_state_();
this->publish_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();
}
if (this->cooling_state_pin_ != nullptr) {
this->cooling_state_pin_->setup();
this->cooling_state_ = this->cooling_state_pin_->digital_read();
}
} }
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,14 +143,18 @@ 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 (new_mode == climate::CLIMATE_MODE_HEAT && this->supports_heat_) { if (this->active_state_id_.has_value()) {
this->parent_->set_enum_datapoint_value(*this->active_state_id_, *this->active_state_heating_value_); if (new_mode == climate::CLIMATE_MODE_HEAT && this->supports_heat_) {
} else if (new_mode == climate::CLIMATE_MODE_COOL && this->supports_cool_) { 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_cooling_value_); } else if (new_mode == climate::CLIMATE_MODE_COOL && this->supports_cool_) {
} else if (new_mode == climate::CLIMATE_MODE_DRY && this->active_state_drying_value_.has_value()) { this->parent_->set_enum_datapoint_value(*this->active_state_id_, *this->active_state_cooling_value_);
this->parent_->set_enum_datapoint_value(*this->active_state_id_, *this->active_state_drying_value_); } else if (new_mode == climate::CLIMATE_MODE_DRY && this->active_state_drying_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_drying_value_);
this->parent_->set_enum_datapoint_value(*this->active_state_id_, *this->active_state_fanonly_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_);
}
} else {
ESP_LOGW(TAG, "Active state (mode) datapoint not configured");
} }
} }
@ -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->active_state_id_.has_value()) { 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 // 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;