From 4ea7f1ee57c1e65c190e86354539c2dd8fa58297 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Mon, 23 Dec 2024 03:55:50 +0100 Subject: [PATCH 1/6] New event handler This rebuild the engine to send events to Home Assistant --- ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml | 30 +- .../TX-Ultimate-Easy-ESPHome_core_api.yaml | 41 --- ...Ultimate-Easy-ESPHome_core_hw_buttons.yaml | 113 ++++-- ...-Ultimate-Easy-ESPHome_core_hw_relays.yaml | 2 +- ...X-Ultimate-Easy-ESPHome_core_hw_touch.yaml | 340 ++++++++++++++---- README.md | 33 +- docs/events.md | 229 ++++++++++++ 7 files changed, 595 insertions(+), 193 deletions(-) delete mode 100644 ESPHome/TX-Ultimate-Easy-ESPHome_core_api.yaml create mode 100644 docs/events.md diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml index 5911a02..824a6a0 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 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..9254909 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_click", 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..6d55d03 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,55 @@ 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; + 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 +313,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 +363,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 +390,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..116a3a9 100644 --- a/README.md +++ b/README.md @@ -44,38 +44,7 @@ device integration rather than implementing its own automation tools. 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. +For more details, please refeer to our **[Events docs](docs/events.md)**. ### Device Configuration #### Relay Modes diff --git a/docs/events.md b/docs/events.md new file mode 100644 index 0000000..af3b187 --- /dev/null +++ b/docs/events.md @@ -0,0 +1,229 @@ +# 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. From a00e15fa853782dc4491463fdc477edf9722c687 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Mon, 23 Dec 2024 03:59:29 +0100 Subject: [PATCH 2/6] lint --- README.md | 15 ++++++++++----- docs/events.md | 13 ++++++++++--- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 116a3a9..49e53bb 100644 --- a/README.md +++ b/README.md @@ -29,20 +29,23 @@ ## 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. +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 refeer to our **[Events docs](docs/events.md)**. @@ -135,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 index af3b187..172f0c4 100644 --- a/docs/events.md +++ b/docs/events.md @@ -2,11 +2,17 @@ ## 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. +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: +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 @@ -226,4 +232,5 @@ action: 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. +This event engine provides a robust and extensible framework for handling device interactions, +allowing users to implement highly customized automations with ease. From 2a8255b788c48177521258733f354ea17e80570f Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Mon, 23 Dec 2024 04:16:28 +0100 Subject: [PATCH 3/6] Use `long_press` and not `long_click` --- ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_buttons.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_buttons.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_buttons.yaml index 9254909..3029db4 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_buttons.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_buttons.yaml @@ -264,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(id(button_press_button), "long_click", 1); + 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"); } From be6a4a51e2872d1473eb41ee27f0376456766f11 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Mon, 23 Dec 2024 04:24:50 +0100 Subject: [PATCH 4/6] Use `set_gang_count` --- ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml | 3 +++ ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_touch.yaml | 1 + 2 files changed, 4 insertions(+) diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml index 824a6a0..bad2704 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml @@ -160,6 +160,9 @@ select: entity_category: config disabled_by_default: false icon: mdi:dip-switch + on_value: + then: + - lambda: set_gang_count(static_cast(i)+1); text_sensor: - id: tx_fw_version diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_touch.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_touch.yaml index 6d55d03..8c9f090 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_touch.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_touch.yaml @@ -262,6 +262,7 @@ script: - lambda: |- const uint8_t num_gangs = (sl_tx_model_gang->active_index().has_value()) ? (sl_tx_model_gang->active_index().value() + 1) : 0; + 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); From f9e9243de50ebab16e087b5f4d7ec0522b4a9b74 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Mon, 23 Dec 2024 04:31:16 +0100 Subject: [PATCH 5/6] Specify device when setting gang count --- ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml | 2 +- ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_touch.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml index bad2704..75bfc76 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml @@ -162,7 +162,7 @@ select: icon: mdi:dip-switch on_value: then: - - lambda: set_gang_count(static_cast(i)+1); + - 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_hw_touch.yaml b/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_touch.yaml index 8c9f090..4c3dfd4 100644 --- a/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_touch.yaml +++ b/ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_touch.yaml @@ -262,7 +262,7 @@ script: - lambda: |- const uint8_t num_gangs = (sl_tx_model_gang->active_index().has_value()) ? (sl_tx_model_gang->active_index().value() + 1) : 0; - set_gang_count(num_gangs); + 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); From 5d5a3d3e778db937c4b7456a9bcdcf5476e5b2db Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Mon, 23 Dec 2024 04:37:53 +0100 Subject: [PATCH 6/6] Typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 49e53bb..4918684 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ TX Ultimate Easy uses Home Assistant's native Events system for reliable automat 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 refeer to our **[Events docs](docs/events.md)**. +For more details, please refer to our **[Events docs](docs/events.md)**. ### Device Configuration #### Relay Modes