From 9dca482d42371babf679c69ca5f7b818a32e4253 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Koco=C5=84?= Date: Mon, 27 Apr 2026 13:34:09 +0200 Subject: [PATCH] init upload --- sonoff-m5-1g-us.yaml | 149 ++++++++++++++++++++++++++ sonoff-m5-2g-us.yaml | 183 ++++++++++++++++++++++++++++++++ sonoff-m5-3g-us.yaml | 195 +++++++++++++++++++++++++++++++++++ sonoff-m5/backlight.yaml | 22 ++++ sonoff-m5/board.yaml | 6 ++ sonoff-m5/button-a.yaml | 60 +++++++++++ sonoff-m5/button-b.yaml | 60 +++++++++++ sonoff-m5/button-c.yaml | 60 +++++++++++ sonoff-m5/indicator-led.yaml | 15 +++ sonoff-m5/mode-button-a.yaml | 21 ++++ sonoff-m5/mode-button-b.yaml | 21 ++++ sonoff-m5/mode-button-c.yaml | 21 ++++ sonoff-m5/relay-a.yaml | 11 ++ sonoff-m5/relay-b.yaml | 11 ++ sonoff-m5/relay-c.yaml | 11 ++ sonoff-m5/status-led.yaml | 31 ++++++ sonoff-m5/timings.yaml | 26 +++++ standard/diagnostics.yaml | 103 ++++++++++++++++++ standard/internaltemp.yaml | 9 ++ standard/project.yaml | 53 ++++++++++ standard/wifi.yaml | 50 +++++++++ 21 files changed, 1118 insertions(+) create mode 100644 sonoff-m5-1g-us.yaml create mode 100644 sonoff-m5-2g-us.yaml create mode 100644 sonoff-m5-3g-us.yaml create mode 100644 sonoff-m5/backlight.yaml create mode 100644 sonoff-m5/board.yaml create mode 100644 sonoff-m5/button-a.yaml create mode 100644 sonoff-m5/button-b.yaml create mode 100644 sonoff-m5/button-c.yaml create mode 100644 sonoff-m5/indicator-led.yaml create mode 100644 sonoff-m5/mode-button-a.yaml create mode 100644 sonoff-m5/mode-button-b.yaml create mode 100644 sonoff-m5/mode-button-c.yaml create mode 100644 sonoff-m5/relay-a.yaml create mode 100644 sonoff-m5/relay-b.yaml create mode 100644 sonoff-m5/relay-c.yaml create mode 100644 sonoff-m5/status-led.yaml create mode 100644 sonoff-m5/timings.yaml create mode 100644 standard/diagnostics.yaml create mode 100644 standard/internaltemp.yaml create mode 100644 standard/project.yaml create mode 100644 standard/wifi.yaml diff --git a/sonoff-m5-1g-us.yaml b/sonoff-m5-1g-us.yaml new file mode 100644 index 0000000..2148f49 --- /dev/null +++ b/sonoff-m5-1g-us.yaml @@ -0,0 +1,149 @@ +# ESPHome Firmware for +# Sonoff Switchman M5 1-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), gesture: (click|double_click|button_hold) } +# - Off-state (Background Brightness) of the LEDs is configurable via the UI +# +# For the below example, you need to keep the following entries in your secrets.yaml file: +# - wifi_ssid: "" +# - wifi_password: "" +# - ota_password: "" +# - api_key: "<32-byte-base-64-secret>" +# +# Example file (lab-office-wasw-003.yaml) +# +# substitutions: +# device_site: "lab" +# device_location_code: "office" +# device_location_name: "Office" +# device_type_code: "wasw" +# device_type_name: "Wall Switch" +# device_number: "003" +# device_ip: "192.168.1.31" +# +# packages: +# base_package: +# url: https://github.com/mariodivece/esphometemplates/ +# ref: main +# file: sonoff-m5-1g-us.yaml +# refresh: 0d +# + +substitutions: + # User-required substitutions + device_site: "home" + device_location_code: "bedroom01" + device_location_name: "Bedroom 1" + device_type_code: "wasw" + device_type_name: "Wall Switch" + device_number: "044" + device_ip: "0.0.0.0" + + # Project Substitutions (not intended for user substitution) + device_model: "Switchman M5 (1-Gang)" + device_make: "Sonoff" + package_version: "2024.2.13" + package_url: "github://mariodivece/esphometemplates/sonoff-m5-1g-us.yaml@main" + + # Relay Configurations + relay_a_gpio: GPIO23 + + # Button Configurations + button_a_gpio: GPIO00 + + # Indicator LED + led_indicator_gpio: GPIO19 + +# Allow importing this package +dashboard_import: + package_import_url: ${package_url} + import_full_config: false + +# Import packages +packages: + standard_package: + url: https://github.com/mariodivece/esphometemplates/ + ref: main + refresh: 0d + files: + - standard/project.yaml + - standard/diagnostics.yaml + - standard/wifi.yaml + - standard/internaltemp.yaml + sonoffm5_package: + url: https://github.com/mariodivece/esphometemplates/ + ref: main + refresh: 0d + files: + - sonoff-m5/board.yaml + - sonoff-m5/timings.yaml + - sonoff-m5/status-led.yaml + - sonoff-m5/backlight.yaml + - sonoff-m5/indicator-led.yaml + - sonoff-m5/mode-button-a.yaml + - sonoff-m5/relay-a.yaml + - sonoff-m5/button-a.yaml + +switch: + + # Modify behavior of imported Relay A + - id: !extend relay_a + on_turn_on: + - switch.turn_on: led_indicator + on_turn_off: + - switch.turn_off: led_indicator + +binary_sensor: + + # Button A + - id: !extend button_a + pin: + ignore_strapping_warning: true + on_press: + # Latching + - if: + condition: + - lambda: 'return id(mode_a).active_index() == 0;' + then: + - switch.toggle: relay_a + # Momentary + - if: + condition: + - lambda: 'return id(mode_a).active_index() == 1;' + then: + - switch.turn_on: relay_a + # Pulse + - if: + condition: + - lambda: 'return id(mode_a).active_index() == 2;' + then: + - switch.turn_on: relay_a + - delay: ${timing_pulse} + - switch.turn_off: relay_a + # Decoupled + - if: + condition: + - lambda: 'return id(mode_a).active_index() == 3;' + then: + - switch.turn_on: led_indicator + + on_release: + # Momentary + - if: + condition: + - lambda: 'return id(mode_a).active_index() == 1;' + then: + - switch.turn_off: relay_a + # Decoupled + - if: + condition: + - lambda: 'return id(mode_a).active_index() == 3;' + then: + - switch.turn_off: led_indicator diff --git a/sonoff-m5-2g-us.yaml b/sonoff-m5-2g-us.yaml new file mode 100644 index 0000000..7b02e79 --- /dev/null +++ b/sonoff-m5-2g-us.yaml @@ -0,0 +1,183 @@ +# ESPHome Firmware for +# Sonoff Switchman M5 2-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), gesture: (click|double_click|button_hold) } +# - Off-state (Background Brightness) of the LEDs is configurable via the UI +# +# For the below example to work, you need to keep the following entries in your secrets.yaml file: +# - wifi_ssid: "" +# - wifi_password: "" +# - ota_password: "" +# - api_key: "<32-byte-base-64-secret>" +# +# Example file (lab-office-wasw-003.yaml) +# +# substitutions: +# device_site: "lab" +# device_location_code: "office" +# device_location_name: "Office" +# device_type_code: "wasw" +# device_type_name: "Wall Switch" +# device_number: "003" +# device_ip: "192.168.1.31" +# +# packages: +# base_package: +# url: https://github.com/mariodivece/esphometemplates/ +# ref: main +# file: sonoff-m5-2g-us.yaml +# refresh: 0d +# + +substitutions: + # User-required substitutions + device_site: "home" + device_location_code: "bedroom01" + device_location_name: "Bedroom 1" + device_type_code: "wasw" + device_type_name: "Wall Switch" + device_number: "044" + device_ip: "0.0.0.0" + + # Project Substitutions (not intended for user substitution) + device_model: "Switchman M5 (2-Gang)" + device_make: "Sonoff" + package_version: "2024.2.13" + package_url: "github://mariodivece/esphometemplates/sonoff-m5-2g-us.yaml@main" + + # Relay Configurations + relay_a_gpio: GPIO23 + relay_b_gpio: GPIO19 + + # Button Configurations + button_a_gpio: GPIO04 + button_b_gpio: GPIO15 + + # Indicator LED + led_indicator_gpio: GPIO22 + +# Allow importing this package +dashboard_import: + package_import_url: ${package_url} + import_full_config: false + +# Import packages +packages: + standard_package: + url: https://github.com/mariodivece/esphometemplates/ + ref: main + refresh: 0d + files: + - standard/project.yaml + - standard/diagnostics.yaml + - standard/wifi.yaml + - standard/internaltemp.yaml + sonoffm5_package: + url: https://github.com/mariodivece/esphometemplates/ + ref: main + refresh: 0d + files: + - sonoff-m5/board.yaml + - sonoff-m5/timings.yaml + - sonoff-m5/status-led.yaml + - sonoff-m5/backlight.yaml + - sonoff-m5/indicator-led.yaml + - sonoff-m5/mode-button-a.yaml + - sonoff-m5/mode-button-b.yaml + - sonoff-m5/relay-a.yaml + - sonoff-m5/relay-b.yaml + - sonoff-m5/button-a.yaml + - sonoff-m5/button-b.yaml + +switch: + + # Modify behavior of imported Relay B + - id: !extend relay_b + on_turn_on: + - switch.turn_on: led_indicator + on_turn_off: + - switch.turn_off: led_indicator + +binary_sensor: + + # Button A + - id: !extend button_a + on_press: + # Latching + - if: + condition: + - lambda: 'return id(mode_a).active_index() == 0;' + then: + - switch.toggle: relay_a + # Momentary + - if: + condition: + - lambda: 'return id(mode_a).active_index() == 1;' + then: + - switch.turn_on: relay_a + # Pulse + - if: + condition: + - lambda: 'return id(mode_a).active_index() == 2;' + then: + - switch.turn_on: relay_a + - delay: ${timing_pulse} + - switch.turn_off: relay_a + on_release: + # Momentary + - if: + condition: + - lambda: 'return id(mode_a).active_index() == 1;' + then: + - switch.turn_off: relay_a + + # Button B + - id: !extend button_b + on_press: + # Latching + - if: + condition: + - lambda: 'return id(mode_b).active_index() == 0;' + then: + - switch.toggle: relay_b + # Momentary + - if: + condition: + - lambda: 'return id(mode_b).active_index() == 1;' + then: + - switch.turn_on: relay_b + # Pulse + - if: + condition: + - lambda: 'return id(mode_b).active_index() == 2;' + then: + - switch.turn_on: relay_b + - delay: ${timing_pulse} + - switch.turn_off: relay_b + # Decoupled + - if: + condition: + - lambda: 'return id(mode_b).active_index() == 3;' + then: + - switch.turn_on: led_indicator + + on_release: + # Momentary + - if: + condition: + - lambda: 'return id(mode_b).active_index() == 1;' + then: + - switch.turn_off: relay_b + # Decoupled + - if: + condition: + - lambda: 'return id(mode_b).active_index() == 3;' + then: + - switch.turn_off: led_indicator diff --git a/sonoff-m5-3g-us.yaml b/sonoff-m5-3g-us.yaml new file mode 100644 index 0000000..70b1804 --- /dev/null +++ b/sonoff-m5-3g-us.yaml @@ -0,0 +1,195 @@ +# ESPHome Firmware for +# 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|button_hold) } +# - Off-state (Background Brightness) of the LEDs is configurable via the UI +# +# For the below example, you need to keep the following entries in your secrets.yaml file: +# - wifi_ssid: "" +# - wifi_password: "" +# - ota_password: "" +# - api_key: "<32-byte-base-64-secret>" +# +# Example file (lab-office-wasw-003.yaml) +# +# substitutions: +# device_site: "lab" +# device_location_code: "office" +# device_location_name: "Office" +# device_type_code: "wasw" +# device_type_name: "Wall Switch" +# device_number: "003" +# device_ip: "192.168.1.31" +# +# packages: +# base_package: +# url: https://github.com/mariodivece/esphometemplates/ +# ref: main +# file: sonoff-m5-3g-us.yaml +# refresh: 0d +# + +substitutions: + # User-required substitutions + device_site: "home" + device_location_code: "bedroom01" + device_location_name: "Bedroom 1" + device_type_code: "wasw" + device_type_name: "Wall Switch" + device_number: "044" + device_ip: "0.0.0.0" + + # Project Substitutions (not intended for user substitution) + device_model: "Switchman M5 (3-Gang)" + device_make: "Sonoff" + package_version: "2024.2.13" + package_url: "github://mariodivece/esphometemplates/sonoff-m5-3g-us.yaml@main" + + # Relay Configurations + relay_a_gpio: GPIO23 + relay_b_gpio: GPIO19 + relay_c_gpio: GPIO22 + + # Button Configurations + button_a_gpio: GPIO04 + button_b_gpio: GPIO00 + button_c_gpio: GPIO15 + +# Allow importing this package +dashboard_import: + package_import_url: ${package_url} + import_full_config: false + +# Import packages +packages: + standard_package: + url: https://github.com/mariodivece/esphometemplates/ + ref: main + refresh: 0d + files: + - standard/project.yaml + - standard/diagnostics.yaml + - standard/wifi.yaml + - standard/internaltemp.yaml + sonoffm5_package: + url: https://github.com/mariodivece/esphometemplates/ + ref: main + refresh: 0d + files: + - sonoff-m5/board.yaml + - sonoff-m5/timings.yaml + - sonoff-m5/status-led.yaml + - sonoff-m5/backlight.yaml + - sonoff-m5/mode-button-a.yaml + - sonoff-m5/mode-button-b.yaml + - sonoff-m5/mode-button-c.yaml + - sonoff-m5/relay-a.yaml + - sonoff-m5/relay-b.yaml + - sonoff-m5/relay-c.yaml + - sonoff-m5/button-a.yaml + - sonoff-m5/button-b.yaml + - sonoff-m5/button-c.yaml + +binary_sensor: + # Buttn A + - id: !extend button_a + on_press: + # Latching + - if: + condition: + - lambda: 'return id(mode_a).active_index() == 0;' + then: + - switch.toggle: relay_a + # Momentary + - if: + condition: + - lambda: 'return id(mode_a).active_index() == 1;' + then: + - switch.turn_on: relay_a + # Pulse + - if: + condition: + - lambda: 'return id(mode_a).active_index() == 2;' + then: + - switch.turn_on: relay_a + - delay: ${timing_pulse} + - switch.turn_off: relay_a + + on_release: + # Momentary + - if: + condition: + - lambda: 'return id(mode_a).active_index() == 1;' + then: + - switch.turn_off: relay_a + + # Button B + - id: !extend button_b + on_press: + # Latching + - if: + condition: + - lambda: 'return id(mode_b).active_index() == 0;' + then: + - switch.toggle: relay_b + # Momentary + - if: + condition: + - lambda: 'return id(mode_b).active_index() == 1;' + then: + - switch.turn_on: relay_b + # Pulse + - if: + condition: + - lambda: 'return id(mode_b).active_index() == 2;' + then: + - switch.turn_on: relay_b + - delay: ${timing_pulse} + - switch.turn_off: relay_b + + on_release: + # Momentary + - if: + condition: + - lambda: 'return id(mode_b).active_index() == 1;' + then: + - switch.turn_off: relay_b + + # Button C + - id: !extend button_c + on_press: + # Latching + - if: + condition: + - lambda: 'return id(mode_c).active_index() == 0;' + then: + - switch.toggle: relay_c + # Momentary + - if: + condition: + - lambda: 'return id(mode_c).active_index() == 1;' + then: + - switch.turn_on: relay_c + # Pulse + - if: + condition: + - lambda: 'return id(mode_c).active_index() == 2;' + then: + - switch.turn_on: relay_c + - delay: ${timing_pulse} + - switch.turn_off: relay_c + + on_release: + # Momentary + - if: + condition: + - lambda: 'return id(mode_c).active_index() == 1;' + then: + - switch.turn_off: relay_c diff --git a/sonoff-m5/backlight.yaml b/sonoff-m5/backlight.yaml new file mode 100644 index 0000000..78ce2a9 --- /dev/null +++ b/sonoff-m5/backlight.yaml @@ -0,0 +1,22 @@ +# NOTE: This file is not a stand-alone package. It is part of +# a 'root' device template and expects the substitutions that +# are hereby referenced to be defined by its parent. + +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 + +light: + + # 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' \ No newline at end of file diff --git a/sonoff-m5/board.yaml b/sonoff-m5/board.yaml new file mode 100644 index 0000000..7f32178 --- /dev/null +++ b/sonoff-m5/board.yaml @@ -0,0 +1,6 @@ +# Define the board for the compiler +esp32: + board: esp32dev + framework: + type: arduino + version: recommended \ No newline at end of file diff --git a/sonoff-m5/button-a.yaml b/sonoff-m5/button-a.yaml new file mode 100644 index 0000000..b98e1fe --- /dev/null +++ b/sonoff-m5/button-a.yaml @@ -0,0 +1,60 @@ +# NOTE: This file is not a stand-alone package. It is part of +# a 'root' device template and expects the substitutions that +# are hereby referenced to be defined by its parent. + +binary_sensor: + # Physical Button A + - platform: gpio + name: "Button A" + id: button_a + pin: + number: ${button_a_gpio} + mode: INPUT_PULLUP + inverted: true + ignore_strapping_warning: false + + filters: + - delayed_on: ${filter_delay_on} + - delayed_off: ${filter_delay_off} + + on_multi_click: + # single click detection + - timing: + - ${timing_click_1} + - ${timing_click_2} + then: + - homeassistant.event: + event: esphome.on_gesture + data: + button: A + gesture: single_click + + # double click detection + - timing: + - ${timing_double_click_1} + - ${timing_double_click_2} + - ${timing_double_click_3} + - ${timing_double_click_4} + then: + - homeassistant.event: + event: esphome.on_gesture + data: + button: A + gesture: double_click + + # hold detection + - timing: + - ${timing_hold} + 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: ${timing_hold_repeat} + - light.turn_off: led_status diff --git a/sonoff-m5/button-b.yaml b/sonoff-m5/button-b.yaml new file mode 100644 index 0000000..5297235 --- /dev/null +++ b/sonoff-m5/button-b.yaml @@ -0,0 +1,60 @@ +# NOTE: This file is not a stand-alone package. It is part of +# a 'root' device template and expects the substitutions that +# are hereby referenced to be defined by its parent. + +binary_sensor: + # Physical Button B + - platform: gpio + name: "Button B" + id: button_b + pin: + number: ${button_b_gpio} + mode: INPUT_PULLUP + inverted: true + ignore_strapping_warning: true + + filters: + - delayed_on: ${filter_delay_on} + - delayed_off: ${filter_delay_off} + + on_multi_click: + # single click detection + - timing: + - ${timing_click_1} + - ${timing_click_2} + then: + - homeassistant.event: + event: esphome.on_gesture + data: + button: B + gesture: single_click + + # double click detection + - timing: + - ${timing_double_click_1} + - ${timing_double_click_2} + - ${timing_double_click_3} + - ${timing_double_click_4} + then: + - homeassistant.event: + event: esphome.on_gesture + data: + button: B + gesture: double_click + + # hold detection + - timing: + - ${timing_hold} + 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: ${timing_hold_repeat} + - light.turn_off: led_status diff --git a/sonoff-m5/button-c.yaml b/sonoff-m5/button-c.yaml new file mode 100644 index 0000000..09aa773 --- /dev/null +++ b/sonoff-m5/button-c.yaml @@ -0,0 +1,60 @@ +# NOTE: This file is not a stand-alone package. It is part of +# a 'root' device template and expects the substitutions that +# are hereby referenced to be defined by its parent. + +binary_sensor: + # Physical Button C + - platform: gpio + name: "Button C" + id: button_c + pin: + number: ${button_c_gpio} + mode: INPUT_PULLUP + inverted: true + ignore_strapping_warning: true + + filters: + - delayed_on: ${filter_delay_on} + - delayed_off: ${filter_delay_off} + + on_multi_click: + # single click detection + - timing: + - ${timing_click_1} + - ${timing_click_2} + then: + - homeassistant.event: + event: esphome.on_gesture + data: + button: C + gesture: single_click + + # double click detection + - timing: + - ${timing_double_click_1} + - ${timing_double_click_2} + - ${timing_double_click_3} + - ${timing_double_click_4} + then: + - homeassistant.event: + event: esphome.on_gesture + data: + button: C + gesture: double_click + + # hold detection + - timing: + - ${timing_hold} + 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: ${timing_hold_repeat} + - light.turn_off: led_status diff --git a/sonoff-m5/indicator-led.yaml b/sonoff-m5/indicator-led.yaml new file mode 100644 index 0000000..2c1d643 --- /dev/null +++ b/sonoff-m5/indicator-led.yaml @@ -0,0 +1,15 @@ +# NOTE: This file is not a stand-alone package. It is part of +# a 'root' device template and expects the substitutions that +# are hereby referenced to be defined by its parent. + +# Allow importing this package +dashboard_import: + package_import_url: "github://mariodivece/esphometemplates/sonoff-m5/indicator-led.yaml@main" + import_full_config: false + +switch: + # Physical indicator of the relay + - platform: gpio + id: led_indicator + internal: true + pin: ${led_indicator_gpio} \ No newline at end of file diff --git a/sonoff-m5/mode-button-a.yaml b/sonoff-m5/mode-button-a.yaml new file mode 100644 index 0000000..1a4e83b --- /dev/null +++ b/sonoff-m5/mode-button-a.yaml @@ -0,0 +1,21 @@ +# NOTE: This file is not a stand-alone package. It is part of +# a 'root' device template and expects the substitutions that +# are hereby referenced to be defined by its parent. + +select: + # Config-only select for operation mode + - platform: template + name: "Mode - Button A" + id: mode_a + icon: 'mdi:link-box-outline' + entity_category: 'config' + options: + - "Latching" # 0 + - "Momentary" # 1 + - "Pulse" # 2 + - "Decoupled" # 3 + initial_option: "Latching" + restore_value: true + optimistic: true + set_action: + - switch.turn_off: relay_a diff --git a/sonoff-m5/mode-button-b.yaml b/sonoff-m5/mode-button-b.yaml new file mode 100644 index 0000000..3d4f5a8 --- /dev/null +++ b/sonoff-m5/mode-button-b.yaml @@ -0,0 +1,21 @@ +# NOTE: This file is not a stand-alone package. It is part of +# a 'root' device template and expects the substitutions that +# are hereby referenced to be defined by its parent. + +select: + # Config-only select for operation mode + - platform: template + name: "Mode - Button B" + id: mode_b + icon: 'mdi:link-box-outline' + entity_category: 'config' + options: + - "Latching" # 0 + - "Momentary" # 1 + - "Pulse" # 2 + - "Decoupled" # 3 + initial_option: "Latching" + restore_value: true + optimistic: true + set_action: + - switch.turn_off: relay_b diff --git a/sonoff-m5/mode-button-c.yaml b/sonoff-m5/mode-button-c.yaml new file mode 100644 index 0000000..9db3613 --- /dev/null +++ b/sonoff-m5/mode-button-c.yaml @@ -0,0 +1,21 @@ +# NOTE: This file is not a stand-alone package. It is part of +# a 'root' device template and expects the substitutions that +# are hereby referenced to be defined by its parent. + +select: + # Config-only select for operation mode + - platform: template + name: "Mode - Button C" + id: mode_c + icon: 'mdi:link-box-outline' + entity_category: 'config' + options: + - "Latching" # 0 + - "Momentary" # 1 + - "Pulse" # 2 + - "Decoupled" # 3 + initial_option: "Latching" + restore_value: true + optimistic: true + set_action: + - switch.turn_off: relay_c diff --git a/sonoff-m5/relay-a.yaml b/sonoff-m5/relay-a.yaml new file mode 100644 index 0000000..7632c6b --- /dev/null +++ b/sonoff-m5/relay-a.yaml @@ -0,0 +1,11 @@ +# NOTE: This file is not a stand-alone package. It is part of +# a 'root' device template and expects the substitutions that +# are hereby referenced to be defined by its parent. + +switch: + # Physical GPIO Relay + - platform: gpio + name: "Relay A" + pin: ${relay_a_gpio} + id: relay_a + restore_mode: RESTORE_DEFAULT_OFF \ No newline at end of file diff --git a/sonoff-m5/relay-b.yaml b/sonoff-m5/relay-b.yaml new file mode 100644 index 0000000..e0a31b9 --- /dev/null +++ b/sonoff-m5/relay-b.yaml @@ -0,0 +1,11 @@ +# NOTE: This file is not a stand-alone package. It is part of +# a 'root' device template and expects the substitutions that +# are hereby referenced to be defined by its parent. + +switch: + # Physical GPIO Relay + - platform: gpio + name: "Relay B" + pin: ${relay_b_gpio} + id: relay_b + restore_mode: RESTORE_DEFAULT_OFF \ No newline at end of file diff --git a/sonoff-m5/relay-c.yaml b/sonoff-m5/relay-c.yaml new file mode 100644 index 0000000..b1b4378 --- /dev/null +++ b/sonoff-m5/relay-c.yaml @@ -0,0 +1,11 @@ +# NOTE: This file is not a stand-alone package. It is part of +# a 'root' device template and expects the substitutions that +# are hereby referenced to be defined by its parent. + +switch: + # Physical GPIO Relay + - platform: gpio + name: "Relay C" + pin: ${relay_c_gpio} + id: relay_c + restore_mode: RESTORE_DEFAULT_OFF \ No newline at end of file diff --git a/sonoff-m5/status-led.yaml b/sonoff-m5/status-led.yaml new file mode 100644 index 0000000..2971ed2 --- /dev/null +++ b/sonoff-m5/status-led.yaml @@ -0,0 +1,31 @@ +# NOTE: This file is not a stand-alone package. It is part of +# a 'root' device template and expects the substitutions that +# are hereby referenced to be defined by its parent. + +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 + ignore_strapping_warning: true + internal: true + restore_mode: RESTORE_DEFAULT_ON + +binary_sensor: + + # 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 \ No newline at end of file diff --git a/sonoff-m5/timings.yaml b/sonoff-m5/timings.yaml new file mode 100644 index 0000000..41dd14e --- /dev/null +++ b/sonoff-m5/timings.yaml @@ -0,0 +1,26 @@ + +# NOTE: This file is not a stand-alone package. It is part of +# a 'root' device template and expects the substitutions that +# are hereby referenced to be defined by its parent. + +substitutions: + # Button timing configurations + filter_delay_on: 50ms + filter_delay_off: 50ms + + # Single Click Timings + timing_click_1: ON for at most 400ms + timing_click_2: OFF for at least 600ms + + # Double Click Timings + timing_double_click_1: ON for at most 500ms + timing_double_click_2: OFF for at most 400ms + timing_double_click_3: ON for at most 500ms + timing_double_click_4: OFF for at least 250ms + + # Button Hold Timings + timing_hold: ON for at least 1s + timing_hold_repeat: 100ms + + # Pulse Switch + timing_pulse: 250ms \ No newline at end of file diff --git a/standard/diagnostics.yaml b/standard/diagnostics.yaml new file mode 100644 index 0000000..c962628 --- /dev/null +++ b/standard/diagnostics.yaml @@ -0,0 +1,103 @@ +# NOTE: This file is not a stand-alone package. It is part of +# a 'root' device template and expects the substitutions that +# are hereby referenced to be defined by its parent. + +substitutions: + log_level: INFO + timezone: "America/Mexico_City" + +# Enable logging via network and disable serial port +logger: + level: "${log_level}" + baud_rate: 0 + +# Provide date and time +time: + - platform: sntp + id: time_service + timezone: ${timezone} + update_interval: 15min + servers: + - 0.pool.ntp.org + - 1.pool.ntp.org + - 2.pool.ntp.org + +# Diagnostic output sensors +text_sensor: + + - platform: wifi_info + ip_address: + id: ip_address + name: "IP Address" + icon: "mdi:wan" + + - platform: template + name: "Uptime" + id: uptime_human + icon: "mdi:timer-check-outline" + update_interval: 60s + entity_category: "diagnostic" + disabled_by_default: true + +binary_sensor: + # Diagnostic sensor for connection + - platform: status + icon: 'mdi:home-assistant' + name: "API Status" + id: sensor_status + disabled_by_default: true + +sensor: + # Device Memory + - platform: template + id: esp_memory + icon: mdi:memory + name: Free Memory + lambda: return heap_caps_get_free_size(MALLOC_CAP_INTERNAL) / 1024; + unit_of_measurement: "kB" + state_class: measurement + entity_category: "diagnostic" + disabled_by_default: true + + # Captures the uptime and updates the human-readable + # text sensor displayed. This is an internal sensor only. + - platform: uptime + name: "Uptime" + id: sensor_uptime + update_interval: 60s + entity_category: "diagnostic" + internal: true + on_raw_value: + then: + - text_sensor.template.publish: + id: uptime_human + state: !lambda |- + int seconds = round(id(sensor_uptime).raw_state); + int days = seconds / (24 * 3600); + seconds = seconds % (24 * 3600); + int hours = seconds / 3600; + seconds = seconds % 3600; + int minutes = seconds / 60; + seconds = seconds % 60; + return ( + (days ? String(days) + "d " : "") + + (hours ? String(hours) + "h " : "") + + (minutes ? String(minutes) + "m " : "") + + (String(seconds) + "s") + ).c_str(); + +# Provide a pre-built button for restarting the device +button: + - platform: restart + name: "Reboot Device" + id: button_restart + icon: mdi:power-cycle + entity_category: "diagnostic" + + # Provide a button to reset all defined flash settings. + - platform: factory_reset + disabled_by_default: false + name: "Load Factory Settings" + id: factory_reset_all + icon: mdi:factory + \ No newline at end of file diff --git a/standard/internaltemp.yaml b/standard/internaltemp.yaml new file mode 100644 index 0000000..5781fd7 --- /dev/null +++ b/standard/internaltemp.yaml @@ -0,0 +1,9 @@ +# NOTE: This file is not a stand-alone package. It is part of +# a 'root' device template and expects the substitutions that +# are hereby referenced to be defined by its parent. + +sensor: + - platform: internal_temperature + name: "Internal Temperature" + disabled_by_default: true + icon: mdi:heat-wave diff --git a/standard/project.yaml b/standard/project.yaml new file mode 100644 index 0000000..3629975 --- /dev/null +++ b/standard/project.yaml @@ -0,0 +1,53 @@ +# NOTE: This file is not a stand-alone package. It is part of +# a 'root' device template and expects the substitutions that +# are hereby referenced to be defined by its parent. + +substitutions: + # Generated name and unique device id for the device + # Not intended for user substitutions + device_name: "${device_location_name} - ${device_type_name} - ${device_number}" + device_code: "${device_site}-${device_location_code}-${device_type_code}-${device_number}" + +# Define a global variable for CPU speed +globals: + - id: cpu_speed + type: int + restore_value: no + initial_value: "0" + +# Setup the integration and define some project variables +esphome: + name: "${device_code}" + friendly_name: "${device_name}" + comment: "${device_model} by ${device_make}" + name_add_mac_suffix: false + min_version: "2023.2.0" + project: + name: "${device_make}.${device_model}" + version: "${package_version}" + on_boot: + - priority: 900.0 + then: + - lambda: |- + id(cpu_speed) = ESP.getCpuFreqMHz(); + +text_sensor: + # Show firmware template version + - platform: template + name: "Deployment Version" + lambda: return {"${package_version}"}; + disabled_by_default: true + icon: "mdi:tag" + entity_category: diagnostic + +sensor: + # Device CPU Frequency + - platform: template + name: "CPU Frequency" + icon: "mdi:speedometer" + accuracy_decimals: 0 + unit_of_measurement: Mhz + disabled_by_default: true + lambda: |- + return (id(cpu_speed)); + entity_category: diagnostic \ No newline at end of file diff --git a/standard/wifi.yaml b/standard/wifi.yaml new file mode 100644 index 0000000..62a821f --- /dev/null +++ b/standard/wifi.yaml @@ -0,0 +1,50 @@ +# NOTE: This file is not a stand-alone package. It is part of +# a 'root' device template and expects the substitutions that +# are hereby referenced to be defined by its parent. + +substitutions: + # WiFi Substitutions + api_key: !secret api_key + wifi_ssid: !secret wifi_ssid + wifi_password: !secret wifi_password + ota_password: !secret ota_password + +# Enable Home Assistant API +api: + # Disable reboot if no client connected (defaults to 15min) + reboot_timeout: 0s + encryption: + key: "${api_key}" + +sensor: + - platform: wifi_signal + name: "RSSI" + id: sensor_rssi + icon: 'mdi:signal' + update_interval: 60s + entity_category: "diagnostic" + +# Enable OTA +ota: + - platform: esphome + password: "${ota_password}" + +# Enable Safe Mode +safe_mode: + +# Enable WiFi and AP for captive portal +wifi: + fast_connect: false + power_save_mode: light + ssid: "${wifi_ssid}" + password: "${wifi_password}" + use_address: "${device_ip}" + + # Enable fallback hotspot (captive portal) in case wifi connection fails + # password for hostspot is the same as password for net AP (needs captive_portal) + ap: + ssid: "${device_code}-setup" + password: "${wifi_password}" + ap_timeout: 5min + +captive_portal: