Add a bunch of Feit Dimmers

This commit is contained in:
ChNussbaum 2020-05-13 16:36:37 -05:00
parent 14abb72561
commit 3457f49bdc
10 changed files with 250 additions and 69 deletions

View File

@ -40,13 +40,22 @@
> This switch will be installed in place of the switch that controls my [TREO LED Pool Lights](https://www.amazon.com/gp/product/B06XTRLM5M/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1). These lights have the option to select different colors by briefly turning them off and back on again and they do remember the last color when turned on again. The custom light component handles tracking the current color and exposes custom "effects" for each of the colors to [Home Assistant](https://www.home-assistant.io/). I went with the triple switch so that I could use the third button to control my [Patio Lights](#patio-lights) which otherwise do not have a physical switch. Note I have tested the code on a [WEMOS D1 Mini clone](https://www.amazon.com/gp/product/B076F52NQD/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1) but I have not installed this on the switch yet or confirmed the timings actually work with the lights yet.
## Dimmer Switches
> I have been trying to find a dimmer switch I realy like to standardize on through out my home but haven't found it yet. These are the dimmers I have tried so far.
> ### [Feit Dimmer](https://www.costco.com/feit-electric-smart-dimmer%2c-3-pack.product.100518151.html)
> I bought these as a 2 pack from Costco. The price is right, they seem to be a fairly solid device, and I was able to flash them using [Tuya-Convert](https://github.com/ct-Open-Source/tuya-convert). Things I don't like are the fact that you have to click repeatedly to change the brightness (can't hold to change) and all buttons are managed by the Tuya MCU so no ability to do things like double-taps or change the default brightness based on day/night mode.
> After trying several dimmers I finally decided to standardize on on the [Feit Dimmers](https://www.amazon.com/gp/product/B07SXDFH38/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&psc=1). 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
> > * They can be linked via a traveler wire (this works even when flashed with ESPHome and while not mentioned in the documentation you can link more than 2 switches this way)
> Things I don't like about these switches:
> > * Have to click repeatedly to change the brightness (can't hold to change)
> > * All buttons are managed by the Tuya MCU so no ability to do things like double-taps (although I may have a solution for this but haven't had a chance to do a POC)
> I have created a custom component for these that should work with most (if not all) Tuya dimmers which provides the following extra features:
> > * Resets the brightness level back to a default level when turned off so that it always comes on at the same level instead of the level it was at when turned off
> > * The default level is configurable as different levels when my house is in "Day" mode vs "Night" mode (based on a binary sensor in Home Assistant)
> > * Provides a service that I can dynamically change the current default brightness level
> > * Allows you to "link" another light in Home Assistant that will be controlled by this dimmer
> The following devices are Feit Dimmers:
> > * Basement Stair Lights/Basement Stair Lights 2
> > * Computer Light
> > * Family Room Light
> > * Kitchen Table Light
> > * Office Light
> ### [MOES Dimmer](https://www.amazon.com/gp/product/B07PLCMR71/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1)
> I bought one of these off Amazon. The price is good, I like the ability to touch the level you want on the front (and even better you can change the level from the touch sensor before you turn the light on), and I was able to flash it using [Tuya-Convert](https://github.com/ct-Open-Source/tuya-convert). What I don't like is the loose feeling of the switch and the fact that the Tuya MCU is controlling everything so no ability to do things like double-taps or change the default brightness based on day/night mode.
> > * Family Room Light

View File

@ -0,0 +1,15 @@
substitutions:
device_id: basement_stair_lights
device_name: Basement Stair Lights
platform: ESP8266
board: esp01_1m
ip_address: !secret basement_stair_lights_ip
ota_pwd: !secret basement_stair_lights_ota_pwd
api_pwd: !secret basement_stair_lights_api_pwd
ap_wifi_pwd: !secret basement_stair_lights_ap_wifi_pwd
day_brightness: "1"
night_brightness: ".03"
night_auto_off_time: 15min
linked_lights: "light.basement_stair_lights_2"
<<: !include common/device_tuya_dimmer.yaml

View File

@ -0,0 +1,15 @@
substitutions:
device_id: basement_stair_lights_2
device_name: Basement Stair Lights 2
platform: ESP8266
board: esp01_1m
ip_address: !secret basement_stair_lights_2_ip
ota_pwd: !secret basement_stair_lights_2_ota_pwd
api_pwd: !secret basement_stair_lights_2_api_pwd
ap_wifi_pwd: !secret basement_stair_lights_2_ap_wifi_pwd
day_brightness: "1"
night_brightness: ".03"
night_auto_off_time: 15min
linked_lights: "light.basement_stair_lights"
<<: !include common/device_tuya_dimmer.yaml

View File

@ -0,0 +1,50 @@
esphome:
<<: !include esphome.yaml
includes:
- tuya_light_control.h
<<: !include common_tuya_dimmer.yaml
<<: !include logger/logger_none.yaml
interval:
- interval: 1min
then:
if:
condition:
and:
- binary_sensor.is_off: day_night
- for:
time: ${night_auto_off_time}
condition:
light.is_on: tuya_light
then:
- light.turn_off: tuya_light
custom_component:
- lambda: |-
auto control = new TuyaLightControl();
control->set_switch_id(1);
control->set_dimmer_id(2);
control->set_min_value(0);
control->set_max_value(1000);
control->set_tuya_parent(tuya_tuya);
control->set_day_brightness(${day_brightness});
control->set_night_brightness(${night_brightness});
control->set_api_server(api_apiserver);
control->set_linked_lights("${linked_lights}");
return {control};
binary_sensor:
- !include binary_sensor/status.yaml
- !include binary_sensor/day_night.yaml
sensor:
- !include sensor/uptime.yaml
- !include sensor/wifi.yaml
switch:
- !include switch/restart.yaml
text_sensor:
- !include text_sensor/version.yaml
- !include text_sensor/wifi.yaml

15
computer_light.yaml Normal file
View File

@ -0,0 +1,15 @@
substitutions:
device_id: computer_light
device_name: Computer Light
platform: ESP8266
board: esp01_1m
ip_address: !secret computer_light_ip
ota_pwd: !secret computer_light_ota_pwd
api_pwd: !secret computer_light_api_pwd
ap_wifi_pwd: !secret computer_light_ap_wifi_pwd
day_brightness: "1"
night_brightness: ".03"
night_auto_off_time: 15min
linked_lights: ""
<<: !include common/device_tuya_dimmer.yaml

View File

@ -7,23 +7,9 @@ substitutions:
ota_pwd: !secret family_room_light_ota_pwd
api_pwd: !secret family_room_light_api_pwd
ap_wifi_pwd: !secret family_room_light_ap_wifi_pwd
day_brightness: "1"
night_brightness: ".03"
night_auto_off_time: 15min
linked_lights: ""
esphome:
<<: !include common/esphome.yaml
<<: !include common/common_tuya_dimmer.yaml
<<: !include common/logger/logger_none.yaml
binary_sensor:
- !include common/binary_sensor/status.yaml
sensor:
- !include common/sensor/uptime.yaml
- !include common/sensor/wifi.yaml
switch:
- !include common/switch/restart.yaml
text_sensor:
- !include common/text_sensor/version.yaml
- !include common/text_sensor/wifi.yaml
<<: !include common/device_tuya_dimmer.yaml

View File

@ -33,11 +33,13 @@ binary_sensor:
inverted: True
on_multi_click:
- timing:
- ON for at least 5s
- ON for at least 3s
- OFF for at least .1s
then:
- switch.toggle: fire_pit
- timing:
- ON for at most 5s
- ON for at most 3s
- OFF for at least .1s
then:
- switch.turn_off: fire_pit
@ -52,13 +54,13 @@ switch:
name: "Fountain"
icon: mdi:fountain
pin: D1
inverted: false
inverted: true
- platform: gpio
id: fire_pit
name: "Fire Pit"
icon: mdi:fire
pin: D2
inverted: false
inverted: true
text_sensor:
- !include common/text_sensor/version.yaml

View File

@ -7,23 +7,9 @@ substitutions:
ota_pwd: !secret kitchen_table_light_ota_pwd
api_pwd: !secret kitchen_table_light_api_pwd
ap_wifi_pwd: !secret kitchen_table_light_ap_wifi_pwd
day_brightness: "1"
night_brightness: ".03"
night_auto_off_time: 15min
linked_lights: ""
esphome:
<<: !include common/esphome.yaml
<<: !include common/common_tuya_dimmer.yaml
<<: !include common/logger/logger_none.yaml
binary_sensor:
- !include common/binary_sensor/status.yaml
sensor:
- !include common/sensor/uptime.yaml
- !include common/sensor/wifi.yaml
switch:
- !include common/switch/restart.yaml
text_sensor:
- !include common/text_sensor/version.yaml
- !include common/text_sensor/wifi.yaml
<<: !include common/device_tuya_dimmer.yaml

View File

@ -7,23 +7,9 @@ substitutions:
ota_pwd: !secret office_light_ota_pwd
api_pwd: !secret office_light_api_pwd
ap_wifi_pwd: !secret office_light_ap_wifi_pwd
day_brightness: "1"
night_brightness: ".03"
night_auto_off_time: 15min
linked_lights: ""
esphome:
<<: !include common/esphome.yaml
<<: !include common/common_tuya_dimmer.yaml
<<: !include common/logger/logger_none.yaml
binary_sensor:
- !include common/binary_sensor/status.yaml
sensor:
- !include common/sensor/uptime.yaml
- !include common/sensor/wifi.yaml
switch:
- !include common/switch/restart.yaml
text_sensor:
- !include common/text_sensor/version.yaml
- !include common/text_sensor/wifi.yaml
<<: !include common/device_tuya_dimmer.yaml

117
tuya_light_control.h Normal file
View File

@ -0,0 +1,117 @@
#include "esphome.h"
class TuyaLightControl : public Component, public CustomAPIDevice {
public:
void setup() 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_tuya_parent(esphome::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; }
void set_day_brightness(float brightness) { this->day_brightness_ = brightness; }
void set_night_brightness(float brightness) { this->night_brightness_ = brightness; }
void set_api_server(api::APIServer *api_server) { this->api_server_ = api_server; };
void set_linked_lights(const std::string linked_lights);
void set_default_brightness(float brightness);
void on_day_night_changed(std::string state);
protected:
void handle_datapoint(esphome::tuya::TuyaDatapoint datapoint);
void set_brightness();
esphome::tuya::Tuya *parent_;
optional<uint8_t> switch_id_{};
optional<uint8_t> dimmer_id_{};
uint32_t min_value_ = 0;
uint32_t max_value_ = 1000;
float day_brightness_ = 1;
float night_brightness_ = .03;
float default_brightness_ = 1;
api::APIServer *api_server_;
api::HomeAssistantServiceCallAction<> *turn_on_service_;
api::HomeAssistantServiceCallAction<> *turn_off_service_;
bool has_linked_lights_ = false;
bool is_on_;
uint32_t brightness_pct_;
};
void TuyaLightControl::setup() {
this->parent_->register_listener(*this->switch_id_, [this](esphome::tuya::TuyaDatapoint datapoint) {
this->handle_datapoint(datapoint);
});
this->parent_->register_listener(*this->dimmer_id_, [this](esphome::tuya::TuyaDatapoint datapoint) {
this->handle_datapoint(datapoint);
});
register_service(&TuyaLightControl::set_default_brightness, "set_default_brightness", {"brightness"});
subscribe_homeassistant_state(&TuyaLightControl::on_day_night_changed, "sensor.day_night");
}
void TuyaLightControl::set_linked_lights(const std::string linked_lights) {
if (linked_lights != "") {
this->has_linked_lights_ = true;
this->turn_on_service_ = new api::HomeAssistantServiceCallAction<>(this->api_server_, false);
this->turn_on_service_->set_service("light.turn_on");
this->turn_on_service_->add_data("entity_id", linked_lights);
this->turn_on_service_->add_variable("brightness_pct", [=]() { return this->brightness_pct_; });
this->turn_on_service_->add_data_template("brightness_pct", "{{ brightness_pct }}");
this->turn_off_service_ = new api::HomeAssistantServiceCallAction<>(this->api_server_, false);
this->turn_off_service_->set_service("light.turn_off");
this->turn_off_service_->add_data("entity_id", linked_lights);
}
}
void TuyaLightControl::set_default_brightness(float brightness) {
this->default_brightness_ = brightness > 1 ? 1 : brightness;
this->set_brightness();
}
void TuyaLightControl::on_day_night_changed(std::string state) {
if (state == "Day") {
this->default_brightness_ = this->day_brightness_;
}
else if (state == "Night")
{
this->default_brightness_ = this->night_brightness_;
}
this->set_brightness();
}
void TuyaLightControl::handle_datapoint(esphome::tuya::TuyaDatapoint datapoint) {
if (datapoint.id == *this->switch_id_) {
this->is_on_ = datapoint.value_bool;
if (this->has_linked_lights_) {
if (this->is_on_) {
this->turn_on_service_->play();
}
else {
this->turn_off_service_->play();
}
}
this->set_brightness();
}
else if (datapoint.id == *this->dimmer_id_) {
this->brightness_pct_ = static_cast<uint32_t>(datapoint.value_uint * 100 / this->max_value_);
if (this->has_linked_lights_) {
if (this->is_on_) {
this->turn_on_service_->play();
}
}
}
}
void TuyaLightControl::set_brightness() {
if (!this->is_on_) {
auto brightness_int = static_cast<uint32_t>(this->default_brightness_ * this->max_value_);
brightness_int = std::max(brightness_int, this->min_value_);
esphome::tuya::TuyaDatapoint datapoint{};
datapoint.id = *this->dimmer_id_;
datapoint.type = esphome::tuya::TuyaDatapointType::INTEGER;
datapoint.value_uint = brightness_int;
this->parent_->set_datapoint_value(datapoint);
}
}