diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml index 7e65564..2a88338 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml @@ -21,6 +21,14 @@ substitutions: version: '0.0.4' + 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_api: !include TX-Ultimate-Easy-ESPHome_core_api.yaml @@ -103,9 +111,9 @@ select: name: Model (Format) platform: template options: - - "EU (Square, T5-xC-86)" - - "US (Rectangle, T5-xC-120)" - initial_option: "EU (Square, T5-xC-86)" + - "${TX_MODEL_FORMAT_EU_TEXT}" + - "${TX_MODEL_FORMAT_US_TEXT}" + initial_option: "${TX_MODEL_FORMAT_EU_TEXT}" optimistic: true restore_value: true internal: false @@ -117,11 +125,11 @@ select: name: Model (Gang) platform: template options: - - "1 Gang" - - "2 Gang" - - "3 Gang" - - "4 Gang" - initial_option: "1 Gang" + - "${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 diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_leds.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_leds.yaml index 3892843..3f2fac0 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_leds.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_leds.yaml @@ -14,6 +14,17 @@ 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 @@ -817,6 +828,62 @@ script: 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}; + + ESP_LOGI("core_hw_leds.light_set_state", "Setting light group %d, index %d to state %s", + light_group, light_index, state ? "ON" : "OFF"); + + switch (light_group) { + case 1: + if (light_index >= id(gb_lights_1).size()) { + ESP_LOGE("light_set_state", "Invalid light_index %d for group 1", light_index); + return; + } + if (state and !id(gb_lights_1)[light_index]->current_values.is_on()) { + 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_TRANSITION_TURN_ON / 100.0f); + call.perform(); + } else if (!state and id(gb_lights_1)[light_index]->current_values.is_on()) { + 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("light_set_state", "Invalid light_index %d for group 2", light_index); + return; + } + if (state and !id(gb_lights_2)[light_index]->current_values.is_on()) { + 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_TRANSITION_TURN_ON / 100.0f); + call.perform(); + } else if (!state and id(gb_lights_2)[light_index]->current_values.is_on()) { + 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 @@ -824,11 +891,11 @@ select: name: Relay 1 light mode platform: template options: - - "Disabled" - - "Bottom" - - "Top" - - "Both" - initial_option: "Bottom" + - "${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 @@ -854,11 +921,11 @@ select: name: Relay 1 light mode platform: template options: - - "Disabled" - - "Left" - - "Right" - - "Both" - initial_option: "Right" + - "${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 diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_relays.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_relays.yaml index ead05a5..88a9d9d 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_relays.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_relays.yaml @@ -144,60 +144,70 @@ script: - script.wait: boot_initialize_relays - wait_until: condition: - - lambda: return sl_tx_model_format->active_index().has_value(); - lambda: return id(boot_initialization_relays); - lambda: |- - auto model_format = sl_tx_model_format->active_index(); - if (!model_format.has_value()) { - ESP_LOGE("core_hw_relays", "Model (Format) not defined"); + 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; } - std::vector relay_modes; - const bool is_eu_model = model_format.value() == 0; + 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}"; - // Select appropriate light mode selectors based on model - if (is_eu_model) { - relay_modes = {sl_relay_1_light_mode_eu, sl_relay_2_light_mode_eu, - sl_relay_3_light_mode_eu, sl_relay_4_light_mode_eu}; - } else { - relay_modes = {sl_relay_1_light_mode_us, sl_relay_2_light_mode_us, - sl_relay_3_light_mode_us, sl_relay_4_light_mode_us}; - } - - // Get switch states - const std::vector switches = {sw_relay_1, sw_relay_2, sw_relay_3, sw_relay_4}; - - // Check if light vectors are initialized - if (id(gb_lights_1).empty() || id(gb_lights_2).empty()) { - ESP_LOGE("core_hw_relays", "Light vector not initialized"); - return; - } - - // Update lights based on relay states - for (size_t i = 0; i < relay_modes.size() && i < id(gb_lights_1).size(); ++i) { - if (!relay_modes[i] || !switches[i]) continue; - - auto light_index = relay_modes[i]->active_index(); - if (!light_index.has_value()) continue; - - const uint8_t light_idx = light_index.value(); - const bool switch_state = switches[i]->state; - - // Update first light group (bottom/left) - if ((light_idx == 1 || light_idx == 3) && i < id(gb_lights_1).size() && id(gb_lights_1)[i]) { - if (switch_state) - id(gb_lights_1)[i]->turn_on(); - else - id(gb_lights_1)[i]->turn_off(); + // 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; } - // Update second light group (top/right) - if ((light_idx == 2 || light_idx == 3) && i < id(gb_lights_2).size() && id(gb_lights_2)[i]) { - if (switch_state) - id(gb_lights_2)[i]->turn_on(); - else - id(gb_lights_2)[i]->turn_off(); + 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 } }