Compare commits

..

36 Commits
0.0.3 ... 0.0.4

Author SHA1 Message Date
Edward Firmo
9bf6eff7d6 CodeRabbitAI 2024-12-20 23:59:59 +01:00
Edward Firmo
9fbc499339 Open links in another tab 2024-12-20 23:27:21 +01:00
Edward Firmo
9646d5292a Fix Discord server again 2024-12-20 23:13:49 +01:00
Edward Firmo
c01f8a4623 FIx Discord badge 2024-12-20 23:08:55 +01:00
Edward Firmo
6f4d8ff611 Update README.md 2024-12-20 22:58:06 +01:00
Edward Firmo
82b6d8cb25 Lint 2024-12-20 22:38:05 +01:00
Edward Firmo
d0b8ba55ba Clean-up logs
The less the more
2024-12-20 22:32:59 +01:00
Edward Firmo
8f4a2a9402 Device name from App 2024-12-20 21:23:28 +01:00
Edward Firmo
55cde35d31 Publish device name only at boot and api connection 2024-12-20 21:00:24 +01:00
Edward Firmo
e1b8469aa5 Remove sun platform
It isn't in use yet
2024-12-20 20:51:52 +01:00
Edward Firmo
e0a5ea1cc8 Do not toggle if other action is on place
Helps with #18
2024-12-20 20:39:19 +01:00
Edward Firmo
da83c0749b Lint 2024-12-20 18:14:29 +01:00
Edward Firmo
ffe0d56576 Lint 2024-12-20 18:13:02 +01:00
Edward Firmo
b1b1a40d5e New implementation of show_relay_status
Solves #28
I believe this also solves #21
2024-12-20 18:07:17 +01:00
Edward Firmo
0cc17b715f Lint 2024-12-20 02:35:16 +01:00
Edward Firmo
b1dbda4efe Remove references to Blueprint in the README
Solves #30
2024-12-20 02:31:12 +01:00
Edward Firmo
cc5858be8b Lint 2024-12-20 02:10:33 +01:00
Edward Firmo
59da9bcb96 Wait for initialization to complete before update relay status
That was crashing that method right after boot.

- Solves #28
2024-12-20 02:08:49 +01:00
Edward Firmo
c62e7a689c Use version as reference for component 2024-12-20 00:21:39 +01:00
Edward Firmo
62e4e3d511 More CodeRabbitAI suggestions 2024-12-19 23:52:21 +01:00
Edward Firmo
e9890c937e CodeRabbitAI suggestions 2024-12-19 23:39:32 +01:00
Edward Firmo
81bf402e35 Fix IDF version label 2024-12-19 21:43:06 +01:00
Edward Firmo
6d11d50e25 Fix yaml-file reference 2024-12-19 21:40:53 +01:00
Edward Firmo
fa2c212efe Update validate_esphome_beta.yml 2024-12-19 21:32:39 +01:00
Edward Firmo
3412e2389a Test with Beta 2024-12-19 21:25:58 +01:00
Edward Firmo
a4eff7276a Lint 2024-12-19 21:17:46 +01:00
Edward Firmo
7c04d152a0 Lint 2024-12-19 21:15:18 +01:00
Edward Firmo
2e15149d3d Clean-up buttons 2024-12-19 21:11:55 +01:00
Edward Firmo
818c6067e0 Bump to v0.0.4 2024-12-19 20:46:19 +01:00
Edward Firmo
2f92e874b3 Clean-up relay mode select 2024-12-19 20:45:31 +01:00
Edward Firmo
13722eccd0 Reorg relays 2024-12-19 20:30:55 +01:00
Edward Firmo
51bf0dceab Reorg led select 2024-12-19 20:20:05 +01:00
Edward Firmo
01293fd62d Review effects 2024-12-19 20:13:17 +01:00
Edward Firmo
3f86f7dee9 Reorg led files 2024-12-19 20:11:52 +01:00
Edward Firmo
b6d9ae5a96 Split files
To improve readability and increase my chances to have more people collaborating with this project.

Solves #27
2024-12-19 19:35:46 +01:00
Edward Firmo
7e46ecb1b3 Fix led mapping on US model
Tentatively solves #29
2024-08-29 18:15:09 +02:00
17 changed files with 2264 additions and 1850 deletions

View File

@@ -3,24 +3,6 @@ name: Validate ESPHome
# yamllint disable-line rule:truthy
on:
push:
paths:
- "*.yaml"
- "prebuilt/*.yaml"
- ".test/*.yaml"
- "*.h"
- "*.c"
- "*.cpp"
- "*.py"
pull_request:
paths:
- "*.yaml"
- "prebuilt/*.yaml"
- ".test/*.yaml"
- "*.h"
- "*.c"
- "*.cpp"
- "*.py"
workflow_dispatch:
concurrency:
@@ -56,10 +38,10 @@ jobs:
- name: Build core
uses: esphome/build-action@main
with:
yaml_file: ".test/esphome_ard_basic.yaml"
yaml-file: ".test/esphome_ard_basic.yaml"
build_bluetooth_proxy_4:
name: Bluetooth Proxy (IDF v4)
name: Bluetooth Proxy (IDF)
needs: build_basic
runs-on: ubuntu-latest
steps:
@@ -67,10 +49,10 @@ jobs:
- name: Build core
uses: esphome/build-action@main
with:
yaml_file: ".test/esphome_idf_bluetooth_proxy.yaml"
yaml-file: ".test/esphome_idf_bluetooth_proxy.yaml"
build_bluetooth_proxy_5:
name: Bluetooth Proxy (IDF v5)
build_bluetooth_proxy_53:
name: Bluetooth Proxy (IDF v5.3)
needs: build_basic
runs-on: ubuntu-latest
steps:
@@ -78,5 +60,5 @@ jobs:
- name: Build core
uses: esphome/build-action@main
with:
yaml_file: ".test/esphome_idf5_bluetooth_proxy.yaml"
yaml-file: ".test/esphome_idf53_bluetooth_proxy.yaml"
...

View File

@@ -3,6 +3,24 @@ name: Validate ESPHome (Beta)
# yamllint disable-line rule:truthy
on:
push:
paths:
- "*.yaml"
- "ESPHome/*.yaml"
- ".test/*.yaml"
- "*.h"
- "*.c"
- "*.cpp"
- "*.py"
pull_request:
paths:
- "*.yaml"
- "ESPHome/*.yaml"
- ".test/*.yaml"
- "*.h"
- "*.c"
- "*.cpp"
- "*.py"
workflow_dispatch:
concurrency:
@@ -10,32 +28,9 @@ concurrency:
cancel-in-progress: true
jobs:
setup_dependencies:
name: Setup & Cache Dependencies
runs-on: ubuntu-latest
outputs:
cache-hit-arduino: ${{ steps.cache-arduino.outputs.cache-hit }}
steps:
- name: Checkout repository
uses: actions/checkout@main
- name: Cache Arduino Dependencies
id: cache-arduino
uses: actions/cache@main
with:
path: |
~/.esphome/cache
~/.platformio/packages
~/.platformio/platforms
key: ${{ runner.os }}-arduino-${{ hashFiles('**/esphome_ard_basic.yaml') }}
restore-keys: |
${{ runner.os }}-arduino-
code_scan:
name: Code scan (YAML)
runs-on: "ubuntu-latest"
needs: setup_dependencies
steps:
- name: Checkout Code
uses: actions/checkout@main
@@ -53,48 +48,38 @@ jobs:
build_basic:
name: Basic
needs: [code_scan, setup_dependencies]
needs:
- code_scan
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- id: ard
yaml_file: ".test/esphome_ard_basic.yaml"
cache-hit: ${{ needs.setup_dependencies.outputs.cache-hit-arduino }}
steps:
- name: Checkout repository
uses: actions/checkout@main
- name: Firmware
if: steps.matrix.outputs.cache-hit != 'true'
- uses: actions/checkout@main
- name: Build core
uses: esphome/build-action@main
with:
yaml_file: ${{ matrix.yaml_file }}
yaml-file: ".test/esphome_ard_basic.yaml"
version: beta
build_bluetooth_proxy:
name: Bluetooth Proxy
build_bluetooth_proxy_4:
name: Bluetooth Proxy (IDF)
needs: build_basic
runs-on: ubuntu-latest
strategy:
matrix:
include:
- id: idf_v4
base: idf_v4
yaml_file: ".test/esphome_idf_bluetooth_proxy.yaml"
- id: idf_v5
base: idf_v5
yaml_file: ".test/esphome_idf5_bluetooth_proxy.yaml"
steps:
- name: Checkout repository
uses: actions/checkout@main
- name: Build Bluetooth Proxy Firmware
- uses: actions/checkout@main
- name: Build core
uses: esphome/build-action@main
with:
yaml_file: ${{ matrix.yaml_file }}
yaml-file: ".test/esphome_idf_bluetooth_proxy.yaml"
version: beta
build_bluetooth_proxy_53:
name: Bluetooth Proxy (IDF v5.3)
needs: build_basic
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build core
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_idf53_bluetooth_proxy.yaml"
version: beta
...

View File

@@ -6,6 +6,6 @@ packages:
esp32:
framework:
type: esp-idf
version: 5.0.2
platform_version: 6.3.2
version: 5.3.1
platform_version: 6.9.0
...

View File

@@ -1,3 +1,15 @@
####################################################################################################
##### TX Ultimate Easy for ESPHome #####
##### Repository: https://github.com/edwardtfn/TX-Ultimate-Easy #####
####################################################################################################
##### Purpose: ESPHome Core - Add-on - BLE Proxy #####
####################################################################################################
##### Author: edwardtfn - https://github.com/edwardtfn - https://buymeacoffee.com/edwardfirmo #####
####################################################################################################
##### NOTE: #####
##### - Make changes ONLY if absolutely necessary and you have the required knowledge. #####
##### - For normal system use, modifications to this file are NOT required. #####
####################################################################################################
---
bluetooth_proxy:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,41 @@
####################################################################################################
##### TX Ultimate Easy for ESPHome #####
##### Repository: https://github.com/edwardtfn/TX-Ultimate-Easy #####
####################################################################################################
##### Purpose: ESPHome Core - API #####
####################################################################################################
##### Author: edwardtfn - https://github.com/edwardtfn - https://buymeacoffee.com/edwardfirmo #####
####################################################################################################
##### NOTE: #####
##### - Make changes ONLY if absolutely necessary and you have the required knowledge. #####
##### - For normal system use, modifications to this file are NOT required. #####
####################################################################################################
---
api:
id: api_server
on_client_connected:
then:
- script.execute: publish_device_info
script:
- id: !extend button_action
then:
- script.execute:
id: send_event_to_ha
component: !lambda return component.c_str();
event: !lambda return event.c_str();
- id: send_event_to_ha
mode: queued
parameters:
component: string
event: string
then:
- homeassistant.event:
event: esphome.tx_ultimate_easy
data:
device_name: !lambda return tx_device_name->state.c_str();
firmware: ${version}
component: !lambda return component.c_str();
event: !lambda return event.c_str();
...

View File

@@ -0,0 +1,277 @@
####################################################################################################
##### TX Ultimate Easy for ESPHome #####
##### Repository: https://github.com/edwardtfn/TX-Ultimate-Easy #####
####################################################################################################
##### Purpose: ESPHome Core - Hardware - Buttons #####
####################################################################################################
##### Author: edwardtfn - https://github.com/edwardtfn - https://buymeacoffee.com/edwardfirmo #####
####################################################################################################
##### NOTE: #####
##### - Make changes ONLY if absolutely necessary and you have the required knowledge. #####
##### - For normal system use, modifications to this file are NOT required. #####
####################################################################################################
---
substitutions:
invalid_cooldown: 100ms
BUTTON_ACTION_NONE_TEXT: "None"
BUTTON_1_ACTION_TEXT: "Relay 1 (toggle)"
BUTTON_2_ACTION_TEXT: "Relay 2 (toggle)"
BUTTON_3_ACTION_TEXT: "Relay 3 (toggle)"
BUTTON_4_ACTION_TEXT: "Relay 4 (toggle)"
binary_sensor:
- id: bs_button_1
name: Button 1
icon: mdi:gesture-tap-box
internal: false
platform: template
on_click:
then:
- script.execute:
id: button_action
component: bs_button_1
event: click
on_double_click:
then:
- script.execute:
id: button_action
component: bs_button_1
event: double_click
on_multi_click:
- timing: &long_click-timing
- ON for at least 0.8s
invalid_cooldown: ${invalid_cooldown}
then:
- script.execute:
id: button_action
component: bs_button_1
event: long_click
- id: bs_button_2
name: Button 2
icon: mdi:gesture-tap-box
internal: true
platform: template
on_click:
then:
- script.execute:
id: button_action
component: bs_button_2
event: click
on_double_click:
then:
- script.execute:
id: button_action
component: bs_button_2
event: double_click
on_multi_click:
- timing: *long_click-timing
invalid_cooldown: ${invalid_cooldown}
then:
- script.execute:
id: button_action
component: bs_button_2
event: long_click
- id: bs_button_3
name: Button 3
icon: mdi:gesture-tap-box
internal: true
platform: template
on_click:
then:
- script.execute:
id: button_action
component: bs_button_3
event: click
on_double_click:
then:
- script.execute:
id: button_action
component: bs_button_3
event: double_click
on_multi_click:
- timing: *long_click-timing
invalid_cooldown: ${invalid_cooldown}
then:
- script.execute:
id: button_action
component: bs_button_3
event: long_click
- id: bs_button_4
name: Button 4
icon: mdi:gesture-tap-box
internal: true
platform: template
on_click:
then:
- script.execute:
id: button_action
component: bs_button_4
event: click
on_double_click:
then:
- script.execute:
id: button_action
component: bs_button_4
event: double_click
on_multi_click:
- timing: *long_click-timing
invalid_cooldown: ${invalid_cooldown}
then:
- script.execute:
id: button_action
component: bs_button_4
event: long_click
script:
- id: !extend boot_initialize
then:
- script.execute: boot_initialize_buttons
- id: boot_initialize_buttons
mode: restart
then:
- wait_until:
condition:
- lambda: return sl_tx_model_gang->active_index().has_value();
- lambda: |-
const uint8_t num_gangs = (sl_tx_model_gang->active_index().has_value()) ?
(sl_tx_model_gang->active_index().value() + 1) : 0;
if (num_gangs < 1 || num_gangs > 4) {
ESP_LOGE("core_hw_buttons", "Invalid number of gangs: %" PRIu8, num_gangs);
return;
}
bs_button_1->publish_state(false);
bs_button_1->set_internal(num_gangs < 1);
sl_button_1_action->set_internal(num_gangs < 1);
bs_button_2->publish_state(false);
bs_button_2->set_internal(num_gangs < 2);
sl_button_2_action->set_internal(num_gangs < 2);
bs_button_3->publish_state(false);
bs_button_3->set_internal(num_gangs < 3);
sl_button_3_action->set_internal(num_gangs < 3);
bs_button_4->publish_state(false);
bs_button_4->set_internal(num_gangs < 4);
sl_button_4_action->set_internal(num_gangs < 4);
- id: button_action
mode: parallel
parameters:
component: string
event: string
then: # There's nothing here so far
# Extended by:
# - core_api
- id: buttons_release
mode: restart
then:
- lambda: |-
std::vector<binary_sensor::BinarySensor*> buttons = {
bs_button_1, bs_button_2, bs_button_3, bs_button_4
};
for (auto* button : buttons) {
if (button->state) {
button->publish_state(false);
}
}
- id: !extend touch_on_multi_touch_release
then:
- script.execute: buttons_release
- id: !extend touch_on_press
then:
- script.execute:
id: touch_on_press_buttons
touch_x: !lambda return touch_x;
- id: touch_on_press_buttons
mode: restart
parameters:
touch_x: uint8_t
then:
- lambda: |-
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;
}
}
- id: !extend touch_on_release
then:
- script.execute: buttons_release
- id: !extend touch_swipe_left
then:
- script.execute: buttons_release
- id: !extend touch_swipe_right
then:
- script.execute: buttons_release
select:
- &button_select_action_base
id: sl_button_1_action
name: Button 1 action
platform: template
options:
- "${BUTTON_ACTION_NONE_TEXT}"
- "${BUTTON_1_ACTION_TEXT}"
initial_option: "${BUTTON_1_ACTION_TEXT}"
optimistic: true
restore_value: true
internal: true
entity_category: config
disabled_by_default: false
icon: mdi:dip-switch
- id: sl_button_2_action
name: Button 2 action
platform: template
options:
- "${BUTTON_ACTION_NONE_TEXT}"
- "${BUTTON_2_ACTION_TEXT}"
initial_option: "${BUTTON_2_ACTION_TEXT}"
<<: *button_select_action_base
- id: sl_button_3_action
name: Button 3 action
platform: template
options:
- "${BUTTON_ACTION_NONE_TEXT}"
- "${BUTTON_3_ACTION_TEXT}"
initial_option: "${BUTTON_3_ACTION_TEXT}"
<<: *button_select_action_base
- id: sl_button_4_action
name: Button 4 action
platform: template
options:
- "${BUTTON_ACTION_NONE_TEXT}"
- "${BUTTON_4_ACTION_TEXT}"
initial_option: "${BUTTON_4_ACTION_TEXT}"
<<: *button_select_action_base
...

View File

@@ -0,0 +1,963 @@
####################################################################################################
##### TX Ultimate Easy for ESPHome #####
##### Repository: https://github.com/edwardtfn/TX-Ultimate-Easy #####
####################################################################################################
##### Purpose: ESPHome Core - Hardware - LEDs #####
####################################################################################################
##### Author: edwardtfn - https://github.com/edwardtfn - https://buymeacoffee.com/edwardfirmo #####
####################################################################################################
##### NOTE: #####
##### - Make changes ONLY if absolutely necessary and you have the required knowledge. #####
##### - For normal system use, modifications to this file are NOT required. #####
####################################################################################################
---
substitutions:
default_transition_length: 500ms
LIGHT_MODE_BOTH_TEXT: "Both"
LIGHT_MODE_DISABLED_TEXT: "Disabled"
LIGHT_MODE_LEFT_TEXT: "Left"
LIGHT_MODE_RIGHT_TEXT: "Right"
LIGHT_MODE_BOTTOM_TEXT: "Bottom"
LIGHT_MODE_TOP_TEXT: "Top"
LIGHT_TRANSITION_TURN_ON: '0' # Transition time in msec
LIGHT_TRANSITION_TURN_OFF: '0' # Transition time in msec
LIGHT_BRIGHTNESS_TURN_ON: '0' # Brightness (1 to 100%, 0 to not set it)
globals:
- id: gb_lights_1
type: std::vector<light::LightState*>
restore_value: false
- id: gb_lights_2
type: std::vector<light::LightState*>
restore_value: false
light:
- id: light_output_1
name: Light output 1
internal: true
platform: binary
output: output_relay_1
- id: light_output_2
name: Light output 2
internal: true
platform: binary
output: output_relay_2
- id: light_output_3
name: Light output 3
internal: true
platform: binary
output: output_relay_3
- id: light_output_4
name: Light output 4
internal: true
platform: binary
output: output_relay_4
- id: light_full
name: Light - All
internal: true
platform: neopixelbus
type: GRB
variant: WS2811
# method: esp32_rmt
num_leds: 32
pin: GPIO13
- id: light_eu
name: Light
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_effects.yaml
segments:
- id: light_full
from: 0
to: 27
- id: light_us
name: Light
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_effects.yaml
segments:
- id: light_full
from: 0
to: 31
# Those lights are available based on the model selections
- id: light_eu_bottom
name: Light - Bottom
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_internal.yaml
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_effects.yaml
segments:
- id: light_full
from: 6
to: 12
reversed: true
- id: light_eu_left
name: Light - Left
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_internal.yaml
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_effects.yaml
segments:
- id: light_full
from: 13
to: 19
reversed: true
- id: light_eu_right
name: Light - Right
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_internal.yaml
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_effects.yaml
segments:
- id: light_full
from: 27
to: 27
reversed: false
- id: light_full
from: 0
to: 5
reversed: false
- id: light_eu_top
name: Light - Top
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_internal.yaml
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_effects.yaml
segments:
- id: light_full
from: 20
to: 26
reversed: false
- id: light_us_bottom
name: Light - Bottom
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_internal.yaml
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_effects.yaml
segments:
- id: light_full
from: 9
to: 14
reversed: true
- id: light_us_left
name: Light - Left
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_internal.yaml
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_effects.yaml
segments:
- id: light_full
from: 15
to: 24
reversed: true
- id: light_us_right
name: Light - Right
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_internal.yaml
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_effects.yaml
segments:
- id: light_full
from: 31
to: 31
reversed: false
- id: light_full
from: 0
to: 8
reversed: false
- id: light_us_top
name: Light - Top
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_internal.yaml
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_effects.yaml
segments:
- id: light_full
from: 25
to: 30
reversed: false
- id: light_00
name: Light - LED 00
disabled_by_default: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 0
to: 0
- id: light_01
name: Light - LED 01
disabled_by_default: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 1
to: 1
- id: light_02
name: Light - LED 02
disabled_by_default: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 2
to: 2
- id: light_03
name: Light - LED 03
disabled_by_default: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 3
to: 3
- id: light_04
name: Light - LED 04
disabled_by_default: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 4
to: 4
- id: light_05
name: Light - LED 05
disabled_by_default: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 5
to: 5
- id: light_06
name: Light - LED 06
disabled_by_default: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 6
to: 6
- id: light_07
name: Light - LED 07
disabled_by_default: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 7
to: 7
- id: light_08
name: Light - LED 08
disabled_by_default: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 8
to: 8
- id: light_09
name: Light - LED 09
disabled_by_default: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 9
to: 9
- id: light_10
name: Light - LED 10
disabled_by_default: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 10
to: 10
- id: light_11
name: Light - LED 11
disabled_by_default: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 11
to: 11
- id: light_12
name: Light - LED 12
disabled_by_default: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 12
to: 12
- id: light_13
name: Light - LED 13
disabled_by_default: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 13
to: 13
- id: light_14
name: Light - LED 14
disabled_by_default: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 14
to: 14
- id: light_15
name: Light - LED 15
disabled_by_default: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 15
to: 15
- id: light_16
name: Light - LED 16
disabled_by_default: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 16
to: 16
- id: light_17
name: Light - LED 17
disabled_by_default: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 17
to: 17
- id: light_18
name: Light - LED 18
disabled_by_default: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 18
to: 18
- id: light_19
name: Light - LED 19
disabled_by_default: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 19
to: 19
- id: light_20
name: Light - LED 20
disabled_by_default: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 20
to: 20
- id: light_21
name: Light - LED 21
disabled_by_default: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 21
to: 21
- id: light_22
name: Light - LED 22
disabled_by_default: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 22
to: 22
- id: light_23
name: Light - LED 23
disabled_by_default: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 23
to: 23
- id: light_24
name: Light - LED 24
disabled_by_default: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 24
to: 24
- id: light_25
name: Light - LED 25
disabled_by_default: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 25
to: 25
- id: light_26
name: Light - LED 26
disabled_by_default: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 26
to: 26
- id: light_27
name: Light - LED 27
disabled_by_default: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 27
to: 27
- id: light_28
name: Light - LED 28
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_internal.yaml
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 28
to: 28
- id: light_29
name: Light - LED 29
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_internal.yaml
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 29
to: 29
- id: light_30
name: Light - LED 30
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_internal.yaml
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 30
to: 30
- id: light_31
name: Light - LED 31
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_internal.yaml
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 31
to: 31
- id: light_eu_rl_1_1_bottom
name: Light - Relay 1 of 1 (bottom)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 9
to: 9
- id: light_eu_rl_1_1_top
name: Light - Relay 1 of 1 (top)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 23
to: 23
- id: light_eu_rl_1_2_bottom
name: Light - Relay 1 of 2 (bottom)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 11
to: 11
- id: light_eu_rl_1_2_top
name: Light - Relay 1 of 2 (top)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 21
to: 21
- id: light_eu_rl_2_2_bottom
name: Light - Relay 2 of 2 (bottom)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 7
to: 7
- id: light_eu_rl_2_2_top
name: Light - Relay 2 of 2 (top)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 25
to: 25
- id: light_eu_rl_1_3_bottom
name: Light - Relay 1 of 3 (bottom)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 12
to: 12
- id: light_eu_rl_1_3_top
name: Light - Relay 1 of 3 (top)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 20
to: 20
- id: light_eu_rl_2_3_bottom
name: Light - Relay 2 of 3 (bottom)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 9
to: 9
- id: light_eu_rl_2_3_top
name: Light - Relay 2 of 3 (top)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 23
to: 23
- id: light_eu_rl_3_3_bottom
name: Light - Relay 3 of 3 (bottom)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 6
to: 6
- id: light_eu_rl_3_3_top
name: Light - Relay 3 of 3 (top)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 26
to: 26
- id: light_eu_rl_1_4_bottom
name: Light - Relay 1 of 4 (bottom)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 12
to: 12
- id: light_eu_rl_1_4_top
name: Light - Relay 1 of 4 (top)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 20
to: 20
- id: light_eu_rl_2_4_bottom
name: Light - Relay 2 of 4 (bottom)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 10
to: 10
- id: light_eu_rl_2_4_top
name: Light - Relay 2 of 4 (top)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 22
to: 22
- id: light_eu_rl_3_4_bottom
name: Light - Relay 3 of 4 (bottom)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 8
to: 8
- id: light_eu_rl_3_4_top
name: Light - Relay 3 of 4 (top)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 24
to: 24
- id: light_eu_rl_4_4_bottom
name: Light - Relay 4 of 4 (bottom)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 6
to: 6
- id: light_eu_rl_4_4_top
name: Light - Relay 4 of 4 (top)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 26
to: 26
- id: light_us_rl_1_1_left
name: Light - Relay 1 of 1 (left)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 15
to: 24
- id: light_us_rl_1_1_right
name: Light - Relay 1 of 1 (right)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
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
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 20
to: 24
- id: light_us_rl_1_2_right
name: Light - Relay 1 of 2 (right)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
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
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 15
to: 19
- id: light_us_rl_2_2_right
name: Light - Relay 2 of 2 (right)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 4
to: 8
- id: light_us_rl_1_3_left
name: Light - Relay 1 of 3 (left)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 22
to: 23
- id: light_us_rl_1_3_right
name: Light - Relay 1 of 3 (right)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 0
to: 1
- id: light_us_rl_2_3_left
name: Light - Relay 2 of 3 (left)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 19
to: 20
- id: light_us_rl_2_3_right
name: Light - Relay 2 of 3 (right)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 3
to: 4
- id: light_us_rl_3_3_left
name: Light - Relay 3 of 3 (left)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 17
to: 18
- id: light_us_rl_3_3_right
name: Light - Relay 3 of 3 (right)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 6
to: 7
- id: light_us_rl_1_4_left
name: Light - Relay 1 of 4 (left)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 12
to: 12
- id: light_us_rl_1_4_right
name: Light - Relay 1 of 4 (right)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 31
to: 31
- id: light_us_rl_2_4_left
name: Light - Relay 2 of 4 (left)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 24
to: 24
- id: light_us_rl_2_4_right
name: Light - Relay 2 of 4 (right)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 2
to: 2
- id: light_us_rl_3_4_left
name: Light - Relay 3 of 4 (left)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 21
to: 21
- id: light_us_rl_3_4_right
name: Light - Relay 3 of 4 (right)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 4
to: 4
- id: light_us_rl_4_4_left
name: Light - Relay 4 of 4 (left)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 19
to: 19
- id: light_us_rl_4_4_right
name: Light - Relay 4 of 4 (right)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 7
to: 7
script:
- id: !extend boot_initialize
then:
- wait_until:
condition:
- lambda: return sl_tx_model_format->active_index().has_value();
- lambda: return sl_tx_model_gang->active_index().has_value();
- lambda: |-
const bool is_model_us = sl_tx_model_format->active_index().has_value() and
sl_tx_model_format->active_index().value() == 1;
const uint8_t num_gangs = (sl_tx_model_gang->active_index().has_value()) ?
(sl_tx_model_gang->active_index().value() + 1) : 0;
if (num_gangs < 1 || num_gangs > 4) {
ESP_LOGE("core_hw_leds", "Invalid number of gangs: %" PRIu8, num_gangs);
return;
}
light_28->set_internal(!is_model_us);
light_29->set_internal(!is_model_us);
light_30->set_internal(!is_model_us);
light_31->set_internal(!is_model_us);
light_eu->set_internal(is_model_us);
light_eu_bottom->set_internal(is_model_us);
light_eu_left->set_internal(is_model_us);
light_eu_right->set_internal(is_model_us);
light_eu_top->set_internal(is_model_us);
light_us->set_internal(!is_model_us);
light_us_bottom->set_internal(!is_model_us);
light_us_left->set_internal(!is_model_us);
light_us_right->set_internal(!is_model_us);
light_us_top->set_internal(!is_model_us);
switch (num_gangs) {
case 1: // 1 Gang
if (is_model_us) {
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 (is_model_us) {
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 (is_model_us) {
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 (is_model_us) {
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;
}
- id: light_set_state
mode: parallel
parameters:
light_group: uint8_t
light_index: uint8_t
state: bool
then:
- lambda: |-
static const uint32_t LIGHT_TRANSITION_TURN_ON = ${LIGHT_TRANSITION_TURN_ON};
static const uint32_t LIGHT_TRANSITION_TURN_OFF = ${LIGHT_TRANSITION_TURN_OFF};
static const uint8_t LIGHT_BRIGHTNESS_TURN_ON = ${LIGHT_BRIGHTNESS_TURN_ON};
const bool is_model_us = sl_tx_model_format->active_index().has_value() and
sl_tx_model_format->active_index().value() == 1;
const std::string light_mode_group_1 = is_model_us ? "${LIGHT_MODE_LEFT_TEXT}" : "${LIGHT_MODE_BOTTOM_TEXT}";
const std::string light_mode_group_2 = is_model_us ? "${LIGHT_MODE_RIGHT_TEXT}" : "${LIGHT_MODE_TOP_TEXT}";
switch (light_group) {
case 1:
if (light_index >= id(gb_lights_1).size()) {
ESP_LOGE("core_hw_leds", "Invalid set with %s light for Relay %" PRIu8,
light_mode_group_1.c_str(), light_index);
return;
}
if (state and !id(gb_lights_1)[light_index]->current_values.is_on()) {
ESP_LOGI("core_hw_leds", "Turn-on %s light for Relay %" PRIu8,
light_mode_group_1.c_str(), light_index);
auto call = id(gb_lights_1)[light_index]->turn_on();
if (LIGHT_TRANSITION_TURN_ON > 0)
call.set_transition_length(LIGHT_TRANSITION_TURN_ON); // in ms
if (LIGHT_BRIGHTNESS_TURN_ON > 0 and LIGHT_BRIGHTNESS_TURN_ON <= 100)
call.set_brightness(LIGHT_BRIGHTNESS_TURN_ON / 100.0f);
call.perform();
} else if (!state and id(gb_lights_1)[light_index]->current_values.is_on()) {
ESP_LOGI("core_hw_leds", "Turn-off %s light for Relay %" PRIu8,
light_mode_group_1.c_str(), light_index);
auto call = id(gb_lights_1)[light_index]->turn_off();
if (LIGHT_TRANSITION_TURN_OFF > 0)
call.set_transition_length(LIGHT_TRANSITION_TURN_OFF); // in ms
call.perform();
}
break;
case 2:
if (light_index >= id(gb_lights_2).size()) {
ESP_LOGE("core_hw_leds", "Invalid set with %s light for Relay %" PRIu8,
light_mode_group_2.c_str(), light_index);
return;
}
if (state and !id(gb_lights_2)[light_index]->current_values.is_on()) {
ESP_LOGI("core_hw_leds", "Turn-on %s light for Relay %" PRIu8,
light_mode_group_2.c_str(), light_index);
auto call = id(gb_lights_2)[light_index]->turn_on();
if (LIGHT_TRANSITION_TURN_ON > 0)
call.set_transition_length(LIGHT_TRANSITION_TURN_ON); // in ms
if (LIGHT_BRIGHTNESS_TURN_ON > 0 and LIGHT_BRIGHTNESS_TURN_ON <= 100)
call.set_brightness(LIGHT_BRIGHTNESS_TURN_ON / 100.0f);
call.perform();
} else if (!state and id(gb_lights_2)[light_index]->current_values.is_on()) {
ESP_LOGI("core_hw_leds", "Turn-off %s light for Relay %" PRIu8,
light_mode_group_2.c_str(), light_index);
auto call = id(gb_lights_2)[light_index]->turn_off();
if (LIGHT_TRANSITION_TURN_OFF > 0)
call.set_transition_length(LIGHT_TRANSITION_TURN_OFF); // in ms
call.perform();
}
break;
}
select:
# EU relay light mode template
- &relay_light_mode_eu
id: sl_relay_1_light_mode_eu
name: Relay 1 light mode
platform: template
options:
- "${LIGHT_MODE_DISABLED_TEXT}"
- "${LIGHT_MODE_BOTTOM_TEXT}"
- "${LIGHT_MODE_TOP_TEXT}"
- "${LIGHT_MODE_BOTH_TEXT}"
initial_option: "${LIGHT_MODE_BOTTOM_TEXT}"
optimistic: true
restore_value: true
internal: true
entity_category: config
disabled_by_default: false
icon: mdi:dots-square
- id: sl_relay_2_light_mode_eu
name: Relay 2 light mode
<<: *relay_light_mode_eu
- id: sl_relay_3_light_mode_eu
name: Relay 3 light mode
<<: *relay_light_mode_eu
- id: sl_relay_4_light_mode_eu
name: Relay 4 light mode
<<: *relay_light_mode_eu
# US relay light mode template
- &relay_light_mode_us
id: sl_relay_1_light_mode_us
name: Relay 1 light mode
platform: template
options:
- "${LIGHT_MODE_DISABLED_TEXT}"
- "${LIGHT_MODE_LEFT_TEXT}"
- "${LIGHT_MODE_RIGHT_TEXT}"
- "${LIGHT_MODE_BOTH_TEXT}"
initial_option: "${LIGHT_MODE_RIGHT_TEXT}"
optimistic: true
restore_value: true
internal: true
entity_category: config
disabled_by_default: false
icon: mdi:dots-square
- id: sl_relay_2_light_mode_us
name: Relay 2 light mode
<<: *relay_light_mode_us
- id: sl_relay_3_light_mode_us
name: Relay 3 light mode
<<: *relay_light_mode_us
- id: sl_relay_4_light_mode_us
name: Relay 4 light mode
<<: *relay_light_mode_us
...

View File

@@ -0,0 +1,4 @@
---
platform: partition
default_transition_length: ${default_transition_length}
...

View File

@@ -0,0 +1,40 @@
---
effects:
- addressable_rainbow:
name: "Rainbow"
- addressable_rainbow:
name: "Rainbow - Fast"
speed: 50
- pulse:
name: "Pulse"
transition_length: 1s
update_interval: 1s
- pulse:
name: "Pulse - Slow"
transition_length: 2s
update_interval: 2s
- addressable_scan:
name: "Scan"
move_interval: 100ms
scan_width: 3
- addressable_twinkle:
name: "Twinkle"
twinkle_probability: 5%
progress_interval: 4ms
- addressable_random_twinkle:
name: "Random Twinkle"
twinkle_probability: 20%
progress_interval: 32ms
- addressable_fireworks:
name: "Fireworks"
update_interval: 32ms
spark_probability: 10%
use_random_color: false
fade_out_rate: 120
- addressable_flicker:
name: "Flicker"
update_interval: 16ms
intensity: 5%
- random:
name: "Random"
...

View File

@@ -0,0 +1,4 @@
---
internal: true
disabled_by_default: true
...

View File

@@ -0,0 +1,272 @@
####################################################################################################
##### TX Ultimate Easy for ESPHome #####
##### Repository: https://github.com/edwardtfn/TX-Ultimate-Easy #####
####################################################################################################
##### Purpose: ESPHome Core - Hardware - Relays #####
####################################################################################################
##### Author: edwardtfn - https://github.com/edwardtfn - https://buymeacoffee.com/edwardfirmo #####
####################################################################################################
##### NOTE: #####
##### - Make changes ONLY if absolutely necessary and you have the required knowledge. #####
##### - For normal system use, modifications to this file are NOT required. #####
####################################################################################################
---
binary_sensor:
- id: !extend bs_button_1
on_click:
then:
- if:
condition:
- lambda: return sl_button_1_action->active_index().has_value();
- lambda: return sl_button_1_action->active_index().value() == 1;
- and: &button_click_no_other_click
- lambda: return not bs_multi_touch->state;
- lambda: return not bs_swipe_left->state;
- lambda: return not bs_swipe_down->state;
- lambda: return not bs_swipe_right->state;
then:
- switch.toggle: sw_relay_1
- id: !extend bs_button_2
on_click:
then:
- if:
condition:
- lambda: return sl_button_2_action->active_index().has_value();
- lambda: return sl_button_2_action->active_index().value() == 1;
- and: *button_click_no_other_click
then:
- switch.toggle: sw_relay_2
- id: !extend bs_button_3
on_click:
then:
- if:
condition:
- lambda: return sl_button_3_action->active_index().has_value();
- lambda: return sl_button_3_action->active_index().value() == 1;
- and: *button_click_no_other_click
then:
- switch.toggle: sw_relay_3
- id: !extend bs_button_4
on_click:
then:
- if:
condition:
- lambda: return sl_button_4_action->active_index().has_value();
- lambda: return sl_button_4_action->active_index().value() == 1;
- and: *button_click_no_other_click
then:
- switch.toggle: sw_relay_4
globals:
- id: boot_initialization_relays
type: bool
restore_value: false
initial_value: 'false'
output:
- id: output_relay_1
platform: gpio
pin: GPIO18
- id: output_relay_2
platform: gpio
pin: GPIO17
- id: output_relay_3
platform: gpio
pin: GPIO27
- id: output_relay_4
platform: gpio
pin: GPIO23
script:
- id: !extend boot_initialize
then:
- script.execute: boot_initialize_relays
- id: boot_initialize_relays
mode: restart
then:
- wait_until:
condition:
- lambda: return sl_tx_model_format->active_index().has_value();
- lambda: return sl_tx_model_gang->active_index().has_value();
- lambda: |-
const bool is_model_us = sl_tx_model_format->active_index().has_value() and
sl_tx_model_format->active_index().value() == 1;
const uint8_t num_gangs = (sl_tx_model_gang->active_index().has_value()) ?
(sl_tx_model_gang->active_index().value() + 1) : 0;
if (num_gangs < 1 || num_gangs > 4) {
ESP_LOGE("core_hw_relays", "Invalid number of gangs: %" PRIu8, num_gangs);
return;
}
sl_relay_1_mode->set_internal(num_gangs < 1);
sl_relay_1_light_mode_eu->set_internal(is_model_us or num_gangs < 1);
sl_relay_1_light_mode_us->set_internal(!is_model_us or num_gangs < 1);
sl_relay_2_mode->set_internal(num_gangs < 2);
sl_relay_2_light_mode_eu->set_internal(is_model_us or num_gangs < 2);
sl_relay_2_light_mode_us->set_internal(!is_model_us or num_gangs < 2);
sl_relay_3_mode->set_internal(num_gangs < 3);
sl_relay_3_light_mode_eu->set_internal(is_model_us or num_gangs < 3);
sl_relay_3_light_mode_us->set_internal(!is_model_us or num_gangs < 3);
sl_relay_4_mode->set_internal(num_gangs < 4);
sl_relay_4_light_mode_eu->set_internal(is_model_us or num_gangs < 4);
sl_relay_4_light_mode_us->set_internal(!is_model_us or num_gangs < 4);
auto relay_mode_index = sl_relay_1_mode->active_index();
if (relay_mode_index.has_value()) {
light_output_1->set_internal(false or relay_mode_index.value() != 1);
sw_relay_1->set_internal(false or relay_mode_index.value() != 0);
}
relay_mode_index = sl_relay_2_mode->active_index();
if (relay_mode_index.has_value()) {
light_output_2->set_internal(num_gangs < 2 or relay_mode_index.value() != 1);
sw_relay_2->set_internal(num_gangs < 2 or relay_mode_index.value() != 0);
}
relay_mode_index = sl_relay_3_mode->active_index();
if (relay_mode_index.has_value()) {
light_output_3->set_internal(num_gangs < 3 or relay_mode_index.value() != 1);
sw_relay_3->set_internal(num_gangs < 3 or relay_mode_index.value() != 0);
}
relay_mode_index = sl_relay_4_mode->active_index();
if (relay_mode_index.has_value()) {
light_output_4->set_internal(num_gangs < 4 or relay_mode_index.value() != 1);
sw_relay_4->set_internal(num_gangs < 4 or relay_mode_index.value() != 0);
}
id(boot_initialization_relays) = true;
- id: show_relay_status
mode: restart
then:
- script.wait: boot_initialize_relays
- wait_until:
condition:
- lambda: return id(boot_initialization_relays);
- lambda: |-
const bool is_model_us = sl_tx_model_format->active_index().has_value() and
sl_tx_model_format->active_index().value() == 1;
const uint8_t num_gangs = (sl_tx_model_gang->active_index().has_value())
? (sl_tx_model_gang->active_index().value() + 1)
: 0;
if (num_gangs < 1 || num_gangs > 4) {
ESP_LOGE("core_hw_relays", "Invalid number of gangs: %" PRIu8, num_gangs);
return;
}
for (uint8_t i = 0; i < num_gangs; i++) {
bool relay_state = false;
std::string light_mode;
const std::string light_mode_group_1 = is_model_us
? "${LIGHT_MODE_LEFT_TEXT}"
: "${LIGHT_MODE_BOTTOM_TEXT}";
const std::string light_mode_group_2 = is_model_us
? "${LIGHT_MODE_RIGHT_TEXT}"
: "${LIGHT_MODE_TOP_TEXT}";
// Determine relay state and light mode
switch (i) {
case 0:
relay_state = id(sw_relay_1).state;
light_mode = is_model_us
? id(sl_relay_1_light_mode_us)->state
: id(sl_relay_1_light_mode_eu)->state;
break;
case 1:
relay_state = id(sw_relay_2).state;
light_mode = is_model_us
? id(sl_relay_2_light_mode_us)->state
: id(sl_relay_2_light_mode_eu)->state;
break;
case 2:
relay_state = id(sw_relay_3).state;
light_mode = is_model_us
? id(sl_relay_3_light_mode_us)->state
: id(sl_relay_3_light_mode_eu)->state;
break;
case 3:
relay_state = id(sw_relay_4).state;
light_mode = is_model_us
? id(sl_relay_4_light_mode_us)->state
: id(sl_relay_4_light_mode_eu)->state;
break;
}
ESP_LOGV("core_hw_relays", "Relay %" PRIu8 " is %s", i + 1, relay_state ? "ON" : "OFF");
ESP_LOGV("core_hw_relays", "Light Mode for Relay %" PRIu8 ": %s", i + 1, light_mode.c_str());
// Use light_set_state for light updates
if (relay_state) {
if (light_mode == light_mode_group_1 || light_mode == "${LIGHT_MODE_BOTH_TEXT}") {
light_set_state->execute(1, i, true); // Left/bottom light
}
if (light_mode == light_mode_group_2 || light_mode == "${LIGHT_MODE_BOTH_TEXT}") {
light_set_state->execute(2, i, true); // Right/top light
}
} else {
light_set_state->execute(1, i, false); // Turn off left/bottom light
light_set_state->execute(2, i, false); // Turn off right/top light
}
}
select:
- &relay_select_mode_base
id: sl_relay_1_mode
name: Relay 1 mode
platform: template
options:
- "Relay"
- "Light"
- "Not in use"
optimistic: true
restore_value: true
internal: true
entity_category: config
disabled_by_default: false
icon: mdi:dip-switch
- id: sl_relay_2_mode
name: Relay 2 mode
<<: *relay_select_mode_base
- id: sl_relay_3_mode
name: Relay 3 mode
<<: *relay_select_mode_base
- id: sl_relay_4_mode
name: Relay 4 mode
<<: *relay_select_mode_base
switch:
- &relay_switch_base
id: sw_relay_1
name: Relay 1
platform: output
output: output_relay_1
restore_mode: RESTORE_DEFAULT_OFF
internal: true
on_turn_on:
then:
- script.execute: show_relay_status
on_turn_off:
then:
- script.execute: show_relay_status
- id: sw_relay_2
name: Relay 2
output: output_relay_2
<<: *relay_switch_base
- id: sw_relay_3
name: Relay 3
output: output_relay_3
<<: *relay_switch_base
- id: sw_relay_4
name: Relay 4
output: output_relay_4
<<: *relay_switch_base
...

View File

@@ -0,0 +1,29 @@
####################################################################################################
##### TX Ultimate Easy for ESPHome #####
##### Repository: https://github.com/edwardtfn/TX-Ultimate-Easy #####
####################################################################################################
##### Purpose: ESPHome Core - Hardware - Speaker #####
####################################################################################################
##### Author: edwardtfn - https://github.com/edwardtfn - https://buymeacoffee.com/edwardfirmo #####
####################################################################################################
##### NOTE: #####
##### - Make changes ONLY if absolutely necessary and you have the required knowledge. #####
##### - For normal system use, modifications to this file are NOT required. #####
####################################################################################################
---
i2s_audio:
id: if_i2s_audio
i2s_bclk_pin: GPIO2
i2s_lrclk_pin: GPIO4
media_player:
- id: mp_speaker
name: Speaker
platform: i2s_audio
i2s_dout_pin: GPIO15
i2s_audio_id: if_i2s_audio
i2s_comm_fmt: lsb
dac_type: external
mode: mono
internal: false
...

View File

@@ -0,0 +1,240 @@
####################################################################################################
##### TX Ultimate Easy for ESPHome #####
##### Repository: https://github.com/edwardtfn/TX-Ultimate-Easy #####
####################################################################################################
##### Purpose: ESPHome Core - Hardware - Touch panel #####
####################################################################################################
##### Author: edwardtfn - https://github.com/edwardtfn - https://buymeacoffee.com/edwardfirmo #####
####################################################################################################
##### NOTE: #####
##### - Make changes ONLY if absolutely necessary and you have the required knowledge. #####
##### - For normal system use, modifications to this file are NOT required. #####
####################################################################################################
---
binary_sensor:
- id: bs_multi_touch
name: Multi-touch
icon: mdi:gesture-two-tap
internal: false
platform: template
on_click:
then:
- lambda: send_event_to_ha->execute("multi_touch", "multi_touch");
- id: bs_swipe_left
name: Swipe left
icon: mdi:gesture-swipe-left
internal: true
platform: template
on_click:
then:
- lambda: send_event_to_ha->execute("swipe", "left");
- id: bs_swipe_right
name: Swipe right
icon: mdi:gesture-swipe-right
internal: true
platform: template
on_click:
then:
- lambda: send_event_to_ha->execute("swipe", "right");
- id: bs_swipe_up
name: Swipe up
icon: mdi:gesture-swipe-up
internal: true
platform: template
on_click:
then:
- lambda: send_event_to_ha->execute("swipe", "up");
- id: bs_swipe_down
name: Swipe down
icon: mdi:gesture-swipe-down
internal: true
platform: template
on_click:
then:
- lambda: send_event_to_ha->execute("swipe", "down");
external_components:
- source:
type: git
url: https://github.com/edwardtfn/TX-Ultimate-Easy
ref: ${version}
refresh: 1h
components:
- tx_ultimate_easy
number:
- id: nr_touch_duration
name: Touch duration
icon: mdi:timer-cog-outline
unit_of_measurement: ms
# mode: box
internal: false
entity_category: config
platform: template
min_value: 10
max_value: 1500
step: 1
initial_value: 250
optimistic: true
restore_value: true
script:
- id: !extend boot_initialize
then:
- script.execute: boot_initialize_touch
- id: boot_initialize_touch
mode: restart
then:
- wait_until:
condition:
- lambda: return sl_tx_model_format->active_index().has_value();
- lambda: |-
const bool is_model_us = sl_tx_model_format->active_index().has_value() and
sl_tx_model_format->active_index().value() == 1;
bs_multi_touch->publish_state(false);
bs_swipe_down->publish_state(false);
bs_swipe_down->set_internal(!is_model_us);
bs_swipe_left->publish_state(false);
bs_swipe_left->set_internal(is_model_us);
bs_swipe_right->publish_state(false);
bs_swipe_right->set_internal(is_model_us);
bs_swipe_up->publish_state(false);
bs_swipe_up->set_internal(!is_model_us);
- id: touch_on_multi_touch_release
mode: restart
then:
# Extended by:
# - HW Buttons
# - HW Vibration
- script.execute: touch_on_multi_touch_release_touch
- id: touch_on_multi_touch_release_touch
mode: restart
then:
- lambda: bs_multi_touch->publish_state(true);
- delay: !lambda return nr_touch_duration->state;
- lambda: bs_multi_touch->publish_state(false);
- id: touch_on_press
mode: restart
parameters:
touch_x: uint8_t
then:
# Extended by:
# - HW Buttons
# - HW Vibration
- id: touch_on_release
mode: restart
then:
# Extended by:
# - HW Buttons
# - HW Vibration
- script.execute: touch_swipe_turn_off_binary_sensor
- id: touch_swipe_left
mode: restart
then:
# Extended by:
# - HW Buttons
- script.execute: touch_swipe_left_touch
- id: touch_swipe_left_touch
mode: restart
then:
- binary_sensor.template.publish:
id: bs_swipe_left
state: ON # yamllint disable-line rule:truthy
- delay: !lambda return nr_touch_duration->state;
- script.execute: touch_swipe_turn_off_binary_sensor
- id: touch_swipe_right
mode: restart
then:
# Extended by:
# - HW Buttons
- script.execute: touch_swipe_right_touch
- id: touch_swipe_right_touch
mode: restart
then:
- binary_sensor.template.publish:
id: bs_swipe_right
state: ON # yamllint disable-line rule:truthy
- delay: !lambda return nr_touch_duration->state;
- script.execute: touch_swipe_turn_off_binary_sensor
- id: touch_swipe_turn_off_binary_sensor
mode: restart
then:
- if:
condition:
binary_sensor.is_on: bs_swipe_left
then:
- binary_sensor.template.publish:
id: bs_swipe_left
state: OFF # yamllint disable-line rule:truthy
- if:
condition:
binary_sensor.is_on: bs_swipe_right
then:
- binary_sensor.template.publish:
id: bs_swipe_right
state: OFF # yamllint disable-line rule:truthy
switch:
- id: sw_touch_panel_power
name: Touch panel - Power
platform: gpio
pin:
number: GPIO5
inverted: true
restore_mode: ALWAYS_ON
internal: false
entity_category: config
tx_ultimate_easy:
id: tx_ultimate
uart: uart_touch
on_multi_touch_release:
- lambda: ESP_LOGI("tx_ultimate_easy", "Multi-touch released");
- script.execute: touch_on_multi_touch_release
on_press:
- lambda: |-
ESP_LOGI("tx_ultimate_easy", "Pressed at position %" PRIu8, static_cast<uint8_t>(touch.x));
- script.execute:
id: touch_on_press
touch_x: !lambda return static_cast<uint8_t>(touch.x);
on_release:
- lambda: ESP_LOGI("tx_ultimate_easy", "Released");
- script.execute: touch_on_release
on_swipe_left:
- lambda: ESP_LOGI("tx_ultimate_easy", "Swipe left");
- script.execute: touch_swipe_left
on_swipe_right:
- lambda: ESP_LOGI("tx_ultimate_easy", "Swipe right");
- script.execute: touch_swipe_right
on_touch_event:
- lambda: |-
ESP_LOGD("tx_ultimate_easy", "Touch event:");
ESP_LOGD("tx_ultimate_easy", " State: %i (%s)", touch.state, touch.state_str.c_str());
ESP_LOGD("tx_ultimate_easy", " Position: %i", touch.x);
uart:
id: uart_touch
tx_pin: GPIO19
rx_pin: GPIO22
baud_rate: 115200
...

View File

@@ -0,0 +1,137 @@
####################################################################################################
##### TX Ultimate Easy for ESPHome #####
##### Repository: https://github.com/edwardtfn/TX-Ultimate-Easy #####
####################################################################################################
##### Purpose: ESPHome Core - Hardware - Vibration system #####
####################################################################################################
##### Author: edwardtfn - https://github.com/edwardtfn - https://buymeacoffee.com/edwardfirmo #####
####################################################################################################
##### NOTE: #####
##### - Make changes ONLY if absolutely necessary and you have the required knowledge. #####
##### - For normal system use, modifications to this file are NOT required. #####
####################################################################################################
---
substitutions:
vibration_max_duration: 2s
binary_sensor:
- id: bs_vibrating
name: Vibrating
icon: mdi:vibrate
internal: false
platform: template
lambda: return sw_vibration_motor->state;
button:
- id: bt_vibrate
name: Vibrate
icon: mdi:vibrate
internal: false
platform: template
on_press:
then:
- script.execute: vibrate
number:
- id: nr_vibrating_duration
name: Vibrate duration
icon: mdi:vibrate
unit_of_measurement: ms
internal: false
entity_category: config
platform: template
min_value: 1
max_value: 500
step: 1
initial_value: 15
optimistic: true
restore_value: true
ota:
on_state_change:
then:
- switch.turn_off: sw_vibration_motor
script:
- id: !extend touch_on_multi_touch_release
then:
- script.execute: touch_on_multi_touch_release_vibration
- id: touch_on_multi_touch_release_vibration
mode: restart
then:
- lambda: |-
if (sl_touch_vibration_feedback->state != "Disabled")
vibrate->execute();
- id: !extend touch_on_press
then:
- script.execute: touch_on_press_vibration
- id: touch_on_press_vibration
mode: restart
then:
- lambda: |-
if (sl_touch_vibration_feedback->state == "On press" or sl_touch_vibration_feedback->state == "Always")
vibrate->execute();
- id: !extend touch_on_release
then:
- script.execute: touch_on_release_vibration
- id: touch_on_release_vibration
mode: restart
then:
- lambda: |-
if (sl_touch_vibration_feedback->state == "On release" or sl_touch_vibration_feedback->state == "Always")
vibrate->execute();
- 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_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
switch:
- id: sw_vibration_motor
name: Vibration motor
platform: gpio
pin: GPIO21
restore_mode: ALWAYS_OFF
internal: true
on_turn_on:
then:
- binary_sensor.template.publish:
id: bs_vibrating
state: ON # yamllint disable-line rule:truthy
- delay: ${vibration_max_duration}
- if:
condition:
switch.is_on: sw_vibration_motor
then:
- switch.turn_off: sw_vibration_motor
on_turn_off:
then:
- binary_sensor.template.publish:
id: bs_vibrating
state: OFF # yamllint disable-line rule:truthy
...

154
README.md
View File

@@ -1,59 +1,141 @@
# TX Ultimate Easy
| &nbsp;![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. |
<!-- markdownlint-disable MD033 -->
<a href="https://github.com/edwardtfn/TX-Ultimate-Easy/commits/main" target="_blank">![GitHub Activity][commits-shield]</a>
<a href="LICENSE" target="_blank">![License][license-shield]</a>
<a href="https://github.com/edwardtfn/TX-Ultimate-Easy/commits/main" target="_blank">![GitHub Last Commit][last-commit-shield]</a>
<a href="https://esphome.io/" target="_blank">![ESPHome][esphome-shield]</a>
<a href="https://discord.gg/Db6WJWzWuf" target="_blank">![Discord][discord-shield]</a>
<a href="https://www.buymeacoffee.com/edwardfirmo" target="_blank">![Buy me an ice-cream][buymeacoffee-shield]</a>
<!-- markdownlint-enable MD033 -->
<!-- markdownlint-disable MD013 -->
| &nbsp;![TX Ultimate Easy Logo](Assets/Logo.webp) | TX Ultimate Easy provides custom ESPHome firmware for Sonoff TX Ultimate devices. Our project focuses on user-friendly configuration through the Home Assistant UI, eliminating the need for manual YAML editing. Whether you're new to home automation or an experienced user, TX Ultimate Easy makes it simple to manage your device. |
| --- | :-- |
<!-- markdownlint-enable MD013 -->
## Features
[commits-shield]: https://img.shields.io/github/commit-activity/y/edwardtfn/TX-Ultimate-Easy
[commits]: https://github.com/edwardtfn/TX-Ultimate-Easy/commits/main
[license-shield]: https://img.shields.io/github/license/edwardtfn/TX-Ultimate-Easy
[license]: LICENSE
[last-commit-shield]: https://img.shields.io/github/last-commit/edwardtfn/TX-Ultimate-Easy
[esphome-shield]: https://img.shields.io/badge/powered%20by-ESPHome-blue
[esphome]: https://esphome.io/
[discord-shield]: https://img.shields.io/discord/1243652421692031016?logo=discord
[discord]: https://discord.gg/Db6WJWzWuf
[buymeacoffee-shield]: https://img.shields.io/static/v1?label=Buy%20me%20an%20ice%20cream&message=❄&color=blue
[buymeacoffee]: https://www.buymeacoffee.com/edwardfirmo
- **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.
## Integration with Home Assistant
## Getting Started
TX Ultimate Easy exposes your device's components (sensors, touch panel, relays, etc.) to Home Assistant, allowing you to:
### Prerequisites
- Monitor sensor states and values
- Control device components through the Home Assistant UI
- Use device triggers and states in your Home Assistant automations and scripts
- Configure device behavior through Home Assistant's service calls
- Sonoff TX Ultimate device
- Home Assistant installed
- ESPHome add-on installed in Home Assistant
All automation capabilities are handled through Home Assistant's native automation system - this project focuses on providing reliable device integration rather than implementing its own automation tools.
### Installation
To be written.
## Key Features
### Configuration
- **Home Assistant UI Configuration**: Manage all device settings directly through the Home Assistant interface
- **Zero YAML Knowledge Required**: After initial setup, no manual YAML editing needed
- **Flexible Light Control**: Customize LED behavior and effects
- **Touch Panel Support**: Full support for touch gestures and multi-touch capabilities
- **Advanced Automations**: Create complex automations using Home Assistant's powerful automation engine
- **BLE Proxy Support**: Optional Bluetooth Low Energy proxy functionality
- **Audio Feedback**: Built-in speaker support for audible feedback
- **Haptic Feedback**: Vibration motor support for tactile feedback
- **Via Home Assistant UI:**
All device settings can be managed through the Home Assistant interface. No need to edit YAML files directly.
## Hardware Support
- **Using Blueprints:**
Import and use blueprints to quickly configure your device for common use cases.
- Compatible with all Sonoff TX Ultimate variants:
- EU format (Square, T5-xC-86)
- US format (Rectangle, T5-xC-120)
- 1/2/3/4 gang versions
## Documentation
To be written.
## Prerequisites
Before getting started, ensure you have:
1. A Sonoff TX Ultimate device
2. Home Assistant installation
3. ESPHome add-on installed in Home Assistant
4. Basic knowledge of Home Assistant
## Installation
Detailed installation instructions coming soon. The process will include:
1. Initial ESPHome setup
2. Device flashing
3. Home Assistant integration
4. Basic configuration
## Usage
After installation, you can:
1. Configure your device through Home Assistant UI
2. Customize touch behaviors
3. Set up LED patterns and effects
4. Create automations
5. Enable optional features like BLE proxy
## Configuration Options
TX Ultimate Easy offers extensive configuration options:
- Touch panel sensitivity and gestures
- LED colors, patterns, and behaviors
- Relay modes and functions
- Audio and haptic feedback settings
- Network and connectivity options
## 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.
We welcome contributions from the community! Here's how you can help:
1. Fork the repository
2. Create a feature branch from `dev`
3. Make your changes
4. Submit a pull request targeting the `dev` branch
Please ensure your code follows our standards:
- Passes all lint checks (YAML, C++, Markdown)
- Includes appropriate documentation
- Follows existing code style
All pull requests should be made against the `dev` branch. We don't accept pull requests directly to `main` as it's reserved for stable releases.
## Support and Community
Need help? Here are your options:
- **Bug Reports & Feature Requests**: Use [GitHub Issues](https://github.com/edwardtfn/TX-Ultimate-Easy/issues) for all bug reports and feature requests
- **Community Chat**: Join our [Discord Server](https://discord.gg/Db6WJWzWuf) for discussions and community interaction
- **Support the Project**: Consider supporting through Buy Me a Coffee
Note: For proper tracking and resolution, all bug reports and feature requests must be submitted through GitHub Issues, not Discord. The Issues page can be found at: [Issues · edwardtfn/TX-Ultimate-Easy](https://github.com/edwardtfn/TX-Ultimate-Easy/issues)
[![Buy Me a Coffee](https://www.buymeacoffee.com/assets/img/custom_images/yellow_img.png)](https://www.buymeacoffee.com/edwardfirmo)
## Acknowledgments
This project builds upon the work of several amazing projects and contributors:
- [SmartHome yourself - SONOFF TX Ultimate for ESPHome](https://github.com/SmartHome-yourself/sonoff-tx-ultimate-for-esphome)
- [Un loco y su tecnología - Sonoff TX Ultimate with ESPHome](https://www.youtube.com/watch?v=58v8oqSQgXQ)
Special thanks to all contributors and community members who help make this project better.
## 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)
---
<!-- markdownlint-disable MD033 -->
<img src="Assets/Logo.webp" alt="TX Ultimate Easy Logo" width="100"/>
<!-- markdownlint-enable MD033 -->

View File

@@ -1,3 +1,9 @@
####################################################################################################
##### TX Ultimate Easy for ESPHome #####
##### Repository: https://github.com/edwardtfn/TX-Ultimate-Easy #####
####################################################################################################
##### Author: edwardtfn - https://github.com/edwardtfn - https://buymeacoffee.com/edwardfirmo #####
####################################################################################################
---
substitutions:
name: tx-ultimate-easy