ESPHome - Sonoff R4 Magic Switch - debounce YAML

Hello,
I had trouble finding the right value for timeout on MagicSwitch external component by ssieb since my Sonoff Basic R4 is connected to 3 physical switches (2x no. 6 and 1x no. 7) so typical situation 3 switches controlling 1 light.

I did not wanted to mess with the wiring much and thanks to this setup the reported pulse value was all over the place ranging from 1 200us to 80 000us… So the lower you go the more probable is registering the switch press but in the 2000 region it starts registering multiple pulses and turns on and off multiple times on one press. Below 1000 it register pulses without pressing the switch.

Wanted to share this code that debounces the multiple “false” triggering since it might be useful to someone. It is cruel and probably not the correct solution but it works…

esphome:
  name: basic-r4
  friendly_name: basic-r4
  platformio_options:
    board_build.mcu: esp32c3
    board_build.variant: esp32c3

esp32:
  variant: ESP32C3
  board: esp32-c3-devkitm-1
  framework:
    type: esp-idf
#this is taken from ESPhome devices website. I did not mess with it..
    sdkconfig_options:
      CONFIG_BT_BLE_50_FEATURES_SUPPORTED: y
      CONFIG_BT_BLE_42_FEATURES_SUPPORTED: y
      CONFIG_ESP_TASK_WDT_TIMEOUT_S: "10"


mdns:

logger:
  level: DEBUG

api:
  encryption:
    key: "le secret key"
ota:
  - platform: esphome
    password: "le secret pass"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
#fast connect not necessary actually I would recommend to disable it for testing 
  fast_connect: True
  ap:
  
# Magic switch mode
external_components:
  - source:
      type: git
      url: https://github.com/ssieb/esphome_components
    components: [ magic_switch ]
    refresh: 1min


magic_switch:
  pin: 5
  timeout: 1000us #feel free to mess with this value for me anything below 1000 can trigger on its own
  on_switch:
    - script.execute: main_light_toggle

esp32_ble_tracker:
  scan_parameters:
    active: true
    interval: 1100ms
    window: 1100ms

bluetooth_proxy:
  active: true

binary_sensor:
  - platform: gpio #to enable physical button on sonoff
    pin:
      number: GPIO9
      mode:
        input: true
        pullup: true
      inverted: true
    id: button_1
    on_press:
      then:
        - light.toggle: main_light

output: 
  - platform: gpio #work around to show the relay as light in HA
    pin: GPIO04
    id: main_relay


light:
  - platform: status_led #my desired LED behaviour
    name: "Status LED"
    id: status_led_onboard
    pin:
      number: GPIO6
      inverted: false
    disabled_by_default: True
    icon: "mdi:led-outline"

  - platform: binary #work around to show the relay as light in HA
    id: main_light
    name: "Light"
    output: main_relay
    restore_mode: ALWAYS_OFF
    on_turn_on:
      - script.execute: blink_status_led
    on_turn_off:
      - script.execute: blink_status_led
  


script:
  - id: main_light_toggle #script that "debounces" the pulses
    mode: single
    then:
      - light.toggle:
          id: main_light
      - delay: 150ms #prolly can be much less but this works good enough.
      
  - id: blink_status_led #my desired LED behaviour
    mode: restart
    then:
      - light.turn_on:
          id: status_led_onboard

      - delay: 500ms
      - light.turn_off: status_led_onboard

I would recommend starting with the default template from Sonoff BASIC R4 v1.0 | devices.esphome.io and figuring out the typical pulse value and implement this in case of troubles I had.

2 Likes

Hi, did you have the same problem on the stock firmware?

Hi, yes, it was pretty regular that the sonoff did not registered a switch push. Now it seems a bit better but I have to observe it under real usage. It actually depends a lot how you push the switch.

Hi,

I have ABB 1066U 3-way rocker switch connected to the Sonoff BASIC R4. It appears to be a rather fast switch, because a timeout of 700us seems about right to catch the presses reliably. Your timeout script really comes into its own. Thanks to your efforts I gave magic switch mode a second chance.

Still, stress-testing somehow throws it off whack. First, it sporadically fails to register presses and then becomes unresponsive for a while. I tried setting the script mode to ‘restart’ but that had no effect.

Any ideas?

Interesting. I would have expected 3-5X that.
Anybody has done research if the component uses interrupts, peripherals or what to detect?

Hi,
the " - id: main_light_toggle" script definitely can’t be restart. It must be single otherwise it will behave as it is not there. Won’t have the “debouncing” effect.

If you can try another switch of the same model and brand it might help. They are not all the same…

I still have some miss-registered triggers especially if you slam the switch real hard and quick but works good enough. Current settings are:

timeout: 970us
delay on script: 150ms

Altho I have observed one weird behaviour and my thinking it it is connected to the external component itself somehow. Sometimes when the sonoff looses connection to the HA (wifi issue) it can turn on the light on its own…