diff --git a/.test/esphome_ard_hw_relays.yaml b/.test/esphome_ard_hw_relays.yaml index b12f6fe5..db28fc11 100644 --- a/.test/esphome_ard_hw_relays.yaml +++ b/.test/esphome_ard_hw_relays.yaml @@ -2,5 +2,5 @@ packages: common_arduino: !include common_ard.yaml core_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml - standard_hw_relays_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_relays.yaml + hw_relays_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_hw_relays.yaml ... diff --git a/.test/esphome_ard_hw_speaker.yaml b/.test/esphome_ard_hw_speaker.yaml index e054db85..83affc7e 100644 --- a/.test/esphome_ard_hw_speaker.yaml +++ b/.test/esphome_ard_hw_speaker.yaml @@ -2,5 +2,5 @@ packages: common_arduino: !include common_ard.yaml core_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml - standard_hw_speaker_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_speaker.yaml + hw_speaker_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_hw_speaker.yaml ... diff --git a/.test/esphome_ard_hw_vibration.yaml b/.test/esphome_ard_hw_vibration.yaml index b0f06f60..7a616da1 100644 --- a/.test/esphome_ard_hw_vibration.yaml +++ b/.test/esphome_ard_hw_vibration.yaml @@ -2,5 +2,5 @@ packages: common_arduino: !include common_ard.yaml core_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml - standard_hw_vibration_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_vibration.yaml + hw_vibration_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_hw_vibration.yaml ... diff --git a/.test/esphome_idf_hw_relays.yaml b/.test/esphome_idf_hw_relays.yaml index b746d8af..df295ee7 100644 --- a/.test/esphome_idf_hw_relays.yaml +++ b/.test/esphome_idf_hw_relays.yaml @@ -2,5 +2,5 @@ packages: common_idf: !include common_idf.yaml core_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml - standard_hw_relays_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_relays.yaml + hw_relays_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_hw_relays.yaml ... diff --git a/.test/esphome_idf_hw_speaker.yaml b/.test/esphome_idf_hw_speaker.yaml index 2ce797ac..31111a57 100644 --- a/.test/esphome_idf_hw_speaker.yaml +++ b/.test/esphome_idf_hw_speaker.yaml @@ -2,5 +2,5 @@ packages: common_idf: !include common_idf.yaml core_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml - standard_hw_speaker_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_speaker.yaml + hw_speaker_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_hw_speaker.yaml ... diff --git a/.test/esphome_idf_hw_vibration.yaml b/.test/esphome_idf_hw_vibration.yaml index 30d73582..48aef5f0 100644 --- a/.test/esphome_idf_hw_vibration.yaml +++ b/.test/esphome_idf_hw_vibration.yaml @@ -2,5 +2,5 @@ packages: common_idf: !include common_idf.yaml core_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml - standard_hw_vibration_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_vibration.yaml + hw_vibration_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_hw_vibration.yaml ... diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core_common.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_common.yaml similarity index 72% rename from ESPHome/TX-Ultimate-Easy-ESPHome_core_common.yaml rename to ESPHome/TX-Ultimate-Easy-ESPHome_common.yaml index 1e7531f4..b75ca90a 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core_common.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_common.yaml @@ -2,7 +2,7 @@ ##### TX Ultimate Easy for ESPHome ##### ##### Repository: https://github.com/edwardtfn/TX-Ultimate-Easy ##### #################################################################################################### -##### Purpose: ESPHome Core - Common ##### +##### Purpose: ESPHome - Common ##### #################################################################################################### ##### Author: edwardtfn - https://github.com/edwardtfn - https://buymeacoffee.com/edwardfirmo ##### #################################################################################################### @@ -29,14 +29,14 @@ substitutions: DUMP_CONFIG_CALLER_DELAY: 5s # Delay to dump config after requested - TAG_CORE_COMMON: core.common + TAG_COMMON: tx_ultimate_easy.common api: id: api_server + homeassistant_services: true on_client_connected: then: - script.execute: dump_config_caller - - script.execute: publish_device_info binary_sensor: - id: bs_pending_restart @@ -73,18 +73,23 @@ esp32: flash_size: 8MB framework: type: esp-idf + advanced: + loop_task_stack_size: 16384 + sdkconfig_options: + CONFIG_ESP32_REV_MIN_3: y esphome: name: ${name} friendly_name: ${friendly_name} comment: TX Ultimate Easy - min_version: 2025.8.0 + min_version: 2025.11.0 project: name: "edwardtfn.tx_ultimate_easy" version: ${version} platformio_options: build_flags: - - -D TX_ULTIMATE_EASY_CORE_COMMON + - -D TX_ULTIMATE_EASY_COMMON + - -D TX_ULTIMATE_EASY_FIRMWARE_VERSION="${version}" on_boot: - priority: 1000 # Very early in boot process @@ -145,13 +150,7 @@ script: then: - lambda: |- // Send event to Home Assistant - esphome::api::CustomAPIDevice ha_event; - ha_event.fire_homeassistant_event("${EVENT_NAME}", { - {"device_name", id(tx_device_name).state.c_str()}, - {"firmware", "${version}"}, - {"domain", "boot"}, - {"type", type.c_str()} - }); + esphome::tx_ultimate_easy::fire_ha_event("boot", type.c_str(), {}); - id: boot_done mode: restart @@ -174,6 +173,7 @@ script: # - HW Buttons # - HW Relays # - HW Touch + - script.execute: update_device_name - script.execute: id: api_send_ha_event_boot type: start @@ -182,16 +182,15 @@ script: - lambda: return sl_tx_model_format->active_index().has_value(); - lambda: return sl_tx_model_gang->active_index().has_value(); - lambda: |- - id(is_us_model) = (sl_tx_model_format->state == "${TX_MODEL_FORMAT_US_TEXT}"); + id(is_us_model) = strcmp(sl_tx_model_format->current_option(), "${TX_MODEL_FORMAT_US_TEXT}") == 0; id(gang_count) = sl_tx_model_gang->active_index().value() + 1; if (id(gang_count) < 1 || id(gang_count) > 4) { - ESP_LOGE("${TAG_CORE_COMMON}", "Invalid number of gangs: %" PRIu8, id(gang_count)); + ESP_LOGE("${TAG_COMMON}", "Invalid number of gangs: %" PRIu8, id(gang_count)); } - id: boot_sequence mode: restart then: - - script.execute: publish_device_info - binary_sensor.template.publish: id: bs_pending_restart state: false @@ -202,43 +201,43 @@ script: # Extended by all modules - lambda: |- // Device identification - ESP_LOGCONFIG("${TAG_CORE_COMMON}", "Device friendly name: ${friendly_name}"); - ESP_LOGCONFIG("${TAG_CORE_COMMON}", "Device name: ${name}"); - ESP_LOGCONFIG("${TAG_CORE_COMMON}", "Device name (HA): %s", tx_device_name->state.c_str()); - ESP_LOGCONFIG("${TAG_CORE_COMMON}", "Device hostname: %s", App.get_name().c_str()); + ESP_LOGCONFIG("${TAG_COMMON}", "Device friendly name: ${friendly_name}"); + ESP_LOGCONFIG("${TAG_COMMON}", "Device name: ${name}"); + ESP_LOGCONFIG("${TAG_COMMON}", "Device name (HA): %s", esphome::tx_ultimate_easy::cached_device_name.c_str()); + ESP_LOGCONFIG("${TAG_COMMON}", "Device hostname: %s", App.get_name().c_str()); dump_config_versions->execute(); // Framework detection #ifdef USE_ARDUINO - ESP_LOGCONFIG("${TAG_CORE_COMMON}", "Framework: Arduino"); + ESP_LOGCONFIG("${TAG_COMMON}", "Framework: Arduino"); #elif defined(USE_ESP_IDF) - ESP_LOGCONFIG("${TAG_CORE_COMMON}", "Framework: ESP-IDF"); + ESP_LOGCONFIG("${TAG_COMMON}", "Framework: ESP-IDF"); #else - ESP_LOGW("${TAG_CORE_COMMON}", "Framework: UNKNOWN"); + ESP_LOGW("${TAG_COMMON}", "Framework: UNKNOWN"); #endif // Model configuration - ESP_LOGCONFIG("${TAG_CORE_COMMON}", "Model format (selected): %s", - sl_tx_model_format->state.c_str()); - ESP_LOGCONFIG("${TAG_CORE_COMMON}", "Model format (detected): %s", + ESP_LOGCONFIG("${TAG_COMMON}", "Model format (selected): %s", + sl_tx_model_format->current_option()); + ESP_LOGCONFIG("${TAG_COMMON}", "Model format (detected): %s", id(is_us_model) ? "US" : "EU"); - ESP_LOGCONFIG("${TAG_CORE_COMMON}", "Gangs (selected): %s", - sl_tx_model_gang->state.c_str()); - ESP_LOGCONFIG("${TAG_CORE_COMMON}", "Gangs (detected): %" PRIu8 "-Gang%s", + ESP_LOGCONFIG("${TAG_COMMON}", "Gangs (selected): %s", + sl_tx_model_gang->current_option()); + ESP_LOGCONFIG("${TAG_COMMON}", "Gangs (detected): %" PRIu8 "-Gang%s", id(gang_count), id(gang_count) > 1 ? "s" : ""); // Boot completion status if (bs_boot_completed->state) - ESP_LOGCONFIG("${TAG_CORE_COMMON}", "Boot completed: Yes"); + ESP_LOGCONFIG("${TAG_COMMON}", "Boot completed: Yes"); else - ESP_LOGW("${TAG_CORE_COMMON}", "Boot completed: NO"); + ESP_LOGW("${TAG_COMMON}", "Boot completed: NO"); // System state if (bs_pending_restart->state) - ESP_LOGW("${TAG_CORE_COMMON}", "Pending restart: YES"); + ESP_LOGW("${TAG_COMMON}", "Pending restart: YES"); else - ESP_LOGCONFIG("${TAG_CORE_COMMON}", "Pending restart: No"); + ESP_LOGCONFIG("${TAG_COMMON}", "Pending restart: No"); - id: dump_config_caller mode: restart @@ -263,17 +262,10 @@ script: then: - lambda: |- // Version information - ESP_LOGCONFIG("${TAG_CORE_COMMON}", "TX Ultimate firmware version: ${version}"); + ESP_LOGCONFIG("${TAG_COMMON}", "TX Ultimate firmware version: ${version}"); // ESPHome builder information - ESP_LOGCONFIG("${TAG_CORE_COMMON}", "ESPHome builder: " ESPHOME_VERSION); - ESP_LOGCONFIG("${TAG_CORE_COMMON}", "ESPHome build timestamp: %s", App.get_compilation_time().c_str()); - - - id: publish_device_info - mode: restart - then: - - lambda: |- - tx_fw_version->publish_state("${version}"); - tx_device_name->publish_state(App.get_name().c_str()); + ESP_LOGCONFIG("${TAG_COMMON}", "ESPHome builder: " ESPHOME_VERSION); + ESP_LOGCONFIG("${TAG_COMMON}", "ESPHome build timestamp: %s", App.get_compilation_time().c_str()); - id: restore_from_nvs mode: single @@ -287,6 +279,16 @@ script: if (id(gang_count) < 1 || id(gang_count) > 4) return 0; // default to 1-Gang return static_cast(id(gang_count)) - 1; + - id: update_device_name + mode: single + then: + - lambda: |- + if (esphome::tx_ultimate_easy::cached_device_name.empty()) { + esphome::tx_ultimate_easy::initialize_cached_device_name(App.get_name()); + ESP_LOGI("${TAG_COMMON}", "Device name: %s", esphome::tx_ultimate_easy::cached_device_name.c_str()); + tx_device_name->publish_state(esphome::tx_ultimate_easy::cached_device_name); + } + select: - id: sl_tx_model_format name: Model (Format) @@ -303,10 +305,8 @@ select: icon: mdi:tablet-cellphone on_value: then: - - binary_sensor.template.publish: - id: bs_pending_restart - state: true - lambda: |- + bs_pending_restart->publish_state(true); id(is_us_model) = (x == "${TX_MODEL_FORMAT_US_TEXT}"); - id: sl_tx_model_gang @@ -326,10 +326,8 @@ select: icon: mdi:dip-switch on_value: then: - - binary_sensor.template.publish: - id: bs_pending_restart - state: true - lambda: |- + bs_pending_restart->publish_state(true); id(gang_count) = static_cast(i) + 1; tx_ultimate->set_gang_count(id(gang_count)); @@ -353,26 +351,18 @@ text_sensor: disabled_by_default: false update_interval: never lambda: |- - return {"${name}"}; - filters: - - lambda: |- - const std::string raw_name = x; - std::string result; - bool last_was_underscore = false; - for (const char& c : raw_name) { - if (isalnum(c)) { - result += tolower(c); // Add alphanumeric characters as lowercase - last_was_underscore = false; - } else if (!last_was_underscore) { // Replace non-alphanumeric with '_' but avoid consecutive '_' - result += '_'; - last_was_underscore = true; - } - } - return result; + return { esphome::tx_ultimate_easy::cached_device_name }; tx_ultimate_easy: id: tx_ultimate wifi: id: wifi_component + use_psram: true + + on_connect: + then: + - lambda: |- + tx_fw_version->publish_state("${version}"); + update_device_name->execute(); ... diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml index 6672dd3a..52c581bc 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml @@ -13,9 +13,9 @@ --- packages: # yamllint disable rule:colons - core_common: !include TX-Ultimate-Easy-ESPHome_core_common.yaml - core_hw_buttons: !include TX-Ultimate-Easy-ESPHome_core_hw_buttons.yaml - core_hw_leds: !include TX-Ultimate-Easy-ESPHome_core_hw_leds.yaml - core_hw_touch: !include TX-Ultimate-Easy-ESPHome_core_hw_touch.yaml + common: !include TX-Ultimate-Easy-ESPHome_common.yaml + hw_buttons: !include TX-Ultimate-Easy-ESPHome_hw_buttons.yaml + hw_leds: !include TX-Ultimate-Easy-ESPHome_hw_leds.yaml + hw_touch: !include TX-Ultimate-Easy-ESPHome_hw_touch.yaml # yamllint enable rule:colons ... diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_audio.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_hw_audio.yaml similarity index 83% rename from ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_audio.yaml rename to ESPHome/TX-Ultimate-Easy-ESPHome_hw_audio.yaml index a11e595a..aedb90d0 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_audio.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_hw_audio.yaml @@ -2,7 +2,7 @@ ##### TX Ultimate Easy for ESPHome ##### ##### Repository: https://github.com/edwardtfn/TX-Ultimate-Easy ##### #################################################################################################### -##### Purpose: ESPHome - Standard - I2S Audio ##### +##### Purpose: ESPHome - Hardward - I2S Audio ##### #################################################################################################### ##### Author: edwardtfn - https://github.com/edwardtfn - https://buymeacoffee.com/edwardfirmo ##### #################################################################################################### @@ -14,12 +14,12 @@ substitutions: SWITCH_AUDIO_AMPLIFIER_RESTORE_MODE: RESTORE_DEFAULT_ON - TAG_STD_HW_AUDIO: std.hw.audio + TAG_HW_AUDIO: tx_ultimate_easy.hw.audio esphome: platformio_options: build_flags: - - -D TX_ULTIMATE_EASY_STANDARD_HW_AUDIO + - -D TX_ULTIMATE_EASY_HW_AUDIO i2s_audio: - id: if_i2s_audio @@ -32,12 +32,12 @@ script: - script.wait: dump_config - lambda: |- // Check for requirements - #if !defined(TX_ULTIMATE_EASY_CORE_COMMON) - #error "The package TX-Ultimate-Easy-ESPHome_core_common.yaml is required." + #if !defined(TX_ULTIMATE_EASY_COMMON) + #error "The package TX-Ultimate-Easy-ESPHome_common.yaml is required." #endif // Identify itself - ESP_LOGCONFIG(ESPHOME_PROJECT_NAME, " - Standard - Hardware - Audio"); + ESP_LOGCONFIG(ESPHOME_PROJECT_NAME, " - Hardware - Audio"); switch: - id: sw_audio_amplifier diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_buttons.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_hw_buttons.yaml similarity index 88% rename from ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_buttons.yaml rename to ESPHome/TX-Ultimate-Easy-ESPHome_hw_buttons.yaml index b5b22fdc..a6f0243d 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_buttons.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_hw_buttons.yaml @@ -2,7 +2,7 @@ ##### TX Ultimate Easy for ESPHome ##### ##### Repository: https://github.com/edwardtfn/TX-Ultimate-Easy ##### #################################################################################################### -##### Purpose: ESPHome Core - Hardware - Buttons ##### +##### Purpose: ESPHome - Hardware - Buttons ##### #################################################################################################### ##### Author: edwardtfn - https://github.com/edwardtfn - https://buymeacoffee.com/edwardfirmo ##### #################################################################################################### @@ -36,7 +36,7 @@ substitutions: BUTTON_3_ID: '3' BUTTON_4_ID: '4' - TAG_CORE_HW_BUTTONS: core.hw.buttons + TAG_HW_BUTTONS: tx_ultimate_easy.hw.buttons binary_sensor: - &binary_sensor_button_base @@ -62,7 +62,7 @@ binary_sensor: esphome: platformio_options: build_flags: - - -D TX_ULTIMATE_EASY_CORE_HW_BUTTONS + - -D TX_ULTIMATE_EASY_HW_BUTTONS globals: # Packed button actions - replaces 4 separate selects @@ -124,18 +124,13 @@ script: then: - lambda: |- // Send event to Home Assistant - esphome::api::CustomAPIDevice ha_event; - ha_event.fire_homeassistant_event("${EVENT_NAME}", { - {"device_name", id(tx_device_name).state.c_str()}, - {"firmware", "${version}"}, - {"domain", "touch"}, - {"type", "button"}, + esphome::tx_ultimate_easy::fire_ha_event("touch", "button", { {"action", action.c_str()}, {"button_id", std::to_string(button)}, {"count", std::to_string(count)}, {"position", std::to_string(id(button_press_position))} }); - ESP_LOGI("${TAG_CORE_HW_BUTTONS}", "Button %" PRIu8 " action: '%s'", button, action.c_str()); + ESP_LOGI("${TAG_HW_BUTTONS}", "Button %" PRIu8 " action: '%s'", button, action.c_str()); if (action == "click") { switch (button) { case ${BUTTON_1_ID}: @@ -221,32 +216,32 @@ script: - lambda: |- std::string gang_count_plural_suffix = id(gang_count) > 1 ? "s" : ""; // Button's actions - ESP_LOGCONFIG("${TAG_CORE_HW_BUTTONS}", "Button%s action%s:", + ESP_LOGCONFIG("${TAG_HW_BUTTONS}", "Button%s action%s:", gang_count_plural_suffix.c_str(), gang_count_plural_suffix.c_str()); - ESP_LOGCONFIG("${TAG_CORE_HW_BUTTONS}", " Relay 1: %s", sl_button_1_action->has_state() ? - sl_button_1_action->state.c_str() : "Unknown"); + ESP_LOGCONFIG("${TAG_HW_BUTTONS}", " Relay 1: %s", sl_button_1_action->has_state() ? + sl_button_1_action->current_option() : "Unknown"); if (id(gang_count) >= 2) - ESP_LOGCONFIG("${TAG_CORE_HW_BUTTONS}", " Relay 2: %s", sl_button_2_action->has_state() ? - sl_button_2_action->state.c_str() : "Unknown"); + ESP_LOGCONFIG("${TAG_HW_BUTTONS}", " Relay 2: %s", sl_button_2_action->has_state() ? + sl_button_2_action->current_option() : "Unknown"); if (id(gang_count) >= 3) - ESP_LOGCONFIG("${TAG_CORE_HW_BUTTONS}", " Relay 3: %s", sl_button_3_action->has_state() ? - sl_button_3_action->state.c_str() : "Unknown"); + ESP_LOGCONFIG("${TAG_HW_BUTTONS}", " Relay 3: %s", sl_button_3_action->has_state() ? + sl_button_3_action->current_option() : "Unknown"); if (id(gang_count) >= 4) - ESP_LOGCONFIG("${TAG_CORE_HW_BUTTONS}", " Relay 4: %s", sl_button_4_action->has_state() ? - sl_button_4_action->state.c_str() : "Unknown"); + ESP_LOGCONFIG("${TAG_HW_BUTTONS}", " Relay 4: %s", sl_button_4_action->has_state() ? + sl_button_4_action->current_option() : "Unknown"); - id: !extend dump_config_list_packages then: - script.wait: dump_config - lambda: |- // Check for requirements - #if !defined(TX_ULTIMATE_EASY_CORE_COMMON) - #error "The package TX-Ultimate-Easy-ESPHome_core_common.yaml is required." + #if !defined(TX_ULTIMATE_EASY_COMMON) + #error "The package TX-Ultimate-Easy-ESPHome_common.yaml is required." #endif // Identify itself - ESP_LOGCONFIG(ESPHOME_PROJECT_NAME, " - Core - Hardware - Buttons"); + ESP_LOGCONFIG(ESPHOME_PROJECT_NAME, " - Hardware - Buttons"); - id: !extend restore_from_nvs then: @@ -315,20 +310,20 @@ script: id(button_press_start_time) < current_time) { uint32_t press_duration = current_time - id(button_press_start_time); // Handle overflow (optional, since it's unlikely to happen here) - ESP_LOGI("${TAG_CORE_HW_BUTTONS}", "Button press duration: %" PRIu32 " ms", press_duration); + ESP_LOGI("${TAG_HW_BUTTONS}", "Button press duration: %" PRIu32 " ms", press_duration); if (press_duration < ${BUTTON_CLICK_MIN_LENGTH}) { - ESP_LOGW("${TAG_CORE_HW_BUTTONS}", "Ignoring button press (too short)"); + ESP_LOGW("${TAG_HW_BUTTONS}", "Ignoring button press (too short)"); } else if (press_duration >= ${BUTTON_CLICK_MIN_LENGTH} and press_duration <= ${BUTTON_CLICK_MAX_LENGTH}) { // Short/normal click button_click_event->execute(id(button_press_button), id(click_counter)); } else if (press_duration >= ${BUTTON_LONG_PRESS_DELAY} and press_duration <= ${BUTTON_PRESS_TIMEOUT}) { button_action->execute(id(button_press_button), "long_press", 1); } else if (press_duration > ${BUTTON_PRESS_TIMEOUT}) { // Timeout or invalid - ESP_LOGW("${TAG_CORE_HW_BUTTONS}", + ESP_LOGW("${TAG_HW_BUTTONS}", "Button press cancelled or timed out after ${BUTTON_PRESS_TIMEOUT} ms"); } } else { - ESP_LOGW("${TAG_CORE_HW_BUTTONS}", "Press event timestamp not recorded yet"); + ESP_LOGW("${TAG_HW_BUTTONS}", "Press event timestamp not recorded yet"); } id(button_press_start_time) = 0; diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_leds.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_hw_leds.yaml similarity index 90% rename from ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_leds.yaml rename to ESPHome/TX-Ultimate-Easy-ESPHome_hw_leds.yaml index a345ea65..654110f8 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_leds.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_hw_leds.yaml @@ -2,7 +2,7 @@ ##### TX Ultimate Easy for ESPHome ##### ##### Repository: https://github.com/edwardtfn/TX-Ultimate-Easy ##### #################################################################################################### -##### Purpose: ESPHome Core - Hardware - LEDs ##### +##### Purpose: ESPHome - Hardware - LEDs ##### #################################################################################################### ##### Author: edwardtfn - https://github.com/edwardtfn - https://buymeacoffee.com/edwardfirmo ##### #################################################################################################### @@ -32,12 +32,12 @@ substitutions: LIGHT_ATTRS_DEFAULT: '0x64FFFFFF' # brightness=100, RGB=255,255,255 LIGHT_DUAL_ATTRS_DEFAULT: '0x64FFFFFF64FFFFFF' # Both lights: brightness=100, RGB=255,255,255 - TAG_CORE_HW_LEDS: core.hw.leds + TAG_HW_LEDS: tx_ultimate_easy.hw.leds esphome: platformio_options: build_flags: - - -D TX_ULTIMATE_EASY_CORE_HW_LEDS + - -D TX_ULTIMATE_EASY_HW_LEDS globals: # light_full with effect support @@ -601,34 +601,34 @@ script: then: - lambda: |- // Transition times - ESP_LOGCONFIG("${TAG_CORE_HW_LEDS}", "Transition times:"); - ESP_LOGCONFIG("${TAG_CORE_HW_LEDS}", " Default: ${default_transition_length}"); + ESP_LOGCONFIG("${TAG_HW_LEDS}", "Transition times:"); + ESP_LOGCONFIG("${TAG_HW_LEDS}", " Default: ${default_transition_length}"); if (${LIGHT_TRANSITION_TURN_ON} > 0) - ESP_LOGCONFIG("${TAG_CORE_HW_LEDS}", " Turning on: ${LIGHT_TRANSITION_TURN_ON}ms"); + ESP_LOGCONFIG("${TAG_HW_LEDS}", " Turning on: ${LIGHT_TRANSITION_TURN_ON}ms"); else - ESP_LOGCONFIG("${TAG_CORE_HW_LEDS}", " Turning on: Disabled"); + ESP_LOGCONFIG("${TAG_HW_LEDS}", " Turning on: Disabled"); if (${LIGHT_TRANSITION_TURN_OFF} > 0) - ESP_LOGCONFIG("${TAG_CORE_HW_LEDS}", " Turning off: ${LIGHT_TRANSITION_TURN_OFF}ms"); + ESP_LOGCONFIG("${TAG_HW_LEDS}", " Turning off: ${LIGHT_TRANSITION_TURN_OFF}ms"); else - ESP_LOGCONFIG("${TAG_CORE_HW_LEDS}", " Turning off: Disabled"); + ESP_LOGCONFIG("${TAG_HW_LEDS}", " Turning off: Disabled"); // Restore modes - ESP_LOGCONFIG("${TAG_CORE_HW_LEDS}", "LED restore modes:"); - ESP_LOGCONFIG("${TAG_CORE_HW_LEDS}", " Light - All: ${LIGHT_FULL_RESTORE_MODE}"); - ESP_LOGCONFIG("${TAG_CORE_HW_LEDS}", " Sides: ${LIGHT_SIDES_RESTORE_MODE}"); - ESP_LOGCONFIG("${TAG_CORE_HW_LEDS}", " Individual: ${LIGHT_INDIVIDUAL_RESTORE_MODE}"); + ESP_LOGCONFIG("${TAG_HW_LEDS}", "LED restore modes:"); + ESP_LOGCONFIG("${TAG_HW_LEDS}", " Light - All: ${LIGHT_FULL_RESTORE_MODE}"); + ESP_LOGCONFIG("${TAG_HW_LEDS}", " Sides: ${LIGHT_SIDES_RESTORE_MODE}"); + ESP_LOGCONFIG("${TAG_HW_LEDS}", " Individual: ${LIGHT_INDIVIDUAL_RESTORE_MODE}"); - id: !extend dump_config_list_packages then: - script.wait: dump_config - lambda: |- // Check for requirements - #if !defined(TX_ULTIMATE_EASY_CORE_COMMON) - #error "The package TX-Ultimate-Easy-ESPHome_core_common.yaml is required." + #if !defined(TX_ULTIMATE_EASY_COMMON) + #error "The package TX-Ultimate-Easy-ESPHome_common.yaml is required." #endif // Identify itself - ESP_LOGCONFIG(ESPHOME_PROJECT_NAME, " - Core - Hardware - LEDs"); + ESP_LOGCONFIG(ESPHOME_PROJECT_NAME, " - Hardware - LEDs"); - id: light_attributes_restore mode: parallel @@ -638,11 +638,11 @@ script: then: - lambda: |- if (!light_ptr) { - ESP_LOGE("${TAG_CORE_HW_LEDS}", "Invalid light pointer"); + ESP_LOGE("${TAG_HW_LEDS}", "Invalid light pointer"); return; } if (!attr_global_ptr) { - ESP_LOGE("${TAG_CORE_HW_LEDS}", "Invalid attributes pointer"); + ESP_LOGE("${TAG_HW_LEDS}", "Invalid attributes pointer"); return; } tx_ultimate_easy::LightAttributes attrs = tx_ultimate_easy::unpack_light_attributes(*attr_global_ptr); @@ -650,7 +650,7 @@ script: call.set_brightness(attrs.brightness / 100.0f); call.set_rgb(attrs.red / 255.0f, attrs.green / 255.0f, attrs.blue / 255.0f); call.perform(); - ESP_LOGI("${TAG_CORE_HW_LEDS}", "Restored light attributes: brightness=%d%%, RGB=(%d,%d,%d)", + ESP_LOGI("${TAG_HW_LEDS}", "Restored light attributes: brightness=%d%%, RGB=(%d,%d,%d)", attrs.brightness, attrs.red, attrs.green, attrs.blue); - id: light_attributes_restore_dual @@ -662,15 +662,15 @@ script: then: - lambda: |- if (!light_ptr) { - ESP_LOGE("${TAG_CORE_HW_LEDS}", "Invalid light pointer"); + ESP_LOGE("${TAG_HW_LEDS}", "Invalid light pointer"); return; } if (!attr_global_ptr) { - ESP_LOGE("${TAG_CORE_HW_LEDS}", "Invalid attributes pointer"); + ESP_LOGE("${TAG_HW_LEDS}", "Invalid attributes pointer"); return; } if (group_index != 1 && group_index != 2) { - ESP_LOGE("${TAG_CORE_HW_LEDS}", "Invalid group_index=%d (expected 1 or 2)", group_index); + ESP_LOGE("${TAG_HW_LEDS}", "Invalid group_index=%d (expected 1 or 2)", group_index); return; } auto attrs_pair = tx_ultimate_easy::unpack_dual_light_attributes(*attr_global_ptr); @@ -680,7 +680,7 @@ script: call.set_brightness(attrs.brightness / 100.0f); call.set_rgb(attrs.red / 255.0f, attrs.green / 255.0f, attrs.blue / 255.0f); call.perform(); - ESP_LOGI("${TAG_CORE_HW_LEDS}", "Restored (group=%d) attributes: brightness=%d%%, RGB=(%d,%d,%d)", + ESP_LOGI("${TAG_HW_LEDS}", "Restored (group=%d) attributes: brightness=%d%%, RGB=(%d,%d,%d)", group_index, attrs.brightness, attrs.red, attrs.green, attrs.blue); - id: light_attributes_save @@ -691,11 +691,11 @@ script: then: - lambda: |- if (!light_ptr) { - ESP_LOGE("${TAG_CORE_HW_LEDS}", "Invalid light pointer"); + ESP_LOGE("${TAG_HW_LEDS}", "Invalid light pointer"); return; } if (!attr_global_ptr) { - ESP_LOGE("${TAG_CORE_HW_LEDS}", "Invalid attributes pointer"); + ESP_LOGE("${TAG_HW_LEDS}", "Invalid attributes pointer"); return; } auto current = light_ptr->current_values; @@ -707,7 +707,7 @@ script: }; *attr_global_ptr = tx_ultimate_easy::pack_light_attributes(attrs); - ESP_LOGD("${TAG_CORE_HW_LEDS}", "Saved light attributes: brightness=%d%%, RGB=(%d,%d,%d)", + ESP_LOGD("${TAG_HW_LEDS}", "Saved light attributes: brightness=%d%%, RGB=(%d,%d,%d)", attrs.brightness, attrs.red, attrs.green, attrs.blue); - id: light_attributes_save_dual @@ -719,15 +719,15 @@ script: then: - lambda: |- if (!light_ptr) { - ESP_LOGE("${TAG_CORE_HW_LEDS}", "Invalid light pointer"); + ESP_LOGE("${TAG_HW_LEDS}", "Invalid light pointer"); return; } if (!attr_global_ptr) { - ESP_LOGE("${TAG_CORE_HW_LEDS}", "Invalid attributes pointer"); + ESP_LOGE("${TAG_HW_LEDS}", "Invalid attributes pointer"); return; } if (group_index != 1 && group_index != 2) { - ESP_LOGE("${TAG_CORE_HW_LEDS}", "Invalid group_index=%d (expected 1 or 2)", group_index); + ESP_LOGE("${TAG_HW_LEDS}", "Invalid group_index=%d (expected 1 or 2)", group_index); return; } auto current = light_ptr->current_values; @@ -761,7 +761,7 @@ script: // Store effect index (16 bits) + reserved space for future use *effect_global_ptr = effect_index & 0xFFFF; - ESP_LOGD("${TAG_CORE_HW_LEDS}", "Saved effect index: %d", effect_index); + ESP_LOGD("${TAG_HW_LEDS}", "Saved effect index: %d", effect_index); - id: light_effect_restore mode: parallel @@ -776,7 +776,7 @@ script: if (effect_index == 0) return; // No effect if (effect_index > light_ptr->get_effect_count()) { - ESP_LOGW("${TAG_CORE_HW_LEDS}", "Invalid effect index: %d (max: %d)", + ESP_LOGW("${TAG_HW_LEDS}", "Invalid effect index: %d (max: %d)", effect_index, light_ptr->get_effect_count()); return; } @@ -785,7 +785,7 @@ script: call.set_effect(effect_index); call.perform(); - ESP_LOGI("${TAG_CORE_HW_LEDS}", "Restored effect: %s (index=%d)", + ESP_LOGI("${TAG_HW_LEDS}", "Restored effect: %s (index=%d)", light_ptr->get_effect_name_by_index(effect_index).c_str(), effect_index); - id: !extend restore_from_nvs diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_relays.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_hw_relays.yaml similarity index 85% rename from ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_relays.yaml rename to ESPHome/TX-Ultimate-Easy-ESPHome_hw_relays.yaml index 8fe72877..dd5d7da0 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_relays.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_hw_relays.yaml @@ -2,7 +2,7 @@ ##### TX Ultimate Easy for ESPHome ##### ##### Repository: https://github.com/edwardtfn/TX-Ultimate-Easy ##### #################################################################################################### -##### Purpose: ESPHome - Standard - Hardware - Relays ##### +##### Purpose: ESPHome - Hardware - Relays ##### #################################################################################################### ##### Author: edwardtfn - https://github.com/edwardtfn - https://buymeacoffee.com/edwardfirmo ##### #################################################################################################### @@ -23,12 +23,12 @@ substitutions: RELAYS_EXPOSE_LEDS_TO_HA_RESTORE_MODE: ALWAYS_OFF RELAYS_SWITCH_RESTORE_MODE: ALWAYS_OFF - TAG_STD_HW_RELAYS: std.hw.relays + TAG_HW_RELAYS: tx_ultimate_easy.hw.relays esphome: platformio_options: build_flags: - - -D TX_ULTIMATE_EASY_STANDARD_HW_RELAYS + - -D TX_ULTIMATE_EASY_HW_RELAYS globals: - &global_attr_dual_light @@ -116,18 +116,14 @@ light: restore_mode: ${RELAYS_LIGHT_RESTORE_MODE} on_turn_on: then: - - if: - condition: - - switch.is_off: sw_relay_1 - then: - - switch.turn_on: sw_relay_1 + - lambda: |- + if (not sw_relay_1->state) + sw_relay_1->turn_on(); on_turn_off: then: - - if: - condition: - - switch.is_on: sw_relay_1 - then: - - switch.turn_off: sw_relay_1 + - lambda: |- + if (sw_relay_1->state) + sw_relay_1->turn_off(); - id: light_output_2 name: Light output 2 output: output_relay_2 @@ -136,18 +132,14 @@ light: restore_mode: ${RELAYS_LIGHT_RESTORE_MODE} on_turn_on: then: - - if: - condition: - - switch.is_off: sw_relay_2 - then: - - switch.turn_on: sw_relay_2 + - lambda: |- + if (not sw_relay_2->state) + sw_relay_2->turn_on(); on_turn_off: then: - - if: - condition: - - switch.is_on: sw_relay_2 - then: - - switch.turn_off: sw_relay_2 + - lambda: |- + if (sw_relay_2->state) + sw_relay_2->turn_off(); - id: light_output_3 name: Light output 3 output: output_relay_3 @@ -156,18 +148,14 @@ light: restore_mode: ${RELAYS_LIGHT_RESTORE_MODE} on_turn_on: then: - - if: - condition: - - switch.is_off: sw_relay_3 - then: - - switch.turn_on: sw_relay_3 + - lambda: |- + if (not sw_relay_3->state) + sw_relay_3->turn_on(); on_turn_off: then: - - if: - condition: - - switch.is_on: sw_relay_3 - then: - - switch.turn_off: sw_relay_3 + - lambda: |- + if (sw_relay_3->state) + sw_relay_3->turn_off(); - id: light_output_4 name: Light output 4 output: output_relay_4 @@ -176,18 +164,14 @@ light: restore_mode: ${RELAYS_LIGHT_RESTORE_MODE} on_turn_on: then: - - if: - condition: - - switch.is_off: sw_relay_4 - then: - - switch.turn_on: sw_relay_4 + - lambda: |- + if (not sw_relay_4->state) + sw_relay_4->turn_on(); on_turn_off: then: - - if: - condition: - - switch.is_on: sw_relay_4 - then: - - switch.turn_off: sw_relay_4 + - lambda: |- + if (sw_relay_4->state) + sw_relay_4->turn_off(); # These lights are used to indicate relay's statuses - &light_partition_relays @@ -815,7 +799,7 @@ script: } break; default: - ESP_LOGE("${TAG_STD_HW_RELAYS}", "Invalid gang count: %" PRIu8, id(gang_count)); + ESP_LOGE("${TAG_HW_RELAYS}", "Invalid gang count: %" PRIu8, id(gang_count)); break; } id(boot_initialization_relays_group_assignments) = true; @@ -956,38 +940,38 @@ script: std::string select_state; bool toggle_relay = false; if (api_disconnected) { - ESP_LOGW("${TAG_STD_HW_RELAYS}", "Toggle relays:"); - ESP_LOGW("${TAG_STD_HW_RELAYS}", " API state: DISCONNECTED"); - ESP_LOGW("${TAG_STD_HW_RELAYS}", " Button: %" PRIu8, button); + ESP_LOGW("${TAG_HW_RELAYS}", "Toggle relays:"); + ESP_LOGW("${TAG_HW_RELAYS}", " API state: DISCONNECTED"); + ESP_LOGW("${TAG_HW_RELAYS}", " Button: %" PRIu8, button); } else { - ESP_LOGVV("${TAG_STD_HW_RELAYS}", "Toggle relays:"); - ESP_LOGVV("${TAG_STD_HW_RELAYS}", " API state: Connected"); - ESP_LOGVV("${TAG_STD_HW_RELAYS}", " Button: %" PRIu8, button); + ESP_LOGVV("${TAG_HW_RELAYS}", "Toggle relays:"); + ESP_LOGVV("${TAG_HW_RELAYS}", " API state: Connected"); + ESP_LOGVV("${TAG_HW_RELAYS}", " Button: %" PRIu8, button); } switch (button) { case ${BUTTON_1_ID}: - select_state = sl_button_1_action->state; + select_state = sl_button_1_action->current_option(); toggle_relay = (select_state == "${BUTTON_1_ACTION_TEXT}" or (api_disconnected and select_state == "${BUTTON_1_ACTION_FAILSAFE_TEXT}")); if (toggle_relay) sw_relay_1->toggle(); break; case ${BUTTON_2_ID}: - select_state = sl_button_2_action->state; + select_state = sl_button_2_action->current_option(); toggle_relay = (select_state == "${BUTTON_2_ACTION_TEXT}" or (api_disconnected and select_state == "${BUTTON_2_ACTION_FAILSAFE_TEXT}")); if (toggle_relay) sw_relay_2->toggle(); break; case ${BUTTON_3_ID}: - select_state = sl_button_3_action->state; + select_state = sl_button_3_action->current_option(); toggle_relay = (select_state == "${BUTTON_3_ACTION_TEXT}" or (api_disconnected and select_state == "${BUTTON_3_ACTION_FAILSAFE_TEXT}")); if (toggle_relay) sw_relay_3->toggle(); break; case ${BUTTON_4_ID}: - select_state = sl_button_4_action->state; + select_state = sl_button_4_action->current_option(); toggle_relay = (select_state == "${BUTTON_4_ACTION_TEXT}" or (api_disconnected and select_state == "${BUTTON_4_ACTION_FAILSAFE_TEXT}")); if (toggle_relay) @@ -995,12 +979,12 @@ script: break; } if (toggle_relay) { - ESP_LOGI("${TAG_STD_HW_RELAYS}", "Toggle relay %" PRIu8 ": (%s)", button, select_state.c_str()); + ESP_LOGI("${TAG_HW_RELAYS}", "Toggle relay %" PRIu8 ": (%s)", button, select_state.c_str()); } else if (not select_state.empty()) { - ESP_LOGV("${TAG_STD_HW_RELAYS}", "Ignoring toggle for relay %" PRIu8 ": action is '%s'", + ESP_LOGV("${TAG_HW_RELAYS}", "Ignoring toggle for relay %" PRIu8 ": action is '%s'", button, select_state.c_str()); } else { - ESP_LOGE("${TAG_STD_HW_RELAYS}", "No button action selected for button %" PRIu8, button); + ESP_LOGE("${TAG_HW_RELAYS}", "No button action selected for button %" PRIu8, button); } - id: !extend dump_config @@ -1008,76 +992,75 @@ script: - lambda: |- std::string gang_count_plural_suffix = id(gang_count) > 1 ? "s" : ""; // Relay's modes - ESP_LOGCONFIG("${TAG_STD_HW_RELAYS}", "Relay%s mode%s:", gang_count_plural_suffix.c_str(), + ESP_LOGCONFIG("${TAG_HW_RELAYS}", "Relay%s mode%s:", gang_count_plural_suffix.c_str(), gang_count_plural_suffix.c_str()); - ESP_LOGCONFIG("${TAG_STD_HW_RELAYS}", " Relay 1: %s", sl_relay_1_mode->has_state() ? - sl_relay_1_mode->state.c_str() : "Unknown"); + ESP_LOGCONFIG("${TAG_HW_RELAYS}", " Relay 1: %s", sl_relay_1_mode->has_state() ? + sl_relay_1_mode->current_option() : "Unknown"); if (id(gang_count) >= 2) - ESP_LOGCONFIG("${TAG_STD_HW_RELAYS}", " Relay 2: %s", sl_relay_2_mode->has_state() ? - sl_relay_2_mode->state.c_str() : "Unknown"); + ESP_LOGCONFIG("${TAG_HW_RELAYS}", " Relay 2: %s", sl_relay_2_mode->has_state() ? + sl_relay_2_mode->current_option() : "Unknown"); if (id(gang_count) >= 3) - ESP_LOGCONFIG("${TAG_STD_HW_RELAYS}", " Relay 3: %s", sl_relay_3_mode->has_state() ? - sl_relay_3_mode->state.c_str() : "Unknown"); + ESP_LOGCONFIG("${TAG_HW_RELAYS}", " Relay 3: %s", sl_relay_3_mode->has_state() ? + sl_relay_3_mode->current_option() : "Unknown"); if (id(gang_count) >= 4) - ESP_LOGCONFIG("${TAG_STD_HW_RELAYS}", " Relay 4: %s", sl_relay_4_mode->has_state() ? - sl_relay_4_mode->state.c_str() : "Unknown"); + ESP_LOGCONFIG("${TAG_HW_RELAYS}", " Relay 4: %s", sl_relay_4_mode->has_state() ? + sl_relay_4_mode->current_option() : "Unknown"); // Relay's states - ESP_LOGCONFIG("${TAG_STD_HW_RELAYS}", "Relay%s state%s:", gang_count_plural_suffix.c_str(), + ESP_LOGCONFIG("${TAG_HW_RELAYS}", "Relay%s state%s:", gang_count_plural_suffix.c_str(), gang_count_plural_suffix.c_str()); - ESP_LOGCONFIG("${TAG_STD_HW_RELAYS}", " Relay 1: %s", sw_relay_1->state ? "ON" : "OFF"); + ESP_LOGCONFIG("${TAG_HW_RELAYS}", " Relay 1: %s", sw_relay_1->state ? "ON" : "OFF"); if (id(gang_count) >= 2) - ESP_LOGCONFIG("${TAG_STD_HW_RELAYS}", " Relay 2: %s", sw_relay_2->state ? "ON" : "OFF"); + ESP_LOGCONFIG("${TAG_HW_RELAYS}", " Relay 2: %s", sw_relay_2->state ? "ON" : "OFF"); if (id(gang_count) >= 3) - ESP_LOGCONFIG("${TAG_STD_HW_RELAYS}", " Relay 3: %s", sw_relay_3->state ? "ON" : "OFF"); + ESP_LOGCONFIG("${TAG_HW_RELAYS}", " Relay 3: %s", sw_relay_3->state ? "ON" : "OFF"); if (id(gang_count) >= 4) - ESP_LOGCONFIG("${TAG_STD_HW_RELAYS}", " Relay 4: %s", sw_relay_4->state ? "ON" : "OFF"); - ESP_LOGCONFIG("${TAG_STD_HW_RELAYS}", "Expose Relay's LEDs to Home Assistant: %s", + ESP_LOGCONFIG("${TAG_HW_RELAYS}", " Relay 4: %s", sw_relay_4->state ? "ON" : "OFF"); + ESP_LOGCONFIG("${TAG_HW_RELAYS}", "Expose Relay's LEDs to Home Assistant: %s", YESNO(sw_expose_relays_leds_to_ha->state)); // Boot initialization statuses - ESP_LOGCONFIG("${TAG_STD_HW_RELAYS}", "Boot initialization flags:"); - ESP_LOGCONFIG("${TAG_STD_HW_RELAYS}", " Overall: %s", YESNO(id(boot_initialization_relays))); - ESP_LOGCONFIG("${TAG_STD_HW_RELAYS}", " Groups: %s", + ESP_LOGCONFIG("${TAG_HW_RELAYS}", "Boot initialization flags:"); + ESP_LOGCONFIG("${TAG_HW_RELAYS}", " Overall: %s", YESNO(id(boot_initialization_relays))); + ESP_LOGCONFIG("${TAG_HW_RELAYS}", " Groups: %s", YESNO(id(boot_initialization_relays_group_assignments))); - ESP_LOGCONFIG("${TAG_STD_HW_RELAYS}", " Light modes: %s", YESNO(id(boot_initialization_relays_light_modes))); - ESP_LOGCONFIG("${TAG_STD_HW_RELAYS}", " Relay modes: %s", YESNO(id(boot_initialization_relays_relay_modes))); - ESP_LOGCONFIG("${TAG_STD_HW_RELAYS}", " Status LEDs: %s", YESNO(id(boot_initialization_relays_relay_leds))); + ESP_LOGCONFIG("${TAG_HW_RELAYS}", " Light modes: %s", YESNO(id(boot_initialization_relays_light_modes))); + ESP_LOGCONFIG("${TAG_HW_RELAYS}", " Relay modes: %s", YESNO(id(boot_initialization_relays_relay_modes))); + ESP_LOGCONFIG("${TAG_HW_RELAYS}", " Status LEDs: %s", YESNO(id(boot_initialization_relays_relay_leds))); // Relay's LEDs modes - ESP_LOGCONFIG("${TAG_STD_HW_RELAYS}", "Relay%s LEDs mode%s:", gang_count_plural_suffix.c_str(), + ESP_LOGCONFIG("${TAG_HW_RELAYS}", "Relay%s LEDs mode%s:", gang_count_plural_suffix.c_str(), gang_count_plural_suffix.c_str()); - ESP_LOGCONFIG("${TAG_STD_HW_RELAYS}", " Relay 1: %s", id(is_us_model) ? - sl_relay_1_light_mode_us->state.c_str() : - sl_relay_1_light_mode_eu->state.c_str()); + ESP_LOGCONFIG("${TAG_HW_RELAYS}", " Relay 1: %s", id(is_us_model) ? + sl_relay_1_light_mode_us->current_option() : + sl_relay_1_light_mode_eu->current_option()); if (id(gang_count) >= 2) - ESP_LOGCONFIG("${TAG_STD_HW_RELAYS}", " Relay 2: %s", id(is_us_model) ? - sl_relay_2_light_mode_us->state.c_str() : - sl_relay_2_light_mode_eu->state.c_str()); + ESP_LOGCONFIG("${TAG_HW_RELAYS}", " Relay 2: %s", id(is_us_model) ? + sl_relay_2_light_mode_us->current_option() : + sl_relay_2_light_mode_eu->current_option()); if (id(gang_count) >= 3) - ESP_LOGCONFIG("${TAG_STD_HW_RELAYS}", " Relay 3: %s", id(is_us_model) ? - sl_relay_3_light_mode_us->state.c_str() : - sl_relay_3_light_mode_eu->state.c_str()); + ESP_LOGCONFIG("${TAG_HW_RELAYS}", " Relay 3: %s", id(is_us_model) ? + sl_relay_3_light_mode_us->current_option() : + sl_relay_3_light_mode_eu->current_option()); if (id(gang_count) >= 4) - ESP_LOGCONFIG("${TAG_STD_HW_RELAYS}", " Relay 4: %s", id(is_us_model) ? - sl_relay_4_light_mode_us->state.c_str() : - sl_relay_4_light_mode_eu->state.c_str()); + ESP_LOGCONFIG("${TAG_HW_RELAYS}", " Relay 4: %s", id(is_us_model) ? + sl_relay_4_light_mode_us->current_option() : + sl_relay_4_light_mode_eu->current_option()); - id: !extend dump_config_list_packages then: - script.wait: dump_config - lambda: |- // Check for requirements - #if !defined(TX_ULTIMATE_EASY_CORE_COMMON) - #error "The package TX-Ultimate-Easy-ESPHome_core_common.yaml is required." + #if !defined(TX_ULTIMATE_EASY_COMMON) + #error "The package TX-Ultimate-Easy-ESPHome_common.yaml is required." #endif - #if !defined(TX_ULTIMATE_EASY_CORE_HW_LEDS) - #error "The package TX-Ultimate-Easy-ESPHome_core_hw_leds.yaml is required." - #endif // TX_ULTIMATE_EASY_CORE_HW_LEDS - + #if !defined(TX_ULTIMATE_EASY_HW_LEDS) + #error "The package TX-Ultimate-Easy-ESPHome_hw_leds.yaml is required." + #endif // TX_ULTIMATE_EASY_HW_LEDS // Identify itself - ESP_LOGCONFIG(ESPHOME_PROJECT_NAME, " - Standard - Hardware - Relays"); + ESP_LOGCONFIG(ESPHOME_PROJECT_NAME, " - Hardware - Relays"); - id: light_set_state mode: parallel @@ -1101,11 +1084,11 @@ script: switch (light_group) { case 1: if (light_index >= id(gb_lights_1).size()) { - ESP_LOGE("${TAG_STD_HW_RELAYS}", "Invalid set with %s light for Relay %" PRIu8, light_mode_group_1.c_str(), light_index+1); + ESP_LOGE("${TAG_HW_RELAYS}", "Invalid set with %s light for Relay %" PRIu8, light_mode_group_1.c_str(), light_index+1); return; } if (state and !id(gb_lights_1)[light_index]->current_values.is_on()) { - ESP_LOGI("${TAG_STD_HW_RELAYS}", "Turn-on %s light for Relay %" PRIu8, light_mode_group_1.c_str(), light_index+1); + ESP_LOGI("${TAG_HW_RELAYS}", "Turn-on %s light for Relay %" PRIu8, light_mode_group_1.c_str(), light_index+1); auto call = id(gb_lights_1)[light_index]->turn_on(); if (LIGHT_TRANSITION_TURN_ON > 0) call.set_transition_length(LIGHT_TRANSITION_TURN_ON); // in ms @@ -1113,7 +1096,7 @@ script: call.set_brightness(LIGHT_BRIGHTNESS_TURN_ON / 100.0f); call.perform(); } else if (!state and id(gb_lights_1)[light_index]->current_values.is_on()) { - ESP_LOGI("${TAG_STD_HW_RELAYS}", "Turn-off %s light for Relay %" PRIu8, light_mode_group_1.c_str(), light_index+1); + ESP_LOGI("${TAG_HW_RELAYS}", "Turn-off %s light for Relay %" PRIu8, light_mode_group_1.c_str(), light_index+1); auto call = id(gb_lights_1)[light_index]->turn_off(); if (LIGHT_TRANSITION_TURN_OFF > 0) call.set_transition_length(LIGHT_TRANSITION_TURN_OFF); // in ms @@ -1122,12 +1105,12 @@ script: break; case 2: if (light_index >= id(gb_lights_2).size()) { - ESP_LOGE("${TAG_STD_HW_RELAYS}", + ESP_LOGE("${TAG_HW_RELAYS}", "Invalid set with %s light for Relay %" PRIu8, light_mode_group_2.c_str(), light_index+1); return; } if (state and !id(gb_lights_2)[light_index]->current_values.is_on()) { - ESP_LOGI("${TAG_STD_HW_RELAYS}", + ESP_LOGI("${TAG_HW_RELAYS}", "Turn-on %s light for Relay %" PRIu8, light_mode_group_2.c_str(), light_index+1); auto call = id(gb_lights_2)[light_index]->turn_on(); if (LIGHT_TRANSITION_TURN_ON > 0) @@ -1136,7 +1119,7 @@ script: call.set_brightness(LIGHT_BRIGHTNESS_TURN_ON / 100.0f); call.perform(); } else if (!state and id(gb_lights_2)[light_index]->current_values.is_on()) { - ESP_LOGI("${TAG_STD_HW_RELAYS}", + ESP_LOGI("${TAG_HW_RELAYS}", "Turn-off %s light for Relay %" PRIu8, light_mode_group_2.c_str(), light_index+1); auto call = id(gb_lights_2)[light_index]->turn_off(); if (LIGHT_TRANSITION_TURN_OFF > 0) @@ -1145,7 +1128,7 @@ script: } break; default: - ESP_LOGE("${TAG_STD_HW_RELAYS}", "Invalid light_group=%" PRIu8 " (expected 1 or 2)", light_group); + ESP_LOGE("${TAG_HW_RELAYS}", "Invalid light_group=%" PRIu8 " (expected 1 or 2)", light_group); break; } @@ -1193,28 +1176,17 @@ script: id: sl_relay_4_light_mode_eu index: !lambda return std::min((uint8_t)((id(relay_light_modes_packed) >> 12) & 0x0F), (uint8_t)3); - # Switch states - - switch.control: - id: sw_expose_relays_leds_to_ha - state: !lambda return (id(relay_switches_packed) & 0x01); - - switch.control: - id: sw_relay_1 - state: !lambda return (id(relay_switches_packed) & 0x02); - - switch.control: - id: sw_relay_2 - state: !lambda return (id(relay_switches_packed) & 0x04); - - switch.control: - id: sw_relay_3 - state: !lambda return (id(relay_switches_packed) & 0x08); - - switch.control: - id: sw_relay_4 - state: !lambda return (id(relay_switches_packed) & 0x10); - - # update lights based on new relay statuses (catch up, as this should be done when each relay is updated) - - script.execute: show_relay_status - - # Light attributes restoration - lambda: |- + // Switch states + sw_expose_relays_leds_to_ha->control(id(relay_switches_packed) & 0x01); + sw_relay_1->control(id(relay_switches_packed) & 0x02); + sw_relay_2->control(id(relay_switches_packed) & 0x04); + sw_relay_3->control(id(relay_switches_packed) & 0x08); + sw_relay_4->control(id(relay_switches_packed) & 0x10); + + // update lights based on new relay statuses (catch up, as this should be done when each relay is updated) + show_relay_status->execute(); + // Restore all light attributes based on current model and gang count switch (id(gang_count)) { case 1: // 1-Gang @@ -1285,7 +1257,7 @@ script: - script.wait: boot_initialize_relays - lambda: |- if (not id(boot_initialization_relays)) { - ESP_LOGW("${TAG_STD_HW_RELAYS}", "Relays not initialized yet"); + ESP_LOGW("${TAG_HW_RELAYS}", "Relays not initialized yet"); if (not boot_initialize_relays->is_running()) boot_initialize_relays->execute(); return; @@ -1305,31 +1277,31 @@ script: case 0: relay_state = id(sw_relay_1).state; light_mode = id(is_us_model) - ? id(sl_relay_1_light_mode_us)->state - : id(sl_relay_1_light_mode_eu)->state; + ? sl_relay_1_light_mode_us->current_option() + : sl_relay_1_light_mode_eu->current_option(); break; case 1: relay_state = id(sw_relay_2).state; light_mode = id(is_us_model) - ? id(sl_relay_2_light_mode_us)->state - : id(sl_relay_2_light_mode_eu)->state; + ? sl_relay_2_light_mode_us->current_option() + : sl_relay_2_light_mode_eu->current_option(); break; case 2: relay_state = id(sw_relay_3).state; light_mode = id(is_us_model) - ? id(sl_relay_3_light_mode_us)->state - : id(sl_relay_3_light_mode_eu)->state; + ? sl_relay_3_light_mode_us->current_option() + : sl_relay_3_light_mode_eu->current_option(); break; case 3: relay_state = id(sw_relay_4).state; light_mode = id(is_us_model) - ? id(sl_relay_4_light_mode_us)->state - : id(sl_relay_4_light_mode_eu)->state; + ? sl_relay_4_light_mode_us->current_option() + : sl_relay_4_light_mode_eu->current_option(); break; } - ESP_LOGV("${TAG_STD_HW_RELAYS}", "Relay %" PRIu8 " is %s", i + 1, relay_state ? "ON" : "OFF"); - ESP_LOGV("${TAG_STD_HW_RELAYS}", "Light Mode for Relay %" PRIu8 ": %s", i + 1, light_mode.c_str()); + ESP_LOGV("${TAG_HW_RELAYS}", "Relay %" PRIu8 " is %s", i + 1, relay_state ? "ON" : "OFF"); + ESP_LOGV("${TAG_HW_RELAYS}", "Light Mode for Relay %" PRIu8 ": %s", i + 1, light_mode.c_str()); // Use light_set_state for light updates if (light_mode != "${LIGHT_MODE_DISABLED_TEXT}") { @@ -1379,13 +1351,13 @@ select: if (previous_mode != "${LIGHT_MODE_DISABLED_TEXT}" && current_mode == "${LIGHT_MODE_DISABLED_TEXT}") { // Transitioning TO Disabled - turn off lights - ESP_LOGI("${TAG_STD_HW_RELAYS}", + ESP_LOGI("${TAG_HW_RELAYS}", "Relay 1 light mode changed to ${LIGHT_MODE_DISABLED_TEXT} - turning off lights"); id(light_set_state)->execute(1, 0, false); // Group 1, relay index 0 id(light_set_state)->execute(2, 0, false); // Group 2, relay index 0 } else if (previous_mode == "${LIGHT_MODE_DISABLED_TEXT}" && current_mode != "${LIGHT_MODE_DISABLED_TEXT}") { // Transitioning FROM Disabled - update lights based on relay state - ESP_LOGI("${TAG_STD_HW_RELAYS}", + ESP_LOGI("${TAG_HW_RELAYS}", "Relay 1 light mode changed from ${LIGHT_MODE_DISABLED_TEXT} - updating lights"); bool relay_state = id(sw_relay_1).state; if (current_mode == "${LIGHT_MODE_BOTTOM_TEXT}" || current_mode == "${LIGHT_MODE_BOTH_TEXT}") { @@ -1434,13 +1406,13 @@ select: if (previous_mode != "${LIGHT_MODE_DISABLED_TEXT}" && current_mode == "${LIGHT_MODE_DISABLED_TEXT}") { // Transitioning TO Disabled - turn off lights - ESP_LOGI("${TAG_STD_HW_RELAYS}", + ESP_LOGI("${TAG_HW_RELAYS}", "Relay 1 light mode changed to ${LIGHT_MODE_DISABLED_TEXT} - turning off lights"); id(light_set_state)->execute(1, 0, false); // Group 1, relay index 0 id(light_set_state)->execute(2, 0, false); // Group 2, relay index 0 } else if (previous_mode == "${LIGHT_MODE_DISABLED_TEXT}" && current_mode != "${LIGHT_MODE_DISABLED_TEXT}") { // Transitioning FROM Disabled - update lights based on relay state - ESP_LOGI("${TAG_STD_HW_RELAYS}", + ESP_LOGI("${TAG_HW_RELAYS}", "Relay 1 light mode changed from ${LIGHT_MODE_DISABLED_TEXT} - updating lights"); bool relay_state = id(sw_relay_1).state; if (current_mode == "${LIGHT_MODE_LEFT_TEXT}" || current_mode == "${LIGHT_MODE_BOTH_TEXT}") { @@ -1469,10 +1441,8 @@ select: icon: mdi:dip-switch on_value: then: - - binary_sensor.template.publish: - id: bs_pending_restart - state: true - lambda: |- + bs_pending_restart->publish_state(true); id(relay_modes_packed) = (id(relay_modes_packed) & ~(0x0F << 0)) | ((id(sl_relay_1_mode).active_index().value_or(0) & 0x0F) << 0); @@ -1498,13 +1468,13 @@ select: if (previous_mode != "${LIGHT_MODE_DISABLED_TEXT}" && current_mode == "${LIGHT_MODE_DISABLED_TEXT}") { // Transitioning TO Disabled - turn off lights - ESP_LOGI("${TAG_STD_HW_RELAYS}", + ESP_LOGI("${TAG_HW_RELAYS}", "Relay 2 light mode changed to ${LIGHT_MODE_DISABLED_TEXT} - turning off lights"); id(light_set_state)->execute(1, 1, false); // Group 1, relay index 1 id(light_set_state)->execute(2, 1, false); // Group 2, relay index 1 } else if (previous_mode == "${LIGHT_MODE_DISABLED_TEXT}" && current_mode != "${LIGHT_MODE_DISABLED_TEXT}") { // Transitioning FROM Disabled - update lights based on relay state - ESP_LOGI("${TAG_STD_HW_RELAYS}", + ESP_LOGI("${TAG_HW_RELAYS}", "Relay 2 light mode changed from ${LIGHT_MODE_DISABLED_TEXT} - updating lights"); bool relay_state = id(sw_relay_2).state; if (current_mode == "${LIGHT_MODE_BOTTOM_TEXT}" || current_mode == "${LIGHT_MODE_BOTH_TEXT}") { @@ -1539,13 +1509,13 @@ select: if (previous_mode != "${LIGHT_MODE_DISABLED_TEXT}" && current_mode == "${LIGHT_MODE_DISABLED_TEXT}") { // Transitioning TO Disabled - turn off lights - ESP_LOGI("${TAG_STD_HW_RELAYS}", + ESP_LOGI("${TAG_HW_RELAYS}", "Relay 2 light mode changed to ${LIGHT_MODE_DISABLED_TEXT} - turning off lights"); id(light_set_state)->execute(1, 1, false); // Group 1, relay index 1 id(light_set_state)->execute(2, 1, false); // Group 2, relay index 1 } else if (previous_mode == "${LIGHT_MODE_DISABLED_TEXT}" && current_mode != "${LIGHT_MODE_DISABLED_TEXT}") { // Transitioning FROM Disabled - update lights based on relay state - ESP_LOGI("${TAG_STD_HW_RELAYS}", + ESP_LOGI("${TAG_HW_RELAYS}", "Relay 2 light mode changed from ${LIGHT_MODE_DISABLED_TEXT} - updating lights"); bool relay_state = id(sw_relay_2).state; if (current_mode == "${LIGHT_MODE_LEFT_TEXT}" || current_mode == "${LIGHT_MODE_BOTH_TEXT}") { @@ -1574,10 +1544,8 @@ select: icon: mdi:dip-switch on_value: then: - - binary_sensor.template.publish: - id: bs_pending_restart - state: true - lambda: |- + bs_pending_restart->publish_state(true); id(relay_modes_packed) = (id(relay_modes_packed) & ~(0x0F << 4)) | ((id(sl_relay_2_mode).active_index().value_or(0) & 0x0F) << 4); @@ -1603,13 +1571,13 @@ select: if (previous_mode != "${LIGHT_MODE_DISABLED_TEXT}" && current_mode == "${LIGHT_MODE_DISABLED_TEXT}") { // Transitioning TO Disabled - turn off lights - ESP_LOGI("${TAG_STD_HW_RELAYS}", + ESP_LOGI("${TAG_HW_RELAYS}", "Relay 3 light mode changed to ${LIGHT_MODE_DISABLED_TEXT} - turning off lights"); id(light_set_state)->execute(1, 2, false); // Group 1, relay index 2 id(light_set_state)->execute(2, 2, false); // Group 2, relay index 2 } else if (previous_mode == "${LIGHT_MODE_DISABLED_TEXT}" && current_mode != "${LIGHT_MODE_DISABLED_TEXT}") { // Transitioning FROM Disabled - update lights based on relay state - ESP_LOGI("${TAG_STD_HW_RELAYS}", + ESP_LOGI("${TAG_HW_RELAYS}", "Relay 3 light mode changed from ${LIGHT_MODE_DISABLED_TEXT} - updating lights"); bool relay_state = id(sw_relay_3).state; if (current_mode == "${LIGHT_MODE_BOTTOM_TEXT}" || current_mode == "${LIGHT_MODE_BOTH_TEXT}") { @@ -1644,13 +1612,13 @@ select: if (previous_mode != "${LIGHT_MODE_DISABLED_TEXT}" && current_mode == "${LIGHT_MODE_DISABLED_TEXT}") { // Transitioning TO Disabled - turn off lights - ESP_LOGI("${TAG_STD_HW_RELAYS}", + ESP_LOGI("${TAG_HW_RELAYS}", "Relay 3 light mode changed to ${LIGHT_MODE_DISABLED_TEXT} - turning off lights"); id(light_set_state)->execute(1, 2, false); // Group 1, relay index 2 id(light_set_state)->execute(2, 2, false); // Group 2, relay index 2 } else if (previous_mode == "${LIGHT_MODE_DISABLED_TEXT}" && current_mode != "${LIGHT_MODE_DISABLED_TEXT}") { // Transitioning FROM Disabled - update lights based on relay state - ESP_LOGI("${TAG_STD_HW_RELAYS}", + ESP_LOGI("${TAG_HW_RELAYS}", "Relay 3 light mode changed from ${LIGHT_MODE_DISABLED_TEXT} - updating lights"); bool relay_state = id(sw_relay_3).state; if (current_mode == "${LIGHT_MODE_LEFT_TEXT}" || current_mode == "${LIGHT_MODE_BOTH_TEXT}") { @@ -1679,10 +1647,8 @@ select: icon: mdi:dip-switch on_value: then: - - binary_sensor.template.publish: - id: bs_pending_restart - state: true - lambda: |- + bs_pending_restart->publish_state(true); id(relay_modes_packed) = (id(relay_modes_packed) & ~(0x0F << 8)) | ((id(sl_relay_3_mode).active_index().value_or(0) & 0x0F) << 8); @@ -1708,12 +1674,12 @@ select: if (previous_mode != "${LIGHT_MODE_DISABLED_TEXT}" && current_mode == "${LIGHT_MODE_DISABLED_TEXT}") { // Transitioning TO Disabled - turn off lights - ESP_LOGI("${TAG_STD_HW_RELAYS}", "Relay 4 light mode changed to ${LIGHT_MODE_DISABLED_TEXT} - turning off lights"); + ESP_LOGI("${TAG_HW_RELAYS}", "Relay 4 light mode changed to ${LIGHT_MODE_DISABLED_TEXT} - turning off lights"); id(light_set_state)->execute(1, 3, false); // Group 1, relay index 3 id(light_set_state)->execute(2, 3, false); // Group 2, relay index 3 } else if (previous_mode == "${LIGHT_MODE_DISABLED_TEXT}" && current_mode != "${LIGHT_MODE_DISABLED_TEXT}") { // Transitioning FROM Disabled - update lights based on relay state - ESP_LOGI("${TAG_STD_HW_RELAYS}", "Relay 4 light mode changed from ${LIGHT_MODE_DISABLED_TEXT} - updating lights"); + ESP_LOGI("${TAG_HW_RELAYS}", "Relay 4 light mode changed from ${LIGHT_MODE_DISABLED_TEXT} - updating lights"); bool relay_state = id(sw_relay_4).state; if (current_mode == "${LIGHT_MODE_BOTTOM_TEXT}" || current_mode == "${LIGHT_MODE_BOTH_TEXT}") { id(light_set_state)->execute(1, 3, relay_state); @@ -1747,12 +1713,12 @@ select: if (previous_mode != "${LIGHT_MODE_DISABLED_TEXT}" && current_mode == "${LIGHT_MODE_DISABLED_TEXT}") { // Transitioning TO Disabled - turn off lights - ESP_LOGI("${TAG_STD_HW_RELAYS}", "Relay 4 light mode changed to ${LIGHT_MODE_DISABLED_TEXT} - turning off lights"); + ESP_LOGI("${TAG_HW_RELAYS}", "Relay 4 light mode changed to ${LIGHT_MODE_DISABLED_TEXT} - turning off lights"); id(light_set_state)->execute(1, 3, false); // Group 1, relay index 3 id(light_set_state)->execute(2, 3, false); // Group 2, relay index 3 } else if (previous_mode == "${LIGHT_MODE_DISABLED_TEXT}" && current_mode != "${LIGHT_MODE_DISABLED_TEXT}") { // Transitioning FROM Disabled - update lights based on relay state - ESP_LOGI("${TAG_STD_HW_RELAYS}", "Relay 4 light mode changed from ${LIGHT_MODE_DISABLED_TEXT} - updating lights"); + ESP_LOGI("${TAG_HW_RELAYS}", "Relay 4 light mode changed from ${LIGHT_MODE_DISABLED_TEXT} - updating lights"); bool relay_state = id(sw_relay_4).state; if (current_mode == "${LIGHT_MODE_LEFT_TEXT}" || current_mode == "${LIGHT_MODE_BOTH_TEXT}") { id(light_set_state)->execute(1, 3, relay_state); @@ -1780,10 +1746,8 @@ select: icon: mdi:dip-switch on_value: then: - - binary_sensor.template.publish: - id: bs_pending_restart - state: true - lambda: |- + bs_pending_restart->publish_state(true); id(relay_modes_packed) = (id(relay_modes_packed) & ~(0x0F << 12)) | ((id(sl_relay_4_mode).active_index().value_or(0) & 0x0F) << 12); @@ -1797,16 +1761,12 @@ switch: entity_category: config on_state: then: - - binary_sensor.template.publish: - id: bs_pending_restart - state: true - - if: - condition: - - lambda: return x; // Turned on? - then: - - lambda: id(relay_switches_packed) |= 0x01; // Set bit 0 - else: - - lambda: id(relay_switches_packed) &= ~0x01; // Clear bit 0 + - lambda: |- + bs_pending_restart->publish_state(true); + if (x) // Turned on? + id(relay_switches_packed) |= 0x01; // Set bit 0 + else + id(relay_switches_packed) &= ~0x01; // Clear bit 0 - id: sw_relay_1 name: Relay 1 @@ -1816,23 +1776,14 @@ switch: internal: true on_state: then: - - script.execute: show_relay_status - on_turn_on: - then: - - if: - condition: - - light.is_off: light_output_1 - then: - light.turn_on: light_output_1 - - lambda: id(relay_switches_packed) |= 0x02; // Set bit 1 - on_turn_off: - then: - - if: - condition: - - light.is_on: light_output_1 - then: - - light.turn_off: light_output_1 - - lambda: id(relay_switches_packed) &= ~0x02; // Clear bit 1 + - lambda: |- + show_relay_status->execute(); + if (light_output_1->current_values.is_on() != x) + light_output_1->toggle(); + if (x) // Turned on? + id(relay_switches_packed) |= 0x02; // Set bit 1 + else + id(relay_switches_packed) &= ~0x02; // Clear bit 1 - id: sw_relay_2 name: Relay 2 output: output_relay_2 @@ -1841,23 +1792,14 @@ switch: internal: true on_state: then: - - script.execute: show_relay_status - on_turn_on: - then: - - if: - condition: - - light.is_off: light_output_2 - then: - light.turn_on: light_output_2 - - lambda: id(relay_switches_packed) |= 0x04; // Set bit 2 - on_turn_off: - then: - - if: - condition: - - light.is_on: light_output_2 - then: - - light.turn_off: light_output_2 - - lambda: id(relay_switches_packed) &= ~0x04; // Clear bit 2 + - lambda: |- + show_relay_status->execute(); + if (light_output_2->current_values.is_on() != x) + light_output_2->toggle(); + if (x) // Turned on? + id(relay_switches_packed) |= 0x04; // Set bit 2 + else + id(relay_switches_packed) &= ~0x04; // Clear bit 2 - id: sw_relay_3 name: Relay 3 output: output_relay_3 @@ -1866,23 +1808,14 @@ switch: internal: true on_state: then: - - script.execute: show_relay_status - on_turn_on: - then: - - if: - condition: - - light.is_off: light_output_3 - then: - - light.turn_on: light_output_3 - - lambda: id(relay_switches_packed) |= 0x08; // Set bit 3 - on_turn_off: - then: - - if: - condition: - - light.is_on: light_output_3 - then: - - light.turn_off: light_output_3 - - lambda: id(relay_switches_packed) &= ~0x08; // Clear bit 3 + - lambda: |- + show_relay_status->execute(); + if (light_output_3->current_values.is_on() != x) + light_output_3->toggle(); + if (x) // Turned on? + id(relay_switches_packed) |= 0x08; // Set bit 3 + else + id(relay_switches_packed) &= ~0x08; // Clear bit 3 - id: sw_relay_4 name: Relay 4 output: output_relay_4 @@ -1891,22 +1824,12 @@ switch: internal: true on_state: then: - - script.execute: show_relay_status - on_turn_on: - then: - - if: - condition: - - light.is_off: light_output_4 - then: - - light.turn_on: light_output_4 - - lambda: id(relay_switches_packed) |= 0x10; // Set bit 4 - on_turn_off: - then: - - if: - condition: - - light.is_on: light_output_4 - then: - - light.turn_off: light_output_4 - - lambda: id(relay_switches_packed) &= ~0x10; // Clear bit 4 - + - lambda: |- + show_relay_status->execute(); + if (light_output_4->current_values.is_on() != x) + light_output_4->toggle(); + if (x) // Turned on? + id(relay_switches_packed) |= 0x10; // Set bit 4 + else + id(relay_switches_packed) &= ~0x10; // Clear bit 4 ... diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_speaker.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_hw_speaker.yaml similarity index 84% rename from ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_speaker.yaml rename to ESPHome/TX-Ultimate-Easy-ESPHome_hw_speaker.yaml index 3cd86786..872827bd 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_speaker.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_hw_speaker.yaml @@ -2,7 +2,7 @@ ##### TX Ultimate Easy for ESPHome ##### ##### Repository: https://github.com/edwardtfn/TX-Ultimate-Easy ##### #################################################################################################### -##### Purpose: ESPHome - Standard - Hardware - Speaker ##### +##### Purpose: ESPHome - Hardware - Speaker ##### #################################################################################################### ##### Author: edwardtfn - https://github.com/edwardtfn - https://buymeacoffee.com/edwardfirmo ##### #################################################################################################### @@ -16,10 +16,10 @@ substitutions: # d=32 (32nd note), o=5 (octave 5), b=100 (tempo 100) tone_volume_change: "scale_up:d=32,o=5,b=100:c,c#,d#,e,f#,g#,a#,b" # Use "none" to disable sound - TAG_STD_HW_SPEAKER: std.hw.speaker + TAG_HW_SPEAKER: tx_ultimate_easy.hw.speaker packages: - standard_hw_audio: !include TX-Ultimate-Easy-ESPHome_standard_hw_audio.yaml + hw_audio: !include TX-Ultimate-Easy-ESPHome_hw_audio.yaml api: actions: @@ -33,14 +33,14 @@ api: - lambda: |- rtttl_speaker->stop(); if (speaker_volume->state > 0) { - ESP_LOGI("${TAG_STD_HW_SPEAKER}", "Play tone: '%s'", tone.c_str()); + ESP_LOGI("${TAG_HW_SPEAKER}", "Play tone: '%s'", tone.c_str()); rtttl_speaker->play(tone.c_str()); } esphome: platformio_options: build_flags: - - -D TX_ULTIMATE_EASY_STANDARD_HW_SPEAKER + - -D TX_ULTIMATE_EASY_HW_SPEAKER number: - id: speaker_volume @@ -59,10 +59,8 @@ number: optimistic: true set_action: then: - - speaker.volume_set: - id: speaker_embedded - volume: !lambda return x/100.0f; - lambda: |- + speaker_embedded->set_volume(x/100.0f); static const std::string tone_volume_change = "${tone_volume_change}"; // Play sound if tone_volume_change is not "none" if (x > 0 and !tone_volume_change.empty() and tone_volume_change != "none") @@ -78,15 +76,15 @@ script: - script.wait: dump_config - lambda: |- // Check for requirements - #if !defined(TX_ULTIMATE_EASY_CORE_COMMON) - #error "The package TX-Ultimate-Easy-ESPHome_core_common.yaml is required." + #if !defined(TX_ULTIMATE_EASY_COMMON) + #error "The package TX-Ultimate-Easy-ESPHome_common.yaml is required." #endif - #if !defined(TX_ULTIMATE_EASY_STANDARD_HW_AUDIO) - #error "The package TX-Ultimate-Easy-ESPHome_standard_hw_audio.yaml is required." + #if !defined(TX_ULTIMATE_EASY_HW_AUDIO) + #error "The package TX-Ultimate-Easy-ESPHome_hw_audio.yaml is required." #endif // Identify itself - ESP_LOGCONFIG(ESPHOME_PROJECT_NAME, " - Standard - Hardware - Speaker"); + ESP_LOGCONFIG(ESPHOME_PROJECT_NAME, " - Hardware - Speaker"); - id: speaker_play_click then: @@ -131,8 +129,9 @@ script: mode: restart then: - lambda: |- - if (sl_touch_speaker_feedback->state != "Disabled") + if (strcmp(sl_touch_speaker_feedback->current_option(), "Disabled") != 0) { speaker_play_click->execute(); + } - id: !extend touch_on_press then: @@ -142,8 +141,10 @@ script: mode: restart then: - lambda: |- - if (sl_touch_speaker_feedback->state == "On press" or sl_touch_speaker_feedback->state == "Always") + if (strcmp(sl_touch_speaker_feedback->current_option(), "On press") == 0 or + strcmp(sl_touch_speaker_feedback->current_option(), "Always") == 0) { speaker_play_click->execute(); + } - id: !extend touch_on_release then: @@ -153,8 +154,10 @@ script: mode: restart then: - lambda: |- - if (sl_touch_speaker_feedback->state == "On release" or sl_touch_speaker_feedback->state == "Always") + if (strcmp(sl_touch_speaker_feedback->current_option(), "On release") == 0 or + strcmp(sl_touch_speaker_feedback->current_option(), "Always") == 0) { speaker_play_click->execute(); + } select: - id: sl_touch_speaker_feedback diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_touch.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_hw_touch.yaml similarity index 76% rename from ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_touch.yaml rename to ESPHome/TX-Ultimate-Easy-ESPHome_hw_touch.yaml index 5d1d7a2b..1309ac44 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_touch.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_hw_touch.yaml @@ -2,7 +2,7 @@ ##### TX Ultimate Easy for ESPHome ##### ##### Repository: https://github.com/edwardtfn/TX-Ultimate-Easy ##### #################################################################################################### -##### Purpose: ESPHome Core - Hardware - Touch panel ##### +##### Purpose: ESPHome - Hardware - Touch panel ##### #################################################################################################### ##### Author: edwardtfn - https://github.com/edwardtfn - https://buymeacoffee.com/edwardfirmo ##### #################################################################################################### @@ -14,7 +14,7 @@ substitutions: TOUCH_POSITION_MAX_VALUE: '10' # Maximum touch position value returned by the touch pad via uart - TAG_CORE_HW_TOUCH: core.hw.touch + TAG_HW_TOUCH: tx_ultimate_easy.hw.touch binary_sensor: - &bs_button_event_template @@ -203,7 +203,7 @@ binary_sensor: esphome: platformio_options: build_flags: - - -D TX_ULTIMATE_EASY_CORE_HW_TOUCH + - -D TX_ULTIMATE_EASY_HW_TOUCH number: - id: nr_touch_duration @@ -229,8 +229,9 @@ script: - id: boot_initialize_touch mode: restart then: - - script.execute: boot_initialize_touch_format - - script.execute: boot_initialize_touch_gang + - lambda: |- + boot_initialize_touch_format->execute(); + boot_initialize_touch_gang->execute(); - id: boot_initialize_touch_format mode: restart @@ -286,22 +287,22 @@ script: - lambda: |- // Touch panel's state if (sw_touch_panel_power->state) - ESP_LOGCONFIG("${TAG_CORE_HW_TOUCH}", "Touch panel - Power: On"); + ESP_LOGCONFIG("${TAG_HW_TOUCH}", "Touch panel - Power: On"); else - ESP_LOGW("${TAG_CORE_HW_TOUCH}", "Touch panel - Power: OFF"); - ESP_LOGCONFIG("${TAG_CORE_HW_TOUCH}", "Touch event duration: %.0fms", nr_touch_duration->state); + ESP_LOGW("${TAG_HW_TOUCH}", "Touch panel - Power: OFF"); + ESP_LOGCONFIG("${TAG_HW_TOUCH}", "Touch event duration: %.0fms", nr_touch_duration->state); - id: !extend dump_config_list_packages then: - script.wait: dump_config - lambda: |- // Check for requirements - #if !defined(TX_ULTIMATE_EASY_CORE_COMMON) - #error "The package TX-Ultimate-Easy-ESPHome_core_common.yaml is required." + #if !defined(TX_ULTIMATE_EASY_COMMON) + #error "The package TX-Ultimate-Easy-ESPHome_common.yaml is required." #endif // Identify itself - ESP_LOGCONFIG(ESPHOME_PROJECT_NAME, " - Core - Hardware - Touchpad"); + ESP_LOGCONFIG(ESPHOME_PROJECT_NAME, " - Hardware - Touchpad"); - id: touch_on_multi_touch_release mode: restart @@ -335,24 +336,18 @@ script: then: # Extended by: # - HW Buttons - - binary_sensor.template.publish: - id: bs_swipe_left - state: ON # yamllint disable-line rule:truthy - - binary_sensor.template.publish: - id: bs_swipe_down - state: ON # yamllint disable-line rule:truthy + - lambda: |- + bs_swipe_left->publish_state(true); + bs_swipe_up->publish_state(true); - id: touch_swipe_right mode: restart then: # Extended by: # - HW Buttons - - binary_sensor.template.publish: - id: bs_swipe_right - state: ON # yamllint disable-line rule:truthy - - binary_sensor.template.publish: - id: bs_swipe_up - state: ON # yamllint disable-line rule:truthy + - lambda: |- + bs_swipe_right->publish_state(true); + bs_swipe_down->publish_state(true); switch: - id: sw_touch_panel_power @@ -372,24 +367,19 @@ tx_ultimate_easy: - lambda: |- const uint8_t touch_position = static_cast(touch.x); if (touch_position > ${TOUCH_POSITION_MAX_VALUE}) { // Check for valid range - ESP_LOGE("${TAG_CORE_HW_TOUCH}", "Invalid long-touch position: %" PRIu8, touch_position); + ESP_LOGE("${TAG_HW_TOUCH}", "Invalid long-touch position: %" PRIu8, touch_position); } else { - ESP_LOGI("${TAG_CORE_HW_TOUCH}", "Long-touch released at position %" PRIu8, touch_position); + ESP_LOGI("${TAG_HW_TOUCH}", "Long-touch released at position %" PRIu8, touch_position); } on_multi_touch_release: then: - - homeassistant.event: - event: ${EVENT_NAME} - data: - device_name: !lambda return id(tx_device_name).state.c_str(); - firmware: ${version} - domain: touch - type: multi_touch - action: release - position: !lambda return std::to_string(touch.x); - lambda: |- - ESP_LOGI("${TAG_CORE_HW_TOUCH}", "Multi-touch released"); + esphome::tx_ultimate_easy::fire_ha_event("touch", "multi_touch", { + {"action", "release"}, + {"position", std::to_string(touch.x)} + }); + ESP_LOGI("${TAG_HW_TOUCH}", "Multi-touch released"); touch_on_multi_touch_release->execute(); on_press: @@ -397,73 +387,49 @@ tx_ultimate_easy: - lambda: |- const uint8_t position = static_cast(touch.x); if (position > ${TOUCH_POSITION_MAX_VALUE}) { // Check for valid range - ESP_LOGE("${TAG_CORE_HW_TOUCH}", "Invalid touch position: %" PRIu8, position); + ESP_LOGE("${TAG_HW_TOUCH}", "Invalid touch position: %" PRIu8, position); } else { - ESP_LOGI("${TAG_CORE_HW_TOUCH}", "Pressed at position %" PRIu8, position); + ESP_LOGI("${TAG_HW_TOUCH}", "Pressed at position %" PRIu8, position); touch_on_press->execute(static_cast(touch.button), position); } on_release: then: - lambda: |- - ESP_LOGI("${TAG_CORE_HW_TOUCH}", "Released"); - - script.execute: touch_on_release + ESP_LOGI("${TAG_HW_TOUCH}", "Released"); + touch_on_release->execute(); on_swipe_left: then: - - homeassistant.event: - event: ${EVENT_NAME} - data: - device_name: !lambda return id(tx_device_name).state.c_str(); - firmware: ${version} - domain: touch - type: swipe - action: !lambda |- - if (sl_tx_model_format->state == "${TX_MODEL_FORMAT_EU_TEXT}") - return "left"; - else - return "down"; - swipe-direction: !lambda |- - if (sl_tx_model_format->state == "${TX_MODEL_FORMAT_EU_TEXT}") - return "left"; - else - return "down"; - position: !lambda return std::to_string(touch.x); - lambda: |- - ESP_LOGI("${TAG_CORE_HW_TOUCH}", "Swipe %s", - (sl_tx_model_format->state == "${TX_MODEL_FORMAT_EU_TEXT}") ? "left" : "down"); + const char *direction = (sl_tx_model_format->current_option() == "${TX_MODEL_FORMAT_EU_TEXT}") ? + "left" : "up"; + esphome::tx_ultimate_easy::fire_ha_event("touch", "swipe", { + {"action", direction}, + {"swipe-direction", direction}, + {"position", std::to_string(touch.x)} + }); + ESP_LOGI("${TAG_HW_TOUCH}", "Swipe %s", direction); touch_swipe_left->execute(); on_swipe_right: then: - - homeassistant.event: - event: ${EVENT_NAME} - data: - device_name: !lambda return id(tx_device_name).state.c_str(); - firmware: ${version} - domain: touch - type: swipe - action: !lambda |- - if (sl_tx_model_format->state == "${TX_MODEL_FORMAT_EU_TEXT}") - return "right"; - else - return "up"; - swipe-direction: !lambda |- - if (sl_tx_model_format->state == "${TX_MODEL_FORMAT_EU_TEXT}") - return "right"; - else - return "up"; - position: !lambda return std::to_string(touch.x); - lambda: |- - ESP_LOGI("${TAG_CORE_HW_TOUCH}", "Swipe %s", - (sl_tx_model_format->state == "${TX_MODEL_FORMAT_EU_TEXT}") ? "right" : "up"); + const char *direction = (sl_tx_model_format->current_option() == "${TX_MODEL_FORMAT_EU_TEXT}") ? + "right" : "down"; + esphome::tx_ultimate_easy::fire_ha_event("touch", "swipe", { + {"action", direction}, + {"swipe-direction", direction}, + {"position", std::to_string(touch.x)} + }); + ESP_LOGI("${TAG_HW_TOUCH}", "Swipe %s", direction); touch_swipe_right->execute(); on_touch_event: - lambda: |- - ESP_LOGD("${TAG_CORE_HW_TOUCH}", "Touch event:"); - ESP_LOGD("${TAG_CORE_HW_TOUCH}", " State: %i (%s)", touch.state, touch.state_str.c_str()); - ESP_LOGD("${TAG_CORE_HW_TOUCH}", " Position: %i", touch.x); + ESP_LOGD("${TAG_HW_TOUCH}", "Touch event:"); + ESP_LOGD("${TAG_HW_TOUCH}", " State: %i (%s)", touch.state, touch.state_str.c_str()); + ESP_LOGD("${TAG_HW_TOUCH}", " Position: %i", touch.x); uart: - id: uart_touch diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_vibration.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_hw_vibration.yaml similarity index 71% rename from ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_vibration.yaml rename to ESPHome/TX-Ultimate-Easy-ESPHome_hw_vibration.yaml index 2dba6177..6151a940 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_vibration.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_hw_vibration.yaml @@ -2,7 +2,7 @@ ##### TX Ultimate Easy for ESPHome ##### ##### Repository: https://github.com/edwardtfn/TX-Ultimate-Easy ##### #################################################################################################### -##### Purpose: ESPHome - Standard - Hardware - Vibration system ##### +##### Purpose: ESPHome - Hardware - Vibration system ##### #################################################################################################### ##### Author: edwardtfn - https://github.com/edwardtfn - https://buymeacoffee.com/edwardfirmo ##### #################################################################################################### @@ -14,7 +14,7 @@ substitutions: vibration_max_duration: 2s - TAG_STD_HW_VIBRATION: std.hw.vibration + TAG_HW_VIBRATION: tx_ultimate_easy.vibration binary_sensor: - id: bs_vibrating @@ -37,7 +37,7 @@ button: esphome: platformio_options: build_flags: - - -D TX_ULTIMATE_EASY_STANDARD_HW_VIBRATION + - -D TX_ULTIMATE_EASY_HW_VIBRATION number: - id: nr_vibrating_duration @@ -64,28 +64,28 @@ script: then: - lambda: |- // Configuration - ESP_LOGCONFIG("${TAG_STD_HW_VIBRATION}", "Touch - Vibration feedback: %s", - sl_touch_vibration_feedback->state.c_str()); - ESP_LOGCONFIG("${TAG_STD_HW_VIBRATION}", "Vibrate duration: %.0fms", nr_vibrating_duration->state); - ESP_LOGCONFIG("${TAG_STD_HW_VIBRATION}", "Vibrate max duration: ${vibration_max_duration}"); + ESP_LOGCONFIG("${TAG_HW_VIBRATION}", "Touch - Vibration feedback: %s", + sl_touch_vibration_feedback->current_option()); + ESP_LOGCONFIG("${TAG_HW_VIBRATION}", "Vibrate duration: %.0fms", nr_vibrating_duration->state); + ESP_LOGCONFIG("${TAG_HW_VIBRATION}", "Vibrate max duration: ${vibration_max_duration}"); // State if (bs_vibrating->state) - ESP_LOGW("${TAG_STD_HW_VIBRATION}", "Vibrating now: YES"); + ESP_LOGW("${TAG_HW_VIBRATION}", "Vibrating now: YES"); else - ESP_LOGCONFIG("${TAG_STD_HW_VIBRATION}", "Vibrating now: No"); + ESP_LOGCONFIG("${TAG_HW_VIBRATION}", "Vibrating now: No"); - id: !extend dump_config_list_packages then: - script.wait: dump_config - lambda: |- // Check for requirements - #if !defined(TX_ULTIMATE_EASY_CORE_COMMON) - #error "The package TX-Ultimate-Easy-ESPHome_core_common.yaml is required." + #if !defined(TX_ULTIMATE_EASY_COMMON) + #error "The package TX-Ultimate-Easy-ESPHome_common.yaml is required." #endif // Identify itself - ESP_LOGCONFIG(ESPHOME_PROJECT_NAME, " - Standard - Hardware - Vibration"); + ESP_LOGCONFIG(ESPHOME_PROJECT_NAME, " - Hardware - Vibration"); - id: !extend touch_on_multi_touch_release then: @@ -95,8 +95,9 @@ script: mode: restart then: - lambda: |- - if (sl_touch_vibration_feedback->state != "Disabled") + if (strcmp(sl_touch_vibration_feedback->current_option(), "Disabled") != 0) { vibrate->execute(); + } - id: !extend touch_on_press then: @@ -106,8 +107,10 @@ script: mode: restart then: - lambda: |- - if (sl_touch_vibration_feedback->state == "On press" or sl_touch_vibration_feedback->state == "Always") + if (strcmp(sl_touch_vibration_feedback->current_option(), "On press") == 0 or + strcmp(sl_touch_vibration_feedback->current_option(), "Always") == 0) { vibrate->execute(); + } - id: !extend touch_on_release then: @@ -117,8 +120,10 @@ script: mode: restart then: - lambda: |- - if (sl_touch_vibration_feedback->state == "On release" or sl_touch_vibration_feedback->state == "Always") + if (strcmp(sl_touch_vibration_feedback->current_option(), "On release") == 0 or + strcmp(sl_touch_vibration_feedback->current_option(), "Always") == 0) { vibrate->execute(); + } - id: vibrate mode: restart @@ -153,15 +158,9 @@ switch: internal: true on_state: then: - - binary_sensor.template.publish: - id: bs_vibrating - state: !lambda return x; + - lambda: bs_vibrating->publish_state(x); on_turn_on: then: - delay: ${vibration_max_duration} - - if: - condition: - switch.is_on: sw_vibration_motor - then: - - switch.turn_off: sw_vibration_motor + - lambda: if (sw_vibration_motor->state) sw_vibration_motor->turn_off(); ... diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_standard_media_player.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_media_player.yaml similarity index 75% rename from ESPHome/TX-Ultimate-Easy-ESPHome_standard_media_player.yaml rename to ESPHome/TX-Ultimate-Easy-ESPHome_media_player.yaml index 3d51e866..d30680ed 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_standard_media_player.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_media_player.yaml @@ -2,7 +2,7 @@ ##### TX Ultimate Easy for ESPHome ##### ##### Repository: https://github.com/edwardtfn/TX-Ultimate-Easy ##### #################################################################################################### -##### Purpose: ESPHome - Add-on - Media player ##### +##### Purpose: ESPHome - Media player ##### #################################################################################################### ##### Author: edwardtfn - https://github.com/edwardtfn - https://buymeacoffee.com/edwardfirmo ##### #################################################################################################### @@ -12,15 +12,15 @@ #################################################################################################### --- substitutions: - TAG_STD_MEDIA_PLAYER: "std.media-player" + TAG_MEDIA_PLAYER: tx_ultimate_easy.media-player packages: - standard_hw_speaker: !include TX-Ultimate-Easy-ESPHome_standard_hw_speaker.yaml + hw_speaker: !include TX-Ultimate-Easy-ESPHome_hw_speaker.yaml esphome: platformio_options: build_flags: - - -D TX_ULTIMATE_EASY_STANDARD_MEDIA_PLAYER + - -D TX_ULTIMATE_EASY_MEDIA_PLAYER globals: - id: last_media_player_volume @@ -57,7 +57,7 @@ media_player: id(persistent_media_player_volume) = static_cast(mp_media_player->volume * 100.0f); if (id(persistent_media_player_volume) != id(last_media_player_volume)) { id(last_media_player_volume) = id(persistent_media_player_volume); - ESP_LOGD("${TAG_STD_MEDIA_PLAYER}", "Media player volume changed to %" PRIu8 "%%, updating number entity", + ESP_LOGD("${TAG_MEDIA_PLAYER}", "Media player volume changed to %" PRIu8 "%%, updating number entity", id(persistent_media_player_volume)); } @@ -70,25 +70,25 @@ script: then: - lambda: |- // Volume sync configuration - ESP_LOGCONFIG("${TAG_STD_MEDIA_PLAYER}", "Media Player Volume Sync:"); - ESP_LOGCONFIG("${TAG_STD_MEDIA_PLAYER}", " Persistent volume: %" PRIu8 "%", + ESP_LOGCONFIG("${TAG_MEDIA_PLAYER}", "Media Player Volume Sync:"); + ESP_LOGCONFIG("${TAG_MEDIA_PLAYER}", " Persistent volume: %" PRIu8 "%", id(persistent_media_player_volume)); - ESP_LOGCONFIG("${TAG_STD_MEDIA_PLAYER}", " Current volume: %.1f%%", mp_media_player->volume * 100.0f); + ESP_LOGCONFIG("${TAG_MEDIA_PLAYER}", " Current volume: %.1f%%", mp_media_player->volume * 100.0f); - id: !extend dump_config_list_packages then: - script.wait: dump_config - lambda: |- // Check for requirements - #if !defined(TX_ULTIMATE_EASY_CORE_COMMON) - #error "The package TX-Ultimate-Easy-ESPHome_core_common.yaml is required." - #endif // TX_ULTIMATE_EASY_CORE - #if !defined(TX_ULTIMATE_EASY_STANDARD_HW_SPEAKER) - #error "The package TX-Ultimate-Easy-ESPHome_standard_hw_speaker.yaml is required." - #endif // TX_ULTIMATE_EASY_STANDARD_HW_SPEAKER + #if !defined(TX_ULTIMATE_EASY_COMMON) + #error "The package TX-Ultimate-Easy-ESPHome_common.yaml is required." + #endif // TX_ULTIMATE_EASY_COMMON + #if !defined(TX_ULTIMATE_EASY_HW_SPEAKER) + #error "The package TX-Ultimate-Easy-ESPHome_hw_speaker.yaml is required." + #endif // TX_ULTIMATE_EASY_HW_SPEAKER // Identify itself - ESP_LOGCONFIG(ESPHOME_PROJECT_NAME, " - Standard - Media Player"); + ESP_LOGCONFIG(ESPHOME_PROJECT_NAME, " - Media Player"); - id: sync_initial_volume mode: restart @@ -99,7 +99,7 @@ script: volume: !lambda return id(persistent_media_player_volume) / 100.0f; - lambda: |- id(last_media_player_volume) = id(persistent_media_player_volume); - ESP_LOGI("${TAG_STD_MEDIA_PLAYER}", "Initial volume sync: %.1f%% (restored from persistence)", + ESP_LOGI("${TAG_MEDIA_PLAYER}", "Initial volume sync: %.1f%% (restored from persistence)", id(persistent_media_player_volume)); speaker: diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_standard.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_standard.yaml index 17cbe16d..7a6d7ac2 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_standard.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_standard.yaml @@ -13,8 +13,8 @@ --- packages: # yamllint disable rule:colons - standard_hw_relays: !include TX-Ultimate-Easy-ESPHome_standard_hw_relays.yaml - standard_hw_vibration: !include TX-Ultimate-Easy-ESPHome_standard_hw_vibration.yaml - standard_media_player: !include TX-Ultimate-Easy-ESPHome_standard_media_player.yaml + hw_relays: !include TX-Ultimate-Easy-ESPHome_hw_relays.yaml + hw_vibration: !include TX-Ultimate-Easy-ESPHome_hw_vibration.yaml + media_player: !include TX-Ultimate-Easy-ESPHome_media_player.yaml # yamllint enable rule:colons ... diff --git a/TX-Ultimate-Easy-ESPHome_advanced.yaml b/TX-Ultimate-Easy-ESPHome_advanced.yaml index 9ffd141f..f5d05b18 100644 --- a/TX-Ultimate-Easy-ESPHome_advanced.yaml +++ b/TX-Ultimate-Easy-ESPHome_advanced.yaml @@ -23,16 +23,16 @@ packages: refresh: 5min files: # Core (essential) packages - Do not disable these unless you know what you're doing - - ESPHome/TX-Ultimate-Easy-ESPHome_core_common.yaml # Basic shared settings - - ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_buttons.yaml # Button logic - - ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_leds.yaml # LED configuration - - ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_touch.yaml # Touch panel support + - ESPHome/TX-Ultimate-Easy-ESPHome_common.yaml # Basic shared settings + - ESPHome/TX-Ultimate-Easy-ESPHome_hw_buttons.yaml # Button logic + - ESPHome/TX-Ultimate-Easy-ESPHome_hw_leds.yaml # LED configuration + - ESPHome/TX-Ultimate-Easy-ESPHome_hw_touch.yaml # Touch panel support # Optional functionality - Can be enabled/disabled as needed - - ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_relays.yaml # Relay control - - ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_vibration.yaml # Haptic feedback + - ESPHome/TX-Ultimate-Easy-ESPHome_hw_relays.yaml # Relay control + - ESPHome/TX-Ultimate-Easy-ESPHome_hw_vibration.yaml # Haptic feedback # Audio options (use none or choose only one - using both will fail) - - ESPHome/TX-Ultimate-Easy-ESPHome_standard_media_player.yaml # Media player (Recommended for most users) + - ESPHome/TX-Ultimate-Easy-ESPHome_media_player.yaml # Media player (Recommended for most users) # - ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_speaker.yaml # Basic speaker ... diff --git a/components/tx_ultimate_easy/tx_ultimate_easy_api.cpp b/components/tx_ultimate_easy/tx_ultimate_easy_api.cpp new file mode 100644 index 00000000..a9e883a4 --- /dev/null +++ b/components/tx_ultimate_easy/tx_ultimate_easy_api.cpp @@ -0,0 +1,68 @@ +// tx_ultimate_easy_api.cpp +#include "tx_ultimate_easy_api.h" +#include "esphome/core/application.h" +#include + +// Macro stringification helpers +#define STRINGIFY_IMPL(x) #x +#define STRINGIFY(x) STRINGIFY_IMPL(x) + +namespace esphome { + namespace tx_ultimate_easy { + + static const char *TAG_COMPONENT_BASE = "tx_ultimate_easy.component.api"; + + // Cached strings to avoid repeated lookups and string copies + std::string cached_device_name; + + void initialize_cached_device_name(const std::string& raw_name) { + if (!cached_device_name.empty()) return; // Already initialized + + bool last_was_underscore = false; + for (const char& c : raw_name) { + if (std::isalnum(static_cast(c))) { + cached_device_name += static_cast(std::tolower(static_cast(c))); + last_was_underscore = false; + } else if (!last_was_underscore) { + cached_device_name += '_'; + last_was_underscore = true; + } + } + // Remove trailing underscore if present + if (!cached_device_name.empty() && cached_device_name.back() == '_') { + cached_device_name.pop_back(); + } + } + + // Fire a Home Assistant event for TX Ultimate Easy + void fire_ha_event(const std::string &domain, const std::string &type, std::map data) { + // Add guard for uninitialized device name + if (cached_device_name.empty()) { + ESP_LOGW(TAG_COMPONENT_BASE, "Device name not initialized; HA event may have empty device_name field"); + } + + // Add device name and type to the event data + data["device_name"] = cached_device_name; + data["firmware"] = STRINGIFY(TX_ULTIMATE_EASY_FIRMWARE_VERSION); + data["domain"] = domain; + data["type"] = type; + + // Log the event being fired + ESP_LOGD(TAG_COMPONENT_BASE, "HA event: %s/%s", domain.c_str(), type.c_str()); + + // Log additional data if verbose logging is enabled + #if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + for (const auto &[key, value] : data) { + ESP_LOGVV(TAG_COMPONENT_BASE, " Event data: %s=%s", key.c_str(), value.c_str()); + } + #endif + + // Create API device and fire the event + esphome::api::CustomAPIDevice ha_event; + ha_event.fire_homeassistant_event("esphome.tx_ultimate_easy", data); + + ESP_LOGV(TAG_COMPONENT_BASE, "HA event 'esphome.tx_ultimate_easy' sent successfully"); + } + + } // namespace tx_ultimate_easy +} // namespace esphome diff --git a/components/tx_ultimate_easy/tx_ultimate_easy_api.h b/components/tx_ultimate_easy/tx_ultimate_easy_api.h new file mode 100644 index 00000000..6161ff84 --- /dev/null +++ b/components/tx_ultimate_easy/tx_ultimate_easy_api.h @@ -0,0 +1,95 @@ +// tx_ultimate_easy_api.h - Public API for TX Ultimate Easy component +#pragma once + +#include "esphome/components/api/custom_api_device.h" // For API HA event call +#include "esphome/core/application.h" // For App +#include "esphome/core/hal.h" // For delay() +#include "esphome/core/log.h" +#include +#include +#include + +#ifndef TX_ULTIMATE_EASY_FIRMWARE_VERSION +#define TX_ULTIMATE_EASY_FIRMWARE_VERSION "unknown" +#endif + +namespace esphome { + namespace tx_ultimate_easy { + + // Cached device name to avoid repeated lookups and string copies + extern std::string cached_device_name; + + /** + * @brief Initialize the cached device name from a raw name string. + * + * Sanitizes the raw device name by converting it to lowercase alphanumeric + * characters with underscores replacing non-alphanumeric characters. Consecutive + * underscores are avoided. This function should be called early in the boot + * process (e.g., on WiFi connect) to populate the cached_device_name. + * + * If cached_device_name is already populated (non-empty), this function does + * nothing to avoid overwriting an existing value. + * + * @param raw_name The raw device name (typically from App.get_name()) to sanitize + * + * Example: + * Raw name: "TX-Ultimate Easy!" + * Result: "tx_ultimate_easy" + */ + void initialize_cached_device_name(const std::string &raw_name); + + /// @brief Feed the watchdog timer with an optional delay + /// + /// This utility function combines a delay with a watchdog timer feed operation. + /// It's commonly used in long-running operations to prevent watchdog timeouts + /// while giving the system time to process other tasks. + /// + /// @param ms Delay duration in milliseconds before feeding the watchdog (default: 5ms) + /// + /// @note This function is blocking - execution will pause for the specified duration + /// @note Minimum recommended delay is 5ms to allow system task processing + /// + /// @code + /// // Example usage with default 5ms delay + /// feed_wdt_delay(); + /// + /// // Example usage with custom 25ms delay + /// feed_wdt_delay(25); + /// + /// // Common pattern in loops + /// for (uint8_t i = 0; i < 10; ++i) { + /// // ... do work ... + /// feed_wdt_delay(5); // Prevent watchdog timeout + /// } + /// @endcode + /// + /// @see delay() + /// @see App.feed_wdt() + inline void feed_wdt_delay(uint32_t ms = 5) { + esphome::delay(ms); // Block execution for specified milliseconds + esphome::App.feed_wdt(); // Reset the watchdog timer + } + + /** + * @brief Fire a Home Assistant event for TX Ultimate Easy + * + * Automatically adds device_name, firmware, domain and type to the event data. + * + * @param domain Event domain (e.g., "touch", "audio", "relay"). + * @param type Event type (e.g., "multi_touch", "swipe", "boot"). + * @param data Additional event data; core fields are injected automatically. + * + * @note The event name is fixed to "esphome.tx_ultimate_easy". + * + * @code + * fire_ha_event("touch", "swipe", { + * {"swipe-direction", "left"}, + * {"position", "3"} + * }); + * @endcode + */ + void fire_ha_event(const std::string &domain, const std::string &type, + std::map data = {}); + + } // namespace tx_ultimate_easy +} // namespace esphome diff --git a/components/tx_ultimate_easy/tx_ultimate_easy_light.cpp b/components/tx_ultimate_easy/tx_ultimate_easy_light.cpp index c6e0123b..d1ed0b3d 100644 --- a/components/tx_ultimate_easy/tx_ultimate_easy_light.cpp +++ b/components/tx_ultimate_easy/tx_ultimate_easy_light.cpp @@ -1,6 +1,6 @@ // tx_ultimate_easy_light.cpp -#ifdef TX_ULTIMATE_EASY_CORE_HW_LEDS +#ifdef TX_ULTIMATE_EASY_HW_LEDS #include "esphome/core/log.h" #include "tx_ultimate_easy_light.h" @@ -55,4 +55,4 @@ namespace esphome { } // namespace tx_ultimate_easy } // namespace esphome -#endif // TX_ULTIMATE_EASY_CORE_HW_LEDS +#endif // TX_ULTIMATE_EASY_HW_LEDS diff --git a/components/tx_ultimate_easy/tx_ultimate_easy_light.h b/components/tx_ultimate_easy/tx_ultimate_easy_light.h index 8e3da9c1..e9cc6595 100644 --- a/components/tx_ultimate_easy/tx_ultimate_easy_light.h +++ b/components/tx_ultimate_easy/tx_ultimate_easy_light.h @@ -2,7 +2,7 @@ #pragma once -#ifdef TX_ULTIMATE_EASY_CORE_HW_LEDS +#ifdef TX_ULTIMATE_EASY_HW_LEDS #include "esphome/core/automation.h" #include "esphome/core/component.h" @@ -113,4 +113,4 @@ namespace esphome { } // namespace tx_ultimate_easy } // namespace esphome -#endif // TX_ULTIMATE_EASY_CORE_HW_LEDS +#endif // TX_ULTIMATE_EASY_HW_LEDS diff --git a/components/tx_ultimate_easy/tx_ultimate_easy_touch.cpp b/components/tx_ultimate_easy/tx_ultimate_easy_touch.cpp index 7c1b4d36..5d577ccc 100644 --- a/components/tx_ultimate_easy/tx_ultimate_easy_touch.cpp +++ b/components/tx_ultimate_easy/tx_ultimate_easy_touch.cpp @@ -1,6 +1,6 @@ // tx_ultimate_easy_touch.cpp -#ifdef TX_ULTIMATE_EASY_CORE_HW_TOUCH +#ifdef TX_ULTIMATE_EASY_HW_TOUCH #include "esphome/core/log.h" #include "tx_ultimate_easy_touch.h" @@ -232,4 +232,4 @@ namespace esphome { } // namespace tx_ultimate_easy } // namespace esphome -#endif // TX_ULTIMATE_EASY_CORE_HW_TOUCH +#endif // TX_ULTIMATE_EASY_HW_TOUCH diff --git a/components/tx_ultimate_easy/tx_ultimate_easy_touch.h b/components/tx_ultimate_easy/tx_ultimate_easy_touch.h index 867d0ec5..b9d5fec7 100644 --- a/components/tx_ultimate_easy/tx_ultimate_easy_touch.h +++ b/components/tx_ultimate_easy/tx_ultimate_easy_touch.h @@ -2,7 +2,7 @@ #pragma once -#ifdef TX_ULTIMATE_EASY_CORE_HW_TOUCH +#ifdef TX_ULTIMATE_EASY_HW_TOUCH #include "esphome/core/automation.h" #include "esphome/core/component.h" @@ -84,4 +84,4 @@ namespace esphome { } // namespace tx_ultimate_easy } // namespace esphome -#endif // TX_ULTIMATE_EASY_CORE_HW_TOUCH +#endif // TX_ULTIMATE_EASY_HW_TOUCH diff --git a/versioning/VERSION b/versioning/VERSION index 85c303d5..66918793 100644 --- a/versioning/VERSION +++ b/versioning/VERSION @@ -1 +1 @@ -2025.10.1 +9999.99.9 diff --git a/versioning/VERSION_YAML b/versioning/VERSION_YAML index 913e59f0..276ec8d9 100644 --- a/versioning/VERSION_YAML +++ b/versioning/VERSION_YAML @@ -1 +1 @@ -version: 2025.10.1 +version: 9999.99.9