646 lines
19 KiB
YAML
646 lines
19 KiB
YAML
####################################################################################################
|
|
##### 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)
|
|
|
|
LIGHT_FULL_RESTORE_MODE: RESTORE_DEFAULT_OFF
|
|
LIGHT_SIDES_RESTORE_MODE: RESTORE_DEFAULT_OFF
|
|
LIGHT_INDIVIDUAL_RESTORE_MODE: RESTORE_DEFAULT_OFF
|
|
|
|
LIGHT_ATTRS_DEFAULT: '0x64FFFFFF' # brightness=100, RGB=255,255,255
|
|
LIGHT_DUAL_ATTRS_DEFAULT: '0x64FFFFFF64FFFFFF' # Both lights: brightness=100, RGB=255,255,255
|
|
|
|
TAG_CORE_HW_LEDS: core.hw.leds
|
|
|
|
esphome:
|
|
platformio_options:
|
|
build_flags:
|
|
- -D TX_ULTIMATE_EASY_CORE_HW_LEDS
|
|
|
|
light:
|
|
# These lights are controlling the LEDs on the device
|
|
- id: light_full
|
|
name: Light - All
|
|
internal: true
|
|
num_leds: 32
|
|
pin: GPIO13
|
|
restore_mode: ${LIGHT_FULL_RESTORE_MODE}
|
|
platform: esp32_rmt_led_strip
|
|
rgb_order: GRB
|
|
chipset: ws2812
|
|
max_refresh_rate: 33ms
|
|
use_psram: false
|
|
# platform: neopixelbus
|
|
# type: GRB
|
|
# variant: WS2811
|
|
|
|
# Those lights are available based on the model selections
|
|
- &light_partition_with_effects_eu
|
|
id: light_eu
|
|
name: Light EU
|
|
platform: partition
|
|
default_transition_length: ${default_transition_length}
|
|
internal: true
|
|
restore_mode: ${LIGHT_SIDES_RESTORE_MODE}
|
|
effects:
|
|
- addressable_rainbow:
|
|
name: "Rainbow"
|
|
width: 28
|
|
- addressable_rainbow:
|
|
name: "Rainbow - Fast"
|
|
width: 28
|
|
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"
|
|
segments:
|
|
- id: light_full
|
|
from: 0
|
|
to: 27
|
|
|
|
- &light_partition_with_effects_us
|
|
id: light_us
|
|
name: Light US
|
|
platform: partition
|
|
default_transition_length: ${default_transition_length}
|
|
internal: true
|
|
restore_mode: ${LIGHT_SIDES_RESTORE_MODE}
|
|
effects:
|
|
- addressable_rainbow:
|
|
name: "Rainbow"
|
|
width: 32
|
|
- addressable_rainbow:
|
|
name: "Rainbow - Fast"
|
|
width: 32
|
|
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"
|
|
segments:
|
|
- id: light_full
|
|
from: 0
|
|
to: 31
|
|
|
|
- &light_partition_no_effects_disabled
|
|
id: light_eu_bottom
|
|
name: Light - Bottom EU
|
|
platform: partition
|
|
disabled_by_default: true
|
|
default_transition_length: ${default_transition_length}
|
|
restore_mode: ${LIGHT_SIDES_RESTORE_MODE}
|
|
internal: true
|
|
segments:
|
|
- id: light_full
|
|
from: 6
|
|
to: 12
|
|
reversed: true
|
|
- id: light_eu_left
|
|
name: Light - Left EU
|
|
<<: *light_partition_no_effects_disabled
|
|
segments:
|
|
- id: light_full
|
|
from: 13
|
|
to: 19
|
|
reversed: true
|
|
- id: light_eu_right
|
|
name: Light - Right EU
|
|
<<: *light_partition_no_effects_disabled
|
|
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 EU
|
|
<<: *light_partition_no_effects_disabled
|
|
segments:
|
|
- id: light_full
|
|
from: 20
|
|
to: 26
|
|
reversed: false
|
|
- id: light_us_bottom
|
|
name: Light - Bottom US
|
|
<<: *light_partition_no_effects_disabled
|
|
segments:
|
|
- id: light_full
|
|
from: 9
|
|
to: 14
|
|
reversed: true
|
|
- id: light_us_left
|
|
name: Light - Left US
|
|
<<: *light_partition_no_effects_disabled
|
|
segments:
|
|
- id: light_full
|
|
from: 15
|
|
to: 24
|
|
reversed: true
|
|
- id: light_us_right
|
|
name: Light - Right US
|
|
<<: *light_partition_no_effects_disabled
|
|
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 US
|
|
<<: *light_partition_no_effects_disabled
|
|
segments:
|
|
- id: light_full
|
|
from: 25
|
|
to: 30
|
|
reversed: false
|
|
|
|
- &light_partition_individual_led
|
|
id: light_00
|
|
name: Light - LED 00
|
|
platform: partition
|
|
disabled_by_default: true
|
|
default_transition_length: ${default_transition_length}
|
|
restore_mode: ${LIGHT_INDIVIDUAL_RESTORE_MODE}
|
|
segments:
|
|
- id: light_full
|
|
from: 0
|
|
to: 0
|
|
- id: light_01
|
|
name: Light - LED 01
|
|
<<: *light_partition_individual_led
|
|
segments:
|
|
- id: light_full
|
|
from: 1
|
|
to: 1
|
|
- id: light_02
|
|
name: Light - LED 02
|
|
<<: *light_partition_individual_led
|
|
segments:
|
|
- id: light_full
|
|
from: 2
|
|
to: 2
|
|
- id: light_03
|
|
name: Light - LED 03
|
|
<<: *light_partition_individual_led
|
|
segments:
|
|
- id: light_full
|
|
from: 3
|
|
to: 3
|
|
- id: light_04
|
|
name: Light - LED 04
|
|
<<: *light_partition_individual_led
|
|
segments:
|
|
- id: light_full
|
|
from: 4
|
|
to: 4
|
|
- id: light_05
|
|
name: Light - LED 05
|
|
<<: *light_partition_individual_led
|
|
segments:
|
|
- id: light_full
|
|
from: 5
|
|
to: 5
|
|
- id: light_06
|
|
name: Light - LED 06
|
|
<<: *light_partition_individual_led
|
|
segments:
|
|
- id: light_full
|
|
from: 6
|
|
to: 6
|
|
- id: light_07
|
|
name: Light - LED 07
|
|
<<: *light_partition_individual_led
|
|
segments:
|
|
- id: light_full
|
|
from: 7
|
|
to: 7
|
|
- id: light_08
|
|
name: Light - LED 08
|
|
<<: *light_partition_individual_led
|
|
segments:
|
|
- id: light_full
|
|
from: 8
|
|
to: 8
|
|
- id: light_09
|
|
name: Light - LED 09
|
|
<<: *light_partition_individual_led
|
|
segments:
|
|
- id: light_full
|
|
from: 9
|
|
to: 9
|
|
- id: light_10
|
|
name: Light - LED 10
|
|
<<: *light_partition_individual_led
|
|
segments:
|
|
- id: light_full
|
|
from: 10
|
|
to: 10
|
|
- id: light_11
|
|
name: Light - LED 11
|
|
<<: *light_partition_individual_led
|
|
segments:
|
|
- id: light_full
|
|
from: 11
|
|
to: 11
|
|
- id: light_12
|
|
name: Light - LED 12
|
|
<<: *light_partition_individual_led
|
|
segments:
|
|
- id: light_full
|
|
from: 12
|
|
to: 12
|
|
- id: light_13
|
|
name: Light - LED 13
|
|
<<: *light_partition_individual_led
|
|
segments:
|
|
- id: light_full
|
|
from: 13
|
|
to: 13
|
|
- id: light_14
|
|
name: Light - LED 14
|
|
<<: *light_partition_individual_led
|
|
segments:
|
|
- id: light_full
|
|
from: 14
|
|
to: 14
|
|
- id: light_15
|
|
name: Light - LED 15
|
|
<<: *light_partition_individual_led
|
|
segments:
|
|
- id: light_full
|
|
from: 15
|
|
to: 15
|
|
- id: light_16
|
|
name: Light - LED 16
|
|
<<: *light_partition_individual_led
|
|
segments:
|
|
- id: light_full
|
|
from: 16
|
|
to: 16
|
|
- id: light_17
|
|
name: Light - LED 17
|
|
<<: *light_partition_individual_led
|
|
segments:
|
|
- id: light_full
|
|
from: 17
|
|
to: 17
|
|
- id: light_18
|
|
name: Light - LED 18
|
|
<<: *light_partition_individual_led
|
|
segments:
|
|
- id: light_full
|
|
from: 18
|
|
to: 18
|
|
- id: light_19
|
|
name: Light - LED 19
|
|
<<: *light_partition_individual_led
|
|
segments:
|
|
- id: light_full
|
|
from: 19
|
|
to: 19
|
|
- id: light_20
|
|
name: Light - LED 20
|
|
<<: *light_partition_individual_led
|
|
segments:
|
|
- id: light_full
|
|
from: 20
|
|
to: 20
|
|
- id: light_21
|
|
name: Light - LED 21
|
|
<<: *light_partition_individual_led
|
|
segments:
|
|
- id: light_full
|
|
from: 21
|
|
to: 21
|
|
- id: light_22
|
|
name: Light - LED 22
|
|
<<: *light_partition_individual_led
|
|
segments:
|
|
- id: light_full
|
|
from: 22
|
|
to: 22
|
|
- id: light_23
|
|
name: Light - LED 23
|
|
<<: *light_partition_individual_led
|
|
segments:
|
|
- id: light_full
|
|
from: 23
|
|
to: 23
|
|
- id: light_24
|
|
name: Light - LED 24
|
|
<<: *light_partition_individual_led
|
|
segments:
|
|
- id: light_full
|
|
from: 24
|
|
to: 24
|
|
- id: light_25
|
|
name: Light - LED 25
|
|
<<: *light_partition_individual_led
|
|
segments:
|
|
- id: light_full
|
|
from: 25
|
|
to: 25
|
|
- id: light_26
|
|
name: Light - LED 26
|
|
<<: *light_partition_individual_led
|
|
segments:
|
|
- id: light_full
|
|
from: 26
|
|
to: 26
|
|
- id: light_27
|
|
name: Light - LED 27
|
|
<<: *light_partition_individual_led
|
|
segments:
|
|
- id: light_full
|
|
from: 27
|
|
to: 27
|
|
- id: light_28 # US Model only
|
|
name: Light - LED 28
|
|
internal: true
|
|
<<: *light_partition_individual_led
|
|
segments:
|
|
- id: light_full
|
|
from: 28
|
|
to: 28
|
|
- id: light_29 # US Model only
|
|
name: Light - LED 29
|
|
internal: true
|
|
<<: *light_partition_individual_led
|
|
segments:
|
|
- id: light_full
|
|
from: 29
|
|
to: 29
|
|
- id: light_30 # US Model only
|
|
name: Light - LED 30
|
|
internal: true
|
|
<<: *light_partition_individual_led
|
|
segments:
|
|
- id: light_full
|
|
from: 30
|
|
to: 30
|
|
- id: light_31 # US Model only
|
|
name: Light - LED 31
|
|
internal: true
|
|
<<: *light_partition_individual_led
|
|
segments:
|
|
- id: light_full
|
|
from: 31
|
|
to: 31
|
|
|
|
script:
|
|
- id: !extend boot_initialize
|
|
then:
|
|
- lambda: |-
|
|
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: |-
|
|
// Transition times
|
|
ESP_LOGCONFIG("${TAG_CORE_HW_LEDS}", "Transition times:");
|
|
ESP_LOGCONFIG("${TAG_CORE_HW_LEDS}", " Default: ${default_transition_length}");
|
|
if (${LIGHT_TRANSITION_TURN_ON} > 0)
|
|
ESP_LOGCONFIG("${TAG_CORE_HW_LEDS}", " Turning on: ${LIGHT_TRANSITION_TURN_ON}ms");
|
|
else
|
|
ESP_LOGCONFIG("${TAG_CORE_HW_LEDS}", " Turning on: Disabled");
|
|
if (${LIGHT_TRANSITION_TURN_OFF} > 0)
|
|
ESP_LOGCONFIG("${TAG_CORE_HW_LEDS}", " Turning off: ${LIGHT_TRANSITION_TURN_OFF}ms");
|
|
else
|
|
ESP_LOGCONFIG("${TAG_CORE_HW_LEDS}", " Turning off: Disabled");
|
|
|
|
// Restore modes
|
|
ESP_LOGCONFIG("${TAG_CORE_HW_LEDS}", "LED restore modes:");
|
|
ESP_LOGCONFIG("${TAG_CORE_HW_LEDS}", " Light - All: ${LIGHT_FULL_RESTORE_MODE}");
|
|
ESP_LOGCONFIG("${TAG_CORE_HW_LEDS}", " Sides: ${LIGHT_SIDES_RESTORE_MODE}");
|
|
ESP_LOGCONFIG("${TAG_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_COMMON)
|
|
#error "The package TX-Ultimate-Easy-ESPHome_core_common.yaml is required."
|
|
#endif
|
|
|
|
// Identify itself
|
|
ESP_LOGCONFIG(ESPHOME_PROJECT_NAME, " - Core - Hardware - LEDs");
|
|
|
|
- id: light_attributes_restore
|
|
mode: parallel
|
|
parameters:
|
|
light_ptr: light::LightState*
|
|
attr_global_ptr: uint32_t*
|
|
then:
|
|
- lambda: |-
|
|
if (!light_ptr) {
|
|
ESP_LOGE("${TAG_CORE_HW_LEDS}", "Invalid light pointer");
|
|
return;
|
|
}
|
|
if (!attr_global_ptr) {
|
|
ESP_LOGE("${TAG_CORE_HW_LEDS}", "Invalid attributes pointer");
|
|
return;
|
|
}
|
|
tx_ultimate_easy::LightAttributes attrs = tx_ultimate_easy::unpack_light_attributes(*attr_global_ptr);
|
|
auto call = light_ptr->make_call();
|
|
call.set_brightness(attrs.brightness / 100.0f);
|
|
call.set_rgb(attrs.red / 255.0f, attrs.green / 255.0f, attrs.blue / 255.0f);
|
|
call.perform();
|
|
ESP_LOGI("${TAG_CORE_HW_LEDS}", "Restored light attributes: brightness=%d%%, RGB=(%d,%d,%d)",
|
|
attrs.brightness, attrs.red, attrs.green, attrs.blue);
|
|
|
|
- id: light_attributes_restore_dual
|
|
mode: parallel
|
|
parameters:
|
|
light_ptr: light::LightState*
|
|
attr_global_ptr: uint64_t*
|
|
group_index: uint8_t # 1 or 2
|
|
then:
|
|
- lambda: |-
|
|
if (!light_ptr) {
|
|
ESP_LOGE("${TAG_CORE_HW_LEDS}", "Invalid light pointer");
|
|
return;
|
|
}
|
|
if (!attr_global_ptr) {
|
|
ESP_LOGE("${TAG_CORE_HW_LEDS}", "Invalid attributes pointer");
|
|
return;
|
|
}
|
|
if (group_index != 1 && group_index != 2) {
|
|
ESP_LOGE("${TAG_CORE_HW_LEDS}", "Invalid group_index=%d (expected 1 or 2)", group_index);
|
|
return;
|
|
}
|
|
auto attrs_pair = tx_ultimate_easy::unpack_dual_light_attributes(*attr_global_ptr);
|
|
tx_ultimate_easy::LightAttributes attrs = (group_index == 1) ? attrs_pair.first : attrs_pair.second;
|
|
|
|
auto call = light_ptr->make_call();
|
|
call.set_brightness(attrs.brightness / 100.0f);
|
|
call.set_rgb(attrs.red / 255.0f, attrs.green / 255.0f, attrs.blue / 255.0f);
|
|
call.perform();
|
|
ESP_LOGI("${TAG_CORE_HW_LEDS}", "Restored (group=%d) attributes: brightness=%d%%, RGB=(%d,%d,%d)",
|
|
group_index, attrs.brightness, attrs.red, attrs.green, attrs.blue);
|
|
|
|
- id: light_attributes_save
|
|
mode: parallel
|
|
parameters:
|
|
light_ptr: light::LightState*
|
|
attr_global_ptr: uint32_t*
|
|
then:
|
|
- lambda: |-
|
|
if (!light_ptr) {
|
|
ESP_LOGE("${TAG_CORE_HW_LEDS}", "Invalid light pointer");
|
|
return;
|
|
}
|
|
if (!attr_global_ptr) {
|
|
ESP_LOGE("${TAG_CORE_HW_LEDS}", "Invalid attributes pointer");
|
|
return;
|
|
}
|
|
auto current = light_ptr->current_values;
|
|
tx_ultimate_easy::LightAttributes attrs = {
|
|
.brightness = uint8_t(current.get_brightness() * 100.0f),
|
|
.red = uint8_t(current.get_red() * 255.0f),
|
|
.green = uint8_t(current.get_green() * 255.0f),
|
|
.blue = uint8_t(current.get_blue() * 255.0f)
|
|
};
|
|
|
|
*attr_global_ptr = tx_ultimate_easy::pack_light_attributes(attrs);
|
|
ESP_LOGD("${TAG_CORE_HW_LEDS}", "Saved light attributes: brightness=%d%%, RGB=(%d,%d,%d)",
|
|
attrs.brightness, attrs.red, attrs.green, attrs.blue);
|
|
|
|
- id: light_attributes_save_dual
|
|
mode: queued # To prevent two instances trying to change the same global
|
|
parameters:
|
|
light_ptr: light::LightState*
|
|
attr_global_ptr: uint64_t*
|
|
group_index: uint8_t # 1 or 2 (which group within the dual pack)
|
|
then:
|
|
- lambda: |-
|
|
if (!light_ptr) {
|
|
ESP_LOGE("${TAG_CORE_HW_LEDS}", "Invalid light pointer");
|
|
return;
|
|
}
|
|
if (!attr_global_ptr) {
|
|
ESP_LOGE("${TAG_CORE_HW_LEDS}", "Invalid attributes pointer");
|
|
return;
|
|
}
|
|
if (group_index != 1 && group_index != 2) {
|
|
ESP_LOGE("${TAG_CORE_HW_LEDS}", "Invalid group_index=%d (expected 1 or 2)", group_index);
|
|
return;
|
|
}
|
|
auto current = light_ptr->current_values;
|
|
tx_ultimate_easy::LightAttributes new_attrs = {
|
|
.brightness = uint8_t(current.get_brightness() * 100.0f),
|
|
.red = uint8_t(current.get_red() * 255.0f),
|
|
.green = uint8_t(current.get_green() * 255.0f),
|
|
.blue = uint8_t(current.get_blue() * 255.0f)
|
|
};
|
|
|
|
// Unpack existing dual attributes
|
|
auto existing = tx_ultimate_easy::unpack_dual_light_attributes(*attr_global_ptr);
|
|
|
|
// Update the appropriate group
|
|
if (group_index == 1) {
|
|
*attr_global_ptr = tx_ultimate_easy::pack_dual_light_attributes(new_attrs, existing.second);
|
|
} else {
|
|
*attr_global_ptr = tx_ultimate_easy::pack_dual_light_attributes(existing.first, new_attrs);
|
|
}
|
|
|
|
...
|