For completeness and in case someone comes along trying to piece this all together (like I would have been doing several weeks ago), here is all of my ESPHome YAML CODE to go along with Aaron’s hardware modification. No ownership here - I just cobbled together stuff from others’ work and am putting it all in one place as part of this FEIT Dimmer thread.
First I have a subfolder in ESPHOME directory called COMMON. In COMMON I have 3 files. My “base code” file which holds the majority of the common elements for the FEIT / 8266 lights. This allows for each switch to be customized if needed but uses the same base code so no need to copy\ paste all the code over and over if I make a change to the base setup. (Using a similar setup for all of my KMC wifi switchable outlets.)
#FILENAME: config/esphome/common/base.feit.intertek.5014010.yaml
esphome:
name: $node_name
platform: ESP8266
board: esp01_1m
# Allow "dimmer and toggle" states to be stored in the flash storage to
#survive a power cycle. CAUTION - there are real risks of wearing out flash
#storage prematurely with this option. See ESPHome documentation
esp8266_restore_from_flash: true
# Allow a fallback access point to be created. See wifi-iot.yaml for actual
#ap setup.
captive_portal:
# Enable logging
logger:
# Do not send logging info on the UART channel - interferes with MCU operation
baud_rate: 0
#Has been reported that anything but NONE causes flickering and strange
#operation. ERROR has not caused any issues.
level: ERROR
# Enable Home Assistant API - no password required
api:
# Enable OTA Updates - no password required
ota:
# MQTT seemed to be causing periodic re-boots. Disabled for now.
#Come back to this for possible testing later.
#mqtt:
# broker: 192.168.50.25
# username: mqttuser
# password: xxxxxxxxxxx
# Enable the 8266 to talk to the MCU chip via UART
uart:
rx_pin: GPIO3
tx_pin: GPIO1
baud_rate: 9600
# Register the Tuya MCU connection
tuya:
# Make the light
#Minimum set to 10 arbitrarily at this point. 0 also seems to work.
light:
- platform: "tuya"
name: "$device_verbose_name Dimmer"
dimmer_datapoint: 2
switch_datapoint: 1
min_value: 10
max_value: 1000
restore_mode: ALWAYS_OFF
# Create a sensor in HA that shows wifi DB and run-time counter. Mostly for
#troubleshooting installation issues and reboot issues. Probably remove once
#setup is stable. "Geek" info after that. The bigger the negative number - the
#worse the signal performance. (-55 better than -85)
sensor:
- platform: wifi_signal
name: "$device_verbose_name Signal Sensor"
- platform: uptime
name: "$device_verbose_name Uptime"
Then I have my Wifi common setup which I am using in all of my devices. Again if I reconfigure my IOT network or change password - just one change and recompile/update all sensors.
#FILENAME: config/esphome/common/wifi-iot.yaml
wifi:
ssid: "XXXXXXX-IOT"
password: !secret iot_wifi_password
power_save_mode: none
# Enable fallback hotspot (captive portal) in case wifi connection fails
#Ensure that "node_name" + " Fallback Hotspot" does not exceed 32 characters
#Requires captive_portal be set in common device YAML
ap:
ssid: "$node_name Fallback Hotspot"
password: !secret iot_fallback_password
And finally my secrets.yaml for the wifi (evidently ESPHOME uses its own secrets file and it has to be in the same directory as the base file - or at least that was made it work for me. I’m just referring to my primary secrets file in the main HA directory.)
#FILENAME: config/esphome/common/secrets.yaml
#ESPHome Common Secrets pulled from Home Assistant Secrets
<<: !include ../../secrets.yaml
(Side note - the HA File Editor throws a red explanation point warning flag with the space between the colon and the ! but if you remove the space to satisfy the editor, then the overall YAML fails validation. It works for me with the space in there and I just ignore the editor warning.)
I have a separate YAML for each numbered switch where the file name is the nodename (file name actually has nothing to do with the ESPHome process after the file is created - I just do it that way to keep them all separate and easy to find/edit.)
|n the individual device files I put my overrides. So in the case of Aaron’s LED mod, I put the PWM code just in the switch file instead of the base file - since most of my switches do NOT have this modification.
#FILENAME: config/esphome/feit-108.yaml
substitutions:
node_name: feit-108
device_verbose_name: "Feit-108 Switch"
packages:
wifi: !include common/wifi-iot.yaml
device_base: !include common/base.feit.intertek.5014010.yaml
#Enable status reporting via LED. Ties to the hardware modified LED connected to GPIO4
#Same LED that is modified below for PWM dimming. Backlight LED for main switchplate.
status_led:
pin:
number: GPIO4
# Inverted: True if you want the "normal" state to be LED-Off and only illuminate on
# Error or Warning. See documentation for "status_led" in ESPHome
inverted: True
# Create PWM LED hijacked from switch backlight illumination (hardware mod)
light:
- platform: monochromatic
output: pwm_output
#Note - this will expose the led as a toggle and dimmer to HA as a new device. If you want to
#permanently dim the LED but not have a new device in HA, there is a ESPHome attribute
#called "internal" that will hide the device from external. Alternatively you can put name: in config
# but leave blank. See Switch Component in documentation.
name: "$node_name Bullseye"
#Pull the last value from flash on boot and set dim level of this LED.
restore_mode: RESTORE_DEFAULT_ON
# Added gamma_correct based on some other comments on the forum regarding non-color output.
#This seems to make the min and max power settings in the output section to work correctly and be
#be honored by the duty cycle slider in HA.
gamma_correct: 1.0
output:
- platform: esp8266_pwm
pin: GPIO4
id: pwm_output
inverted: True
frequency: 1000 Hz
min_power: 0.08
max_power: 1
Some observations:
-
If you use esp8266_restore_from_flash: true, you should put ALWAYS_ON or ALWAYS_OFF for any device that you don’t want restored to last state (and save the write-to-flash wear that comes with it) which is what I did with the main light switch. It appears that the dim level set on the “mains” is still stored in flash - even with ALWAYS_OFF set. I dimmed the mains, cut the power and on reboot the mains were off - but when I turned them on they went to the dim level I had set before cutting power - NOT to 100%… FWIW. But the same behavior happens on the unmodded lights as well. Dim the mains, cut the power. Turn power back on - light is off but dimness level is retained.
-
As annotated in the code remarks, I added gamma_correct into the light definition of the backlight. This seems to have fixed the Min and Max power not being honored by the duty cycle slider. The slider tells the software PWM what percentage duty cycle to run. Gamma_correct seems to be necessary for non-color LED use like a monochromatic LED or using software PWM to drive another device like a fan.
-
Software PWM - I’m in over my head on this at the moment. I think the maximum frequency of software PWM on the 8266 is 1000hz. So I think that is what should be specified in the frequency parameter (which is also the default value.) This is a 10 bit value (0-1023) and the input is a duty cycle (0-100%). The ESPHome function takes care of the math and all you do is move the slider.
-
The software PWM and the status_led slow cycle pulsing seem to fight each other at times. Behavior seems to depend on the duty cycle selected for the backlight. On boot, there is a bit of a light show of different pulse and strobing. There may be more meaningful info encoded in all that strobing - but for me the big “telltale” is that it is blinking which means it is not yet in a “ready” state. Once it is connected and ready - it either goes steady & set dim level - or it goes out completely if you have the backlight turned off.
-
The blinking during a firmware update is also hit-miss and seems to be related to the dim level selected. That was just an incidental action - so I would not rely on that to tell you something is happening or not.
-
There are times where a full power cycle AFTER a flash seems to be required to get all of the PWM stuff working correctly. I have been power cycling all of my FEIT dimmers after a flash as a matter of course because there seemed to be post-flash anomolies like the mains on/off not working via software otherwise.
-
The full brightness (100% duty cycle) seems to be just slightly less than the factory setup. I haven’t used a meter to see what voltage is being delivered and I don’t own an O-scope to look at the waveform at 100%. I can really only notice the brightness difference if I hold two switches side by side. Not a show-stopper for me since “full bright” on the OEM setup is VERY bright to me.
-
SAFETY CAUTION - the DC side of this switch is floating. Logic ground is not tied to earth ground or AC Common. I discovered this the hard way with AC attached to an open switch on the bench. Goes without saying - but assume anything could shock you if you have mains connected. In fact - Earth Ground is not tied to ANYTHING on the switch except the mounting tabs which is the purpose of earth ground on an AC switch I guess. Otherwise you would be “bonding” ground to common at two places. Just hadn’t personally thought this all the way through until I got zapped.
DISCLAIMER - I am a HA / Hardware hacking newbie. I’m sure some old hands will come along and point out a bunch of things I am doing wrong. But at this point, this combo of ESPHome and hardware hack is working for me and doing what it was intended to do (ESPhome on a FEIT Wifi Dimmer with a dimmable backlight all controlled from HA)