diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_leds.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_leds.yaml index 08197a7..a4567d2 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_leds.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_leds.yaml @@ -29,6 +29,8 @@ substitutions: LIGHT_SIDES_RESTORE_MODE: RESTORE_DEFAULT_OFF LIGHT_INDIVIDUAL_RESTORE_MODE: RESTORE_DEFAULT_OFF + LIGHT_ATTRS_DEFAULT: '0x64FFFFFF' # brightness=100, RGB=255,255,255 + TAG_CORE_HW_LEDS: core.hw.leds esphome: @@ -36,14 +38,6 @@ esphome: build_flags: - -D TX_ULTIMATE_EASY_CORE_HW_LEDS -globals: - - id: gb_lights_1 - type: std::vector - restore_value: false - - id: gb_lights_2 - type: std::vector - restore_value: false - light: # These lights are controlling the LEDs on the device - id: light_full @@ -550,6 +544,40 @@ script: // 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: |- + 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_save + mode: parallel + parameters: + light_ptr: light::LightState* + attr_global_ptr: uint32_t* + then: + - lambda: |- + 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); + select: # EU relay light mode template - &relay_light_mode_eu diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_relays.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_relays.yaml index d2a52bd..9ab29e8 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_relays.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_relays.yaml @@ -47,6 +47,13 @@ globals: restore_value: false initial_value: 'false' + - id: gb_lights_1 + type: std::vector + restore_value: false + - id: gb_lights_2 + type: std::vector + restore_value: false + # Packed relay modes - replaces 4 separate selects - id: relay_modes_packed type: uint16_t @@ -62,10 +69,10 @@ globals: initial_value: '0' # All switches default to OFF # Bit layout: [unused(3)][sw_relay4][sw_relay3][sw_relay2][sw_relay1][sw_expose_leds] -# - id: attr_light_output_1 -# type: tx_ultimate_easy::LightAttributes -# restore_value: true -# initial_value: + - id: attr_light_output_1 + type: uint32_t + restore_value: true + initial_value: '${LIGHT_ATTRS_DEFAULT}' light: # These lights are used for the physical relays to be shown as lights @@ -89,6 +96,12 @@ light: - switch.is_on: sw_relay_1 then: - switch.turn_off: sw_relay_1 + on_state: + then: + - script.execute: + id: light_attributes_save + light_ptr: !lambda return id(light_output_1); + attr_global_ptr: !lambda return &id(attr_light_output_1); - id: light_output_2 name: Light output 2 output: output_relay_2 @@ -770,6 +783,10 @@ script: #if !defined(TX_ULTIMATE_EASY_CORE) #error "The package TX-Ultimate-Easy-ESPHome_core.yaml is required." #endif + #if !defined(TX_ULTIMATE_EASY_CORE_HW_LEDS) + #error "The package TX-Ultimate-Easy-ESPHome_core_hw_leds.yaml is required." + #endif // TX_ULTIMATE_EASY_CORE_HW_LEDS + // Identify itself ESP_LOGCONFIG(ESPHOME_PROJECT_NAME, " - Standard - Hardware - Relays"); diff --git a/components/tx_ultimate_easy/tx_ultimate_easy.cpp b/components/tx_ultimate_easy/tx_ultimate_easy.cpp index 82f560b..d820448 100644 --- a/components/tx_ultimate_easy/tx_ultimate_easy.cpp +++ b/components/tx_ultimate_easy/tx_ultimate_easy.cpp @@ -223,5 +223,28 @@ namespace esphome { return tp; } + // LightAttributes + + // Constant definitions + const LightAttributes LIGHT_ATTRS_DEFAULT = {100, 255, 255, 255}; + const uint32_t LIGHT_ATTRS_DEFAULT_PACKED = 0x64FFFFFF; + + // Function implementations + uint32_t pack_light_attributes(const LightAttributes& attr) { + return (uint32_t(attr.brightness) << 24) | + (uint32_t(attr.red) << 16) | + (uint32_t(attr.green) << 8) | + (uint32_t(attr.blue)); + } + + LightAttributes unpack_light_attributes(uint32_t packed) { + return { + .brightness = uint8_t((packed >> 24) & 0xFF), + .red = uint8_t((packed >> 16) & 0xFF), + .green = uint8_t((packed >> 8) & 0xFF), + .blue = uint8_t(packed & 0xFF) + }; + } + } // namespace tx_ultimate_easy } // namespace esphome diff --git a/components/tx_ultimate_easy/tx_ultimate_easy.h b/components/tx_ultimate_easy/tx_ultimate_easy.h index c982537..5175398 100644 --- a/components/tx_ultimate_easy/tx_ultimate_easy.h +++ b/components/tx_ultimate_easy/tx_ultimate_easy.h @@ -34,13 +34,6 @@ namespace esphome { // Log tag static const char *TAG = "tx_ultimate_easy"; - struct LightAttributes { - uint8_t brightness; - uint8_t red; - uint8_t green; - uint8_t blue; - }; - struct TouchPoint { uint8_t button = 0; int8_t x = -1; @@ -89,5 +82,73 @@ namespace esphome { }; // class TxUltimateEasy + /** + * @brief Light attributes structure for storing color and brightness data. + * + * This structure represents the visual attributes of a light without the state (on/off). + * It's designed to be packed efficiently into a 32-bit integer for NVS storage. + * RGB components use the full 8-bit range (0-255) while brightness uses percentage (0-100). + */ + struct LightAttributes { + uint8_t brightness; ///< Light brightness percentage (0-100, where 100 = full brightness) + uint8_t red; ///< Red color component (0-255) + uint8_t green; ///< Green color component (0-255) + uint8_t blue; ///< Blue color component (0-255) + }; + + /** + * @brief Packs LightAttributes structure into a 32-bit integer for storage. + * + * Bit layout: [brightness(8)][red(8)][green(8)][blue(8)] + * This allows efficient storage in ESPHome globals with restore_value support. + * Note: Brightness values > 100 will be clamped to 100 during packing. + * + * @param attr The LightAttributes structure to pack + * @return uint32_t Packed representation suitable for NVS storage + * + * @example + * LightAttributes attrs = {75, 255, 128, 64}; + * uint32_t packed = pack_light_attributes(attrs); // Returns 0x4BFF8040 + */ + uint32_t pack_light_attributes(const LightAttributes& attr); + + /** + * @brief Unpacks a 32-bit integer back into LightAttributes structure. + * + * Reverses the packing operation to extract individual color and brightness values. + * Brightness values > 100 in the packed data will be clamped to 100. + * + * @param packed The packed 32-bit representation + * @return LightAttributes The unpacked structure with individual components + * + * @example + * uint32_t packed = 0x4BFF8040; + * LightAttributes attrs = unpack_light_attributes(packed); + * // attrs.brightness = 75, attrs.red = 255, attrs.green = 128, attrs.blue = 64 + */ + LightAttributes unpack_light_attributes(uint32_t packed); + + /** + * @brief Default light attributes for initialization. + * + * Provides sensible defaults for new lights: + * - Brightness: 100 (full brightness) + * - Red: 255 (full intensity) + * - Green: 255 (full intensity) + * - Blue: 255 (full intensity) + * Result: Pure white color at full brightness + */ + extern const LightAttributes LIGHT_ATTRS_DEFAULT; + + /** + * @brief Pre-packed version of DEFAULT_LIGHT_ATTRS for convenience. + * + * This constant contains LIGHT_ATTRS_DEFAULT already packed into uint32_t format, + * suitable for direct use in ESPHome YAML initial_value fields. + * + * Value: 0x64FFFFFF (brightness=100, RGB=255,255,255) + */ + extern const uint32_t LIGHT_ATTRS_DEFAULT_PACKED; + } // namespace tx_ultimate_easy } // namespace esphome