Merge branch 'main' into dev

This commit is contained in:
Edward Firmo
2025-05-02 18:30:35 +02:00
committed by GitHub
46 changed files with 1177 additions and 1308 deletions

View File

@@ -11,22 +11,14 @@
##### - For normal system use, modifications to this file are NOT required. #####
####################################################################################################
---
packages:
standard_hw_speaker: !include TX-Ultimate-Easy-ESPHome_standard_hw_speaker.yaml
bluetooth_proxy:
esp32:
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:
platformio_options:
@@ -39,11 +31,28 @@ light:
- id: !extend light_full
platform: esp32_rmt_led_strip
rgb_order: GRB
rmt_channel: 0
rmt_channel: 1
chipset: ws2812
max_refresh_rate: 33ms
use_psram: false
type: !remove
variant: !remove
max_refresh_rate: 33ms
media_player: !remove
script:
- id: !extend dump_config_list_packages
then:
- script.wait: dump_config
- lambda: |-
// Check for requirements
#if !defined(TX_ULTIMATE_EASY_CORE)
#error "The package TX-Ultimate-Easy-ESPHome_core.yaml is required."
#endif
// Identify itself
ESP_LOGCONFIG(ESPHOME_PROJECT_NAME, " - Add-on - BLE Proxy");
switch:
- id: !remove sw_speaker_amplifier
...

View File

@@ -0,0 +1,68 @@
####################################################################################################
##### TX Ultimate Easy for ESPHome #####
##### Repository: https://github.com/edwardtfn/TX-Ultimate-Easy #####
####################################################################################################
##### Purpose: ESPHome - Add-on - Media player #####
####################################################################################################
##### 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. #####
####################################################################################################
---
packages:
standard_hw_audio: !include TX-Ultimate-Easy-ESPHome_standard_hw_audio.yaml
esp32:
framework:
type: arduino
esphome:
platformio_options:
build_flags:
- -D TX_ULTIMATE_EASY_ADDON_MEDIA_PLAYER
media_player:
- id: mp_media_player
name: Media Player
internal: false
platform: i2s_audio
i2s_dout_pin: GPIO15
i2s_audio_id: if_i2s_audio
i2s_comm_fmt: msb
dac_type: external
mode: mono
mute_pin:
number: GPIO26
inverted: true
allow_other_uses: true
script:
- id: !extend dump_config_list_packages
then:
- script.wait: dump_config
- lambda: |-
// Check for requirements
#if !defined(TX_ULTIMATE_EASY_CORE)
#error "The package TX-Ultimate-Easy-ESPHome_core.yaml is required."
#endif
#if !defined(TX_ULTIMATE_EASY_STANDARD_HW_AUDIO)
#error "The package TX-Ultimate-Easy-ESPHome_standard_hw_audio.yaml is required."
#endif
// Identify itself
ESP_LOGCONFIG(ESPHOME_PROJECT_NAME, " - Add-on - Media Player");
switch:
- id: sw_speaker_amplifier
name: Speaker - Amplifier
platform: gpio
pin:
number: GPIO26
inverted: true
allow_other_uses: true
restore_mode: RESTORE_DEFAULT_ON
internal: true
entity_category: config
...

View File

@@ -11,202 +11,11 @@
##### - For normal system use, modifications to this file are NOT required. #####
####################################################################################################
---
substitutions:
name: tx-ultimate-easy
friendly_name: TX Ultimate Easy
<<: !include ../versioning/VERSION_YAML
TX_MODEL_FORMAT_EU_TEXT: "EU (Square, T5-xC-86)"
TX_MODEL_FORMAT_US_TEXT: "US (Rectangle, T5-xC-120)"
TX_MODEL_1_GANG_TEXT: "1 Gang"
TX_MODEL_2_GANG_TEXT: "2 Gang"
TX_MODEL_3_GANG_TEXT: "3 Gang"
TX_MODEL_4_GANG_TEXT: "4 Gang"
packages:
# yamllint disable rule:colons
core_hw_buttons: !include TX-Ultimate-Easy-ESPHome_core_hw_buttons.yaml
core_hw_leds: !include TX-Ultimate-Easy-ESPHome_core_hw_leds.yaml
core_hw_relays: !include TX-Ultimate-Easy-ESPHome_core_hw_relays.yaml
core_hw_speaker: !include TX-Ultimate-Easy-ESPHome_core_hw_speaker.yaml
core_hw_touch: !include TX-Ultimate-Easy-ESPHome_core_hw_touch.yaml
core_hw_vibration: !include TX-Ultimate-Easy-ESPHome_core_hw_vibration.yaml
core_common: !include TX-Ultimate-Easy-ESPHome_core_common.yaml
core_hw_buttons: !include TX-Ultimate-Easy-ESPHome_core_hw_buttons.yaml
core_hw_leds: !include TX-Ultimate-Easy-ESPHome_core_hw_leds.yaml
core_hw_touch: !include TX-Ultimate-Easy-ESPHome_core_hw_touch.yaml
# yamllint enable rule:colons
api:
id: api_server
on_client_connected:
then:
- script.execute: publish_device_info
button:
- id: bt_restart
name: Restart
internal: false
platform: restart
captive_portal:
id: ap_captive_portal
esp32:
board: esp32dev
flash_size: 8MB
esphome:
name: ${name}
friendly_name: ${friendly_name}
comment: TX Ultimate Easy
platformio_options:
build_flags:
- -D TX_ULTIMATE_EASY_CORE
on_boot:
- priority: 700
then:
- script.execute: boot_initialize
- priority: 600 # This is where most sensors are set up.
then:
- script.execute: boot_sequence
- priority: -100 # At this priority, pretty much everything should already be initialized.
then:
- script.execute: boot_done
improv_serial:
id: serial_improv
logger:
level: DEBUG
ota:
platform: esphome
psram:
script:
- id: api_send_ha_event_boot
mode: queued
parameters:
type: string
then:
- homeassistant.event:
event: esphome.tx_ultimate_easy
data:
device_name: !lambda return tx_device_name->state.c_str();
firmware: ${version}
domain: boot
type: !lambda return type.c_str();
- id: boot_done
mode: restart
then:
- script.execute:
id: api_send_ha_event_boot
type: done
- id: boot_initialize
mode: restart
then:
# Extended by:
# - HW Buttons
# - HW Relays
# - HW Touch
- script.execute:
id: api_send_ha_event_boot
type: start
- id: boot_sequence
mode: restart
then:
- script.execute: publish_device_info
- id: publish_device_info
mode: restart
then:
- lambda: |-
tx_fw_version->publish_state("${version}");
tx_device_name->publish_state(App.get_name().c_str());
select:
- id: sl_tx_model_format
name: Model (Format)
platform: template
options:
- "${TX_MODEL_FORMAT_EU_TEXT}"
- "${TX_MODEL_FORMAT_US_TEXT}"
initial_option: "${TX_MODEL_FORMAT_EU_TEXT}"
optimistic: true
restore_value: true
internal: false
entity_category: config
disabled_by_default: false
icon: mdi:tablet-cellphone
- id: sl_tx_model_gang
name: Model (Gang)
platform: template
options:
- "${TX_MODEL_1_GANG_TEXT}"
- "${TX_MODEL_2_GANG_TEXT}"
- "${TX_MODEL_3_GANG_TEXT}"
- "${TX_MODEL_4_GANG_TEXT}"
initial_option: "${TX_MODEL_1_GANG_TEXT}"
optimistic: true
restore_value: true
internal: false
entity_category: config
disabled_by_default: false
icon: mdi:dip-switch
on_value:
then:
- lambda: tx_ultimate->set_gang_count(static_cast<uint8_t>(i)+1);
text_sensor:
- id: tx_fw_version
name: Firmware version
platform: template
entity_category: diagnostic
icon: mdi:tag-text-outline
internal: false
update_interval: never
lambda: |-
return {"${version}"};
- id: tx_device_name
name: Device Name
platform: template
icon: mdi:identifier
entity_category: diagnostic
internal: false
disabled_by_default: false
update_interval: never
lambda: |-
return {"${name}"};
filters:
- lambda: |-
const std::string raw_name = x;
std::string result;
bool last_was_underscore = false;
for (const char& c : raw_name) {
if (isalnum(c)) {
result += tolower(c); // Add alphanumeric characters as lowercase
last_was_underscore = false;
} else if (!last_was_underscore) { // Replace non-alphanumeric with '_' but avoid consecutive '_'
result += '_';
last_was_underscore = true;
}
}
return result;
time:
- id: time_source
platform: homeassistant
web_server:
wifi:
ap:
...

View File

@@ -19,6 +19,10 @@ substitutions:
BUTTON_2_ACTION_TEXT: "Relay 2 (toggle)"
BUTTON_3_ACTION_TEXT: "Relay 3 (toggle)"
BUTTON_4_ACTION_TEXT: "Relay 4 (toggle)"
BUTTON_1_ACTION_FAILSAFE_TEXT: "Relay 1 (API failsafe only)"
BUTTON_2_ACTION_FAILSAFE_TEXT: "Relay 2 (API failsafe only)"
BUTTON_3_ACTION_FAILSAFE_TEXT: "Relay 3 (API failsafe only)"
BUTTON_4_ACTION_FAILSAFE_TEXT: "Relay 4 (API failsafe only)"
BUTTON_CLICK_MIN_LENGTH: '50' # The minimum duration the click should last, in msec
BUTTON_CLICK_MAX_LENGTH: '350' # The maximum duration the click should last, in msec
@@ -53,6 +57,11 @@ binary_sensor:
internal: false
<<: *binary_sensor_button_base
esphome:
platformio_options:
build_flags:
- -D TX_ULTIMATE_EASY_CORE_HW_BUTTONS
globals:
- id: button_press_button
type: uint8_t
@@ -82,28 +91,19 @@ script:
- 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_1->set_internal(id(gang_count) < 1);
sl_button_1_action->set_internal(id(gang_count) < 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_2->set_internal(id(gang_count) < 2);
sl_button_2_action->set_internal(id(gang_count) < 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_3->set_internal(id(gang_count) < 3);
sl_button_3_action->set_internal(id(gang_count) < 3);
bs_button_4->publish_state(false);
bs_button_4->set_internal(num_gangs < 4);
sl_button_4_action->set_internal(num_gangs < 4);
bs_button_4->set_internal(id(gang_count) < 4);
sl_button_4_action->set_internal(id(gang_count) < 4);
- id: button_action
mode: parallel
@@ -205,6 +205,41 @@ script:
}
}
- id: !extend dump_config
then:
- lambda: |-
// Button's actions
ESP_LOGCONFIG("core_hw_buttons", "Button%s action%s:",
id(gang_count_plural_suffix).c_str(),
id(gang_count_plural_suffix).c_str());
ESP_LOGCONFIG("core_hw_buttons", " Relay 1: %s", sl_button_1_action->has_state()
? sl_button_1_action->state.c_str()
: "Unknown");
if (id(gang_count) >= 2)
ESP_LOGCONFIG("core_hw_buttons", " Relay 2: %s", sl_button_2_action->has_state()
? sl_button_2_action->state.c_str()
: "Unknown");
if (id(gang_count) >= 3)
ESP_LOGCONFIG("core_hw_buttons", " Relay 3: %s", sl_button_3_action->has_state()
? sl_button_3_action->state.c_str()
: "Unknown");
if (id(gang_count) >= 4)
ESP_LOGCONFIG("core_hw_buttons", " Relay 4: %s", sl_button_4_action->has_state()
? sl_button_4_action->state.c_str()
: "Unknown");
- id: !extend dump_config_list_packages
then:
- script.wait: dump_config
- lambda: |-
// Check for requirements
#if !defined(TX_ULTIMATE_EASY_CORE)
#error "The package TX-Ultimate-Easy-ESPHome_core.yaml is required."
#endif
// Identify itself
ESP_LOGCONFIG(ESPHOME_PROJECT_NAME, " - Core - Hardware - Buttons");
- id: !extend touch_on_multi_touch_release
then:
- script.execute: buttons_release
@@ -289,6 +324,7 @@ select:
options:
- "${BUTTON_ACTION_NONE_TEXT}"
- "${BUTTON_1_ACTION_TEXT}"
- "${BUTTON_1_ACTION_FAILSAFE_TEXT}"
initial_option: "${BUTTON_1_ACTION_TEXT}"
optimistic: true
restore_value: true
@@ -303,6 +339,7 @@ select:
options:
- "${BUTTON_ACTION_NONE_TEXT}"
- "${BUTTON_2_ACTION_TEXT}"
- "${BUTTON_2_ACTION_FAILSAFE_TEXT}"
initial_option: "${BUTTON_2_ACTION_TEXT}"
<<: *button_select_action_base
@@ -312,6 +349,7 @@ select:
options:
- "${BUTTON_ACTION_NONE_TEXT}"
- "${BUTTON_3_ACTION_TEXT}"
- "${BUTTON_3_ACTION_FAILSAFE_TEXT}"
initial_option: "${BUTTON_3_ACTION_TEXT}"
<<: *button_select_action_base
@@ -321,6 +359,7 @@ select:
options:
- "${BUTTON_ACTION_NONE_TEXT}"
- "${BUTTON_4_ACTION_TEXT}"
- "${BUTTON_4_ACTION_FAILSAFE_TEXT}"
initial_option: "${BUTTON_4_ACTION_TEXT}"
<<: *button_select_action_base
...

View File

@@ -28,7 +28,11 @@ substitutions:
LIGHT_FULL_RESTORE_MODE: RESTORE_DEFAULT_OFF
LIGHT_SIDES_RESTORE_MODE: RESTORE_DEFAULT_OFF
LIGHT_INDIVIDUAL_RESTORE_MODE: RESTORE_DEFAULT_OFF
LIGHT_RELAYS_RESTORE_MODE: RESTORE_DEFAULT_OFF
esphome:
platformio_options:
build_flags:
- -D TX_ULTIMATE_EASY_CORE_HW_LEDS
globals:
- id: gb_lights_1
@@ -43,13 +47,12 @@ light:
- id: light_full
name: Light - All
internal: true
platform: neopixelbus
type: GRB
variant: WS2811
# method: esp32_rmt
num_leds: 32
pin: GPIO13
restore_mode: ${LIGHT_FULL_RESTORE_MODE}
platform: neopixelbus
type: GRB
variant: WS2811
# Those lights are available based on the model selections
- &light_partition_with_effects
@@ -418,370 +421,77 @@ light:
from: 31
to: 31
# These lights are used to indicate relay's statuses
- &light_partition_relays
id: light_eu_rl_1_1_bottom
name: Light - Relay 1 of 1 (bottom)
platform: partition
internal: true
default_transition_length: ${default_transition_length}
restore_mode: ${LIGHT_RELAYS_RESTORE_MODE}
segments:
- id: light_full
from: 9
to: 9
- id: light_eu_rl_1_1_top
name: Light - Relay 1 of 1 (top)
<<: *light_partition_relays
segments:
- id: light_full
from: 23
to: 23
- id: light_eu_rl_1_2_bottom
name: Light - Relay 1 of 2 (bottom)
<<: *light_partition_relays
segments:
- id: light_full
from: 11
to: 11
- id: light_eu_rl_1_2_top
name: Light - Relay 1 of 2 (top)
<<: *light_partition_relays
segments:
- id: light_full
from: 21
to: 21
- id: light_eu_rl_2_2_bottom
name: Light - Relay 2 of 2 (bottom)
<<: *light_partition_relays
segments:
- id: light_full
from: 7
to: 7
- id: light_eu_rl_2_2_top
name: Light - Relay 2 of 2 (top)
<<: *light_partition_relays
segments:
- id: light_full
from: 25
to: 25
- id: light_eu_rl_1_3_bottom
name: Light - Relay 1 of 3 (bottom)
<<: *light_partition_relays
segments:
- id: light_full
from: 12
to: 12
- id: light_eu_rl_1_3_top
name: Light - Relay 1 of 3 (top)
<<: *light_partition_relays
segments:
- id: light_full
from: 20
to: 20
- id: light_eu_rl_2_3_bottom
name: Light - Relay 2 of 3 (bottom)
<<: *light_partition_relays
segments:
- id: light_full
from: 9
to: 9
- id: light_eu_rl_2_3_top
name: Light - Relay 2 of 3 (top)
<<: *light_partition_relays
segments:
- id: light_full
from: 23
to: 23
- id: light_eu_rl_3_3_bottom
name: Light - Relay 3 of 3 (bottom)
<<: *light_partition_relays
segments:
- id: light_full
from: 6
to: 6
- id: light_eu_rl_3_3_top
name: Light - Relay 3 of 3 (top)
<<: *light_partition_relays
segments:
- id: light_full
from: 26
to: 26
- id: light_eu_rl_1_4_bottom
name: Light - Relay 1 of 4 (bottom)
<<: *light_partition_relays
segments:
- id: light_full
from: 12
to: 12
- id: light_eu_rl_1_4_top
name: Light - Relay 1 of 4 (top)
<<: *light_partition_relays
segments:
- id: light_full
from: 20
to: 20
- id: light_eu_rl_2_4_bottom
name: Light - Relay 2 of 4 (bottom)
<<: *light_partition_relays
segments:
- id: light_full
from: 10
to: 10
- id: light_eu_rl_2_4_top
name: Light - Relay 2 of 4 (top)
<<: *light_partition_relays
segments:
- id: light_full
from: 22
to: 22
- id: light_eu_rl_3_4_bottom
name: Light - Relay 3 of 4 (bottom)
<<: *light_partition_relays
segments:
- id: light_full
from: 8
to: 8
- id: light_eu_rl_3_4_top
name: Light - Relay 3 of 4 (top)
<<: *light_partition_relays
segments:
- id: light_full
from: 24
to: 24
- id: light_eu_rl_4_4_bottom
name: Light - Relay 4 of 4 (bottom)
<<: *light_partition_relays
segments:
- id: light_full
from: 6
to: 6
- id: light_eu_rl_4_4_top
name: Light - Relay 4 of 4 (top)
<<: *light_partition_relays
segments:
- id: light_full
from: 26
to: 26
- id: light_us_rl_1_1_left
name: Light - Relay 1 of 1 (left)
<<: *light_partition_relays
segments:
- id: light_full
from: 15
to: 24
- id: light_us_rl_1_1_right
name: Light - Relay 1 of 1 (right)
<<: *light_partition_relays
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)
<<: *light_partition_relays
segments:
- id: light_full
from: 20
to: 24
- id: light_us_rl_1_2_right
name: Light - Relay 1 of 2 (right)
<<: *light_partition_relays
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)
<<: *light_partition_relays
segments:
- id: light_full
from: 15
to: 19
- id: light_us_rl_2_2_right
name: Light - Relay 2 of 2 (right)
<<: *light_partition_relays
segments:
- id: light_full
from: 4
to: 8
- id: light_us_rl_1_3_left
name: Light - Relay 1 of 3 (left)
<<: *light_partition_relays
segments:
- id: light_full
from: 22
to: 23
- id: light_us_rl_1_3_right
name: Light - Relay 1 of 3 (right)
<<: *light_partition_relays
segments:
- id: light_full
from: 0
to: 1
- id: light_us_rl_2_3_left
name: Light - Relay 2 of 3 (left)
<<: *light_partition_relays
segments:
- id: light_full
from: 19
to: 20
- id: light_us_rl_2_3_right
name: Light - Relay 2 of 3 (right)
<<: *light_partition_relays
segments:
- id: light_full
from: 3
to: 4
- id: light_us_rl_3_3_left
name: Light - Relay 3 of 3 (left)
<<: *light_partition_relays
segments:
- id: light_full
from: 17
to: 18
- id: light_us_rl_3_3_right
name: Light - Relay 3 of 3 (right)
<<: *light_partition_relays
segments:
- id: light_full
from: 6
to: 7
- id: light_us_rl_1_4_left
name: Light - Relay 1 of 4 (left)
<<: *light_partition_relays
segments:
- id: light_full
from: 12
to: 12
- id: light_us_rl_1_4_right
name: Light - Relay 1 of 4 (right)
<<: *light_partition_relays
segments:
- id: light_full
from: 31
to: 31
- id: light_us_rl_2_4_left
name: Light - Relay 2 of 4 (left)
<<: *light_partition_relays
segments:
- id: light_full
from: 24
to: 24
- id: light_us_rl_2_4_right
name: Light - Relay 2 of 4 (right)
<<: *light_partition_relays
segments:
- id: light_full
from: 2
to: 2
- id: light_us_rl_3_4_left
name: Light - Relay 3 of 4 (left)
<<: *light_partition_relays
segments:
- id: light_full
from: 21
to: 21
- id: light_us_rl_3_4_right
name: Light - Relay 3 of 4 (right)
<<: *light_partition_relays
segments:
- id: light_full
from: 4
to: 4
- id: light_us_rl_4_4_left
name: Light - Relay 4 of 4 (left)
<<: *light_partition_relays
segments:
- id: light_full
from: 19
to: 19
- id: light_us_rl_4_4_right
name: Light - Relay 4 of 4 (right)
<<: *light_partition_relays
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: // 4 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;
}
light_28->set_internal(!id(is_us_model));
light_29->set_internal(!id(is_us_model));
light_30->set_internal(!id(is_us_model));
light_31->set_internal(!id(is_us_model));
light_eu->set_internal(id(is_us_model));
light_eu_bottom->set_internal(id(is_us_model));
light_eu_left->set_internal(id(is_us_model));
light_eu_right->set_internal(id(is_us_model));
light_eu_top->set_internal(id(is_us_model));
light_us->set_internal(!id(is_us_model));
light_us_bottom->set_internal(!id(is_us_model));
light_us_left->set_internal(!id(is_us_model));
light_us_right->set_internal(!id(is_us_model));
light_us_top->set_internal(!id(is_us_model));
- id: !extend dump_config
then:
- lambda: |-
// Relay's LEDs modes
ESP_LOGCONFIG("core_hw_leds", "Relay%s LEDs mode%s:",
id(gang_count_plural_suffix).c_str(),
id(gang_count_plural_suffix).c_str());
ESP_LOGCONFIG("core_hw_leds", " Relay 1: %s", id(is_us_model)
? sl_relay_1_light_mode_us->state.c_str()
: sl_relay_1_light_mode_eu->state.c_str());
if (id(gang_count) >= 2)
ESP_LOGCONFIG("core_hw_leds", " Relay 2: %s", id(is_us_model)
? sl_relay_2_light_mode_us->state.c_str()
: sl_relay_2_light_mode_eu->state.c_str());
if (id(gang_count) >= 3)
ESP_LOGCONFIG("core_hw_leds", " Relay 3: %s", id(is_us_model)
? sl_relay_3_light_mode_us->state.c_str()
: sl_relay_3_light_mode_eu->state.c_str());
if (id(gang_count) >= 4)
ESP_LOGCONFIG("core_hw_leds", " Relay 4: %s", id(is_us_model)
? sl_relay_4_light_mode_us->state.c_str()
: sl_relay_4_light_mode_eu->state.c_str());
// Transition times
ESP_LOGCONFIG("core_hw_leds", "Transition times:");
ESP_LOGCONFIG("core_hw_leds", " Default: ${default_transition_length}");
if (${LIGHT_TRANSITION_TURN_ON} > 0)
ESP_LOGCONFIG("core_hw_leds", " Turning on: ${LIGHT_TRANSITION_TURN_ON}ms");
else
ESP_LOGCONFIG("core_hw_leds", " Turning on: Disabled");
if (${LIGHT_TRANSITION_TURN_OFF} > 0)
ESP_LOGCONFIG("core_hw_leds", " Turning off: ${LIGHT_TRANSITION_TURN_OFF}ms");
else
ESP_LOGCONFIG("core_hw_leds", " Turning off: Disabled");
// Restore modes
ESP_LOGCONFIG("core_hw_leds", "LED restore modes:");
ESP_LOGCONFIG("core_hw_leds", " Light - All: ${LIGHT_FULL_RESTORE_MODE}");
ESP_LOGCONFIG("core_hw_leds", " Sides: ${LIGHT_SIDES_RESTORE_MODE}");
ESP_LOGCONFIG("core_hw_leds", " Individual: ${LIGHT_INDIVIDUAL_RESTORE_MODE}");
- id: !extend dump_config_list_packages
then:
- script.wait: dump_config
- lambda: |-
// Check for requirements
#if !defined(TX_ULTIMATE_EASY_CORE)
#error "The package TX-Ultimate-Easy-ESPHome_core.yaml is required."
#endif
// Identify itself
ESP_LOGCONFIG(ESPHOME_PROJECT_NAME, " - Core - Hardware - LEDs");
- id: light_set_state
mode: parallel
@@ -795,10 +505,12 @@ script:
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}";
const std::string light_mode_group_1 = id(is_us_model)
? "${LIGHT_MODE_LEFT_TEXT}"
: "${LIGHT_MODE_BOTTOM_TEXT}";
const std::string light_mode_group_2 = id(is_us_model)
? "${LIGHT_MODE_RIGHT_TEXT}"
: "${LIGHT_MODE_TOP_TEXT}";
switch (light_group) {
case 1:
@@ -869,15 +581,12 @@ select:
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
@@ -899,15 +608,12 @@ select:
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

@@ -2,7 +2,7 @@
##### TX Ultimate Easy for ESPHome #####
##### Repository: https://github.com/edwardtfn/TX-Ultimate-Easy #####
####################################################################################################
##### Purpose: ESPHome Core - Hardware - Speaker #####
##### Purpose: ESPHome Core - Hardware - Media player #####
####################################################################################################
##### Author: edwardtfn - https://github.com/edwardtfn - https://buymeacoffee.com/edwardfirmo #####
####################################################################################################
@@ -17,13 +17,13 @@ i2s_audio:
i2s_lrclk_pin: GPIO4
media_player:
- id: mp_speaker
name: Speaker
- id: mp_media_player
name: Media Player
internal: false
platform: i2s_audio
i2s_dout_pin: GPIO15
i2s_audio_id: if_i2s_audio
i2s_comm_fmt: lsb
i2s_comm_fmt: msb # Experimental - It was 'lsb' until v2024.12.12
dac_type: external
mode: mono
internal: false
...

View File

@@ -1,441 +0,0 @@
####################################################################################################
##### 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. #####
####################################################################################################
---
substitutions:
RELAY_MODE_TEXT_SWITCH: "Switch"
RELAY_MODE_TEXT_LIGHT: "Light"
RELAY_MODE_TEXT_NOT_USED: "Not in use"
RELAY_RESTORE_MODE: RESTORE_DEFAULT_OFF
globals:
- id: boot_initialization_relays
type: bool
restore_value: false
initial_value: 'false'
light:
# These lights are used for the physical relays to be shown as lights
- id: light_output_1
name: Light output 1
output: output_relay_1
platform: binary
internal: true
restore_mode: ${RELAY_RESTORE_MODE}
on_turn_on:
then:
- if:
condition:
- switch.is_off: sw_relay_1
then:
- switch.turn_on: sw_relay_1
on_turn_off:
then:
- if:
condition:
- switch.is_on: sw_relay_1
then:
- switch.turn_off: sw_relay_1
- id: light_output_2
name: Light output 2
output: output_relay_2
platform: binary
internal: true
on_turn_on:
then:
- if:
condition:
- switch.is_off: sw_relay_2
then:
- switch.turn_on: sw_relay_2
on_turn_off:
then:
- if:
condition:
- switch.is_on: sw_relay_2
then:
- switch.turn_off: sw_relay_2
- id: light_output_3
name: Light output 3
output: output_relay_3
platform: binary
internal: true
on_turn_on:
then:
- if:
condition:
- switch.is_off: sw_relay_3
then:
- switch.turn_on: sw_relay_3
on_turn_off:
then:
- if:
condition:
- switch.is_on: sw_relay_3
then:
- switch.turn_off: sw_relay_3
- id: light_output_4
name: Light output 4
output: output_relay_4
platform: binary
internal: true
on_turn_on:
then:
- if:
condition:
- switch.is_off: sw_relay_4
then:
- switch.turn_on: sw_relay_4
on_turn_off:
then:
- if:
condition:
- switch.is_on: sw_relay_4
then:
- switch.turn_off: sw_relay_4
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: !extend button_click_event
then:
- lambda: |-
// Handle only single clicks
if (click_count != 1)
return;
// Ignore if other touch events are active
if (bs_multi_touch->state ||
bs_swipe_left->state ||
bs_swipe_down->state ||
bs_swipe_right->state) {
return;
}
// Toggle relay if corresponding button action is enabled
ESP_LOGVV("core_hw_relays", "Toggle relays: (${BUTTON_ACTION_NONE_TEXT})");
ESP_LOGVV("core_hw_relays", " Relay 1: %s (%s)",
YESNO(sl_button_1_action->state != "${BUTTON_ACTION_NONE_TEXT}"),
sl_button_1_action->state.c_str());
ESP_LOGVV("core_hw_relays", " Relay 2: %s (%s)",
YESNO(sl_button_2_action->state != "${BUTTON_ACTION_NONE_TEXT}"),
sl_button_2_action->state.c_str());
ESP_LOGVV("core_hw_relays", " Relay 3: %s (%s)",
YESNO(sl_button_3_action->state != "${BUTTON_ACTION_NONE_TEXT}"),
sl_button_3_action->state.c_str());
ESP_LOGVV("core_hw_relays", " Relay 4: %s (%s)",
YESNO(sl_button_4_action->state != "${BUTTON_ACTION_NONE_TEXT}"),
sl_button_4_action->state.c_str());
switch (button) {
case ${BUTTON_1_ID}:
if (sl_button_1_action->state != "${BUTTON_ACTION_NONE_TEXT}") {
ESP_LOGV("core_hw_relays", "Toggle relay 1: (%s)", sl_button_1_action->state.c_str());
sw_relay_1->toggle();
} else {
ESP_LOGV("core_hw_relays", "Ignoring toggle for relay 1: action is '%s'",
sl_button_1_action->state.c_str());
}
break;
case ${BUTTON_2_ID}:
if (sl_button_2_action->state != "${BUTTON_ACTION_NONE_TEXT}") {
ESP_LOGV("core_hw_relays", "Toggle relay 2: (%s)", sl_button_2_action->state.c_str());
sw_relay_2->toggle();
} else {
ESP_LOGV("core_hw_relays", "Ignoring toggle for relay 2: action is '%s'",
sl_button_2_action->state.c_str());
}
break;
case ${BUTTON_3_ID}:
if (sl_button_3_action->state != "${BUTTON_ACTION_NONE_TEXT}") {
ESP_LOGV("core_hw_relays", "Toggle relay 3: (%s)", sl_button_3_action->state.c_str());
sw_relay_3->toggle();
} else {
ESP_LOGV("core_hw_relays", "Ignoring toggle for relay 3: action is '%s'",
sl_button_3_action->state.c_str());
}
break;
case ${BUTTON_4_ID}:
if (sl_button_4_action->state != "${BUTTON_ACTION_NONE_TEXT}") {
ESP_LOGV("core_hw_relays", "Toggle relay 4: (%s)", sl_button_4_action->state.c_str());
sw_relay_4->toggle();
} else {
ESP_LOGV("core_hw_relays", "Ignoring toggle for relay 4: action is '%s'",
sl_button_4_action->state.c_str());
}
break;
}
- 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 display mode
platform: template
options:
- "${RELAY_MODE_TEXT_SWITCH}"
- "${RELAY_MODE_TEXT_LIGHT}"
- "${RELAY_MODE_TEXT_NOT_USED}"
initial_option: "${RELAY_MODE_TEXT_SWITCH}"
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 display mode
<<: *relay_select_mode_base
- id: sl_relay_3_mode
name: Relay 3 display mode
<<: *relay_select_mode_base
- id: sl_relay_4_mode
name: Relay 4 display mode
<<: *relay_select_mode_base
switch:
- id: sw_relay_1
name: Relay 1
output: output_relay_1
platform: output
restore_mode: ${RELAY_RESTORE_MODE}
internal: true
on_turn_on:
then:
- script.execute: show_relay_status
- if:
condition:
- light.is_off: light_output_1
then:
light.turn_on: light_output_1
on_turn_off:
then:
- script.execute: show_relay_status
- if:
condition:
- light.is_on: light_output_1
then:
- light.turn_off: light_output_1
- id: sw_relay_2
name: Relay 2
output: output_relay_2
platform: output
restore_mode: ${RELAY_RESTORE_MODE}
internal: true
on_turn_on:
then:
- script.execute: show_relay_status
- if:
condition:
- light.is_off: light_output_2
then:
light.turn_on: light_output_2
on_turn_off:
then:
- script.execute: show_relay_status
- if:
condition:
- light.is_on: light_output_2
then:
- light.turn_off: light_output_2
- id: sw_relay_3
name: Relay 3
output: output_relay_3
platform: output
restore_mode: ${RELAY_RESTORE_MODE}
internal: true
on_turn_on:
then:
- script.execute: show_relay_status
- if:
condition:
- light.is_off: light_output_3
then:
- light.turn_on: light_output_3
on_turn_off:
then:
- script.execute: show_relay_status
- if:
condition:
- light.is_on: light_output_3
then:
- light.turn_off: light_output_3
- id: sw_relay_4
name: Relay 4
output: output_relay_4
platform: output
restore_mode: ${RELAY_RESTORE_MODE}
internal: true
on_turn_on:
then:
- script.execute: show_relay_status
- if:
condition:
- light.is_off: light_output_4
then:
- light.turn_on: light_output_4
on_turn_off:
then:
- script.execute: show_relay_status
- if:
condition:
- light.is_on: light_output_4
then:
- light.turn_off: light_output_4
...

View File

@@ -198,6 +198,11 @@ binary_sensor:
id: bs_swipe_down
state: OFF # yamllint disable-line rule:truthy
esphome:
platformio_options:
build_flags:
- -D TX_ULTIMATE_EASY_CORE_HW_TOUCH
external_components:
- source:
type: git
@@ -256,13 +261,8 @@ script:
- id: boot_initialize_touch_gang
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;
tx_ultimate->set_gang_count(num_gangs);
tx_ultimate->set_gang_count(id(gang_count));
bs_button_1_click_event->publish_state(false);
bs_button_2_click_event->publish_state(false);
bs_button_3_click_event->publish_state(false);
@@ -275,18 +275,40 @@ script:
bs_button_2_long_press_event->publish_state(false);
bs_button_3_long_press_event->publish_state(false);
bs_button_4_long_press_event->publish_state(false);
bs_button_1_click_event->set_internal(num_gangs < 1);
bs_button_2_click_event->set_internal(num_gangs < 2);
bs_button_3_click_event->set_internal(num_gangs < 3);
bs_button_4_click_event->set_internal(num_gangs < 4);
bs_button_1_double_click_event->set_internal(num_gangs < 1);
bs_button_2_double_click_event->set_internal(num_gangs < 2);
bs_button_3_double_click_event->set_internal(num_gangs < 3);
bs_button_4_double_click_event->set_internal(num_gangs < 4);
bs_button_1_long_press_event->set_internal(num_gangs < 1);
bs_button_2_long_press_event->set_internal(num_gangs < 2);
bs_button_3_long_press_event->set_internal(num_gangs < 3);
bs_button_4_long_press_event->set_internal(num_gangs < 4);
bs_button_1_click_event->set_internal(id(gang_count) < 1);
bs_button_2_click_event->set_internal(id(gang_count) < 2);
bs_button_3_click_event->set_internal(id(gang_count) < 3);
bs_button_4_click_event->set_internal(id(gang_count) < 4);
bs_button_1_double_click_event->set_internal(id(gang_count) < 1);
bs_button_2_double_click_event->set_internal(id(gang_count) < 2);
bs_button_3_double_click_event->set_internal(id(gang_count) < 3);
bs_button_4_double_click_event->set_internal(id(gang_count) < 4);
bs_button_1_long_press_event->set_internal(id(gang_count) < 1);
bs_button_2_long_press_event->set_internal(id(gang_count) < 2);
bs_button_3_long_press_event->set_internal(id(gang_count) < 3);
bs_button_4_long_press_event->set_internal(id(gang_count) < 4);
- id: !extend dump_config
then:
- lambda: |-
// Touch panel's state
if (sw_touch_panel_power->state)
ESP_LOGCONFIG("core_hw_touch", "Touch panel - Power: On");
else
ESP_LOGW("core_hw_touch", "Touch panel - Power: OFF");
ESP_LOGCONFIG("core_hw_touch", "Touch event duration: %.0fms", nr_touch_duration->state);
- id: !extend dump_config_list_packages
then:
- script.wait: dump_config
- lambda: |-
// Check for requirements
#if !defined(TX_ULTIMATE_EASY_CORE)
#error "The package TX-Ultimate-Easy-ESPHome_core.yaml is required."
#endif
// Identify itself
ESP_LOGCONFIG(ESPHOME_PROJECT_NAME, " - Core - Hardware - Touchpad");
- id: touch_on_multi_touch_release
mode: restart
@@ -296,7 +318,7 @@ script:
# - HW Vibration
- binary_sensor.template.publish:
id: bs_multi_touch
state: OFF # yamllint disable-line rule:truthy
state: ON # yamllint disable-line rule:truthy
- id: touch_on_press
mode: restart
@@ -358,9 +380,9 @@ tx_ultimate_easy:
- lambda: |-
const uint8_t touch_position = static_cast<uint8_t>(touch.x);
if (touch_position > ${TOUCH_POSITION_MAX_VALUE}) { // Check for valid range
ESP_LOGE("tx_ultimate_easy", "Invalid long-touch position: %" PRIu8, touch_position);
ESP_LOGE("core_hw_touch", "Invalid long-touch position: %" PRIu8, touch_position);
} else {
ESP_LOGI("tx_ultimate_easy", "Long-touch released at position %" PRIu8, touch_position);
ESP_LOGI("core_hw_touch", "Long-touch released at position %" PRIu8, touch_position);
}
on_multi_touch_release:
@@ -373,21 +395,21 @@ tx_ultimate_easy:
type: multi_touch
action: release
position: !lambda return touch.x;
- lambda: ESP_LOGI("tx_ultimate_easy", "Multi-touch released");
- lambda: ESP_LOGI("core_hw_touch", "Multi-touch released");
- script.execute: touch_on_multi_touch_release
on_press:
- lambda: |-
const uint8_t position = static_cast<uint8_t>(touch.x);
if (position > ${TOUCH_POSITION_MAX_VALUE}) { // Check for valid range
ESP_LOGE("tx_ultimate_easy", "Invalid touch position: %" PRIu8, position);
ESP_LOGE("core_hw_touch", "Invalid touch position: %" PRIu8, position);
} else {
ESP_LOGI("tx_ultimate_easy", "Pressed at position %" PRIu8, position);
ESP_LOGI("core_hw_touch", "Pressed at position %" PRIu8, position);
touch_on_press->execute(static_cast<uint8_t>(touch.button), position);
}
on_release:
- lambda: ESP_LOGI("tx_ultimate_easy", "Released");
- lambda: ESP_LOGI("core_hw_touch", "Released");
- script.execute: touch_on_release
on_swipe_left:
@@ -399,12 +421,12 @@ tx_ultimate_easy:
domain: touch
type: swipe
action: !lambda |-
return sl_tx_model_format->state == "${TX_MODEL_FORMAT_US_TEXT}" ? "left" : "down";
return sl_tx_model_format->state == "${TX_MODEL_FORMAT_EU_TEXT}" ? "left" : "down";
swipe-direction: !lambda |-
return sl_tx_model_format->state == "${TX_MODEL_FORMAT_US_TEXT}" ? "left" : "down";
return sl_tx_model_format->state == "${TX_MODEL_FORMAT_EU_TEXT}" ? "left" : "down";
position: !lambda return touch.x;
- lambda: |-
ESP_LOGI("tx_ultimate_easy", "Swipe %s", sl_tx_model_format->state == "${TX_MODEL_FORMAT_US_TEXT}"
ESP_LOGI("core_hw_touch", "Swipe %s", sl_tx_model_format->state == "${TX_MODEL_FORMAT_EU_TEXT}"
? "left"
: "down");
- script.execute: touch_swipe_left
@@ -418,21 +440,21 @@ tx_ultimate_easy:
domain: touch
type: swipe
action: !lambda |-
return sl_tx_model_format->state == "${TX_MODEL_FORMAT_US_TEXT}" ? "right" : "up";
return sl_tx_model_format->state == "${TX_MODEL_FORMAT_EU_TEXT}" ? "right" : "up";
swipe-direction: !lambda |-
return sl_tx_model_format->state == "${TX_MODEL_FORMAT_US_TEXT}" ? "right" : "up";
return sl_tx_model_format->state == "${TX_MODEL_FORMAT_EU_TEXT}" ? "right" : "up";
position: !lambda return touch.x;
- lambda: |-
ESP_LOGI("tx_ultimate_easy", "Swipe %s", sl_tx_model_format->state == "${TX_MODEL_FORMAT_US_TEXT}"
ESP_LOGI("core_hw_touch", "Swipe %s", sl_tx_model_format->state == "${TX_MODEL_FORMAT_EU_TEXT}"
? "right"
: "up");
- 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);
ESP_LOGD("core_hw_touch", "Touch event:");
ESP_LOGD("core_hw_touch", " State: %i (%s)", touch.state, touch.state_str.c_str());
ESP_LOGD("core_hw_touch", " Position: %i", touch.x);
uart:
- id: uart_touch

View File

@@ -1,137 +0,0 @@
####################################################################################################
##### 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
...