Compare commits

...

117 Commits

Author SHA1 Message Date
GitHub Actions
db83050d7b Bump version to 2025.8.2 [skip-versioning] 2025-08-02 22:10:08 +00:00
Edward Firmo
d7dcc05506 Merge pull request #119 from edwardtfn/stable_tag_update
Return last position on swipe
2025-08-03 00:09:59 +02:00
Edward Firmo
b6dc915469 use main also for advanced 2025-08-02 23:55:52 +02:00
Edward Firmo
dcc68f7077 Revert defaults 2025-08-02 23:53:13 +02:00
Edward Firmo
23d28a32a3 Improved readability 2025-08-02 23:50:42 +02:00
Edward Firmo
ba8f19060f Declare variable used in the loop 2025-08-02 23:40:01 +02:00
Edward Firmo
c36af8a220 Return last position on swipe
As per #110
2025-08-02 23:26:49 +02:00
Edward Firmo
6fad9d7074 Update stable tag automatically
To make it easier to release.
I will point users to `main` instead.
2025-08-02 22:58:11 +02:00
GitHub Actions
f79ed28364 Bump version to 2025.8.1 [skip-versioning] 2025-08-01 08:22:09 +00:00
Edward Firmo
11807ce892 Merge pull request #112 from edwardtfn/idf-as-default
Set ESP-IDF as default framework
2025-08-01 10:22:00 +02:00
Edward Firmo
526b257ad6 Use github.event.inputs.skip_dev 2025-08-01 09:28:42 +02:00
Edward Firmo
0a95a7f8d0 Fix typo on std::string 2025-08-01 09:10:58 +02:00
Edward Firmo
6687c5c6a5 Fix other references to gang_count_plural_suffix 2025-08-01 09:01:37 +02:00
Edward Firmo
ad92799035 Remove gang_count_plural_suffix and set audio channel to mono 2025-08-01 08:51:33 +02:00
Edward Firmo
8e4bbda412 Fix totals 2025-07-31 13:29:34 +02:00
Edward Firmo
8eaa60b5c0 Update totals 2025-07-31 13:14:11 +02:00
Edward Firmo
334932c6c8 Completely remove media player specific tests 2025-07-31 11:24:33 +02:00
Edward Firmo
0480f2ddf3 Media player is already part of standard package 2025-07-31 11:22:29 +02:00
Edward Firmo
720cf3ab36 Ensure tests call the right media player code 2025-07-31 11:18:40 +02:00
Edward Firmo
9edd43079b Use globals for persistence 2025-07-31 10:58:22 +02:00
Edward Firmo
a67f3dfd4a Removed initial value for volume control 2025-07-31 10:34:03 +02:00
Edward Firmo
796eb7620c Remember Media Player volume 2025-07-31 10:26:37 +02:00
Edward Firmo
e53334ac18 Clarify support to bluetooth_proxy 2025-07-31 07:21:48 +02:00
GitHub Actions
7d2080cd8d Bump version to 2025.7.3 [skip-versioning] 2025-07-31 03:20:55 +00:00
Edward Firmo
efd44fab02 Merge pull request #115 from MorghusDragon/correctly-looping-rainbow-effect
Fix rainbow effect loop by setting correct width per model.
2025-07-31 05:20:44 +02:00
Edward Firmo
8422168837 Remove effects from smaller segments 2025-07-30 19:34:56 +02:00
Edward Firmo
0b7f83ebca Add anchor per model 2025-07-30 19:15:39 +02:00
Edward Firmo
5aecb343f6 Return full audio settings 2025-07-30 19:00:54 +02:00
Edward Firmo
a4340da836 Lint 2025-07-30 07:31:17 +02:00
Edward Firmo
912607d1ec Refine speaker settings for esp-idf
Solves #95
2025-07-30 07:28:05 +02:00
Edward Firmo
ba041a9d50 Set audio channel to mono 2025-07-29 21:19:21 +02:00
Edward Firmo
b99a6b8c54 Fail-fast - Test basic before hardware 2025-07-29 16:06:11 +02:00
Edward Firmo
29b292bf45 Fix dependencies 2025-07-29 16:00:40 +02:00
Edward Firmo
4c0a83851e Test basic on dev 2025-07-29 15:54:34 +02:00
Edward Firmo
9663f295d5 Lint 2025-07-29 15:44:22 +02:00
Edward Firmo
4707506c74 Fix grouping 2025-07-29 15:40:49 +02:00
Edward Firmo
5b77f44ae2 Lint 2025-07-29 15:33:54 +02:00
Edward Firmo
efd4eaa6bb Detailed summary 2025-07-29 15:26:04 +02:00
Edward Firmo
bc0b775df2 A bit more reorg 2025-07-29 15:21:48 +02:00
Edward Firmo
ddfd4b3220 Add environment names 2025-07-29 15:12:35 +02:00
Edward Firmo
54ac959abb Org test back on platform-centric 2025-07-29 15:07:06 +02:00
Edward Firmo
9fdfd52ad4 Resolve conflict with PR#116 2025-07-29 14:58:48 +02:00
Edward Firmo
e326f03502 Merge branch 'main' into idf-as-default 2025-07-29 14:55:53 +02:00
GitHub Actions
754ad9cffe Bump version to 2025.7.2 [skip-versioning] 2025-07-29 12:54:52 +00:00
Edward Firmo
637f47583a Merge pull request #116 from MorghusDragon/fix-incorrect-multitouch-trigger-when-swiping
Fix incorrect triggering of multitouch event when swiping
2025-07-29 14:54:39 +02:00
Edward Firmo
bd86371453 Lint 2025-07-29 14:48:06 +02:00
Edward Firmo
54c9119a63 Test basic first 2025-07-29 14:45:52 +02:00
Morghus
2d1ef49ca9 Fix incorrect triggering of multitouch event when swiping 2025-07-29 20:58:44 +12:00
Morghus
1190802ccd Extract base light effect configuration so it can be customized per model. 2025-07-29 20:51:32 +12:00
Edward Firmo
2cc8199593 No limits on the core tests 2025-07-29 10:46:41 +02:00
Edward Firmo
669a78a427 Reorg tests 2025-07-29 10:39:06 +02:00
Edward Firmo
78d820d91e Remove BLE proxy addon 2025-07-29 10:35:11 +02:00
Edward Firmo
a8277e5b88 Fail-fast tests 2025-07-29 10:33:56 +02:00
Edward Firmo
458273206d Test idf first 2025-07-29 10:26:03 +02:00
Edward Firmo
982c64c1c1 Use latest (main) for all actions 2025-07-29 10:22:11 +02:00
Edward Firmo
66d1b27c0d Run tests on every push 2025-07-29 10:15:41 +02:00
Edward Firmo
f9da912777 Test Media player under IDF and unify ESPHome tests 2025-07-29 10:13:18 +02:00
Edward Firmo
6d663323e5 Simplify tests in a matrix
To make it easier to maintain
2025-07-29 10:06:46 +02:00
Edward Firmo
122cfff8db Fix compiler key name 2025-07-29 09:50:19 +02:00
Edward Firmo
70a054616c Remove old code 2025-07-29 09:39:49 +02:00
Edward Firmo
5957e277b7 Remove mapping on !lambda calls 2025-07-29 09:31:35 +02:00
Edward Firmo
7e070617ae Rebuild homeassistant.event calls
To support ESPHome 2025.8
2025-07-29 09:28:57 +02:00
Edward Firmo
50a11f61ff Removed allow_other_uses for pin 26 2025-07-29 09:20:05 +02:00
Edward Firmo
97b193d7c3 Add notice about migration to ESP-IDF 2025-07-29 09:15:49 +02:00
Edward Firmo
644ba8e711 Add test against ESPHome Dev 2025-07-29 09:05:29 +02:00
Edward Firmo
36b28a2475 Make media player dependent on speaker 2025-07-29 09:03:45 +02:00
Edward Firmo
1bd51f304d Deprecate BLE proxy addon package
This kind of solves #9

Replace TX-Ultimate-Easy-ESPHome_addon_ble_proxy.yaml with compilation
error to force migration to direct bluetooth_proxy configuration.

BREAKING CHANGE: Configurations including this package will fail to
compile. Users must remove the package reference and add bluetooth_proxy
directly to their YAML.

Before:
  packages:
    addon_bluetooth_proxy: !include TX-Ultimate-Easy-ESPHome_addon_ble_proxy.yaml

After:
  bluetooth_proxy:
2025-07-29 09:00:38 +02:00
Edward Firmo
680042a428 Replaces i2s_audio.media_player by i2s_audio.speaker.media_player 2025-07-29 08:44:46 +02:00
Edward Firmo
0a3ceb97f5 No special settings for IDF 2025-07-14 13:54:07 +02:00
Edward Firmo
daaffdb6ca Set ESP-IDF as default framework 2025-07-14 13:51:21 +02:00
GitHub Actions
ffdb3a22b5 Bump version to 2025.7.1 [skip-versioning] 2025-07-09 22:42:27 +00:00
Edward Firmo
b426bdd5dc Merge pull request #111 from edwardtfn/remove-duplicated-names
Support to ESPHome 2025.7.0
2025-07-10 00:42:19 +02:00
Edward Firmo
3cdd9f87af Standardize std::to_string 2025-07-10 00:29:34 +02:00
Edward Firmo
ddb26cd833 Test with recommended IDF only 2025-07-10 00:13:56 +02:00
Edward Firmo
5ea4f2015b Support to ESPHome 2025.7.0
- Resolve duplicated names
- Rebuilt HA event calls
2025-07-09 23:36:54 +02:00
GitHub Actions
ddb5e0f783 Bump version to 2025.5.1 [skip-versioning] 2025-05-14 19:19:50 +00:00
Edward Firmo
ab078f597a Merge pull request #106 from edwardtfn/dev
Remove enforcing psram mode to octal
2025-05-14 21:19:39 +02:00
Edward Firmo
5eb42082db Remove rmt_channel
Not supported with IDF 5
2025-05-14 21:07:07 +02:00
Edward Firmo
b1a978b3f3 Remove rmt_channel
Not supported with IDF 5
2025-05-14 20:57:58 +02:00
Edward Firmo
4ec44e611f Merge branch 'main' into dev 2025-05-02 18:30:35 +02:00
Edward Firmo
4d7895a2e9 Remove enforcing psram mode to octal
Solves #105
2025-05-02 18:29:07 +02:00
GitHub Actions
be76ebd603 Bump version to 2025.3.1 [skip-versioning] 2025-03-21 19:08:53 +00:00
Edward Firmo
49a0f088e7 Merge pull request #101 from edwardtfn/edwardtfn-patch-1
Remove reference to tj-actions
2025-03-21 20:08:45 +01:00
Edward Firmo
ace945a4ea Update validate_yamllint.yml 2025-03-15 18:23:25 +01:00
Edward Firmo
e944cd2c21 Remove reference to tj-actions
Security reasons
2025-03-15 18:19:32 +01:00
GitHub Actions
1cf6f60c78 Bump version to 2025.1.4 [skip-versioning] 2025-01-07 07:49:22 +00:00
Edward Firmo
58ba5e0136 Merge pull request #92 from edwardtfn/fix-name-CORE-is-not-defined
Fix missing `add_idf_sdkconfig_option`
2025-01-07 08:49:12 +01:00
Edward Firmo
b0b19fee45 Fix missing add_idf_sdkconfig_option 2025-01-07 08:48:38 +01:00
GitHub Actions
fe222ffe32 Bump version to 2025.1.3 [skip-versioning] 2025-01-07 07:17:53 +00:00
Edward Firmo
bb09d7f7f7 Merge pull request #91 from edwardtfn/fix-name-CORE-is-not-defined
Fix `name 'CORE' is not defined`
2025-01-07 08:17:42 +01:00
Edward Firmo
b6e3f41952 Fix name 'CORE' is not defined 2025-01-07 08:15:27 +01:00
GitHub Actions
ba3fc89032 Bump version to 2025.1.2 [skip-versioning] 2025-01-06 16:01:26 +00:00
Edward Firmo
fcbc92aaec Merge pull request #88 from edwardtfn/revert-to-media-player-as-default
Revert to media player and neopixelbus as default
2025-01-06 17:01:15 +01:00
GitHub Actions
a59f667e7d Bump version to 2025.1.1 [skip-versioning] 2025-01-06 16:00:59 +00:00
Edward Firmo
ff3bf05ed1 Merge pull request #90 from Matthijs33/patch-1
Fix value for multi_touch event publishing
2025-01-06 17:00:46 +01:00
Edward Firmo
8a4009dd7e Move sdkconfig_options to component 2025-01-05 12:58:45 +01:00
Edward Firmo
6bdf6e97b7 Move sdkconfig to component 2025-01-05 12:51:22 +01:00
Edward Firmo
acb602c4ca Lint 2025-01-05 12:44:48 +01:00
Edward Firmo
9bae016573 Lint 2025-01-05 12:43:08 +01:00
Edward Firmo
e47726dc47 Advanced settings with granular package selection
Resolves #86
2025-01-05 12:40:52 +01:00
Edward Firmo
5988681132 Include common 2025-01-05 11:02:46 +01:00
Edward Firmo
5d80ce1117 Do not remove attributes twice 2025-01-05 01:34:18 +01:00
Edward Firmo
036e62b277 Remove check for framework type 2025-01-05 01:06:52 +01:00
Edward Firmo
56c613a70f Remove sw_speaker_amplifier when the media_player is removed 2025-01-05 00:54:48 +01:00
Edward Firmo
12fd2d3747 Lint 2025-01-05 00:38:30 +01:00
Edward Firmo
81f0420987 Lint 2025-01-05 00:37:05 +01:00
Edward Firmo
e89adca5cb Remove reference to esphome_fw_version 2025-01-05 00:34:40 +01:00
Edward Firmo
a64c45b37b Media Player is not compatible with IDF 2025-01-04 23:58:05 +01:00
Edward Firmo
95291c0381 Remove non-essential packages 2025-01-04 23:54:35 +01:00
Edward Firmo
39cf0f2b10 Do not remove media player from core 2025-01-04 22:58:09 +01:00
Edward Firmo
8d03105caf Reorg tests 2025-01-04 22:54:08 +01:00
Edward Firmo
e911482deb Lint 2025-01-04 22:39:31 +01:00
Edward Firmo
ef4f412223 Split extensions 2025-01-04 22:38:19 +01:00
Edward Firmo
9d64b099a4 Lint 2025-01-04 22:34:38 +01:00
Edward Firmo
037801e961 Revert to media player and neopixelbus 2025-01-04 22:31:14 +01:00
Edward Firmo
79b57304c7 Point users to stable tag. 2025-01-03 22:53:46 +01:00
Matthijs33
48ddfbf8b0 Update TX-Ultimate-Easy-ESPHome_core_hw_touch.yaml
fixes #74
Value was "OFF" instead of "ON"
2025-01-01 14:32:17 +01:00
47 changed files with 1270 additions and 1250 deletions

View File

@@ -1,12 +1,36 @@
---
name: Validate ESPHome (Latest)
name: Validate ESPHome
permissions:
contents: read
pull-requests: read
on: # yamllint disable-line rule:truthy
push:
paths:
- "**/*.yml"
- "**/*.yaml"
- "**/*.h"
- "**/*.cpp"
- "**/*.c"
- "**/*.py"
pull_request:
paths:
- "**/*.yml"
- "**/*.yaml"
- "**/*.h"
- "**/*.cpp"
- "**/*.c"
- "**/*.py"
workflow_dispatch:
inputs:
skip_dev:
description: 'Skip dev testing (test only on latest)'
required: false
default: false
type: boolean
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
@@ -15,250 +39,383 @@ concurrency:
jobs:
code_scan:
name: Code scan (YAML)
runs-on: "ubuntu-latest"
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@main
- name: Setup Python
uses: actions/setup-python@main
with:
python-version: '3.8'
python-version: '3.11'
- name: Install Yamllint
run: pip install yamllint
- name: Validate YAML files
run: find . -name "*.yaml" -exec yamllint -c ./.rules/yamllint.yml {} +
# Arduino Framework - Foundation (latest)
build_ard_core:
name: Core (Arduino)
name: "🏗️ Arduino Core (latest)"
needs: code_scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build Core (Arduino)
- name: Build Arduino Core - latest
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_ard_core.yaml"
version: latest
build_idf_core:
name: Core (IDF)
needs: code_scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build Core (IDF)
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_idf_core.yaml"
version: latest
build_idf53_core:
name: Core (IDF v5.3)
needs: code_scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build Core (IDF v5.3)
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_idf53_core.yaml"
version: latest
build_ard_basic:
name: Basic (Arduino)
name: "📦 Arduino Basic (latest)"
needs: build_ard_core
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build Basic (Arduino)
- name: Build Arduino Basic - latest
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_ard_basic.yaml"
version: latest
build_idf_basic:
name: Basic (IDF)
needs: build_idf_core
build_ard_basic_dev:
name: "📦 Arduino Basic (dev)"
needs: build_ard_core
if: success() && !github.event.inputs.skip_dev
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build Basic (IDF)
- name: Build Arduino Basic - dev
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_idf_basic.yaml"
version: latest
build_idf53_basic:
name: Basic (IDF v5.3)
needs: build_idf53_core
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build Basic (IDF v5.3)
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_idf53_basic.yaml"
version: latest
yaml-file: ".test/esphome_ard_basic.yaml"
version: dev
build_ard_hw_relays:
name: HW Relays (Arduino)
needs: build_ard_core
name: "🔌 Arduino HW Relays (latest)"
needs: build_ard_basic
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build HW Relays (Arduino)
- name: Build Arduino HW Relays - latest
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_ard_hw_relays.yaml"
version: latest
build_idf_hw_relays:
name: HW Relays (IDF)
needs: build_idf_core
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build HW Relays (IDF)
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_idf_hw_relays.yaml"
version: latest
build_idf53_hw_relays:
name: HW Relays (IDF v5.3)
needs: build_idf53_core
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build HW Relays (IDF v5.3)
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_idf53_hw_relays.yaml"
version: latest
build_ard_hw_speaker:
name: HW Speaker (Arduino)
needs: build_ard_core
name: "🔌 Arduino HW Speaker (latest)"
needs: build_ard_basic
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build HW Speaker (Arduino)
- name: Build Arduino HW Speaker - latest
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_ard_hw_speaker.yaml"
version: latest
build_idf_hw_speaker:
name: HW Speaker (IDF)
needs: build_idf_core
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build HW Speaker (IDF)
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_idf_hw_speaker.yaml"
version: latest
build_idf53_hw_speaker:
name: HW Speaker (IDF v5.3)
needs: build_idf53_core
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build HW Speaker (IDF v5.3)
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_idf53_hw_speaker.yaml"
version: latest
build_ard_hw_vibration:
name: HW Vibration (Arduino)
needs: build_ard_core
name: "🔌 Arduino HW Vibration (latest)"
needs: build_ard_basic
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build HW Vibration (Arduino)
- name: Build Arduino HW Vibration - latest
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_ard_hw_vibration.yaml"
version: latest
build_idf_hw_vibration:
name: HW Vibration (IDF)
needs: build_idf_core
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build HW Vibration (IDF)
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_idf_hw_vibration.yaml"
version: latest
build_idf53_hw_vibration:
name: HW Vibration (IDF v5.3)
needs: build_idf53_core
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build HW Vibration (IDF v5.3)
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_idf53_hw_vibration.yaml"
version: latest
build_ard_ble_proxy:
name: Bluetooth Proxy (Ard)
build_ard_ble_proxy_latest:
name: "⚡ Arduino BLE Proxy (latest)"
needs: build_ard_basic
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build BLE Proxy (Ard)
- name: Build Arduino BLE Proxy - latest
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_ard_ble_proxy.yaml"
version: latest
build_idf_ble_proxy:
name: Bluetooth Proxy (IDF)
build_ard_ble_proxy_dev:
name: "⚡ Arduino BLE Proxy (dev)"
needs: build_ard_basic_dev
if: success() && !github.event.inputs.skip_dev
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build Arduino BLE Proxy - dev
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_ard_ble_proxy.yaml"
version: dev
# IDF Framework - Foundation (latest)
build_idf_core:
name: "🏗️ IDF Core (latest)"
needs: code_scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build IDF Core - latest
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_idf_core.yaml"
version: latest
build_idf_basic:
name: "📦 IDF Basic (latest)"
needs: build_idf_core
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build IDF Basic - latest
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_idf_basic.yaml"
version: latest
build_idf_basic_dev:
name: "📦 IDF Basic (dev)"
needs: build_idf_core
if: success() && !github.event.inputs.skip_dev
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build IDF Basic - dev
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_idf_basic.yaml"
version: dev
build_idf_hw_relays:
name: "🔌 IDF HW Relays (latest)"
needs: build_idf_basic
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build BLE Proxy (IDF)
- name: Build IDF HW Relays - latest
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_idf_hw_relays.yaml"
version: latest
build_idf_hw_speaker:
name: "🔌 IDF HW Speaker (latest)"
needs: build_idf_basic
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build IDF HW Speaker - latest
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_idf_hw_speaker.yaml"
version: latest
build_idf_hw_vibration:
name: "🔌 IDF HW Vibration (latest)"
needs: build_idf_basic
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build IDF HW Vibration - latest
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_idf_hw_vibration.yaml"
version: latest
build_idf_ble_proxy_latest:
name: "⚡ IDF BLE Proxy (latest)"
needs: build_idf_basic
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build IDF BLE Proxy - latest
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_idf_ble_proxy.yaml"
version: latest
build_idf53_ble_proxy:
name: Bluetooth Proxy (IDF v5.3)
needs: build_idf53_basic
build_idf_ble_proxy_dev:
name: "⚡ IDF BLE Proxy (dev)"
needs: build_idf_basic_dev
if: success() && !github.event.inputs.skip_dev
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build BLE Proxy (IDF v5.3)
- name: Build IDF BLE Proxy - dev
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_idf53_ble_proxy.yaml"
version: latest
yaml-file: ".test/esphome_idf_ble_proxy.yaml"
version: dev
build_ard_media_player:
name: Media Player (Ard)
# Summary Jobs - Grouped by framework and environment
summary_arduino:
name: "📊 Arduino Framework"
needs:
- build_ard_core
- build_ard_basic
- build_ard_basic_dev
- build_ard_hw_relays
- build_ard_hw_speaker
- build_ard_hw_vibration
- build_ard_ble_proxy_latest
- build_ard_ble_proxy_dev
if: always()
runs-on: ubuntu-latest
steps:
- name: Arduino Framework Results
run: |
SUCCESS=0
TOTAL=0
# Count latest builds (always run)
[ "${{ needs.build_ard_core.result }}" == "success" ] && SUCCESS=$((SUCCESS + 1))
[ "${{ needs.build_ard_basic.result }}" == "success" ] && SUCCESS=$((SUCCESS + 1))
[ "${{ needs.build_ard_hw_relays.result }}" == "success" ] && SUCCESS=$((SUCCESS + 1))
[ "${{ needs.build_ard_hw_speaker.result }}" == "success" ] && SUCCESS=$((SUCCESS + 1))
[ "${{ needs.build_ard_hw_vibration.result }}" == "success" ] && SUCCESS=$((SUCCESS + 1))
[ "${{ needs.build_ard_ble_proxy_latest.result }}" == "success" ] && SUCCESS=$((SUCCESS + 1))
TOTAL=$((TOTAL + 6))
# Count dev builds (if not skipped)
if [ "${{ github.event.inputs.skip_dev }}" != "true" ]; then
[ "${{ needs.build_ard_basic_dev.result }}" == "success" ] && SUCCESS=$((SUCCESS + 1))
[ "${{ needs.build_ard_ble_proxy_dev.result }}" == "success" ] && SUCCESS=$((SUCCESS + 1))
TOTAL=$((TOTAL + 2))
fi
echo "🤖 Arduino Framework: $SUCCESS/$TOTAL builds passed"
if [ "$SUCCESS" -eq "$TOTAL" ]; then
echo "✅ All Arduino builds successful!"
else
echo "❌ Some Arduino builds failed"
exit 1
fi
summary_idf:
name: "📊 ESP-IDF Framework"
needs:
- build_idf_core
- build_idf_basic
- build_idf_basic_dev
- build_idf_hw_relays
- build_idf_hw_speaker
- build_idf_hw_vibration
- build_idf_ble_proxy_latest
- build_idf_ble_proxy_dev
if: always()
runs-on: ubuntu-latest
steps:
- name: ESP-IDF Framework Results
run: |
SUCCESS=0
TOTAL=0
# Count latest builds (always run)
[ "${{ needs.build_idf_core.result }}" == "success" ] && SUCCESS=$((SUCCESS + 1))
[ "${{ needs.build_idf_basic.result }}" == "success" ] && SUCCESS=$((SUCCESS + 1))
[ "${{ needs.build_idf_hw_relays.result }}" == "success" ] && SUCCESS=$((SUCCESS + 1))
[ "${{ needs.build_idf_hw_speaker.result }}" == "success" ] && SUCCESS=$((SUCCESS + 1))
[ "${{ needs.build_idf_hw_vibration.result }}" == "success" ] && SUCCESS=$((SUCCESS + 1))
[ "${{ needs.build_idf_ble_proxy_latest.result }}" == "success" ] && SUCCESS=$((SUCCESS + 1))
TOTAL=$((TOTAL + 6))
# Count dev builds (if not skipped)
if [ "${{ github.event.inputs.skip_dev }}" != "true" ]; then
[ "${{ needs.build_idf_basic_dev.result }}" == "success" ] && SUCCESS=$((SUCCESS + 1))
[ "${{ needs.build_idf_ble_proxy_dev.result }}" == "success" ] && SUCCESS=$((SUCCESS + 1))
TOTAL=$((TOTAL + 2))
fi
echo "🔧 ESP-IDF Framework: $SUCCESS/$TOTAL builds passed"
if [ "$SUCCESS" -eq "$TOTAL" ]; then
echo "✅ All ESP-IDF builds successful!"
else
echo "❌ Some ESP-IDF builds failed"
exit 1
fi
summary_latest:
name: "📊 ESPHome (Latest)"
needs:
- build_ard_core
- build_ard_basic
- build_ard_hw_relays
- build_ard_hw_speaker
- build_ard_hw_vibration
- build_ard_ble_proxy_latest
- build_idf_core
- build_idf_basic
- build_idf_hw_relays
- build_idf_hw_speaker
- build_idf_hw_vibration
- build_idf_ble_proxy_latest
if: always()
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build Media Player (Ard)
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_ard_media_player.yaml"
version: latest
- name: Latest ESPHome Results
run: |
SUCCESS=0
TOTAL=12
# Arduino Latest builds
[ "${{ needs.build_ard_core.result }}" == "success" ] && SUCCESS=$((SUCCESS + 1))
[ "${{ needs.build_ard_basic.result }}" == "success" ] && SUCCESS=$((SUCCESS + 1))
[ "${{ needs.build_ard_hw_relays.result }}" == "success" ] && SUCCESS=$((SUCCESS + 1))
[ "${{ needs.build_ard_hw_speaker.result }}" == "success" ] && SUCCESS=$((SUCCESS + 1))
[ "${{ needs.build_ard_hw_vibration.result }}" == "success" ] && SUCCESS=$((SUCCESS + 1))
[ "${{ needs.build_ard_ble_proxy_latest.result }}" == "success" ] && SUCCESS=$((SUCCESS + 1))
# ESP-IDF Latest builds
[ "${{ needs.build_idf_core.result }}" == "success" ] && SUCCESS=$((SUCCESS + 1))
[ "${{ needs.build_idf_basic.result }}" == "success" ] && SUCCESS=$((SUCCESS + 1))
[ "${{ needs.build_idf_hw_relays.result }}" == "success" ] && SUCCESS=$((SUCCESS + 1))
[ "${{ needs.build_idf_hw_speaker.result }}" == "success" ] && SUCCESS=$((SUCCESS + 1))
[ "${{ needs.build_idf_hw_vibration.result }}" == "success" ] && SUCCESS=$((SUCCESS + 1))
[ "${{ needs.build_idf_ble_proxy_latest.result }}" == "success" ] && SUCCESS=$((SUCCESS + 1))
echo "📋 ESPHome (Latest): $SUCCESS/$TOTAL builds passed"
if [ "$SUCCESS" -eq "$TOTAL" ]; then
echo "✅ All builds on latest ESPHome successful!"
else
echo "❌ Some builds on latest ESPHome failed"
exit 1
fi
summary_dev:
name: "📊 ESPHome (Dev)"
needs:
- build_ard_basic_dev
- build_ard_ble_proxy_dev
- build_idf_basic_dev
- build_idf_ble_proxy_dev
if: always() && !github.event.inputs.skip_dev
runs-on: ubuntu-latest
steps:
- name: Dev ESPHome Results
run: |
SUCCESS=0
TOTAL=4
# Arduino Dev builds
[ "${{ needs.build_ard_basic_dev.result }}" == "success" ] && SUCCESS=$((SUCCESS + 1))
[ "${{ needs.build_ard_ble_proxy_dev.result }}" == "success" ] && SUCCESS=$((SUCCESS + 1))
# ESP-IDF Dev builds
[ "${{ needs.build_idf_basic_dev.result }}" == "success" ] && SUCCESS=$((SUCCESS + 1))
[ "${{ needs.build_idf_ble_proxy_dev.result }}" == "success" ] && SUCCESS=$((SUCCESS + 1))
echo "🚀 ESPHome (Dev): $SUCCESS/$TOTAL builds passed"
if [ "$SUCCESS" -eq "$TOTAL" ]; then
echo "✅ All builds on dev ESPHome successful!"
else
echo "❌ Some builds on dev ESPHome failed"
exit 1
fi
...

View File

@@ -1,270 +0,0 @@
---
name: Validate ESPHome (Beta)
permissions:
contents: read
pull-requests: read
on: # yamllint disable-line rule:truthy
push:
paths:
- "**/*.{yml,yaml,h,cpp,c,py}" # Match any file with the extensions in any directory
pull_request:
paths:
- "**/*.{yml,yaml,h,cpp,c,py}" # Match any file with the extensions in any directory
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
code_scan:
name: Code scan (YAML)
runs-on: "ubuntu-latest"
steps:
- name: Checkout Code
uses: actions/checkout@main
- name: Setup Python
uses: actions/setup-python@main
with:
python-version: '3.8'
- name: Install Yamllint
run: pip install yamllint
- name: Validate YAML files
run: find . -name "*.yaml" -exec yamllint -c ./.rules/yamllint.yml {} +
build_ard_core:
name: Core (Arduino)
needs: code_scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build Core (Arduino)
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_ard_core.yaml"
version: beta
build_idf_core:
name: Core (IDF)
needs: code_scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build Core (IDF)
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_idf_core.yaml"
version: beta
build_idf53_core:
name: Core (IDF v5.3)
needs: code_scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build Core (IDF v5.3)
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_idf53_core.yaml"
version: beta
build_ard_basic:
name: Basic (Arduino)
needs: build_ard_core
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build Basic (Arduino)
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_ard_basic.yaml"
version: beta
build_idf_basic:
name: Basic (IDF)
needs: build_idf_core
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build Basic (IDF)
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_idf_basic.yaml"
version: beta
build_idf53_basic:
name: Basic (IDF v5.3)
needs: build_idf53_core
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build Basic (IDF v5.3)
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_idf53_basic.yaml"
version: beta
build_ard_hw_relays:
name: HW Relays (Arduino)
needs: build_ard_core
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build HW Relays (Arduino)
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_ard_hw_relays.yaml"
version: beta
build_idf_hw_relays:
name: HW Relays (IDF)
needs: build_idf_core
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build HW Relays (IDF)
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_idf_hw_relays.yaml"
version: beta
build_idf53_hw_relays:
name: HW Relays (IDF v5.3)
needs: build_idf53_core
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build HW Relays (IDF v5.3)
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_idf53_hw_relays.yaml"
version: beta
build_ard_hw_speaker:
name: HW Speaker (Arduino)
needs: build_ard_core
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build HW Speaker (Arduino)
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_ard_hw_speaker.yaml"
version: beta
build_idf_hw_speaker:
name: HW Speaker (IDF)
needs: build_idf_core
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build HW Speaker (IDF)
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_idf_hw_speaker.yaml"
version: beta
build_idf53_hw_speaker:
name: HW Speaker (IDF v5.3)
needs: build_idf53_core
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build HW Speaker (IDF v5.3)
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_idf53_hw_speaker.yaml"
version: beta
build_ard_hw_vibration:
name: HW Vibration (Arduino)
needs: build_ard_core
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build HW Vibration (Arduino)
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_ard_hw_vibration.yaml"
version: beta
build_idf_hw_vibration:
name: HW Vibration (IDF)
needs: build_idf_core
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build HW Vibration (IDF)
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_idf_hw_vibration.yaml"
version: beta
build_idf53_hw_vibration:
name: HW Vibration (IDF v5.3)
needs: build_idf53_core
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build HW Vibration (IDF v5.3)
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_idf53_hw_vibration.yaml"
version: beta
build_ard_ble_proxy:
name: Bluetooth Proxy (Ard)
needs: build_ard_basic
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build BLE Proxy (Ard)
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_ard_ble_proxy.yaml"
version: beta
build_idf_ble_proxy:
name: Bluetooth Proxy (IDF)
needs: build_idf_basic
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build BLE Proxy (IDF)
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_idf_ble_proxy.yaml"
version: beta
build_idf53_ble_proxy:
name: Bluetooth Proxy (IDF v5.3)
needs: build_idf53_basic
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build BLE Proxy (IDF v5.3)
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_idf53_ble_proxy.yaml"
version: beta
build_ard_media_player:
name: Media Player (Ard)
needs:
- build_ard_basic
- build_ard_hw_relays
- build_ard_hw_vibration
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: Build Media Player (Ard)
uses: esphome/build-action@main
with:
yaml-file: ".test/esphome_ard_media_player.yaml"
version: beta
...

View File

@@ -17,23 +17,28 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@main
uses: actions/checkout@v4
with:
fetch-depth: '0'
fetch-depth: 0 # Ensures full commit history for diff
# https://github.com/marketplace/actions/markdownlint-cli2-action
- name: Identify changed files
uses: tj-actions/changed-files@v41
id: changed-files
with:
files: '**/*.md'
separator: ","
# https://github.com/marketplace/actions/markdownlint-cli2-action
run: |
BASE=${{ github.event.before }}
HEAD=${{ github.sha }}
FILES=$(git diff --name-only $BASE $HEAD -- '**/*.md' | tr '\n' ',')
echo "changed_files=$FILES" >> $GITHUB_ENV
if [[ -n "$FILES" ]]; then
echo "any_changed=true" >> $GITHUB_ENV
else
echo "any_changed=false" >> $GITHUB_ENV
fi
- name: Markdown Lint
uses: DavidAnson/markdownlint-cli2-action@v14
if: steps.changed-files.outputs.any_changed == 'true'
if: env.any_changed == 'true'
with:
globs: ${{ steps.changed-files.outputs.all_changed_files }}
globs: ${{ env.changed_files }}
separator: ","
config: '.rules/.markdownlint.jsonc'
fix: true
@@ -43,15 +48,27 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@main
uses: actions/checkout@v4
with:
fetch-depth: '0'
fetch-depth: 0
- name: Identify changed files
id: changed-files
run: |
BASE=${{ github.event.before }}
HEAD=${{ github.sha }}
FILES=$(git diff --name-only $BASE $HEAD -- '**/*.md' | tr '\n' ',')
echo "changed_files=$FILES" >> $GITHUB_ENV
if [[ -n "$FILES" ]]; then
echo "any_changed=true" >> $GITHUB_ENV
else
echo "any_changed=false" >> $GITHUB_ENV
fi
# https://github.com/gaurav-nelson/github-action-markdown-link-check
- name: Markdown links
uses: gaurav-nelson/github-action-markdown-link-check@v1
if: env.any_changed == 'true'
with:
# yamllint disable-line rule:truthy
check-modified-files-only: yes
config-file: '.rules/mlc_config.json'
base-branch: 'main'

View File

@@ -19,24 +19,29 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@main
uses: actions/checkout@v4
with:
fetch-depth: '0'
fetch-depth: 0 # Ensures full commit history for diff
- name: Identify changed files
uses: tj-actions/changed-files@v41
id: changed-files
with:
files: '**/*.y*ml'
separator: ","
run: |
BASE=${{ github.event.before }}
HEAD=${{ github.sha }}
FILES=$(git diff --name-only $BASE $HEAD -- '**/*.yml' '**/*.yaml' | tr '\n' ',')
echo "changed_files=$FILES" >> $GITHUB_ENV
if [[ -n "$FILES" ]]; then
echo "any_changed=true" >> $GITHUB_ENV
else
echo "any_changed=false" >> $GITHUB_ENV
fi
- name: Validate YAML
if: steps.changed-files.outputs.any_changed == 'true'
if: env.any_changed == 'true'
run: |
IFS=',' read -ra FILES <<< "${{ steps.changed-files.outputs.all_changed_files }}"
IFS=',' read -ra FILES <<< "${{ env.changed_files }}"
for file in "${FILES[@]}"; do
if [[ "$file" =~ ^*\.yaml$ ]] || \
[[ "$file" =~ ^ESPHome/*\.yaml$ ]]; then
if [[ "$file" =~ ^.*\.yaml$ ]] || [[ "$file" =~ ^ESPHome/.*\.yaml$ ]]; then
echo "Skipping $file"
continue
fi

View File

@@ -4,7 +4,6 @@
# 2. Manual dispatch - allows independent control over stable and latest tags
---
name: Version and Tags
on: # yamllint disable-line rule:truthy
@@ -76,7 +75,7 @@ jobs:
# Update tag
NEW_VERSION=$(cat ./versioning/VERSION)
echo "Updating stable tag to $NEW_VERSION"
git tag -fa stable -m "Update stable tag"
git tag -fa stable -m "Update stable tag to $NEW_VERSION"
git push origin stable --force
- name: Update latest tag
@@ -101,6 +100,6 @@ jobs:
# Update tag
NEW_VERSION=$(cat ./versioning/VERSION)
echo "Updating latest tag to $NEW_VERSION"
git tag -fa latest -m "Update latest tag"
git tag -fa latest -m "Update latest tag to $NEW_VERSION"
git push origin latest --force
...

5
.test/common.yaml Normal file
View File

@@ -0,0 +1,5 @@
---
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
...

8
.test/common_ard.yaml Normal file
View File

@@ -0,0 +1,8 @@
---
packages:
common: !include common.yaml
esp32:
framework:
type: arduino
...

8
.test/common_idf.yaml Normal file
View File

@@ -0,0 +1,8 @@
---
packages:
common: !include common.yaml
esp32:
framework:
type: esp-idf
...

View File

@@ -1,13 +1,6 @@
---
packages:
common_arduino: !include common_ard.yaml
core_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml
standard_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_standard.yaml
esp32:
framework:
type: arduino
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
...

View File

@@ -1,14 +1,8 @@
---
packages:
common_arduino: !include common_ard.yaml
core_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml
standard_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_standard.yaml
addon_bluetooth_proxy: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_addon_ble_proxy.yaml
esp32:
framework:
type: arduino
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
bluetooth_proxy:
...

View File

@@ -1,12 +1,5 @@
---
packages:
common_arduino: !include common_ard.yaml
core_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml
esp32:
framework:
type: arduino
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
...

View File

@@ -1,13 +1,6 @@
---
packages:
common_arduino: !include common_ard.yaml
core_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml
standard_hw_relays_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_relays.yaml
esp32:
framework:
type: arduino
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
...

View File

@@ -1,13 +1,6 @@
---
packages:
common_arduino: !include common_ard.yaml
core_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml
standard_hw_speaker_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_speaker.yaml
esp32:
framework:
type: arduino
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
...

View File

@@ -1,13 +1,6 @@
---
packages:
common_arduino: !include common_ard.yaml
core_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml
standard_hw_vibration_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_vibration.yaml
esp32:
framework:
type: arduino
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
...

View File

@@ -1,15 +0,0 @@
---
packages:
core_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml
standard_hw_relays_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_relays.yaml
standard_hw_vibration_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_vibration.yaml
addon_media_player: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_addon_media_player.yaml
esp32:
framework:
type: arduino
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
...

View File

@@ -1,15 +0,0 @@
---
packages:
core_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml
standard_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_standard.yaml
esp32:
framework:
type: esp-idf
version: 5.3.1
platform_version: 6.9.0
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
...

View File

@@ -1,16 +0,0 @@
---
packages:
core_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml
standard_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_standard.yaml
addon_bluetooth_proxy: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_addon_ble_proxy.yaml
esp32:
framework:
type: esp-idf
version: 5.3.1
platform_version: 6.9.0
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
...

View File

@@ -1,14 +0,0 @@
---
packages:
core_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml
esp32:
framework:
type: esp-idf
version: 5.3.1
platform_version: 6.9.0
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
...

View File

@@ -1,15 +0,0 @@
---
packages:
core_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml
standard_hw_relays_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_relays.yaml
esp32:
framework:
type: esp-idf
version: 5.3.1
platform_version: 6.9.0
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
...

View File

@@ -1,15 +0,0 @@
---
packages:
core_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml
standard_hw_speaker_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_speaker.yaml
esp32:
framework:
type: esp-idf
version: 5.3.1
platform_version: 6.9.0
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
...

View File

@@ -1,15 +0,0 @@
---
packages:
core_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml
standard_hw_vibration_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_vibration.yaml
esp32:
framework:
type: esp-idf
version: 5.3.1
platform_version: 6.9.0
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
...

View File

@@ -1,13 +1,6 @@
---
packages:
common_idf: !include common_idf.yaml
core_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml
standard_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_standard.yaml
esp32:
framework:
type: esp-idf
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
...

View File

@@ -1,14 +1,8 @@
---
packages:
common: !include common.yaml
core_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml
standard_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_standard.yaml
addon_bluetooth_proxy: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_addon_ble_proxy.yaml
esp32:
framework:
type: esp-idf
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
bluetooth_proxy:
...

View File

@@ -1,12 +1,5 @@
---
packages:
common_idf: !include common_idf.yaml
core_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml
esp32:
framework:
type: esp-idf
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
...

View File

@@ -1,13 +1,6 @@
---
packages:
common_idf: !include common_idf.yaml
core_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml
standard_hw_relays_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_relays.yaml
esp32:
framework:
type: esp-idf
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
...

View File

@@ -1,13 +1,6 @@
---
packages:
common_idf: !include common_idf.yaml
core_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml
standard_hw_speaker_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_speaker.yaml
esp32:
framework:
type: esp-idf
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
...

View File

@@ -1,13 +1,6 @@
---
packages:
common_idf: !include common_idf.yaml
core_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml
standard_hw_vibration_package: !include ../ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_vibration.yaml
esp32:
framework:
type: esp-idf
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
...

View File

@@ -2,7 +2,7 @@
##### TX Ultimate Easy for ESPHome #####
##### Repository: https://github.com/edwardtfn/TX-Ultimate-Easy #####
####################################################################################################
##### Purpose: ESPHome Core - Hardware - Media player #####
##### Purpose: ESPHome Basic (includes core plus non-essential, but recommended packages) #####
####################################################################################################
##### Author: edwardtfn - https://github.com/edwardtfn - https://buymeacoffee.com/edwardfirmo #####
####################################################################################################
@@ -11,19 +11,9 @@
##### - For normal system use, modifications to this file are NOT required. #####
####################################################################################################
---
i2s_audio:
id: if_i2s_audio
i2s_bclk_pin: GPIO2
i2s_lrclk_pin: GPIO4
media_player:
- id: mp_media_player
name: Media Player
internal: false
platform: i2s_audio
i2s_dout_pin: GPIO15
i2s_audio_id: if_i2s_audio
i2s_comm_fmt: msb # Experimental - It was 'lsb' until v2024.12.12
dac_type: external
mode: mono
packages:
# yamllint disable rule:colons
core: !include TX-Ultimate-Easy-ESPHome_core.yaml
standard: !include TX-Ultimate-Easy-ESPHome_standard.yaml
# yamllint enable rule:colons
...

View File

@@ -2,32 +2,22 @@
##### TX Ultimate Easy for ESPHome #####
##### Repository: https://github.com/edwardtfn/TX-Ultimate-Easy #####
####################################################################################################
##### Purpose: ESPHome Core - Add-on - BLE Proxy #####
##### Purpose: ESPHome Core - Add-on - BLE Proxy (REMOVED) #####
####################################################################################################
##### 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. #####
##### REMOVAL NOTICE: #####
##### This package has been removed. Please update your configuration. #####
##### Add BLE proxy functionality directly in your YAML configuration instead: #####
##### bluetooth_proxy: #####
####################################################################################################
---
bluetooth_proxy:
esphome:
platformio_options:
build_flags:
- -D TX_ULTIMATE_EASY_ADDON_BLE_PROXY
# Trigger the error at compile time
script:
- id: !extend dump_config_list_packages
- id: force_compilation_error
then:
- script.wait: dump_config
- lambda: |-
// Check for requirements
#if !defined(TX_ULTIMATE_EASY_CORE)
#error "The package TX-Ultimate-Easy-ESPHome_core.yaml is required."
#endif
// Identify itself
ESP_LOGCONFIG(ESPHOME_PROJECT_NAME, " - Add-on - BLE Proxy");
#error "The package TX-Ultimate-Easy-ESPHome_addon_ble_proxy.yaml has been removed." \
"Please remove this package from your configuration and add" \
"'bluetooth_proxy:' directly to your YAML instead."
...

View File

@@ -1,68 +0,0 @@
####################################################################################################
##### TX Ultimate Easy for ESPHome #####
##### Repository: https://github.com/edwardtfn/TX-Ultimate-Easy #####
####################################################################################################
##### Purpose: ESPHome - Add-on - Media player #####
####################################################################################################
##### 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. #####
####################################################################################################
---
packages:
standard_hw_audio: !include TX-Ultimate-Easy-ESPHome_standard_hw_audio.yaml
esp32:
framework:
type: arduino
esphome:
platformio_options:
build_flags:
- -D TX_ULTIMATE_EASY_ADDON_MEDIA_PLAYER
media_player:
- id: mp_media_player
name: Media Player
internal: false
platform: i2s_audio
i2s_dout_pin: GPIO15
i2s_audio_id: if_i2s_audio
i2s_comm_fmt: msb
dac_type: external
mode: mono
mute_pin:
number: GPIO26
inverted: true
allow_other_uses: true
script:
- id: !extend dump_config_list_packages
then:
- script.wait: dump_config
- lambda: |-
// Check for requirements
#if !defined(TX_ULTIMATE_EASY_CORE)
#error "The package TX-Ultimate-Easy-ESPHome_core.yaml is required."
#endif
#if !defined(TX_ULTIMATE_EASY_STANDARD_HW_AUDIO)
#error "The package TX-Ultimate-Easy-ESPHome_standard_hw_audio.yaml is required."
#endif
// Identify itself
ESP_LOGCONFIG(ESPHOME_PROJECT_NAME, " - Add-on - Media Player");
switch:
- id: sw_speaker_amplifier
name: Speaker - Amplifier
platform: gpio
pin:
number: GPIO26
inverted: true
allow_other_uses: true
restore_mode: RESTORE_DEFAULT_ON
internal: true
entity_category: config
...

View File

@@ -11,312 +11,11 @@
##### - For normal system use, modifications to this file are NOT required. #####
####################################################################################################
---
substitutions:
name: tx-ultimate-easy
friendly_name: TX Ultimate Easy
<<: !include ../versioning/VERSION_YAML
TX_MODEL_FORMAT_EU_TEXT: "EU (Square, T5-xC-86)"
TX_MODEL_FORMAT_US_TEXT: "US (Rectangle, T5-xC-120)"
TX_MODEL_1_GANG_TEXT: "1 Gang"
TX_MODEL_2_GANG_TEXT: "2 Gang"
TX_MODEL_3_GANG_TEXT: "3 Gang"
TX_MODEL_4_GANG_TEXT: "4 Gang"
DUMP_CONFIG_CALLER_DELAY: 10s # Delay to dump config after requested
packages:
# yamllint disable rule:colons
core_common: !include TX-Ultimate-Easy-ESPHome_core_common.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_touch: !include TX-Ultimate-Easy-ESPHome_core_hw_touch.yaml
# yamllint enable rule:colons
api:
id: api_server
on_client_connected:
then:
- script.execute: dump_config_caller
- script.execute: publish_device_info
binary_sensor:
- id: bs_pending_restart
name: Pending Restart Status
internal: false
disabled_by_default: false
platform: template
entity_category: diagnostic
device_class: problem
on_state:
then:
- lambda: |-
if (x)
ESP_LOGW("core", "Pending restart: YES");
else
ESP_LOGCONFIG("core", "Pending restart: No");
- script.execute: dump_config_caller
esp32:
board: esp32dev # adafruit_feather_esp32_v2 # esp32dev
flash_size: 8MB
framework:
type: esp-idf
esphome:
name: ${name}
friendly_name: ${friendly_name}
comment: TX Ultimate Easy
project:
name: "edwardtfn.tx_ultimate_easy"
version: ${version}
platformio_options:
build_flags:
- -D TX_ULTIMATE_EASY_CORE
on_boot:
- priority: 700
then:
- script.execute: boot_initialize
- priority: 600 # This is where most sensors are set up.
then:
- script.execute: boot_sequence
- priority: -100 # At this priority, pretty much everything should already be initialized.
then:
- 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'
- id: gang_count_plural_suffix
type: std::string
restore_value: true
max_restore_data_length: 3
# initial_value: "''"
logger:
level: DEBUG
ota:
platform: esphome
psram:
mode: octal
speed: 80MHz
script:
- id: api_send_ha_event_boot
mode: queued
parameters:
type: string
then:
- homeassistant.event:
event: esphome.tx_ultimate_easy
data:
device_name: !lambda return tx_device_name->state.c_str();
firmware: ${version}
domain: boot
type: !lambda return type.c_str();
- id: boot_done
mode: restart
then:
- script.execute:
id: api_send_ha_event_boot
type: done
- id: boot_initialize
mode: restart
then:
# Extended by:
# - HW Buttons
# - HW Relays
# - HW Touch
- script.execute:
id: api_send_ha_event_boot
type: start
- wait_until:
condition:
- lambda: return sl_tx_model_format->active_index().has_value();
- lambda: return sl_tx_model_gang->active_index().has_value();
- lambda: |-
id(is_us_model) = (sl_tx_model_format->state == "${TX_MODEL_FORMAT_US_TEXT}");
id(gang_count) = sl_tx_model_gang->active_index().value() + 1;
if (id(gang_count) < 1 || id(gang_count) > 4) {
ESP_LOGE("core_hw_leds", "Invalid number of gangs: %" PRIu8, id(gang_count));
}
id(gang_count_plural_suffix) = id(gang_count) > 1 ? "s" : "";
- id: boot_sequence
mode: restart
then:
- script.execute: publish_device_info
- binary_sensor.template.publish:
id: bs_pending_restart
state: false
- id: dump_config
mode: restart
then:
# Extended by all modules
- lambda: |-
// Device identification
ESP_LOGCONFIG("core", "Device friendly name: ${friendly_name}");
ESP_LOGCONFIG("core", "Device name: ${name}");
ESP_LOGCONFIG("core", "Device name (HA): %s", tx_device_name->state.c_str());
ESP_LOGCONFIG("core", "Device hostname: %s", App.get_name().c_str());
dump_config_versions->execute();
// Framework detection
#ifdef USE_ARDUINO
ESP_LOGCONFIG("core", "Framework: Arduino");
#elif defined(USE_ESP_IDF)
ESP_LOGCONFIG("core", "Framework: ESP-IDF");
#else
ESP_LOGW("core", "Framework: UNKNOWN");
#endif
// Model configuration
ESP_LOGCONFIG("core", "Model format (selected): %s", sl_tx_model_format->state.c_str());
ESP_LOGCONFIG("core", "Model format (detected): %s", id(is_us_model) ? "US" : "EU");
ESP_LOGCONFIG("core", "Gangs (selected): %s", sl_tx_model_gang->state.c_str());
ESP_LOGCONFIG("core", "Gangs (detected): %" PRIu8 "-Gang%s", id(gang_count), id(gang_count_plural_suffix).c_str());
// System state
if (bs_pending_restart->state)
ESP_LOGW("core", "Pending restart: YES");
else
ESP_LOGCONFIG("core", "Pending restart: No");
- id: dump_config_caller
mode: restart
then:
- delay: ${DUMP_CONFIG_CALLER_DELAY}
- script.execute: dump_config
- script.wait: dump_config
- script.execute: dump_config_list_packages
- id: dump_config_list_packages
mode: restart
then:
- script.wait: dump_config
- lambda: |-
ESP_LOGCONFIG(ESPHOME_PROJECT_NAME, "Installed packages:");
// Identify itself
ESP_LOGCONFIG(ESPHOME_PROJECT_NAME, " - Core");
- id: dump_config_versions
mode: restart
then:
- lambda: |-
// Version information
ESP_LOGCONFIG("core", "TX Ultimate firmware version: ${version}");
- id: publish_device_info
mode: restart
then:
- lambda: |-
tx_fw_version->publish_state("${version}");
tx_device_name->publish_state(App.get_name().c_str());
select:
- id: sl_tx_model_format
name: Model (Format)
platform: template
options:
- "${TX_MODEL_FORMAT_EU_TEXT}"
- "${TX_MODEL_FORMAT_US_TEXT}"
initial_option: "${TX_MODEL_FORMAT_EU_TEXT}"
optimistic: true
restore_value: true
internal: false
entity_category: config
disabled_by_default: false
icon: mdi:tablet-cellphone
on_value:
then:
- binary_sensor.template.publish:
id: bs_pending_restart
state: true
- 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
name: Model (Gang)
platform: template
options:
- "${TX_MODEL_1_GANG_TEXT}"
- "${TX_MODEL_2_GANG_TEXT}"
- "${TX_MODEL_3_GANG_TEXT}"
- "${TX_MODEL_4_GANG_TEXT}"
initial_option: "${TX_MODEL_1_GANG_TEXT}"
optimistic: true
restore_value: true
internal: false
entity_category: config
disabled_by_default: false
icon: mdi:dip-switch
on_value:
then:
- binary_sensor.template.publish:
id: bs_pending_restart
state: true
- 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:
- id: tx_fw_version
name: TX Ultimate Easy Firmware Version
platform: template
entity_category: diagnostic
icon: mdi:tag-text-outline
internal: false
update_interval: never
lambda: |-
return {"${version}"};
- id: tx_device_name
name: Device Name
platform: template
icon: mdi:identifier
entity_category: diagnostic
internal: false
disabled_by_default: false
update_interval: never
lambda: |-
return {"${name}"};
filters:
- lambda: |-
const std::string raw_name = x;
std::string result;
bool last_was_underscore = false;
for (const char& c : raw_name) {
if (isalnum(c)) {
result += tolower(c); // Add alphanumeric characters as lowercase
last_was_underscore = false;
} else if (!last_was_underscore) { // Replace non-alphanumeric with '_' but avoid consecutive '_'
result += '_';
last_was_underscore = true;
}
}
return result;
wifi:
id: wifi_component
...

View File

@@ -0,0 +1,319 @@
####################################################################################################
##### TX Ultimate Easy for ESPHome #####
##### Repository: https://github.com/edwardtfn/TX-Ultimate-Easy #####
####################################################################################################
##### Purpose: ESPHome Core - Common #####
####################################################################################################
##### 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. #####
####################################################################################################
---
substitutions:
name: tx-ultimate-easy
friendly_name: TX Ultimate Easy
<<: !include ../versioning/VERSION_YAML
EVENT_NAME: esphome.tx_ultimate_easy
TX_MODEL_FORMAT_EU_TEXT: "EU (Square, T5-xC-86)"
TX_MODEL_FORMAT_US_TEXT: "US (Rectangle, T5-xC-120)"
TX_MODEL_1_GANG_TEXT: "1 Gang"
TX_MODEL_2_GANG_TEXT: "2 Gang"
TX_MODEL_3_GANG_TEXT: "3 Gang"
TX_MODEL_4_GANG_TEXT: "4 Gang"
DUMP_CONFIG_CALLER_DELAY: 10s # Delay to dump config after requested
api:
id: api_server
on_client_connected:
then:
- script.execute: dump_config_caller
- script.execute: publish_device_info
binary_sensor:
- id: bs_pending_restart
name: Pending Restart Status
internal: false
disabled_by_default: false
platform: template
entity_category: diagnostic
device_class: problem
on_state:
then:
- lambda: |-
if (x)
ESP_LOGW("core", "Pending restart: YES");
else
ESP_LOGCONFIG("core", "Pending restart: No");
- script.execute: dump_config_caller
button:
- id: bt_restart
name: Restart
internal: false
platform: restart
esp32:
board: esp32dev
flash_size: 8MB
framework:
type: esp-idf
esphome:
name: ${name}
friendly_name: ${friendly_name}
comment: TX Ultimate Easy
project:
name: "edwardtfn.tx_ultimate_easy"
version: ${version}
platformio_options:
build_flags:
- -D TX_ULTIMATE_EASY_CORE
on_boot:
- priority: 700
then:
- script.execute: boot_initialize
- priority: 600 # This is where most sensors are set up.
then:
- script.execute: boot_sequence
- priority: -100 # At this priority, pretty much everything should already be initialized.
then:
- 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'
logger:
level: DEBUG
ota:
platform: esphome
psram:
script:
- id: api_send_ha_event_boot
mode: queued
parameters:
type: string
then:
- lambda: |-
// Send event to Home Assistant
esphome::api::CustomAPIDevice ha_event;
ha_event.fire_homeassistant_event("${EVENT_NAME}", {
{"device_name", id(tx_device_name).state.c_str()},
{"firmware", "${version}"},
{"domain", "boot"},
{"type", type.c_str()}
});
- id: boot_done
mode: restart
then:
- script.execute:
id: api_send_ha_event_boot
type: done
- id: boot_initialize
mode: restart
then:
# Extended by:
# - HW Buttons
# - HW Relays
# - HW Touch
- script.execute:
id: api_send_ha_event_boot
type: start
- wait_until:
condition:
- lambda: return sl_tx_model_format->active_index().has_value();
- lambda: return sl_tx_model_gang->active_index().has_value();
- lambda: |-
id(is_us_model) = (sl_tx_model_format->state == "${TX_MODEL_FORMAT_US_TEXT}");
id(gang_count) = sl_tx_model_gang->active_index().value() + 1;
if (id(gang_count) < 1 || id(gang_count) > 4) {
ESP_LOGE("core_hw_leds", "Invalid number of gangs: %" PRIu8, id(gang_count));
}
- id: boot_sequence
mode: restart
then:
- script.execute: publish_device_info
- binary_sensor.template.publish:
id: bs_pending_restart
state: false
- id: dump_config
mode: restart
then:
# Extended by all modules
- lambda: |-
// Device identification
ESP_LOGCONFIG("core", "Device friendly name: ${friendly_name}");
ESP_LOGCONFIG("core", "Device name: ${name}");
ESP_LOGCONFIG("core", "Device name (HA): %s", tx_device_name->state.c_str());
ESP_LOGCONFIG("core", "Device hostname: %s", App.get_name().c_str());
dump_config_versions->execute();
// Framework detection
#ifdef USE_ARDUINO
ESP_LOGCONFIG("core", "Framework: Arduino");
#elif defined(USE_ESP_IDF)
ESP_LOGCONFIG("core", "Framework: ESP-IDF");
#else
ESP_LOGW("core", "Framework: UNKNOWN");
#endif
// Model configuration
ESP_LOGCONFIG("core", "Model format (selected): %s", sl_tx_model_format->state.c_str());
ESP_LOGCONFIG("core", "Model format (detected): %s", id(is_us_model) ? "US" : "EU");
ESP_LOGCONFIG("core", "Gangs (selected): %s", sl_tx_model_gang->state.c_str());
ESP_LOGCONFIG("core", "Gangs (detected): %" PRIu8 "-Gang%s", id(gang_count), id(gang_count) > 1 ? "s" : "");
// System state
if (bs_pending_restart->state)
ESP_LOGW("core", "Pending restart: YES");
else
ESP_LOGCONFIG("core", "Pending restart: No");
- id: dump_config_caller
mode: restart
then:
- delay: ${DUMP_CONFIG_CALLER_DELAY}
- script.execute: dump_config
- script.wait: dump_config
- script.execute: dump_config_list_packages
- id: dump_config_list_packages
mode: restart
then:
- script.wait: dump_config
- lambda: |-
ESP_LOGCONFIG(ESPHOME_PROJECT_NAME, "Installed packages:");
// Identify itself
ESP_LOGCONFIG(ESPHOME_PROJECT_NAME, " - Core");
- id: dump_config_versions
mode: restart
then:
- lambda: |-
// Version information
ESP_LOGCONFIG("core", "TX Ultimate firmware version: ${version}");
// ESPHome builder information
ESP_LOGCONFIG("core", "ESPHome builder: " ESPHOME_VERSION);
ESP_LOGCONFIG("core", "ESPHome build timestamp: %s", App.get_compilation_time().c_str());
- id: publish_device_info
mode: restart
then:
- lambda: |-
tx_fw_version->publish_state("${version}");
tx_device_name->publish_state(App.get_name().c_str());
select:
- id: sl_tx_model_format
name: Model (Format)
platform: template
options:
- "${TX_MODEL_FORMAT_EU_TEXT}"
- "${TX_MODEL_FORMAT_US_TEXT}"
initial_option: "${TX_MODEL_FORMAT_EU_TEXT}"
optimistic: true
restore_value: true
internal: false
entity_category: config
disabled_by_default: false
icon: mdi:tablet-cellphone
on_value:
then:
- binary_sensor.template.publish:
id: bs_pending_restart
state: true
- 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
name: Model (Gang)
platform: template
options:
- "${TX_MODEL_1_GANG_TEXT}"
- "${TX_MODEL_2_GANG_TEXT}"
- "${TX_MODEL_3_GANG_TEXT}"
- "${TX_MODEL_4_GANG_TEXT}"
initial_option: "${TX_MODEL_1_GANG_TEXT}"
optimistic: true
restore_value: true
internal: false
entity_category: config
disabled_by_default: false
icon: mdi:dip-switch
on_value:
then:
- binary_sensor.template.publish:
id: bs_pending_restart
state: true
- 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:
- id: tx_fw_version
name: TX Ultimate Easy Firmware Version
platform: template
entity_category: diagnostic
icon: mdi:tag-text-outline
internal: false
update_interval: never
lambda: |-
return {"${version}"};
- id: tx_device_name
name: Device Name
platform: template
icon: mdi:identifier
entity_category: diagnostic
internal: false
disabled_by_default: false
update_interval: never
lambda: |-
return {"${name}"};
filters:
- lambda: |-
const std::string raw_name = x;
std::string result;
bool last_was_underscore = false;
for (const char& c : raw_name) {
if (isalnum(c)) {
result += tolower(c); // Add alphanumeric characters as lowercase
last_was_underscore = false;
} else if (!last_was_underscore) { // Replace non-alphanumeric with '_' but avoid consecutive '_'
result += '_';
last_was_underscore = true;
}
}
return result;
wifi:
id: wifi_component
...

View File

@@ -112,18 +112,19 @@ script:
action: string
count: uint8_t
then:
- 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: |-
// Send event to Home Assistant
esphome::api::CustomAPIDevice ha_event;
ha_event.fire_homeassistant_event("${EVENT_NAME}", {
{"device_name", id(tx_device_name).state.c_str()},
{"firmware", "${version}"},
{"domain", "touch"},
{"type", "button"},
{"action", action.c_str()},
{"button_id", std::to_string(button)},
{"count", std::to_string(count)},
{"position", std::to_string(id(button_press_position))}
});
ESP_LOGI("core_hw_buttons", "Button %" PRIu8 " action: '%s'", button, action.c_str());
if (action == "click") {
switch (button) {
@@ -208,10 +209,11 @@ script:
- id: !extend dump_config
then:
- lambda: |-
std::string gang_count_plural_suffix = id(gang_count) > 1 ? "s" : "";
// Button's actions
ESP_LOGCONFIG("core_hw_buttons", "Button%s action%s:",
id(gang_count_plural_suffix).c_str(),
id(gang_count_plural_suffix).c_str());
gang_count_plural_suffix.c_str(),
gang_count_plural_suffix.c_str());
ESP_LOGCONFIG("core_hw_buttons", " Relay 1: %s", sl_button_1_action->has_state()
? sl_button_1_action->state.c_str()
: "Unknown");

View File

@@ -47,20 +47,22 @@ light:
- id: light_full
name: Light - All
internal: true
platform: esp32_rmt_led_strip
rgb_order: GRB
rmt_channel: 1
chipset: ws2812
num_leds: 32
pin: GPIO13
restore_mode: ${LIGHT_FULL_RESTORE_MODE}
platform: esp32_rmt_led_strip
rgb_order: GRB
chipset: ws2812
max_refresh_rate: 33ms
use_psram: true
use_psram: false
# platform: neopixelbus
# type: GRB
# variant: WS2811
# Those lights are available based on the model selections
- &light_partition_with_effects
- &light_partition_with_effects_eu
id: light_eu
name: Light
name: Light EU
platform: partition
default_transition_length: ${default_transition_length}
internal: true
@@ -68,8 +70,10 @@ light:
effects:
- addressable_rainbow:
name: "Rainbow"
width: 28
- addressable_rainbow:
name: "Rainbow - Fast"
width: 28
speed: 50
- pulse:
name: "Pulse"
@@ -108,35 +112,82 @@ light:
from: 0
to: 27
- id: light_us
name: Light
<<: *light_partition_with_effects
- &light_partition_with_effects_us
id: light_us
name: Light US
platform: partition
default_transition_length: ${default_transition_length}
internal: true
restore_mode: ${LIGHT_SIDES_RESTORE_MODE}
effects:
- addressable_rainbow:
name: "Rainbow"
width: 32
- addressable_rainbow:
name: "Rainbow - Fast"
width: 32
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:
- id: light_full
from: 0
to: 31
- &light_partition_with_effects_disabled
- &light_partition_no_effects_disabled
id: light_eu_bottom
name: Light - Bottom
name: Light - Bottom EU
platform: partition
disabled_by_default: true
<<: *light_partition_with_effects
default_transition_length: ${default_transition_length}
restore_mode: ${LIGHT_SIDES_RESTORE_MODE}
internal: true
segments:
- id: light_full
from: 6
to: 12
reversed: true
- id: light_eu_left
name: Light - Left
<<: *light_partition_with_effects_disabled
name: Light - Left EU
<<: *light_partition_no_effects_disabled
segments:
- id: light_full
from: 13
to: 19
reversed: true
- id: light_eu_right
name: Light - Right
<<: *light_partition_with_effects_disabled
name: Light - Right EU
<<: *light_partition_no_effects_disabled
segments:
- id: light_full
from: 27
@@ -147,32 +198,32 @@ light:
to: 5
reversed: false
- id: light_eu_top
name: Light - Top
<<: *light_partition_with_effects_disabled
name: Light - Top EU
<<: *light_partition_no_effects_disabled
segments:
- id: light_full
from: 20
to: 26
reversed: false
- id: light_us_bottom
name: Light - Bottom
<<: *light_partition_with_effects_disabled
name: Light - Bottom US
<<: *light_partition_no_effects_disabled
segments:
- id: light_full
from: 9
to: 14
reversed: true
- id: light_us_left
name: Light - Left
<<: *light_partition_with_effects_disabled
name: Light - Left US
<<: *light_partition_no_effects_disabled
segments:
- id: light_full
from: 15
to: 24
reversed: true
- id: light_us_right
name: Light - Right
<<: *light_partition_with_effects_disabled
name: Light - Right US
<<: *light_partition_no_effects_disabled
segments:
- id: light_full
from: 31
@@ -183,8 +234,8 @@ light:
to: 8
reversed: false
- id: light_us_top
name: Light - Top
<<: *light_partition_with_effects_disabled
name: Light - Top US
<<: *light_partition_no_effects_disabled
segments:
- id: light_full
from: 25
@@ -446,10 +497,11 @@ script:
- id: !extend dump_config
then:
- lambda: |-
std::string gang_count_plural_suffix = id(gang_count) > 1 ? "s" : "";
// Relay's LEDs modes
ESP_LOGCONFIG("core_hw_leds", "Relay%s LEDs mode%s:",
id(gang_count_plural_suffix).c_str(),
id(gang_count_plural_suffix).c_str());
gang_count_plural_suffix.c_str(),
gang_count_plural_suffix.c_str());
ESP_LOGCONFIG("core_hw_leds", " Relay 1: %s", id(is_us_model)
? sl_relay_1_light_mode_us->state.c_str()
: sl_relay_1_light_mode_eu->state.c_str());
@@ -570,7 +622,7 @@ select:
# EU relay light mode template
- &relay_light_mode_eu
id: sl_relay_1_light_mode_eu
name: Relay 1 light mode
name: Relay 1 light mode EU
platform: template
options:
- "${LIGHT_MODE_DISABLED_TEXT}"
@@ -585,19 +637,19 @@ select:
disabled_by_default: false
icon: mdi:dots-square
- id: sl_relay_2_light_mode_eu
name: Relay 2 light mode
name: Relay 2 light mode EU
<<: *relay_light_mode_eu
- id: sl_relay_3_light_mode_eu
name: Relay 3 light mode
name: Relay 3 light mode EU
<<: *relay_light_mode_eu
- id: sl_relay_4_light_mode_eu
name: Relay 4 light mode
name: Relay 4 light mode EU
<<: *relay_light_mode_eu
# US relay light mode template
- &relay_light_mode_us
id: sl_relay_1_light_mode_us
name: Relay 1 light mode
name: Relay 1 light mode US
platform: template
options:
- "${LIGHT_MODE_DISABLED_TEXT}"
@@ -612,12 +664,12 @@ select:
disabled_by_default: false
icon: mdi:dots-square
- id: sl_relay_2_light_mode_us
name: Relay 2 light mode
name: Relay 2 light mode US
<<: *relay_light_mode_us
- id: sl_relay_3_light_mode_us
name: Relay 3 light mode
name: Relay 3 light mode US
<<: *relay_light_mode_us
- id: sl_relay_4_light_mode_us
name: Relay 4 light mode
name: Relay 4 light mode US
<<: *relay_light_mode_us
...

View File

@@ -318,7 +318,7 @@ script:
# - HW Vibration
- binary_sensor.template.publish:
id: bs_multi_touch
state: OFF # yamllint disable-line rule:truthy
state: ON # yamllint disable-line rule:truthy
- id: touch_on_press
mode: restart
@@ -386,69 +386,85 @@ tx_ultimate_easy:
}
on_multi_touch_release:
- homeassistant.event:
event: esphome.tx_ultimate_easy
data:
device_name: !lambda return tx_device_name->state.c_str();
firmware: ${version}
domain: touch
type: multi_touch
action: release
position: !lambda return touch.x;
- lambda: ESP_LOGI("core_hw_touch", "Multi-touch released");
- script.execute: touch_on_multi_touch_release
then:
- homeassistant.event:
event: ${EVENT_NAME}
data:
device_name: !lambda return id(tx_device_name).state.c_str();
firmware: ${version}
domain: touch
type: multi_touch
action: release
position: !lambda return std::to_string(touch.x);
- lambda: |-
ESP_LOGI("core_hw_touch", "Multi-touch released");
touch_on_multi_touch_release->execute();
on_press:
- lambda: |-
const uint8_t position = static_cast<uint8_t>(touch.x);
if (position > ${TOUCH_POSITION_MAX_VALUE}) { // Check for valid range
ESP_LOGE("core_hw_touch", "Invalid touch position: %" PRIu8, position);
} else {
ESP_LOGI("core_hw_touch", "Pressed at position %" PRIu8, position);
touch_on_press->execute(static_cast<uint8_t>(touch.button), position);
}
then:
- lambda: |-
const uint8_t position = static_cast<uint8_t>(touch.x);
if (position > ${TOUCH_POSITION_MAX_VALUE}) { // Check for valid range
ESP_LOGE("core_hw_touch", "Invalid touch position: %" PRIu8, position);
} else {
ESP_LOGI("core_hw_touch", "Pressed at position %" PRIu8, position);
touch_on_press->execute(static_cast<uint8_t>(touch.button), position);
}
on_release:
- lambda: ESP_LOGI("core_hw_touch", "Released");
- script.execute: touch_on_release
then:
- lambda: ESP_LOGI("core_hw_touch", "Released");
- script.execute: touch_on_release
on_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
then:
- homeassistant.event:
event: ${EVENT_NAME}
data:
device_name: !lambda return id(tx_device_name).state.c_str();
firmware: ${version}
domain: touch
type: swipe
action: !lambda |-
if (sl_tx_model_format->state == "${TX_MODEL_FORMAT_EU_TEXT}")
return "left";
else
return "down";
swipe-direction: !lambda |-
if (sl_tx_model_format->state == "${TX_MODEL_FORMAT_EU_TEXT}")
return "left";
else
return "down";
position: !lambda return std::to_string(touch.x);
- lambda: |-
ESP_LOGI("core_hw_touch", "Swipe %s",
(sl_tx_model_format->state == "${TX_MODEL_FORMAT_EU_TEXT}") ? "left" : "down");
touch_swipe_left->execute();
on_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
then:
- homeassistant.event:
event: ${EVENT_NAME}
data:
device_name: !lambda return id(tx_device_name).state.c_str();
firmware: ${version}
domain: touch
type: swipe
action: !lambda |-
if (sl_tx_model_format->state == "${TX_MODEL_FORMAT_EU_TEXT}")
return "right";
else
return "up";
swipe-direction: !lambda |-
if (sl_tx_model_format->state == "${TX_MODEL_FORMAT_EU_TEXT}")
return "right";
else
return "up";
position: !lambda return std::to_string(touch.x);
- lambda: |-
ESP_LOGI("core_hw_touch", "Swipe %s",
(sl_tx_model_format->state == "${TX_MODEL_FORMAT_EU_TEXT}") ? "right" : "up");
touch_swipe_right->execute();
on_touch_event:
- lambda: |-

View File

@@ -13,60 +13,8 @@
---
packages:
# yamllint disable rule:colons
core_hw_relays: !include TX-Ultimate-Easy-ESPHome_standard_hw_relays.yaml
core_hw_speaker: !include TX-Ultimate-Easy-ESPHome_standard_hw_speaker.yaml
core_hw_vibration: !include TX-Ultimate-Easy-ESPHome_standard_hw_vibration.yaml
standard_hw_relays: !include TX-Ultimate-Easy-ESPHome_standard_hw_relays.yaml
standard_hw_vibration: !include TX-Ultimate-Easy-ESPHome_standard_hw_vibration.yaml
standard_media_player: !include TX-Ultimate-Easy-ESPHome_standard_media_player.yaml
# yamllint enable rule:colons
button:
- id: bt_restart
name: Restart
internal: false
platform: restart
captive_portal:
id: ap_captive_portal
esphome:
platformio_options:
build_flags:
- -D TX_ULTIMATE_EASY_STANDARD
script:
- id: !extend dump_config_list_packages
then:
- script.wait: dump_config
- lambda: |-
// Check for requirements
#if !defined(TX_ULTIMATE_EASY_CORE)
#error "The package TX-Ultimate-Easy-ESPHome_core.yaml is required."
#endif
// Identify itself
ESP_LOGCONFIG(ESPHOME_PROJECT_NAME, " - Standard");
- id: !extend dump_config_versions
then:
- lambda: |-
// Version information
ESP_LOGCONFIG("standard", "ESPHome builder: %s", esphome_fw_version->state.c_str());
improv_serial:
id: serial_improv
text_sensor:
- id: esphome_fw_version
name: ESPHome Version
platform: version
entity_category: diagnostic
internal: false
time:
- id: time_source
platform: homeassistant
web_server:
wifi:
ap:
...

View File

@@ -11,15 +11,18 @@
##### - For normal system use, modifications to this file are NOT required. #####
####################################################################################################
---
substitutions:
SWITCH_AUDIO_AMPLIFIER_RESTORE_MODE: RESTORE_DEFAULT_ON
esphome:
platformio_options:
build_flags:
- -D TX_ULTIMATE_EASY_STANDARD_HW_AUDIO
i2s_audio:
id: if_i2s_audio
i2s_bclk_pin: GPIO2
i2s_lrclk_pin: GPIO4
- id: if_i2s_audio
i2s_bclk_pin: GPIO2
i2s_lrclk_pin: GPIO4
script:
- id: !extend dump_config_list_packages
@@ -33,4 +36,15 @@ script:
// Identify itself
ESP_LOGCONFIG(ESPHOME_PROJECT_NAME, " - Standard - Hardware - Audio");
switch:
- id: sw_audio_amplifier
name: Audio Amplifier
platform: gpio
pin:
number: GPIO26
inverted: false
restore_mode: ${SWITCH_AUDIO_AMPLIFIER_RESTORE_MODE}
internal: true
entity_category: config
...

View File

@@ -703,10 +703,11 @@ script:
- id: !extend dump_config
then:
- lambda: |-
std::string gang_count_plural_suffix = id(gang_count) > 1 ? "s" : "";
// Relay's modes
ESP_LOGCONFIG("standard_hw_relays", "Relay%s mode%s:",
id(gang_count_plural_suffix).c_str(),
id(gang_count_plural_suffix).c_str());
gang_count_plural_suffix.c_str(),
gang_count_plural_suffix.c_str());
ESP_LOGCONFIG("standard_hw_relays", " Relay 1: %s", sl_relay_1_mode->has_state()
? sl_relay_1_mode->state.c_str()
: "Unknown");
@@ -725,8 +726,8 @@ script:
// Relay's states
ESP_LOGCONFIG("standard_hw_relays", "Relay%s state%s:",
id(gang_count_plural_suffix).c_str(),
id(gang_count_plural_suffix).c_str());
gang_count_plural_suffix.c_str(),
gang_count_plural_suffix.c_str());
ESP_LOGCONFIG("standard_hw_relays", " Relay 1: %s", sw_relay_1->state ? "ON" : "OFF");
if (id(gang_count) >= 2)
ESP_LOGCONFIG("standard_hw_relays", " Relay 2: %s", sw_relay_2->state ? "ON" : "OFF");

View File

@@ -38,11 +38,11 @@ api:
esphome:
platformio_options:
build_flags:
- -D TX_ULTIMATE_EASY_STANDARD_SPEAKER
- -D TX_ULTIMATE_EASY_STANDARD_HW_SPEAKER
number:
- id: speaker_volume
name: Sound - Volume
name: Speaker Volume
platform: template
max_value: 100
min_value: 0
@@ -179,4 +179,8 @@ speaker:
i2s_audio_id: if_i2s_audio
i2s_comm_fmt: stand_msb
channel: mono
timeout: never
bits_per_sample: 16bit
sample_rate: 48000
buffer_duration: 500ms
...

View File

@@ -0,0 +1,112 @@
####################################################################################################
##### TX Ultimate Easy for ESPHome #####
##### Repository: https://github.com/edwardtfn/TX-Ultimate-Easy #####
####################################################################################################
##### Purpose: ESPHome - Add-on - Media player #####
####################################################################################################
##### 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. #####
####################################################################################################
---
packages:
standard_hw_speaker: !include TX-Ultimate-Easy-ESPHome_standard_hw_speaker.yaml
esphome:
platformio_options:
build_flags:
- -D TX_ULTIMATE_EASY_STANDARD_MEDIA_PLAYER
globals:
- id: last_media_player_volume
type: uint8_t
restore_value: false
initial_value: '100'
- id: persistent_media_player_volume
type: uint8_t
restore_value: true
initial_value: '100'
media_player:
- id: mp_media_player
name: Media Player
internal: false
platform: speaker
codec_support_enabled: true
buffer_size: 250000
task_stack_in_psram: false
announcement_pipeline:
speaker: announcement_spk_resampling_input
format: WAV
num_channels: 1
sample_rate: 48000
media_pipeline:
speaker: media_spk_resampling_input
format: FLAC
num_channels: 1
sample_rate: 48000
on_state:
then:
- lambda: |-
// Check if volume has changed and update number entity
id(persistent_media_player_volume) = static_cast<uint8_t>(mp_media_player->volume * 100.0f);
if (id(persistent_media_player_volume) != id(last_media_player_volume)) {
id(last_media_player_volume) = id(persistent_media_player_volume);
ESP_LOGD("media_player_volume", "Media player volume changed to %" PRIu8 "%%, updating number entity", id(persistent_media_player_volume));
}
script:
- id: !extend boot_sequence
then:
- script.execute: sync_initial_volume
- id: !extend dump_config
then:
- lambda: |-
// Volume sync configuration
ESP_LOGCONFIG("standard_media_player", "Media Player Volume Sync:");
ESP_LOGCONFIG("standard_media_player", " Persistent volume: %" PRIu8 "%", id(persistent_media_player_volume));
ESP_LOGCONFIG("standard_media_player", " Current volume: %.1f%%", mp_media_player->volume * 100.0f);
- id: !extend dump_config_list_packages
then:
- script.wait: dump_config
- lambda: |-
// Check for requirements
#if !defined(TX_ULTIMATE_EASY_CORE)
#error "The package TX-Ultimate-Easy-ESPHome_core.yaml is required."
#endif // TX_ULTIMATE_EASY_CORE
#if !defined(TX_ULTIMATE_EASY_STANDARD_HW_SPEAKER)
#error "The package TX-Ultimate-Easy-ESPHome_standard_hw_speaker.yaml is required."
#endif // TX_ULTIMATE_EASY_STANDARD_HW_SPEAKER
// Identify itself
ESP_LOGCONFIG(ESPHOME_PROJECT_NAME, " - Standard - Media Player");
- id: sync_initial_volume
mode: restart
then:
- delay: 2s # Wait for media player to initialize
- media_player.volume_set: # Sync initial volume from persisted number entity to media player
id: mp_media_player
volume: !lambda return id(persistent_media_player_volume) / 100.0f;
- lambda: |-
id(last_media_player_volume) = id(persistent_media_player_volume);
ESP_LOGI("media_player_volume", "Initial volume sync: %.1f%% (restored from persistence)", id(persistent_media_player_volume));
speaker:
- platform: mixer
id: mixer_speaker_embedded
output_speaker: speaker_embedded
source_speakers:
- id: announcement_speaker_embedded
- id: media_speaker_embedded
- platform: resampler
id: announcement_spk_resampling_input
output_speaker: announcement_speaker_embedded
- platform: resampler
id: media_spk_resampling_input
output_speaker: media_speaker_embedded
...

143
README.md
View File

@@ -27,6 +27,45 @@
[buymeacoffee-shield]: https://img.shields.io/static/v1?label=Buy%20me%20an%20ice%20cream&message=❄&color=blue
[buymeacoffee]: https://www.buymeacoffee.com/edwardfirmo
## Framework Migration to ESP-IDF
> [!IMPORTANT]
> **ESP-IDF Framework Migration**
>
> Starting with version **2025.8.0**, TX Ultimate Easy will use **ESP-IDF** as the default framework, following ESPHome's direction towards ESP-IDF for better performance, stability, and feature support.
>
> **What this means for you:**
> - **New installations**: Will automatically use ESP-IDF (no action required)
> - **Existing Arduino users**: Can continue using Arduino but with limited support
> - **Migration recommended**: For better performance and full feature support
>
> **Arduino Framework Support:**
> - Still functional but **no longer actively tested**
> - **Limited support** will be provided for Arduino-specific issues
> - May miss out on new features optimized for ESP-IDF
### Migration Guidelines
#### For New Users
No action required - ESP-IDF will be used automatically.
#### For Existing Arduino Users
**Option 1: Migrate to ESP-IDF (Recommended)**
1. **Best practice**: Flash via serial/USB to ensure proper partition setup
2. **Alternative**: If serial flashing isn't possible, flash OTA twice consecutively to improve success rate
**Option 2: Continue with Arduino**
Add this to your YAML configuration to force Arduino framework:
```yaml
esp32:
framework:
type: arduino
```
> [!WARNING]
> **Migration via OTA:** When switching frameworks via OTA, the partition table may not update correctly. Flash twice in succession to ensure both firmware partitions contain the latest firmware and prevent boot failures.
## Integration with Home Assistant
TX Ultimate Easy exposes your device's components (sensors, touch panel, relays, etc.) to Home Assistant,
@@ -70,9 +109,10 @@ All device behaviors can be customized through Home Assistant automations withou
- **Flexible Light Control**: Customize LED behavior and effects
- **Touch Panel Support**: Full support for touch gestures and multi-touch capabilities
- **Advanced Automations**: Create complex automations using Home Assistant's powerful automation engine
- **BLE Proxy Support**: Optional Bluetooth Low Energy proxy functionality
- **Bluetooth Proxy Support**: Compatible with ESPHome's bluetooth_proxy component for BLE device integration
- **Audio Feedback**: Built-in speaker support for audible feedback
- **Haptic Feedback**: Vibration motor support for tactile feedback
- **ESP-IDF Framework**: Enhanced performance and stability with ESP-IDF support
## Hardware Support
@@ -111,28 +151,104 @@ Follow these steps to get your TX Ultimate device up and running with ESPHome.
4. Copy this basic configuration to your new device:
```yaml
substitutions:
name: tx-ultimate-easy # Change this to your device name
name: tx-ultimate-easy
friendly_name: TX Ultimate Easy
packages:
remote_package:
url: https://github.com/edwardtfn/TX-Ultimate-Easy
ref: main # For latest stable release
files:
- TX-Ultimate-Easy-ESPHome.yaml
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
```
packages:
remote_package:
url: https://github.com/edwardtfn/TX-Ultimate-Easy
ref: main # Or you can specify a version, like `ref: v2024.12.6` or `ref: latest`
refresh: 5min
files:
- ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml # Core (essential) packages
- ESPHome/TX-Ultimate-Easy-ESPHome_standard.yaml # Non-essential, but recommended packages
```
You can also use a specific version tag for better control over updates:
```yaml
ref: v2024.12.2 # Using specific version for controlled updates
```
**Note:** [Click here](https://github.com/edwardtfn/TX-Ultimate-Easy/tags) for a full list of versions available.
**Notes:**
- [Click here](https://github.com/edwardtfn/TX-Ultimate-Easy/tags) for a full list of versions available.
- [Click here](TX-Ultimate-Easy-ESPHome.yaml)
for the latest version of this yaml.
5. Click "Save" and then "Install"
> [!IMPORTANT]
> Starting from version 2025.1.0, non-essential components like `web_server`, `captive_portal`, and `wifi`
> are no longer included in the core package. If you need these components,
> you must add them manually to your local configuration file.
> For example:
> ```yaml
> # Add these to your configuration if needed
> web_server:
> captive_portal:
> wifi:
> ap: # Access point configuration
> ```
### Optional Features
#### Bluetooth Proxy
TX Ultimate Easy is fully compatible with ESPHome's `bluetooth_proxy` component.
To enable Bluetooth proxy functionality, add the following to your device configuration:
```yaml
bluetooth_proxy:
# Optional: Configure specific settings
# active: true
```
**Requirements for Bluetooth Proxy:**
- ESP-IDF framework (default framework, not recommended with Arduino framework)
- Sufficient memory (TX Ultimate Easy components are compatible,
but adding additional custom components may require memory optimization)
> [!NOTE]
> Bluetooth proxy functionality is provided by ESPHome's native component.
> TX Ultimate Easy ensures compatibility but does not include it by default to maintain optimal memory usage.
### Advanced Settings
For more granular control over components,
you can use our [advanced configuration template](TX-Ultimate-Easy-ESPHome_advanced.yaml).
This template allows you to selectively include specific packages, which can be useful for:
- Troubleshooting specific components
- Reducing memory usage by excluding unused features
- Customizing functionality for specific use cases
Here's an example of the advanced configuration:
```yaml
packages:
remote_package:
url: https://github.com/edwardtfn/TX-Ultimate-Easy
ref: main # Or you can specify a version, like `ref: v2024.12.6` or `ref: latest`
refresh: 5min
files:
# Core (essential) packages
- ESPHome/TX-Ultimate-Easy-ESPHome_core_common.yaml # Basic shared settings
- ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_buttons.yaml # Button logic
- ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_leds.yaml # LED configuration
- ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_touch.yaml # Touch panel support
# Optional but recommended packages
- ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_relays.yaml # Relay control
- ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_vibration.yaml # Haptic feedback
# Audio options (use none or choose only one - using both will fail)
- ESPHome/TX-Ultimate-Easy-ESPHome_standard_media_player.yaml # Media player (Recommended for most users)
# - ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_speaker.yaml # Basic speaker
# Optional: Add Bluetooth proxy support
bluetooth_proxy:
```
> [!NOTE]
> Use the advanced configuration with caution. Excluding core packages may cause instability or reduced functionality.
### Device Flashing
Initial flashing must be done via serial connection.
@@ -252,7 +368,7 @@ After installation, you can:
2. Customize touch behaviors
3. Set up LED patterns and effects
4. Create automations
5. Enable optional features like BLE proxy
5. Enable optional features like Bluetooth proxy
## Configuration Options
@@ -263,6 +379,7 @@ TX Ultimate Easy offers extensive configuration options:
- Relay modes and functions
- Audio and haptic feedback settings
- Network and connectivity options
- Optional Bluetooth proxy functionality
## Contributing

View File

@@ -16,11 +16,10 @@ wifi:
packages:
remote_package:
url: https://github.com/edwardtfn/TX-Ultimate-Easy
ref: latest # Or you can specify a version, like `ref: v2024.12.6`
ref: stable # Or you can specify a version, like `ref: v2024.12.6` or `ref: latest` to the latest non-stable
refresh: 5min
files:
- ESPHome/TX-Ultimate-Easy-ESPHome_core.yaml # Core (essential) packages
- ESPHome/TX-Ultimate-Easy-ESPHome_standard.yaml # Non-essential, but recommended packages
# - ESPHome/TX-Ultimate-Easy-ESPHome_addon_ble_proxy.yaml # Adds BLE proxy support
# - ESPHome/TX-Ultimate-Easy-ESPHome_addon_media_player.yaml # Adds experimental Media Player (limited)
...

View File

@@ -0,0 +1,38 @@
####################################################################################################
##### TX Ultimate Easy for ESPHome #####
##### Repository: https://github.com/edwardtfn/TX-Ultimate-Easy #####
####################################################################################################
##### Author: edwardtfn - https://github.com/edwardtfn - https://buymeacoffee.com/edwardfirmo #####
####################################################################################################
##### WARNING: This is an advanced configuration template. Use with caution as improper #####
##### configuration may lead to reduced functionality or system instability. #####
####################################################################################################
---
substitutions:
name: tx-ultimate-easy-adv
friendly_name: TX Ultimate Easy Advanced
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
packages:
remote_package:
url: https://github.com/edwardtfn/TX-Ultimate-Easy
ref: stable # Or you can specify a version, like `ref: v2024.12.6` or `ref: latest` to the latest non-stable
refresh: 5min
files:
# Core (essential) packages - Do not disable these unless you know what you're doing
- ESPHome/TX-Ultimate-Easy-ESPHome_core_common.yaml # Basic shared settings
- ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_buttons.yaml # Button logic
- ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_leds.yaml # LED configuration
- ESPHome/TX-Ultimate-Easy-ESPHome_core_hw_touch.yaml # Touch panel support
# Optional functionality - Can be enabled/disabled as needed
- ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_relays.yaml # Relay control
- ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_vibration.yaml # Haptic feedback
# Audio options (use none or choose only one - using both will fail)
- ESPHome/TX-Ultimate-Easy-ESPHome_standard_media_player.yaml # Media player (Recommended for most users)
# - ESPHome/TX-Ultimate-Easy-ESPHome_standard_hw_speaker.yaml # Basic speaker
...

View File

@@ -1,11 +1,12 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome import automation
from esphome.components import uart
from esphome.components.esp32 import add_idf_sdkconfig_option
from esphome.const import (
CONF_ID,
)
from esphome import automation
from esphome.core import CORE
CODEOWNERS = ["@edwardtfn"]
DEPENDENCIES = ['uart']
@@ -109,3 +110,17 @@ async def to_code(config):
await cg.register_component(var, config)
await uart.register_uart_device(var, config)
await register_tx_ultimate_easy(var, config)
if CORE.using_esp_idf:
add_idf_sdkconfig_option("CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST", True)
add_idf_sdkconfig_option("CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY", True)
add_idf_sdkconfig_option("CONFIG_ESP32_REV_MIN_3", True)
add_idf_sdkconfig_option("CONFIG_MBEDTLS_DYNAMIC_BUFFER", True)
add_idf_sdkconfig_option("CONFIG_MBEDTLS_DYNAMIC_FREE_CA_CERT", True)
add_idf_sdkconfig_option("CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA", True)
add_idf_sdkconfig_option("CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC", True)
add_idf_sdkconfig_option("CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY", True)
add_idf_sdkconfig_option("CONFIG_SPIRAM_RODATA", True)
add_idf_sdkconfig_option("CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP", True)
cg.add_define("USE_TX_ULTIMATE_EASY")

View File

@@ -69,9 +69,9 @@ namespace esphome {
if (this->gang_count_ == 1)
return 1;
//Calculate button number Change to round up insted of truncate (integer division)
// Calculate button number Change to round up instead of truncate (integer division)
const uint8_t width = (TOUCH_MAX_POSITION + gang_count_) / this->gang_count_; // Width of each button region
if (width < 1) // Invalid width - and prevents division by zero removed "width > gang_count_" issue with 2 gang
if (width < 1) // 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
@@ -141,8 +141,36 @@ namespace esphome {
switch (uart_received_bytes[4]) {
case TOUCH_STATE_RELEASE:
case TOUCH_STATE_MULTI_TOUCH:
return uart_received_bytes[5];
case TOUCH_STATE_SWIPE_LEFT:
case TOUCH_STATE_SWIPE_RIGHT:
// uart_received_bytes[5] indicates swipe direction:
// 12 = find last touch position (scan right to left)
// 13 = find first touch position (scan left to right)
// Bytes 6-7 contain a 10-bit bitmap of touch positions:
// Byte 7: bits 0-7 represent positions 1-8
// Byte 6: bits 0-1 represent positions 9-10
switch (uart_received_bytes[5]) {
case 12:
for (uint8_t i = 10; i > 0; i--) {
if (i > 8
? uart_received_bytes[6] & (1 << (i - 9))
: uart_received_bytes[7] & (1 << (i - 1))) {
return i;
}
}
break;
case 13:
for (uint8_t i = 1; i <= 10; i++) {
if (i > 8
? uart_received_bytes[6] & (1 << (i - 9))
: uart_received_bytes[7] & (1 << (i - 1))) {
return i;
}
}
break;
}
return uart_received_bytes[5];
default:
@@ -152,8 +180,10 @@ namespace esphome {
int TxUltimateEasy::get_touch_state(const std::array<int, UART_RECEIVED_BYTES_SIZE> &uart_received_bytes) {
int state = uart_received_bytes[4];
if (state == TOUCH_STATE_PRESS && uart_received_bytes[5] != 0) state = TOUCH_STATE_RELEASE;
if (state == TOUCH_STATE_RELEASE && uart_received_bytes[5] == TOUCH_STATE_MULTI_TOUCH) state = TOUCH_STATE_MULTI_TOUCH;
if (state == TOUCH_STATE_PRESS && uart_received_bytes[5] != 0)
state = TOUCH_STATE_RELEASE;
if (state == TOUCH_STATE_RELEASE && uart_received_bytes[5] == TOUCH_STATE_MULTI_TOUCH)
state = TOUCH_STATE_MULTI_TOUCH;
if (state == TOUCH_STATE_SWIPE) {
state = (uart_received_bytes[5] == TOUCH_STATE_SWIPE_RIGHT) ? TOUCH_STATE_SWIPE_RIGHT :
(uart_received_bytes[5] == TOUCH_STATE_SWIPE_LEFT) ? TOUCH_STATE_SWIPE_LEFT : state;

View File

@@ -1 +1 @@
2024.12.27
2025.8.2

View File

@@ -1 +1 @@
version: 2024.12.27
version: 2025.8.2