diff --git a/esphome/esp-maindishwasherpower.yaml b/esphome/esp-maindishwasherpower.yaml deleted file mode 100644 index f91162a..0000000 --- a/esphome/esp-maindishwasherpower.yaml +++ /dev/null @@ -1,170 +0,0 @@ -########################################################################################## -########################################################################################## -# MAIN DISHWASHER POWER -# Controlled by a Athom Smart Plug V1 -# package_import_url: github://athom-tech/athom-configs/athom-smart-plug.yaml -# -# V1.1 2025-06-12 package added for energy entities -# V1.0 2025-06-10 YAML Tidyups -# -########################################################################################## -########################################################################################## - -########################################################################################## -# SPECIFIC DEVICE VARIABLE SUBSTITUTIONS -# If NOT using a secrets file, just replace these with the passwords etc (in quotes) -########################################################################################## -substitutions: - # Device Naming - device_name: "esp-maindishwasherpower" - friendly_name: "Main Dishwasher Power" - description_comment: "Main Dishwasher Power Monitor :: Athom Smart Plug Power Monitor V1" - device_area: "Kitchen" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant. - - # Project Naming - project_name: "Athom Technology.Smart Plug V1" # Project Details - project_version: "v1.1" # Project V denotes release of yaml file, allowing checking of deployed vs latest version - - # Passwords - api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names - ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names - static_ip_address: !secret esp-maindishwasherpower_ip - - # Device Settings - log_level: "INFO" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE - update_interval: "60s" # update time for for general sensors etc - - # Device Settings - relay_icon: "mdi:dishwasher" - current_limit : "10" # Current Limit in Amps. AU Plug = 10. IL, BR, EU, UK, US Plug = 16. - -########################################################################################## -# PACKAGES -# https://esphome.io/components/esphome.html -########################################################################################## -packages: - common_wifi: !include - file: common/network_common.yaml - vars: - local_static_ip_address: "${static_ip_address}" - local_ota_pass: "${ota_pass}" - common_api: !include - file: common/api_common.yaml - vars: - local_api_key: "${api_key}" - common_sntp: !include - file: common/sntp_common.yaml - common_general_sensors: !include - file: common/sensors_common.yaml - vars: - local_friendly_name: "${friendly_name}" - local_update_interval: "${update_interval}" - - # Web and MQTT Packages - #common_webportal: !include - # file: common/webportal_common.yaml - #common_mqtt: !include - # file: common/mqtt_common.yaml - - - # Device Specific included packages - common_athompowermonV1: !include - file: common/athompowermonv1_common.yaml - vars: - local_friendly_name: "${friendly_name}" - local_current_limit: "${current_limit}" - -########################################################################################## -# ESPHome -# https://esphome.io/components/esphome.html -########################################################################################## -esphome: - name: "${device_name}" - friendly_name: "${friendly_name}" - comment: "${description_comment}" # Appears on the esphome page in HA - area: "${device_area}" - name_add_mac_suffix: False - min_version: 2024.6.0 - project: - name: "${project_name}" - version: "${project_version}" - on_boot: - priority: 200 - then: - - switch.turn_on: "relay" - -########################################################################################## -# ESP Platform and Framework -# https://esphome.io/components/esp32.html -########################################################################################## -esp8266: - board: esp8285 - restore_from_flash: true # mainly for calculating cumulative energy, but not that important here - -preferences: - flash_write_interval: 5min - -mdns: - disabled: false - -#dashboard_import: -# package_import_url: github://athom-tech/esp32-configs/athom-smart-plug.yaml - -########################################################################################## -# ESPHome LOGGING -# https://esphome.io/components/logger.html -########################################################################################## -logger: - level: "${log_level}" #INFO Level suggested, or DEBUG for testing - #baud_rate: 0 # set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM) - #esp8266_store_log_strings_in_flash: false - #tx_buffer_size: 64 - -########################################################################################## -# STATUS LED -# https://esphome.io/components/status_led.html -########################################################################################## -status_led: - pin: - number: GPIO13 - inverted: True - -########################################################################################## -# BINARY SENSORS -# https://esphome.io/components/binary_sensor/ -########################################################################################## -binary_sensor: - - platform: gpio - pin: - number: 3 - mode: INPUT_PULLUP - inverted: true - name: "Power Button" - id: power_button - filters: - - delayed_on: 20ms - on_click: - - min_length: 20ms - max_length: 500ms - then: - - switch.toggle: - id: relay - - - platform: template - name: "Relay Status" - lambda: |- - return id(relay).state; - -################################################################################################# -# SWITCH COMPONENT -# https://esphome.io/components/switch/ -################################################################################################# -switch: - - platform: gpio - name: "Power Output" - pin: GPIO14 - id: relay - restore_mode: RESTORE_DEFAULT_OFF # Ensures the relay is restored (or off) at boot - #internal: true # Hides the switch from Home Assistant - icon: "${relay_icon}" - diff --git a/esphome/esp-officemultiusb copy.yaml.bak b/esphome/esp-officemultiusb copy.yaml.bak deleted file mode 100644 index 6ab9b65..0000000 --- a/esphome/esp-officemultiusb copy.yaml.bak +++ /dev/null @@ -1,188 +0,0 @@ -############################################# -############################################# -# OFFICE MULTI USB CONTROL -# Controlled by a Sonoff Basic R1 -# -# V1.0 2025-06-18 Initial Version -# -########################################################################################## -########################################################################################## - -########################################################################################## -# SPECIFIC DEVICE VARIABLE SUBSTITUTIONS -# If NOT using a secrets file, just replace these with the passwords etc (in quotes) -########################################################################################## -substitutions: - # Device Naming - device_name: "esp-officemultiusb" - friendly_name: "Office Multi USB Control" - mqtt_device_name: "office-multiusb-control" - description_comment: "Multi USB control in the Office (behind monitors) :: Sonoff Basic" - device_area: "Office" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant. - - # Project Naming - project_name: "Sonoff Technologies.Sonoff Basic V1" # Project Details - project_version: "v1.0" # Project V denotes release of yaml file, allowing checking of deployed vs latest version - - # Passwords - api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names - ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names - static_ip_address: !secret esp-officeelvcontrol_ip - mqtt_main_command_topic: !secret mqtt_main_command_topic - - # Device Settings - relay_icon: "mdi:generator-portable" - log_level: "ERROR" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE - update_interval: "60s" # update time for for general sensors etc - - # MQTT Controls - mqtt_main_topic: "${mqtt_main_command_topic}/${mqtt_device_name}/operation" # Topic we will use to command stuff from external withougt HA - #mqtt_status_topic: "${mqtt_main_status_topic}/esphome/${device_name}" # Topic we will use to read stuff from external withougt HA - #mqtt_main_status_topic: !secret mqtt_main_status_topic - #mqtt_remote_device1_command_topic: "${mqtt_main_command_topic}/masterbath-towelrail/operation" - #mqtt_remote_device1_command1: "BOOST" - -########################################################################################## -# PACKAGES: Included Common Packages -# https://esphome.io/components/esphome.html -########################################################################################## -packages: - common_wifi: !include - file: common/network_common.yaml - vars: - local_static_ip_address: "${static_ip_address}" - local_ota_pass: "${ota_pass}" - common_api: !include - file: common/api_common.yaml - vars: - local_api_key: "${api_key}" - #common_webportal: !include - # file: common/webportal_common.yaml - common_mqtt: !include - file: common/mqtt_common.yaml - common_sntp: !include - file: common/sntp_common.yaml - common_general_sensors: !include - file: common/sensors_common.yaml - vars: - local_friendly_name: "${friendly_name}" - local_update_interval: "${update_interval}" - -########################################################################################## -# ESPHome -# https://esphome.io/components/esphome.html -########################################################################################## -esphome: - name: "${device_name}" - friendly_name: "${friendly_name}" - comment: "${description_comment}" # Appears on the esphome page in HA - area: "${device_area}" -# platformio_options: -# build_flags: -# - "-Os" # optimize for size -# - "-Wl,--gc-sections" # drop unused code/data -# - "-fno-exceptions" # strip C++ exceptions -# - "-fno-rtti" # strip C++ RTTI - - -########################################################################################## -# ESP Platform and Framework -# https://esphome.io/components/esp32.html -########################################################################################## -esp8266: - board: esp01_1m # The original sonoff basic - restore_from_flash: True # restore some values on reboot - -preferences: - flash_write_interval: 5min - -mdns: - disabled: False - -########################################################################################## -# ESPHome Logging Enable -# https://esphome.io/components/logger.html -########################################################################################## -logger: - level: "${log_level}" #INFO Level suggested, or DEBUG for testing - baud_rate: 0 # set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM) - #esp8266_store_log_strings_in_flash: false - #tx_buffer_size: 64 - -########################################################################################## -# SWITCH COMPONENT -# https://esphome.io/components/switch/ -########################################################################################## -# Sonoff Basic R1 Relay Switch is GPIO12 -############################################# -switch: - - platform: gpio - name: "ELV Power Supply" - pin: GPIO12 - id: relay1 - restore_mode: RESTORE_DEFAULT_ON - icon: "${relay_icon}" - -########################################################################################## -# BINARY SENSORS -# https://esphome.io/components/binary_sensor/ -########################################################################################## -# Sonoff Basic R1 Button is GPIO03 -############################################# -binary_sensor: - - - platform: gpio - pin: - number: GPIO03 - mode: INPUT_PULLUP - inverted: true - name: "Power Button" - id: power_button - filters: - - delayed_on: 20ms - on_click: - - min_length: 20ms - max_length: 500ms - then: - - lambda: |- - if (id(relay1).state) { - // Relay is ON: turn it OFF - id(relay1).turn_off(); - } else { - // Relay is OFF: turn it ON - id(relay1).turn_on(); - } - - # Mimics actual relay status (but not controllable) - - platform: template - name: "Relay Status" - lambda: |- - return id(relay1).state; - -########################################################################################## -# STATUS LED -# https://esphome.io/components/status_led.html -########################################################################################## -# Sonoff Basic R1 LED is GPIO13 -############################################# -status_led: - pin: - number: GPIO13 - inverted: yes - -########################################################################################## -# MQTT COMMANDS -# This adds device-specific MQTT command triggers to the common MQTT configuration. -########################################################################################## -mqtt: - on_message: - # Relay 1 control - - topic: "${mqtt_main_topic}/relay1/set" - payload: "ON" - then: - - switch.turn_on: relay1 - - topic: "${mqtt_main_topic}/relay1/set" - payload: "OFF" - then: - - switch.turn_off: relay1 - diff --git a/esphome/esp-poolpumppower copy.yaml.bak b/esphome/esp-poolpumppower copy.yaml.bak deleted file mode 100644 index 6935040..0000000 --- a/esphome/esp-poolpumppower copy.yaml.bak +++ /dev/null @@ -1,682 +0,0 @@ -########################################################################################## -########################################################################################## -# POOL PUMP POWER AND TIMER -# Controlled by a Athom Smart Plug V3 -# -# dashboard_import: -# package_import_url: github://athom-tech/esp32-configs/athom-smart-plug.yaml -# -# V2.3 2025-06-19 Minor changes to remember mode in reboot and to ensure offline functionality -# V2.2 2025-06-14 Fixes to offline time when sntp/network unavailable -# V2.1 2025-06-12 Added select and button to chose modes, added countdown & startup to boost -# V2.0 2025-06-05 YAML Tidyups -# -# INSTRUCTIONS -# - It allows the device to work in a standalone timer style operation -# - The timer has a morning and evening time (but no weekday/weekend settings) -# - Default values are set, but changed values are remembered in flash -# - It uses SNTP for time setting (but obviously only if wifi & networking are working) -# - It will default to an internal timer if no wifi. To reset internal timer, reboot the device at 12pm (noon) -# - If on a network and there is a MQTT server, you can set the on/off times via MQTT (See below commands) -# - You can set 4 modes ON/OFF/TIMER/BOOST via MQTT. Setting BOOST gives you a oneshot operation -# - Any new timer times set via MQTT will be remembered though a reboot -# - On startup, or a reboot, the device will always turn on for the BOOST Duration (BOOST mode, default 2 hours) -# - TIMER mode will always be switched on after BOOST mode is complete -# - Home Assistant entities are set so that BOOST mode can be pressed with a button and other modes selectable with a dropdown -# - If you need it ON continuously with no MQTT, toggle power ON/OFF 4 times within 30 seconds (with ~2 secs in between to allow it to boot) -# -# MQTT Commands -# Values will be set in place on the update_interval time, not immediately -# Use 00:00 in 24hr format for time setting. (Note there is no weekday/weekend setting) -# mqtt_timer_topic/morning-on/06:00 : Time device will go on -# mqtt_timer_topic/morning-off/08:00 : Time device will go off -# mqtt_timer_topic/evening-on/09:00 : Time device will go on -# mqtt_timer_topic/evening-off/00:00 : Time device will go off -# mqtt_timer_topic/boost-time/0000 : Time in minutes device will temporarily go on for (1-1439) -# mqtt_timer_topic/operation/ON : Device permanently on -# mqtt_timer_topic/operation/OFF : Device permanently off -# mqtt_timer_topic/operation/TIMER : Device will obey timer settings -# mqtt_timer_topic/operation/BOOST : Turn on for (boost_duration) minutes then BOOST (also on startup) -# -# operation_mode: -# 0 = OFF -# 1 = ON -# 2 = TIMER -# 3 = BOOST -# -########################################################################################## -########################################################################################## - -########################################################################################## -# SPECIFIC DEVICE VARIABLE SUBSTITUTIONS -# If NOT using a secrets file, just replace these with the passwords etc (in quotes) -########################################################################################## -substitutions: - # Device Naming - device_name: "esp-poolpumppower" - friendly_name: "Pool Pump Power" - description_comment: "Pool Pump Power :: Athom Smart Plug Power V3" - device_area: "Outside" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant. - - # Project Naming - project_name: "Athom Technology.Smart Plug V3" # Project Details - project_version: "v2.2" # Project V denotes release of yaml file, allowing checking of deployed vs latest version - - # Passwords - api_key: !secret esp-poolpumppower_api_key # unfortunately you can't use substitutions inside secrets names - ota_pass: !secret esp-poolpumppower_ota_pass # unfortunately you can't use substitutions inside secrets names - static_ip_address: !secret esp-poolpumppower_ip - - # Device Settings - log_level: "INFO" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE - update_interval: "20s" # update time for for general sensors etc - - # Device Settings - relay_icon: "mdi:pool" - current_limit : "10" # Current Limit in Amps. AU Plug = 10. IL, BR, EU, UK, US Plug = 16. - mqtt_timer_topic: "viewroad-commands/poolpump-timer" # Topics you will use to change stuff - boost_duration_default: "60" # Minutes to stay ON in STARTUP mode before reverting to TIMER - morning_on_default: "450" # Default in minutes from midnight. Default 07:30 => 450 - morning_off_default: "450" # Default in minutes from midnight. Default 07:30 => 450 (same as ON as no need for morning schedule) - evening_on_default: "1260" # Default in minutes from midnight. Default 21:00 => 1260 - evening_off_default: "1350" # Default in minutes from midnight. Default 22:30 => 1350 => 1440 is midnight - -########################################################################################## -# PACKAGES -# https://esphome.io/components/esphome.html -########################################################################################## -packages: - common_wifi: !include - file: common/network_common.yaml - vars: - local_static_ip_address: "${static_ip_address}" - local_ota_pass: "${ota_pass}" - common_api: !include - file: common/api_common.yaml - vars: - local_api_key: "${api_key}" - common_sntp: !include - file: common/sntp_common.yaml - common_general_sensors: !include - file: common/sensors_common.yaml - vars: - local_friendly_name: "${friendly_name}" - local_update_interval: "${update_interval}" - - # Web and MQTT Packages - #common_webportal: !include - # file: common/webportal_common.yaml - common_mqtt: !include - file: common/mqtt_common.yaml - - # Device Specific included packages - common_athompowermonV3: !include - file: common/athompowermonv3_common.yaml - vars: - local_current_limit: "${current_limit}" - -########################################################################################## -# ESPHome -# https://esphome.io/components/esphome.html -########################################################################################## -esphome: - name: "${device_name}" - friendly_name: "${friendly_name}" - comment: "${description_comment}" #Appears on the esphome page in HA - area: "${device_area}" - name_add_mac_suffix: False - min_version: 2024.6.0 - project: - name: "${project_name}" - version: "${project_version}" - platformio_options: - board_build.mcu: esp32c3 - board_build.variant: esp32c3 - board_build.flash_mode: dio - -########################################################################################## -# ESP Platform and Framework -# https://esphome.io/components/esp32.html -########################################################################################## -esp32: - board: esp32-c3-devkitm-1 - flash_size: 4MB - variant: ESP32C3 - framework: - type: esp-idf # "esp-idf" OR "arduino". Suggested ESP-IDF Framework, or Plug Out the UART Cable Might Cause ESP32 Hang. - version: recommended # recommended, latest or dev - -preferences: - flash_write_interval: 5min - -esp32_improv: - authorizer: none - -########################################################################################## -# ESPHome Logging Enable -# https://esphome.io/components/logger.html -########################################################################################## -logger: - level: "${log_level}" #INFO Level suggested, or DEBUG for testing - baud_rate: 0 #set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM) - #esp8266_store_log_strings_in_flash: false - #tx_buffer_size: 64 - -########################################################################################## -# Global Variables for use in automations etc -# https://esphome.io/guides/automations.html?highlight=globals#global-variables -########################################################################################## -globals: - - # Tracks the time (in seconds from midnight) at the previous boot - - id: last_boot_time_s - type: int - restore_value: true - initial_value: "0" - - # Counts how many consecutive boots have occurred (within X seconds) - - id: boot_count - type: int - restore_value: true - initial_value: "0" - - # Morning On time (minutes from midnight), - - id: morning_on - type: int - restore_value: False - initial_value: "${morning_on_default}" - - # Morning Off time (minutes from midnight), - - id: morning_off - type: int - restore_value: False - initial_value: "${morning_off_default}" - - # Evening On time (minutes from midnight), - - id: evening_on - type: int - restore_value: False - initial_value: "${evening_on_default}" - - # Evening Off time (minutes from midnight), - - id: evening_off - type: int - restore_value: False - initial_value: "${evening_off_default}" - - # Boost Duration (minutes), - - id: boost_duration - type: int - restore_value: False - initial_value: "${boost_duration_default}" - - #################################################### - # operation_mode: - # 0 = OFF - # 1 = ON - # 2 = TIMER - # 3 = BOOST - #################################################### - - id: operation_mode - type: int - restore_value: True - initial_value: "2" - - #################################################### - # current_mins is set if SNTP is invalid. - # We assume user powers on the device at 12:00 noon - # => 12 * 60 = 720 minutes from midnight. - # Not restored, so it resets each boot. - #################################################### - - id: current_mins - type: int - restore_value: true - initial_value: "720" # 720 is 12:00 Noon - - #################################################### - # boost_timer: counts minutes in BOOST mode - # After 'boost_duration' minutes, revert to TIMER. - # Not restored, so each boot starts fresh at 0. - #################################################### - - id: boost_timer - type: int - restore_value: true - initial_value: "0" - -########################################################################################## -# Text Sensors -# https://esphome.io/components/text_sensor/index.html -########################################################################################## -text_sensor: - -############################ -# MQTT Subscriptions -############################ - #################################################### - # Subscribe to the Morning On time, format "HH:MM" - # We check x.size() == 5 and x[2] == ':', - # then parse x.substr(0,2) and x.substr(3,2) - # std::string uses 'substr', not 'substring'. - #################################################### - - platform: mqtt_subscribe - name: "Morning On Time Setting" - id: morning_on_topic - topic: "${mqtt_timer_topic}/morning-on" # Stored in the format HH:MM - internal: True - on_value: - then: - - lambda: |- - // Expect "HH:MM" => total length = 5, with ':' - if (x.size() == 5 && x[2] == ':') { - int hour = atoi(x.substr(0, 2).c_str()); // "HH" - int minute = atoi(x.substr(3, 2).c_str()); // "MM" - id(morning_on) = hour * 60 + minute; - ESP_LOGI("timer","Received new Morning On: %02d:%02d", hour, minute); - } else { - ESP_LOGW("timer","Invalid Morning On format: %s", x.c_str()); - } - #################################################### - # Morning Off time => "HH:MM" - #################################################### - - platform: mqtt_subscribe - name: "Morning Off Time Setting" - id: morning_off_topic - topic: "${mqtt_timer_topic}/morning-off" # Stored in the format HH:MM - internal: True # No need to show this in Home Assistant as there is a sensor that shows the set value - on_value: - then: - - lambda: |- - if (x.size() == 5 && x[2] == ':') { - int hour = atoi(x.substr(0, 2).c_str()); - int minute = atoi(x.substr(3, 2).c_str()); - id(morning_off) = hour * 60 + minute; - ESP_LOGI("timer","Received new Morning Off: %02d:%02d", hour, minute); - } else { - ESP_LOGW("timer","Invalid Morning Off format: %s", x.c_str()); - } - #################################################### - # Evening On time => "HH:MM" - #################################################### - - platform: mqtt_subscribe - name: "Evening On Time Setting" - id: evening_on_topic - topic: "${mqtt_timer_topic}/evening-on" # Stored in the format HH:MM - internal: True # No need to show this in Home Assistant as there is a sensor that shows the set value - on_value: - then: - - lambda: |- - if (x.size() == 5 && x[2] == ':') { - int hour = atoi(x.substr(0, 2).c_str()); - int minute = atoi(x.substr(3, 2).c_str()); - id(evening_on) = hour * 60 + minute; - ESP_LOGI("timer","Received new Evening On: %02d:%02d", hour, minute); - } else { - ESP_LOGW("timer","Invalid Evening On format: %s", x.c_str()); - } - #################################################### - # Evening Off time => "HH:MM" - #################################################### - - platform: mqtt_subscribe - name: "Evening Off Time Setting" - id: evening_off_topic - topic: "${mqtt_timer_topic}/evening-off" # Stored in the format HH:MM - internal: True # No need to show this in Home Assistant as there is a sensor that shows the set value - on_value: - then: - - lambda: |- - if (x.size() == 5 && x[2] == ':') { - int hour = atoi(x.substr(0, 2).c_str()); - int minute = atoi(x.substr(3, 2).c_str()); - id(evening_off) = hour * 60 + minute; - ESP_LOGI("timer","Received new Evening Off: %02d:%02d", hour, minute); - } else { - ESP_LOGW("timer","Invalid Evening Off format: %s", x.c_str()); - } - #################################################### - # Boost duration => 1 - 1439 - #################################################### - - platform: mqtt_subscribe - name: "Boost Duration" - id: boost_time_topic - topic: "${mqtt_timer_topic}/boost-time" # Stored as an integer from 1-1439 - internal: True # No need to show this in Home Assistant as there is a sensor that shows the set value - on_value: - then: - - lambda: |- - // parse as integer - char *endptr; - long v = strtol(x.c_str(), &endptr, 10); - - // invalid if nothing parsed, trailing chars, or out of 0–1439 - if (endptr == x.c_str() || *endptr != '\0' || v < 0 || v > 1439) { - ESP_LOGE("boost_time", "Invalid boost_time '%s'", x.c_str()); - } else { - id(boost_duration) = static_cast(v); - } - - #################################################### - # Subscribe to operation mode: - # OFF, ON, TIMER, BOOST - # We do case-insensitive compare using strcasecmp - # (Requires typically included in ESPHome) - #################################################### - # MQTT subscription: set mode, then immediately re-evaluate relay - - platform: mqtt_subscribe - id: timer_operation_mode_topic - topic: "${mqtt_timer_topic}/operation" - internal: True # No need to show this in Home Assistant as there is a sensor that shows the set value - on_value: - then: - - lambda: |- - if (strcasecmp(x.c_str(), "TIMER") == 0) { - id(operation_mode) = 2; - ESP_LOGI("timer","Operation mode set to TIMER"); - } else if (strcasecmp(x.c_str(), "ON") == 0) { - id(operation_mode) = 1; - ESP_LOGI("timer","Operation mode set to ON"); - } else if (strcasecmp(x.c_str(), "OFF") == 0) { - id(operation_mode) = 0; - ESP_LOGI("timer","Operation mode set to OFF"); - } else if (strcasecmp(x.c_str(), "BOOST") == 0) { - id(operation_mode) = 3; - id(boost_timer) = 0; - ESP_LOGI("timer","Operation mode set to BOOST"); - } else { - ESP_LOGW("timer","Invalid operation mode: %s", x.c_str()); - } - - script.execute: evaluate_relay_state - - ###################################################### - # Expose the current operation mode (OFF, ON, TIMER, BOOST) - ###################################################### - - platform: template - name: "Operation Mode State" - lambda: |- - // 0=OFF, 1=ON, 2=TIMER, 3=BOOST - switch (id(operation_mode)) { - case 0: return {"OFF"}; - case 1: return {"ON"}; - case 2: return {"TIMER"}; - case 3: return {"BOOST"}; - default: return {"UNKNOWN"}; - } - update_interval: 5s - - ###################################################### - # Expose the "Morning On" time as a text (HH:MM) - ###################################################### - - platform: template - name: "Timeclock: Morning On Time" - lambda: |- - int hour = id(morning_on) / 60; - int minute = id(morning_on) % 60; - // Increase to 16 for safety - char buff[16]; - snprintf(buff, sizeof(buff), "%02d:%02d", hour, minute); - return { std::string(buff) }; - update_interval: "${update_interval}" - - ###################################################### - # Expose the "Morning Off" time as a text (HH:MM) - ###################################################### - - platform: template - name: "Timeclock: Morning Off Time" - lambda: |- - int hour = id(morning_off) / 60; - int minute = id(morning_off) % 60; - // Increase buffer size to 8 just to be safe - // Increase to 16 for safety - char buff[16]; - snprintf(buff, sizeof(buff), "%02d:%02d", hour, minute); - return { std::string(buff) }; - update_interval: "${update_interval}" - - ###################################################### - # Expose the "Evening On" time as a text (HH:MM) - ###################################################### - - platform: template - name: "Timeclock: Evening On Time" - lambda: |- - int hour = id(evening_on) / 60; - int minute = id(evening_on) % 60; - // Increase buffer size to 8 just to be safe - // Increase to 16 for safety - char buff[16]; - snprintf(buff, sizeof(buff), "%02d:%02d", hour, minute); - return { std::string(buff) }; - update_interval: "${update_interval}" - - ###################################################### - # Expose the "Evening Off" time as a text (HH:MM) - ###################################################### - - platform: template - name: "Timeclock: Evening Off Time" - lambda: |- - int hour = id(evening_off) / 60; - int minute = id(evening_off) % 60; - // Increase buffer size to 8 just to be safe - // Increase to 16 for safety - char buff[16]; - snprintf(buff, sizeof(buff), "%02d:%02d", hour, minute); - return { std::string(buff) }; - update_interval: "${update_interval}" - -########################################################################################## -# BINARY SENSORS -# https://esphome.io/components/binary_sensor/ -########################################################################################## -binary_sensor: - - platform: gpio - pin: - number: GPIO3 - mode: INPUT_PULLUP - inverted: true - name: "Power Button" - id: power_button - filters: - - delayed_on: 20ms - on_click: - - min_length: 20ms - max_length: 500ms - then: - - lambda: |- - if (id(relay).state) { - // Relay is ON: turn it OFF and set mode to 0 (TIMER) - id(relay).turn_off(); - id(operation_mode) = 2; - } else { - // Relay is OFF: turn it ON and set mode to 3 (BOOST) - id(relay).turn_on(); - id(operation_mode) = 3; - } - - - platform: template - name: "Relay Status" - lambda: |- - return id(relay).state; - -########################################################################################## -# Sensors -# https://esphome.io/components/text_sensor/index.html -########################################################################################## -sensor: - - platform: template - name: "Timeclock: Boost Duration" - id: boost_duration_time - unit_of_measurement: "mins" - accuracy_decimals: "0" - update_interval: "${update_interval}" - lambda: |- - return id(boost_duration); - - - platform: template - name: "Mins from Midnight" - id: mins_from_midnight - unit_of_measurement: "mins" - accuracy_decimals: "0" - update_interval: "${update_interval}" - internal: True # No need to show this in Home Assistant - lambda: |- - return id(current_mins); - - # A value in mins if a timer is running showing how many mins left - - platform: template - name: "Timer Minutes Remaining" - id: timer_minutes_remaining - unit_of_measurement: "Mins" - update_interval: 5s - accuracy_decimals: "0" - lambda: |- - // always zero if relay is off - if (!id(relay).state) { - return 0; - } - int rem = 0; - // only calculate for mode 2 (scheduled) or mode 3 (BOOST) - if (id(operation_mode) == 2) { - int a = id(morning_off) - id(current_mins); - int b = id(evening_off) - id(current_mins); - // if a is negative, use b; otherwise pick the smaller of a or b - rem = (a < 0) ? b : (a < b ? a : b); - } - else if (id(operation_mode) == 3) { - rem = id(boost_duration) - id(boost_timer); - } - // never return negative - return rem > 0 ? rem : 0; - - -################################################################################################# -# SWITCH COMPONENT -# https://esphome.io/components/switch/ -################################################################################################# -switch: - - platform: gpio - name: "Power Output" - pin: GPIO5 - id: relay - restore_mode: RESTORE_DEFAULT_OFF # Ensures the relay is restored (or off) at boot - #internal: true # Hides the switch from Home Assistant - icon: "${relay_icon}" - -################################################################################################# -# BUTTON COMPONENT -# https://esphome.io/components/button/index.html -################################################################################################# -button: - - platform: template - name: "Boost now" - id: boost_button - icon: "mdi:play-circle-outline" - on_press: - # 1) reset BOOST timer and set mode - - lambda: |- - id(boost_timer) = 0; - id(operation_mode) = 3; - # 2) immediately re-evaluate relay state - - script.execute: evaluate_relay_state - -################################################################################################# -# SELECT COMPONENT -# https://esphome.io/components/select/index.html -################################################################################################# -select: - - platform: template - name: "Operation Mode" - id: operation_mode_select - update_interval: 5s - options: - - "OFF" - - "ON" - - "TIMER" - - "BOOST" - - # show the current mode - lambda: |- - switch (id(operation_mode)) { - case 1: return std::string("ON"); - case 2: return std::string("TIMER"); - case 3: return std::string("BOOST"); - default: return std::string("OFF"); - } - - # when changed in HA, set mode & re-evaluate - set_action: - - lambda: |- - if (x == "OFF") { id(operation_mode) = 0; } - else if (x == "ON") { id(operation_mode) = 1; } - else if (x == "TIMER") { id(operation_mode) = 2; } - else { // BOOST - id(boost_timer) = 0; - id(operation_mode) = 3; - } - - script.execute: evaluate_relay_state - -################################################################################################# -# SCRIPT COMPONENT -# https://esphome.io/components/script.html -################################################################################################# -# Script: evaluate and drive the relay -script: - - id: evaluate_relay_state - then: - - lambda: |- - int mode = id(operation_mode); - - // BOOST just forces the relay on - if (mode == 3) { - id(relay).turn_on(); - return; - } - - // OFF → always off - if (mode == 0) { - id(relay).turn_off(); - return; - } - - // ON → always on - if (mode == 1) { - id(relay).turn_on(); - return; - } - - // TIMER → follow schedule windows - { - bool should_on = false; - if (id(current_mins) >= id(morning_on) && id(current_mins) < id(morning_off)) - should_on = true; - if (id(current_mins) >= id(evening_on) && id(current_mins) < id(evening_off)) - should_on = true; - if (should_on) id(relay).turn_on(); - else id(relay).turn_off(); - } - -################################################################################################# -# INTERVAL COMPONENT -# https://esphome.io/components/interval.html -################################################################################################# -# Interval: bumps time (even if no SNTP), then calls the script to evaluate relay state -interval: - - interval: "1min" - then: - - lambda: |- - // — update current_mins via SNTP or fallback - if (!id(sntp_time).now().is_valid()) { - id(current_mins)++; - if (id(current_mins) >= 1440) id(current_mins) = 0; - } else { - auto now = id(sntp_time).now(); - id(current_mins) = now.hour * 60 + now.minute; - } - - // — if in BOOST, advance boost_timer and expire when done - if (id(operation_mode) == 3) { - id(boost_timer)++; - if (id(boost_timer) >= id(boost_duration)) { - id(operation_mode) = 2; - //id(mqtt_client).publish("${mqtt_timer_topic}/operation", "TIMER"); - } - } - - script.execute: evaluate_relay_state -