From e2e9549b9d5dbdf9d6f66af1cd1e8737ec7e20a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Koco=C5=84?= Date: Mon, 27 Apr 2026 15:14:20 +0200 Subject: [PATCH] auto-commit --- sonoff-m5-1g-us.yaml | 386 ++++++++++++++++++++++++++++++++++++------- sonoff-m5-2g-us.yaml | 1 - 2 files changed, 329 insertions(+), 58 deletions(-) diff --git a/sonoff-m5-1g-us.yaml b/sonoff-m5-1g-us.yaml index 8d62986..a668b98 100644 --- a/sonoff-m5-1g-us.yaml +++ b/sonoff-m5-1g-us.yaml @@ -2,7 +2,7 @@ # Sonoff Switchman M5 1-Gang US # Copyright (c) 2024 Mario Di Vece # License: [MIT](https://opensource.org/license/mit/) -# Decription: +# Description: # 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. @@ -10,31 +10,12 @@ # - 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 @@ -46,61 +27,218 @@ substitutions: device_number: "044" device_ip: "0.0.0.0" - # Project Substitutions (not intended for user substitution) + # Project Substitutions device_model: "Switchman M5 (1-Gang)" device_make: "Sonoff" package_version: "2024.2.13" package_url: "https://gitea.domowyasystent.com/PeakControl/devices/raw/branch/main/sonoff-m5-1g-us.yaml" - # Relay Configurations + # Generated device name/code + device_name: "${device_location_name} - ${device_type_name} - ${device_number}" + device_code: "${device_site}-${device_location_code}-${device_type_code}-${device_number}" + + # WiFi / API secrets + api_key: !secret api_key + wifi_ssid: !secret wifi_ssid + wifi_password: !secret wifi_password + ota_password: !secret ota_password + + # Relay GPIO relay_a_gpio: GPIO23 - # Button Configurations + # Button GPIO button_a_gpio: GPIO00 - # Indicator LED + # Indicator LED GPIO led_indicator_gpio: GPIO19 -# Import packages -packages: - standard_package: - url: https://gitea.domowyasystent.com/PeakControl/devices/ - ref: main - refresh: 0d - files: - - standard/project.yaml - - standard/diagnostics.yaml - - standard/wifi.yaml - - standard/internaltemp.yaml - sonoffm5_package: - url: https://gitea.domowyasystent.com/PeakControl/devices/ - 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 + # Diagnostics + log_level: INFO + timezone: "America/Mexico_City" + + # Button timing configurations + filter_delay_on: 50ms + filter_delay_off: 50ms + timing_click_1: ON for at most 400ms + timing_click_2: OFF for at least 600ms + 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 + timing_hold: ON for at least 1s + timing_hold_repeat: 100ms + timing_pulse: 250ms + +# ── Board ────────────────────────────────────────────────────────────────────── + +esp32: + board: esp32dev + framework: + type: arduino + version: recommended + +# ── ESPHome / Project ────────────────────────────────────────────────────────── + +globals: + - id: cpu_speed + type: int + restore_value: no + initial_value: "0" + +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(); + +# ── Connectivity ─────────────────────────────────────────────────────────────── + +api: + reboot_timeout: 0s + encryption: + key: "${api_key}" + +ota: + - platform: esphome + password: "${ota_password}" + +safe_mode: + +wifi: + fast_connect: false + power_save_mode: light + ssid: "${wifi_ssid}" + password: "${wifi_password}" + use_address: "${device_ip}" + ap: + ssid: "${device_code}-setup" + password: "${wifi_password}" + ap_timeout: 5min + +captive_portal: + +# ── Logging / Time ───────────────────────────────────────────────────────────── + +logger: + level: "${log_level}" + baud_rate: 0 + +time: + - platform: sntp + id: time_service + timezone: ${timezone} + update_interval: 15min + servers: + - 0.pool.ntp.org + - 1.pool.ntp.org + - 2.pool.ntp.org + +# ── Outputs ──────────────────────────────────────────────────────────────────── + +output: + - platform: ledc + id: pwm_output + pin: GPIO18 + frequency: 1000 Hz + +# ── Lights ───────────────────────────────────────────────────────────────────── + +light: + - platform: status_led + name: "LED" + id: led_status + pin: + number: GPIO05 + inverted: true + ignore_strapping_warning: true + internal: true + restore_mode: RESTORE_DEFAULT_ON + + - platform: monochromatic + output: pwm_output + name: "Background Brightness" + restore_mode: RESTORE_DEFAULT_OFF + icon: 'mdi:led-outline' + entity_category: 'config' + +# ── Switches ─────────────────────────────────────────────────────────────────── switch: - - # Modify behavior of imported Relay A - - id: !extend relay_a + - platform: gpio + name: "Relay A" + pin: ${relay_a_gpio} + id: relay_a + restore_mode: RESTORE_DEFAULT_OFF on_turn_on: - - switch.turn_on: led_indicator + - switch.turn_on: led_indicator on_turn_off: - - switch.turn_off: led_indicator + - switch.turn_off: led_indicator + + - platform: gpio + id: led_indicator + internal: true + pin: ${led_indicator_gpio} + +# ── Selects ──────────────────────────────────────────────────────────────────── + +select: + - 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 + +# ── Binary Sensors ───────────────────────────────────────────────────────────── binary_sensor: + - platform: status + icon: 'mdi:home-assistant' + name: "API Status" + id: sensor_status + disabled_by_default: true - # Button A - - id: !extend button_a + - 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 + + - platform: gpio + name: "Button A" + id: button_a pin: + number: ${button_a_gpio} + mode: INPUT_PULLUP + inverted: true ignore_strapping_warning: true + filters: + - delayed_on: ${filter_delay_on} + - delayed_off: ${filter_delay_off} on_press: # Latching - if: @@ -128,7 +266,6 @@ binary_sensor: - lambda: 'return id(mode_a).active_index() == 3;' then: - switch.turn_on: led_indicator - on_release: # Momentary - if: @@ -142,3 +279,138 @@ binary_sensor: - lambda: 'return id(mode_a).active_index() == 3;' then: - switch.turn_off: led_indicator + on_multi_click: + - timing: + - ${timing_click_1} + - ${timing_click_2} + then: + - homeassistant.event: + event: esphome.on_gesture + data: + button: A + gesture: single_click + - 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 + - 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 + +# ── Sensors ──────────────────────────────────────────────────────────────────── + +sensor: + - platform: wifi_signal + name: "RSSI" + id: sensor_rssi + icon: 'mdi:signal' + update_interval: 60s + entity_category: "diagnostic" + + - platform: internal_temperature + name: "Internal Temperature" + disabled_by_default: true + icon: mdi:heat-wave + + - 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 + + - 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 + + - 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(); + +# ── Text 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 + + - platform: template + name: "Deployment Version" + lambda: return {"${package_version}"}; + disabled_by_default: true + icon: "mdi:tag" + entity_category: diagnostic + +# ── Buttons ──────────────────────────────────────────────────────────────────── + +button: + - platform: restart + name: "Reboot Device" + id: button_restart + icon: mdi:power-cycle + entity_category: "diagnostic" + + - platform: factory_reset + disabled_by_default: false + name: "Load Factory Settings" + id: factory_reset_all + icon: mdi:factory diff --git a/sonoff-m5-2g-us.yaml b/sonoff-m5-2g-us.yaml index 7b02e79..c80c62f 100644 --- a/sonoff-m5-2g-us.yaml +++ b/sonoff-m5-2g-us.yaml @@ -50,7 +50,6 @@ substitutions: 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