diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml index 5911a02..75bfc76 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml @@ -27,7 +27,6 @@ substitutions: packages: # yamllint disable rule:colons - core_api: !include TX-Ultimate-Easy-ESPHome_core_api.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_relays: !include TX-Ultimate-Easy-ESPHome_core_hw_relays.yaml @@ -36,6 +35,12 @@ packages: core_hw_vibration: !include TX-Ultimate-Easy-ESPHome_core_hw_vibration.yaml # yamllint enable rule:colons +api: + id: api_server + on_client_connected: + then: + - script.execute: publish_device_info + button: - id: bt_restart name: Restart @@ -82,13 +87,25 @@ ota: 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: send_event_to_ha - component: boot - event: done + id: api_send_ha_event_boot + type: done - id: boot_initialize mode: restart @@ -98,9 +115,8 @@ script: # - HW Relays # - HW Touch - script.execute: - id: send_event_to_ha - component: boot - event: start + id: api_send_ha_event_boot + type: start - id: boot_sequence mode: restart @@ -144,6 +160,9 @@ select: entity_category: config disabled_by_default: false icon: mdi:dip-switch + on_value: + then: + - lambda: tx_ultimate->set_gang_count(static_cast(i)+1); text_sensor: - id: tx_fw_version diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core_api.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core_api.yaml deleted file mode 100644 index ff4bb80..0000000 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core_api.yaml +++ /dev/null @@ -1,41 +0,0 @@ -#################################################################################################### -##### 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(); -... diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_buttons.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_buttons.yaml index 7573678..3029db4 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_buttons.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_buttons.yaml @@ -108,33 +108,89 @@ script: - id: button_action mode: parallel parameters: - component: string - event: string + button: uint8_t + action: string + count: uint8_t then: - # Extended by: - # - core_api + - homeassistant.event: + event: esphome.tx_ultimate_easy + data: + device_name: !lambda return tx_device_name->state.c_str(); + firmware: ${version} + domain: touch + type: button + action: !lambda return action.c_str(); + button_id: !lambda return button; + count: !lambda return count; + position: !lambda return id(button_press_position); - lambda: |- - ESP_LOGI("core_hw_buttons", "Button '%s' action: '%s'", component.c_str(), event.c_str()); + ESP_LOGI("core_hw_buttons", "Button %" PRIu8 " action: '%s'", button, action.c_str()); + if (action == "click") { + switch (button) { + case ${BUTTON_1_ID}: + bs_button_1_click_event->publish_state(true); + break; + case ${BUTTON_2_ID}: + bs_button_2_click_event->publish_state(true); + break; + case ${BUTTON_3_ID}: + bs_button_3_click_event->publish_state(true); + break; + case ${BUTTON_4_ID}: + bs_button_4_click_event->publish_state(true); + break; + } + } else if (action == "double_click") { + switch (button) { + case ${BUTTON_1_ID}: + bs_button_1_double_click_event->publish_state(true); + break; + case ${BUTTON_2_ID}: + bs_button_2_double_click_event->publish_state(true); + break; + case ${BUTTON_3_ID}: + bs_button_3_double_click_event->publish_state(true); + break; + case ${BUTTON_4_ID}: + bs_button_4_double_click_event->publish_state(true); + break; + } + } else if (action == "long_press") { + switch (button) { + case ${BUTTON_1_ID}: + bs_button_1_long_press_event->publish_state(true); + break; + case ${BUTTON_2_ID}: + bs_button_2_long_press_event->publish_state(true); + break; + case ${BUTTON_3_ID}: + bs_button_3_long_press_event->publish_state(true); + break; + case ${BUTTON_4_ID}: + bs_button_4_long_press_event->publish_state(true); + break; + } + } id(button_press_button) = 0; - id(click_counter) = 0; + id(button_press_position) = 0; id(button_press_start_time) = 0; + id(click_counter) = 0; buttons_release->execute(); - id: button_click_event mode: restart parameters: - button_id: uint8_t + button: uint8_t click_count: uint8_t then: - delay: milliseconds: ${BUTTON_MULTI_CLICK_DELAY} - lambda: |- - const std::string button_name = "bs_button_" + std::to_string(button_id); std::string event_name; if (click_count == 1) event_name = "click"; else if (click_count == 2) event_name = "double_click"; - else event_name = std::to_string(click_count) + "_click"; - button_action->execute(button_name.c_str(), event_name.c_str()); + else event_name = "multiple_click"; + button_action->execute(button, event_name.c_str(), click_count); - id: buttons_release mode: restart @@ -157,30 +213,24 @@ script: then: - script.execute: id: touch_on_press_buttons - touch_position: !lambda return touch_position; + button: !lambda return button; + position: !lambda return position; - id: touch_on_press_buttons mode: restart parameters: - touch_position: uint8_t + button: uint8_t + position: uint8_t then: - lambda: |- id(button_press_start_time) = millis(); - id(button_press_position) = touch_position; - uint8_t button = 0; - auto model_index = sl_tx_model_gang->active_index(); - if (model_index.has_value()) { - const uint8_t model_idx = model_index.value() + 1; // Increment for 1-based indexing - if (model_idx == 1) { - button = 1; // Single button, always 1 - } else { - const uint8_t width = ${TOUCH_POSITION_MAX_VALUE} / model_idx; // Width of each button region - ESP_LOGV("core_hw_buttons", "Button regions: width=%" PRIu8 ", touch_position=%" PRIu8, - width, touch_position); - button = (touch_position / width) + 1; // Determine button region - if (button > model_idx) - button = model_idx; // Clamp to max button count - } + id(button_press_button) = button; + // Update counters + if (id(button_press_position) == position) { + id(click_counter)++; + } else { + id(click_counter) = 1; + id(button_press_position) = position; } // Update binary sensor switch (button) { @@ -197,13 +247,6 @@ script: bs_button_4->publish_state(true); break; } - // Update counters - if (id(button_press_button) == button) { - id(click_counter)++; - } else { - id(click_counter) = 1; - id(button_press_button) = button; - } - id: !extend touch_on_release then: @@ -221,7 +264,7 @@ script: press_duration <= ${BUTTON_CLICK_MAX_LENGTH}) { // Short/normal click button_click_event->execute(id(button_press_button), id(click_counter)); } else if (press_duration >= ${BUTTON_LONG_PRESS_DELAY} and press_duration <= ${BUTTON_PRESS_TIMEOUT}) { - button_action->execute(("bs_button_" + std::to_string(id(button_press_button))).c_str(), "long_click"); + button_action->execute(id(button_press_button), "long_press", 1); } else if (press_duration > ${BUTTON_PRESS_TIMEOUT}) { // Timeout or invalid ESP_LOGW("core_hw_buttons", "Button press cancelled or timed out after ${BUTTON_PRESS_TIMEOUT} ms"); } diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_relays.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_relays.yaml index 80b6bd5..ae3191f 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_relays.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_relays.yaml @@ -189,7 +189,7 @@ script: } // Toggle relay if corresponding button action is enabled - switch (button_id) { + switch (button) { case ${BUTTON_1_ID}: if (sl_button_1_action->state != "${RELAY_MODE_TEXT_NOT_USED}") sw_relay_1->toggle(); diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_touch.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_touch.yaml index 0a47ab3..4c3dfd4 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_touch.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_touch.yaml @@ -15,50 +15,188 @@ substitutions: TOUCH_POSITION_MAX_VALUE: '10' # Maximum touch position value returned by the touch pad via uart binary_sensor: + - &bs_button_event_template + id: bs_button_event_template + icon: mdi:gesture-tap-box + internal: true + disabled_by_default: true + platform: template + + - id: bs_button_1_click_event + name: Button 1 - Click event + internal: false + <<: *bs_button_event_template + on_press: + then: + - delay: !lambda return nr_touch_duration->state; + - binary_sensor.template.publish: + id: bs_button_1_click_event + state: OFF # yamllint disable-line rule:truthy + - id: bs_button_2_click_event + name: Button 2 - Click event + internal: false + <<: *bs_button_event_template + on_press: + then: + - delay: !lambda return nr_touch_duration->state; + - binary_sensor.template.publish: + id: bs_button_2_click_event + state: OFF # yamllint disable-line rule:truthy + - id: bs_button_3_click_event + name: Button 3 - Click event + internal: false + <<: *bs_button_event_template + on_press: + then: + - delay: !lambda return nr_touch_duration->state; + - binary_sensor.template.publish: + id: bs_button_3_click_event + state: OFF # yamllint disable-line rule:truthy + - id: bs_button_4_click_event + name: Button 4 - Click event + internal: false + <<: *bs_button_event_template + on_press: + then: + - delay: !lambda return nr_touch_duration->state; + - binary_sensor.template.publish: + id: bs_button_4_click_event + state: OFF # yamllint disable-line rule:truthy + + - id: bs_button_1_double_click_event + name: Button 1 - Double-click event + internal: false + <<: *bs_button_event_template + on_press: + then: + - delay: !lambda return nr_touch_duration->state; + - binary_sensor.template.publish: + id: bs_button_1_double_click_event + state: OFF # yamllint disable-line rule:truthy + - id: bs_button_2_double_click_event + name: Button 2 - Double-click event + internal: false + <<: *bs_button_event_template + on_press: + then: + - delay: !lambda return nr_touch_duration->state; + - binary_sensor.template.publish: + id: bs_button_2_double_click_event + state: OFF # yamllint disable-line rule:truthy + - id: bs_button_3_double_click_event + name: Button 3 - Double-click event + internal: false + <<: *bs_button_event_template + on_press: + then: + - delay: !lambda return nr_touch_duration->state; + - binary_sensor.template.publish: + id: bs_button_3_double_click_event + state: OFF # yamllint disable-line rule:truthy + - id: bs_button_4_double_click_event + name: Button 4 - Double-click event + internal: false + <<: *bs_button_event_template + on_press: + then: + - delay: !lambda return nr_touch_duration->state; + - binary_sensor.template.publish: + id: bs_button_4_double_click_event + state: OFF # yamllint disable-line rule:truthy + + - id: bs_button_1_long_press_event + name: Button 1 - Long-press event + internal: false + <<: *bs_button_event_template + on_press: + then: + - delay: !lambda return nr_touch_duration->state; + - binary_sensor.template.publish: + id: bs_button_1_long_press_event + state: OFF # yamllint disable-line rule:truthy + - id: bs_button_2_long_press_event + name: Button 2 - Long-press event + internal: false + <<: *bs_button_event_template + on_press: + then: + - delay: !lambda return nr_touch_duration->state; + - binary_sensor.template.publish: + id: bs_button_2_long_press_event + state: OFF # yamllint disable-line rule:truthy + - id: bs_button_3_long_press_event + name: Button 3 - Long-press event + internal: false + <<: *bs_button_event_template + on_press: + then: + - delay: !lambda return nr_touch_duration->state; + - binary_sensor.template.publish: + id: bs_button_3_long_press_event + state: OFF # yamllint disable-line rule:truthy + - id: bs_button_4_long_press_event + name: Button 4 - Long-press event + internal: false + <<: *bs_button_event_template + on_press: + then: + - delay: !lambda return nr_touch_duration->state; + - binary_sensor.template.publish: + id: bs_button_4_long_press_event + state: OFF # yamllint disable-line rule:truthy + - id: bs_multi_touch - name: Multi-touch + name: Multi-touch event icon: mdi:gesture-two-tap internal: false - platform: template - on_click: + <<: *bs_button_event_template + on_press: then: - - lambda: send_event_to_ha->execute("multi_touch", "multi_touch"); + - delay: !lambda return nr_touch_duration->state; + - binary_sensor.template.publish: + id: bs_multi_touch + state: OFF # yamllint disable-line rule:truthy - id: bs_swipe_left - name: Swipe left + name: Swipe left event icon: mdi:gesture-swipe-left - internal: true - platform: template - on_click: + <<: *bs_button_event_template + on_press: then: - - lambda: send_event_to_ha->execute("swipe", "left"); - + - delay: !lambda return nr_touch_duration->state; + - binary_sensor.template.publish: + id: bs_swipe_left + state: OFF # yamllint disable-line rule:truthy - id: bs_swipe_right - name: Swipe right + name: Swipe right event icon: mdi:gesture-swipe-right - internal: true - platform: template - on_click: + <<: *bs_button_event_template + on_press: then: - - lambda: send_event_to_ha->execute("swipe", "right"); - + - delay: !lambda return nr_touch_duration->state; + - binary_sensor.template.publish: + id: bs_swipe_right + state: OFF # yamllint disable-line rule:truthy - id: bs_swipe_up - name: Swipe up + name: Swipe up event icon: mdi:gesture-swipe-up - internal: true - platform: template - on_click: + <<: *bs_button_event_template + on_press: then: - - lambda: send_event_to_ha->execute("swipe", "up"); - + - delay: !lambda return nr_touch_duration->state; + - binary_sensor.template.publish: + id: bs_swipe_up + state: OFF # yamllint disable-line rule:truthy - id: bs_swipe_down - name: Swipe down + name: Swipe down event icon: mdi:gesture-swipe-down - internal: true - platform: template - on_click: + <<: *bs_button_event_template + on_press: then: - - lambda: send_event_to_ha->execute("swipe", "down"); + - delay: !lambda return nr_touch_duration->state; + - binary_sensor.template.publish: + id: bs_swipe_down + state: OFF # yamllint disable-line rule:truthy external_components: - source: @@ -71,7 +209,7 @@ external_components: number: - id: nr_touch_duration - name: Touch duration + name: Touch event duration icon: mdi:timer-cog-outline unit_of_measurement: ms # mode: box @@ -91,6 +229,12 @@ script: - script.execute: boot_initialize_touch - id: boot_initialize_touch + mode: restart + then: + - script.execute: boot_initialize_touch_format + - script.execute: boot_initialize_touch_gang + + - id: boot_initialize_touch_format mode: restart then: - wait_until: @@ -109,25 +253,56 @@ script: bs_swipe_up->publish_state(false); bs_swipe_up->set_internal(!is_model_us); + - 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); + bs_button_1_click_event->publish_state(false); + bs_button_2_click_event->publish_state(false); + bs_button_3_click_event->publish_state(false); + bs_button_4_click_event->publish_state(false); + bs_button_1_double_click_event->publish_state(false); + bs_button_2_double_click_event->publish_state(false); + bs_button_3_double_click_event->publish_state(false); + bs_button_4_double_click_event->publish_state(false); + bs_button_1_long_press_event->publish_state(false); + 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); + - 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); + - binary_sensor.template.publish: + id: bs_multi_touch + state: OFF # yamllint disable-line rule:truthy - id: touch_on_press mode: restart parameters: - touch_position: uint8_t + button: uint8_t + position: uint8_t then: # Extended by: # - HW Buttons @@ -139,57 +314,30 @@ script: # 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 + - binary_sensor.template.publish: + id: bs_swipe_down + state: ON # yamllint disable-line rule:truthy - 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 + - binary_sensor.template.publish: + id: bs_swipe_up + state: ON # yamllint disable-line rule:truthy switch: - id: sw_touch_panel_power @@ -216,17 +364,26 @@ tx_ultimate_easy: } on_multi_touch_release: + - homeassistant.event: + event: esphome.tx_ultimate_easy + data: + device_name: !lambda return tx_device_name->state.c_str(); + firmware: ${version} + domain: touch + type: multi_touch + action: release + position: !lambda return touch.x; - lambda: ESP_LOGI("tx_ultimate_easy", "Multi-touch released"); - script.execute: touch_on_multi_touch_release on_press: - lambda: |- - const uint8_t touch_position = static_cast(touch.x); - if (touch_position > ${TOUCH_POSITION_MAX_VALUE}) { // Check for valid range - ESP_LOGE("tx_ultimate_easy", "Invalid touch position: %" PRIu8, touch_position); + const uint8_t position = static_cast(touch.x); + if (position > ${TOUCH_POSITION_MAX_VALUE}) { // Check for valid range + ESP_LOGE("tx_ultimate_easy", "Invalid touch position: %" PRIu8, position); } else { - ESP_LOGI("tx_ultimate_easy", "Pressed at position %" PRIu8, touch_position); - touch_on_press->execute(touch_position); + ESP_LOGI("tx_ultimate_easy", "Pressed at position %" PRIu8, position); + touch_on_press->execute(static_cast(touch.button), position); } on_release: @@ -234,11 +391,41 @@ tx_ultimate_easy: - script.execute: touch_on_release on_swipe_left: - - lambda: ESP_LOGI("tx_ultimate_easy", "Swipe left"); + - homeassistant.event: + event: esphome.tx_ultimate_easy + data: + device_name: !lambda return tx_device_name->state.c_str(); + firmware: ${version} + domain: touch + type: swipe + action: !lambda |- + return sl_tx_model_format->state == "${TX_MODEL_FORMAT_US_TEXT}" ? "left" : "down"; + swipe-direction: !lambda |- + return sl_tx_model_format->state == "${TX_MODEL_FORMAT_US_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}" + ? "left" + : "down"); - script.execute: touch_swipe_left on_swipe_right: - - lambda: ESP_LOGI("tx_ultimate_easy", "Swipe right"); + - homeassistant.event: + event: esphome.tx_ultimate_easy + data: + device_name: !lambda return tx_device_name->state.c_str(); + firmware: ${version} + domain: touch + type: swipe + action: !lambda |- + return sl_tx_model_format->state == "${TX_MODEL_FORMAT_US_TEXT}" ? "right" : "up"; + swipe-direction: !lambda |- + return sl_tx_model_format->state == "${TX_MODEL_FORMAT_US_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}" + ? "right" + : "up"); - script.execute: touch_swipe_right on_touch_event: diff --git a/README.md b/README.md index 79b2db7..4918684 100644 --- a/README.md +++ b/README.md @@ -29,53 +29,25 @@ ## Integration with Home Assistant -TX Ultimate Easy exposes your device's components (sensors, touch panel, relays, etc.) to Home Assistant, allowing you to: +TX Ultimate Easy exposes your device's components (sensors, touch panel, relays, etc.) to Home Assistant, +allowing you to: - 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 -All automation capabilities are handled through Home Assistant's native automation system - this project focuses on providing reliable +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. ### Event-Based Automation TX Ultimate Easy uses Home Assistant's native Events system for reliable automation triggers. -While sensors show the current state (e.g., button pressed/not pressed), events capture-specific actions like clicks, swipes, and long presses. - -To view available events: - -1. Go to Developer Tools in Home Assistant -2. Select the "Events" tab -3. Enter `esphome.tx_ultimate_easy` in the "Event to subscribe to" field -4. Click "Start listening" -5. Interact with your device to see events in real-time - -Example event trigger in automation (YAML): - -```yaml -triggers: - - platform: event - event_type: esphome.tx_ultimate_easy - event_data: - device_name: your_device_name # Replace with your specific device name - component: bs_button_1 # Button identifier (e.g., bs_button_1, bs_button_2, bs_button_3 or bs_button_4) - event: click -actions: - - action: light.toggle - target: - entity_id: light.living_room -``` - -**Common event types**: -- `click`: Single press and release -- `double_click`: Two quick presses -- `long_press`: Press and hold -- `swipe_left`: Left swipe gesture -- `swipe_right`: Right swipe gesture - -You can also create event-based automations through the Home Assistant UI by selecting "Event" as the trigger type and filtering by your device. +While sensors show the current state (e.g., button pressed/not pressed), +events capture-specific actions like clicks, swipes, and long presses. + +For more details, please refer to our **[Events docs](docs/events.md)**. ### Device Configuration #### Relay Modes @@ -166,8 +138,10 @@ Please ensure your code follows our standards: 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 +- **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: diff --git a/docs/events.md b/docs/events.md new file mode 100644 index 0000000..172f0c4 --- /dev/null +++ b/docs/events.md @@ -0,0 +1,236 @@ +# Updating the Event Engine in TX Ultimate Easy + +## Overview of the Event System + +The TX Ultimate Easy firmware introduces a powerful +and flexible event system designed to handle various types of interactions, +such as touch gestures and device states. +This system leverages Home Assistant's native event structure, +ensuring seamless integration and enabling users to create advanced automations. + +### Event Structure + +All events emitted by the device are categorized under the `esphome.tx_ultimate_easy` event type in Home Assistant. +The `data` field within the event payload provides details about the specific interaction. +Below is a detailed description of the keys used: + +#### Example Event Payload + +```yaml + event: + event_type: esphome.tx_ultimate_easy + data: + device_id: "abc123" + device_name: "living_room_panel" + firmware: "2024.12.1" + domain: touch + type: button + action: click + button_id: 2 + count: 1 + position: 3 +``` + +### Key Definitions + +#### `device_id` + +- **Description**: A unique identifier for the device emitting the event. +- **Example**: `device_id: "abc123"` + +#### `device_name` + +- **Description**: A Home Assistant-compatible version of the hostname, with blanks and invalid characters replaced by `_`. +- **Example**: `device_name: "living_room_panel"` + +#### `firmware` + +- **Description**: The firmware version of the device, formatted as `YYYY.M.S`. +- **Example**: `firmware: "2024.12.1"` + +#### `domain` + +- **Description**: The high-level category of the event. +- **Examples**: + - `boot` + - `touch` + +#### `type` + +- **Description**: Specifies the subcategory within the `domain`. +- **Examples**: + - For `domain: boot`: `start`, `done` + - For `domain: touch`: `button`, `swipe`, `multi_touch` + +#### `action` + +- **Description**: Indicates the specific action or interaction. +- **Examples**: + - For `type: button`: `click`, `double-click`, `long-press`, `multiple-click` + - For `type: swipe`: `left`, `right`, `up`, `down` + +#### `button_id` + +- **Description**: Identifies the button involved in the event (specific to `type: button`). +- **Example**: `button_id: 2` + +#### `count` + +- **Description**: Indicates the number of clicks or interactions (used with `action: multiple-click`). +- **Example**: `count: 3` + +#### `swipe-direction` + +- **Description**: Specifies the direction of a swipe (used with `type: swipe`). +- **Examples**: `left`, `right`, `up`, `down` + +#### `position` + +- **Description**: An integer from 1 to 10 indicating the touch position (available on all touch events). +- **Example**: `position: 3` + +### Supported Event Types + +#### Boot Events + +```yaml + event: + device_id: "abc123" + device_name: "living_room_panel" + firmware: "2024.12.1" + domain: boot + type: start + action: null +``` + +```yaml + event: + device_id: "abc123" + device_name: "living_room_panel" + firmware: "2024.12.1" + domain: boot + type: done + action: null +``` + +#### Touch Events + +##### Button Event + +```yaml + event: + device_id: "abc123" + device_name: "living_room_panel" + firmware: "2024.12.1" + domain: touch + type: button + action: click + button_id: 1 + count: 1 + position: 3 +``` + +```yaml + event: + device_id: "abc123" + device_name: "living_room_panel" + firmware: "2024.12.1" + domain: touch + type: button + action: multiple-click + button_id: 1 + count: 5 + position: 3 +``` + +##### Swipe Event + +```yaml + event: + device_id: "abc123" + device_name: "living_room_panel" + firmware: "2024.12.1" + domain: touch + type: swipe + action: left + swipe-direction: left + position: 3 +``` + +```yaml + event: + device_id: "abc123" + device_name: "living_room_panel" + firmware: "2024.12.1" + domain: touch + type: swipe + action: up + swipe-direction: up + position: 3 +``` + +##### Multi-Touch Event + +```yaml + event: + device_id: "abc123" + device_name: "living_room_panel" + firmware: "2024.12.1" + domain: touch + type: multi_touch + action: release + position: 3 +``` + +### Integration in Automations + +#### Listening to Events + +To utilize these events in Home Assistant, follow these steps: + +1. Open the **Developer Tools** in Home Assistant. +2. Navigate to the **Events** tab. +3. Enter `esphome.tx_ultimate_easy` in the "Event to subscribe to" field. +4. Click "Start listening." +5. Trigger interactions on your TX Ultimate Easy device to see the events in real-time. + +#### Example Automation YAML + +##### Automation for a Single Click + +```yaml +trigger: + - platform: event + event_type: esphome.tx_ultimate_easy + event_data: + domain: touch + type: button + action: click + button_id: 1 + position: 3 +action: + - service: light.toggle + target: + entity_id: light.living_room +``` + +##### Automation for a Swipe Gesture + +```yaml +trigger: + - platform: event + event_type: esphome.tx_ultimate_easy + event_data: + domain: touch + type: swipe + action: left + swipe-direction: left + position: 3 +action: + - service: script.activate_scene + target: + entity_id: scene.relax_mode +``` + +This event engine provides a robust and extensible framework for handling device interactions, +allowing users to implement highly customized automations with ease.