From d4e741216c9d83934f5ad6c64911171dad4e3e1d Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Fri, 24 May 2024 14:12:33 +0200 Subject: [PATCH 01/28] First draft --- .gitignore | 2 + ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml | 192 +++++++++++++++++++++ README.md | 56 ++++++ TX-Ultimate-Easy-ESPHome.yaml | 15 ++ 4 files changed, 265 insertions(+) create mode 100644 .gitignore create mode 100644 ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml create mode 100644 TX-Ultimate-Easy-ESPHome.yaml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f232f71 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.cmd +*.bat diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml new file mode 100644 index 0000000..11e0173 --- /dev/null +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml @@ -0,0 +1,192 @@ +substitutions: + name: tx-ultimate + friendly_name: TX Ultimate + + led_pin: GPIO13 + status_led_pin: GPIO33 + + audio_sdata_pin: GPIO15 + +api: + +binary_sensor: + - id: bs_vibrating + name: Vibrating + icon: mdi:vibrate + internal: false + platform: template + lambda: return sw_vibration_motor->state; + +# 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: + - switch.turn_on: sw_vibration_motor + - delay: !lambda return nr_vibrating_duration->state; + - switch.turn_off: sw_vibration_motor + +captive_portal: + +esp32: + board: esp32dev + framework: + type: esp-idf + 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} + 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()) { + sw_relay_1->set_internal(false); + sw_relay_2->set_internal(index.value() < 1); + sw_relay_3->set_internal(index.value() < 2); + sw_relay_4->set_internal(index.value() < 3); + } + +i2s_audio: + id: if_i2s_audio + i2s_lrclk_pin: GPIO4 + i2s_bclk_pin: GPIO2 + +logger: + +number: + - id: nr_vibrating_duration + name: Vibrate duration + icon: mdi:vibrate + unit_of_measurement: ms + mode: box + internal: false + platform: template + min_value: 10 + max_value: 3000 + step: 1 + initial_value: 50 + optimistic: true + restore_value: true + +ota: + +psram: + +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 + +switch: + - id: sw_pa_power + name: PA - Power + platform: gpio + pin: GPIO26 + restore_mode: ALWAYS_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: true + + - 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); + +uart: + id: if_uart_touch + tx_pin: GPIO19 + rx_pin: GPIO22 + baud_rate: 115200 + debug: + direction: BOTH #RX + dummy_receiver: false + after: + timeout: 2s + bytes: 2048 + sequence: + #- lambda: UARTDebug::log_string(direction, bytes); + - lambda: UARTDebug::log_hex(direction, bytes, ' '); + +wifi: + ap: diff --git a/README.md b/README.md index e5c5ecc..1a8d48f 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,58 @@ # TX-Ultimate-Easy ESPHome based custom firmware for Sonoff TX Ultimate. Easy to setup. + +# TX Ultimate Easy + +Welcome to TX Ultimate Easy! This project aims to provide custom firmware for Sonoff TX Ultimate devices based on ESPHome, making it easy for even the least tech-savvy users to configure and use. Our goal is to have all the configurations manageable directly through the Home Assistant UI or via blueprints, eliminating the need to edit YAML files manually. + +## Features + +- **Simple Setup:** Configure your Sonoff TX Ultimate through Home Assistant UI. +- **No YAML Editing:** All settings are adjustable without touching YAML files after the initial setup. +- **User-Friendly:** Designed for users of all technical levels. +- **Customizable:** Flexibility to adapt the firmware to your needs. +- **Seamless Integration:** Works flawlessly with Home Assistant. + +## Getting Started + +### Prerequisites + +- Sonoff TX Ultimate device +- Home Assistant installed +- ESPHome add-on installed in Home Assistant + +### Installation +To be written. + +### Configuration + +- **Via Home Assistant UI:** + All device settings can be managed through the Home Assistant interface. No need to edit YAML files directly. + +- **Using Blueprints:** + Import and use blueprints to quickly configure your device for common use cases. + +## Documentation +To be written. + +## Contributing + +We welcome contributions from the community. If you have ideas for new features, improvements, or bug fixes, please open an issue or submit a pull request. + +## License + +This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. + +## Acknowledgments + +This project is highly inspired by these other projects: +- [SmartHome yourself - SONOFF TX Ultimate for ESPHome (Custom Component)](https://github.com/SmartHome-yourself/sonoff-tx-ultimate-for-esphome) +- [Un loco y su tecnologĂ­a - Sonoff TX Ultimate with ESPHome | Absolute power](https://www.youtube.com/watch?v=58v8oqSQgXQ) + +Thanks a lot for sharing all your discoveries and ideas. + +## Support + +If you find this project helpful, consider supporting us through Buy Me a Coffee: + +[![Buy Me a Coffee](https://www.buymeacoffee.com/assets/img/custom_images/yellow_img.png)](https://www.buymeacoffee.com/edwardfirmo) diff --git a/TX-Ultimate-Easy-ESPHome.yaml b/TX-Ultimate-Easy-ESPHome.yaml new file mode 100644 index 0000000..61290cc --- /dev/null +++ b/TX-Ultimate-Easy-ESPHome.yaml @@ -0,0 +1,15 @@ +substitutions: + name: tx-ultimate-easy + friendly_name: TX Ultimate Easy + +wifi: + ssid: !secret wifi_ssid + password: !secret wifi_password + +packages: + remote_package: + url: https://github.com/edwardtfn/TX-Ultimate-Easy + ref: dev + refresh: 30s + files: + - ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml From 1621f09038c8b4e169e20878375b35b3da7a2907 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Fri, 24 May 2024 14:42:15 +0200 Subject: [PATCH 02/28] Added light --- ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml | 71 +++++++++++++++++++--- 1 file changed, 64 insertions(+), 7 deletions(-) diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml index 11e0173..2ed279f 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml @@ -1,11 +1,6 @@ substitutions: - name: tx-ultimate - friendly_name: TX Ultimate - - led_pin: GPIO13 - status_led_pin: GPIO33 - - audio_sdata_pin: GPIO15 + name: tx-ultimate-easy + friendly_name: TX Ultimate Easy api: @@ -77,6 +72,66 @@ i2s_audio: i2s_lrclk_pin: GPIO4 i2s_bclk_pin: GPIO2 +light: + - id: light_led + name: Light - LED + platform: esp32_rmt_led_strip + rgb_order: GRB + pin: GPIO33 + num_leds: 28 + rmt_channel: 0 + chipset: ws2812 + 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_status +# name: Light - Status +# platform: esp32_rmt_led_strip +# rgb_order: GRB +# pin: GPIO13 +# num_leds: 1 +# rmt_channel: 0 +# chipset: ws2812 + logger: number: @@ -188,5 +243,7 @@ uart: #- lambda: UARTDebug::log_string(direction, bytes); - lambda: UARTDebug::log_hex(direction, bytes, ' '); +web_server: + wifi: ap: From 13fa6dc58376f64aa08600a8928198f34cc5acaf Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Fri, 24 May 2024 23:53:10 +0200 Subject: [PATCH 03/28] Add files via upload --- 44592A30-6A11-4082-BAD8-19E41B940F78.webp | Bin 0 -> 266974 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 44592A30-6A11-4082-BAD8-19E41B940F78.webp diff --git a/44592A30-6A11-4082-BAD8-19E41B940F78.webp b/44592A30-6A11-4082-BAD8-19E41B940F78.webp new file mode 100644 index 0000000000000000000000000000000000000000..1a5cc8dd89594a9cbf75bd579ec8419dc03e161a GIT binary patch literal 266974 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 literal 0 HcmV?d00001 From ebc8cdb8f0316c6b0508fc4cd9d2d5239e2930f8 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Fri, 24 May 2024 23:54:04 +0200 Subject: [PATCH 04/28] Create empty --- Assets/empty | 1 + 1 file changed, 1 insertion(+) create mode 100644 Assets/empty diff --git a/Assets/empty b/Assets/empty new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Assets/empty @@ -0,0 +1 @@ + From 675068e82599afd65461a2b3692d12343522cbfb Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Fri, 24 May 2024 23:54:56 +0200 Subject: [PATCH 05/28] Rename 44592A30-6A11-4082-BAD8-19E41B940F78.webp to Assets/Logo.webp --- .../Logo.webp | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename 44592A30-6A11-4082-BAD8-19E41B940F78.webp => Assets/Logo.webp (100%) diff --git a/44592A30-6A11-4082-BAD8-19E41B940F78.webp b/Assets/Logo.webp similarity index 100% rename from 44592A30-6A11-4082-BAD8-19E41B940F78.webp rename to Assets/Logo.webp From f63204accfebed82408ab96fe9ed59be970385a7 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Fri, 24 May 2024 23:55:54 +0200 Subject: [PATCH 06/28] Delete Assets/empty --- Assets/empty | 1 - 1 file changed, 1 deletion(-) delete mode 100644 Assets/empty diff --git a/Assets/empty b/Assets/empty deleted file mode 100644 index 8b13789..0000000 --- a/Assets/empty +++ /dev/null @@ -1 +0,0 @@ - From a4557e8c40fed18ee2975c3ae2486d9750815931 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Fri, 24 May 2024 23:57:22 +0200 Subject: [PATCH 07/28] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 1a8d48f..d176e98 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # TX-Ultimate-Easy ESPHome based custom firmware for Sonoff TX Ultimate. Easy to setup. +![TX Ultimate Easy logo](Assets/Logo.webp) + # TX Ultimate Easy Welcome to TX Ultimate Easy! This project aims to provide custom firmware for Sonoff TX Ultimate devices based on ESPHome, making it easy for even the least tech-savvy users to configure and use. Our goal is to have all the configurations manageable directly through the Home Assistant UI or via blueprints, eliminating the need to edit YAML files manually. From 7730ed7ddc518d4492f852dfd2cc8e0e18200eb4 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Fri, 24 May 2024 23:59:29 +0200 Subject: [PATCH 08/28] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d176e98..64ff18c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # TX-Ultimate-Easy ESPHome based custom firmware for Sonoff TX Ultimate. Easy to setup. -![TX Ultimate Easy logo](Assets/Logo.webp) +TX Ultimate Easy Logo # TX Ultimate Easy From a1b6568466f660ec88f0be01b78a15a2ceb4b1b0 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Sat, 25 May 2024 00:08:17 +0200 Subject: [PATCH 09/28] Update README.md --- README.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 64ff18c..64ef6f6 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,7 @@ -# TX-Ultimate-Easy -ESPHome based custom firmware for Sonoff TX Ultimate. Easy to setup. - -TX Ultimate Easy Logo - # TX Ultimate Easy -Welcome to TX Ultimate Easy! This project aims to provide custom firmware for Sonoff TX Ultimate devices based on ESPHome, making it easy for even the least tech-savvy users to configure and use. Our goal is to have all the configurations manageable directly through the Home Assistant UI or via blueprints, eliminating the need to edit YAML files manually. +|  ![TX Ultimate Easy Logo](Assets/Logo.webp) | Welcome to TX Ultimate Easy! This project aims to provide custom firmware for Sonoff TX Ultimate devices based on ESPHome, making it easy for even the least tech-savvy users to configure and use. Our goal is to have all the configurations manageable directly through the Home Assistant UI or via blueprints, eliminating the need to edit YAML files manually. | +| --- | :-- | ## Features @@ -58,3 +54,6 @@ Thanks a lot for sharing all your discoveries and ideas. If you find this project helpful, consider supporting us through Buy Me a Coffee: [![Buy Me a Coffee](https://www.buymeacoffee.com/assets/img/custom_images/yellow_img.png)](https://www.buymeacoffee.com/edwardfirmo) + + +TX Ultimate Easy Logo From ee1dd911f281439c808df6285c375a2822bfcb51 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Mon, 27 May 2024 01:16:57 +0200 Subject: [PATCH 10/28] Change framework to Arduino --- ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml | 36 +++++++++++++++------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml index 2ed279f..87e9e45 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml @@ -37,21 +37,33 @@ esp32: board: esp32dev framework: type: esp-idf - 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" +# 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: + - -DDCONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST=true + - -DDCONFIG_BT_BLE_DYNAMIC_ENV_MEMORY=true + - -DDCONFIG_ESP32_REV_MIN_3=true + - -DDCONFIG_MBEDTLS_DYNAMIC_BUFFER=true + - -DDCONFIG_MBEDTLS_DYNAMIC_FREE_CA_CERT=true + - -DDCONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA=true + - -DDCONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC=true + - -DDCONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=true + - -DDCONFIG_SPIRAM_RODATA=true + - -DDCONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=true on_boot: - priority: 700 then: @@ -75,11 +87,13 @@ i2s_audio: light: - id: light_led name: Light - LED + # platform: neopixelbus platform: esp32_rmt_led_strip rgb_order: GRB pin: GPIO33 num_leds: 28 rmt_channel: 0 + # chipset: ws2811 chipset: ws2812 effects: - addressable_rainbow: From ca976fde425f67e2d2a45a16f235558a95616ef5 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Mon, 27 May 2024 01:18:56 +0200 Subject: [PATCH 11/28] Change framework to Arduino --- ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml index 87e9e45..abd7ba2 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml @@ -36,7 +36,8 @@ captive_portal: esp32: board: esp32dev framework: - type: esp-idf + # type: esp-idf + type: arduino # sdkconfig_options: # CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST: "y" # CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY: "y" @@ -87,14 +88,14 @@ i2s_audio: light: - id: light_led name: Light - LED - # platform: neopixelbus - platform: esp32_rmt_led_strip + platform: neopixelbus + # platform: esp32_rmt_led_strip rgb_order: GRB pin: GPIO33 num_leds: 28 rmt_channel: 0 - # chipset: ws2811 - chipset: ws2812 + chipset: ws2811 + # chipset: ws2812 effects: - addressable_rainbow: - addressable_rainbow: From 99cc9f8b7958ba172d8f58334e4919ee65085113 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Mon, 27 May 2024 01:44:00 +0200 Subject: [PATCH 12/28] Switch light platform to neopixelbus and mediaplayer --- ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml index abd7ba2..c83c9ef 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml @@ -89,13 +89,14 @@ light: - id: light_led name: Light - LED platform: neopixelbus + type: GRB + variant: WS2811 # platform: esp32_rmt_led_strip - rgb_order: GRB - pin: GPIO33 - num_leds: 28 - rmt_channel: 0 - chipset: ws2811 + # rgb_order: GRB + # rmt_channel: 0 # chipset: ws2812 + num_leds: 28 + pin: GPIO33 effects: - addressable_rainbow: - addressable_rainbow: @@ -149,6 +150,16 @@ light: logger: +media_player: + - id: mp_audio + name: Audio player + platform: i2s_audio + i2s_dout_pin: GPIO15 + i2s_audio_id: if_i2s_audio + i2s_comm_fmt: lsb + dac_type: external + internal: false + number: - id: nr_vibrating_duration name: Vibrate duration From eba7a98defdb1ea8dacb9f5dda9c66f783af57f8 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Mon, 27 May 2024 01:51:56 +0200 Subject: [PATCH 13/28] Add version sensor --- ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml index c83c9ef..470b8c0 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml @@ -2,6 +2,8 @@ substitutions: name: tx-ultimate-easy friendly_name: TX Ultimate Easy + version: 0.0.1 + api: binary_sensor: @@ -254,6 +256,17 @@ switch: 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}"}; + uart: id: if_uart_touch tx_pin: GPIO19 From 1d1e8e4240385b43670542ed8a0bfc82fdc7043b Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Mon, 27 May 2024 09:43:00 +0200 Subject: [PATCH 14/28] Fix: Build flags --- ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml index 470b8c0..99a5c34 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml @@ -57,16 +57,16 @@ esphome: friendly_name: ${friendly_name} platformio_options: build_flags: - - -DDCONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST=true - - -DDCONFIG_BT_BLE_DYNAMIC_ENV_MEMORY=true - - -DDCONFIG_ESP32_REV_MIN_3=true - - -DDCONFIG_MBEDTLS_DYNAMIC_BUFFER=true - - -DDCONFIG_MBEDTLS_DYNAMIC_FREE_CA_CERT=true - - -DDCONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA=true - - -DDCONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC=true - - -DDCONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=true - - -DDCONFIG_SPIRAM_RODATA=true - - -DDCONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=true + - -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: From 6dca6fcaaff17481d574f84ccc1091d4cc6af354 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Mon, 27 May 2024 11:12:56 +0200 Subject: [PATCH 15/28] Update TX-Ultimate-Easy-ESPHome_core.yaml --- ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml | 38 ++++++++++++++-------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml index 99a5c34..f6b3a5e 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml @@ -81,11 +81,14 @@ esphome: sw_relay_3->set_internal(index.value() < 2); sw_relay_4->set_internal(index.value() < 3); } + - priority: -100 + then: + - lambda: tx_fw_version->publish_state("${version}"); i2s_audio: id: if_i2s_audio - i2s_lrclk_pin: GPIO4 i2s_bclk_pin: GPIO2 + i2s_lrclk_pin: GPIO4 light: - id: light_led @@ -98,7 +101,7 @@ light: # rmt_channel: 0 # chipset: ws2812 num_leds: 28 - pin: GPIO33 + pin: GPIO13 effects: - addressable_rainbow: - addressable_rainbow: @@ -153,13 +156,18 @@ light: logger: media_player: - - id: mp_audio - name: Audio 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: @@ -167,16 +175,15 @@ number: name: Vibrate duration icon: mdi:vibrate unit_of_measurement: ms - mode: box + # mode: box internal: false platform: template - min_value: 10 - max_value: 3000 + min_value: 1 + max_value: 500 step: 1 - initial_value: 50 + initial_value: 15 optimistic: true restore_value: true - ota: psram: @@ -199,11 +206,14 @@ select: icon: mdi:dip-switch switch: - - id: sw_pa_power - name: PA - Power + - id: sw_speaker_aplifier + name: Speaker - Aplifier platform: gpio - pin: GPIO26 - restore_mode: ALWAYS_ON + pin: + number: GPIO26 + inverted: true + allow_other_uses: true + restore_mode: RESTORE_DEFAULT_ON internal: true - id: sw_relay_1 @@ -279,7 +289,7 @@ uart: timeout: 2s bytes: 2048 sequence: - #- lambda: UARTDebug::log_string(direction, bytes); + # - lambda: UARTDebug::log_string(direction, bytes); - lambda: UARTDebug::log_hex(direction, bytes, ' '); web_server: From 19d3fe202fcd1b623cd5b0515a9128a5d6ca5446 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Mon, 27 May 2024 13:24:43 +0200 Subject: [PATCH 16/28] Add sun support To be changed later getting data from the blueprint --- ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml | 44 ++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml index f6b3a5e..9363012 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml @@ -5,6 +5,18 @@ substitutions: 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 @@ -205,6 +217,34 @@ select: 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: 90 + longitude: 180 + switch: - id: sw_speaker_aplifier name: Speaker - Aplifier @@ -277,6 +317,10 @@ text_sensor: lambda: |- return {"${version}"}; +time: + - id: time_source + platform: homeassistant + uart: id: if_uart_touch tx_pin: GPIO19 From 75363c1b626090593fe2e5d63ddae6434e9fb7e4 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Mon, 27 May 2024 13:59:10 +0200 Subject: [PATCH 17/28] Add component `tx_ultimate_easy` Based on https://github.com/SmartHome-yourself/sonoff-tx-ultimate-for-esphome --- ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml | 56 ++++- .../components/tx_ultimate_easy/__init__.py | 99 +++++++++ .../tx_ultimate_easy/tx_ultimate_easy.cpp | 204 ++++++++++++++++++ .../tx_ultimate_easy/tx_ultimate_easy.h | 68 ++++++ 4 files changed, 420 insertions(+), 7 deletions(-) create mode 100644 ESPHome/components/tx_ultimate_easy/__init__.py create mode 100644 ESPHome/components/tx_ultimate_easy/tx_ultimate_easy.cpp create mode 100644 ESPHome/components/tx_ultimate_easy/tx_ultimate_easy.h diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml index 9363012..d7385da 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml @@ -2,7 +2,11 @@ substitutions: name: tx-ultimate-easy friendly_name: TX Ultimate Easy - version: 0.0.1 + latitude: '0' + longitude: '0' + zone_home: 'zone.home' + + version: '0.0.1' api: id: api_server @@ -93,9 +97,20 @@ esphome: sw_relay_3->set_internal(index.value() < 2); sw_relay_4->set_internal(index.value() < 3); } - - priority: -100 + - priority: 600 # This is where most sensors are set up. then: - - lambda: tx_fw_version->publish_state("${version}"); + - 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 + path: ESPHome/components + components: + - tx_ultimate_easy i2s_audio: id: if_i2s_audio @@ -226,7 +241,7 @@ sensor: - id: zone_home_latitude platform: homeassistant - entity_id: zone.home + entity_id: ${zone_home} attribute: latitude internal: false on_value: @@ -234,7 +249,7 @@ sensor: - id: zone_home_longitude platform: homeassistant - entity_id: zone.home + entity_id: ${zone_home} attribute: longitude internal: false on_value: @@ -242,8 +257,8 @@ sensor: sun: id: sun_entity - latitude: 90 - longitude: 180 + latitude: ${latitude} + longitude: ${longitude} switch: - id: sw_speaker_aplifier @@ -317,10 +332,37 @@ text_sensor: 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: + uart: id: if_uart_touch tx_pin: GPIO19 diff --git a/ESPHome/components/tx_ultimate_easy/__init__.py b/ESPHome/components/tx_ultimate_easy/__init__.py new file mode 100644 index 0000000..edac612 --- /dev/null +++ b/ESPHome/components/tx_ultimate_easy/__init__.py @@ -0,0 +1,99 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome.components import uart +from esphome.const import ( + CONF_ID, +) + +from esphome import automation + +CODEOWNERS = ["@edwardtfn"] +DEPENDENCIES = ['uart'] + +CONF_TX_ULTIMATE_EASY = "tx_ultimate_easy" + +CONF_UART = "uart" + +CONF_ON_PRESS = "on_press" +CONF_ON_RELEASE = "on_release" + +CONF_ON_SWIPE_LEFT = "on_swipe_left" +CONF_ON_SWIPE_RIGHT = "on_swipe_right" + +CONF_ON_FULL_TOUCH_RELEASE = "on_full_touch_release" +CONF_ON_LONG_TOUCH_RELEASE = "on_long_touch_release" + +tx_ultimate_easy_ns = cg.esphome_ns.namespace('tx_ultimate_easy') +TouchPoint = tx_ultimate_easy_ns.struct("TouchPoint") + +TxUltimateTouch = tx_ultimate_easy_ns.class_( + 'TxUltimateEasy', cg.Component, uart.UARTDevice) + + +CONFIG_SCHEMA = cv.Schema({ + cv.GenerateID(): cv.declare_id(TxUltimateTouch), + + cv.Required(CONF_UART): cv.use_id(uart), + + cv.Optional(CONF_ON_PRESS): automation.validate_automation(single=True), + cv.Optional(CONF_ON_RELEASE): automation.validate_automation(single=True), + cv.Optional(CONF_ON_SWIPE_LEFT): automation.validate_automation(single=True), + cv.Optional(CONF_ON_SWIPE_RIGHT): automation.validate_automation(single=True), + cv.Optional(CONF_ON_FULL_TOUCH_RELEASE): automation.validate_automation(single=True), + cv.Optional(CONF_ON_LONG_TOUCH_RELEASE): automation.validate_automation(single=True), + +}).extend(cv.COMPONENT_SCHEMA).extend(uart.UART_DEVICE_SCHEMA) + + +async def register_tx_ultimate_easy(var, config): + uart_component = await cg.get_variable(config[CONF_UART]) + cg.add(var.set_uart_component(uart_component)) + + if CONF_ON_PRESS in config: + await automation.build_automation( + var.get_touch_trigger(), + [(TouchPoint, "touch")], + config[CONF_ON_PRESS], + ) + + if CONF_ON_RELEASE in config: + await automation.build_automation( + var.get_release_trigger(), + [(TouchPoint, "touch")], + config[CONF_ON_RELEASE], + ) + + if CONF_ON_SWIPE_LEFT in config: + await automation.build_automation( + var.get_swipe_left_trigger(), + [(TouchPoint, "touch")], + config[CONF_ON_SWIPE_LEFT], + ) + + if CONF_ON_SWIPE_RIGHT in config: + await automation.build_automation( + var.get_swipe_right_trigger(), + [(TouchPoint, "touch")], + config[CONF_ON_SWIPE_RIGHT], + ) + + if CONF_ON_FULL_TOUCH_RELEASE in config: + await automation.build_automation( + var.get_full_touch_release_trigger(), + [(TouchPoint, "touch")], + config[CONF_ON_FULL_TOUCH_RELEASE], + ) + + if CONF_ON_LONG_TOUCH_RELEASE in config: + await automation.build_automation( + var.get_long_touch_release_trigger(), + [(TouchPoint, "touch")], + config[CONF_ON_LONG_TOUCH_RELEASE], + ) + +async def to_code(config): + var = cg.new_Pvariable(config[CONF_ID]) + await cg.register_component(var, config) + await uart.register_uart_device(var, config) + + await register_tx_ultimate_easy(var, config) diff --git a/ESPHome/components/tx_ultimate_easy/tx_ultimate_easy.cpp b/ESPHome/components/tx_ultimate_easy/tx_ultimate_easy.cpp new file mode 100644 index 0000000..5bd5af9 --- /dev/null +++ b/ESPHome/components/tx_ultimate_easy/tx_ultimate_easy.cpp @@ -0,0 +1,204 @@ +#include "esphome/core/log.h" +#include "tx_ultimate_easy.h" + +namespace esphome +{ + namespace tx_ultimate_easy + { + static const char *TAG = "tx_ultimate_easy"; + + void TxUltimateEasy::setup() + { + ESP_LOGI("log", "%s", "Tx Ultimate Touch is initialized"); + } + + void TxUltimateEasy::loop() + { + bool found = false; + + int bytes[15] = {}; + int byte = -1; + int i = 0; + + while (this->available()) + { + byte = this->read(); + if (byte == 170) + { + handle_touch(bytes); + i = 0; + } + + bytes[i] = byte; + + i++; + + if (byte != 0) + { + found = true; + } + }; + + if (found) + { + handle_touch(bytes); + } + } + + void TxUltimateEasy::handle_touch(int bytes[]) + { + ESP_LOGV("UART-Log", "------------"); + for (int i = 0; i < 15; i++) + { + ESP_LOGV("UART-Log", "%i", bytes[i]); + } + + if (is_valid_data(bytes)) + { + send_touch_(get_touch_point(bytes)); + } + } + + void TxUltimateEasy::dump_config() + { + ESP_LOGCONFIG(TAG, "Tx Ultimate Touch"); + } + + void TxUltimateEasy::send_touch_(TouchPoint tp) + { + switch (tp.state) + { + case TOUCH_STATE_RELEASE: + if (tp.x >= 17) + { + tp.x = tp.x - 16; + ESP_LOGD(TAG, "Long Press Release (x=%d)", tp.x); + this->long_touch_release_trigger_.trigger(tp); + } + else + { + ESP_LOGD(TAG, "Release (x=%d)", tp.x); + this->release_trigger_.trigger(tp); + } + break; + + case TOUCH_STATE_PRESS: + ESP_LOGD(TAG, "Press (x=%d)", tp.x); + this->touch_trigger_.trigger(tp); + break; + + case TOUCH_STATE_SWIPE_LEFT: + ESP_LOGD(TAG, "Swipe Left (x=%d)", tp.x); + this->swipe_trigger_left_.trigger(tp); + break; + + case TOUCH_STATE_SWIPE_RIGHT: + ESP_LOGD(TAG, "Swipe Right (x=%d)", tp.x); + this->swipe_trigger_right_.trigger(tp); + break; + + case TOUCH_STATE_ALL_FIELDS: + ESP_LOGD(TAG, "Full Touch Release"); + this->full_touch_release_trigger_.trigger(tp); + break; + + default: + break; + } + } + + bool TxUltimateEasy::is_valid_data(int bytes[]) + { + bool valid = true; + + if (!(bytes[0] == 170 && bytes[1] == 85 && bytes[2] == 1 && bytes[3] == 2)) + { + return false; + } + + int state = get_touch_state(bytes); + if (state != TOUCH_STATE_PRESS && + state != TOUCH_STATE_RELEASE && + state != TOUCH_STATE_SWIPE_LEFT && + state != TOUCH_STATE_SWIPE_RIGHT && + state != TOUCH_STATE_ALL_FIELDS) + { + return false; + } + + if (bytes[6] < 0 && state != TOUCH_STATE_ALL_FIELDS) + { + return false; + } + + return true; + } + + int TxUltimateEasy::get_x_touch_position(int bytes[]) + { + int state = bytes[4]; + switch (state) + { + case TOUCH_STATE_RELEASE: + return bytes[5]; + break; + + case TOUCH_STATE_ALL_FIELDS: + return bytes[5]; + break; + + case TOUCH_STATE_SWIPE_LEFT: + return bytes[5]; + break; + + case TOUCH_STATE_SWIPE_RIGHT: + return bytes[5]; + break; + + default: + return bytes[6]; + break; + } + } + + int TxUltimateEasy::get_touch_state(int bytes[]) + { + int state = bytes[4]; + + if (state == TOUCH_STATE_PRESS && bytes[5] != 0) + { + state = TOUCH_STATE_RELEASE; + } + + if (state == TOUCH_STATE_RELEASE && bytes[5] == TOUCH_STATE_ALL_FIELDS) + { + state = TOUCH_STATE_ALL_FIELDS; + } + + if (state == TOUCH_STATE_SWIPE) + { + if (bytes[5] == TOUCH_STATE_SWIPE_RIGHT) + { + state = TOUCH_STATE_SWIPE_RIGHT; + } + else if (bytes[5] == TOUCH_STATE_SWIPE_LEFT) + { + state = TOUCH_STATE_SWIPE_LEFT; + } + } + + return state; + } + + TouchPoint TxUltimateEasy::get_touch_point(int bytes[]) + { + TouchPoint tp; + + tp.x = get_x_touch_position(bytes); + tp.state = get_touch_state(bytes); + + return tp; + } + + } // namespace tx_ultimate_easy +} // namespace esphome \ No newline at end of file diff --git a/ESPHome/components/tx_ultimate_easy/tx_ultimate_easy.h b/ESPHome/components/tx_ultimate_easy/tx_ultimate_easy.h new file mode 100644 index 0000000..54f33a2 --- /dev/null +++ b/ESPHome/components/tx_ultimate_easy/tx_ultimate_easy.h @@ -0,0 +1,68 @@ +#pragma once + +#include "esphome/core/automation.h" +#include "esphome/core/component.h" +#include "esphome/components/uart/uart.h" +#include "esphome/components/uart/uart_component.h" +#include "esphome/components/binary_sensor/binary_sensor.h" +#include "esphome/components/switch/switch.h" +#include "esphome/components/light/addressable_light.h" + +namespace esphome +{ + namespace tx_ultimate_easy + { + const static uint8_t TOUCH_STATE_RELEASE = 1; + const static uint8_t TOUCH_STATE_PRESS = 2; + const static uint8_t TOUCH_STATE_SWIPE = 3; + + const static uint8_t TOUCH_STATE_ALL_FIELDS = 11; + + const static uint8_t TOUCH_STATE_SWIPE_RIGHT = 12; + const static uint8_t TOUCH_STATE_SWIPE_LEFT = 13; + + struct TouchPoint + { + int8_t x = -1; + int8_t state = -1; + }; + + class TxUltimateEasy : public uart::UARTDevice, public Component + { + public: + Trigger *get_touch_trigger() { return &this->touch_trigger_; } + Trigger *get_release_trigger() { return &this->release_trigger_; } + Trigger *get_swipe_left_trigger() { return &this->swipe_trigger_left_; } + Trigger *get_swipe_right_trigger() { return &this->swipe_trigger_right_; } + Trigger *get_full_touch_release_trigger() { return &this->full_touch_release_trigger_; } + Trigger *get_long_touch_release_trigger() { return &this->long_touch_release_trigger_; } + + void set_uart_component(esphome::uart::UARTComponent *uart_component) + { + this->set_uart_parent(uart_component); + } + + void setup() override; + void loop() override; + void dump_config() override; + + protected: + void send_touch_(TouchPoint tp); + void handle_touch(int bytes[]); + + TouchPoint get_touch_point(int bytes[]); + bool is_valid_data(int bytes[]); + int get_x_touch_position(int bytes[]); + int get_touch_state(int bytes[]); + + Trigger touch_trigger_; + Trigger release_trigger_; + Trigger swipe_trigger_left_; + Trigger swipe_trigger_right_; + Trigger full_touch_release_trigger_; + Trigger long_touch_release_trigger_; + + }; // class TxUltimateEasy + + } // namespace tx_ultimate_easy +} // namespace esphome \ No newline at end of file From 9f8f21c3de40ae2b8987d4a17c221651af9ab194 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Mon, 27 May 2024 14:08:30 +0200 Subject: [PATCH 18/28] Move components to root --- ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml | 1 - {ESPHome/components => components}/tx_ultimate_easy/__init__.py | 0 .../tx_ultimate_easy/tx_ultimate_easy.cpp | 0 .../tx_ultimate_easy/tx_ultimate_easy.h | 0 4 files changed, 1 deletion(-) rename {ESPHome/components => components}/tx_ultimate_easy/__init__.py (100%) rename {ESPHome/components => components}/tx_ultimate_easy/tx_ultimate_easy.cpp (100%) rename {ESPHome/components => components}/tx_ultimate_easy/tx_ultimate_easy.h (100%) diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml index d7385da..f4b3249 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml @@ -108,7 +108,6 @@ external_components: type: git url: https://github.com/edwardtfn/TX-Ultimate-Easy/ ref: dev - path: ESPHome/components components: - tx_ultimate_easy diff --git a/ESPHome/components/tx_ultimate_easy/__init__.py b/components/tx_ultimate_easy/__init__.py similarity index 100% rename from ESPHome/components/tx_ultimate_easy/__init__.py rename to components/tx_ultimate_easy/__init__.py diff --git a/ESPHome/components/tx_ultimate_easy/tx_ultimate_easy.cpp b/components/tx_ultimate_easy/tx_ultimate_easy.cpp similarity index 100% rename from ESPHome/components/tx_ultimate_easy/tx_ultimate_easy.cpp rename to components/tx_ultimate_easy/tx_ultimate_easy.cpp diff --git a/ESPHome/components/tx_ultimate_easy/tx_ultimate_easy.h b/components/tx_ultimate_easy/tx_ultimate_easy.h similarity index 100% rename from ESPHome/components/tx_ultimate_easy/tx_ultimate_easy.h rename to components/tx_ultimate_easy/tx_ultimate_easy.h From 57a8c1307a108e9d8c4e247de405bc53d4444814 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Mon, 27 May 2024 23:13:41 +0200 Subject: [PATCH 19/28] Basic touch event handling --- ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml | 90 +++++- components/tx_ultimate_easy/__init__.py | 32 ++- .../tx_ultimate_easy/tx_ultimate_easy.cpp | 268 +++++++----------- .../tx_ultimate_easy/tx_ultimate_easy.h | 50 ++-- 4 files changed, 226 insertions(+), 214 deletions(-) diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml index f4b3249..e5d7617 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml @@ -30,6 +30,46 @@ binary_sensor: 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 + - delay: !lambda "return (isnan(nr_button_timeout->state) ? 500 : int(nr_button_timeout->state));" + - lambda: bs_button_1->publish_state(false); + + - id: bs_button_2 + name: Button 2 + internal: true + platform: template + on_press: + then: + - switch.toggle: sw_relay_2 + - delay: !lambda "return (isnan(nr_button_timeout->state) ? 500 : int(nr_button_timeout->state));" + - lambda: bs_button_2->publish_state(false); + + - id: bs_button_3 + name: Button 3 + internal: true + platform: template + on_press: + then: + - switch.toggle: sw_relay_3 + - delay: !lambda "return (isnan(nr_button_timeout->state) ? 500 : int(nr_button_timeout->state));" + - lambda: bs_button_3->publish_state(false); + + - id: bs_button_4 + name: Button 4 + internal: true + platform: template + on_press: + then: + - switch.toggle: sw_relay_4 + - delay: !lambda "return (isnan(nr_button_timeout->state) ? 500 : int(nr_button_timeout->state));" + - lambda: bs_button_4->publish_state(false); + # bluetooth_proxy: button: @@ -92,10 +132,19 @@ esphome: - 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(index.value() < 1); - sw_relay_3->set_internal(index.value() < 2); - sw_relay_4->set_internal(index.value() < 3); + 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: @@ -106,7 +155,7 @@ esphome: external_components: - source: type: git - url: https://github.com/edwardtfn/TX-Ultimate-Easy/ + url: https://github.com/edwardtfn/TX-Ultimate-Easy ref: dev components: - tx_ultimate_easy @@ -210,6 +259,20 @@ number: initial_value: 15 optimistic: true restore_value: true + + - id: nr_button_timeout + name: Button timeout + icon: mdi:timer + unit_of_measurement: ms + internal: false + platform: template + min_value: 1 + max_value: 3000 + step: 1 + initial_value: 500 + optimistic: true + restore_value: true + ota: psram: @@ -361,21 +424,20 @@ time: 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); uart: - id: if_uart_touch + id: uart_touch tx_pin: GPIO19 rx_pin: GPIO22 baud_rate: 115200 - debug: - direction: BOTH #RX - dummy_receiver: false - after: - timeout: 2s - bytes: 2048 - sequence: - # - lambda: UARTDebug::log_string(direction, bytes); - - lambda: UARTDebug::log_hex(direction, bytes, ' '); web_server: diff --git a/components/tx_ultimate_easy/__init__.py b/components/tx_ultimate_easy/__init__.py index edac612..545ee57 100644 --- a/components/tx_ultimate_easy/__init__.py +++ b/components/tx_ultimate_easy/__init__.py @@ -14,13 +14,12 @@ CONF_TX_ULTIMATE_EASY = "tx_ultimate_easy" CONF_UART = "uart" +CONF_ON_TOUCH_EVENT = "on_touch_event" CONF_ON_PRESS = "on_press" CONF_ON_RELEASE = "on_release" - CONF_ON_SWIPE_LEFT = "on_swipe_left" CONF_ON_SWIPE_RIGHT = "on_swipe_right" - -CONF_ON_FULL_TOUCH_RELEASE = "on_full_touch_release" +CONF_ON_MULTI_TOUCH_RELEASE = "on_multi_touch_release" CONF_ON_LONG_TOUCH_RELEASE = "on_long_touch_release" tx_ultimate_easy_ns = cg.esphome_ns.namespace('tx_ultimate_easy') @@ -35,11 +34,12 @@ CONFIG_SCHEMA = cv.Schema({ cv.Required(CONF_UART): cv.use_id(uart), + cv.Optional(CONF_ON_TOUCH_EVENT): automation.validate_automation(single=True), cv.Optional(CONF_ON_PRESS): automation.validate_automation(single=True), cv.Optional(CONF_ON_RELEASE): automation.validate_automation(single=True), cv.Optional(CONF_ON_SWIPE_LEFT): automation.validate_automation(single=True), cv.Optional(CONF_ON_SWIPE_RIGHT): automation.validate_automation(single=True), - cv.Optional(CONF_ON_FULL_TOUCH_RELEASE): automation.validate_automation(single=True), + cv.Optional(CONF_ON_MULTI_TOUCH_RELEASE): automation.validate_automation(single=True), cv.Optional(CONF_ON_LONG_TOUCH_RELEASE): automation.validate_automation(single=True), }).extend(cv.COMPONENT_SCHEMA).extend(uart.UART_DEVICE_SCHEMA) @@ -49,44 +49,51 @@ async def register_tx_ultimate_easy(var, config): uart_component = await cg.get_variable(config[CONF_UART]) cg.add(var.set_uart_component(uart_component)) + if CONF_ON_TOUCH_EVENT in config: + await automation.build_automation( + var.get_trigger_touch_event(), + [(TouchPoint, "touch")], + config[CONF_ON_TOUCH_EVENT], + ) + if CONF_ON_PRESS in config: await automation.build_automation( - var.get_touch_trigger(), + var.get_trigger_touch(), [(TouchPoint, "touch")], config[CONF_ON_PRESS], ) if CONF_ON_RELEASE in config: await automation.build_automation( - var.get_release_trigger(), + var.get_trigger_release(), [(TouchPoint, "touch")], config[CONF_ON_RELEASE], ) if CONF_ON_SWIPE_LEFT in config: await automation.build_automation( - var.get_swipe_left_trigger(), + var.get_trigger_swipe_left(), [(TouchPoint, "touch")], config[CONF_ON_SWIPE_LEFT], ) if CONF_ON_SWIPE_RIGHT in config: await automation.build_automation( - var.get_swipe_right_trigger(), + var.get_trigger_swipe_right(), [(TouchPoint, "touch")], config[CONF_ON_SWIPE_RIGHT], ) - if CONF_ON_FULL_TOUCH_RELEASE in config: + if CONF_ON_MULTI_TOUCH_RELEASE in config: await automation.build_automation( - var.get_full_touch_release_trigger(), + var.get_trigger_multi_touch_release(), [(TouchPoint, "touch")], - config[CONF_ON_FULL_TOUCH_RELEASE], + config[CONF_ON_MULTI_TOUCH_RELEASE], ) if CONF_ON_LONG_TOUCH_RELEASE in config: await automation.build_automation( - var.get_long_touch_release_trigger(), + var.get_trigger_long_touch_release(), [(TouchPoint, "touch")], config[CONF_ON_LONG_TOUCH_RELEASE], ) @@ -95,5 +102,4 @@ async def to_code(config): var = cg.new_Pvariable(config[CONF_ID]) await cg.register_component(var, config) await uart.register_uart_device(var, config) - await register_tx_ultimate_easy(var, config) diff --git a/components/tx_ultimate_easy/tx_ultimate_easy.cpp b/components/tx_ultimate_easy/tx_ultimate_easy.cpp index 5bd5af9..5443904 100644 --- a/components/tx_ultimate_easy/tx_ultimate_easy.cpp +++ b/components/tx_ultimate_easy/tx_ultimate_easy.cpp @@ -1,202 +1,152 @@ #include "esphome/core/log.h" #include "tx_ultimate_easy.h" -namespace esphome -{ - namespace tx_ultimate_easy - { +namespace esphome { + namespace tx_ultimate_easy { static const char *TAG = "tx_ultimate_easy"; - void TxUltimateEasy::setup() - { - ESP_LOGI("log", "%s", "Tx Ultimate Touch is initialized"); + void TxUltimateEasy::setup() { + ESP_LOGI("log", "%s", "Tx Ultimate Easy is initialized"); } - void TxUltimateEasy::loop() - { + void TxUltimateEasy::loop() { bool found = false; - - int bytes[15] = {}; + int uart_received_bytes[15] = {}; int byte = -1; int i = 0; - - while (this->available()) - { + while (this->available()) { byte = this->read(); - if (byte == 170) - { - handle_touch(bytes); - i = 0; + if (byte == 170) { + handle_touch(uart_received_bytes); + i = 0; } - - bytes[i] = byte; - + uart_received_bytes[i] = byte; i++; - - if (byte != 0) - { - found = true; + if (byte != 0) { + found = true; } }; + if (found) handle_touch(uart_received_bytes); + } - if (found) - { - handle_touch(bytes); + void TxUltimateEasy::handle_touch(int uart_received_bytes[]) { + ESP_LOGVV(TAG, "------------"); + ESP_LOGVV(TAG, "- UART-Log -"); + ESP_LOGVV(TAG, "------------"); + for (int i = 0; i < 15; i++) ESP_LOGVV(TAG, "UART - Log - Byte[%i]: %i", i, uart_received_bytes[i]); + if (is_valid_data(uart_received_bytes)) send_touch_(get_touch_point(uart_received_bytes)); + } + + void TxUltimateEasy::dump_config() { ESP_LOGCONFIG(TAG, "Tx Ultimate Easy"); } + + void TxUltimateEasy::send_touch_(TouchPoint tp) { + this->trigger_touch_event_.trigger(tp); + switch (tp.state) { + case TOUCH_STATE_RELEASE: + if (tp.x >= 17) { + tp.x = tp.x - 16; + ESP_LOGV(TAG, "Long touch - Released (x=%d)", tp.x); + this->trigger_long_touch_release_.trigger(tp); + } else { + ESP_LOGV(TAG, "Touch - Released (x=%d)", tp.x); + this->trigger_release_.trigger(tp); + } + break; + + case TOUCH_STATE_PRESS: + ESP_LOGV(TAG, "Touch - Pressed (x=%d)", tp.x); + this->trigger_touch_.trigger(tp); + break; + + case TOUCH_STATE_SWIPE_LEFT: + ESP_LOGV(TAG, "Swipe - Left (x=%d)", tp.x); + this->trigger_swipe_left_.trigger(tp); + break; + + case TOUCH_STATE_SWIPE_RIGHT: + ESP_LOGV(TAG, "Swipe - Right (x=%d)", tp.x); + this->trigger_swipe_right_.trigger(tp); + break; + + case TOUCH_STATE_MULTI_TOUCH: + ESP_LOGV(TAG, "Multi touch - Released"); + this->trigger_multi_touch_release_.trigger(tp); + break; + + default: + break; } } - void TxUltimateEasy::handle_touch(int bytes[]) - { - ESP_LOGV("UART-Log", "------------"); - for (int i = 0; i < 15; i++) - { - ESP_LOGV("UART-Log", "%i", bytes[i]); - } - - if (is_valid_data(bytes)) - { - send_touch_(get_touch_point(bytes)); - } - } - - void TxUltimateEasy::dump_config() - { - ESP_LOGCONFIG(TAG, "Tx Ultimate Touch"); - } - - void TxUltimateEasy::send_touch_(TouchPoint tp) - { - switch (tp.state) - { - case TOUCH_STATE_RELEASE: - if (tp.x >= 17) - { - tp.x = tp.x - 16; - ESP_LOGD(TAG, "Long Press Release (x=%d)", tp.x); - this->long_touch_release_trigger_.trigger(tp); - } - else - { - ESP_LOGD(TAG, "Release (x=%d)", tp.x); - this->release_trigger_.trigger(tp); - } - break; - - case TOUCH_STATE_PRESS: - ESP_LOGD(TAG, "Press (x=%d)", tp.x); - this->touch_trigger_.trigger(tp); - break; - - case TOUCH_STATE_SWIPE_LEFT: - ESP_LOGD(TAG, "Swipe Left (x=%d)", tp.x); - this->swipe_trigger_left_.trigger(tp); - break; - - case TOUCH_STATE_SWIPE_RIGHT: - ESP_LOGD(TAG, "Swipe Right (x=%d)", tp.x); - this->swipe_trigger_right_.trigger(tp); - break; - - case TOUCH_STATE_ALL_FIELDS: - ESP_LOGD(TAG, "Full Touch Release"); - this->full_touch_release_trigger_.trigger(tp); - break; - - default: - break; - } - } - - bool TxUltimateEasy::is_valid_data(int bytes[]) - { + bool TxUltimateEasy::is_valid_data(int uart_received_bytes[]) { bool valid = true; + if (!(uart_received_bytes[0] == 170 && uart_received_bytes[1] == 85 && uart_received_bytes[2] == 1 && uart_received_bytes[3] == 2)) return false; - if (!(bytes[0] == 170 && bytes[1] == 85 && bytes[2] == 1 && bytes[3] == 2)) - { - return false; - } - - int state = get_touch_state(bytes); + int state = get_touch_state(uart_received_bytes); if (state != TOUCH_STATE_PRESS && state != TOUCH_STATE_RELEASE && state != TOUCH_STATE_SWIPE_LEFT && state != TOUCH_STATE_SWIPE_RIGHT && - state != TOUCH_STATE_ALL_FIELDS) - { + state != TOUCH_STATE_MULTI_TOUCH) return false; - } - if (bytes[6] < 0 && state != TOUCH_STATE_ALL_FIELDS) - { - return false; - } + if (uart_received_bytes[6] < 0 && state != TOUCH_STATE_MULTI_TOUCH) return false; return true; } - int TxUltimateEasy::get_x_touch_position(int bytes[]) - { - int state = bytes[4]; - switch (state) - { - case TOUCH_STATE_RELEASE: - return bytes[5]; - break; + int TxUltimateEasy::get_touch_position_x(int uart_received_bytes[]) { + int state = uart_received_bytes[4]; + switch (state) { + case TOUCH_STATE_RELEASE: + case TOUCH_STATE_MULTI_TOUCH: + case TOUCH_STATE_SWIPE_LEFT: + case TOUCH_STATE_SWIPE_RIGHT: + return uart_received_bytes[5]; + break; - case TOUCH_STATE_ALL_FIELDS: - return bytes[5]; - break; - - case TOUCH_STATE_SWIPE_LEFT: - return bytes[5]; - break; - - case TOUCH_STATE_SWIPE_RIGHT: - return bytes[5]; - break; - - default: - return bytes[6]; - break; + default: + return uart_received_bytes[6]; + break; } } - int TxUltimateEasy::get_touch_state(int bytes[]) - { - int state = bytes[4]; - - if (state == TOUCH_STATE_PRESS && bytes[5] != 0) - { - state = TOUCH_STATE_RELEASE; + int TxUltimateEasy::get_touch_state(int uart_received_bytes[]) { + int state = uart_received_bytes[4]; + if (state == TOUCH_STATE_PRESS && uart_received_bytes[5] != 0) state = TOUCH_STATE_RELEASE; + if (state == TOUCH_STATE_RELEASE && uart_received_bytes[5] == TOUCH_STATE_MULTI_TOUCH) state = TOUCH_STATE_MULTI_TOUCH; + if (state == TOUCH_STATE_SWIPE) { + if (uart_received_bytes[5] == TOUCH_STATE_SWIPE_RIGHT) state = TOUCH_STATE_SWIPE_RIGHT; + else if (uart_received_bytes[5] == TOUCH_STATE_SWIPE_LEFT) state = TOUCH_STATE_SWIPE_LEFT; } - - if (state == TOUCH_STATE_RELEASE && bytes[5] == TOUCH_STATE_ALL_FIELDS) - { - state = TOUCH_STATE_ALL_FIELDS; - } - - if (state == TOUCH_STATE_SWIPE) - { - if (bytes[5] == TOUCH_STATE_SWIPE_RIGHT) - { - state = TOUCH_STATE_SWIPE_RIGHT; - } - else if (bytes[5] == TOUCH_STATE_SWIPE_LEFT) - { - state = TOUCH_STATE_SWIPE_LEFT; - } - } - return state; } - TouchPoint TxUltimateEasy::get_touch_point(int bytes[]) - { + TouchPoint TxUltimateEasy::get_touch_point(int uart_received_bytes[]) { TouchPoint tp; - - tp.x = get_x_touch_position(bytes); - tp.state = get_touch_state(bytes); - + tp.x = get_touch_position_x(uart_received_bytes); + tp.state = get_touch_state(uart_received_bytes); + tp.state_str = "Unknown"; + switch (tp.state) { + case TOUCH_STATE_RELEASE: + tp.state_str = "RELEASE"; + break; + case TOUCH_STATE_PRESS: + tp.state_str = "PRESS"; + break; + case TOUCH_STATE_SWIPE: + tp.state_str = "SWIPE"; + break; + case TOUCH_STATE_MULTI_TOUCH: + tp.state_str = "MULTI_TOUCH"; + break; + case TOUCH_STATE_SWIPE_RIGHT: + tp.state_str = "SWIPE_RIGHT"; + break; + case TOUCH_STATE_SWIPE_LEFT: + tp.state_str = "SWIPE_LEFT"; + break; + } return tp; } diff --git a/components/tx_ultimate_easy/tx_ultimate_easy.h b/components/tx_ultimate_easy/tx_ultimate_easy.h index 54f33a2..033e471 100644 --- a/components/tx_ultimate_easy/tx_ultimate_easy.h +++ b/components/tx_ultimate_easy/tx_ultimate_easy.h @@ -8,39 +8,32 @@ #include "esphome/components/switch/switch.h" #include "esphome/components/light/addressable_light.h" -namespace esphome -{ - namespace tx_ultimate_easy - { +namespace esphome { + namespace tx_ultimate_easy { const static uint8_t TOUCH_STATE_RELEASE = 1; const static uint8_t TOUCH_STATE_PRESS = 2; const static uint8_t TOUCH_STATE_SWIPE = 3; - - const static uint8_t TOUCH_STATE_ALL_FIELDS = 11; - + const static uint8_t TOUCH_STATE_MULTI_TOUCH = 11; const static uint8_t TOUCH_STATE_SWIPE_RIGHT = 12; const static uint8_t TOUCH_STATE_SWIPE_LEFT = 13; - struct TouchPoint - { + struct TouchPoint { int8_t x = -1; int8_t state = -1; + std::string state_str = "Unknown"; }; - class TxUltimateEasy : public uart::UARTDevice, public Component - { + class TxUltimateEasy : public uart::UARTDevice, public Component { public: - Trigger *get_touch_trigger() { return &this->touch_trigger_; } - Trigger *get_release_trigger() { return &this->release_trigger_; } - Trigger *get_swipe_left_trigger() { return &this->swipe_trigger_left_; } - Trigger *get_swipe_right_trigger() { return &this->swipe_trigger_right_; } - Trigger *get_full_touch_release_trigger() { return &this->full_touch_release_trigger_; } - Trigger *get_long_touch_release_trigger() { return &this->long_touch_release_trigger_; } + Trigger *get_trigger_touch_event() { return &this->trigger_touch_event_; } + Trigger *get_trigger_touch() { return &this->trigger_touch_; } + Trigger *get_trigger_release() { return &this->trigger_release_; } + Trigger *get_trigger_swipe_left() { return &this->trigger_swipe_left_; } + Trigger *get_trigger_swipe_right() { return &this->trigger_swipe_right_; } + Trigger *get_trigger_multi_touch_release() { return &this->trigger_multi_touch_release_; } + Trigger *get_trigger_long_touch_release() { return &this->trigger_long_touch_release_; } - void set_uart_component(esphome::uart::UARTComponent *uart_component) - { - this->set_uart_parent(uart_component); - } + void set_uart_component(esphome::uart::UARTComponent *uart_component) { this->set_uart_parent(uart_component); } void setup() override; void loop() override; @@ -52,15 +45,16 @@ namespace esphome TouchPoint get_touch_point(int bytes[]); bool is_valid_data(int bytes[]); - int get_x_touch_position(int bytes[]); + int get_touch_position_x(int bytes[]); int get_touch_state(int bytes[]); - Trigger touch_trigger_; - Trigger release_trigger_; - Trigger swipe_trigger_left_; - Trigger swipe_trigger_right_; - Trigger full_touch_release_trigger_; - Trigger long_touch_release_trigger_; + Trigger trigger_touch_event_; + Trigger trigger_touch_; + Trigger trigger_release_; + Trigger trigger_swipe_left_; + Trigger trigger_swipe_right_; + Trigger trigger_multi_touch_release_; + Trigger trigger_long_touch_release_; }; // class TxUltimateEasy From a4ac54cc751b831e48d45724194d093ecd092779 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Tue, 28 May 2024 10:02:11 +0200 Subject: [PATCH 20/28] Touch vibration feedback Solves #8 --- ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml | 40 +++++++++++++++++++--- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml index e5d7617..b8a5337 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml @@ -83,11 +83,9 @@ button: icon: mdi:vibrate internal: false platform: template - on_press: + on_press: then: - - switch.turn_on: sw_vibration_motor - - delay: !lambda return nr_vibrating_duration->state; - - switch.turn_off: sw_vibration_motor + - script.execute: vibrate captive_portal: @@ -277,6 +275,14 @@ 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 @@ -294,6 +300,22 @@ select: 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 @@ -433,6 +455,16 @@ tx_ultimate_easy: 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(); + + on_release: + - lambda: |- + if (sl_touch_vibration_feedback->state == "On release" or sl_touch_vibration_feedback->state == "Always") + vibrate->execute(); + uart: id: uart_touch tx_pin: GPIO19 From 4bda955ce4600d757e97aa70977a5ce68546c613 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Tue, 28 May 2024 15:21:04 +0200 Subject: [PATCH 21/28] Add initial relay control by buttons --- ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml | 49 ++++++++++++---------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml index b8a5337..7991eb7 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml @@ -37,8 +37,6 @@ binary_sensor: on_press: then: - switch.toggle: sw_relay_1 - - delay: !lambda "return (isnan(nr_button_timeout->state) ? 500 : int(nr_button_timeout->state));" - - lambda: bs_button_1->publish_state(false); - id: bs_button_2 name: Button 2 @@ -47,8 +45,6 @@ binary_sensor: on_press: then: - switch.toggle: sw_relay_2 - - delay: !lambda "return (isnan(nr_button_timeout->state) ? 500 : int(nr_button_timeout->state));" - - lambda: bs_button_2->publish_state(false); - id: bs_button_3 name: Button 3 @@ -57,8 +53,6 @@ binary_sensor: on_press: then: - switch.toggle: sw_relay_3 - - delay: !lambda "return (isnan(nr_button_timeout->state) ? 500 : int(nr_button_timeout->state));" - - lambda: bs_button_3->publish_state(false); - id: bs_button_4 name: Button 4 @@ -67,8 +61,6 @@ binary_sensor: on_press: then: - switch.toggle: sw_relay_4 - - delay: !lambda "return (isnan(nr_button_timeout->state) ? 500 : int(nr_button_timeout->state));" - - lambda: bs_button_4->publish_state(false); # bluetooth_proxy: @@ -258,19 +250,6 @@ number: optimistic: true restore_value: true - - id: nr_button_timeout - name: Button timeout - icon: mdi:timer - unit_of_measurement: ms - internal: false - platform: template - min_value: 1 - max_value: 3000 - step: 1 - initial_value: 500 - optimistic: true - restore_value: true - ota: psram: @@ -459,11 +438,39 @@ tx_ultimate_easy: - 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 From 3b135b919b9367ef63fd5e752eb055fff319ed6a Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Tue, 28 May 2024 17:49:47 +0200 Subject: [PATCH 22/28] Expose side light groups Solves #5 --- ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml | 270 ++++++++++++++++++++- 1 file changed, 268 insertions(+), 2 deletions(-) diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml index 7991eb7..50d35f7 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml @@ -156,8 +156,8 @@ i2s_audio: i2s_lrclk_pin: GPIO4 light: - - id: light_led - name: Light - LED + - id: light_full + name: Light - All platform: neopixelbus type: GRB variant: WS2811 @@ -209,6 +209,272 @@ light: 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 + - id: light_left + name: Light - Left + disabled_by_default: true + platform: partition + segments: + - id: light_full + from: 13 + to: 19 + reversed: true + - 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 + - id: light_top + name: Light - Top + disabled_by_default: true + platform: partition + segments: + - id: light_full + from: 20 + to: 26 + reversed: false + + - 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 From 48ce6a1167ee70faf2ba37db22a9bf276fb0fbca Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Tue, 28 May 2024 17:51:25 +0200 Subject: [PATCH 23/28] Add side lights effects --- ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml | 164 +++++++++++++++++++++ 1 file changed, 164 insertions(+) diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml index 50d35f7..d139b64 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml @@ -218,6 +218,47 @@ light: 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 @@ -227,6 +268,47 @@ light: 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 @@ -240,6 +322,47 @@ light: 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 @@ -249,6 +372,47 @@ light: 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 From 172f9c1bb96399e6eca6683b7886295262968590 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Tue, 28 May 2024 17:52:11 +0200 Subject: [PATCH 24/28] Exposes touch panel power Solves #4 --- ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml index d139b64..af89838 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml @@ -799,7 +799,7 @@ switch: number: GPIO5 inverted: true restore_mode: ALWAYS_ON - internal: true + internal: false - id: sw_vibration_motor name: Vibration motor From 7579ba955533d2cdb34dede602917fe205da1b92 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Wed, 29 May 2024 01:06:13 +0200 Subject: [PATCH 25/28] Add relay light indicator --- ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml | 333 ++++++++++++++++++++- 1 file changed, 325 insertions(+), 8 deletions(-) diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml index af89838..feccbea 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml @@ -639,6 +639,167 @@ light: from: 27 to: 27 + - id: light_rl_1_1_bottom + name: Light - Relay 1 of 1 (bottom) + internal: true + platform: partition + segments: + - id: light_full + from: 9 + to: 9 + - id: light_rl_1_1_top + name: Light - Relay 1 of 1 (top) + internal: true + platform: partition + segments: + - id: light_full + from: 23 + to: 23 + - id: light_rl_1_2_bottom + name: Light - Relay 1 of 2 (bottom) + internal: true + platform: partition + segments: + - id: light_full + from: 11 + to: 11 + - id: light_rl_1_2_top + name: Light - Relay 1 of 2 (top) + internal: true + platform: partition + segments: + - id: light_full + from: 21 + to: 21 + - id: light_rl_2_2_bottom + name: Light - Relay 2 of 2 (bottom) + internal: true + platform: partition + segments: + - id: light_full + from: 7 + to: 7 + - id: light_rl_2_2_top + name: Light - Relay 2 of 2 (top) + internal: true + platform: partition + segments: + - id: light_full + from: 25 + to: 25 + - id: light_rl_1_3_bottom + name: Light - Relay 1 of 3 (bottom) + internal: true + platform: partition + segments: + - id: light_full + from: 11 + to: 11 + - id: light_rl_1_3_top + name: Light - Relay 1 of 3 (top) + internal: true + platform: partition + segments: + - id: light_full + from: 21 + to: 21 + - id: light_rl_2_3_bottom + name: Light - Relay 2 of 3 (bottom) + internal: true + platform: partition + segments: + - id: light_full + from: 9 + to: 9 + - id: light_rl_2_3_top + name: Light - Relay 2 of 3 (top) + internal: true + platform: partition + segments: + - id: light_full + from: 23 + to: 23 + - id: light_rl_3_3_bottom + name: Light - Relay 3 of 3 (bottom) + internal: true + platform: partition + segments: + - id: light_full + from: 7 + to: 7 + - id: light_rl_3_3_top + name: Light - Relay 3 of 3 (top) + internal: true + platform: partition + segments: + - id: light_full + from: 25 + to: 25 + - id: light_rl_1_4_bottom + name: Light - Relay 1 of 4 (bottom) + internal: true + platform: partition + segments: + - id: light_full + from: 12 + to: 12 + - id: light_rl_1_4_top + name: Light - Relay 1 of 4 (top) + internal: true + platform: partition + segments: + - id: light_full + from: 20 + to: 20 + - id: light_rl_2_4_bottom + name: Light - Relay 2 of 4 (bottom) + internal: true + platform: partition + segments: + - id: light_full + from: 10 + to: 10 + - id: light_rl_2_4_top + name: Light - Relay 2 of 4 (top) + internal: true + platform: partition + segments: + - id: light_full + from: 22 + to: 22 + - id: light_rl_3_4_bottom + name: Light - Relay 3 of 4 (bottom) + internal: true + platform: partition + segments: + - id: light_full + from: 8 + to: 8 + - id: light_rl_3_4_top + name: Light - Relay 3 of 4 (top) + internal: true + platform: partition + segments: + - id: light_full + from: 24 + to: 24 + - id: light_rl_4_4_bottom + name: Light - Relay 4 of 4 (bottom) + internal: true + platform: partition + segments: + - id: light_full + from: 6 + to: 6 + - id: light_rl_4_4_top + name: Light - Relay 4 of 4 (top) + internal: true + platform: partition + segments: + - id: light_full + from: 26 + to: 26 + # - id: light_status # name: Light - Status # platform: esp32_rmt_led_strip @@ -685,6 +846,146 @@ ota: psram: script: + - id: show_relay_status + mode: restart + then: + - lambda: |- + auto model_index = sl_tx_model_gang->active_index(); + auto light_index = sl_relay_light_mode->active_index(); + if (model_index.has_value() and light_index.has_value() and light_index.value() > 0) { + uint8_t model_idx = model_index.value() + 1; + switch (model_idx) { + case 1: // 1 Gang + if (light_index == 1 or light_index == 3) { + if (sw_relay_1->state) + light_rl_1_1_bottom->turn_on().perform(); + else + light_rl_1_1_bottom->turn_off().perform(); + } + if (light_index == 2 or light_index == 3) { + if (sw_relay_1->state) + light_rl_1_1_top->turn_on().perform(); + else + light_rl_1_1_top->turn_off().perform(); + } + break; + case 2: // 2 Gang + if (light_index == 1 or light_index == 3) { + if (sw_relay_1->state) + light_rl_1_2_bottom->turn_on().perform(); + else + light_rl_1_2_bottom->turn_off().perform(); + } + if (light_index == 2 or light_index == 3) { + if (sw_relay_1->state) + light_rl_1_2_top->turn_on().perform(); + else + light_rl_1_2_top->turn_off().perform(); + } + if (light_index == 1 or light_index == 3) { + if (sw_relay_2->state) + light_rl_2_2_bottom->turn_on().perform(); + else + light_rl_2_2_bottom->turn_off().perform(); + } + if (light_index == 2 or light_index == 3) { + if (sw_relay_2->state) + light_rl_2_2_top->turn_on().perform(); + else + light_rl_2_2_top->turn_off().perform(); + } + break; + case 3: // 3 Gang + if (light_index == 1 or light_index == 3) { + if (sw_relay_1->state) + light_rl_1_3_bottom->turn_on().perform(); + else + light_rl_1_3_bottom->turn_off().perform(); + } + if (light_index == 2 or light_index == 3) { + if (sw_relay_1->state) + light_rl_1_3_top->turn_on().perform(); + else + light_rl_1_3_top->turn_off().perform(); + } + if (light_index == 1 or light_index == 3) { + if (sw_relay_2->state) + light_rl_2_3_bottom->turn_on().perform(); + else + light_rl_2_3_bottom->turn_off().perform(); + } + if (light_index == 2 or light_index == 3) { + if (sw_relay_2->state) + light_rl_2_3_top->turn_on().perform(); + else + light_rl_2_3_top->turn_off().perform(); + } + if (light_index == 1 or light_index == 3) { + if (sw_relay_3->state) + light_rl_3_3_bottom->turn_on().perform(); + else + light_rl_3_3_bottom->turn_off().perform(); + } + if (light_index == 2 or light_index == 3) { + if (sw_relay_3->state) + light_rl_3_3_top->turn_on().perform(); + else + light_rl_3_3_top->turn_off().perform(); + } + break; + case 4: // 4 Gang + if (light_index == 1 or light_index == 3) { + if (sw_relay_1->state) + light_rl_1_4_bottom->turn_on().perform(); + else + light_rl_1_4_bottom->turn_off().perform(); + } + if (light_index == 2 or light_index == 3) { + if (sw_relay_1->state) + light_rl_1_4_top->turn_on().perform(); + else + light_rl_1_4_top->turn_off().perform(); + } + if (light_index == 1 or light_index == 3) { + if (sw_relay_2->state) + light_rl_2_4_bottom->turn_on().perform(); + else + light_rl_2_4_bottom->turn_off().perform(); + } + if (light_index == 2 or light_index == 3) { + if (sw_relay_2->state) + light_rl_2_4_top->turn_on().perform(); + else + light_rl_2_4_top->turn_off().perform(); + } + if (light_index == 1 or light_index == 3) { + if (sw_relay_3->state) + light_rl_3_4_bottom->turn_on().perform(); + else + light_rl_3_4_bottom->turn_off().perform(); + } + if (light_index == 2 or light_index == 3) { + if (sw_relay_3->state) + light_rl_3_4_top->turn_on().perform(); + else + light_rl_3_4_top->turn_off().perform(); + } + if (light_index == 1 or light_index == 3) { + if (sw_relay_4->state) + light_rl_4_4_bottom->turn_on().perform(); + else + light_rl_4_4_bottom->turn_off().perform(); + } + if (light_index == 2 or light_index == 3) { + if (sw_relay_4->state) + light_rl_4_4_top->turn_on().perform(); + else + light_rl_4_4_top->turn_off().perform(); + } + break; + } + } + - id: vibrate mode: restart then: @@ -693,21 +994,21 @@ script: - switch.turn_off: sw_vibration_motor select: - - id: sl_tx_model_gang - name: Model + - id: sl_relay_light_mode + name: Relay light mode platform: template options: - - "1 Gang" - - "2 Gang" - - "3 Gang" - - "4 Gang" - initial_option: "1 Gang" + - "Disabled" + - "Bottom" + - "Top" + - "Both" + initial_option: "Bottom" optimistic: true restore_value: true internal: false entity_category: config disabled_by_default: false - icon: mdi:dip-switch + icon: mdi:dots-square - id: sl_touch_vibration_feedback name: Touch - Vibration feedback @@ -725,6 +1026,22 @@ select: disabled_by_default: false icon: mdi:vibrate + - 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 + sensor: - id: sun_elevation name: Sun Elevation From 67390ac8557fe2136abde8e7cb0aef87e1598cab Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Wed, 29 May 2024 11:53:45 +0200 Subject: [PATCH 26/28] Add Swipe sensors --- ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml | 36 ++++++++++++++++++---- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml index feccbea..71defc6 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml @@ -62,6 +62,16 @@ binary_sensor: then: - switch.toggle: sw_relay_4 + - id: bs_swipe_left + name: Swipe left + internal: false + platform: template + + - id: bs_swipe_right + name: Swipe right + internal: false + platform: template + # bluetooth_proxy: button: @@ -135,6 +145,8 @@ esphome: bs_button_2->publish_state(false); bs_button_3->publish_state(false); bs_button_4->publish_state(false); + bs_swipe_left->publish_state(false); + bs_swipe_right->publish_state(false); } - priority: 600 # This is where most sensors are set up. then: @@ -1175,12 +1187,6 @@ 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") @@ -1218,6 +1224,24 @@ tx_ultimate_easy: 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); + if (bs_swipe_left->state) bs_swipe_left->publish_state(false); + if (bs_swipe_right->state) bs_swipe_right->publish_state(false); + + on_swipe_left: + - binary_sensor.template.publish: + id: bs_swipe_left + state: ON + + on_swipe_right: + - binary_sensor.template.publish: + id: bs_swipe_right + state: ON + + 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); uart: id: uart_touch From 07c200fb19e74c619af102d1e41fef4cc86118e0 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Wed, 29 May 2024 20:59:57 +0200 Subject: [PATCH 27/28] Add support to US model --- ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml | 900 +++++++++++++++++---- 1 file changed, 726 insertions(+), 174 deletions(-) diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml index 71defc6..8ac41eb 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml @@ -32,6 +32,7 @@ binary_sensor: - id: bs_button_1 name: Button 1 + icon: mdi:gesture-tap-box internal: false platform: template on_press: @@ -40,6 +41,7 @@ binary_sensor: - id: bs_button_2 name: Button 2 + icon: mdi:gesture-tap-box internal: true platform: template on_press: @@ -48,6 +50,7 @@ binary_sensor: - id: bs_button_3 name: Button 3 + icon: mdi:gesture-tap-box internal: true platform: template on_press: @@ -56,6 +59,7 @@ binary_sensor: - id: bs_button_4 name: Button 4 + icon: mdi:gesture-tap-box internal: true platform: template on_press: @@ -64,12 +68,26 @@ binary_sensor: - id: bs_swipe_left name: Swipe left - internal: false + icon: mdi:gesture-swipe-left + internal: true platform: template - id: bs_swipe_right name: Swipe right - internal: false + icon: mdi:gesture-swipe-right + internal: true + platform: template + + - id: bs_swipe_up + name: Swipe up + icon: mdi:gesture-swipe-up + internal: true + platform: template + + - id: bs_swipe_down + name: Swipe down + icon: mdi:gesture-swipe-down + internal: true platform: template # bluetooth_proxy: @@ -91,6 +109,8 @@ button: captive_portal: +debug: + esp32: board: esp32dev framework: @@ -115,15 +135,60 @@ esphome: 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: + - -DCONFIG_ESP32_REV_MIN_3 + - -DCONFIG_MBEDTLS_DYNAMIC_BUFFER + - -DCONFIG_MBEDTLS_DYNAMIC_FREE_CA_CERT + - -DCONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA + - -DCONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC + - -DCONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY + - -DCONFIG_SPIRAM_RODATA + - -DCONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP + - -DCONFIG_SPIRAM_USE + # - -DCONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL + - -DCONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY + - -DCONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY + - -DCONFIG_SPIRAM_CACHE_LIBCHAR_IN_IRAM + - -DCONFIG_SPIRAM_CACHE_LIBENV_IN_IRAM + - -DCONFIG_SPIRAM_CACHE_LIBFILE_IN_IRAM + - -DCONFIG_SPIRAM_CACHE_LIBIO_IN_IRAM + - -DCONFIG_SPIRAM_CACHE_LIBJMP_IN_IRAM + - -DCONFIG_SPIRAM_CACHE_LIBMATH_IN_IRAM + - -DCONFIG_SPIRAM_CACHE_LIBMEM_IN_IRAM + - -DCONFIG_SPIRAM_CACHE_LIBMISC_IN_IRAM + - -DCONFIG_SPIRAM_CACHE_LIBNUMPARSER_IN_IRAM + - -DCONFIG_SPIRAM_CACHE_LIBRAND_IN_IRAM + - -DCONFIG_SPIRAM_CACHE_LIBSTR_IN_IRAM + - -DCONFIG_SPIRAM_CACHE_LIBTIME_IN_IRAM + + on_boot: + - priority: 701 + then: + - wait_until: + condition: + - lambda: return sl_tx_model_format->active_index().has_value(); + - lambda: |- + auto index = sl_tx_model_format->active_index(); + if (index.has_value()) { + uint8_t idx = index.value(); + bs_swipe_down->set_internal(idx == 0); + bs_swipe_left->set_internal(idx == 1); + bs_swipe_right->set_internal(idx == 1); + bs_swipe_up->set_internal(idx == 0); + light_28->set_internal(idx == 0); + light_29->set_internal(idx == 0); + light_30->set_internal(idx == 0); + light_31->set_internal(idx == 0); + light_eu_bottom->set_internal(idx == 1); + light_eu_left->set_internal(idx == 1); + light_eu_right->set_internal(idx == 1); + light_eu_top->set_internal(idx == 1); + light_us_bottom->set_internal(idx == 0); + light_us_left->set_internal(idx == 0); + light_us_right->set_internal(idx == 0); + light_us_top->set_internal(idx == 0); + sl_relay_light_mode_eu->set_internal(idx == 1); + sl_relay_light_mode_us->set_internal(idx == 0); + } - priority: 700 then: - wait_until: @@ -148,6 +213,56 @@ esphome: bs_swipe_left->publish_state(false); bs_swipe_right->publish_state(false); } + - priority: 699 + 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: |- + auto model_format = sl_tx_model_format->active_index(); + auto model_gang = sl_tx_model_gang->active_index(); + if (model_format.has_value() and model_gang.has_value()) { + bool us_model = (model_gang.value() == 1); + switch (model_gang.value() + 1) { + 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: |- @@ -162,6 +277,14 @@ external_components: components: - tx_ultimate_easy +globals: + - id: gb_lights_1 + type: std::vector + restore_value: false + - id: gb_lights_2 + type: std::vector + restore_value: false + i2s_audio: id: if_i2s_audio i2s_bclk_pin: GPIO2 @@ -170,6 +293,7 @@ i2s_audio: light: - id: light_full name: Light - All + internal: true platform: neopixelbus type: GRB variant: WS2811 @@ -177,8 +301,66 @@ light: # rgb_order: GRB # rmt_channel: 0 # chipset: ws2812 - num_leds: 28 + num_leds: 32 pin: GPIO13 + + - id: light_eu + name: Light + internal: true + platform: partition + segments: + - id: light_full + from: 0 + to: 28 + 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_us + name: Light + internal: true + platform: partition + segments: + - id: light_full + from: 0 + to: 31 effects: - addressable_rainbow: - addressable_rainbow: @@ -221,8 +403,9 @@ light: intensity: 5% - random: - - id: light_bottom + - id: light_eu_bottom name: Light - Bottom + internal: true disabled_by_default: true platform: partition segments: @@ -271,8 +454,9 @@ light: update_interval: 16ms intensity: 5% - random: - - id: light_left + - id: light_eu_left name: Light - Left + internal: true disabled_by_default: true platform: partition segments: @@ -321,8 +505,9 @@ light: update_interval: 16ms intensity: 5% - random: - - id: light_right + - id: light_eu_right name: Light - Right + internal: true disabled_by_default: true platform: partition segments: @@ -375,8 +560,9 @@ light: update_interval: 16ms intensity: 5% - random: - - id: light_top + - id: light_eu_top name: Light - Top + internal: true disabled_by_default: true platform: partition segments: @@ -425,6 +611,214 @@ light: update_interval: 16ms intensity: 5% - random: + - id: light_us_bottom + name: Light - Bottom + internal: true + disabled_by_default: true + platform: partition + segments: + - id: light_full + from: 10 + to: 15 + 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_us_left + name: Light - Left + internal: true + disabled_by_default: true + platform: partition + segments: + - id: light_full + from: 15 + to: 24 + 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_us_right + name: Light - Right + internal: true + disabled_by_default: true + platform: partition + segments: + - id: light_full + from: 31 + to: 31 + reversed: false + - id: light_full + from: 0 + to: 8 + 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_us_top + name: Light - Top + internal: true + disabled_by_default: true + platform: partition + segments: + - id: light_full + from: 25 + to: 30 + 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 @@ -650,8 +1044,44 @@ light: - id: light_full from: 27 to: 27 + - id: light_28 + name: Light - LED 28 + internal: true + disabled_by_default: true + platform: partition + segments: + - id: light_full + from: 28 + to: 28 + - id: light_29 + name: Light - LED 29 + internal: true + disabled_by_default: true + platform: partition + segments: + - id: light_full + from: 29 + to: 29 + - id: light_30 + name: Light - LED 30 + internal: true + disabled_by_default: true + platform: partition + segments: + - id: light_full + from: 30 + to: 30 + - id: light_31 + name: Light - LED 31 + internal: true + disabled_by_default: true + platform: partition + segments: + - id: light_full + from: 31 + to: 31 - - id: light_rl_1_1_bottom + - id: light_eu_rl_1_1_bottom name: Light - Relay 1 of 1 (bottom) internal: true platform: partition @@ -659,7 +1089,7 @@ light: - id: light_full from: 9 to: 9 - - id: light_rl_1_1_top + - id: light_eu_rl_1_1_top name: Light - Relay 1 of 1 (top) internal: true platform: partition @@ -667,7 +1097,7 @@ light: - id: light_full from: 23 to: 23 - - id: light_rl_1_2_bottom + - id: light_eu_rl_1_2_bottom name: Light - Relay 1 of 2 (bottom) internal: true platform: partition @@ -675,7 +1105,7 @@ light: - id: light_full from: 11 to: 11 - - id: light_rl_1_2_top + - id: light_eu_rl_1_2_top name: Light - Relay 1 of 2 (top) internal: true platform: partition @@ -683,7 +1113,7 @@ light: - id: light_full from: 21 to: 21 - - id: light_rl_2_2_bottom + - id: light_eu_rl_2_2_bottom name: Light - Relay 2 of 2 (bottom) internal: true platform: partition @@ -691,7 +1121,7 @@ light: - id: light_full from: 7 to: 7 - - id: light_rl_2_2_top + - id: light_eu_rl_2_2_top name: Light - Relay 2 of 2 (top) internal: true platform: partition @@ -699,7 +1129,7 @@ light: - id: light_full from: 25 to: 25 - - id: light_rl_1_3_bottom + - id: light_eu_rl_1_3_bottom name: Light - Relay 1 of 3 (bottom) internal: true platform: partition @@ -707,7 +1137,7 @@ light: - id: light_full from: 11 to: 11 - - id: light_rl_1_3_top + - id: light_eu_rl_1_3_top name: Light - Relay 1 of 3 (top) internal: true platform: partition @@ -715,7 +1145,7 @@ light: - id: light_full from: 21 to: 21 - - id: light_rl_2_3_bottom + - id: light_eu_rl_2_3_bottom name: Light - Relay 2 of 3 (bottom) internal: true platform: partition @@ -723,7 +1153,7 @@ light: - id: light_full from: 9 to: 9 - - id: light_rl_2_3_top + - id: light_eu_rl_2_3_top name: Light - Relay 2 of 3 (top) internal: true platform: partition @@ -731,7 +1161,7 @@ light: - id: light_full from: 23 to: 23 - - id: light_rl_3_3_bottom + - id: light_eu_rl_3_3_bottom name: Light - Relay 3 of 3 (bottom) internal: true platform: partition @@ -739,7 +1169,7 @@ light: - id: light_full from: 7 to: 7 - - id: light_rl_3_3_top + - id: light_eu_rl_3_3_top name: Light - Relay 3 of 3 (top) internal: true platform: partition @@ -747,7 +1177,7 @@ light: - id: light_full from: 25 to: 25 - - id: light_rl_1_4_bottom + - id: light_eu_rl_1_4_bottom name: Light - Relay 1 of 4 (bottom) internal: true platform: partition @@ -755,7 +1185,7 @@ light: - id: light_full from: 12 to: 12 - - id: light_rl_1_4_top + - id: light_eu_rl_1_4_top name: Light - Relay 1 of 4 (top) internal: true platform: partition @@ -763,7 +1193,7 @@ light: - id: light_full from: 20 to: 20 - - id: light_rl_2_4_bottom + - id: light_eu_rl_2_4_bottom name: Light - Relay 2 of 4 (bottom) internal: true platform: partition @@ -771,7 +1201,7 @@ light: - id: light_full from: 10 to: 10 - - id: light_rl_2_4_top + - id: light_eu_rl_2_4_top name: Light - Relay 2 of 4 (top) internal: true platform: partition @@ -779,7 +1209,7 @@ light: - id: light_full from: 22 to: 22 - - id: light_rl_3_4_bottom + - id: light_eu_rl_3_4_bottom name: Light - Relay 3 of 4 (bottom) internal: true platform: partition @@ -787,7 +1217,7 @@ light: - id: light_full from: 8 to: 8 - - id: light_rl_3_4_top + - id: light_eu_rl_3_4_top name: Light - Relay 3 of 4 (top) internal: true platform: partition @@ -795,7 +1225,7 @@ light: - id: light_full from: 24 to: 24 - - id: light_rl_4_4_bottom + - id: light_eu_rl_4_4_bottom name: Light - Relay 4 of 4 (bottom) internal: true platform: partition @@ -803,7 +1233,7 @@ light: - id: light_full from: 6 to: 6 - - id: light_rl_4_4_top + - id: light_eu_rl_4_4_top name: Light - Relay 4 of 4 (top) internal: true platform: partition @@ -811,6 +1241,172 @@ light: - id: light_full from: 26 to: 26 + - id: light_us_rl_1_1_left + name: Light - Relay 1 of 1 (left) + internal: true + platform: partition + segments: + - id: light_full + from: 15 + to: 24 + - id: light_us_rl_1_1_right + name: Light - Relay 1 of 1 (right) + internal: true + platform: partition + segments: + - id: light_full + from: 31 + to: 31 + - id: light_full + from: 0 + to: 8 + - id: light_us_rl_1_2_left + name: Light - Relay 1 of 2 (left) + internal: true + platform: partition + segments: + - id: light_full + from: 20 + to: 24 + - id: light_us_rl_1_2_right + name: Light - Relay 1 of 2 (right) + internal: true + platform: partition + segments: + - id: light_full + from: 31 + to: 31 + - id: light_full + from: 0 + to: 3 + - id: light_us_rl_2_2_left + name: Light - Relay 2 of 2 (left) + internal: true + platform: partition + segments: + - id: light_full + from: 15 + to: 19 + - id: light_us_rl_2_2_right + name: Light - Relay 2 of 2 (right) + internal: true + platform: partition + segments: + - id: light_full + from: 4 + to: 8 + - id: light_us_rl_1_3_left + name: Light - Relay 1 of 3 (left) + internal: true + platform: partition + segments: + - id: light_full + from: 22 + to: 23 + - id: light_us_rl_1_3_right + name: Light - Relay 1 of 3 (right) + internal: true + platform: partition + segments: + - id: light_full + from: 0 + to: 1 + - id: light_us_rl_2_3_left + name: Light - Relay 2 of 3 (left) + internal: true + platform: partition + segments: + - id: light_full + from: 19 + to: 20 + - id: light_us_rl_2_3_right + name: Light - Relay 2 of 3 (right) + internal: true + platform: partition + segments: + - id: light_full + from: 3 + to: 4 + - id: light_us_rl_3_3_left + name: Light - Relay 3 of 3 (left) + internal: true + platform: partition + segments: + - id: light_full + from: 17 + to: 18 + - id: light_us_rl_3_3_right + name: Light - Relay 3 of 3 (right) + internal: true + platform: partition + segments: + - id: light_full + from: 6 + to: 7 + - id: light_us_rl_1_4_left + name: Light - Relay 1 of 4 (left) + internal: true + platform: partition + segments: + - id: light_full + from: 12 + to: 12 + - id: light_us_rl_1_4_right + name: Light - Relay 1 of 4 (right) + internal: true + platform: partition + segments: + - id: light_full + from: 31 + to: 31 + - id: light_us_rl_2_4_left + name: Light - Relay 2 of 4 (left) + internal: true + platform: partition + segments: + - id: light_full + from: 24 + to: 24 + - id: light_us_rl_2_4_right + name: Light - Relay 2 of 4 (right) + internal: true + platform: partition + segments: + - id: light_full + from: 2 + to: 2 + - id: light_us_rl_3_4_left + name: Light - Relay 3 of 4 (left) + internal: true + platform: partition + segments: + - id: light_full + from: 21 + to: 21 + - id: light_us_rl_3_4_right + name: Light - Relay 3 of 4 (right) + internal: true + platform: partition + segments: + - id: light_full + from: 4 + to: 4 + - id: light_us_rl_4_4_left + name: Light - Relay 4 of 4 (left) + internal: true + platform: partition + segments: + - id: light_full + from: 19 + to: 19 + - id: light_us_rl_4_4_right + name: Light - Relay 4 of 4 (right) + internal: true + platform: partition + segments: + - id: light_full + from: 7 + to: 7 # - id: light_status # name: Light - Status @@ -845,6 +1441,7 @@ number: unit_of_measurement: ms # mode: box internal: false + entity_category: config platform: template min_value: 1 max_value: 500 @@ -862,139 +1459,28 @@ script: mode: restart then: - lambda: |- - auto model_index = sl_tx_model_gang->active_index(); - auto light_index = sl_relay_light_mode->active_index(); - if (model_index.has_value() and light_index.has_value() and light_index.value() > 0) { - uint8_t model_idx = model_index.value() + 1; - switch (model_idx) { - case 1: // 1 Gang - if (light_index == 1 or light_index == 3) { - if (sw_relay_1->state) - light_rl_1_1_bottom->turn_on().perform(); - else - light_rl_1_1_bottom->turn_off().perform(); - } - if (light_index == 2 or light_index == 3) { - if (sw_relay_1->state) - light_rl_1_1_top->turn_on().perform(); - else - light_rl_1_1_top->turn_off().perform(); - } - break; - case 2: // 2 Gang - if (light_index == 1 or light_index == 3) { - if (sw_relay_1->state) - light_rl_1_2_bottom->turn_on().perform(); - else - light_rl_1_2_bottom->turn_off().perform(); - } - if (light_index == 2 or light_index == 3) { - if (sw_relay_1->state) - light_rl_1_2_top->turn_on().perform(); - else - light_rl_1_2_top->turn_off().perform(); - } - if (light_index == 1 or light_index == 3) { - if (sw_relay_2->state) - light_rl_2_2_bottom->turn_on().perform(); - else - light_rl_2_2_bottom->turn_off().perform(); - } - if (light_index == 2 or light_index == 3) { - if (sw_relay_2->state) - light_rl_2_2_top->turn_on().perform(); - else - light_rl_2_2_top->turn_off().perform(); - } - break; - case 3: // 3 Gang - if (light_index == 1 or light_index == 3) { - if (sw_relay_1->state) - light_rl_1_3_bottom->turn_on().perform(); - else - light_rl_1_3_bottom->turn_off().perform(); - } - if (light_index == 2 or light_index == 3) { - if (sw_relay_1->state) - light_rl_1_3_top->turn_on().perform(); - else - light_rl_1_3_top->turn_off().perform(); - } - if (light_index == 1 or light_index == 3) { - if (sw_relay_2->state) - light_rl_2_3_bottom->turn_on().perform(); - else - light_rl_2_3_bottom->turn_off().perform(); - } - if (light_index == 2 or light_index == 3) { - if (sw_relay_2->state) - light_rl_2_3_top->turn_on().perform(); - else - light_rl_2_3_top->turn_off().perform(); - } - if (light_index == 1 or light_index == 3) { - if (sw_relay_3->state) - light_rl_3_3_bottom->turn_on().perform(); - else - light_rl_3_3_bottom->turn_off().perform(); - } - if (light_index == 2 or light_index == 3) { - if (sw_relay_3->state) - light_rl_3_3_top->turn_on().perform(); - else - light_rl_3_3_top->turn_off().perform(); - } - break; - case 4: // 4 Gang - if (light_index == 1 or light_index == 3) { - if (sw_relay_1->state) - light_rl_1_4_bottom->turn_on().perform(); - else - light_rl_1_4_bottom->turn_off().perform(); - } - if (light_index == 2 or light_index == 3) { - if (sw_relay_1->state) - light_rl_1_4_top->turn_on().perform(); - else - light_rl_1_4_top->turn_off().perform(); - } - if (light_index == 1 or light_index == 3) { - if (sw_relay_2->state) - light_rl_2_4_bottom->turn_on().perform(); - else - light_rl_2_4_bottom->turn_off().perform(); - } - if (light_index == 2 or light_index == 3) { - if (sw_relay_2->state) - light_rl_2_4_top->turn_on().perform(); - else - light_rl_2_4_top->turn_off().perform(); - } - if (light_index == 1 or light_index == 3) { - if (sw_relay_3->state) - light_rl_3_4_bottom->turn_on().perform(); - else - light_rl_3_4_bottom->turn_off().perform(); - } - if (light_index == 2 or light_index == 3) { - if (sw_relay_3->state) - light_rl_3_4_top->turn_on().perform(); - else - light_rl_3_4_top->turn_off().perform(); - } - if (light_index == 1 or light_index == 3) { - if (sw_relay_4->state) - light_rl_4_4_bottom->turn_on().perform(); - else - light_rl_4_4_bottom->turn_off().perform(); - } - if (light_index == 2 or light_index == 3) { - if (sw_relay_4->state) - light_rl_4_4_top->turn_on().perform(); - else - light_rl_4_4_top->turn_off().perform(); - } - break; + auto model_format = sl_tx_model_format->active_index(); + auto light_index = ((model_format.has_value() and model_format.value() == 0) + ? sl_relay_light_mode_eu->active_index() + : sl_relay_light_mode_us->active_index()); + if (model_format.has_value() and light_index.has_value() and light_index.value() > 0) { + std::vector switches = {sw_relay_1, sw_relay_2, sw_relay_3, sw_relay_4}; + uint8_t light_idx = light_index.value(); + if (light_idx == 1 or light_idx == 3) { + for (int i = 0; i < id(gb_lights_1).size(); ++i) { + if (switches[i]->state) + id(gb_lights_1)[i]->turn_on().perform(); + else + id(gb_lights_1)[i]->turn_off().perform(); + } + } + if (light_idx == 2 or light_idx == 3) { + for (int i = 0; i < id(gb_lights_2).size(); ++i) { + if (switches[i]->state) + id(gb_lights_2)[i]->turn_on().perform(); + else + id(gb_lights_2)[i]->turn_off().perform(); + } } } @@ -1006,7 +1492,7 @@ script: - switch.turn_off: sw_vibration_motor select: - - id: sl_relay_light_mode + - id: sl_relay_light_mode_eu name: Relay light mode platform: template options: @@ -1017,7 +1503,23 @@ select: initial_option: "Bottom" optimistic: true restore_value: true - internal: false + internal: true + entity_category: config + disabled_by_default: false + icon: mdi:dots-square + + - id: sl_relay_light_mode_us + name: Relay light mode + platform: template + options: + - "Disabled" + - "Left" + - "Right" + - "Both" + initial_option: "Right" + optimistic: true + restore_value: true + internal: true entity_category: config disabled_by_default: false icon: mdi:dots-square @@ -1038,8 +1540,22 @@ select: disabled_by_default: false icon: mdi:vibrate + - 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 + name: Model (Gang) platform: template options: - "1 Gang" @@ -1055,6 +1571,16 @@ select: icon: mdi:dip-switch sensor: + - platform: debug + free: + name: "Heap Free" + block: + name: "Heap Max Block" + loop_time: + name: "Loop Time" + psram: + name: "Free PSRAM" + - id: sun_elevation name: Sun Elevation platform: sun @@ -1083,8 +1609,8 @@ sun: longitude: ${longitude} switch: - - id: sw_speaker_aplifier - name: Speaker - Aplifier + - id: sw_speaker_amplifier + name: Speaker - Amplifier platform: gpio pin: number: GPIO26 @@ -1092,6 +1618,7 @@ switch: allow_other_uses: true restore_mode: RESTORE_DEFAULT_ON internal: true + entity_category: config - id: sw_relay_1 name: Relay 1 @@ -1099,6 +1626,12 @@ switch: pin: GPIO18 restore_mode: RESTORE_DEFAULT_OFF internal: false + 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 @@ -1106,6 +1639,12 @@ switch: pin: GPIO17 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_3 name: Relay 3 @@ -1113,6 +1652,12 @@ switch: pin: GPIO27 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_4 name: Relay 4 @@ -1120,6 +1665,12 @@ switch: pin: GPIO23 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_touch_panel_power name: Touch panel - Power @@ -1129,6 +1680,7 @@ switch: inverted: true restore_mode: ALWAYS_ON internal: false + entity_category: config - id: sw_vibration_motor name: Vibration motor From a5da9c797a8dcd199663f9fab5bde9bb163ec649 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Wed, 29 May 2024 22:11:05 +0200 Subject: [PATCH 28/28] Change flash size to 8MB This enables flash memory for building Bluetooth Proxy (requires by #9), however, there are two downsides: - The system is crashing when BLE is enabled and requires more investigation. - User's cannot change flash size via OTA, so a serial flash will be required. --- ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml | 92 ++++++++++++++++++++-- TX-Ultimate-Easy-ESPHome.yaml | 6 +- 2 files changed, 91 insertions(+), 7 deletions(-) diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml index 8ac41eb..e0194d2 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml @@ -5,6 +5,7 @@ substitutions: latitude: '0' longitude: '0' zone_home: 'zone.home' + default_transition_length: 500ms version: '0.0.1' @@ -90,8 +91,6 @@ binary_sensor: internal: true platform: template -# bluetooth_proxy: - button: - id: bt_restart name: Restart @@ -113,6 +112,7 @@ debug: esp32: board: esp32dev + flash_size: 8MB framework: # type: esp-idf type: arduino @@ -133,8 +133,8 @@ esphome: friendly_name: ${friendly_name} platformio_options: build_flags: - - -DCONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST=true - # - -DCONFIG_BT_BLE_DYNAMIC_ENV_MEMORY=true + - -DCONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST + - -DCONFIG_BT_BLE_DYNAMIC_ENV_MEMORY - -DCONFIG_ESP32_REV_MIN_3 - -DCONFIG_MBEDTLS_DYNAMIC_BUFFER - -DCONFIG_MBEDTLS_DYNAMIC_FREE_CA_CERT @@ -144,8 +144,6 @@ esphome: - -DCONFIG_SPIRAM_RODATA - -DCONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP - -DCONFIG_SPIRAM_USE - # - -DCONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL - - -DCONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY - -DCONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY - -DCONFIG_SPIRAM_CACHE_LIBCHAR_IN_IRAM - -DCONFIG_SPIRAM_CACHE_LIBENV_IN_IRAM @@ -308,6 +306,7 @@ light: name: Light internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 0 @@ -357,6 +356,7 @@ light: name: Light internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 0 @@ -408,6 +408,7 @@ light: internal: true disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 6 @@ -459,6 +460,7 @@ light: internal: true disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 13 @@ -510,6 +512,7 @@ light: internal: true disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 27 @@ -565,6 +568,7 @@ light: internal: true disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 20 @@ -616,6 +620,7 @@ light: internal: true disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 10 @@ -667,6 +672,7 @@ light: internal: true disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 15 @@ -718,6 +724,7 @@ light: internal: true disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 31 @@ -773,6 +780,7 @@ light: internal: true disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 25 @@ -824,6 +832,7 @@ light: name: Light - LED 00 disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 0 @@ -832,6 +841,7 @@ light: name: Light - LED 01 disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 1 @@ -840,6 +850,7 @@ light: name: Light - LED 02 disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 2 @@ -848,6 +859,7 @@ light: name: Light - LED 03 disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 3 @@ -856,6 +868,7 @@ light: name: Light - LED 04 disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 4 @@ -864,6 +877,7 @@ light: name: Light - LED 05 disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 5 @@ -872,6 +886,7 @@ light: name: Light - LED 06 disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 6 @@ -880,6 +895,7 @@ light: name: Light - LED 07 disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 7 @@ -888,6 +904,7 @@ light: name: Light - LED 08 disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 8 @@ -896,6 +913,7 @@ light: name: Light - LED 09 disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 9 @@ -904,6 +922,7 @@ light: name: Light - LED 10 disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 10 @@ -912,6 +931,7 @@ light: name: Light - LED 11 disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 11 @@ -920,6 +940,7 @@ light: name: Light - LED 12 disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 12 @@ -928,6 +949,7 @@ light: name: Light - LED 13 disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 13 @@ -936,6 +958,7 @@ light: name: Light - LED 14 disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 14 @@ -944,6 +967,7 @@ light: name: Light - LED 15 disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 15 @@ -952,6 +976,7 @@ light: name: Light - LED 16 disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 16 @@ -960,6 +985,7 @@ light: name: Light - LED 17 disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 17 @@ -968,6 +994,7 @@ light: name: Light - LED 18 disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 18 @@ -976,6 +1003,7 @@ light: name: Light - LED 19 disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 19 @@ -984,6 +1012,7 @@ light: name: Light - LED 20 disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 20 @@ -992,6 +1021,7 @@ light: name: Light - LED 21 disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 21 @@ -1000,6 +1030,7 @@ light: name: Light - LED 22 disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 22 @@ -1008,6 +1039,7 @@ light: name: Light - LED 23 disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 23 @@ -1016,6 +1048,7 @@ light: name: Light - LED 24 disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 24 @@ -1024,6 +1057,7 @@ light: name: Light - LED 25 disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 25 @@ -1032,6 +1066,7 @@ light: name: Light - LED 26 disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 26 @@ -1040,6 +1075,7 @@ light: name: Light - LED 27 disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 27 @@ -1049,6 +1085,7 @@ light: internal: true disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 28 @@ -1058,6 +1095,7 @@ light: internal: true disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 29 @@ -1067,6 +1105,7 @@ light: internal: true disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 30 @@ -1076,6 +1115,7 @@ light: internal: true disabled_by_default: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 31 @@ -1085,6 +1125,7 @@ light: name: Light - Relay 1 of 1 (bottom) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 9 @@ -1093,6 +1134,7 @@ light: name: Light - Relay 1 of 1 (top) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 23 @@ -1101,6 +1143,7 @@ light: name: Light - Relay 1 of 2 (bottom) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 11 @@ -1109,6 +1152,7 @@ light: name: Light - Relay 1 of 2 (top) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 21 @@ -1117,6 +1161,7 @@ light: name: Light - Relay 2 of 2 (bottom) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 7 @@ -1125,6 +1170,7 @@ light: name: Light - Relay 2 of 2 (top) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 25 @@ -1133,6 +1179,7 @@ light: name: Light - Relay 1 of 3 (bottom) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 11 @@ -1141,6 +1188,7 @@ light: name: Light - Relay 1 of 3 (top) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 21 @@ -1149,6 +1197,7 @@ light: name: Light - Relay 2 of 3 (bottom) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 9 @@ -1157,6 +1206,7 @@ light: name: Light - Relay 2 of 3 (top) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 23 @@ -1165,6 +1215,7 @@ light: name: Light - Relay 3 of 3 (bottom) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 7 @@ -1173,6 +1224,7 @@ light: name: Light - Relay 3 of 3 (top) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 25 @@ -1181,6 +1233,7 @@ light: name: Light - Relay 1 of 4 (bottom) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 12 @@ -1189,6 +1242,7 @@ light: name: Light - Relay 1 of 4 (top) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 20 @@ -1197,6 +1251,7 @@ light: name: Light - Relay 2 of 4 (bottom) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 10 @@ -1205,6 +1260,7 @@ light: name: Light - Relay 2 of 4 (top) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 22 @@ -1213,6 +1269,7 @@ light: name: Light - Relay 3 of 4 (bottom) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 8 @@ -1221,6 +1278,7 @@ light: name: Light - Relay 3 of 4 (top) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 24 @@ -1229,6 +1287,7 @@ light: name: Light - Relay 4 of 4 (bottom) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 6 @@ -1237,6 +1296,7 @@ light: name: Light - Relay 4 of 4 (top) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 26 @@ -1245,6 +1305,7 @@ light: name: Light - Relay 1 of 1 (left) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 15 @@ -1253,6 +1314,7 @@ light: name: Light - Relay 1 of 1 (right) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 31 @@ -1264,6 +1326,7 @@ light: name: Light - Relay 1 of 2 (left) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 20 @@ -1272,6 +1335,7 @@ light: name: Light - Relay 1 of 2 (right) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 31 @@ -1283,6 +1347,7 @@ light: name: Light - Relay 2 of 2 (left) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 15 @@ -1291,6 +1356,7 @@ light: name: Light - Relay 2 of 2 (right) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 4 @@ -1299,6 +1365,7 @@ light: name: Light - Relay 1 of 3 (left) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 22 @@ -1307,6 +1374,7 @@ light: name: Light - Relay 1 of 3 (right) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 0 @@ -1315,6 +1383,7 @@ light: name: Light - Relay 2 of 3 (left) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 19 @@ -1323,6 +1392,7 @@ light: name: Light - Relay 2 of 3 (right) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 3 @@ -1331,6 +1401,7 @@ light: name: Light - Relay 3 of 3 (left) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 17 @@ -1339,6 +1410,7 @@ light: name: Light - Relay 3 of 3 (right) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 6 @@ -1347,6 +1419,7 @@ light: name: Light - Relay 1 of 4 (left) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 12 @@ -1355,6 +1428,7 @@ light: name: Light - Relay 1 of 4 (right) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 31 @@ -1363,6 +1437,7 @@ light: name: Light - Relay 2 of 4 (left) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 24 @@ -1371,6 +1446,7 @@ light: name: Light - Relay 2 of 4 (right) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 2 @@ -1379,6 +1455,7 @@ light: name: Light - Relay 3 of 4 (left) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 21 @@ -1387,6 +1464,7 @@ light: name: Light - Relay 3 of 4 (right) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 4 @@ -1395,6 +1473,7 @@ light: name: Light - Relay 4 of 4 (left) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 19 @@ -1403,6 +1482,7 @@ light: name: Light - Relay 4 of 4 (right) internal: true platform: partition + default_transition_length: ${default_transition_length} segments: - id: light_full from: 7 diff --git a/TX-Ultimate-Easy-ESPHome.yaml b/TX-Ultimate-Easy-ESPHome.yaml index 61290cc..958c3c4 100644 --- a/TX-Ultimate-Easy-ESPHome.yaml +++ b/TX-Ultimate-Easy-ESPHome.yaml @@ -10,6 +10,10 @@ packages: remote_package: url: https://github.com/edwardtfn/TX-Ultimate-Easy ref: dev - refresh: 30s + refresh: 1h files: - ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml + +### Uncomment the lines bellow if you have issues with OTA and cannot flash via serial at this moment. ### +#esp32: +# flash_size: 4MB