Rewrite the Tuya dimmer as fan component (#11)

This commit is contained in:
Chris Nussbaum 2021-07-13 07:55:29 -05:00 committed by GitHub
parent 85a65d6307
commit c7ef8cb8d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 164 additions and 536 deletions

View File

@ -16,6 +16,9 @@ This is a copy of the standard Tuya component with a couple of fixes/tweaks that
### Tuya Light Plus
This an enhanced version of the standard [Tuya](https://esphome.io/components/light/tuya.html) light component that adds a bunch of extra features. I use this component with [Feit Dimmers](https://www.amazon.com/gp/product/B07SXDFH38/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&psc=1) but it will likely work with other Tuya dimmers. More details on features and how to use this component are available [here](./components/tuya_light_plus/README.md).
### Tuya Dimmer as Fan
This a modified version of the Tuya fan component I use with [Feit Dimmers](https://www.amazon.com/gp/product/B07SXDFH38/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&psc=1) (but it will likely work with other Tuya dimmers) to control bathroom fans. The major change from the standard Tuya fan component (other than removing options for speed, oscillation, and direction) is adding a function to always change the dimmer back to the maximum "brightness" effectively making this only an on/off device. Details on how to use this component are available [here](./components/tuya_dimmer_as_fan/README.md).
## Misc Devices
### [Basement Bathroom Sensor](./devices/basement_bathroom_sensor.yaml)
@ -82,10 +85,7 @@ All of my dimmers are using my custom [Tuya Light Plus](./components/tuya_light_
* [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
## Dimmer Switches as On/Off Fan 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 as switches.
#### 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.
I tried to find an on/off switch that looked/felt like the Feit dimmers to use for controlling bathroom fans but didn't find anything so I decided to use the Feit dimmers. I don't want the fans "dimmable" so I created a custom [Tuya Dimmer as Fan](./components/tuya_dimmer_as_fan/README.md) component that changes the "brightness" back to the maximum value if changed at the switch.
* [Master Bath Fan](./devices/master_bath_fan.yaml)

View File

@ -0,0 +1,39 @@
# Tuya Light Plus Component
## Overview
This a modified version of the Tuya fan component I use with [Feit Dimmers](https://www.amazon.com/gp/product/B07SXDFH38/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&psc=1) (but it will likely work with other Tuya dimmers) to control bathroom fans. The major change from the standard Tuya fan component (other than removing options for speed, oscillation, and direction) is adding a function to always change the dimmer back to the maximum "brightness" effectively making this only an on/off device.
## Setup
Using the [External Components](https://esphome.io/components/external_components.html) feature in ESPHome you can add this component to your devices directly from my GitHub repo. Note currently this component requires pulling in my custom version of the Tuya component as well to prevent communication issues between the ESP8266 and the Tuya MCU.
```yaml
external_components:
- source: github://nuttytree/esphome
components: [ tuya, tuya_dimmer_as_fan ]
```
Like the standard Tuya fan component you need to have the [UART](https://esphome.io/components/uart.html) and [Tuya](https://esphome.io/components/tuya.html) components.
```yaml
uart:
rx_pin: GPIO3
tx_pin: GPIO1
baud_rate: 9600
tuya:
```
Add and configure the Tuya Dimmer as Fan component
```yaml
fan:
- platform: tuya_dimmer_as_fan
name: my_fan
switch_datapoint: 1
dimmer_datapoint: 2
dimmer_max_value: 1000
```
## Configuration Variables
* id (Optional, ID): Manually specify the ID used for code generation.
* name (Required, string): The name of the light.
* switch_datapoint (Required, int): The datapoint id number of the power switch.
* dimmer_datapoint (Required, int): The datapoint id number of the dimmer value.
* dimmer_max_value (Optional, int, default 255): The highest dimmer value allowed.

View File

@ -0,0 +1,40 @@
from esphome.components import fan
import esphome.config_validation as cv
import esphome.codegen as cg
from esphome.const import CONF_OUTPUT_ID, CONF_SWITCH_DATAPOINT
from esphome.components.tuya import CONF_TUYA_ID, Tuya
DEPENDENCIES = ["tuya"]
CONF_DIMMER_DATAPOINT = "dimmer_datapoint"
CONF_MAX_VALUE = "dimmer_max_value"
tuya_ns = cg.esphome_ns.namespace("tuya")
TuyaFan = tuya_ns.class_("TuyaDimmerAsFan", cg.Component)
CONFIG_SCHEMA = cv.All(
fan.FAN_SCHEMA.extend(
{
cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(TuyaFan),
cv.GenerateID(CONF_TUYA_ID): cv.use_id(Tuya),
cv.Required(CONF_SWITCH_DATAPOINT): cv.uint8_t,
cv.Required(CONF_DIMMER_DATAPOINT): cv.uint8_t,
cv.Optional(CONF_MAX_VALUE): cv.int_,
}
).extend(cv.COMPONENT_SCHEMA),
)
async def to_code(config):
parent = await cg.get_variable(config[CONF_TUYA_ID])
state = await fan.create_fan_state(config)
var = cg.new_Pvariable(
config[CONF_OUTPUT_ID], parent, state
)
await cg.register_component(var, config)
cg.add(var.set_switch_id(config[CONF_SWITCH_DATAPOINT]))
cg.add(var.set_dimmer_id(config[CONF_DIMMER_DATAPOINT]))
if CONF_MAX_VALUE in config:
cg.add(var.set_dimmer_max_value(config[CONF_MAX_VALUE]))

View File

@ -0,0 +1,40 @@
#include "esphome/core/log.h"
#include "esphome/components/fan/fan_helpers.h"
#include "tuya_dimmer_as_fan.h"
namespace esphome {
namespace tuya {
static const char *const TAG = "tuya.fan";
void TuyaDimmerAsFan::setup() {
auto traits = fan::FanTraits(false, false, false, 1);
this->fan_->set_traits(traits);
this->parent_->register_listener(*this->switch_id_, [this](const TuyaDatapoint &datapoint) {
auto call = this->fan_->make_call();
call.set_state(datapoint.value_bool);
call.perform();
});
this->parent_->register_listener(*this->dimmer_id_, [this](const TuyaDatapoint &datapoint) {
if (datapoint.value_int != this->dimmer_max_value_)
{
this->parent_->set_datapoint_value(*this->dimmer_id_, this->dimmer_max_value_);
}
});
this->fan_->add_on_state_callback([this]() { this->parent_->set_datapoint_value(*this->switch_id_, this->fan_->state); });
// Make sure we start at the max value
this->parent_->set_datapoint_value(*this->dimmer_id_, this->dimmer_max_value_);
}
void TuyaDimmerAsFan::dump_config() {
ESP_LOGCONFIG(TAG, "Tuya Dimmer as Fan:");
ESP_LOGCONFIG(TAG, " Switch has datapoint ID %u", *this->switch_id_);
ESP_LOGCONFIG(TAG, " Dimmer has datapoint ID %u", *this->dimmer_id_);
}
} // namespace tuya
} // namespace esphome

View File

@ -0,0 +1,28 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/components/tuya/tuya.h"
#include "esphome/components/fan/fan_state.h"
namespace esphome {
namespace tuya {
class TuyaDimmerAsFan : public Component {
public:
TuyaDimmerAsFan(Tuya *parent, fan::FanState *fan) : parent_(parent), fan_(fan) {}
void setup() override;
void dump_config() override;
void set_switch_id(uint8_t switch_id) { this->switch_id_ = switch_id; }
void set_dimmer_id(uint8_t dimmer_id) { this->dimmer_id_ = dimmer_id; }
void set_dimmer_max_value(uint32_t max_value) { this->dimmer_max_value_ = max_value; }
protected:
Tuya *parent_;
optional<uint8_t> switch_id_{};
optional<uint8_t> dimmer_id_{};
uint32_t dimmer_max_value_ = 255;
fan::FanState *fan_;
};
} // namespace tuya
} // namespace esphome

View File

@ -1,64 +0,0 @@
#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<uint8_t> dimmer_id_{};
optional<uint8_t> 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;

View File

@ -1,392 +0,0 @@
#include "esphome.h"
using namespace esphome;
#define DOUBLE_TAP_TIMEOUT 300
static const char* TAG = "NuttyTuyaLight";
class TuyaLightPlus : public Component, public light::LightOutput, public api::CustomAPIDevice
{
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_min_value(uint32_t min_value) { this->min_value_ = min_value; }
void set_max_value(uint32_t max_value) { this->max_value_ = max_value; }
light::LightTraits get_traits() override;
void setup_state(light::LightState *state) override;
void write_state(light::LightState *state) override;
void loop() override;
void set_day_default_brightness(float brightness) { this->day_default_brightness_ = brightness; }
void set_night_default_brightness(float brightness) { this->night_default_brightness_ = brightness; }
void set_day_auto_off_minutes(uint32_t minutes) { this->day_auto_off_time_ = minutes * 60 * 1000; }
void set_night_auto_off_minutes(uint32_t minutes) { this->night_auto_off_time_ = minutes * 60 * 1000; }
void set_api_server(api::APIServer *api_server) { this->api_server_ = api_server; };
void set_day_night_sensor(const std::string day_night_sensor);
void set_linked_lights(const std::string linked_lights);
void add_double_tap_while_on_callback(const std::function<void()> &func);
void add_double_tap_while_off_callback(const std::function<void()> &func);
void set_double_tap_while_off_stays_on(bool stays_on) { this->double_tap_while_off_stays_on_ = stays_on; }
void add_double_tap_callback(const std::function<void()> &func);
void set_default_brightness(float brightness);
void set_auto_off_minutes(int minutes) { this->current_auto_off_time_ = minutes * 60 * 1000; }
protected:
float tuya_level_to_brightness(uint32_t level) { return static_cast<float>(level) / static_cast<float>(this->max_value_); }
uint32_t brightness_to_tuya_level(float brightness) { return static_cast<uint32_t>(brightness * this->max_value_); }
float brightness_pct() { return static_cast<uint32_t>(this->state_->current_values.get_brightness() * 100); }
void on_day_night_changed(std::string state);
void handle_tuya_datapoint(tuya::TuyaDatapoint datapoint);
void set_tuya_state(bool state);
void set_tuya_level(uint32_t level);
void update_linked_lights();
void set_default_auto_off_time(int time) { this->default_auto_off_time_ = time; this->current_auto_off_time_ = time; }
tuya::Tuya *parent_;
optional<uint8_t> dimmer_id_{};
optional<uint8_t> switch_id_{};
uint32_t min_value_ = 0;
uint32_t max_value_ = 255;
light::LightState *state_{nullptr};
float day_default_brightness_ = 1;
float night_default_brightness_ = .03;
float default_brightness_ = 1;
uint32_t day_auto_off_time_ = 0;
uint32_t night_auto_off_time_ = 0;
uint32_t default_auto_off_time_ = 0;
uint32_t current_auto_off_time_ = 0;
bool has_linked_lights_;
api::APIServer *api_server_;
api::HomeAssistantServiceCallAction<> *linked_lights_turn_on_action_;
api::HomeAssistantServiceCallAction<> *linked_lights_turn_off_action_;
bool has_double_tap_while_on_ = false;
std::vector<std::function<void()>> double_tap_while_on_callbacks_;
bool has_double_tap_while_off_ = false;
std::vector<std::function<void()>> double_tap_while_off_callbacks_;
bool double_tap_while_off_stays_on_ = true;
bool tuya_state_;
unsigned long state_changed_at_ = 0;
unsigned long double_tap_while_on_timeout_ = 0;
bool was_double_tapped_while_on_;
unsigned long double_tap_while_off_timeout_ = 0;
bool was_double_tapped_while_off_;
};
void TuyaLightPlus::setup()
{
this->parent_->register_listener(*this->switch_id_, [this](tuya::TuyaDatapoint datapoint) { this->handle_tuya_datapoint(datapoint); });
this->parent_->register_listener(*this->dimmer_id_, [this](tuya::TuyaDatapoint datapoint) { this->handle_tuya_datapoint(datapoint); });
this->register_service(&TuyaLightPlus::set_auto_off_minutes, "set_auto_off_minutes", {"minutes"});
this->register_service(&TuyaLightPlus::set_default_brightness, "set_default_brightness", {"brightness"});
}
light::LightTraits TuyaLightPlus::get_traits() {
auto traits = light::LightTraits();
traits.set_supports_brightness(this->dimmer_id_.has_value());
return traits;
}
void TuyaLightPlus::setup_state(light::LightState *state)
{
this->state_ = state;
this->tuya_state_ = this->state_->current_values.is_on();
}
void TuyaLightPlus::write_state(light::LightState *state)
{
float brightness;
state->current_values_as_brightness(&brightness);
if (brightness == 0.0f)
{
this->set_tuya_state(false);
}
else if (this->tuya_state_)
{
// The light is already on so just set the brightness
this->set_tuya_level(this->brightness_to_tuya_level(brightness));
}
else
{
// If the light is currently off only turn it on, we will set the brightness in the datapoint handler
this->set_tuya_state(true);
}
}
void TuyaLightPlus::loop()
{
// Double tap while on timed out
if (this->double_tap_while_on_timeout_ != 0 && millis() > this->double_tap_while_on_timeout_)
{
this->double_tap_while_on_timeout_ = 0;
}
// Handle double tap while on callbacks
if (this->was_double_tapped_while_on_)
{
this->was_double_tapped_while_on_ = false;
for (auto &callback : this->double_tap_while_on_callbacks_)
{
callback();
}
}
// Double tap while off timed out, turn the light on
if (this->double_tap_while_off_timeout_ != 0 && millis() > this->double_tap_while_off_timeout_)
{
this->double_tap_while_off_timeout_ = 0;
this->set_tuya_state(true);
}
// Handle double tap while off callbacks
if (this->was_double_tapped_while_off_)
{
this->was_double_tapped_while_off_ = false;
for (auto &callback : this->double_tap_while_off_callbacks_)
{
callback();
}
}
// Handle auto turn off
if (this->current_auto_off_time_ != 0 && this->tuya_state_ && millis() >= this->state_changed_at_ + this->current_auto_off_time_)
{
this->set_tuya_state(false);
}
}
void TuyaLightPlus::set_day_night_sensor(const std::string day_night_sensor)
{
if (day_night_sensor != "")
{
this->subscribe_homeassistant_state(&TuyaLightPlus::on_day_night_changed, day_night_sensor);
}
}
void TuyaLightPlus::set_linked_lights(const std::string linked_lights)
{
if (linked_lights != "")
{
this->has_linked_lights_ = true;
this->linked_lights_turn_on_action_ = new api::HomeAssistantServiceCallAction<>(this->api_server_, false);
this->linked_lights_turn_on_action_->set_service("light.turn_on");
this->linked_lights_turn_on_action_->add_data("entity_id", linked_lights);
this->linked_lights_turn_on_action_->add_variable("brightness_pct", [=]() { return this->brightness_pct(); });
this->linked_lights_turn_on_action_->add_data_template("brightness_pct", "{{ brightness_pct }}");
this->linked_lights_turn_off_action_ = new api::HomeAssistantServiceCallAction<>(this->api_server_, false);
this->linked_lights_turn_off_action_->set_service("light.turn_off");
this->linked_lights_turn_off_action_->add_data("entity_id", linked_lights);
}
}
void TuyaLightPlus::add_double_tap_while_on_callback(const std::function<void()> &func)
{
this->has_double_tap_while_on_ = true;
this->double_tap_while_on_callbacks_.push_back(func);
}
void TuyaLightPlus::add_double_tap_while_off_callback(const std::function<void()> &func)
{
this->has_double_tap_while_off_ = true;
this->double_tap_while_off_callbacks_.push_back(func);
}
void TuyaLightPlus::add_double_tap_callback(const std::function<void()> &func)
{
this->add_double_tap_while_off_callback(func);
this->add_double_tap_while_on_callback(func);
}
void TuyaLightPlus::set_default_brightness(float brightness)
{
this->default_brightness_ = brightness > 1 ? 1 : brightness;
// If the light is off update the brightness in the state and publish so regardless of how the light is turned on the brightness will be the default
if (!this->tuya_state_)
{
this->state_->current_values.set_brightness(this->default_brightness_);
this->state_->remote_values = this->state_->current_values;
this->state_->publish_state();
}
}
void TuyaLightPlus::on_day_night_changed(std::string state)
{
if (state == "Day")
{
this->set_default_brightness(day_default_brightness_);
this->set_default_auto_off_time(day_auto_off_time_);
}
else if (state == "Night")
{
this->set_default_brightness(night_default_brightness_);
this->set_default_auto_off_time(night_auto_off_time_);
}
}
void TuyaLightPlus::handle_tuya_datapoint(tuya::TuyaDatapoint datapoint)
{
ESP_LOGD(TAG, "Received Datapoint:");
if (datapoint.id == *this->switch_id_)
{
ESP_LOGD(TAG, " Type: Switch");
// Light turned on
if (datapoint.value_bool)
{
ESP_LOGD(TAG, " State: On");
// Turned on with the physical button
if (!this->tuya_state_)
{
ESP_LOGD(TAG, "Turned on at device");
if (this->has_double_tap_while_on_)
{
// We are in a double tap while on timeout period so this is a double tap
if (this->double_tap_while_on_timeout_ != 0)
{
// Double tap while on always stays off otherwise it results in weird flashing behavior
this->set_tuya_state(false);
this->double_tap_while_on_timeout_ = 0;
this->was_double_tapped_while_on_ = true;
return;
}
}
if (this->has_double_tap_while_off_)
{
// We are not in a double tap while off timeout period
if (this->double_tap_while_off_timeout_ == 0)
{
// Turn the light back off and wait to see if we get a double tap
this->set_tuya_state(false);
this->double_tap_while_off_timeout_ = millis() + DOUBLE_TAP_TIMEOUT;
return;
}
// We are in a double tap while off timeout period so this is a double tap
else
{
this->double_tap_while_off_timeout_ = 0;
this->was_double_tapped_while_off_ = true;
// If double tap while off triggers an event but does not turn on the light then turn it back off
if (!this->double_tap_while_off_stays_on_)
{
this->set_tuya_state(false);
return;
}
}
}
// We got through all the double tap logic and the light is still on so update the Tuya state
ESP_LOGD(TAG, "Updating Tuya state to on");
this->tuya_state_ = true;
}
else
{
// Set the brightness to the correct level (it currently is at 0)
this->set_tuya_level(this->brightness_to_tuya_level(this->state_->current_values.get_brightness()));
}
}
// Light turned off
else
{
ESP_LOGD(TAG, " State: Off");
// Turned off with physical button
if (this->tuya_state_)
{
ESP_LOGD(TAG, "Turned off at device");
if (has_double_tap_while_on_)
{
// Start the double tap while on timeout
this->double_tap_while_on_timeout_ = millis() + DOUBLE_TAP_TIMEOUT;
}
// Update the Tuya state
ESP_LOGD(TAG, "Updating Tuya state to off");
this->tuya_state_ = false;
}
// Set the Tuya level to 0 to prevent flashes during double taps
ESP_LOGD(TAG, "Updating Tuya level to 0");
this->set_tuya_level(0);
// Set the current brightness to the default so that it will turn on at the default brightness
ESP_LOGD(TAG, "Updating brightness state to default");
this->state_->current_values.set_brightness(this->default_brightness_);
}
// Update the current values state
ESP_LOGD(TAG, "Updating state to new value");
this->state_->current_values.set_state(this->tuya_state_);
}
else if (datapoint.id == *this->dimmer_id_)
{
ESP_LOGD(TAG, " Type: Brightness");
ESP_LOGD(TAG, " Value: %u", datapoint.value_uint);
// Only react to dimmer level changes if the light is on
if(this->tuya_state_)
{
this->state_->current_values.set_brightness(tuya_level_to_brightness(datapoint.value_uint));
}
}
// Update state changed at time
this->state_changed_at_ = millis();
// If the remote values do not reflect the current values update and publish the values
if (this->state_->current_values.get_state() != this->state_->remote_values.get_state()
|| this->state_->current_values.get_brightness() != this->state_->remote_values.get_brightness())
{
ESP_LOGD(TAG, "Publishing new state");
this->state_->remote_values = this->state_->current_values;
this->state_->publish_state();
}
// Update any linked lights
ESP_LOGD(TAG, "Updating linked lights");
this->update_linked_lights();
}
void TuyaLightPlus::set_tuya_state(bool state)
{
this->tuya_state_ = state;
this->parent_->set_datapoint_value(*this->switch_id_, state);
}
void TuyaLightPlus::set_tuya_level(uint32_t level)
{
this->parent_->set_datapoint_value(*this->dimmer_id_, std::max(level, this->min_value_));
}
void TuyaLightPlus::update_linked_lights()
{
if (this->has_linked_lights_)
{
if (this->state_->current_values.is_on())
{
this->linked_lights_turn_on_action_->play();
}
else
{
this->linked_lights_turn_off_action_->play();
}
}
}
TuyaLightPlus *TuyaLight;

View File

@ -3,7 +3,6 @@ substitutions:
board: esp01_1m
external_components:
# - source: github://nuttytree/esphome@more-tuya-reliability-improvements
- source:
type: local
path: ../components

View File

@ -2,34 +2,23 @@ substitutions:
platform: ESP8266
board: esp01_1m
esphome:
includes:
- ../custom/tuya_dimmer_as_binary_fan_output.h
external_components:
- source:
type: local
path: ../components
components: [ tuya, tuya_dimmer_as_fan ]
packages:
base: !include device_base.yaml
logger: !include logger/logger_no_serial.yaml
uart: !include uart/tuya.yaml
fan:
- platform: binary
id: the_fan
output: tuya_fan_output
name: ${device_name}
tuya:
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
fan:
- platform: tuya_dimmer_as_fan
id: tuya_fan
name: ${device_name}
switch_datapoint: 1
dimmer_datapoint: 2
dimmer_max_value: 1000

View File

@ -1,51 +0,0 @@
substitutions:
platform: ESP8266
board: esp01_1m
log_level: verbose
esphome:
includes:
- ../custom/tuya_light_plus.h
on_boot:
priority: -100
then:
- script.execute: startup
external_components:
# - source: github://nuttytree/esphome@more-tuya-reliability-improvements
- source:
type: local
path: ../components
components: [ tuya ]
packages:
base: !include device_base.yaml
logger: !include logger/logger_no_serial.yaml
uart: !include uart/tuya.yaml
tuya:
light:
- platform: custom
lambda: |-
TuyaLight = new TuyaLightPlus();
TuyaLight->set_switch_id(1);
TuyaLight->set_dimmer_id(2);
TuyaLight->set_min_value(0);
TuyaLight->set_max_value(1000);
TuyaLight->set_tuya_parent(tuya_tuya);
TuyaLight->set_day_night_sensor("sensor.day_night");
TuyaLight->set_day_default_brightness(${day_brightness});
TuyaLight->set_night_default_brightness(${night_brightness});
TuyaLight->set_day_auto_off_minutes(${day_auto_off_minutes});
TuyaLight->set_night_auto_off_minutes(${night_auto_off_minutes});
TuyaLight->set_api_server(api_apiserver);
TuyaLight->set_linked_lights("${linked_lights}");
TuyaLight->set_double_tap_while_off_stays_on(${double_tap_while_off_stays_on});
App.register_component(TuyaLight);
return {TuyaLight};
lights:
- id: tuya_light
name: ${device_name}
gamma_correct: 1.0
default_transition_length: 0s