#################################################################################################### ##### TX Ultimate Easy for ESPHome ##### ##### Repository: https://github.com/edwardtfn/TX-Ultimate-Easy ##### #################################################################################################### ##### Purpose: ESPHome Core - Hardware - Relays ##### #################################################################################################### ##### Author: edwardtfn - https://github.com/edwardtfn - https://buymeacoffee.com/edwardfirmo ##### #################################################################################################### ##### NOTE: ##### ##### - Make changes ONLY if absolutely necessary and you have the required knowledge. ##### ##### - For normal system use, modifications to this file are NOT required. ##### #################################################################################################### --- binary_sensor: - id: !extend bs_button_1 on_click: then: - lambda: |- if (sl_button_1_action->active_index().has_value() and sl_button_1_action->active_index().value() == 1 and !bs_multi_touch->state and !bs_swipe_left->state and !bs_swipe_down->state and !bs_swipe_right->state) sw_relay_1->toggle(); - id: !extend bs_button_2 on_click: then: - lambda: |- if (sl_button_2_action->active_index().has_value() and sl_button_2_action->active_index().value() == 1 and !bs_multi_touch->state and !bs_swipe_left->state and !bs_swipe_down->state and !bs_swipe_right->state) sw_relay_2->toggle(); - id: !extend bs_button_3 on_click: then: - lambda: |- if (sl_button_3_action->active_index().has_value() and sl_button_3_action->active_index().value() == 1 and !bs_multi_touch->state and !bs_swipe_left->state and !bs_swipe_down->state and !bs_swipe_right->state) sw_relay_3->toggle(); - id: !extend bs_button_4 on_click: then: - lambda: |- if (sl_button_4_action->active_index().has_value() and sl_button_4_action->active_index().value() == 1 and !bs_multi_touch->state and !bs_swipe_left->state and !bs_swipe_down->state and !bs_swipe_right->state) sw_relay_4->toggle(); globals: - id: boot_initialization_relays type: bool restore_value: false initial_value: 'false' output: - id: output_relay_1 platform: gpio pin: GPIO18 - id: output_relay_2 platform: gpio pin: GPIO17 - id: output_relay_3 platform: gpio pin: GPIO27 - id: output_relay_4 platform: gpio pin: GPIO23 script: - id: !extend boot_initialize then: - script.execute: boot_initialize_relays - id: boot_initialize_relays mode: restart then: - wait_until: condition: - lambda: return sl_tx_model_format->active_index().has_value(); - lambda: return sl_tx_model_gang->active_index().has_value(); - lambda: |- const bool is_model_us = sl_tx_model_format->active_index().has_value() and sl_tx_model_format->active_index().value() == 1; const uint8_t num_gangs = (sl_tx_model_gang->active_index().has_value()) ? (sl_tx_model_gang->active_index().value() + 1) : 0; if (num_gangs < 1 || num_gangs > 4) { ESP_LOGE("core_hw_relays", "Invalid number of gangs: %" PRIu8, num_gangs); return; } sl_relay_1_mode->set_internal(num_gangs < 1); sl_relay_1_light_mode_eu->set_internal(is_model_us or num_gangs < 1); sl_relay_1_light_mode_us->set_internal(!is_model_us or num_gangs < 1); sl_relay_2_mode->set_internal(num_gangs < 2); sl_relay_2_light_mode_eu->set_internal(is_model_us or num_gangs < 2); sl_relay_2_light_mode_us->set_internal(!is_model_us or num_gangs < 2); sl_relay_3_mode->set_internal(num_gangs < 3); sl_relay_3_light_mode_eu->set_internal(is_model_us or num_gangs < 3); sl_relay_3_light_mode_us->set_internal(!is_model_us or num_gangs < 3); sl_relay_4_mode->set_internal(num_gangs < 4); sl_relay_4_light_mode_eu->set_internal(is_model_us or num_gangs < 4); sl_relay_4_light_mode_us->set_internal(!is_model_us or num_gangs < 4); auto relay_mode_index = sl_relay_1_mode->active_index(); if (relay_mode_index.has_value()) { light_output_1->set_internal(false or relay_mode_index.value() != 1); sw_relay_1->set_internal(false or relay_mode_index.value() != 0); } relay_mode_index = sl_relay_2_mode->active_index(); if (relay_mode_index.has_value()) { light_output_2->set_internal(num_gangs < 2 or relay_mode_index.value() != 1); sw_relay_2->set_internal(num_gangs < 2 or relay_mode_index.value() != 0); } relay_mode_index = sl_relay_3_mode->active_index(); if (relay_mode_index.has_value()) { light_output_3->set_internal(num_gangs < 3 or relay_mode_index.value() != 1); sw_relay_3->set_internal(num_gangs < 3 or relay_mode_index.value() != 0); } relay_mode_index = sl_relay_4_mode->active_index(); if (relay_mode_index.has_value()) { light_output_4->set_internal(num_gangs < 4 or relay_mode_index.value() != 1); sw_relay_4->set_internal(num_gangs < 4 or relay_mode_index.value() != 0); } id(boot_initialization_relays) = true; - id: show_relay_status mode: restart then: - script.wait: boot_initialize_relays - wait_until: condition: - lambda: return sl_tx_model_format->active_index().has_value(); - lambda: return id(boot_initialization_relays); - lambda: |- auto model_format = sl_tx_model_format->active_index(); if (!model_format.has_value()) { ESP_LOGE("core_hw_relays", "Model (Format) not defined"); return; } std::vector relay_modes; const bool is_eu_model = model_format.value() == 0; // Select appropriate light mode selectors based on model if (is_eu_model) { relay_modes = {sl_relay_1_light_mode_eu, sl_relay_2_light_mode_eu, sl_relay_3_light_mode_eu, sl_relay_4_light_mode_eu}; } else { relay_modes = {sl_relay_1_light_mode_us, sl_relay_2_light_mode_us, sl_relay_3_light_mode_us, sl_relay_4_light_mode_us}; } // Get switch states const std::vector switches = {sw_relay_1, sw_relay_2, sw_relay_3, sw_relay_4}; // Check if light vectors are initialized if (id(gb_lights_1).empty() || id(gb_lights_2).empty()) { ESP_LOGE("core_hw_relays", "Light vector not initialized"); return; } // Update lights based on relay states for (size_t i = 0; i < relay_modes.size() && i < id(gb_lights_1).size(); ++i) { if (!relay_modes[i] || !switches[i]) continue; auto light_index = relay_modes[i]->active_index(); if (!light_index.has_value()) continue; const uint8_t light_idx = light_index.value(); const bool switch_state = switches[i]->state; // Update first light group (bottom/left) if ((light_idx == 1 || light_idx == 3) && i < id(gb_lights_1).size() && id(gb_lights_1)[i]) { if (switch_state) id(gb_lights_1)[i]->turn_on(); else id(gb_lights_1)[i]->turn_off(); } // Update second light group (top/right) if ((light_idx == 2 || light_idx == 3) && i < id(gb_lights_2).size() && id(gb_lights_2)[i]) { if (switch_state) id(gb_lights_2)[i]->turn_on(); else id(gb_lights_2)[i]->turn_off(); } } select: - &relay_select_mode_base id: sl_relay_1_mode name: Relay 1 mode platform: template options: - "Relay" - "Light" - "Not in use" optimistic: true restore_value: true internal: true entity_category: config disabled_by_default: false icon: mdi:dip-switch - id: sl_relay_2_mode name: Relay 2 mode <<: *relay_select_mode_base - id: sl_relay_3_mode name: Relay 3 mode <<: *relay_select_mode_base - id: sl_relay_4_mode name: Relay 4 mode <<: *relay_select_mode_base switch: - &relay_switch_base id: sw_relay_1 name: Relay 1 platform: output output: output_relay_1 restore_mode: RESTORE_DEFAULT_OFF internal: true on_turn_on: then: - script.execute: show_relay_status on_turn_off: then: - script.execute: show_relay_status - id: sw_relay_2 name: Relay 2 output: output_relay_2 <<: *relay_switch_base - id: sw_relay_3 name: Relay 3 output: output_relay_3 <<: *relay_switch_base - id: sw_relay_4 name: Relay 4 output: output_relay_4 <<: *relay_switch_base ...