From ffc6fe9ca0a3653e22d64c7c51e697590ad26191 Mon Sep 17 00:00:00 2001 From: Ryan Mounce Date: Wed, 5 May 2021 13:54:31 +0930 Subject: [PATCH] Add support for controlling Tuya fan direction (#1409) --- esphome/components/tuya/fan/__init__.py | 4 ++++ esphome/components/tuya/fan/tuya_fan.cpp | 24 ++++++++++++++++++++++-- esphome/components/tuya/fan/tuya_fan.h | 3 +++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/esphome/components/tuya/fan/__init__.py b/esphome/components/tuya/fan/__init__.py index b5e3e579be..5d3345a5c4 100644 --- a/esphome/components/tuya/fan/__init__.py +++ b/esphome/components/tuya/fan/__init__.py @@ -8,6 +8,7 @@ DEPENDENCIES = ["tuya"] CONF_SPEED_DATAPOINT = "speed_datapoint" CONF_OSCILLATION_DATAPOINT = "oscillation_datapoint" +CONF_DIRECTION_DATAPOINT = "direction_datapoint" TuyaFan = tuya_ns.class_("TuyaFan", cg.Component) @@ -19,6 +20,7 @@ CONFIG_SCHEMA = cv.All( cv.Optional(CONF_OSCILLATION_DATAPOINT): cv.uint8_t, cv.Optional(CONF_SPEED_DATAPOINT): cv.uint8_t, cv.Optional(CONF_SWITCH_DATAPOINT): cv.uint8_t, + cv.Optional(CONF_DIRECTION_DATAPOINT): cv.uint8_t, cv.Optional(CONF_SPEED_COUNT, default=3): cv.int_range(min=1, max=256), } ).extend(cv.COMPONENT_SCHEMA), @@ -41,3 +43,5 @@ def to_code(config): cg.add(var.set_switch_id(config[CONF_SWITCH_DATAPOINT])) if CONF_OSCILLATION_DATAPOINT in config: cg.add(var.set_oscillation_id(config[CONF_OSCILLATION_DATAPOINT])) + if CONF_DIRECTION_DATAPOINT in config: + cg.add(var.set_direction_id(config[CONF_DIRECTION_DATAPOINT])) diff --git a/esphome/components/tuya/fan/tuya_fan.cpp b/esphome/components/tuya/fan/tuya_fan.cpp index 26e5de253d..62f4a78db7 100644 --- a/esphome/components/tuya/fan/tuya_fan.cpp +++ b/esphome/components/tuya/fan/tuya_fan.cpp @@ -8,8 +8,8 @@ namespace tuya { static const char *TAG = "tuya.fan"; void TuyaFan::setup() { - auto traits = - fan::FanTraits(this->oscillation_id_.has_value(), this->speed_id_.has_value(), false, this->speed_count_); + auto traits = fan::FanTraits(this->oscillation_id_.has_value(), this->speed_id_.has_value(), + this->direction_id_.has_value(), this->speed_count_); this->fan_->set_traits(traits); if (this->speed_id_.has_value()) { @@ -39,6 +39,15 @@ void TuyaFan::setup() { ESP_LOGD(TAG, "MCU reported oscillation is: %s", ONOFF(datapoint.value_bool)); }); } + if (this->direction_id_.has_value()) { + this->parent_->register_listener(*this->direction_id_, [this](TuyaDatapoint datapoint) { + auto call = this->fan_->make_call(); + call.set_direction(datapoint.value_bool ? fan::FAN_DIRECTION_REVERSE : fan::FAN_DIRECTION_FORWARD); + call.perform(); + ESP_LOGD(TAG, "MCU reported reverse direction is: %s", ONOFF(datapoint.value_bool)); + }); + } + this->fan_->add_on_state_callback([this]() { this->write_state(); }); } @@ -51,6 +60,8 @@ void TuyaFan::dump_config() { ESP_LOGCONFIG(TAG, " Switch has datapoint ID %u", *this->switch_id_); if (this->oscillation_id_.has_value()) ESP_LOGCONFIG(TAG, " Oscillation has datapoint ID %u", *this->oscillation_id_); + if (this->direction_id_.has_value()) + ESP_LOGCONFIG(TAG, " Direction has datapoint ID %u", *this->direction_id_); } void TuyaFan::write_state() { @@ -70,6 +81,15 @@ void TuyaFan::write_state() { this->parent_->set_datapoint_value(datapoint); ESP_LOGD(TAG, "Setting oscillating: %s", ONOFF(this->fan_->oscillating)); } + if (this->direction_id_.has_value()) { + TuyaDatapoint datapoint{}; + datapoint.id = *this->direction_id_; + datapoint.type = TuyaDatapointType::BOOLEAN; + bool enable = this->fan_->direction == fan::FAN_DIRECTION_REVERSE; + datapoint.value_bool = enable; + this->parent_->set_datapoint_value(datapoint); + ESP_LOGD(TAG, "Setting reverse direction: %s", ONOFF(enable)); + } if (this->speed_id_.has_value()) { TuyaDatapoint datapoint{}; datapoint.id = *this->speed_id_; diff --git a/esphome/components/tuya/fan/tuya_fan.h b/esphome/components/tuya/fan/tuya_fan.h index ae31df087c..a24e7a218e 100644 --- a/esphome/components/tuya/fan/tuya_fan.h +++ b/esphome/components/tuya/fan/tuya_fan.h @@ -15,17 +15,20 @@ class TuyaFan : public Component { void set_speed_id(uint8_t speed_id) { this->speed_id_ = speed_id; } void set_switch_id(uint8_t switch_id) { this->switch_id_ = switch_id; } void set_oscillation_id(uint8_t oscillation_id) { this->oscillation_id_ = oscillation_id; } + void set_direction_id(uint8_t direction_id) { this->direction_id_ = direction_id; } void write_state(); protected: void update_speed_(uint32_t value); void update_switch_(uint32_t value); void update_oscillation_(uint32_t value); + void update_direction_(uint32_t value); Tuya *parent_; optional speed_id_{}; optional switch_id_{}; optional oscillation_id_{}; + optional direction_id_{}; fan::FanState *fan_; int speed_count_{}; };