From c9055f2aefdc99c0e5c3dec6246e53efdffecaff Mon Sep 17 00:00:00 2001 From: Yaroslav Date: Wed, 11 Nov 2020 19:31:35 +0200 Subject: [PATCH] Allow Tuya climate temperature_multiplier to be current/target multiplier (#1345) * Separate temperature_multiplier to current/target multiplier * Apply suggestions from code review Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> --- esphome/components/tuya/climate/__init__.py | 47 +++++++++++++++++-- .../components/tuya/climate/tuya_climate.cpp | 6 +-- .../components/tuya/climate/tuya_climate.h | 10 ++-- tests/test4.yaml | 3 +- 4 files changed, 56 insertions(+), 10 deletions(-) diff --git a/esphome/components/tuya/climate/__init__.py b/esphome/components/tuya/climate/__init__.py index 79c6551c14..f0219de97b 100644 --- a/esphome/components/tuya/climate/__init__.py +++ b/esphome/components/tuya/climate/__init__.py @@ -10,18 +10,54 @@ CODEOWNERS = ['@jesserockz'] CONF_TARGET_TEMPERATURE_DATAPOINT = 'target_temperature_datapoint' CONF_CURRENT_TEMPERATURE_DATAPOINT = 'current_temperature_datapoint' CONF_TEMPERATURE_MULTIPLIER = 'temperature_multiplier' +CONF_CURRENT_TEMPERATURE_MULTIPLIER = 'current_temperature_multiplier' +CONF_TARGET_TEMPERATURE_MULTIPLIER = 'target_temperature_multiplier' TuyaClimate = tuya_ns.class_('TuyaClimate', climate.Climate, cg.Component) + +def validate_temperature_multipliers(value): + if CONF_TEMPERATURE_MULTIPLIER in value: + if ( + CONF_CURRENT_TEMPERATURE_MULTIPLIER in value + or CONF_TARGET_TEMPERATURE_MULTIPLIER in value + ): + raise cv.Invalid((f"Cannot have {CONF_TEMPERATURE_MULTIPLIER} at the same time as " + f"{CONF_CURRENT_TEMPERATURE_MULTIPLIER} and " + f"{CONF_TARGET_TEMPERATURE_MULTIPLIER}")) + if ( + CONF_CURRENT_TEMPERATURE_MULTIPLIER in value + and CONF_TARGET_TEMPERATURE_MULTIPLIER not in value + ): + raise cv.Invalid((f"{CONF_TARGET_TEMPERATURE_MULTIPLIER} required if using " + f"{CONF_CURRENT_TEMPERATURE_MULTIPLIER}")) + if ( + CONF_TARGET_TEMPERATURE_MULTIPLIER in value + and CONF_CURRENT_TEMPERATURE_MULTIPLIER not in value + ): + raise cv.Invalid((f"{CONF_CURRENT_TEMPERATURE_MULTIPLIER} required if using " + f"{CONF_TARGET_TEMPERATURE_MULTIPLIER}")) + keys = ( + CONF_TEMPERATURE_MULTIPLIER, + CONF_CURRENT_TEMPERATURE_MULTIPLIER, + CONF_TARGET_TEMPERATURE_MULTIPLIER + ) + if all(multiplier not in value for multiplier in keys): + value[CONF_TEMPERATURE_MULTIPLIER] = 1.0 + return value + + CONFIG_SCHEMA = cv.All(climate.CLIMATE_SCHEMA.extend({ cv.GenerateID(): cv.declare_id(TuyaClimate), cv.GenerateID(CONF_TUYA_ID): cv.use_id(Tuya), cv.Optional(CONF_SWITCH_DATAPOINT): cv.uint8_t, cv.Optional(CONF_TARGET_TEMPERATURE_DATAPOINT): cv.uint8_t, cv.Optional(CONF_CURRENT_TEMPERATURE_DATAPOINT): cv.uint8_t, - cv.Optional(CONF_TEMPERATURE_MULTIPLIER, default=1): cv.positive_float, + cv.Optional(CONF_TEMPERATURE_MULTIPLIER): cv.positive_float, + cv.Optional(CONF_CURRENT_TEMPERATURE_MULTIPLIER): cv.positive_float, + cv.Optional(CONF_TARGET_TEMPERATURE_MULTIPLIER): cv.positive_float, }).extend(cv.COMPONENT_SCHEMA), cv.has_at_least_one_key( - CONF_TARGET_TEMPERATURE_DATAPOINT, CONF_SWITCH_DATAPOINT)) + CONF_TARGET_TEMPERATURE_DATAPOINT, CONF_SWITCH_DATAPOINT), validate_temperature_multipliers) def to_code(config): @@ -38,4 +74,9 @@ def to_code(config): cg.add(var.set_target_temperature_id(config[CONF_TARGET_TEMPERATURE_DATAPOINT])) if CONF_CURRENT_TEMPERATURE_DATAPOINT in config: cg.add(var.set_current_temperature_id(config[CONF_CURRENT_TEMPERATURE_DATAPOINT])) - cg.add(var.set_temperature_multiplier(config[CONF_TEMPERATURE_MULTIPLIER])) + if CONF_TEMPERATURE_MULTIPLIER in config: + cg.add(var.set_target_temperature_multiplier(config[CONF_TEMPERATURE_MULTIPLIER])) + cg.add(var.set_current_temperature_multiplier(config[CONF_TEMPERATURE_MULTIPLIER])) + else: + cg.add(var.set_current_temperature_multiplier(config[CONF_CURRENT_TEMPERATURE_MULTIPLIER])) + cg.add(var.set_target_temperature_multiplier(config[CONF_TARGET_TEMPERATURE_MULTIPLIER])) diff --git a/esphome/components/tuya/climate/tuya_climate.cpp b/esphome/components/tuya/climate/tuya_climate.cpp index 0b66a58af6..d1f6829e72 100644 --- a/esphome/components/tuya/climate/tuya_climate.cpp +++ b/esphome/components/tuya/climate/tuya_climate.cpp @@ -21,7 +21,7 @@ void TuyaClimate::setup() { } if (this->target_temperature_id_.has_value()) { this->parent_->register_listener(*this->target_temperature_id_, [this](TuyaDatapoint datapoint) { - this->target_temperature = datapoint.value_int * this->temperature_multiplier_; + this->target_temperature = datapoint.value_int * this->target_temperature_multiplier_; this->compute_state_(); this->publish_state(); ESP_LOGD(TAG, "MCU reported target temperature is: %.1f", this->target_temperature); @@ -29,7 +29,7 @@ void TuyaClimate::setup() { } if (this->current_temperature_id_.has_value()) { this->parent_->register_listener(*this->current_temperature_id_, [this](TuyaDatapoint datapoint) { - this->current_temperature = datapoint.value_int * this->temperature_multiplier_; + this->current_temperature = datapoint.value_int * this->current_temperature_multiplier_; this->compute_state_(); this->publish_state(); ESP_LOGD(TAG, "MCU reported current temperature is: %.1f", this->current_temperature); @@ -55,7 +55,7 @@ void TuyaClimate::control(const climate::ClimateCall &call) { TuyaDatapoint datapoint{}; datapoint.id = *this->target_temperature_id_; datapoint.type = TuyaDatapointType::INTEGER; - datapoint.value_int = (int) (this->target_temperature / this->temperature_multiplier_); + datapoint.value_int = (int) (this->target_temperature / this->target_temperature_multiplier_); this->parent_->set_datapoint_value(datapoint); ESP_LOGD(TAG, "Setting target temperature: %.1f", this->target_temperature); } diff --git a/esphome/components/tuya/climate/tuya_climate.h b/esphome/components/tuya/climate/tuya_climate.h index e09e110a35..e9c366e898 100644 --- a/esphome/components/tuya/climate/tuya_climate.h +++ b/esphome/components/tuya/climate/tuya_climate.h @@ -18,8 +18,11 @@ class TuyaClimate : public climate::Climate, public Component { void set_current_temperature_id(uint8_t current_temperature_id) { this->current_temperature_id_ = current_temperature_id; } - void set_temperature_multiplier(float temperature_multiplier) { - this->temperature_multiplier_ = temperature_multiplier; + void set_current_temperature_multiplier(float temperature_multiplier) { + this->current_temperature_multiplier_ = temperature_multiplier; + } + void set_target_temperature_multiplier(float temperature_multiplier) { + this->target_temperature_multiplier_ = temperature_multiplier; } void set_tuya_parent(Tuya *parent) { this->parent_ = parent; } @@ -40,7 +43,8 @@ class TuyaClimate : public climate::Climate, public Component { optional switch_id_{}; optional target_temperature_id_{}; optional current_temperature_id_{}; - float temperature_multiplier_{1.0f}; + float current_temperature_multiplier_{1.0f}; + float target_temperature_multiplier_{1.0f}; }; } // namespace tuya diff --git a/tests/test4.yaml b/tests/test4.yaml index 768252efd2..bfeff01e93 100644 --- a/tests/test4.yaml +++ b/tests/test4.yaml @@ -92,7 +92,8 @@ climate: id: tuya_climate switch_datapoint: 1 target_temperature_datapoint: 3 - temperature_multiplier: 0.5 + current_temperature_multiplier: 0.5 + target_temperature_multiplier: 0.5 switch: - platform: tuya