devices.esphome.io
Sonoff M5 Wall Switch 1/2/3-gang
Sonoff M5 Wall Switch 1/2/3-gang
Device Type: switchElectrical Standard: euBoard: esp32Difficulty: Disassembly required, 3/5
Notes
- status LED (blue) in left-most button
- channel LEDs (red) are dimmable (PWM) while relays OFF; 100% bright when ON
- in 1-gang version LED 1 to/can be activated separately from Relay
- in 2-gang version LED 2 to/can be activated separately from Relay
GPIO Pinout
1-Gang Version
| Pin | Function |
|---|---|
| GPIO00 | Button 1 |
| GPIO23 | Relay 1 |
| GPIO19 | LED 1 |
| GPIO05 | Status LED |
| GPIO18 | PWM for LED 1 |
2-Gang Version
| Pin | Function |
|---|---|
| GPIO04 | Button 1 |
| GPIO15 | Button 2 |
| GPIO23 | Relay 1 / LED 1 |
| GPIO19 | Relay 2 |
| GPIO22 | LED 2 |
| GPIO05 | Status LED |
| GPIO18 | PWM for LED 1/2 |
3-Gang Version
| Pin | Function |
|---|---|
| GPIO04 | Button 1 |
| GPIO00 | Button 2 |
| GPIO15 | Button 3 |
| GPIO23 | Relay 1 / LED 1 |
| GPIO19 | Relay 2 / LED 2 |
| GPIO22 | Relay 3 / LED 3 |
| GPIO05 | Status LED |
| GPIO18 | PWM for LED 1/2/3 |
Basic Configuration (2-Gang)
esphome: name: Sonoff M5 2gang
esp32: board: esp32dev framework: type: arduino # OTA flashingota: - platform: esphome
wifi: # Your Wifi network details # Enable fallback hotspot in case wifi connection fails ap:
# Enabling the logging componentlogger:
# Enable Home Assistant APIapi:
# Enable the captive portalcaptive_portal:
sensor:
- platform: uptime name: "Uptime" id: sensor_uptime update_interval: 300s entity_category: "diagnostic"
button: - platform: restart name: "Restart" id: button_restart
switch: - platform: gpio name: "Left" pin: GPIO23 id: relay_1
- platform: gpio name: "Right" pin: GPIO19 id: relay_2 on_turn_on: - output.turn_on: led_2 on_turn_off: - output.turn_off: led_2
output: - platform: gpio id: led_2 pin: number: GPIO22 inverted: False
- platform: ledc id: pwm_output pin: GPIO18 frequency: 1000 Hz
binary_sensor:
- platform: template name: "API connected" id: sensor_api_connected internal: True entity_category: 'diagnostic' device_class: 'connectivity' lambda: return global_api_server->is_connected(); on_press: - light.turn_on: led_status on_release: - light.turn_off: led_status
- platform: gpio name: "Left" pin: number: GPIO04 mode: INPUT_PULLUP inverted: False on_press: - switch.toggle: relay_1
- platform: gpio name: "Right" pin: number: GPIO15 mode: INPUT_PULLUP inverted: False on_press: - switch.toggle: relay_2
light: - platform: status_led name: "LED" id: led_status pin: number: GPIO05 inverted: True internal: True restore_mode: ALWAYS_OFF
- platform: monochromatic output: pwm_output name: "LEDs" restore_mode: RESTORE_DEFAULT_OFF icon: 'mdi:led-outline' entity_category: 'config'Advanced Configuration (3-Gang, US Version)
# ESPHome Firmware# Sonoff Switchman M5 3-Gang US# Copyright (c) 2024 Mario Di Vece# License: [MIT](https://opensource.org/license/mit/)# Decription:# Aims to provide a feature-rich, production-ready firmware for this elegant device# - Provides Diagnostic data plus, status LED indicator when not connected to Home Assistant API# - Relays may be configured individually on the UI to work in decoupled mode.# LEDs are physically connected to the relays, and they can't be individually controlled :(# - Exposes gestures via events:# esphome.on_gesture { button: (A|B|C), gesture: (click|double_click|hold) }# - Off-state (Background Brightness) of the LEDs is configurable via the UI## Example file (sonoff-m5-3g-office-01.yaml)## substitutions:# usemac: "false"# friendly: "Sonoff M5 3G - Office Switch - 01"# uniquename: "sonoff-m5-3g-office-01"## packages:# base_package:# url: https://github.com/mariodivece/esphometemplates/# ref: main# files: [sonoff-m5-3g-us.yaml]# refresh: 0d
# Basic substitutions (can be safely overriden)substitutions: usemac: "true" friendly: "Sonoff Switchman M5 3G US" uniquename: "switch-m5-3g" loglevel: INFO device_name: "M53G" device_make: "Sonoff" sw_version: "2024.2.4" package_url: "github://mariodivece/esphometemplates/sonoff-m5-3g-us.yaml@main"
# Define the board for the compileresp32: board: esp32dev framework: type: arduino
# Setup the integration and define some project variablesesphome: name: "${uniquename}" friendly_name: "${friendly}" comment: "${device_name} by ${device_make}" name_add_mac_suffix: ${usemac} min_version: "2023.2.0" project: name: "${device_make}.${device_name}" version: "${sw_version}"
# Allow importing this packagedashboard_import: package_import_url: ${package_url} import_full_config: false # OTA flashingota: - platform: esphome
wifi: # Your Wifi network details # Enable fallback hotspot in case wifi connection fails ap:
# Enabling the logging componentlogger:
# Enable Home Assistant APIapi:
# Enable the captive portalcaptive_portal:
sensor:
- platform: uptime name: "Uptime" id: sensor_uptime update_interval: 300s entity_category: "diagnostic"
# Provide a pre-built button for restarting the devicebutton: - platform: restart name: "Restart" id: button_restart
switch: # Physical GPIO Relay - platform: gpio name: "Relay A" pin: GPIO23 id: relay_a
# Physical GPIO Relay - platform: gpio name: "Relay B" pin: GPIO19 id: relay_b
# Physical GPIO Relay - platform: gpio name: "Relay C" pin: GPIO22 id: relay_c
# Config-only switch to decouple relay from button - platform: template name: "Decoupling - Relay A" id: relay_a_decoupled optimistic: true restore_mode: RESTORE_DEFAULT_OFF icon: 'mdi:link-box-outline' entity_category: 'config'
# Config-only switch to decouple relay from button - platform: template name: "Decoupling - Relay B" id: relay_b_decoupled optimistic: true restore_mode: RESTORE_DEFAULT_OFF icon: 'mdi:link-box-outline' entity_category: 'config'
# Config-only switch to decouple relay from button - platform: template name: "Decoupling - Relay C" id: relay_c_decoupled optimistic: true restore_mode: RESTORE_DEFAULT_OFF icon: 'mdi:link-box-outline' entity_category: 'config'
output: # Physical GPIO PWM for off-state background brightness # This pin controls the background brightness for all LEDs # physically attached to the relays - platform: ledc id: pwm_output pin: GPIO18 frequency: 1000 Hz
binary_sensor: # Diagnostic sensor for connection - platform: status name: "Status" id: sensor_status
# Make the status LED blink when not connected/trying to connect - platform: template name: "API connected" id: sensor_api_connected internal: true entity_category: 'diagnostic' device_class: 'connectivity' lambda: return global_api_server->is_connected(); on_press: - light.turn_off: led_status on_release: - light.turn_on: led_status
# Physical Button A - platform: gpio name: "Button A" id: button_a pin: number: GPIO04 mode: INPUT_PULLUP inverted: true
filters: - delayed_on: 10ms
on_press: - if: condition: switch.is_off: relay_a_decoupled then: - switch.toggle: relay_a
on_multi_click: # single click detection - timing: - ON for at most 900ms - OFF for at least 600ms then: - homeassistant.event: event: esphome.on_gesture data: button: "A" gesture: "single_click"
# double click detection - timing: - ON for at most 500ms - OFF for at most 400ms - ON for at most 500ms - OFF for at least 250ms then: - homeassistant.event: event: esphome.on_gesture data: button: "A" gesture: "double_click"
# hold detection - timing: - ON for at least 1s then: - while: condition: binary_sensor.is_on: button_a then: - light.toggle: led_status - homeassistant.event: event: esphome.on_gesture data: button: "A" gesture: "button_hold" - delay: 100ms - light.turn_off: led_status
- platform: gpio name: "Button B" id: button_b pin: number: GPIO00 mode: INPUT_PULLUP inverted: true
filters: - delayed_on: 10ms
on_press: - if: condition: switch.is_off: relay_b_decoupled then: - switch.toggle: relay_b
on_multi_click: # single click detection - timing: - ON for at most 900ms - OFF for at least 600ms then: - homeassistant.event: event: esphome.on_gesture data: button: "B" gesture: "single_click"
# double click detection - timing: - ON for at most 500ms - OFF for at most 400ms - ON for at most 500ms - OFF for at least 250ms then: - homeassistant.event: event: esphome.on_gesture data: button: "B" gesture: "double_click"
# hold detection - timing: - ON for at least 1s then: - while: condition: binary_sensor.is_on: button_b then: - light.toggle: led_status - homeassistant.event: event: esphome.on_gesture data: button: "B" gesture: "button_hold" - delay: 100ms - light.turn_off: led_status
- platform: gpio name: "Button C" id: button_c pin: number: GPIO15 mode: INPUT_PULLUP inverted: true
filters: - delayed_on: 10ms
on_press: - if: condition: switch.is_off: relay_c_decoupled then: - switch.toggle: relay_c
on_multi_click: # single click detection - timing: - ON for at most 900ms - OFF for at least 600ms then: - homeassistant.event: event: esphome.on_gesture data: button: "C" gesture: "single_click"
# double click detection - timing: - ON for at most 500ms - OFF for at most 400ms - ON for at most 500ms - OFF for at least 250ms then: - homeassistant.event: event: esphome.on_gesture data: button: "C" gesture: "double_click"
# hold detection - timing: - ON for at least 1s then: - while: condition: binary_sensor.is_on: button_c then: - light.toggle: led_status - homeassistant.event: event: esphome.on_gesture data: button: "C" gesture: "button_hold" - delay: 100ms - light.turn_off: led_status
light: # Physical pin to the connection status LED # We don't expose this to the HA UI (internal) - platform: status_led name: "LED" id: led_status pin: number: GPIO05 inverted: true internal: true restore_mode: RESTORE_DEFAULT_ON
# HA UI connection to the background brightness (PWM) pin - platform: monochromatic output: pwm_output name: "Background Brightness" restore_mode: RESTORE_DEFAULT_OFF icon: 'mdi:led-outline' entity_category: 'config'