Compare commits

...

129 Commits

Author SHA1 Message Date
GitHub Actions
e8470f56e4 Bump version to 2024.12.16 [skip-versioning] 2024-12-24 11:02:55 +00:00
Edward Firmo
2429c9d616 Merge pull request #70 from edwardtfn/swipe-log-messages
Fix swipe log messages
2024-12-24 12:02:45 +01:00
Edward Firmo
7a5a537847 Fix swipe log messages 2024-12-24 11:57:03 +01:00
GitHub Actions
2aa036dc0e Bump version to 2024.12.15 [skip-versioning] 2024-12-24 10:42:07 +00:00
Edward Firmo
802acdc476 Merge pull request #69 from edwardtfn/esphome-version
Add ESPHome Version sensor
2024-12-24 11:41:57 +01:00
Edward Firmo
37b2e93896 Sensor is diagnostic 2024-12-24 11:17:35 +01:00
Edward Firmo
695cca07a0 Add ESPHome Version sensor
And renames the TX Firmware, which resolves #66
2024-12-24 10:32:31 +01:00
GitHub Actions
f258b8f783 Bump version to 2024.12.14 [skip-versioning] 2024-12-24 09:06:47 +00:00
Edward Firmo
7e055e7737 Merge pull request #68 from edwardtfn/new-led-mapping-us-3gang
New LED mapping for US 3&4-Gang
2024-12-24 10:06:36 +01:00
Edward Firmo
9fec812b66 New LED mapping for 4-Gang US model 2024-12-24 09:59:54 +01:00
Edward Firmo
269ba89bd3 New LED mapping for US 3-Gang
Partially solves #67
2024-12-24 09:49:14 +01:00
GitHub Actions
ae87f025a3 Bump version to 2024.12.13 [skip-versioning] 2024-12-23 23:28:41 +00:00
Edward Firmo
303a3f1267 Merge pull request #64 from edwardtfn/speaker-with-ble-proxy
Add speaker to BLE Proxy add-on
2024-12-24 00:28:31 +01:00
Edward Firmo
a716e8e9cf Change media player fmt to msb 2024-12-24 00:22:52 +01:00
Edward Firmo
d77d761497 Add speaker to BLE Proxy add-on 2024-12-24 00:00:26 +01:00
GitHub Actions
ec528ec128 Bump version to 2024.12.12 [skip-versioning] 2024-12-23 17:52:46 +00:00
Edward Firmo
4ed98e533f Merge pull request #62 from edwardtfn/test-only-on-pull
Run test only on pull request or push to main
2024-12-23 18:52:35 +01:00
Edward Firmo
1ef73d5cd0 Remove paths-ignore 2024-12-23 18:49:50 +01:00
Edward Firmo
420225b6ba Run test only on pull request or push to main 2024-12-23 18:47:41 +01:00
GitHub Actions
8996cfbdf8 Bump version to 2024.12.11 [skip-versioning] 2024-12-23 17:39:57 +00:00
Edward Firmo
085250c471 Merge pull request #61 from edwardtfn/light-restore-state-on-boot
Restore light state on boot
2024-12-23 18:39:47 +01:00
Edward Firmo
6230e31323 Fix inconsistent restore mode variable usage
As suggested by CodeRabbitAI
2024-12-23 18:34:05 +01:00
Edward Firmo
248f7e9cd8 Use substitutions instead 2024-12-23 18:28:58 +01:00
Edward Firmo
6343e6eb4a Restore light state on boot
Trying to solve #47
2024-12-23 18:21:32 +01:00
GitHub Actions
226d5db7c8 Bump version to 2024.12.10 [skip-versioning] 2024-12-23 11:54:54 +00:00
Edward Firmo
dbde1da920 Merge pull request #60 from edwardtfn/buttons-action-fix-01
Fix relay toggle when button action is set to none
2024-12-23 12:54:43 +01:00
Edward Firmo
f2ff037c82 Add a bit more verbose logs 2024-12-23 11:59:26 +01:00
Edward Firmo
82af8b6687 Fix relay toggle when button action is set to none
Solves #59
2024-12-23 11:48:31 +01:00
GitHub Actions
73ecbba3b2 Bump version to 2024.12.9 [skip-versioning] 2024-12-23 03:43:28 +00:00
Edward Firmo
eb1a3954a9 Merge pull request #56 from edwardtfn/new-events
New event handler
2024-12-23 04:43:16 +01:00
Edward Firmo
5d5a3d3e77 Typo 2024-12-23 04:37:53 +01:00
Edward Firmo
f9e9243de5 Specify device when setting gang count 2024-12-23 04:31:16 +01:00
Edward Firmo
be6a4a51e2 Use set_gang_count 2024-12-23 04:24:50 +01:00
Edward Firmo
2a8255b788 Use long_press and not long_click 2024-12-23 04:16:28 +01:00
Edward Firmo
a00e15fa85 lint 2024-12-23 03:59:29 +01:00
Edward Firmo
4ea7f1ee57 New event handler
This rebuild the engine to send events to Home Assistant
2024-12-23 03:55:50 +01:00
GitHub Actions
bd4f6836c9 Bump version to 2024.12.8 [skip-versioning] 2024-12-23 00:14:23 +00:00
Edward Firmo
98ea8810f8 Merge pull request #55 from edwardtfn/relay-on-light-mode
Fix relay on display as light mode
2024-12-23 01:14:09 +01:00
Edward Firmo
552b83f065 Re-add button ids on substitutions 2024-12-23 01:03:51 +01:00
Edward Firmo
ee6f565447 Change refresh to 5min 2024-12-23 00:59:17 +01:00
Edward Firmo
aa4e27ec35 Merge branch 'relay-on-light-mode' of https://github.com/edwardtfn/TX-Ultimate-Easy into relay-on-light-mode 2024-12-23 00:53:37 +01:00
Edward Firmo
8a509cedc8 Point to latest 2024-12-23 00:52:59 +01:00
Edward Firmo
ddea93af6a Merge branch 'main' into relay-on-light-mode 2024-12-23 00:50:29 +01:00
Edward Firmo
dc99319397 Fix relay id on log 2024-12-23 00:46:06 +01:00
Edward Firmo
5ae45fff63 Fix relay on display as light mode
Solves #28
2024-12-23 00:41:51 +01:00
GitHub Actions
bbbaeeb0d4 Bump version to 2024.12.7 [skip-versioning] 2024-12-22 23:02:49 +00:00
Edward Firmo
a9f82d958f Merge pull request #54 from edwardtfn/event-based-automation-docs
Event based automation docs
2024-12-23 00:02:40 +01:00
Edward Firmo
c07e4f195a CodeRabbitAI 2024-12-22 23:55:18 +01:00
Edward Firmo
f1f545198b CodeRabbitAI 2024-12-22 23:47:03 +01:00
Edward Firmo
d87b86bfca CodeRabbitAI 2024-12-22 23:41:02 +01:00
Edward Firmo
f11840d2bc markdownlint 2024-12-22 23:23:22 +01:00
Edward Firmo
42afe71365 Add event based automation overview
Helps with #51
2024-12-22 23:20:39 +01:00
GitHub Actions
09e9d340fc Bump version to 2024.12.6 [skip-versioning] 2024-12-22 16:41:40 +00:00
Edward Firmo
7850d16aeb Push tag before setting latest and stable 2024-12-22 17:40:45 +01:00
Edward Firmo
1f2e60e7db Merge pull request #53 from edwardtfn/use-main-as-ref
Use `main` as reference for remote package
2024-12-22 17:23:39 +01:00
Edward Firmo
dd25e5dbba Use bump_version.sh from folder versioning 2024-12-22 17:19:59 +01:00
Edward Firmo
75f4245fe1 No need another versioning action 2024-12-22 17:16:09 +01:00
Edward Firmo
3b7f811876 Tag latest and stable only after versioning 2024-12-22 17:04:52 +01:00
Edward Firmo
d403bc2aa9 CodeRabbitAI - Remove duplicated badge reference 2024-12-22 16:41:21 +01:00
Edward Firmo
5d780f162e Add version badge 2024-12-22 16:37:05 +01:00
Edward Firmo
0e53dfd3cd CodeRabbitAI 2024-12-22 16:26:49 +01:00
Edward Firmo
23b633cdcb Run all tests in parallel
Let's see if this saves some time.
2024-12-22 16:20:51 +01:00
Edward Firmo
b1187332fb Ensure latest and stable tags are updated on push to main 2024-12-22 16:17:07 +01:00
Edward Firmo
669cc2f2c2 Use main as reference for remote package 2024-12-22 16:03:39 +01:00
GitHub Actions
e5d941c460 Bump version to 2024.12.4 [skip-versioning] 2024-12-22 01:12:50 +00:00
Edward Firmo
9b134a786a Merge pull request #50 from edwardtfn/swipe-priority
Rebuild Button click engine
2024-12-22 02:12:39 +01:00
Edward Firmo
be0fc353f6 Simplify relay handler 2024-12-22 02:03:35 +01:00
Edward Firmo
fbc5cb79cc Reduce BUTTON_MULTI_CLICK_DELAY to 250ms 2024-12-22 01:46:28 +01:00
Edward Firmo
c65acc3298 Pass parameters to button_click_event 2024-12-22 01:37:07 +01:00
Edward Firmo
4d8107faf2 Remove relay from binary sensor 2024-12-22 01:15:26 +01:00
Edward Firmo
65bbd901b1 Clean-up get_button_from_position 2024-12-21 23:32:15 +01:00
Edward Firmo
8c610a406a Log long-press from component
If this works fine, it could replace this part on the new implementation.
2024-12-21 23:17:42 +01:00
Edward Firmo
696e3bf28d Component to provide button number 2024-12-21 23:10:16 +01:00
Edward Firmo
5ae4564e6a CodeRabbitAI Nitpick 2 2024-12-21 22:08:19 +01:00
Edward Firmo
857c43940d CodeRabbitAI Nitpick 2024-12-21 21:54:54 +01:00
Edward Firmo
8668fe8dc9 Fix another bad reference 2024-12-21 21:29:05 +01:00
Edward Firmo
976a903118 Fix references 2024-12-21 21:25:29 +01:00
Edward Firmo
35cc0c4a8e Reorganize scripts for better clarity 2024-12-21 21:18:54 +01:00
Edward Firmo
5c4581563e Rebuild Button click engine
The native engine from ESPHome cannot be used here as a button press event is triggered on touch, which would trigger the click even on swipe.
Other projects solved this by tracking only single click and only at release, so we decided to implement this in a different way, so we can handle multiple or long-clicks also.
This should finally solve #14, but some test is required to ensure nothing else was broken.
2024-12-21 21:14:41 +01:00
GitHub Actions
7f1c362a50 Bump version to 2024.12.3 [skip-versioning] 2024-12-21 17:09:47 +00:00
Edward Firmo
cf3018c95c Merge pull request #49 from edwardtfn/new-versioning-03
Fix verison validation
2024-12-21 18:09:37 +01:00
Edward Firmo
360ae3123a Update bump_version.sh 2024-12-21 18:06:00 +01:00
Edward Firmo
6767b5e765 Fix version validation 2024-12-21 18:00:46 +01:00
Edward Firmo
d5e5ebb3d6 Fix version format 2024-12-21 17:52:33 +01:00
Edward Firmo
46c04eb992 Merge pull request #46 from edwardtfn/new-versioning-03
Rollback to the last working point
2024-12-21 17:50:34 +01:00
Edward Firmo
8558bc3650 Merge branch 'main' into new-versioning-03 2024-12-21 17:49:58 +01:00
Edward Firmo
f32e2eee4f Add quotes around file path in cat command
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2024-12-21 17:14:00 +01:00
Edward Firmo
5a993165cd Rollback to the last working point 2024-12-21 14:54:47 +01:00
Edward Firmo
d04c2aff2f Merge pull request #45 from edwardtfn/new-versioning-02
Use an automation branch
2024-12-21 14:14:00 +01:00
Edward Firmo
2d79ee42c7 Quote variables and url 2024-12-21 14:05:37 +01:00
Edward Firmo
3f4fc7a505 Quote GitHub token in push command
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2024-12-21 13:55:26 +01:00
Edward Firmo
be23a5a0fd Quote variables in temporary branch creation
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2024-12-21 13:54:51 +01:00
Edward Firmo
a23a2db352 Fix invalid YAML structure in push trigger
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2024-12-21 13:35:12 +01:00
Edward Firmo
4e73a11528 Use an automation branch 2024-12-21 13:27:58 +01:00
Edward Firmo
3c98d81bb7 Merge pull request #44 from edwardtfn/new-versioning-01
No leading zero on versions
2024-12-21 12:31:30 +01:00
Edward Firmo
e63447984d Remove duplicated version validation 2024-12-21 12:26:05 +01:00
Edward Firmo
1f1a8049e6 No leading zero on versions 2024-12-21 12:23:32 +01:00
Edward Firmo
0dddc0747b Merge pull request #43 from edwardtfn/test-new-versioning-04
Describe file
2024-12-21 11:55:06 +01:00
Edward Firmo
86d1513c6a Describe file 2024-12-21 11:54:42 +01:00
GitHub Actions
ac4d583b64 Bump version to 2024.12.01 2024-12-21 10:37:03 +00:00
Edward Firmo
15830d4134 Merge pull request #42 from edwardtfn/test-new-versioning-03
Fix repo name
2024-12-21 11:27:19 +01:00
Edward Firmo
0c19ca1205 Fix repo name 2024-12-21 11:26:57 +01:00
Edward Firmo
2d676036dc Merge pull request #41 from edwardtfn/test-new-versioning-02
New approach to GitHub tokens
2024-12-21 11:20:35 +01:00
Edward Firmo
c8ffa9e224 New approach to GitHub tokens 2024-12-21 11:20:13 +01:00
Edward Firmo
1406ada53a Merge pull request #40 from edwardtfn/test-new-versioning
Testing new versioning
2024-12-21 11:13:58 +01:00
Edward Firmo
f02f90c3fa Testing new versioning 2024-12-21 11:05:40 +01:00
Edward Firmo
f6169e3ea2 Merge branch 'main' of https://github.com/edwardtfn/TX-Ultimate-Easy 2024-12-21 11:01:47 +01:00
Edward Firmo
6774a1ac18 Set initial version number 2024-12-21 11:01:01 +01:00
Edward Firmo
21720d8ba3 Merge pull request #39 from edwardtfn/dev
New versioning
2024-12-21 10:58:41 +01:00
Edward Firmo
7727c968db Merge branch 'dev' of https://github.com/edwardtfn/TX-Ultimate-Easy into dev 2024-12-21 10:33:54 +01:00
Edward Firmo
dc9e19d43c Add section about version validation 2024-12-21 10:33:36 +01:00
Edward Firmo
737343e395 Add fetch-depth: 0 to checkout action
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2024-12-21 10:31:23 +01:00
Edward Firmo
5569260f92 Update checkout action version
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2024-12-21 10:30:28 +01:00
Edward Firmo
04ca752c3b Add error handling for git operations
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2024-12-21 10:29:46 +01:00
Edward Firmo
23436428a4 Add error handling for invalid version format
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2024-12-21 10:29:12 +01:00
Edward Firmo
26a244cbed Fix potential overflow in sequence number
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2024-12-21 10:28:14 +01:00
Edward Firmo
ce8b4e700e Merge pull request #38 from edwardtfn/0.0.5
Clean up LED files & new versioning
2024-12-21 10:18:49 +01:00
Edward Firmo
35bf4bc0ec New versioning 2024-12-21 10:17:32 +01:00
Edward Firmo
ee8ff66add Removed LED auxiliary files
Using YAML anchors instead.
It makes it cleaner and easier to understand.
2024-12-21 08:54:41 +01:00
Edward Firmo
96db05cc34 Fix typo 2024-12-21 00:24:02 +01:00
Edward Firmo
61a5d67082 Merge pull request #36 from edwardtfn/dev
v0.0.4 - Bug fixes
2024-12-21 00:17:12 +01:00
Edward Firmo
ce9aefc7fe Merge pull request #37 from edwardtfn/0.0.4
CodeRabbitAI
2024-12-21 00:08:47 +01:00
Edward Firmo
1d38ac282c Merge pull request #35 from edwardtfn/0.0.4
Wrap-up
2024-12-20 23:37:50 +01:00
Edward Firmo
2ae4d2abe8 Merge pull request #34 from edwardtfn/0.0.4
Rebuilt relay status indicator engine
2024-12-20 19:41:14 +01:00
Edward Firmo
3543c0c088 Merge pull request #33 from edwardtfn/0.0.4
Remove references to Blueprint in the README
2024-12-20 02:36:46 +01:00
Edward Firmo
242325e556 Merge pull request #32 from edwardtfn/0.0.4
v0.0.4 - Bug fixes
2024-12-20 02:18:34 +01:00
Edward Firmo
f65f3a930c Merge pull request #26 from edwardtfn/dev
Fix toggle with swipe
2024-07-26 08:35:46 +02:00
Edward Firmo
0bf52a28c0 Merge pull request #25 from edwardtfn/dev
Support ESPHome v2024.6.0
2024-06-20 00:29:03 +02:00
Edward Firmo
976814eb58 Merge pull request #11 from edwardtfn/dev
First workable version
2024-05-29 22:23:15 +02:00
29 changed files with 1585 additions and 686 deletions

View File

@@ -1,32 +0,0 @@
---
name: Update Tags
# yamllint disable-line rule:truthy
on:
release:
types: [published]
jobs:
update-tags:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@main
with:
fetch-depth: '0'
- name: Set up Git
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
- name: Move and push stable tag
run: |
git tag -f stable ${{ github.event.release.tag_name }}
git push -f origin stable
- name: Move and push latest tag
run: |
git tag -f latest ${{ github.event.release.tag_name }}
git push -f origin latest
...

View File

@@ -1,8 +1,7 @@
--- ---
name: Validate ESPHome name: Validate ESPHome (Latest)
# yamllint disable-line rule:truthy on: # yamllint disable-line rule:truthy
on:
workflow_dispatch: workflow_dispatch:
concurrency: concurrency:
@@ -30,8 +29,6 @@ jobs:
build_basic: build_basic:
name: Basic name: Basic
needs:
- code_scan
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@main - uses: actions/checkout@main
@@ -39,10 +36,10 @@ jobs:
uses: esphome/build-action@main uses: esphome/build-action@main
with: with:
yaml-file: ".test/esphome_ard_basic.yaml" yaml-file: ".test/esphome_ard_basic.yaml"
version: latest
build_bluetooth_proxy_4: build_bluetooth_proxy_4:
name: Bluetooth Proxy (IDF) name: Bluetooth Proxy (IDF)
needs: build_basic
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@main - uses: actions/checkout@main
@@ -50,10 +47,10 @@ jobs:
uses: esphome/build-action@main uses: esphome/build-action@main
with: with:
yaml-file: ".test/esphome_idf_bluetooth_proxy.yaml" yaml-file: ".test/esphome_idf_bluetooth_proxy.yaml"
version: latest
build_bluetooth_proxy_53: build_bluetooth_proxy_53:
name: Bluetooth Proxy (IDF v5.3) name: Bluetooth Proxy (IDF v5.3)
needs: build_basic
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@main - uses: actions/checkout@main
@@ -61,4 +58,5 @@ jobs:
uses: esphome/build-action@main uses: esphome/build-action@main
with: with:
yaml-file: ".test/esphome_idf53_bluetooth_proxy.yaml" yaml-file: ".test/esphome_idf53_bluetooth_proxy.yaml"
version: latest
... ...

View File

@@ -1,8 +1,7 @@
--- ---
name: Validate ESPHome (Beta) name: Validate ESPHome (Beta)
# yamllint disable-line rule:truthy on: # yamllint disable-line rule:truthy
on:
push: push:
paths: paths:
- "*.yaml" - "*.yaml"
@@ -12,6 +11,8 @@ on:
- "*.c" - "*.c"
- "*.cpp" - "*.cpp"
- "*.py" - "*.py"
branches:
- main
pull_request: pull_request:
paths: paths:
- "*.yaml" - "*.yaml"
@@ -48,8 +49,6 @@ jobs:
build_basic: build_basic:
name: Basic name: Basic
needs:
- code_scan
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@main - uses: actions/checkout@main
@@ -61,7 +60,6 @@ jobs:
build_bluetooth_proxy_4: build_bluetooth_proxy_4:
name: Bluetooth Proxy (IDF) name: Bluetooth Proxy (IDF)
needs: build_basic
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@main - uses: actions/checkout@main
@@ -73,7 +71,6 @@ jobs:
build_bluetooth_proxy_53: build_bluetooth_proxy_53:
name: Bluetooth Proxy (IDF v5.3) name: Bluetooth Proxy (IDF v5.3)
needs: build_basic
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@main - uses: actions/checkout@main

106
.github/workflows/versioning.yml vendored Normal file
View File

@@ -0,0 +1,106 @@
# This GitHub Actions workflow handles version bumping and tag updates.
# It can be triggered either by:
# 1. Pushing to main branch - automatically bumps version and updates tags
# 2. Manual dispatch - allows independent control over stable and latest tags
---
name: Version and Tags
on: # yamllint disable-line rule:truthy
push:
branches:
- main
paths-ignore:
- '**/VERSION'
- '**/VERSION_YAML'
workflow_dispatch:
inputs:
update_stable:
description: "Update stable tag?"
required: true
default: false
type: boolean
update_latest:
description: "Update latest tag?"
required: true
default: false
type: boolean
jobs:
version-and-tag:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Git
run: |
git config user.name "GitHub Actions"
git config user.email "actions@github.com"
- name: Bump version
run: |
chmod +x ./versioning/bump_version.sh
./versioning/bump_version.sh
- name: Push Changes and Tags
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
git push origin main
git push origin --tags --force
- name: Update stable tag
if: |
success() && (
github.event_name == 'workflow_dispatch' && inputs.update_stable ||
github.event_name == 'push'
)
run: |
# Verify version bump was successful
if [ ! -f "./versioning/VERSION" ]; then
echo "Error: VERSION file not found. Version bump may have failed."
exit 1
fi
# Backup existing tag
if git rev-parse --verify stable >/dev/null 2>&1; then
OLD_STABLE=$(git rev-parse stable)
echo "Backing up current stable tag ($OLD_STABLE)"
fi
# Update tag
NEW_VERSION=$(cat ./versioning/VERSION)
echo "Updating stable tag to $NEW_VERSION"
git tag -fa stable -m "Update stable tag"
git push origin stable --force
- name: Update latest tag
if: |
success() && (
github.event_name == 'workflow_dispatch' && inputs.update_latest ||
github.event_name == 'push'
)
run: |
# Verify version bump was successful
if [ ! -f "./versioning/VERSION" ]; then
echo "Error: VERSION file not found. Version bump may have failed."
exit 1
fi
# Backup existing tag
if git rev-parse --verify latest >/dev/null 2>&1; then
OLD_LATEST=$(git rev-parse latest)
echo "Backing up current latest tag ($OLD_LATEST)"
fi
# Update tag
NEW_VERSION=$(cat ./versioning/VERSION)
echo "Updating latest tag to $NEW_VERSION"
git tag -fa latest -m "Update latest tag"
git push origin latest --force
...

View File

@@ -1,6 +1,6 @@
--- ---
packages: packages:
basic_package: !include ../TX-Ultimate-Easy-ESPHome.yaml # Basic package basic_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml # Basic package
esp32: esp32:
framework: framework:

View File

@@ -1,6 +1,6 @@
--- ---
packages: packages:
basic_package: !include ../TX-Ultimate-Easy-ESPHome.yaml # Core package core_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml
addon_bluetooth_proxy: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_addon_ble_proxy.yaml addon_bluetooth_proxy: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_addon_ble_proxy.yaml
esp32: esp32:

View File

@@ -1,5 +1,5 @@
--- ---
packages: packages:
basic_package: !include ../TX-Ultimate-Easy-ESPHome.yaml # Core package core_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml
addon_bluetooth_proxy: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_addon_ble_proxy.yaml addon_bluetooth_proxy: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_addon_ble_proxy.yaml
... ...

BIN
Assets/Logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 KiB

View File

@@ -11,6 +11,27 @@
##### - For normal system use, modifications to this file are NOT required. ##### ##### - For normal system use, modifications to this file are NOT required. #####
#################################################################################################### ####################################################################################################
--- ---
substitutions:
# RTTTL format: name:d=duration,o=octave,b=tempo:notes
# d=32 (32nd note), o=5 (octave 5), b=100 (tempo 100)
tone_volume_change: "scale_up:d=32,o=5,b=100:c,c#,d#,e,f#,g#,a#,b" # Use "none" to disable sound
api:
actions:
- action: rtttl_play
variables:
# The RTTTL string for the melody to be played.
# It should follow the RTTTL format, including the melody's name,
# default settings, and a sequence of notes.
tone: string
then:
- lambda: |-
rtttl_speaker->stop();
if (rtttl_speaker_gain->state > 0) {
ESP_LOGI("api", "Play tone: '%s'", tone.c_str());
rtttl_speaker->play(tone.c_str());
}
bluetooth_proxy: bluetooth_proxy:
esp32: esp32:
@@ -33,17 +54,54 @@ esphome:
build_flags: build_flags:
- -D TX_ULTIMATE_EASY_ADDON_BLE_PROXY - -D TX_ULTIMATE_EASY_ADDON_BLE_PROXY
i2s_audio: !remove
light: light:
- id: !extend light_full - id: !extend light_full
platform: esp32_rmt_led_strip platform: esp32_rmt_led_strip
rgb_order: GRB rgb_order: GRB
rmt_channel: 0 rmt_channel: 1
chipset: ws2812 chipset: ws2812
type: !remove type: !remove
variant: !remove variant: !remove
max_refresh_rate: 33ms max_refresh_rate: 33ms
use_psram: true
media_player: !remove media_player: !remove
number:
- id: rtttl_speaker_gain
name: Sound - Volume
platform: template
max_value: 100
min_value: 0
step: 1
initial_value: 100
unit_of_measurement: "%"
internal: false
disabled_by_default: true
entity_category: config
device_class: sound_pressure
restore_value: true
optimistic: true
set_action:
then:
- lambda: |-
rtttl_speaker->set_gain((100-(x/10.0f))/100.0f);
std::string tone_volume_change = "${tone_volume_change}";
// Play sound if tone_volume_change is not "none"
if (x > 0 and !tone_volume_change.empty() and tone_volume_change != "none")
rtttl_speaker->play(tone_volume_change);
rtttl_speaker->dump_config();
rtttl:
- id: rtttl_speaker
speaker: mp_speaker
speaker:
- id: mp_speaker
platform: i2s_audio
dac_type: external
i2s_dout_pin: GPIO15
i2s_audio_id: if_i2s_audio
i2s_comm_fmt: stand_msb
channel: mono
... ...

View File

@@ -15,11 +15,7 @@ substitutions:
name: tx-ultimate-easy name: tx-ultimate-easy
friendly_name: TX Ultimate Easy friendly_name: TX Ultimate Easy
latitude: '0' <<: !include ../versioning/VERSION_YAML
longitude: '0'
zone_home: 'zone.home'
version: '0.0.4'
TX_MODEL_FORMAT_EU_TEXT: "EU (Square, T5-xC-86)" TX_MODEL_FORMAT_EU_TEXT: "EU (Square, T5-xC-86)"
TX_MODEL_FORMAT_US_TEXT: "US (Rectangle, T5-xC-120)" TX_MODEL_FORMAT_US_TEXT: "US (Rectangle, T5-xC-120)"
@@ -31,7 +27,6 @@ substitutions:
packages: packages:
# yamllint disable rule:colons # 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_buttons: !include TX-Ultimate-Easy-ESPHome_core_hw_buttons.yaml
core_hw_leds: !include TX-Ultimate-Easy-ESPHome_core_hw_leds.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 core_hw_relays: !include TX-Ultimate-Easy-ESPHome_core_hw_relays.yaml
@@ -40,6 +35,12 @@ packages:
core_hw_vibration: !include TX-Ultimate-Easy-ESPHome_core_hw_vibration.yaml core_hw_vibration: !include TX-Ultimate-Easy-ESPHome_core_hw_vibration.yaml
# yamllint enable rule:colons # yamllint enable rule:colons
api:
id: api_server
on_client_connected:
then:
- script.execute: publish_device_info
button: button:
- id: bt_restart - id: bt_restart
name: Restart name: Restart
@@ -74,25 +75,50 @@ esphome:
then: then:
- script.execute: boot_done - script.execute: boot_done
globals:
- id: is_us_model
type: bool
restore_value: true
initial_value: 'false'
- id: gang_count
type: uint8_t
restore_value: true
initial_value: '0'
improv_serial: improv_serial:
id: serial_improv id: serial_improv
logger: logger:
level: INFO level: DEBUG
ota: ota:
platform: esphome platform: esphome
psram: psram:
mode: octal
speed: 40MHz
script: 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 - id: boot_done
mode: restart mode: restart
then: then:
- script.execute: - script.execute:
id: send_event_to_ha id: api_send_ha_event_boot
component: boot type: done
event: done
- id: boot_initialize - id: boot_initialize
mode: restart mode: restart
@@ -102,9 +128,8 @@ script:
# - HW Relays # - HW Relays
# - HW Touch # - HW Touch
- script.execute: - script.execute:
id: send_event_to_ha id: api_send_ha_event_boot
component: boot type: start
event: start
- id: boot_sequence - id: boot_sequence
mode: restart mode: restart
@@ -132,6 +157,11 @@ select:
entity_category: config entity_category: config
disabled_by_default: false disabled_by_default: false
icon: mdi:tablet-cellphone icon: mdi:tablet-cellphone
on_value:
then:
- lambda: |-
id(is_us_model) = (x == "${TX_MODEL_FORMAT_US_TEXT}");
ESP_LOGI("core", "New model selected: %s", id(is_us_model) ? "US" : "EU");
- id: sl_tx_model_gang - id: sl_tx_model_gang
name: Model (Gang) name: Model (Gang)
@@ -148,10 +178,22 @@ select:
entity_category: config entity_category: config
disabled_by_default: false disabled_by_default: false
icon: mdi:dip-switch icon: mdi:dip-switch
on_value:
then:
- lambda: |-
id(gang_count) = static_cast<uint8_t>(i) + 1;
ESP_LOGI("core", "New model selected: %" PRIu8 "-%s", id(gang_count), id(gang_count) > 1 ? "Gangs" : "Gang");
tx_ultimate->set_gang_count(id(gang_count));
text_sensor: text_sensor:
- id: esphome_fw_version
name: ESPHome Version
platform: version
entity_category: diagnostic
internal: false
- id: tx_fw_version - id: tx_fw_version
name: Firmware version name: TX Ultimate Easy Firmware Version
platform: template platform: template
entity_category: diagnostic entity_category: diagnostic
icon: mdi:tag-text-outline icon: mdi:tag-text-outline

View File

@@ -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();
...

View File

@@ -20,111 +20,59 @@ substitutions:
BUTTON_3_ACTION_TEXT: "Relay 3 (toggle)" BUTTON_3_ACTION_TEXT: "Relay 3 (toggle)"
BUTTON_4_ACTION_TEXT: "Relay 4 (toggle)" BUTTON_4_ACTION_TEXT: "Relay 4 (toggle)"
binary_sensor: BUTTON_CLICK_MIN_LENGTH: '50' # The minimum duration the click should last, in msec
- id: bs_button_1 BUTTON_CLICK_MAX_LENGTH: '350' # The maximum duration the click should last, in msec
name: Button 1 BUTTON_MULTI_CLICK_DELAY: '250' # The time to wait for another click, in msec
icon: mdi:gesture-tap-box BUTTON_PRESS_TIMEOUT: '10000' # Ignore if button is pressed for longer than this time, in msec
internal: false BUTTON_LONG_PRESS_DELAY: '800' # The time to wait to consider a long press, in msec
platform: template
on_click:
then:
- script.execute:
id: button_action
component: bs_button_1
event: click
on_double_click:
then:
- script.execute:
id: button_action
component: bs_button_1
event: double_click
on_multi_click:
- timing: &long_click-timing
- ON for at least 0.8s
invalid_cooldown: ${invalid_cooldown}
then:
- script.execute:
id: button_action
component: bs_button_1
event: long_click
- id: bs_button_2 # Button numbers constants
BUTTON_1_ID: '1'
BUTTON_2_ID: '2'
BUTTON_3_ID: '3'
BUTTON_4_ID: '4'
binary_sensor:
- &binary_sensor_button_base
id: bs_button_2
name: Button 2 name: Button 2
icon: mdi:gesture-tap-box icon: mdi:gesture-tap-box
internal: true
platform: template platform: template
on_click: internal: true
then:
- script.execute:
id: button_action
component: bs_button_2
event: click
on_double_click:
then:
- script.execute:
id: button_action
component: bs_button_2
event: double_click
on_multi_click:
- timing: *long_click-timing
invalid_cooldown: ${invalid_cooldown}
then:
- script.execute:
id: button_action
component: bs_button_2
event: long_click
- id: bs_button_3 - id: bs_button_3
name: Button 3 name: Button 3
icon: mdi:gesture-tap-box <<: *binary_sensor_button_base
internal: true
platform: template
on_click:
then:
- script.execute:
id: button_action
component: bs_button_3
event: click
on_double_click:
then:
- script.execute:
id: button_action
component: bs_button_3
event: double_click
on_multi_click:
- timing: *long_click-timing
invalid_cooldown: ${invalid_cooldown}
then:
- script.execute:
id: button_action
component: bs_button_3
event: long_click
- id: bs_button_4 - id: bs_button_4
name: Button 4 name: Button 4
icon: mdi:gesture-tap-box <<: *binary_sensor_button_base
internal: true
platform: template - id: bs_button_1
on_click: name: Button 1
then: internal: false
- script.execute: <<: *binary_sensor_button_base
id: button_action
component: bs_button_4 globals:
event: click - id: button_press_button
on_double_click: type: uint8_t
then: restore_value: false
- script.execute: initial_value: '0'
id: button_action
component: bs_button_4 - id: button_press_position
event: double_click type: uint8_t
on_multi_click: restore_value: false
- timing: *long_click-timing initial_value: '0'
invalid_cooldown: ${invalid_cooldown}
then: - id: button_press_start_time
- script.execute: type: uint32_t
id: button_action restore_value: false
component: bs_button_4 initial_value: '0'
event: long_click
- id: click_counter
type: uint8_t
restore_value: false
initial_value: '0'
script: script:
- id: !extend boot_initialize - id: !extend boot_initialize
@@ -160,11 +108,89 @@ script:
- id: button_action - id: button_action
mode: parallel mode: parallel
parameters: parameters:
component: string button: uint8_t
event: string action: string
then: # There's nothing here so far count: uint8_t
# Extended by: then:
# - 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 %" 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(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: uint8_t
click_count: uint8_t
then:
- delay:
milliseconds: ${BUTTON_MULTI_CLICK_DELAY}
- lambda: |-
std::string event_name;
if (click_count == 1) event_name = "click";
else if (click_count == 2) event_name = "double_click";
else event_name = "multiple_click";
button_action->execute(button, event_name.c_str(), click_count);
- id: buttons_release - id: buttons_release
mode: restart mode: restart
@@ -187,42 +213,65 @@ script:
then: then:
- script.execute: - script.execute:
id: touch_on_press_buttons id: touch_on_press_buttons
touch_x: !lambda return touch_x; button: !lambda return button;
position: !lambda return position;
- id: touch_on_press_buttons - id: touch_on_press_buttons
mode: restart mode: restart
parameters: parameters:
touch_x: uint8_t button: uint8_t
position: uint8_t
then: then:
- lambda: |- - lambda: |-
auto model_index = sl_tx_model_gang->active_index(); id(button_press_start_time) = millis();
if (model_index.has_value()) { id(button_press_button) = button;
uint8_t model_idx = model_index.value() + 1; // Update counters
switch (model_idx) { if (id(button_press_position) == position) {
case 1: // 1 Gang id(click_counter)++;
} else {
id(click_counter) = 1;
id(button_press_position) = position;
}
// Update binary sensor
switch (button) {
case 1:
bs_button_1->publish_state(true); bs_button_1->publish_state(true);
break; break;
case 2: // 2 Gang case 2:
if (touch_x <= 5) bs_button_1->publish_state(true); bs_button_2->publish_state(true);
else bs_button_2->publish_state(true);
break; break;
case 3: // 3 Gang case 3:
if (touch_x <= 3) bs_button_1->publish_state(true); bs_button_3->publish_state(true);
else if (touch_x <= 7) bs_button_2->publish_state(true);
else bs_button_3->publish_state(true);
break; break;
case 4: // 4 Gang case 4:
if (touch_x <= 2) bs_button_1->publish_state(true); bs_button_4->publish_state(true);
else if (touch_x <= 5) bs_button_2->publish_state(true);
else if (touch_x <= 8) bs_button_3->publish_state(true);
else bs_button_4->publish_state(true);
break; break;
} }
}
- id: !extend touch_on_release - id: !extend touch_on_release
then: then:
- script.execute: buttons_release - lambda: |-
uint32_t current_time = millis();
buttons_release->execute();
if (id(button_press_start_time) > 0 and
id(button_press_start_time) < current_time) {
uint32_t press_duration = current_time - id(button_press_start_time);
// Handle overflow (optional, since it's unlikely to happen here)
ESP_LOGI("core_hw_buttons", "Button press duration: %" PRIu32 " ms", press_duration);
if (press_duration < ${BUTTON_CLICK_MIN_LENGTH}) {
ESP_LOGW("core_hw_buttons", "Ignoring button press (too short)");
} else if (press_duration >= ${BUTTON_CLICK_MIN_LENGTH} and
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_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");
}
} else {
ESP_LOGW("core_hw_buttons", "Press event timestamp not recorded yet");
}
id(button_press_start_time) = 0;
- id: !extend touch_swipe_left - id: !extend touch_swipe_left
then: then:

View File

@@ -25,6 +25,11 @@ substitutions:
LIGHT_TRANSITION_TURN_OFF: '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_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_RELAYS_RESTORE_MODE: RESTORE_DEFAULT_OFF
globals: globals:
- id: gb_lights_1 - id: gb_lights_1
type: std::vector<light::LightState*> type: std::vector<light::LightState*>
@@ -34,27 +39,7 @@ globals:
restore_value: false restore_value: false
light: light:
- id: light_output_1 # These lights are controlling the LEDs on the device
name: Light output 1
internal: true
platform: binary
output: output_relay_1
- id: light_output_2
name: Light output 2
internal: true
platform: binary
output: output_relay_2
- id: light_output_3
name: Light output 3
internal: true
platform: binary
output: output_relay_3
- id: light_output_4
name: Light output 4
internal: true
platform: binary
output: output_relay_4
- id: light_full - id: light_full
name: Light - All name: Light - All
internal: true internal: true
@@ -64,12 +49,54 @@ light:
# method: esp32_rmt # method: esp32_rmt
num_leds: 32 num_leds: 32
pin: GPIO13 pin: GPIO13
restore_mode: ${LIGHT_FULL_RESTORE_MODE}
- id: light_eu # Those lights are available based on the model selections
- &light_partition_with_effects
id: light_eu
name: Light name: Light
platform: partition
default_transition_length: ${default_transition_length}
internal: true internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml restore_mode: ${LIGHT_SIDES_RESTORE_MODE}
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_effects.yaml effects:
- addressable_rainbow:
name: "Rainbow"
- addressable_rainbow:
name: "Rainbow - Fast"
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: segments:
- id: light_full - id: light_full
from: 0 from: 0
@@ -77,20 +104,17 @@ light:
- id: light_us - id: light_us
name: Light name: Light
internal: true <<: *light_partition_with_effects
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_effects.yaml
segments: segments:
- id: light_full - id: light_full
from: 0 from: 0
to: 31 to: 31
# Those lights are available based on the model selections - &light_partition_with_effects_disabled
- id: light_eu_bottom id: light_eu_bottom
name: Light - Bottom name: Light - Bottom
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_internal.yaml disabled_by_default: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml <<: *light_partition_with_effects
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_effects.yaml
segments: segments:
- id: light_full - id: light_full
from: 6 from: 6
@@ -98,9 +122,7 @@ light:
reversed: true reversed: true
- id: light_eu_left - id: light_eu_left
name: Light - Left name: Light - Left
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_internal.yaml <<: *light_partition_with_effects_disabled
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_effects.yaml
segments: segments:
- id: light_full - id: light_full
from: 13 from: 13
@@ -108,9 +130,7 @@ light:
reversed: true reversed: true
- id: light_eu_right - id: light_eu_right
name: Light - Right name: Light - Right
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_internal.yaml <<: *light_partition_with_effects_disabled
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_effects.yaml
segments: segments:
- id: light_full - id: light_full
from: 27 from: 27
@@ -122,9 +142,7 @@ light:
reversed: false reversed: false
- id: light_eu_top - id: light_eu_top
name: Light - Top name: Light - Top
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_internal.yaml <<: *light_partition_with_effects_disabled
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_effects.yaml
segments: segments:
- id: light_full - id: light_full
from: 20 from: 20
@@ -132,9 +150,7 @@ light:
reversed: false reversed: false
- id: light_us_bottom - id: light_us_bottom
name: Light - Bottom name: Light - Bottom
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_internal.yaml <<: *light_partition_with_effects_disabled
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_effects.yaml
segments: segments:
- id: light_full - id: light_full
from: 9 from: 9
@@ -142,9 +158,7 @@ light:
reversed: true reversed: true
- id: light_us_left - id: light_us_left
name: Light - Left name: Light - Left
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_internal.yaml <<: *light_partition_with_effects_disabled
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_effects.yaml
segments: segments:
- id: light_full - id: light_full
from: 15 from: 15
@@ -152,9 +166,7 @@ light:
reversed: true reversed: true
- id: light_us_right - id: light_us_right
name: Light - Right name: Light - Right
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_internal.yaml <<: *light_partition_with_effects_disabled
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_effects.yaml
segments: segments:
- id: light_full - id: light_full
from: 31 from: 31
@@ -166,444 +178,401 @@ light:
reversed: false reversed: false
- id: light_us_top - id: light_us_top
name: Light - Top name: Light - Top
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_internal.yaml <<: *light_partition_with_effects_disabled
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_effects.yaml
segments: segments:
- id: light_full - id: light_full
from: 25 from: 25
to: 30 to: 30
reversed: false reversed: false
- id: light_00 - &light_partition_individual_led
id: light_00
name: Light - LED 00 name: Light - LED 00
platform: partition
disabled_by_default: true disabled_by_default: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml default_transition_length: ${default_transition_length}
restore_mode: ${LIGHT_INDIVIDUAL_RESTORE_MODE}
segments: segments:
- id: light_full - id: light_full
from: 0 from: 0
to: 0 to: 0
- id: light_01 - id: light_01
name: Light - LED 01 name: Light - LED 01
disabled_by_default: true <<: *light_partition_individual_led
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 1 from: 1
to: 1 to: 1
- id: light_02 - id: light_02
name: Light - LED 02 name: Light - LED 02
disabled_by_default: true <<: *light_partition_individual_led
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 2 from: 2
to: 2 to: 2
- id: light_03 - id: light_03
name: Light - LED 03 name: Light - LED 03
disabled_by_default: true <<: *light_partition_individual_led
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 3 from: 3
to: 3 to: 3
- id: light_04 - id: light_04
name: Light - LED 04 name: Light - LED 04
disabled_by_default: true <<: *light_partition_individual_led
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 4 from: 4
to: 4 to: 4
- id: light_05 - id: light_05
name: Light - LED 05 name: Light - LED 05
disabled_by_default: true <<: *light_partition_individual_led
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 5 from: 5
to: 5 to: 5
- id: light_06 - id: light_06
name: Light - LED 06 name: Light - LED 06
disabled_by_default: true <<: *light_partition_individual_led
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 6 from: 6
to: 6 to: 6
- id: light_07 - id: light_07
name: Light - LED 07 name: Light - LED 07
disabled_by_default: true <<: *light_partition_individual_led
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 7 from: 7
to: 7 to: 7
- id: light_08 - id: light_08
name: Light - LED 08 name: Light - LED 08
disabled_by_default: true <<: *light_partition_individual_led
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 8 from: 8
to: 8 to: 8
- id: light_09 - id: light_09
name: Light - LED 09 name: Light - LED 09
disabled_by_default: true <<: *light_partition_individual_led
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 9 from: 9
to: 9 to: 9
- id: light_10 - id: light_10
name: Light - LED 10 name: Light - LED 10
disabled_by_default: true <<: *light_partition_individual_led
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 10 from: 10
to: 10 to: 10
- id: light_11 - id: light_11
name: Light - LED 11 name: Light - LED 11
disabled_by_default: true <<: *light_partition_individual_led
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 11 from: 11
to: 11 to: 11
- id: light_12 - id: light_12
name: Light - LED 12 name: Light - LED 12
disabled_by_default: true <<: *light_partition_individual_led
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 12 from: 12
to: 12 to: 12
- id: light_13 - id: light_13
name: Light - LED 13 name: Light - LED 13
disabled_by_default: true <<: *light_partition_individual_led
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 13 from: 13
to: 13 to: 13
- id: light_14 - id: light_14
name: Light - LED 14 name: Light - LED 14
disabled_by_default: true <<: *light_partition_individual_led
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 14 from: 14
to: 14 to: 14
- id: light_15 - id: light_15
name: Light - LED 15 name: Light - LED 15
disabled_by_default: true <<: *light_partition_individual_led
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 15 from: 15
to: 15 to: 15
- id: light_16 - id: light_16
name: Light - LED 16 name: Light - LED 16
disabled_by_default: true <<: *light_partition_individual_led
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 16 from: 16
to: 16 to: 16
- id: light_17 - id: light_17
name: Light - LED 17 name: Light - LED 17
disabled_by_default: true <<: *light_partition_individual_led
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 17 from: 17
to: 17 to: 17
- id: light_18 - id: light_18
name: Light - LED 18 name: Light - LED 18
disabled_by_default: true <<: *light_partition_individual_led
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 18 from: 18
to: 18 to: 18
- id: light_19 - id: light_19
name: Light - LED 19 name: Light - LED 19
disabled_by_default: true <<: *light_partition_individual_led
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 19 from: 19
to: 19 to: 19
- id: light_20 - id: light_20
name: Light - LED 20 name: Light - LED 20
disabled_by_default: true <<: *light_partition_individual_led
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 20 from: 20
to: 20 to: 20
- id: light_21 - id: light_21
name: Light - LED 21 name: Light - LED 21
disabled_by_default: true <<: *light_partition_individual_led
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 21 from: 21
to: 21 to: 21
- id: light_22 - id: light_22
name: Light - LED 22 name: Light - LED 22
disabled_by_default: true <<: *light_partition_individual_led
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 22 from: 22
to: 22 to: 22
- id: light_23 - id: light_23
name: Light - LED 23 name: Light - LED 23
disabled_by_default: true <<: *light_partition_individual_led
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 23 from: 23
to: 23 to: 23
- id: light_24 - id: light_24
name: Light - LED 24 name: Light - LED 24
disabled_by_default: true <<: *light_partition_individual_led
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 24 from: 24
to: 24 to: 24
- id: light_25 - id: light_25
name: Light - LED 25 name: Light - LED 25
disabled_by_default: true <<: *light_partition_individual_led
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 25 from: 25
to: 25 to: 25
- id: light_26 - id: light_26
name: Light - LED 26 name: Light - LED 26
disabled_by_default: true <<: *light_partition_individual_led
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 26 from: 26
to: 26 to: 26
- id: light_27 - id: light_27
name: Light - LED 27 name: Light - LED 27
disabled_by_default: true <<: *light_partition_individual_led
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 27 from: 27
to: 27 to: 27
- id: light_28 - id: light_28 # US Model only
name: Light - LED 28 name: Light - LED 28
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_internal.yaml internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml <<: *light_partition_individual_led
segments: segments:
- id: light_full - id: light_full
from: 28 from: 28
to: 28 to: 28
- id: light_29 - id: light_29 # US Model only
name: Light - LED 29 name: Light - LED 29
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_internal.yaml internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml <<: *light_partition_individual_led
segments: segments:
- id: light_full - id: light_full
from: 29 from: 29
to: 29 to: 29
- id: light_30 - id: light_30 # US Model only
name: Light - LED 30 name: Light - LED 30
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_internal.yaml internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml <<: *light_partition_individual_led
segments: segments:
- id: light_full - id: light_full
from: 30 from: 30
to: 30 to: 30
- id: light_31 - id: light_31 # US Model only
name: Light - LED 31 name: Light - LED 31
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_internal.yaml internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml <<: *light_partition_individual_led
segments: segments:
- id: light_full - id: light_full
from: 31 from: 31
to: 31 to: 31
- id: light_eu_rl_1_1_bottom # These lights are used to indicate relay's statuses
- &light_partition_relays
id: light_eu_rl_1_1_bottom
name: Light - Relay 1 of 1 (bottom) name: Light - Relay 1 of 1 (bottom)
platform: partition
internal: true internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml default_transition_length: ${default_transition_length}
restore_mode: ${LIGHT_RELAYS_RESTORE_MODE}
segments: segments:
- id: light_full - id: light_full
from: 9 from: 9
to: 9 to: 9
- id: light_eu_rl_1_1_top - id: light_eu_rl_1_1_top
name: Light - Relay 1 of 1 (top) name: Light - Relay 1 of 1 (top)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 23 from: 23
to: 23 to: 23
- id: light_eu_rl_1_2_bottom - id: light_eu_rl_1_2_bottom
name: Light - Relay 1 of 2 (bottom) name: Light - Relay 1 of 2 (bottom)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 11 from: 11
to: 11 to: 11
- id: light_eu_rl_1_2_top - id: light_eu_rl_1_2_top
name: Light - Relay 1 of 2 (top) name: Light - Relay 1 of 2 (top)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 21 from: 21
to: 21 to: 21
- id: light_eu_rl_2_2_bottom - id: light_eu_rl_2_2_bottom
name: Light - Relay 2 of 2 (bottom) name: Light - Relay 2 of 2 (bottom)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 7 from: 7
to: 7 to: 7
- id: light_eu_rl_2_2_top - id: light_eu_rl_2_2_top
name: Light - Relay 2 of 2 (top) name: Light - Relay 2 of 2 (top)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 25 from: 25
to: 25 to: 25
- id: light_eu_rl_1_3_bottom - id: light_eu_rl_1_3_bottom
name: Light - Relay 1 of 3 (bottom) name: Light - Relay 1 of 3 (bottom)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 12 from: 12
to: 12 to: 12
- id: light_eu_rl_1_3_top - id: light_eu_rl_1_3_top
name: Light - Relay 1 of 3 (top) name: Light - Relay 1 of 3 (top)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 20 from: 20
to: 20 to: 20
- id: light_eu_rl_2_3_bottom - id: light_eu_rl_2_3_bottom
name: Light - Relay 2 of 3 (bottom) name: Light - Relay 2 of 3 (bottom)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 9 from: 9
to: 9 to: 9
- id: light_eu_rl_2_3_top - id: light_eu_rl_2_3_top
name: Light - Relay 2 of 3 (top) name: Light - Relay 2 of 3 (top)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 23 from: 23
to: 23 to: 23
- id: light_eu_rl_3_3_bottom - id: light_eu_rl_3_3_bottom
name: Light - Relay 3 of 3 (bottom) name: Light - Relay 3 of 3 (bottom)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 6 from: 6
to: 6 to: 6
- id: light_eu_rl_3_3_top - id: light_eu_rl_3_3_top
name: Light - Relay 3 of 3 (top) name: Light - Relay 3 of 3 (top)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 26 from: 26
to: 26 to: 26
- id: light_eu_rl_1_4_bottom - id: light_eu_rl_1_4_bottom
name: Light - Relay 1 of 4 (bottom) name: Light - Relay 1 of 4 (bottom)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 12 from: 12
to: 12 to: 12
- id: light_eu_rl_1_4_top - id: light_eu_rl_1_4_top
name: Light - Relay 1 of 4 (top) name: Light - Relay 1 of 4 (top)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 20 from: 20
to: 20 to: 20
- id: light_eu_rl_2_4_bottom - id: light_eu_rl_2_4_bottom
name: Light - Relay 2 of 4 (bottom) name: Light - Relay 2 of 4 (bottom)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 10 from: 10
to: 10 to: 10
- id: light_eu_rl_2_4_top - id: light_eu_rl_2_4_top
name: Light - Relay 2 of 4 (top) name: Light - Relay 2 of 4 (top)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 22 from: 22
to: 22 to: 22
- id: light_eu_rl_3_4_bottom - id: light_eu_rl_3_4_bottom
name: Light - Relay 3 of 4 (bottom) name: Light - Relay 3 of 4 (bottom)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 8 from: 8
to: 8 to: 8
- id: light_eu_rl_3_4_top - id: light_eu_rl_3_4_top
name: Light - Relay 3 of 4 (top) name: Light - Relay 3 of 4 (top)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 24 from: 24
to: 24 to: 24
- id: light_eu_rl_4_4_bottom - id: light_eu_rl_4_4_bottom
name: Light - Relay 4 of 4 (bottom) name: Light - Relay 4 of 4 (bottom)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 6 from: 6
to: 6 to: 6
- id: light_eu_rl_4_4_top - id: light_eu_rl_4_4_top
name: Light - Relay 4 of 4 (top) name: Light - Relay 4 of 4 (top)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 26 from: 26
to: 26 to: 26
- id: light_us_rl_1_1_left - id: light_us_rl_1_1_left
name: Light - Relay 1 of 1 (left) name: Light - Relay 1 of 1 (left)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 15 from: 15
to: 24 to: 24
- id: light_us_rl_1_1_right - id: light_us_rl_1_1_right
name: Light - Relay 1 of 1 (right) name: Light - Relay 1 of 1 (right)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 31 from: 31
@@ -613,16 +582,14 @@ light:
to: 8 to: 8
- id: light_us_rl_1_2_left - id: light_us_rl_1_2_left
name: Light - Relay 1 of 2 (left) name: Light - Relay 1 of 2 (left)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 20 from: 20
to: 24 to: 24
- id: light_us_rl_1_2_right - id: light_us_rl_1_2_right
name: Light - Relay 1 of 2 (right) name: Light - Relay 1 of 2 (right)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 31 from: 31
@@ -632,132 +599,119 @@ light:
to: 3 to: 3
- id: light_us_rl_2_2_left - id: light_us_rl_2_2_left
name: Light - Relay 2 of 2 (left) name: Light - Relay 2 of 2 (left)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 15 from: 15
to: 19 to: 19
- id: light_us_rl_2_2_right - id: light_us_rl_2_2_right
name: Light - Relay 2 of 2 (right) name: Light - Relay 2 of 2 (right)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 4 from: 4
to: 8 to: 8
- id: light_us_rl_1_3_left - id: light_us_rl_1_3_left
name: Light - Relay 1 of 3 (left) name: Light - Relay 1 of 3 (left)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 22 from: 22
to: 23 to: 23
- id: light_us_rl_1_3_right - id: light_us_rl_1_3_right
name: Light - Relay 1 of 3 (right) name: Light - Relay 1 of 3 (right)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 0 from: 0
to: 1 to: 1
- id: light_us_rl_2_3_left - id: light_us_rl_2_3_left
name: Light - Relay 2 of 3 (left) name: Light - Relay 2 of 3 (left)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 19 from: 19
to: 20 to: 20
- id: light_us_rl_2_3_right - id: light_us_rl_2_3_right
name: Light - Relay 2 of 3 (right) name: Light - Relay 2 of 3 (right)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 3 from: 3
to: 4 to: 4
- id: light_us_rl_3_3_left - id: light_us_rl_3_3_left
name: Light - Relay 3 of 3 (left) name: Light - Relay 3 of 3 (left)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 17 from: 16
to: 18 to: 17
- id: light_us_rl_3_3_right - id: light_us_rl_3_3_right
name: Light - Relay 3 of 3 (right) name: Light - Relay 3 of 3 (right)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 6 from: 6
to: 7 to: 7
- id: light_us_rl_1_4_left - id: light_us_rl_1_4_left
name: Light - Relay 1 of 4 (left) name: Light - Relay 1 of 4 (left)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 12 from: 23
to: 12 to: 24
- id: light_us_rl_1_4_right - id: light_us_rl_1_4_right
name: Light - Relay 1 of 4 (right) name: Light - Relay 1 of 4 (right)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 31 from: 31
to: 31 to: 31
- id: light_full
from: 0
to: 0
- id: light_us_rl_2_4_left - id: light_us_rl_2_4_left
name: Light - Relay 2 of 4 (left) name: Light - Relay 2 of 4 (left)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 24
to: 24
- id: light_us_rl_2_4_right
name: Light - Relay 2 of 4 (right)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments:
- id: light_full
from: 2
to: 2
- id: light_us_rl_3_4_left
name: Light - Relay 3 of 4 (left)
internal: true
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 21 from: 21
to: 21 to: 22
- id: light_us_rl_2_4_right
name: Light - Relay 2 of 4 (right)
<<: *light_partition_relays
segments:
- id: light_full
from: 1
to: 2
- id: light_us_rl_3_4_left
name: Light - Relay 3 of 4 (left)
<<: *light_partition_relays
segments:
- id: light_full
from: 17
to: 18
- id: light_us_rl_3_4_right - id: light_us_rl_3_4_right
name: Light - Relay 3 of 4 (right) name: Light - Relay 3 of 4 (right)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 4 from: 5
to: 4 to: 6
- id: light_us_rl_4_4_left - id: light_us_rl_4_4_left
name: Light - Relay 4 of 4 (left) name: Light - Relay 4 of 4 (left)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 19 from: 15
to: 19 to: 16
- id: light_us_rl_4_4_right - id: light_us_rl_4_4_right
name: Light - Relay 4 of 4 (right) name: Light - Relay 4 of 4 (right)
internal: true <<: *light_partition_relays
<<: !include TX-Ultimate-Easy-ESPHome_core_hw_leds_light_base.yaml
segments: segments:
- id: light_full - id: light_full
from: 7 from: 7
to: 7 to: 8
script: script:
- id: !extend boot_initialize - id: !extend boot_initialize
@@ -817,7 +771,7 @@ script:
id(gb_lights_2) = { light_eu_rl_1_3_top, light_eu_rl_2_3_top, light_eu_rl_3_3_top }; id(gb_lights_2) = { light_eu_rl_1_3_top, light_eu_rl_2_3_top, light_eu_rl_3_3_top };
} }
break; break;
case 4: // 3 Gang case 4: // 4 Gang
if (is_model_us) { if (is_model_us) {
id(gb_lights_1) = { light_us_rl_1_4_left, light_us_rl_2_4_left, id(gb_lights_1) = { light_us_rl_1_4_left, light_us_rl_2_4_left,
light_us_rl_3_4_left, light_us_rl_4_4_left }; light_us_rl_3_4_left, light_us_rl_4_4_left };
@@ -853,12 +807,12 @@ script:
case 1: case 1:
if (light_index >= id(gb_lights_1).size()) { if (light_index >= id(gb_lights_1).size()) {
ESP_LOGE("core_hw_leds", "Invalid set with %s light for Relay %" PRIu8, ESP_LOGE("core_hw_leds", "Invalid set with %s light for Relay %" PRIu8,
light_mode_group_1.c_str(), light_index); light_mode_group_1.c_str(), light_index+1);
return; return;
} }
if (state and !id(gb_lights_1)[light_index]->current_values.is_on()) { if (state and !id(gb_lights_1)[light_index]->current_values.is_on()) {
ESP_LOGI("core_hw_leds", "Turn-on %s light for Relay %" PRIu8, ESP_LOGI("core_hw_leds", "Turn-on %s light for Relay %" PRIu8,
light_mode_group_1.c_str(), light_index); light_mode_group_1.c_str(), light_index+1);
auto call = id(gb_lights_1)[light_index]->turn_on(); auto call = id(gb_lights_1)[light_index]->turn_on();
if (LIGHT_TRANSITION_TURN_ON > 0) if (LIGHT_TRANSITION_TURN_ON > 0)
call.set_transition_length(LIGHT_TRANSITION_TURN_ON); // in ms call.set_transition_length(LIGHT_TRANSITION_TURN_ON); // in ms
@@ -867,7 +821,7 @@ script:
call.perform(); call.perform();
} else if (!state and id(gb_lights_1)[light_index]->current_values.is_on()) { } else if (!state and id(gb_lights_1)[light_index]->current_values.is_on()) {
ESP_LOGI("core_hw_leds", "Turn-off %s light for Relay %" PRIu8, ESP_LOGI("core_hw_leds", "Turn-off %s light for Relay %" PRIu8,
light_mode_group_1.c_str(), light_index); light_mode_group_1.c_str(), light_index+1);
auto call = id(gb_lights_1)[light_index]->turn_off(); auto call = id(gb_lights_1)[light_index]->turn_off();
if (LIGHT_TRANSITION_TURN_OFF > 0) if (LIGHT_TRANSITION_TURN_OFF > 0)
call.set_transition_length(LIGHT_TRANSITION_TURN_OFF); // in ms call.set_transition_length(LIGHT_TRANSITION_TURN_OFF); // in ms
@@ -877,12 +831,12 @@ script:
case 2: case 2:
if (light_index >= id(gb_lights_2).size()) { if (light_index >= id(gb_lights_2).size()) {
ESP_LOGE("core_hw_leds", "Invalid set with %s light for Relay %" PRIu8, ESP_LOGE("core_hw_leds", "Invalid set with %s light for Relay %" PRIu8,
light_mode_group_2.c_str(), light_index); light_mode_group_2.c_str(), light_index+1);
return; return;
} }
if (state and !id(gb_lights_2)[light_index]->current_values.is_on()) { if (state and !id(gb_lights_2)[light_index]->current_values.is_on()) {
ESP_LOGI("core_hw_leds", "Turn-on %s light for Relay %" PRIu8, ESP_LOGI("core_hw_leds", "Turn-on %s light for Relay %" PRIu8,
light_mode_group_2.c_str(), light_index); light_mode_group_2.c_str(), light_index+1);
auto call = id(gb_lights_2)[light_index]->turn_on(); auto call = id(gb_lights_2)[light_index]->turn_on();
if (LIGHT_TRANSITION_TURN_ON > 0) if (LIGHT_TRANSITION_TURN_ON > 0)
call.set_transition_length(LIGHT_TRANSITION_TURN_ON); // in ms call.set_transition_length(LIGHT_TRANSITION_TURN_ON); // in ms
@@ -891,7 +845,7 @@ script:
call.perform(); call.perform();
} else if (!state and id(gb_lights_2)[light_index]->current_values.is_on()) { } else if (!state and id(gb_lights_2)[light_index]->current_values.is_on()) {
ESP_LOGI("core_hw_leds", "Turn-off %s light for Relay %" PRIu8, ESP_LOGI("core_hw_leds", "Turn-off %s light for Relay %" PRIu8,
light_mode_group_2.c_str(), light_index); light_mode_group_2.c_str(), light_index+1);
auto call = id(gb_lights_2)[light_index]->turn_off(); auto call = id(gb_lights_2)[light_index]->turn_off();
if (LIGHT_TRANSITION_TURN_OFF > 0) if (LIGHT_TRANSITION_TURN_OFF > 0)
call.set_transition_length(LIGHT_TRANSITION_TURN_OFF); // in ms call.set_transition_length(LIGHT_TRANSITION_TURN_OFF); // in ms

View File

@@ -1,4 +0,0 @@
---
platform: partition
default_transition_length: ${default_transition_length}
...

View File

@@ -1,40 +0,0 @@
---
effects:
- addressable_rainbow:
name: "Rainbow"
- addressable_rainbow:
name: "Rainbow - Fast"
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"
...

View File

@@ -1,4 +0,0 @@
---
internal: true
disabled_by_default: true
...

View File

@@ -11,54 +11,11 @@
##### - For normal system use, modifications to this file are NOT required. ##### ##### - For normal system use, modifications to this file are NOT required. #####
#################################################################################################### ####################################################################################################
--- ---
binary_sensor: substitutions:
- id: !extend bs_button_1 RELAY_MODE_TEXT_SWITCH: "Switch"
on_click: RELAY_MODE_TEXT_LIGHT: "Light"
then: RELAY_MODE_TEXT_NOT_USED: "Not in use"
- if: RELAY_RESTORE_MODE: RESTORE_DEFAULT_OFF
condition:
- lambda: return sl_button_1_action->active_index().has_value();
- lambda: return sl_button_1_action->active_index().value() == 1;
- and: &button_click_no_other_click
- lambda: return not bs_multi_touch->state;
- lambda: return not bs_swipe_left->state;
- lambda: return not bs_swipe_down->state;
- lambda: return not bs_swipe_right->state;
then:
- switch.toggle: sw_relay_1
- id: !extend bs_button_2
on_click:
then:
- if:
condition:
- lambda: return sl_button_2_action->active_index().has_value();
- lambda: return sl_button_2_action->active_index().value() == 1;
- and: *button_click_no_other_click
then:
- switch.toggle: sw_relay_2
- id: !extend bs_button_3
on_click:
then:
- if:
condition:
- lambda: return sl_button_3_action->active_index().has_value();
- lambda: return sl_button_3_action->active_index().value() == 1;
- and: *button_click_no_other_click
then:
- switch.toggle: sw_relay_3
- id: !extend bs_button_4
on_click:
then:
- if:
condition:
- lambda: return sl_button_4_action->active_index().has_value();
- lambda: return sl_button_4_action->active_index().value() == 1;
- and: *button_click_no_other_click
then:
- switch.toggle: sw_relay_4
globals: globals:
- id: boot_initialization_relays - id: boot_initialization_relays
@@ -66,6 +23,86 @@ globals:
restore_value: false restore_value: false
initial_value: 'false' initial_value: 'false'
light:
# These lights are used for the physical relays to be shown as lights
- id: light_output_1
name: Light output 1
output: output_relay_1
platform: binary
internal: true
restore_mode: ${RELAY_RESTORE_MODE}
on_turn_on:
then:
- if:
condition:
- switch.is_off: sw_relay_1
then:
- switch.turn_on: sw_relay_1
on_turn_off:
then:
- if:
condition:
- switch.is_on: sw_relay_1
then:
- switch.turn_off: sw_relay_1
- id: light_output_2
name: Light output 2
output: output_relay_2
platform: binary
internal: true
on_turn_on:
then:
- if:
condition:
- switch.is_off: sw_relay_2
then:
- switch.turn_on: sw_relay_2
on_turn_off:
then:
- if:
condition:
- switch.is_on: sw_relay_2
then:
- switch.turn_off: sw_relay_2
- id: light_output_3
name: Light output 3
output: output_relay_3
platform: binary
internal: true
on_turn_on:
then:
- if:
condition:
- switch.is_off: sw_relay_3
then:
- switch.turn_on: sw_relay_3
on_turn_off:
then:
- if:
condition:
- switch.is_on: sw_relay_3
then:
- switch.turn_off: sw_relay_3
- id: light_output_4
name: Light output 4
output: output_relay_4
platform: binary
internal: true
on_turn_on:
then:
- if:
condition:
- switch.is_off: sw_relay_4
then:
- switch.turn_on: sw_relay_4
on_turn_off:
then:
- if:
condition:
- switch.is_on: sw_relay_4
then:
- switch.turn_off: sw_relay_4
output: output:
- id: output_relay_1 - id: output_relay_1
platform: gpio platform: gpio
@@ -138,6 +175,74 @@ script:
} }
id(boot_initialization_relays) = true; id(boot_initialization_relays) = true;
- id: !extend button_click_event
then:
- lambda: |-
// Handle only single clicks
if (click_count != 1)
return;
// Ignore if other touch events are active
if (bs_multi_touch->state ||
bs_swipe_left->state ||
bs_swipe_down->state ||
bs_swipe_right->state) {
return;
}
// Toggle relay if corresponding button action is enabled
ESP_LOGVV("core_hw_relays", "Toggle relays: (${BUTTON_ACTION_NONE_TEXT})");
ESP_LOGVV("core_hw_relays", " Relay 1: %s (%s)",
YESNO(sl_button_1_action->state != "${BUTTON_ACTION_NONE_TEXT}"),
sl_button_1_action->state.c_str());
ESP_LOGVV("core_hw_relays", " Relay 2: %s (%s)",
YESNO(sl_button_2_action->state != "${BUTTON_ACTION_NONE_TEXT}"),
sl_button_2_action->state.c_str());
ESP_LOGVV("core_hw_relays", " Relay 3: %s (%s)",
YESNO(sl_button_3_action->state != "${BUTTON_ACTION_NONE_TEXT}"),
sl_button_3_action->state.c_str());
ESP_LOGVV("core_hw_relays", " Relay 4: %s (%s)",
YESNO(sl_button_4_action->state != "${BUTTON_ACTION_NONE_TEXT}"),
sl_button_4_action->state.c_str());
switch (button) {
case ${BUTTON_1_ID}:
if (sl_button_1_action->state != "${BUTTON_ACTION_NONE_TEXT}") {
ESP_LOGV("core_hw_relays", "Toggle relay 1: (%s)", sl_button_1_action->state.c_str());
sw_relay_1->toggle();
} else {
ESP_LOGV("core_hw_relays", "Ignoring toggle for relay 1: action is '%s'",
sl_button_1_action->state.c_str());
}
break;
case ${BUTTON_2_ID}:
if (sl_button_2_action->state != "${BUTTON_ACTION_NONE_TEXT}") {
ESP_LOGV("core_hw_relays", "Toggle relay 2: (%s)", sl_button_2_action->state.c_str());
sw_relay_2->toggle();
} else {
ESP_LOGV("core_hw_relays", "Ignoring toggle for relay 2: action is '%s'",
sl_button_2_action->state.c_str());
}
break;
case ${BUTTON_3_ID}:
if (sl_button_3_action->state != "${BUTTON_ACTION_NONE_TEXT}") {
ESP_LOGV("core_hw_relays", "Toggle relay 3: (%s)", sl_button_3_action->state.c_str());
sw_relay_3->toggle();
} else {
ESP_LOGV("core_hw_relays", "Ignoring toggle for relay 3: action is '%s'",
sl_button_3_action->state.c_str());
}
break;
case ${BUTTON_4_ID}:
if (sl_button_4_action->state != "${BUTTON_ACTION_NONE_TEXT}") {
ESP_LOGV("core_hw_relays", "Toggle relay 4: (%s)", sl_button_4_action->state.c_str());
sw_relay_4->toggle();
} else {
ESP_LOGV("core_hw_relays", "Ignoring toggle for relay 4: action is '%s'",
sl_button_4_action->state.c_str());
}
break;
}
- id: show_relay_status - id: show_relay_status
mode: restart mode: restart
then: then:
@@ -215,12 +320,13 @@ script:
select: select:
- &relay_select_mode_base - &relay_select_mode_base
id: sl_relay_1_mode id: sl_relay_1_mode
name: Relay 1 mode name: Relay 1 display mode
platform: template platform: template
options: options:
- "Relay" - "${RELAY_MODE_TEXT_SWITCH}"
- "Light" - "${RELAY_MODE_TEXT_LIGHT}"
- "Not in use" - "${RELAY_MODE_TEXT_NOT_USED}"
initial_option: "${RELAY_MODE_TEXT_SWITCH}"
optimistic: true optimistic: true
restore_value: true restore_value: true
internal: true internal: true
@@ -229,44 +335,107 @@ select:
icon: mdi:dip-switch icon: mdi:dip-switch
- id: sl_relay_2_mode - id: sl_relay_2_mode
name: Relay 2 mode name: Relay 2 display mode
<<: *relay_select_mode_base <<: *relay_select_mode_base
- id: sl_relay_3_mode - id: sl_relay_3_mode
name: Relay 3 mode name: Relay 3 display mode
<<: *relay_select_mode_base <<: *relay_select_mode_base
- id: sl_relay_4_mode - id: sl_relay_4_mode
name: Relay 4 mode name: Relay 4 display mode
<<: *relay_select_mode_base <<: *relay_select_mode_base
switch: switch:
- &relay_switch_base - id: sw_relay_1
id: sw_relay_1
name: Relay 1 name: Relay 1
platform: output
output: output_relay_1 output: output_relay_1
restore_mode: RESTORE_DEFAULT_OFF platform: output
restore_mode: ${RELAY_RESTORE_MODE}
internal: true internal: true
on_turn_on: on_turn_on:
then: then:
- script.execute: show_relay_status - script.execute: show_relay_status
- if:
condition:
- light.is_off: light_output_1
then:
light.turn_on: light_output_1
on_turn_off: on_turn_off:
then: then:
- script.execute: show_relay_status - script.execute: show_relay_status
- if:
condition:
- light.is_on: light_output_1
then:
- light.turn_off: light_output_1
- id: sw_relay_2 - id: sw_relay_2
name: Relay 2 name: Relay 2
output: output_relay_2 output: output_relay_2
<<: *relay_switch_base platform: output
restore_mode: ${RELAY_RESTORE_MODE}
internal: true
on_turn_on:
then:
- script.execute: show_relay_status
- if:
condition:
- light.is_off: light_output_2
then:
light.turn_on: light_output_2
on_turn_off:
then:
- script.execute: show_relay_status
- if:
condition:
- light.is_on: light_output_2
then:
- light.turn_off: light_output_2
- id: sw_relay_3 - id: sw_relay_3
name: Relay 3 name: Relay 3
output: output_relay_3 output: output_relay_3
<<: *relay_switch_base platform: output
restore_mode: ${RELAY_RESTORE_MODE}
internal: true
on_turn_on:
then:
- script.execute: show_relay_status
- if:
condition:
- light.is_off: light_output_3
then:
- light.turn_on: light_output_3
on_turn_off:
then:
- script.execute: show_relay_status
- if:
condition:
- light.is_on: light_output_3
then:
- light.turn_off: light_output_3
- id: sw_relay_4 - id: sw_relay_4
name: Relay 4 name: Relay 4
output: output_relay_4 output: output_relay_4
<<: *relay_switch_base platform: output
restore_mode: ${RELAY_RESTORE_MODE}
internal: true
on_turn_on:
then:
- script.execute: show_relay_status
- if:
condition:
- light.is_off: light_output_4
then:
- light.turn_on: light_output_4
on_turn_off:
then:
- script.execute: show_relay_status
- if:
condition:
- light.is_on: light_output_4
then:
- light.turn_off: light_output_4
... ...

View File

@@ -19,11 +19,11 @@ i2s_audio:
media_player: media_player:
- id: mp_speaker - id: mp_speaker
name: Speaker name: Speaker
internal: false
platform: i2s_audio platform: i2s_audio
i2s_dout_pin: GPIO15 i2s_dout_pin: GPIO15
i2s_audio_id: if_i2s_audio i2s_audio_id: if_i2s_audio
i2s_comm_fmt: lsb i2s_comm_fmt: msb # Experimental - It was 'lsb' until v2024.12.12
dac_type: external dac_type: external
mode: mono mode: mono
internal: false
... ...

View File

@@ -11,64 +11,205 @@
##### - For normal system use, modifications to this file are NOT required. ##### ##### - For normal system use, modifications to this file are NOT required. #####
#################################################################################################### ####################################################################################################
--- ---
substitutions:
TOUCH_POSITION_MAX_VALUE: '10' # Maximum touch position value returned by the touch pad via uart
binary_sensor: 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 - id: bs_multi_touch
name: Multi-touch name: Multi-touch event
icon: mdi:gesture-two-tap icon: mdi:gesture-two-tap
internal: false internal: false
platform: template <<: *bs_button_event_template
on_click: on_press:
then: 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 - id: bs_swipe_left
name: Swipe left name: Swipe left event
icon: mdi:gesture-swipe-left icon: mdi:gesture-swipe-left
internal: true <<: *bs_button_event_template
platform: template on_press:
on_click:
then: 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 - id: bs_swipe_right
name: Swipe right name: Swipe right event
icon: mdi:gesture-swipe-right icon: mdi:gesture-swipe-right
internal: true <<: *bs_button_event_template
platform: template on_press:
on_click:
then: 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 - id: bs_swipe_up
name: Swipe up name: Swipe up event
icon: mdi:gesture-swipe-up icon: mdi:gesture-swipe-up
internal: true <<: *bs_button_event_template
platform: template on_press:
on_click:
then: 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 - id: bs_swipe_down
name: Swipe down name: Swipe down event
icon: mdi:gesture-swipe-down icon: mdi:gesture-swipe-down
internal: true <<: *bs_button_event_template
platform: template on_press:
on_click:
then: 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: external_components:
- source: - source:
type: git type: git
url: https://github.com/edwardtfn/TX-Ultimate-Easy url: https://github.com/edwardtfn/TX-Ultimate-Easy
ref: ${version} ref: v${version}
refresh: 1h refresh: 1h
components: components:
- tx_ultimate_easy - tx_ultimate_easy
number: number:
- id: nr_touch_duration - id: nr_touch_duration
name: Touch duration name: Touch event duration
icon: mdi:timer-cog-outline icon: mdi:timer-cog-outline
unit_of_measurement: ms unit_of_measurement: ms
# mode: box # mode: box
@@ -88,6 +229,12 @@ script:
- script.execute: boot_initialize_touch - script.execute: boot_initialize_touch
- id: 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 mode: restart
then: then:
- wait_until: - wait_until:
@@ -106,25 +253,56 @@ script:
bs_swipe_up->publish_state(false); bs_swipe_up->publish_state(false);
bs_swipe_up->set_internal(!is_model_us); 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 - id: touch_on_multi_touch_release
mode: restart mode: restart
then: then:
# Extended by: # Extended by:
# - HW Buttons # - HW Buttons
# - HW Vibration # - HW Vibration
- script.execute: touch_on_multi_touch_release_touch - binary_sensor.template.publish:
id: bs_multi_touch
- id: touch_on_multi_touch_release_touch state: OFF # yamllint disable-line rule:truthy
mode: restart
then:
- lambda: bs_multi_touch->publish_state(true);
- delay: !lambda return nr_touch_duration->state;
- lambda: bs_multi_touch->publish_state(false);
- id: touch_on_press - id: touch_on_press
mode: restart mode: restart
parameters: parameters:
touch_x: uint8_t button: uint8_t
position: uint8_t
then: then:
# Extended by: # Extended by:
# - HW Buttons # - HW Buttons
@@ -136,57 +314,30 @@ script:
# Extended by: # Extended by:
# - HW Buttons # - HW Buttons
# - HW Vibration # - HW Vibration
- script.execute: touch_swipe_turn_off_binary_sensor
- id: touch_swipe_left - id: touch_swipe_left
mode: restart mode: restart
then: then:
# Extended by: # Extended by:
# - HW Buttons # - HW Buttons
- script.execute: touch_swipe_left_touch
- id: touch_swipe_left_touch
mode: restart
then:
- binary_sensor.template.publish: - binary_sensor.template.publish:
id: bs_swipe_left id: bs_swipe_left
state: ON # yamllint disable-line rule:truthy state: ON # yamllint disable-line rule:truthy
- delay: !lambda return nr_touch_duration->state; - binary_sensor.template.publish:
- script.execute: touch_swipe_turn_off_binary_sensor id: bs_swipe_down
state: ON # yamllint disable-line rule:truthy
- id: touch_swipe_right - id: touch_swipe_right
mode: restart mode: restart
then: then:
# Extended by: # Extended by:
# - HW Buttons # - HW Buttons
- script.execute: touch_swipe_right_touch
- id: touch_swipe_right_touch
mode: restart
then:
- binary_sensor.template.publish: - binary_sensor.template.publish:
id: bs_swipe_right id: bs_swipe_right
state: ON # yamllint disable-line rule:truthy 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: - binary_sensor.template.publish:
id: bs_swipe_left id: bs_swipe_up
state: OFF # yamllint disable-line rule:truthy state: ON # 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
switch: switch:
- id: sw_touch_panel_power - id: sw_touch_panel_power
@@ -203,37 +354,88 @@ tx_ultimate_easy:
id: tx_ultimate id: tx_ultimate
uart: uart_touch uart: uart_touch
on_long_touch_release:
- lambda: |-
const uint8_t touch_position = static_cast<uint8_t>(touch.x);
if (touch_position > ${TOUCH_POSITION_MAX_VALUE}) { // Check for valid range
ESP_LOGE("core_hw_touch", "Invalid long-touch position: %" PRIu8, touch_position);
} else {
ESP_LOGI("core_hw_touch", "Long-touch released at position %" PRIu8, touch_position);
}
on_multi_touch_release: on_multi_touch_release:
- lambda: ESP_LOGI("tx_ultimate_easy", "Multi-touch released"); - 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("core_hw_touch", "Multi-touch released");
- script.execute: touch_on_multi_touch_release - script.execute: touch_on_multi_touch_release
on_press: on_press:
- lambda: |- - lambda: |-
ESP_LOGI("tx_ultimate_easy", "Pressed at position %" PRIu8, static_cast<uint8_t>(touch.x)); const uint8_t position = static_cast<uint8_t>(touch.x);
- script.execute: if (position > ${TOUCH_POSITION_MAX_VALUE}) { // Check for valid range
id: touch_on_press ESP_LOGE("core_hw_touch", "Invalid touch position: %" PRIu8, position);
touch_x: !lambda return static_cast<uint8_t>(touch.x); } else {
ESP_LOGI("core_hw_touch", "Pressed at position %" PRIu8, position);
touch_on_press->execute(static_cast<uint8_t>(touch.button), position);
}
on_release: on_release:
- lambda: ESP_LOGI("tx_ultimate_easy", "Released"); - lambda: ESP_LOGI("core_hw_touch", "Released");
- script.execute: touch_on_release - script.execute: touch_on_release
on_swipe_left: 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_EU_TEXT}" ? "left" : "down";
swipe-direction: !lambda |-
return sl_tx_model_format->state == "${TX_MODEL_FORMAT_EU_TEXT}" ? "left" : "down";
position: !lambda return touch.x;
- lambda: |-
ESP_LOGI("core_hw_touch", "Swipe %s", sl_tx_model_format->state == "${TX_MODEL_FORMAT_EU_TEXT}"
? "left"
: "down");
- script.execute: touch_swipe_left - script.execute: touch_swipe_left
on_swipe_right: 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_EU_TEXT}" ? "right" : "up";
swipe-direction: !lambda |-
return sl_tx_model_format->state == "${TX_MODEL_FORMAT_EU_TEXT}" ? "right" : "up";
position: !lambda return touch.x;
- lambda: |-
ESP_LOGI("core_hw_touch", "Swipe %s", sl_tx_model_format->state == "${TX_MODEL_FORMAT_EU_TEXT}"
? "right"
: "up");
- script.execute: touch_swipe_right - script.execute: touch_swipe_right
on_touch_event: on_touch_event:
- lambda: |- - lambda: |-
ESP_LOGD("tx_ultimate_easy", "Touch event:"); ESP_LOGD("core_hw_touch", "Touch event:");
ESP_LOGD("tx_ultimate_easy", " State: %i (%s)", touch.state, touch.state_str.c_str()); ESP_LOGD("core_hw_touch", " State: %i (%s)", touch.state, touch.state_str.c_str());
ESP_LOGD("tx_ultimate_easy", " Position: %i", touch.x); ESP_LOGD("core_hw_touch", " Position: %i", touch.x);
uart: uart:
id: uart_touch - id: uart_touch
tx_pin: GPIO19 tx_pin: GPIO19
rx_pin: GPIO22 rx_pin: GPIO22
baud_rate: 115200 baud_rate: 115200

View File

@@ -1,19 +1,20 @@
# TX Ultimate Easy # TX Ultimate Easy
<!-- markdownlint-disable MD033 --> [![Version][version-shield]](https://github.com/edwardtfn/TX-Ultimate-Easy/tags)
<a href="https://github.com/edwardtfn/TX-Ultimate-Easy/commits/main" target="_blank">![GitHub Activity][commits-shield]</a> [![GitHub Activity][commits-shield]](https://github.com/edwardtfn/TX-Ultimate-Easy/commits/main)
<a href="LICENSE" target="_blank">![License][license-shield]</a> [![License][license-shield]](LICENSE)
<a href="https://github.com/edwardtfn/TX-Ultimate-Easy/commits/main" target="_blank">![GitHub Last Commit][last-commit-shield]</a> [![GitHub Last Commit][last-commit-shield]](https://github.com/edwardtfn/TX-Ultimate-Easy/commits/main)
<a href="https://esphome.io/" target="_blank">![ESPHome][esphome-shield]</a> [![ESPHome][esphome-shield]](https://esphome.io/)
<a href="https://discord.gg/Db6WJWzWuf" target="_blank">![Discord][discord-shield]</a> [![Discord][discord-shield]](https://discord.gg/Db6WJWzWuf)
<a href="https://www.buymeacoffee.com/edwardfirmo" target="_blank">![Buy me an ice-cream][buymeacoffee-shield]</a> [![Buy me an ice-cream][buymeacoffee-shield]](https://www.buymeacoffee.com/edwardfirmo)
<!-- markdownlint-enable MD033 -->
<!-- markdownlint-disable MD013 --> <!-- markdownlint-disable MD013 -->
| &nbsp;![TX Ultimate Easy Logo](Assets/Logo.webp) | TX Ultimate Easy provides custom ESPHome firmware for Sonoff TX Ultimate devices. Our project focuses on user-friendly configuration through the Home Assistant UI, eliminating the need for manual YAML editing. Whether you're new to home automation or an experienced user, TX Ultimate Easy makes it simple to manage your device. | | &nbsp;![TX Ultimate Easy Logo](Assets/Logo.webp) | TX Ultimate Easy provides custom ESPHome firmware for Sonoff TX Ultimate devices. Our project focuses on user-friendly configuration through the Home Assistant UI, eliminating the need for manual YAML editing. Whether you're new to home automation or an experienced user, TX Ultimate Easy makes it simple to manage your device. |
| --- | :-- | | --- | :-- |
<!-- markdownlint-enable MD013 --> <!-- markdownlint-enable MD013 -->
[version-shield]: https://img.shields.io/github/v/tag/edwardtfn/TX-Ultimate-Easy?label=version
[version]: https://github.com/edwardtfn/TX-Ultimate-Easy/tags
[commits-shield]: https://img.shields.io/github/commit-activity/y/edwardtfn/TX-Ultimate-Easy [commits-shield]: https://img.shields.io/github/commit-activity/y/edwardtfn/TX-Ultimate-Easy
[commits]: https://github.com/edwardtfn/TX-Ultimate-Easy/commits/main [commits]: https://github.com/edwardtfn/TX-Ultimate-Easy/commits/main
[license-shield]: https://img.shields.io/github/license/edwardtfn/TX-Ultimate-Easy [license-shield]: https://img.shields.io/github/license/edwardtfn/TX-Ultimate-Easy
@@ -28,14 +29,39 @@
## Integration with Home Assistant ## 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 - Monitor sensor states and values
- Control device components through the Home Assistant UI - Control device components through the Home Assistant UI
- Use device triggers and states in your Home Assistant automations and scripts - Use device triggers and states in your Home Assistant automations and scripts
- Configure device behavior through Home Assistant's service calls - 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 device integration rather than implementing its own automation tools. 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.
For more details, please refer to our **[Events docs](docs/events.md)**.
### Device Configuration
#### Relay Modes
- **Light Mode**: Exposes the relay as a light entity with brightness controls (if supported)
- **Switch Mode**: Exposes the relay as a simple on/off switch entity
#### Button Actions
- **None**: Allows using button events for custom automations
Example: Trigger scenes or complex automations through Home Assistant
- **Relay Toggle**: Direct control of the associated relay
Example: Toggle relay state with each press, independent of Home Assistant
#### Automation
All device behaviors can be customized through Home Assistant automations without relying on local device triggers.
## Key Features ## Key Features
@@ -98,26 +124,29 @@ TX Ultimate Easy offers extensive configuration options:
We welcome contributions from the community! Here's how you can help: We welcome contributions from the community! Here's how you can help:
1. Fork the repository 1. Fork the repository
2. Create a feature branch from `dev` 2. Create a feature branch from `main`
3. Make your changes 3. Make your changes
4. Submit a pull request targeting the `dev` branch 4. Submit a pull request targeting the `main` branch
Please ensure your code follows our standards: Please ensure your code follows our standards:
- Passes all lint checks (YAML, C++, Markdown) - Passes all lint checks (YAML, C++, Markdown)
- Includes appropriate documentation - Includes appropriate documentation
- Follows existing code style - Follows existing code style
All pull requests should be made against the `dev` branch. We don't accept pull requests directly to `main` as it's reserved for stable releases.
## Support and Community ## Support and Community
Need help? Here are your options: 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 - **Bug Reports & Feature Requests**: Use [GitHub Issues](https://github.com/edwardtfn/TX-Ultimate-Easy/issues)
- **Community Chat**: Join our [Discord Server](https://discord.gg/Db6WJWzWuf) for discussions and community interaction 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 - **Support the Project**: Consider supporting through Buy Me a Coffee
Note: For proper tracking and resolution, all bug reports and feature requests must be submitted through GitHub Issues, not Discord. The Issues page can be found at: [Issues · edwardtfn/TX-Ultimate-Easy](https://github.com/edwardtfn/TX-Ultimate-Easy/issues) Note: For proper tracking and resolution:
- All bug reports and feature requests must be submitted through GitHub Issues, not Discord
- Submit issues here: [Issues · edwardtfn/TX-Ultimate-Easy](https://github.com/edwardtfn/TX-Ultimate-Easy/issues)
[![Buy Me a Coffee](https://www.buymeacoffee.com/assets/img/custom_images/yellow_img.png)](https://www.buymeacoffee.com/edwardfirmo) [![Buy Me a Coffee](https://www.buymeacoffee.com/assets/img/custom_images/yellow_img.png)](https://www.buymeacoffee.com/edwardfirmo)

View File

@@ -16,8 +16,8 @@ wifi:
packages: packages:
remote_package: remote_package:
url: https://github.com/edwardtfn/TX-Ultimate-Easy url: https://github.com/edwardtfn/TX-Ultimate-Easy
ref: dev ref: latest # Or you can specify a version, like `ref: v2024.12.6`
refresh: 30s refresh: 5min
files: files:
- ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml - ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml
# - ESPHome/TX-Ultimate-Easy-ESPHome_addon_ble_proxy.yaml # Adds experimental BLE proxy support (limited) # - ESPHome/TX-Ultimate-Easy-ESPHome_addon_ble_proxy.yaml # Adds experimental BLE proxy support (limited)

View File

@@ -13,6 +13,7 @@ DEPENDENCIES = ['uart']
CONF_TX_ULTIMATE_EASY = "tx_ultimate_easy" CONF_TX_ULTIMATE_EASY = "tx_ultimate_easy"
CONF_UART = "uart" CONF_UART = "uart"
CONF_GANG_COUNT = "gang_count"
CONF_ON_TOUCH_EVENT = "on_touch_event" CONF_ON_TOUCH_EVENT = "on_touch_event"
CONF_ON_PRESS = "on_press" CONF_ON_PRESS = "on_press"
@@ -33,6 +34,7 @@ CONFIG_SCHEMA = cv.Schema({
cv.GenerateID(): cv.declare_id(TxUltimateTouch), cv.GenerateID(): cv.declare_id(TxUltimateTouch),
cv.Required(CONF_UART): cv.use_id(uart), cv.Required(CONF_UART): cv.use_id(uart),
cv.Optional(CONF_GANG_COUNT, default=1): cv.int_range(min=1, max=4),
cv.Optional(CONF_ON_TOUCH_EVENT): automation.validate_automation(single=True), cv.Optional(CONF_ON_TOUCH_EVENT): automation.validate_automation(single=True),
cv.Optional(CONF_ON_PRESS): automation.validate_automation(single=True), cv.Optional(CONF_ON_PRESS): automation.validate_automation(single=True),
@@ -49,6 +51,9 @@ async def register_tx_ultimate_easy(var, config):
uart_component = await cg.get_variable(config[CONF_UART]) uart_component = await cg.get_variable(config[CONF_UART])
cg.add(var.set_uart_component(uart_component)) cg.add(var.set_uart_component(uart_component))
if CONF_GANG_COUNT in config:
cg.add(var.set_gang_count(config[CONF_GANG_COUNT]))
if CONF_ON_TOUCH_EVENT in config: if CONF_ON_TOUCH_EVENT in config:
await automation.build_automation( await automation.build_automation(
var.get_trigger_touch_event(), var.get_trigger_touch_event(),
@@ -98,6 +103,7 @@ async def register_tx_ultimate_easy(var, config):
config[CONF_ON_LONG_TOUCH_RELEASE], config[CONF_ON_LONG_TOUCH_RELEASE],
) )
async def to_code(config): async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID]) var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config) await cg.register_component(var, config)

View File

@@ -48,6 +48,35 @@ namespace esphome {
void TxUltimateEasy::dump_config() { void TxUltimateEasy::dump_config() {
ESP_LOGCONFIG(TAG, "TX Ultimate Easy"); ESP_LOGCONFIG(TAG, "TX Ultimate Easy");
ESP_LOGCONFIG(TAG, " Gang count: %" PRIu8, this->gang_count_);
}
bool TxUltimateEasy::set_gang_count(const uint8_t gang_count) {
// Hardware supports maximum of 4 touch-sensitive buttons
if (gang_count < 1 or gang_count > 4)
return false;
this->gang_count_ = gang_count;
return true;
}
uint8_t TxUltimateEasy::get_button_from_position(const uint8_t position) {
// Validate position bounds
if (position > TOUCH_MAX_POSITION)
return 0;
// Special case for single gang (only one button exists)
if (this->gang_count_ == 1)
return 1;
// Calculate button number
const uint8_t width = (TOUCH_MAX_POSITION + 1) / this->gang_count_; // Width of each button region
if (width < 1 or width > this->gang_count_) // Invalid width - and prevents division by zero
return 0;
const uint8_t button = std::min(
static_cast<uint8_t>((position / width) + 1), // Convert position to button index
this->gang_count_ // Clamp to max gang count
);
return button;
} }
void TxUltimateEasy::send_touch_(TouchPoint tp) { void TxUltimateEasy::send_touch_(TouchPoint tp) {
@@ -103,6 +132,7 @@ namespace esphome {
state == TOUCH_STATE_SWIPE_LEFT || state == TOUCH_STATE_SWIPE_LEFT ||
state == TOUCH_STATE_SWIPE_RIGHT || state == TOUCH_STATE_SWIPE_RIGHT ||
state == TOUCH_STATE_MULTI_TOUCH) && state == TOUCH_STATE_MULTI_TOUCH) &&
// Multi-touch events may have x < 0, all other events require valid x position
(uart_received_bytes[6] >= 0 || state == TOUCH_STATE_MULTI_TOUCH); (uart_received_bytes[6] >= 0 || state == TOUCH_STATE_MULTI_TOUCH);
} }
@@ -133,6 +163,8 @@ namespace esphome {
TouchPoint TxUltimateEasy::get_touch_point(const std::array<int, UART_RECEIVED_BYTES_SIZE> &uart_received_bytes) { TouchPoint TxUltimateEasy::get_touch_point(const std::array<int, UART_RECEIVED_BYTES_SIZE> &uart_received_bytes) {
TouchPoint tp; TouchPoint tp;
tp.x = this->get_touch_position_x(uart_received_bytes); tp.x = this->get_touch_position_x(uart_received_bytes);
if (tp.x >= 0)
tp.button = this->get_button_from_position(static_cast<uint8_t>(tp.x));
tp.state = this->get_touch_state(uart_received_bytes); tp.state = this->get_touch_state(uart_received_bytes);
switch (tp.state) { switch (tp.state) {
case TOUCH_STATE_RELEASE: case TOUCH_STATE_RELEASE:

View File

@@ -13,6 +13,9 @@
namespace esphome { namespace esphome {
namespace tx_ultimate_easy { namespace tx_ultimate_easy {
// Touch Max Position
constexpr uint8_t TOUCH_MAX_POSITION = 10;
// Touch State Constants // Touch State Constants
constexpr uint8_t TOUCH_STATE_RELEASE = 0x01; constexpr uint8_t TOUCH_STATE_RELEASE = 0x01;
constexpr uint8_t TOUCH_STATE_PRESS = 0x02; constexpr uint8_t TOUCH_STATE_PRESS = 0x02;
@@ -32,6 +35,7 @@ namespace esphome {
static const char *TAG = "tx_ultimate_easy"; static const char *TAG = "tx_ultimate_easy";
struct TouchPoint { struct TouchPoint {
uint8_t button = 0;
int8_t x = -1; int8_t x = -1;
int8_t state = -1; int8_t state = -1;
std::string state_str = "Unknown"; std::string state_str = "Unknown";
@@ -53,6 +57,10 @@ namespace esphome {
void loop() override; void loop() override;
void dump_config() override; void dump_config() override;
uint8_t get_gang_count() { return this->gang_count_; }
bool set_gang_count(const uint8_t gang_count);
uint8_t get_button_from_position(const uint8_t position);
protected: protected:
void send_touch_(TouchPoint tp); void send_touch_(TouchPoint tp);
void handle_touch(const std::array<int, UART_RECEIVED_BYTES_SIZE> &bytes); void handle_touch(const std::array<int, UART_RECEIVED_BYTES_SIZE> &bytes);
@@ -70,6 +78,8 @@ namespace esphome {
Trigger<TouchPoint> trigger_multi_touch_release_; Trigger<TouchPoint> trigger_multi_touch_release_;
Trigger<TouchPoint> trigger_long_touch_release_; Trigger<TouchPoint> trigger_long_touch_release_;
uint8_t gang_count_ = 1;
}; // class TxUltimateEasy }; // class TxUltimateEasy
} // namespace tx_ultimate_easy } // namespace tx_ultimate_easy

236
docs/events.md Normal file
View File

@@ -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.

76
versioning/README.md Normal file
View File

@@ -0,0 +1,76 @@
# Versioning
## Overview
This project uses a time-based versioning scheme: `year.month.sequential_number`.
The system automates version updates and tagging to ensure consistent, conflict-free management of releases.
### Examples
- `2024.1.1` First release of January 2024.
- `2024.12.2` Second release of December 2024.
## How It Works
1. **Temporary Branch Creation**: A unique branch is created for each workflow run.
2. **Version Update**: The workflow updates the `VERSION` and `VERSION_YAML` files using the current date and release sequence.
3. **Commit with Marker**: Changes are committed with a `[skip-versioning]` marker to prevent triggering the workflow again.
4. **Merge into Main**: The temporary branch is merged into `main`.
5. **Branch Cleanup**: The temporary branch is deleted after merging.
## Usage
### Automated Workflow
The versioning process is fully automated:
- Developers submit their changes as usual.
- The workflow handles version updates, tagging, and integration into `main`.
- No manual intervention is needed for versioning.
### Accessing the Version in Code
The version is accessible in the ESPHome YAML configuration file (`TX-Ultimate-Easy-ESPHome_core.yaml`) using the following syntax:
```yaml
substitutions:
version: <<: !include ../versioning/VERSION
```
This ensures the correct version is dynamically included in the ESPHome setup.
## Benefits
- **Clarity**: Easily track when a release occurred with meaningful version numbers.
- **Automation**: Eliminates manual version management.
- **Scalability**: Supports frequent updates and concurrent workflows.
- **Traceability**: Maintains a clear history of changes through Git tags and version files.
## System Details
### Version Format
The format `year.month.sequential_number` includes:
- `year` (YYYY): A 4-digit number representing the year.
- `month` (M): A number from 1 to 12 (no leading zeros).
- `sequential_number`: A positive number incremented with each release in the same month.
### Validation Rules
The `bump_version.sh` script enforces strict validation:
- Year must be a 4-digit number.
- Month must be 112 without leading zeros.
- Sequence must be a positive number without leading zeros.
If validation fails, the workflow stops and provides an error message.
### GitHub Workflow
The workflow is triggered automatically when:
- Changes are pushed to `main`.
- Developers trigger it manually using the `workflow_dispatch` event.
The workflow avoids infinite loops by committing changes with the `[skip-versioning]` marker.
## Extending the System
Consider extending the system to:
- Automatically generate release notes or changelogs.
- Notify stakeholders when a new version is released.
- Integrate versioning information into deployment pipelines.
## FAQ
**Q: What happens if two workflows run concurrently?**
A: Each workflow operates in its own temporary branch, avoiding conflicts.
**Q: Can I manually update the version?**
A: Manual updates are not needed. The workflow ensures accurate, automated versioning.

1
versioning/VERSION Normal file
View File

@@ -0,0 +1 @@
2024.12.16

1
versioning/VERSION_YAML Normal file
View File

@@ -0,0 +1 @@
version: 2024.12.16

View File

@@ -0,0 +1,54 @@
#!/bin/bash
VERSION_FILE="./versioning/VERSION"
VERSION_YAML_FILE="./versioning/VERSION_YAML"
# Read the current version
if [ -f "$VERSION_FILE" ]; then
CURRENT_VERSION=$(cat "$VERSION_FILE")
else
CURRENT_VERSION="0.0.0" # Default if file doesn't exist
fi
# Validate the current version format
if ! [[ "$CURRENT_VERSION" =~ ^[0-9]{4}\.[0-9]{1,2}\.[0-9]+$ ]]; then
echo "Error: Invalid version format in $VERSION_FILE"
exit 1
fi
# Extract components
CURRENT_YEAR=$(date +%Y)
CURRENT_MONTH=$(date +%-m) # Avoid leading zero for the month
CURRENT_SEQ=$(echo "$CURRENT_VERSION" | awk -F. '{print $3}')
VERSION_YEAR=$(echo "$CURRENT_VERSION" | awk -F. '{print $1}')
VERSION_MONTH=$(echo "$CURRENT_VERSION" | awk -F. '{print $2}')
# Determine new version
if [[ "$CURRENT_YEAR" == "$VERSION_YEAR" && "$CURRENT_MONTH" == "$VERSION_MONTH" ]]; then
NEXT_SEQ=$((CURRENT_SEQ + 1))
else
NEXT_SEQ=1 # Reset sequence for a new month
fi
NEW_VERSION="${CURRENT_YEAR}.${CURRENT_MONTH}.${NEXT_SEQ}"
# Update the plain text VERSION file
echo "$NEW_VERSION" > "$VERSION_FILE"
# Update the YAML VERSION_YAML file
echo "version: $NEW_VERSION" > "$VERSION_YAML_FILE"
# Commit and tag
if ! git add "$VERSION_FILE" "$VERSION_YAML_FILE"; then
echo "Error: Failed to stage version files"
exit 1
fi
if ! git commit -m "Bump version to $NEW_VERSION [skip-versioning]"; then
echo "Error: Failed to commit version bump"
exit 1
fi
if ! git tag "v$NEW_VERSION"; then
echo "Error: Failed to create version tag"
exit 1
fi