Hi, i’ve made a configuration for the Shelly Dimmer 2 that i would like to share with the community. I worked on top of previous solutions and improved upon it. On the internet, some solutions have been shared that contain a bug in the overheating protection feature. This is fixed in the solution below. For details about the bug, please follow this link: https://github.com/esphome/issues/issues/3487#issuecomment-1537475866
The solution below contains several features:
- several settings are explicitly mentioned to help you setup the light: gamma_correct, min_brightness, max_brightness, leading_edge, restore_mode
- light remembers brightness value when changing from off to on
- brightness cannot be changed when the light is off and the brightness cannot go below 0 or above 1000. Because of this, the “brigthness remembering” actually works in practice. And also because of this, the light won’t shut off when dimming down.
- both physical buttons can be used to turn on/off the light. Long press initiates the dimming (one button for dimming up, the other button for dimming down). Long-press-release stops the dimming. The settings in the script are tuned for a full dimming in 5 seconds. You can change this to your liking. All processing is done locally on the dimmer itself.
- Additional robustness is introduced: the dimming will stop automaticlly after 5 seconds, even if the stop-signal is missed (e.g. due to an issue with your physical switch or due to misconfiguration in Home Assistant). You change the duration to your liking.
- 3 virtual buttons (dim up, dim down, dim stop) are introduced to Home Assistant, so you can perform super smooth dimming from the Home Assistant front-end, automations and scripts. All with minimum network traffic and all of the logic performed locally on the dimmer. I’m personally using these virtual buttons in combination with a momentary switch in the other side of the room (press-holding and press-releasing that momentary switch will initiate and stop the dimming procedure via a Home Assistant automation).
- the logger is used in a logical way, so you can utilize it when researching and finetuning.
esphome:
name: choose_your_light_name
friendly_name: ${device_name}
comment: Shelly Dimmer 2
substitutions:
device_name: "Name of the Light"
light_name: "Light"
max_temp: "70" # °C
esp8266:
board: esp01_1m
# Enable logging
logger:
baud_rate: 0
# Enable Home Assistant API
api:
encryption:
key: "your encryption key"
ota:
password: "your ota key"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "ssid name"
password: "password"
captive_portal:
uart:
tx_pin: 1
rx_pin: 3
baud_rate: 115200
light:
- platform: shelly_dimmer
name: ${light_name}
id: dimmer
leading_edge: false #choose between leading edge and trailing edge (use trailing edge for led dimming)
min_brightness: 470
max_brightness: 1000
restore_mode: ALWAYS_OFF
default_transition_length: 1s
gamma_correct: 0 #change this to your liking. Default value is 2.8, but 0 prevents some brightness pops for me
firmware:
version: "51.6"
update: true
sensor: #Important: don't change this sensor-part unless you know what you are doing. These sensors will shut the light down when overheating temperature is reached.
# NTC Temperature
- platform: ntc
sensor: temp_resistance_reading
name: Temperature
id: temperature
unit_of_measurement: "°C"
accuracy_decimals: 1
icon: "mdi:thermometer"
calibration:
b_constant: 3350
reference_resistance: 10kOhm
reference_temperature: 298.15K
on_value:
then:
- if:
condition:
- sensor.in_range:
id: temperature
above: ${max_temp}
- light.is_on: dimmer
then:
- light.turn_off:
id: dimmer
- logger.log: "Switch turned off because temperature exceeded ${max_temp}°C"
- homeassistant.service:
service: persistent_notification.create
data:
title: Message from ${device_name}
data_template:
message: Switch turned off because temperature exceeded ${max_temp}°C
on_value_range:
- above: ${max_temp}
then:
- logger.log: "Temperature exceeded ${max_temp}°C"
- homeassistant.service:
service: persistent_notification.create
data:
title: Message from ${device_name}
data_template:
message: Temperature exceeded ${max_temp}°C
- platform: resistance
id: temp_resistance_reading
sensor: temp_analog_reading
configuration: DOWNSTREAM
resistor: 32kOhm
- platform: adc
id: temp_analog_reading
pin: A0
switch:
- platform: restart
name: Reboot
script:
- id: script_dim_down_timer
mode: restart # script will be kept running for 5 seconds sinces the latest time the script is executed
then:
- logger.log: "Dim-down timer script started"
- delay: 5s
- logger.log: "Dim-down timer script finished"
- id: script_dim_up_timer
mode: restart # script will be kept running for 5 seconds sinces the latest time the script is executed
then:
- logger.log: "Dim-up timer script started"
- delay: 5s
- logger.log: "Dim-up timer script finished"
- id: script_dim_down
mode: single # script will run once
then:
- logger.log: "Dim-down script started"
- while:
condition:
and:
- script.is_running: script_dim_down_timer #makes sure that dimming will stop after the set period
- light.is_on: dimmer #prevents dimming of a light that is off
- lambda: 'return(id(dimmer).remote_values.get_brightness() >= 0.01);' #prevents the light from going off and prevents the script from running unnecessary long (it stops at 1% brightness)
then:
- light.dim_relative:
id: dimmer
relative_brightness: -0.5%
transition_length: 0.01s
- delay: 0.01s
- logger.log: "Dim-down script finished"
- id: script_dim_up
mode: single # script will run once
then:
- logger.log: "Dim-up script started"
- while:
condition:
and:
- script.is_running: script_dim_up_timer #makes sure that dimming will stop after the set period
- light.is_on: dimmer #prevents dimming of a light that is off
- lambda: 'return(id(dimmer).remote_values.get_brightness() <= 0.999);' #prevents the script from running unnecessary long (it stops at 100% brightness)
then:
- light.dim_relative:
id: dimmer
relative_brightness: 0.5%
transition_length: 0.01s
- delay: 0.01s
- logger.log: "Dim-up script finished"
- id: script_turn_on_off
mode: single
then:
- logger.log: "Turn_on_off script started"
- if:
condition:
light.is_on:
id: dimmer
then:
- light.turn_off:
id: dimmer
- logger.log: "Light turned off"
else:
- light.turn_on:
id: dimmer
brightness: !lambda |-
return id(dimmer).remote_values.get_brightness();
- logger.log: "Light turned on with previous brightness setting"
binary_sensor:
- platform: gpio
name: Dim Down
id: sensor_dim_down
pin:
number: GPIO12
mode: INPUT
internal: false
on_multi_click:
- timing:
- ON for at most 300ms
then:
- logger.log: "Physical short press (dim_down) trigger"
- script.execute: script_turn_on_off
- timing:
- ON for at least 300ms
then:
- logger.log: "Physical long press (dim_down) trigger"
- script.execute: script_dim_down_timer
- script.execute: script_dim_down
on_release:
then:
- if:
condition:
light.is_on:
id: dimmer
then:
- logger.log: "Physical dim_down release trigger"
- script.stop: script_dim_down_timer
- logger.log: "Script_dim_down_timer stopped"
- platform: gpio
name: Dim Up
id: sensor_dim_up
pin:
number: GPIO14
mode: INPUT
internal: false
on_multi_click:
- timing:
- ON for at most 300ms
then:
- logger.log: "Physical short press (dim_up) trigger"
- script.execute: script_turn_on_off
- timing:
- ON for at least 300ms
then:
- logger.log: "Physical long press (dim_up) trigger"
- script.execute: script_dim_up_timer
- script.execute: script_dim_up
on_release:
then:
- if:
condition:
light.is_on:
id: dimmer
then:
- logger.log: "Physical dim_up release trigger"
- script.stop: script_dim_up_timer
- logger.log: "Script_dim_up_timer stopped"
button:
- platform: template
name: Dim Down
on_press:
then:
- script.execute: script_dim_down_timer
- script.execute: script_dim_down
- platform: template
name: Dim Up
on_press:
then:
- script.execute: script_dim_up_timer
- script.execute: script_dim_up
- platform: template
name: Dim Stop
on_press:
then:
- logger.log: "Stopping timer script"
- script.stop: script_dim_down_timer
- script.stop: script_dim_up_timer