Sonoff SwitchMan M5 3C 3 Gang switch with ESPHome

Thanks, your solution save my day!

Good evening Simon,

Thanks to you as well as some guys over on github working the Tasmota side of things, I’ve put together a solution that solves your issues with the LED working only when actually pressing the button.

Thread is here: Sonoff SwitchMan M5 Ledlink_i · Discussion #15757 · arendst/Tasmota · GitHub

Bottom comment you may have to click “show more”. The 1 gang is there but 2 gang should be easy to put together. Let me know if you need it directly and I will post here.

Thanks for the pin number (22).
In my opinion more elegant way to sync led with relay is to use power_supply (see buttom) in output (last line):

binary_sensor:

  - platform: gpio
    pin:
      number: GPIO4
      mode: INPUT_PULLUP
    id: ${hostname}_switch_1
    on_press:
      then:
        - light.toggle:
            id: ${hostname}_light_1

  - platform: gpio
    pin:
      number: GPIO15
      mode: INPUT_PULLUP
    id: ${hostname}_switch_2
    on_press:
      then:
        - light.toggle:
            id: ${hostname}_light_2

output:

  - platform: gpio
    pin: GPIO23
    id: ${hostname}_relay_1

  - platform: gpio
    pin: GPIO19
    id: ${hostname}_relay_2
    power_supply: ${hostname}_led_2

light:

  - platform: binary
    name: "${name_1}"
    id: ${hostname}_light_1
    output: ${hostname}_relay_1

  - platform: binary
    name: "${name_2}"
    id: ${hostname}_light_2
    output: ${hostname}_relay_2

power_supply:

  - id: ${hostname}_led_2
    enable_time: 0s
    keep_on_time: 0s
    pin:
      number: GPIO22
      inverted: False
1 Like

Thanks for sharing this, it worked for me.

Any idea how to implement with 1 button? I do not get the LED when turning on the light.

Hi, I would like to use my Sonoff Switchman M5 as a smart switch for the yeelight lamp and not as a power cutter. Installed esphome, configuration as below, I searched the entire forum and google, however, I did not find any relevant clues on this topic.

esphome:
  name: switchman-entrance

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: ""

ota:
  password: ""

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Switchman-Entrance"
    password: ""

captive_portal:
    
output:
  - platform: ledc
    pin: 18
    frequency: 1000 Hz
    id: pwm_output
    
  - platform: gpio
    id: relay_1
    pin: 23
    
  - platform: gpio
    id: relay_2
    pin: 19
    
light:
  - platform: monochromatic
    output: pwm_output
    name: "LEDs"
  - platform: status_led
    name: "Swtich state"
    pin:
      number: 5
      inverted: true
    
  - platform: binary
    id: corridor_switch_1
    name: "Left Switch"
    output: relay_1
    
  - platform: binary
    id: corridor_switch_2
    name: "Right Switch"
    output: relay_2

    
binary_sensor:
  - platform: gpio
    id: left_button
    pin:
      number: 4
      mode: INPUT_PULLUP
    on_press:
      - light.toggle: corridor_switch_1
      
  - platform: gpio
    id: right_button
    pin:
      number: 15
      mode: INPUT_PULLUP
    on_press:
      - light.toggle: corridor_switch_2
      

what am i doing wrong, triggering gpio 22 changes RIGHT led for me, not the left one

  • #18 - controls both leds
  • #relay 1 [23] - linked to left LED!
  • #18 off, 22 on = right only (when relay1 is off)
  • #22 controls right one
  • #18 controls both, but relay 1 on = only left on

No way to have ONLY left led on without latching the relay

I thought I would share my config for my 3C switches. Feel free to use it or parts of it if you want (I spent way too much time coming up with this, so other people using it only feels right)

Features and comments:

  • PWM on both the red leds (when the relay is off) and the blue LED. This meant i opted not to have the blue led as a status led (you can opt the other way around with minimal changes, though)
  • Events for single click, double click and long press
  • Upon double click, the blue led flashes once to give some immediate feedback. Upon a long press, it flashes twice.
  • To make sure that the single click wouldn’t also trigger for a double click, I built in a delay before triggering the single click. I went with 200ms after trying some values, as it was both something I would even trust guests with, and while it was noticeable when paying attention, it wasn’t bothersome to me in normal usage. You could make the delay shorter, but I wouldn’t recommend going below 100ms
substitutions:
  deviceName: switch-1
  encryptionKey: "********"
  accessPointPassword: "*********"
  otaPassword: "******"

esphome:
  name: "${deviceName}"

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "${encryptionKey}"

ota:
  password: "${accessPointPassword}"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "${deviceName} AP"
    password: "${accessPointPassword}"

captive_portal:

script:
  - id: blink_blue
    then:
      - light.toggle: 
          id: blue_led
          transition_length: 0s
      - delay: 200ms
      - light.toggle: 
          id: blue_led
          transition_length: 0s
  - id: blink_blue_twice
    then:
      - light.toggle: 
          id: blue_led
          transition_length: 0s
      - delay: 200ms
      - light.toggle: 
          id: blue_led
          transition_length: 0s
      - delay: 200ms
      - light.toggle: 
          id: blue_led
          transition_length: 0s
      - delay: 200ms
      - light.toggle: 
          id: blue_led
          transition_length: 0s

switch:
    - platform: gpio
      id: relay_1
      name: "Left Light"
      pin: 23
    - platform: gpio
      id: relay_2
      name: "Middle Light"
      pin: 19
    - platform: gpio
      id: relay_3
      name: "Right Light"
      pin: 22

output:
    - platform: ledc
      pin: 18
      frequency: 1000 Hz
      id: pwm_output
    - platform: ledc
      pin:
        number: 5
        inverted: true
      frequency: 1000 Hz
      id: pwm_blue

light:
    - platform: monochromatic
      output: pwm_output
      name: "Red LEDs (when lights are off)"
    - platform: monochromatic
      name: "Blue LED"
      output: pwm_blue
      id: blue_led

binary_sensor:
    - id: left_button
      platform: gpio
      pin:
        number: 4
        mode: INPUT_PULLUP
        inverted: true
      on_multi_click:
        - timing:
            - ON for 50ms to 350ms
            - OFF for at least 201ms
          then:
            - homeassistant.event:
                event: esphome.switch_click
                data:
                  device: "${deviceName}"
                  button: left
            - switch.toggle: relay_1
        - timing:
            - ON for 50ms to 350ms
            - OFF for 5ms to 200ms
            - ON for 50ms to 350ms
            - OFF for at least 1ms
          then:
            - homeassistant.event:
                event: esphome.switch_double_click
                data:
                  device: "${deviceName}"
                  button: left
            - script.execute: blink_blue
        - timing:
            - ON for at least 500ms
          then:
            - homeassistant.event:
                event: esphome.switch_long_press
                data:
                  device: "${deviceName}"
                  button: left
            - script.execute: blink_blue_twice
          
    - id: middle_button
      platform: gpio
      pin:
        number: 0
        mode: INPUT_PULLUP
        inverted: true
      on_multi_click:
        - timing:
            - ON for 50ms to 350ms
            - OFF for at least 201ms
          then:
            - homeassistant.event:
                event: esphome.switch_click
                data:
                  device: "${deviceName}"
                  button: middle
            - switch.toggle: relay_2
        - timing:
            - ON for 50ms to 350ms
            - OFF for 5ms to 200ms
            - ON for 50ms to 350ms
            - OFF for at least 1ms
          then:
            - homeassistant.event:
                event: esphome.switch_double_click
                data:
                  device: "${deviceName}"
                  button: middle
            - script.execute: blink_blue
        - timing:
            - ON for at least 500ms
          then:
            - homeassistant.event:
                event: esphome.switch_long_press
                data:
                  device: "${deviceName}"
                  button: middle
            - script.execute: blink_blue_twice
    - id: right_button
      platform: gpio
      pin:
        number: 15
        mode: INPUT_PULLUP
        inverted: true
      on_multi_click:
        - timing:
            - ON for 50ms to 350ms
            - OFF for at least 201ms
          then:
            - homeassistant.event:
                event: esphome.switch_click
                data:
                  device: "${deviceName}"
                  button: right
            - switch.toggle: relay_3
        - timing:
            - ON for 50ms to 350ms
            - OFF for 5ms to 200ms
            - ON for 50ms to 350ms
            - OFF for at least 1ms
          then:
            - homeassistant.event:
                event: esphome.switch_double_click
                data:
                  device: "${deviceName}"
                  button: right
            - script.execute: blink_blue
        - timing:
            - ON for at least 500ms
          then:
            - homeassistant.event:
                event: esphome.switch_long_press
                data:
                  device: "${deviceName}"
                  button: right
            - script.execute: blink_blue_twice
5 Likes

The LH Red LED is connected directly to the relay switch, so it should act correctly. For some reason the RH Red LED is activated separately ( pin 22)

This is my config and it works as it should.

switch:
  - platform: gpio
    id: relay_1
    name: "light 1"
    pin: 23
  - platform: gpio
    id: relay_2
    pin: 19
    name: "light 2"  
  - platform: gpio
    id: relay_3
    pin: 22
    name: "$RH Red Light"
    
output:
  - platform: ledc
    pin: 18
    frequency: 1000 Hz
    id: pwm_output
 
light:
  - platform: monochromatic
    output: pwm_output
    name: "LEDs"
  - platform: status_led
    name: "Swtich state"
    pin:
      number: 0
      inverted: true

binary_sensor:
  - platform: gpio
    id: left_button
    pin:
      number: 4
      mode: INPUT_PULLUP
    on_press:
      - switch.toggle: relay_1
  - platform: gpio
    id: right_button
    pin:
      number: 15
      mode: INPUT_PULLUP
    on_press:
      - switch.toggle: relay_2
      - switch.toggle: relay_3

Thanks for this, i’m using it for my switch with some basic modifications.

I have a bit of trouble figuring out the best way to implement double click and long press into Home Assistant.
I’d like to have LB double click, LB long press, RB double click, RB long press buttons exposed to HA so i can use the buttons to toggle other lights or automations in my house.

The configuration I provided does all that. It sends events in all these cases. You just need to set up your automations to listen for the right events. The events are esphome.switch_click, esphome.switch_double_click and esphome.switch_long_press. The data of the event will include which switch it is from and which button was used.

So, for example, you could listen to the esphome.switch_long_press event with data of:

device: switch-1
button: left

And your automation will only happen when the left button of switch-1 is long pressed.

1 Like

Based on Jasper123 great script the events of the long_press, double etc can be placed in a automation. For me it was not clear how to trap these events but I finally understood his comments.

Here is screenshot of how it listen to these events.

Hope that helps somebody else.

I somehow prefer to code actions directly in ESPHOME setup rather than firing events to HA and then reacting over there, i.e.

- timing: #short
          - ON for at most 1s
          - OFF for at least 0.05s
        then:
          - if:
              condition: 
                api.connected:
              then:
                - homeassistant.service:
                    service: light.toggle
                    data:
                      entity_id: light.table_lamp
              else:
              - http_request.post: "http://192.168.10.77/light/table_lamp/toggle"

btw,the condition is to go directly to Esphome device if HA is unavailable (fallback option, HA way reacts way faster)

5 Likes

That is nice!

Would it be possible to change Jaspers script (which is great) to use the single press to switch on a light through HA. But when HA is unreachable (I.e. server is offline, wifi is down) to fallback to the local relay?

Sure just check two posts before yours for the solution :wink:

I attempted asking for help a few times and deleted my posts, each time I thought I had it figured, I later got stuck. I’ll like to implement this condition into Jasper’s config because I’m getting an error when I do. I’d like to have a fall back to toggle my zigbee hue light of HA goes down. Thanks.

Thank you for sharing this. I agree it is simpler and works well.

I got XNDZ’s script implemented into Jaspers’s and works great, the only downside is that the red led’s are connected to the relays. The double and long press dims and brightens my hue light, awesome. Thanks guys!

I’ll like to know how to power on the relay by default. When there’s an outage (which we experience here often) the M5 would start up being off at default. I’ll rather put this into ESPhome rather than HA automations. Someone please help me with this, thanks.

Set the restore for relay to always on, like this

switch:
  - platform: gpio
    id: relay_1
    name: "light 1"
    pin: 23
    restore_mode: ALWAYS_ON
1 Like