substitutions: name: tx-ultimate-easy friendly_name: TX Ultimate Easy latitude: '0' longitude: '0' zone_home: 'zone.home' version: '0.0.1' api: id: api_server services: - service: set_float variables: component: string val: float then: - lambda: |- if (!isnan(val)) { if (component == "latitude") sun_entity->set_latitude(val); else if (component == "longitude") sun_entity->set_longitude(val); } binary_sensor: - id: bs_vibrating name: Vibrating icon: mdi:vibrate internal: false platform: template lambda: return sw_vibration_motor->state; - id: bs_button_1 name: Button 1 internal: false platform: template on_press: then: - switch.toggle: sw_relay_1 - id: bs_button_2 name: Button 2 internal: true platform: template on_press: then: - switch.toggle: sw_relay_2 - id: bs_button_3 name: Button 3 internal: true platform: template on_press: then: - switch.toggle: sw_relay_3 - id: bs_button_4 name: Button 4 internal: true platform: template on_press: then: - switch.toggle: sw_relay_4 # bluetooth_proxy: button: - id: bt_restart name: Restart internal: false platform: restart - id: bt_vibrate name: Vibrate icon: mdi:vibrate internal: false platform: template on_press: then: - script.execute: vibrate captive_portal: esp32: board: esp32dev framework: # type: esp-idf type: arduino # sdkconfig_options: # CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST: "y" # CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY: "y" # CONFIG_ESP32_REV_MIN_3: "y" # CONFIG_MBEDTLS_DYNAMIC_BUFFER: "y" # CONFIG_MBEDTLS_DYNAMIC_FREE_CA_CERT: "y" # CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA: "y" # CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC: "y" # CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY: "y" # CONFIG_SPIRAM_RODATA: "y" # CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP: "y" esphome: name: ${name} friendly_name: ${friendly_name} platformio_options: build_flags: - -DCONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST=true # - -DCONFIG_BT_BLE_DYNAMIC_ENV_MEMORY=true - -DCONFIG_ESP32_REV_MIN_3=true - -DCONFIG_MBEDTLS_DYNAMIC_BUFFER=true - -DCONFIG_MBEDTLS_DYNAMIC_FREE_CA_CERT=true - -DCONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA=true - -DCONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC=true - -DCONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=true - -DCONFIG_SPIRAM_RODATA=true - -DCONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=true on_boot: - priority: 700 then: - wait_until: condition: - lambda: return sl_tx_model_gang->active_index().has_value(); - lambda: |- auto index = sl_tx_model_gang->active_index(); if (index.has_value()) { uint8_t idx = index.value(); sw_relay_1->set_internal(false); sw_relay_2->set_internal(idx < 1); sw_relay_3->set_internal(idx < 2); sw_relay_4->set_internal(idx < 3); bs_button_1->set_internal(false); bs_button_2->set_internal(idx < 1); bs_button_3->set_internal(idx < 2); bs_button_4->set_internal(idx < 3); bs_button_1->publish_state(false); bs_button_2->publish_state(false); bs_button_3->publish_state(false); bs_button_4->publish_state(false); } - priority: 600 # This is where most sensors are set up. then: - lambda: |- tx_fw_version->publish_state("${version}"); tx_device_name->publish_state("${name}"); external_components: - source: type: git url: https://github.com/edwardtfn/TX-Ultimate-Easy ref: dev components: - tx_ultimate_easy i2s_audio: id: if_i2s_audio i2s_bclk_pin: GPIO2 i2s_lrclk_pin: GPIO4 light: - id: light_full name: Light - All platform: neopixelbus type: GRB variant: WS2811 # platform: esp32_rmt_led_strip # rgb_order: GRB # rmt_channel: 0 # chipset: ws2812 num_leds: 28 pin: GPIO13 effects: - addressable_rainbow: - addressable_rainbow: name: "Rainbow - Fast" speed: 50 - pulse: - pulse: name: "Pulse - Fast" transition_length: 0.5s update_interval: 0.5s - pulse: name: "Pulse - Slow" update_interval: 2s - addressable_scan: - addressable_scan: name: Scan Effect With Custom Values move_interval: 100ms scan_width: 3 - addressable_twinkle: - addressable_twinkle: name: Twinkle Effect With Custom Values twinkle_probability: 5% progress_interval: 4ms - addressable_random_twinkle: - addressable_random_twinkle: name: Random Twinkle Effect With Custom Values twinkle_probability: 20% progress_interval: 32ms - addressable_fireworks: - addressable_fireworks: name: Fireworks Effect With Custom Values update_interval: 32ms spark_probability: 10% use_random_color: false fade_out_rate: 120 - addressable_flicker: - addressable_flicker: name: Flicker Effect With Custom Values update_interval: 16ms intensity: 5% - random: - id: light_bottom name: Light - Bottom disabled_by_default: true platform: partition segments: - id: light_full from: 6 to: 12 reversed: true effects: - addressable_rainbow: - addressable_rainbow: name: "Rainbow - Fast" speed: 50 - pulse: - pulse: name: "Pulse - Fast" transition_length: 0.5s update_interval: 0.5s - pulse: name: "Pulse - Slow" update_interval: 2s - addressable_scan: - addressable_scan: name: Scan Effect With Custom Values move_interval: 100ms scan_width: 3 - addressable_twinkle: - addressable_twinkle: name: Twinkle Effect With Custom Values twinkle_probability: 5% progress_interval: 4ms - addressable_random_twinkle: - addressable_random_twinkle: name: Random Twinkle Effect With Custom Values twinkle_probability: 20% progress_interval: 32ms - addressable_fireworks: - addressable_fireworks: name: Fireworks Effect With Custom Values update_interval: 32ms spark_probability: 10% use_random_color: false fade_out_rate: 120 - addressable_flicker: - addressable_flicker: name: Flicker Effect With Custom Values update_interval: 16ms intensity: 5% - random: - id: light_left name: Light - Left disabled_by_default: true platform: partition segments: - id: light_full from: 13 to: 19 reversed: true effects: - addressable_rainbow: - addressable_rainbow: name: "Rainbow - Fast" speed: 50 - pulse: - pulse: name: "Pulse - Fast" transition_length: 0.5s update_interval: 0.5s - pulse: name: "Pulse - Slow" update_interval: 2s - addressable_scan: - addressable_scan: name: Scan Effect With Custom Values move_interval: 100ms scan_width: 3 - addressable_twinkle: - addressable_twinkle: name: Twinkle Effect With Custom Values twinkle_probability: 5% progress_interval: 4ms - addressable_random_twinkle: - addressable_random_twinkle: name: Random Twinkle Effect With Custom Values twinkle_probability: 20% progress_interval: 32ms - addressable_fireworks: - addressable_fireworks: name: Fireworks Effect With Custom Values update_interval: 32ms spark_probability: 10% use_random_color: false fade_out_rate: 120 - addressable_flicker: - addressable_flicker: name: Flicker Effect With Custom Values update_interval: 16ms intensity: 5% - random: - id: light_right name: Light - Right disabled_by_default: true platform: partition segments: - id: light_full from: 27 to: 27 reversed: false - id: light_full from: 0 to: 5 reversed: false effects: - addressable_rainbow: - addressable_rainbow: name: "Rainbow - Fast" speed: 50 - pulse: - pulse: name: "Pulse - Fast" transition_length: 0.5s update_interval: 0.5s - pulse: name: "Pulse - Slow" update_interval: 2s - addressable_scan: - addressable_scan: name: Scan Effect With Custom Values move_interval: 100ms scan_width: 3 - addressable_twinkle: - addressable_twinkle: name: Twinkle Effect With Custom Values twinkle_probability: 5% progress_interval: 4ms - addressable_random_twinkle: - addressable_random_twinkle: name: Random Twinkle Effect With Custom Values twinkle_probability: 20% progress_interval: 32ms - addressable_fireworks: - addressable_fireworks: name: Fireworks Effect With Custom Values update_interval: 32ms spark_probability: 10% use_random_color: false fade_out_rate: 120 - addressable_flicker: - addressable_flicker: name: Flicker Effect With Custom Values update_interval: 16ms intensity: 5% - random: - id: light_top name: Light - Top disabled_by_default: true platform: partition segments: - id: light_full from: 20 to: 26 reversed: false effects: - addressable_rainbow: - addressable_rainbow: name: "Rainbow - Fast" speed: 50 - pulse: - pulse: name: "Pulse - Fast" transition_length: 0.5s update_interval: 0.5s - pulse: name: "Pulse - Slow" update_interval: 2s - addressable_scan: - addressable_scan: name: Scan Effect With Custom Values move_interval: 100ms scan_width: 3 - addressable_twinkle: - addressable_twinkle: name: Twinkle Effect With Custom Values twinkle_probability: 5% progress_interval: 4ms - addressable_random_twinkle: - addressable_random_twinkle: name: Random Twinkle Effect With Custom Values twinkle_probability: 20% progress_interval: 32ms - addressable_fireworks: - addressable_fireworks: name: Fireworks Effect With Custom Values update_interval: 32ms spark_probability: 10% use_random_color: false fade_out_rate: 120 - addressable_flicker: - addressable_flicker: name: Flicker Effect With Custom Values update_interval: 16ms intensity: 5% - random: - id: light_00 name: Light - LED 00 disabled_by_default: true platform: partition segments: - id: light_full from: 0 to: 0 - id: light_01 name: Light - LED 01 disabled_by_default: true platform: partition segments: - id: light_full from: 1 to: 1 - id: light_02 name: Light - LED 02 disabled_by_default: true platform: partition segments: - id: light_full from: 2 to: 2 - id: light_03 name: Light - LED 03 disabled_by_default: true platform: partition segments: - id: light_full from: 3 to: 3 - id: light_04 name: Light - LED 04 disabled_by_default: true platform: partition segments: - id: light_full from: 4 to: 4 - id: light_05 name: Light - LED 05 disabled_by_default: true platform: partition segments: - id: light_full from: 5 to: 5 - id: light_06 name: Light - LED 06 disabled_by_default: true platform: partition segments: - id: light_full from: 6 to: 6 - id: light_07 name: Light - LED 07 disabled_by_default: true platform: partition segments: - id: light_full from: 7 to: 7 - id: light_08 name: Light - LED 08 disabled_by_default: true platform: partition segments: - id: light_full from: 8 to: 8 - id: light_09 name: Light - LED 09 disabled_by_default: true platform: partition segments: - id: light_full from: 9 to: 9 - id: light_10 name: Light - LED 10 disabled_by_default: true platform: partition segments: - id: light_full from: 10 to: 10 - id: light_11 name: Light - LED 11 disabled_by_default: true platform: partition segments: - id: light_full from: 11 to: 11 - id: light_12 name: Light - LED 12 disabled_by_default: true platform: partition segments: - id: light_full from: 12 to: 12 - id: light_13 name: Light - LED 13 disabled_by_default: true platform: partition segments: - id: light_full from: 13 to: 13 - id: light_14 name: Light - LED 14 disabled_by_default: true platform: partition segments: - id: light_full from: 14 to: 14 - id: light_15 name: Light - LED 15 disabled_by_default: true platform: partition segments: - id: light_full from: 15 to: 15 - id: light_16 name: Light - LED 16 disabled_by_default: true platform: partition segments: - id: light_full from: 16 to: 16 - id: light_17 name: Light - LED 17 disabled_by_default: true platform: partition segments: - id: light_full from: 17 to: 17 - id: light_18 name: Light - LED 18 disabled_by_default: true platform: partition segments: - id: light_full from: 18 to: 18 - id: light_19 name: Light - LED 19 disabled_by_default: true platform: partition segments: - id: light_full from: 19 to: 19 - id: light_20 name: Light - LED 20 disabled_by_default: true platform: partition segments: - id: light_full from: 20 to: 20 - id: light_21 name: Light - LED 21 disabled_by_default: true platform: partition segments: - id: light_full from: 21 to: 21 - id: light_22 name: Light - LED 22 disabled_by_default: true platform: partition segments: - id: light_full from: 22 to: 22 - id: light_23 name: Light - LED 23 disabled_by_default: true platform: partition segments: - id: light_full from: 23 to: 23 - id: light_24 name: Light - LED 24 disabled_by_default: true platform: partition segments: - id: light_full from: 24 to: 24 - id: light_25 name: Light - LED 25 disabled_by_default: true platform: partition segments: - id: light_full from: 25 to: 25 - id: light_26 name: Light - LED 26 disabled_by_default: true platform: partition segments: - id: light_full from: 26 to: 26 - id: light_27 name: Light - LED 27 disabled_by_default: true platform: partition segments: - id: light_full from: 27 to: 27 # - id: light_status # name: Light - Status # platform: esp32_rmt_led_strip # rgb_order: GRB # pin: GPIO13 # num_leds: 1 # rmt_channel: 0 # chipset: ws2812 logger: media_player: - id: mp_speaker name: Speaker platform: i2s_audio i2s_dout_pin: GPIO15 i2s_audio_id: if_i2s_audio i2s_comm_fmt: lsb dac_type: external mode: mono mute_pin: number: GPIO26 inverted: true allow_other_uses: true internal: false number: - id: nr_vibrating_duration name: Vibrate duration icon: mdi:vibrate unit_of_measurement: ms # mode: box internal: false platform: template min_value: 1 max_value: 500 step: 1 initial_value: 15 optimistic: true restore_value: true ota: psram: script: - id: vibrate mode: restart then: - switch.turn_on: sw_vibration_motor - delay: !lambda return nr_vibrating_duration->state; - switch.turn_off: sw_vibration_motor select: - id: sl_tx_model_gang name: Model 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 - id: sl_touch_vibration_feedback name: Touch - Vibration feedback platform: template options: - "Disabled" - "On press" - "On release" - "Always" initial_option: "Disabled" optimistic: true restore_value: true internal: false entity_category: config disabled_by_default: false icon: mdi:vibrate 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} switch: - id: sw_speaker_aplifier name: Speaker - Aplifier platform: gpio pin: number: GPIO26 inverted: true allow_other_uses: true restore_mode: RESTORE_DEFAULT_ON internal: true - id: sw_relay_1 name: Relay 1 platform: gpio pin: GPIO18 restore_mode: RESTORE_DEFAULT_OFF internal: false - id: sw_relay_2 name: Relay 2 platform: gpio pin: GPIO17 restore_mode: RESTORE_DEFAULT_OFF internal: true - id: sw_relay_3 name: Relay 3 platform: gpio pin: GPIO27 restore_mode: RESTORE_DEFAULT_OFF internal: true - id: sw_relay_4 name: Relay 4 platform: gpio pin: GPIO23 restore_mode: RESTORE_DEFAULT_OFF internal: true - id: sw_touch_panel_power name: Touch panel - Power platform: gpio pin: number: GPIO5 inverted: true restore_mode: ALWAYS_ON internal: false - id: sw_vibration_motor name: Vibration motor platform: gpio pin: GPIO21 restore_mode: ALWAYS_OFF internal: true on_turn_on: then: - lambda: bs_vibrating->publish_state(true); on_turn_off: then: - lambda: bs_vibrating->publish_state(false); 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 tx_ultimate_easy: id: tx_ultimate uart: uart_touch on_touch_event: - lambda: |- ESP_LOGD("tx_ultimate_easy.on_touch_event", "Touch event:"); ESP_LOGD("tx_ultimate_easy.on_touch_event", " State: %i (%s)", touch.state, touch.state_str.c_str()); ESP_LOGD("tx_ultimate_easy.on_touch_event", " Position: %i", touch.x); on_press: - lambda: |- if (sl_touch_vibration_feedback->state == "On press" or sl_touch_vibration_feedback->state == "Always") vibrate->execute(); auto model_index = sl_tx_model_gang->active_index(); if (model_index.has_value()) { uint8_t model_idx = model_index.value() + 1; switch (model_idx) { case 1: // 1 Gang bs_button_1->publish_state(true); break; case 2: // 2 Gang if (touch.x <= 5) bs_button_1->publish_state(true); else bs_button_2->publish_state(true); break; case 3: // 3 Gang if (touch.x <= 3) bs_button_1->publish_state(true); else if (touch.x <= 7) bs_button_2->publish_state(true); else bs_button_3->publish_state(true); break; case 4: // 4 Gang if (touch.x <= 2) bs_button_1->publish_state(true); else if (touch.x <= 5) bs_button_2->publish_state(true); else if (touch.x <= 8) bs_button_3->publish_state(true); else bs_button_4->publish_state(true); break; } } on_release: - lambda: |- if (sl_touch_vibration_feedback->state == "On release" or sl_touch_vibration_feedback->state == "Always") vibrate->execute(); if (bs_button_1->state) bs_button_1->publish_state(false); if (bs_button_2->state) bs_button_2->publish_state(false); if (bs_button_3->state) bs_button_3->publish_state(false); if (bs_button_4->state) bs_button_4->publish_state(false); uart: id: uart_touch tx_pin: GPIO19 rx_pin: GPIO22 baud_rate: 115200 web_server: wifi: ap: