Shelly 2 dimmer

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
5 Likes