#################################################################################################### ##### TX Ultimate Easy for ESPHome ##### ##### Repository: https://github.com/edwardtfn/TX-Ultimate-Easy ##### #################################################################################################### ##### Purpose: ESPHome Core ##### #################################################################################################### ##### 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. ##### #################################################################################################### --- substitutions: name: tx-ultimate-easy friendly_name: TX Ultimate Easy latitude: '0' longitude: '0' zone_home: 'zone.home' version: '0.0.3' packages: # yamllint disable rule:colons core_api: !include TX-Ultimate-Easy-ESPHome_core_api.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_relays: !include TX-Ultimate-Easy-ESPHome_core_hw_relays.yaml core_hw_speaker: !include TX-Ultimate-Easy-ESPHome_core_hw_speaker.yaml core_hw_touch: !include TX-Ultimate-Easy-ESPHome_core_hw_touch.yaml core_hw_vibration: !include TX-Ultimate-Easy-ESPHome_core_hw_vibration.yaml # yamllint enable rule:colons button: - id: bt_restart name: Restart internal: false platform: restart captive_portal: id: ap_captive_portal esp32: board: esp32dev flash_size: 8MB esphome: name: ${name} friendly_name: ${friendly_name} comment: TX Ultimate Easy platformio_options: build_flags: - -D TX_ULTIMATE_EASY_CORE on_boot: - priority: 700 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 us_model = 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; bs_button_1->publish_state(false); bs_button_1->set_internal(num_gangs < 1); sl_button_1_action->set_internal(num_gangs < 1); bs_button_2->publish_state(false); bs_button_2->set_internal(num_gangs < 2); sl_button_2_action->set_internal(num_gangs < 2); bs_button_3->publish_state(false); bs_button_3->set_internal(num_gangs < 3); sl_button_3_action->set_internal(num_gangs < 3); bs_button_4->publish_state(false); bs_button_4->set_internal(num_gangs < 4); sl_button_4_action->set_internal(num_gangs < 4); bs_multi_touch->publish_state(false); bs_swipe_down->publish_state(false); bs_swipe_down->set_internal(!us_model); bs_swipe_left->publish_state(false); bs_swipe_left->set_internal(us_model); bs_swipe_right->publish_state(false); bs_swipe_right->set_internal(us_model); bs_swipe_up->publish_state(false); bs_swipe_up->set_internal(!us_model); light_28->set_internal(!us_model); light_29->set_internal(!us_model); light_30->set_internal(!us_model); light_31->set_internal(!us_model); light_eu->set_internal(us_model); light_eu_bottom->set_internal(us_model); light_eu_left->set_internal(us_model); light_eu_right->set_internal(us_model); light_eu_top->set_internal(us_model); light_us->set_internal(!us_model); light_us_bottom->set_internal(!us_model); light_us_left->set_internal(!us_model); light_us_right->set_internal(!us_model); light_us_top->set_internal(!us_model); sl_relay_1_mode->set_internal(num_gangs < 1); sl_relay_1_light_mode_eu->set_internal(us_model or num_gangs < 1); sl_relay_1_light_mode_us->set_internal(!us_model or num_gangs < 1); sl_relay_2_mode->set_internal(num_gangs < 2); sl_relay_2_light_mode_eu->set_internal(us_model or num_gangs < 2); sl_relay_2_light_mode_us->set_internal(!us_model or num_gangs < 2); sl_relay_3_mode->set_internal(num_gangs < 3); sl_relay_3_light_mode_eu->set_internal(us_model or num_gangs < 3); sl_relay_3_light_mode_us->set_internal(!us_model or num_gangs < 3); sl_relay_4_mode->set_internal(num_gangs < 4); sl_relay_4_light_mode_eu->set_internal(us_model or num_gangs < 4); sl_relay_4_light_mode_us->set_internal(!us_model or num_gangs < 4); auto relay_mode_index = sl_relay_1_mode->active_index(); if (relay_mode_index.has_value()) { ligth_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()) { ligth_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()) { ligth_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()) { ligth_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); } switch (num_gangs) { case 1: // 1 Gang if (us_model) { id(gb_lights_1) = { light_us_rl_1_1_left }; id(gb_lights_2) = { light_us_rl_1_1_right }; } else { id(gb_lights_1) = { light_eu_rl_1_1_bottom }; id(gb_lights_2) = { light_eu_rl_1_1_top }; } break; case 2: // 2 Gang if (us_model) { id(gb_lights_1) = { light_us_rl_1_2_left, light_us_rl_2_2_left }; id(gb_lights_2) = { light_us_rl_1_2_right, light_us_rl_2_2_right }; } else { id(gb_lights_1) = { light_eu_rl_1_2_bottom, light_eu_rl_2_2_bottom }; id(gb_lights_2) = { light_eu_rl_1_2_top, light_eu_rl_2_2_top }; } break; case 3: // 3 Gang if (us_model) { id(gb_lights_1) = { light_us_rl_1_3_left, light_us_rl_2_3_left, light_us_rl_3_3_left }; id(gb_lights_2) = { light_us_rl_1_3_right, light_us_rl_2_3_right, light_us_rl_3_3_right }; } else { id(gb_lights_1) = { light_eu_rl_1_3_bottom, light_eu_rl_2_3_bottom, light_eu_rl_3_3_bottom }; id(gb_lights_2) = { light_eu_rl_1_3_top, light_eu_rl_2_3_top, light_eu_rl_3_3_top }; } break; case 4: // 3 Gang if (us_model) { id(gb_lights_1) = { light_us_rl_1_4_left, light_us_rl_2_4_left, light_us_rl_3_4_left, light_us_rl_4_4_left }; id(gb_lights_2) = { light_us_rl_1_4_right, light_us_rl_2_4_right, light_us_rl_3_4_right, light_us_rl_4_4_right }; } else { id(gb_lights_1) = { light_eu_rl_1_4_bottom, light_eu_rl_2_4_bottom, light_eu_rl_3_4_bottom, light_eu_rl_4_4_bottom }; id(gb_lights_2) = { light_eu_rl_1_4_top, light_eu_rl_2_4_top, light_eu_rl_3_4_top, light_eu_rl_4_4_top }; } break; } - priority: 600 # This is where most sensors are set up. then: - lambda: |- tx_fw_version->publish_state("${version}"); tx_device_name->publish_state("${name}"); - priority: -100 # At this priority, pretty much everything should already be initialized. then: - lambda: send_event_to_ha->execute("boot", "done"); improv_serial: id: serial_improv logger: ota: platform: esphome psram: script: - id: boot_initialize mode: restart then: # There's nothing here so far select: - id: sl_tx_model_format name: Model (Format) platform: template options: - "EU (Square, T5-xC-86)" - "US (Rectangle, T5-xC-120)" initial_option: "EU (Square, T5-xC-86)" optimistic: true restore_value: true internal: false entity_category: config disabled_by_default: false icon: mdi:tablet-cellphone - id: sl_tx_model_gang name: Model (Gang) platform: template options: - "1 Gang" - "2 Gang" - "3 Gang" - "4 Gang" initial_option: "1 Gang" optimistic: true restore_value: true internal: false entity_category: config disabled_by_default: false icon: mdi:dip-switch sensor: - id: sun_elevation name: Sun Elevation platform: sun type: elevation internal: true - id: zone_home_latitude platform: homeassistant entity_id: ${zone_home} attribute: latitude internal: false on_value: - lambda: if (!isnan(x)) sun_entity->set_latitude(x); - id: zone_home_longitude platform: homeassistant entity_id: ${zone_home} attribute: longitude internal: false on_value: - lambda: if (!isnan(x)) sun_entity->set_longitude(x); sun: id: sun_entity latitude: ${latitude} longitude: ${longitude} text_sensor: - id: tx_fw_version name: Firmware version platform: template entity_category: diagnostic icon: mdi:tag-text-outline internal: false update_interval: never lambda: |- return {"${version}"}; - id: tx_device_name name: Device Name platform: template icon: mdi:identifier entity_category: diagnostic internal: false disabled_by_default: false 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; time: - id: time_source platform: homeassistant web_server: wifi: ap: ...