From 70ab0d912e5d025c5e36fffcf5f10d1c9b0cc0ad Mon Sep 17 00:00:00 2001 From: ChNussbaum Date: Fri, 20 Nov 2020 08:07:51 -0600 Subject: [PATCH] Add Tuya Dimmer as Fan and update Master Bath Fan --- README.md | 10 +++- custom/tuya_dimmer_as_binary_fan_output.h | 64 +++++++++++++++++++++++ devices/master_bath_fan.yaml | 33 +----------- packages/feit_dimmer_as_fan.yaml | 38 ++++++++++++++ 4 files changed, 112 insertions(+), 33 deletions(-) create mode 100644 custom/tuya_dimmer_as_binary_fan_output.h create mode 100644 packages/feit_dimmer_as_fan.yaml diff --git a/README.md b/README.md index bd4859f..50169c5 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ ## Dimmer Switches > ### [Feit Dimmers](https://www.amazon.com/gp/product/B07SXDFH38/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&psc=1) -> After trying several dimmers I finally decided to standardize on on the Feit Dimmers. I bought the first couple of these at Costco for a better price than Amazon but Costco doesn't seem to carry them anymore. +> After trying several dimmers I finally decided to standardize on on the Feit dimmers. I bought the first couple of these at Costco for a better price than Amazon but Costco doesn't seem to carry them anymore. > Things I like about these switches: > > * Can be flashed using [Tuya-Convert](https://github.com/ct-Open-Source/tuya-convert) > > * Have a solid feel to them @@ -84,3 +84,11 @@ > > * [Living Room Lights](./devices/living_room_lights.yaml) > > * [Master Bathroom Lights](./devices/master_bath_lights_1.yaml)/[Master Bathroom Lights 2](./devices/master_bath_lights_2.yaml) > > * [Office Light](./devices/office_light.yaml) + +## Dimmer Switches as On/Off Switches +> ### [Feit Dimmers](https://www.amazon.com/gp/product/B07SXDFH38/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&psc=1) +> I tried to find an on/off switch that looked/felt like the Feit dimmers but didn't find anything so I decided to use the Feit dimmers. + +> #### Fans +> I created a custom [tuya_dimmer_as_binary_fan_output.h](./custom/tuya_dimmer_as_binary_fan_output.h) component that prevents the dimmer from being dimmed (always changes it right back to 100%) and can report the change in on/off status back to a fan component. +> > * [Master Bath Fan](./devices/master_bath_fan.yaml) \ No newline at end of file diff --git a/custom/tuya_dimmer_as_binary_fan_output.h b/custom/tuya_dimmer_as_binary_fan_output.h new file mode 100644 index 0000000..be0fc48 --- /dev/null +++ b/custom/tuya_dimmer_as_binary_fan_output.h @@ -0,0 +1,64 @@ +#include "esphome.h" + +using namespace esphome; + +class TuyaDimmerBinaryFanOutput : public Component, public output::BinaryOutput +{ + public: + void setup() override; + + void set_dimmer_id(uint8_t dimmer_id) { this->dimmer_id_ = dimmer_id; } + void set_switch_id(uint8_t switch_id) { this->switch_id_ = switch_id; } + void set_tuya_parent(tuya::Tuya *parent) { this->parent_ = parent; } + void set_max_value(uint32_t max_value) { max_value_ = max_value; } + void set_fan(fan::FanState *fan) { fan_ = fan; } + + protected: + void write_state(bool state) override; + void handle_tuya_datapoint(tuya::TuyaDatapoint datapoint); + + tuya::Tuya *parent_; + optional dimmer_id_{}; + optional switch_id_{}; + uint32_t max_value_ = 1000; + fan::FanState *fan_; +}; + +void TuyaDimmerBinaryFanOutput::setup() +{ + parent_->register_listener(*switch_id_, [this](tuya::TuyaDatapoint datapoint) { handle_tuya_datapoint(datapoint); }); + + parent_->register_listener(*dimmer_id_, [this](tuya::TuyaDatapoint datapoint) { handle_tuya_datapoint(datapoint); }); +} + +void TuyaDimmerBinaryFanOutput::write_state(bool state) +{ + tuya::TuyaDatapoint datapoint{}; + datapoint.id = *switch_id_; + datapoint.type = tuya::TuyaDatapointType::BOOLEAN; + datapoint.value_bool = state; + parent_->set_datapoint_value(datapoint); +} + +void TuyaDimmerBinaryFanOutput::handle_tuya_datapoint(tuya::TuyaDatapoint datapoint) +{ + if (datapoint.id == *switch_id_) + { + auto call = fan_->make_call(); + call.set_state(datapoint.value_bool); + call.perform(); + } + else if (datapoint.id == *dimmer_id_) + { + if (datapoint.value_uint < max_value_) + { + tuya::TuyaDatapoint datapoint{}; + datapoint.id = *dimmer_id_; + datapoint.type = tuya::TuyaDatapointType::INTEGER; + datapoint.value_uint = max_value_; + parent_->set_datapoint_value(datapoint); + } + } +} + +TuyaDimmerBinaryFanOutput *TuyaFanOutput; \ No newline at end of file diff --git a/devices/master_bath_fan.yaml b/devices/master_bath_fan.yaml index aae7d93..f930b36 100644 --- a/devices/master_bath_fan.yaml +++ b/devices/master_bath_fan.yaml @@ -1,41 +1,10 @@ substitutions: device_id: master_bath_fan device_name: Master Bathroom Fan - platform: ESP8266 - board: esp01_1m ip_address: !secret master_bath_fan_ip ota_pwd: !secret master_bath_fan_ota_pwd api_pwd: !secret master_bath_fan_api_pwd ap_wifi_pwd: !secret master_bath_fan_ap_wifi_pwd packages: - device_base: !include ../packages/device_base.yaml - -binary_sensor: - - platform: gpio - id: fan_button - pin: - number: 13 - mode: INPUT_PULLUP - on_press: - then: - - fan.toggle: the_fan - -fan: - - platform: binary - id: the_fan - output: fan_output - name: ${device_name} - -output: - - platform: gpio - id: fan_output - pin: 12 - - platform: gpio - id: button_led - pin: 4 - -status_led: - pin: - number: 5 - inverted: true + device_base: !include ../packages/feit_dimmer_as_fan.yaml diff --git a/packages/feit_dimmer_as_fan.yaml b/packages/feit_dimmer_as_fan.yaml new file mode 100644 index 0000000..37900b2 --- /dev/null +++ b/packages/feit_dimmer_as_fan.yaml @@ -0,0 +1,38 @@ +substitutions: + platform: ESP8266 + board: esp01_1m + +esphome: + includes: + - ../custom/tuya_dimmer_as_binary_fan_output.h + +packages: + device_base: !include device_base.yaml + +<<: !include ../components/logger/logger_no_serial.yaml + +fan: + - platform: binary + id: the_fan + output: tuya_fan_output + name: ${device_name} + +output: + - platform: custom + type: binary + lambda: |- + TuyaFanOutput = new TuyaDimmerBinaryFanOutput(); + TuyaFanOutput->set_switch_id(1); + TuyaFanOutput->set_dimmer_id(2); + TuyaFanOutput->set_max_value(1000); + TuyaFanOutput->set_tuya_parent(tuya_tuya); + TuyaFanOutput->set_fan(the_fan); + App.register_component(TuyaFanOutput); + return {TuyaFanOutput}; + outputs: + id: tuya_fan_output + +tuya: + +uart: + - !include ../components/uart/tuya.yaml