Add ESP-NOW communication for multi-device relay control#160
Add ESP-NOW communication for multi-device relay control#160jakub-k-dev wants to merge 40 commits intoedwardtfn:mainfrom
Conversation
…wifi_info, optional per-button config
- Send ESP-NOW only on single click (align with relay behavior) - Validate on_receive payload size >= 2 before reading command/relay - Use boolean initial_value for espnow_send/receive_enabled globals
- Replace ESPHome/ESP_NOW_README.md with short docs/espnow.md - Add ESP-NOW to Key Features and Optional Features in README - Document: omit substitutions for buttons that stay local-only
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds an ESP‑NOW peer‑to‑peer relay control package and example: new espnow_component receiver, queued espnow_send(button) script, per‑button MAC/relay mappings, send/receive enable switches, example/test YAMLs, docs/README updates, minor button/relay comment tweaks, and new CI jobs for ESP‑NOW builds. Changes
Sequence Diagram(s)sequenceDiagram
participant Button as Button
participant Script as espnow_send
participant Network as ESP-NOW Network
participant Receiver as Remote Device
participant Relay as Relay Control
Button->>Script: trigger (if sw_espnow_send_enabled)
Script->>Script: resolve target MAC & relay mapping
Script->>Script: validate MAC (non-empty, not all zeros) and clamp relay
Script->>Network: send ESP-NOW packet (cmd=0x01, relay)
Network->>Receiver: deliver message
Receiver->>Receiver: validate data pointer & size, parse payload
alt command == 0x01 and relay valid
Receiver->>Relay: toggle specified relay
else
Receiver->>Receiver: log invalid command/format
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 9
🤖 Fix all issues with AI agents
In `@docs/espnow.md`:
- Around line 10-13: The remote_package block currently sets ref: stable which
conflicts with README examples using ref: main; update the remote_package -> ref
value from "stable" to "main" (or add a short comment documenting when to use
"stable" vs "main") so examples are consistent; look for the remote_package
stanza and the keys url and ref to make the change in docs/espnow.md (and mirror
the same change in any example file that uses ref: stable).
In `@ESPHome/TX-Ultimate-Easy-ESPHome_espnow.yaml`:
- Around line 200-206: The lambda attached to the id: !extend button_click_event
currently sends ESP-NOW for all click counts; update it to only send on
single-clicks by early-returning when the button's click_count is not 1: after
checking id(espnow_send_enabled), add a guard like if (button->click_count != 1)
return; then call espnow_send->execute(button); reference the existing symbols
button_click_event, espnow_send_enabled, espnow_send and button in your change.
- Line 252: Add the YAML document end marker (...) at the end of this YAML file
to match project convention; locate the end of the file (near the last entry
such as the "icon: mdi:radio" mapping) and append a single line containing three
dots (...) on its own line.
- Around line 85-90: The espnow_send script currently uses "mode: single" with a
100ms delay which will drop concurrent calls; change the script "id:
espnow_send" to use "mode: queued" and set a sensible "max_runs" (e.g., 3-10
depending on throughput) so concurrent button presses are queued instead of
ignored, keeping the existing delay and parameter list intact. Ensure you update
only the mode and add max_runs in the espnow_send block so queued runs can
execute sequentially without silent drops.
- Around line 64-79: The receive handler for command == 0x01 toggles
id(sw_relay_1)..id(sw_relay_4) based only on relay_num and does not check the
device's configured gang count, so commands for non-existent relays still toggle
GPIOs; update the block that handles "if (command == 0x01 && relay_num >= 1 &&
relay_num <= 4)" to first read the device's gang/configured relay count (the
variable or config that denotes how many gangs are active) and abort/ignore the
command if relay_num is greater than that count, then only call
id(sw_relay_1)->toggle() ... id(sw_relay_4)->toggle() for relays that are
actually present.
- Around line 28-29: Remove the unused include by deleting "esp_mac.h" from the
includes list in the YAML platformio options (the includes block that currently
contains esp_mac.h); the code parses MAC addresses using sscanf (no esp_mac or
ESP-IDF MAC APIs are referenced), so simply remove the esp_mac.h entry to avoid
an unnecessary dependency.
In `@README.md`:
- Line 278: The long Markdown sentence that begins "Add the ESP-NOW package so
one switch can toggle relays on another switch directly, without Home
Assistant..." exceeds the 200-char limit; split it into multiple shorter lines
(e.g., break after the first clause and again before the parenthetical) so each
line is under 200 characters while preserving the meaning and the ESP-NOW docs
link (docs/espnow.md) and the YAML substitution details (target MAC and relay
per button) intact.
In `@TX-Ultimate-Easy-ESPHome_espnow_example.yaml`:
- Around line 9-11: The substitutions block is missing the required
device_format and gang_count keys; add them to the substitutions section
(alongside name and friendly_name) with appropriate values used elsewhere (e.g.,
device_format: "sonoff_basic" or your device family and gang_count: "1" or the
number of switches) so the template compiles under v2025.12.2+; ensure the
symbol names device_format and gang_count exactly match any references in the
YAML templates or esphome includes.
- Around line 27-48: The user instructions incorrectly reference Home Assistant
UI entities; update the text to tell users to set the YAML substitution
variables espnow_target_mac_button_X and espnow_target_relay_button_X (and
document the espnow_enabled substitution if present) instead of "Button X
ESP-NOW Target MAC Address" and "Button X ESP-NOW Target Relay", and add a short
example substitutions block showing how to override espnow_target_mac_button_1,
espnow_target_relay_button_1, etc. so readers can copy/paste concrete examples
for each switch.
🧹 Nitpick comments (2)
ESPHome/TX-Ultimate-Easy-ESPHome_espnow.yaml (2)
84-197: MAC and relay resolution is duplicated 3–4 times across separate lambdas.The
switch(button)block resolvingmac_strappears in the condition (Line 97), the log lambda (Line 118), and theespnow.sendaddress lambda (Line 148). The relay resolution appears in the log lambda (Line 119) and the data lambda (Line 176). Any change to the mapping requires updating all copies.Consider consolidating by storing the resolved MAC string and relay number into global variables in the condition lambda, then reading them in the subsequent action lambdas. This eliminates all duplicates.
31-40: Theespnow_send_enabled/espnow_receive_enabledglobals duplicate the switch states.The globals and switches both persist and restore independently. You could read the switch state directly (e.g.,
id(sw_espnow_send_enabled)->state) in the lambdas instead of maintaining separate globals, eliminating the dual-state tracking. This would remove the globals entirely.Also applies to: 208-245
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In `@ESPHome/TX-Ultimate-Easy-ESPHome_addon_espnow.yaml`:
- Around line 106-109: Remove the stray preprocessor closing directives that
have no matching `#if`: delete the dangling "#endif" immediately after the case 1
block that sets mac_str = "${espnow_target_mac_button_1}" (and likewise remove
the other unmatched "#endif" noted around line 139) so the switch/case for
mac_str is not broken by unmatched preprocessor tokens.
In `@ESPHome/TX-Ultimate-Easy-ESPHome_espnow.yaml`:
- Line 65: Replace the incorrect substitution ${gangs} with the defined
substitution ${gang_count} throughout
ESPHome/TX-Ultimate-Easy-ESPHome_espnow.yaml (this includes all preprocessor
directives and runtime checks like the relay validation expression `if (command
!= 0x01 or relay_num < 1 or relay_num > ${gangs})`); update every occurrence of
`${gangs}` to `${gang_count}` so the YAML uses the documented substitution name
and the relay_num bounds checks and other directives reference the correct
variable.
- Around line 106-109: Remove the stray unmatched “#endif” directives that
follow the always-compiled switch cases: delete the `#endif` after the switch
`case 1` block where `mac_str = "${espnow_target_mac_button_1}";` and the
similar stray `#endif` in the second lambda (the block assigning `mac_str =
"${espnow_target_mac_button_2}";`), so the switch/case blocks are not closed by
an unmatched preprocessor directive.
🧹 Nitpick comments (2)
ESPHome/TX-Ultimate-Easy-ESPHome_espnow.yaml (2)
91-165: Massive duplication: MAC-lookup and relay-lookup switch blocks are repeated 4 times.The same
switch (button)block resolving MAC and relay is duplicated across:
- Condition lambda (lines 100–129)
- Logging lambda (lines 131–165)
addresslambda (lines 168–201)datalambda (lines 202–231)This makes maintenance error-prone (the stray
#endifbug above is evidence). Consider extracting the MAC and relay resolution into a helper (e.g., a C++ function in an included header, or a single lambda that sets shared variables) and referencing it from each action.
241-278: Dual state management: template switches + globals are redundant.Both the
restore_value: trueglobals and therestore_mode: restore_default_offtemplate switches persist the same boolean. On boot, they could disagree if one restores before the other. Since the template switches already haveoptimistic: trueandrestore_mode, you could drop the globals entirely and read switch state viaid(sw_espnow_send_enabled).statein lambdas instead.
This project is already on the limits of NVS space and saving a couple of settings more could be the last drop, so I'm saving a few bytes here.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@ESPHome/TX-Ultimate-Easy-ESPHome_addon_espnow.yaml`:
- Around line 182-190: The MAC parsing block using sscanf currently returns a
zeroed MAC on failure without notifying the user; modify the else branch (the
path that returns {0x00,...}) to emit a warning log including the offending
mac_str (and optionally TAG/context) before returning zeros — locate the code
around the sscanf call that references mac_str and values[] and add an
ESP_LOGW/LOGW-style warning indicating the malformed MAC string so users can
debug malformed inputs.
- Around line 25-30: Remove the unused include entry "esp_mac.h" from the
esphome -> platformio_options -> includes list (the includes block that
currently contains esp_mac.h) since the code parses MACs manually with
sscanf/string methods and the espnow component manages MAC handling; simply
delete the "esp_mac.h" line from that includes array.
🧹 Nitpick comments (3)
ESPHome/TX-Ultimate-Easy-ESPHome_addon_espnow.yaml (3)
54-54: Minor: inconsistent use oforvs||.Line 54 uses the C++ alternative token
or, while every other boolean expression in this file uses||(e.g., lines 151, 216). Consider using||here for consistency.- if (command != 0x01 or relay_num < 1 or relay_num > ${gang_count} ) { + if (command != 0x01 || relay_num < 1 || relay_num > ${gang_count}) {
120-154: Lambda computesmac_strandrelay_numas local variables, then discards them — only the log line has any effect.The
espnow.sendaction at lines 155–220 cannot access the locals from this lambda, so it re-derivesmac_strandrelay_numfrom scratch. This lambda is effectively dead code apart from theESP_LOGIcall. Either move the log into one of theespnow.sendlambdas, or remove this block entirely to avoid the duplicated switch logic.
87-219: The button → MAC / relay switch-case is duplicated four times.The same
switch (button)mapping appears in:
- Condition lambda (lines 93–116) — resolves MAC
- Logging lambda (lines 123–149) — resolves MAC + relay
- Address lambda (lines 159–180) — resolves MAC again
- Data lambda (lines 193–214) — resolves relay again
Each copy must be kept in sync manually and each carries its own
#if/#endifguards. Consider extracting two helper lambdas or globals (one for MAC, one for relay) that are computed once and shared across the action steps, or restructuring as a single lambda that builds and sends the message in one place.
Changed the mode of espnow_send script to queued and set max_runs to 10.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@ESPHome/TX-Ultimate-Easy-ESPHome_espnow.yaml`:
- Around line 128-129: The current lambda that decides whether to skip ESP-NOW
only checks mac_str != "00:00:00:00:00:00" and allows malformed MACs like
"XX:YY:..." which later cause sscanf to fail and fallback to all-zero MAC;
update the lambda that uses mac_str to validate format by attempting to parse
the hex bytes (use sscanf or equivalent) and require that sscanf returns 6 (or
otherwise confirm 6 hex pairs) before returning true, so malformed strings are
treated as empty/invalid and the log near where the MAC is processed (sscanf)
remains accurate.
- Around line 160-163: The sender-side relay validation incorrectly uses the
sender's ${gang_count}; change the validation in the block that checks relay_num
(and the similar block around line 226) to clamp against the protocol maximum 4
instead of ${gang_count} so it validates 1..4 (e.g., replace uses of
${gang_count} in the relay_num bounds check with 4); keep the receiver-side
validation as-is.
🧹 Nitpick comments (2)
ESPHome/TX-Ultimate-Easy-ESPHome_espnow.yaml (2)
32-41: Consider removing redundant globals in favor of reading switch state directly.The
espnow_send_enabled/espnow_receive_enabledglobals mirror the template switch states and are kept in sync viaon_turn_on/on_turn_off. You could simplify by readingid(sw_espnow_send_enabled).statedirectly, eliminating the extra restore-value globals. That said, this is a common ESPHome micro-optimization pattern, so feel free to keep if preferred.
91-230: Significant DRY violation: the sameswitch(button)MAC/relay resolution is repeated 4 times.The button→MAC and button→relay mapping logic is duplicated across:
- Condition lambda (lines 101–129)
- Then-log lambda (lines 131–163)
- Address lambda (lines 167–200)
- Data lambda (lines 201–229)
Any mapping change requires updating all four blocks. Consider consolidating into a single lambda that resolves the target MAC + relay, validates, and then calls
espnow.senddirectly from C++ (usingid(espnow_component).send(...)) — or at minimum, store the resolved values in local script-scoped variables that the subsequent actions can reference.
I'm moving the changes applied to the other file by mistake. I will remove that other file.
|
@jakub-k-dev, which files/modules are required to run this? I mean, you are extend things from buttons and relays, right, so I need those two files (apart of common base file). Anything else? |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
|
@jakub-k-dev, have you thought about the possibility to assign one button to multiple target devices? substitutions:
espnow_button_1_target:
- mac: "AA:BB:CC:DD:EE:FF"
relay: 1
- max: "FF:EE:DD:CC:BB:AA"
relay: 4
espnow_button_2_target:
- mac: "AB:BC:CD:DE:EF:F0"
relay: 3
espnow_button_3_target:
- mac: "01:12:23:34:45:56"
relay: 2Too complex for now? |
|
@coderabbitai resume |
✅ Actions performedReviews resumed. |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@README.md`:
- Line 378: The markdown link "🇬🇧 [Let's
Automate](https://https://youtu.be/fIOgWQXndhI?si=O3j7sjwn7PvH1vxn)" contains a
duplicated "https://" prefix; edit the README entry to remove the extra protocol
so the href becomes "https://youtu.be/fIOgWQXndhI?si=O3j7sjwn7PvH1vxn" (update
the link text/URL where it appears in the README).
In `@TX-Ultimate-Easy-ESPHome_espnow_example.yaml`:
- Around line 38-44: The numbered steps in the README block contain a duplicate
"Step 3" — change the second occurrence (the line starting "3. To find MAC
addresses:") to "4." so the sequence reads 1, 2, 3, 4; update the literal string
"3. To find MAC addresses:" to "4. To find MAC addresses:" in the YAML comment
block to fix the duplicate numbering.
🧹 Nitpick comments (1)
TX-Ultimate-Easy-ESPHome_espnow_example.yaml (1)
40-42: Instructions still reference entity-style names rather than substitution keys.The config section above (lines 14–19) correctly uses substitution keys like
espnow_target_mac_button_1, but the instructions on lines 41–42 refer to"Button X ESP-NOW Target MAC Address"and"Button X ESP-NOW Target Relay"as if they were HA entities or UI labels. Since the user configures these in YAML, referencing the actual substitution variable names would be clearer.Proposed fix
-##### 3. On the device's YAML in ESPHome, configure: ##### -##### * "Button X ESP-NOW Target MAC Address" - Enter the MAC address of the target device ##### -##### * "Button X ESP-NOW Target Relay" - Select which relay to toggle (1-4) ##### +##### 3. On the device's YAML in ESPHome, configure these substitutions: ##### +##### * espnow_target_mac_button_X - MAC address of the target device ##### +##### * espnow_target_relay_button_X - Which relay to toggle (1-4) #####
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@TX-Ultimate-Easy-ESPHome_espnow_example.yaml`:
- Around line 9-13: The substitutions block uses generic values for name and
friendly_name which will cause mDNS and Home Assistant entity conflicts when
multiple devices use the same values; update the substitutions (specifically the
name and friendly_name entries) to require a unique identifier per device and
add a short comment above them stating "MUST be unique per device — change for
each unit" (or similar) so users know to set distinct names for each physical
device.
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.github/workflows/validate_esphome.yml (1)
513-541:⚠️ Potential issue | 🔴 Critical
summary_devis missing a dependency and has wrong total count.Two issues:
build_ard_espnow_example_devis not listed inneeds(lines 516-522), yet its result is checked on line 535. GitHub Actions will evaluate the expression as an empty string, so it will never count as success.TOTAL=6(line 529) should beTOTAL=8— there are now 8 dev builds being checked (4 Arduino + 4 IDF).Proposed fix
needs: - build_ard_core_dev - build_ard_basic_dev - build_ard_ble_proxy_dev + - build_ard_espnow_example_dev - build_idf_core_dev - build_idf_basic_dev - build_idf_ble_proxy_dev - build_idf_espnow_example_dev if: ${{ always() && (github.event_name != 'workflow_dispatch' || github.event.inputs.skip_dev != 'true') }} runs-on: ubuntu-latest steps: - name: Dev ESPHome Results run: | SUCCESS=0 - TOTAL=6 + TOTAL=8
🤖 Fix all issues with AI agents
In @.test/esphome_ard_espnow_example.yaml:
- Line 13: In the .test/esphome_ard_espnow_example.yaml file fix the typo in the
include path: update the include value referencing
"../TX-Ultimate-Easy-ESPHome_espnow_example.yam" (under the espnow_example key)
to use the correct ".yaml" extension so it reads
"../TX-Ultimate-Easy-ESPHome_espnow_example.yaml".
In @.test/esphome_idf_espnow_example.yaml:
- Line 13: The include path has a typo: change the reference in the
espnow_example entry from "../TX-Ultimate-Easy-ESPHome_espnow_example.yam" to
the correct "../TX-Ultimate-Easy-ESPHome_espnow_example.yaml" so ESPHome can
find the file; update the string in the espnow_example include to have the
trailing "l".
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
|
@coderabbitai resume |
✅ Actions performedReviews resumed. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@TX-Ultimate-Easy-ESPHome_espnow_example.yaml`:
- Around line 38-39: Update the README instruction that tells users to enable a
switch named "ESP-NOW Enabled" to instead refer to the actual switch entities
defined in espnow.yaml: instruct users to enable "ESP-NOW Send Enabled" and
"ESP-NOW Receive Enabled" (or specify which of those two is needed per device)
so they can find the correct switches in Home Assistant; mention espnow.yaml and
the exact switch names "ESP-NOW Send Enabled" and "ESP-NOW Receive Enabled" to
make locating them unambiguous.
🧹 Nitpick comments (3)
TX-Ultimate-Easy-ESPHome_espnow_example.yaml (2)
25-33: Remote package includes look complete.Core, standard, and espnow are all included. Note that
ref: mainmeans this example won't work until the PR is merged — consider mentioning this in the instructions or temporarily using the feature branch ref during development.
53-54: "Fallback behavior" wording is slightly misleading.When the MAC is
00:00:00:00:00:00, ESP-NOW sending is simply skipped — the button's normal local relay toggle still fires through the standard button/relay wiring, not as a "fallback" within ESP-NOW itself. Consider rewording to: "the button will only toggle the local relay (no ESP-NOW message is sent)."ESPHome/TX-Ultimate-Easy-ESPHome_espnow.yaml (1)
88-219: Consider extracting button-to-config lookup into helper functions.The same
switch (button)pattern with MAC/relay lookup is duplicated four times across the condition lambda (line 95), then lambda (line 123), address lambda (line 158), and data lambda (line 193). This duplication adds maintenance burden — adding a 5th button or changing the lookup logic requires updating all four copies.Consider extracting helper functions (e.g.,
getMacForButton(button),getRelayForButton(button)) to consolidate the repeated case/break blocks, even if ESPHome YAML lambda constraints make this approach challenging.
| ##### 1. Flash this configuration to all 3 devices ##### | ||
| ##### 2. In Home Assistant, for each device, enable the control "ESP-NOW Enabled" ##### |
There was a problem hiding this comment.
Instruction references incorrect switch name.
Step 2 says "ESP-NOW Enabled" but the actual switches defined in espnow.yaml are named "ESP-NOW Send Enabled" and "ESP-NOW Receive Enabled". Users won't find a single "ESP-NOW Enabled" entity.
Proposed fix
-##### 2. In Home Assistant, for each device, enable the control "ESP-NOW Enabled" #####
+##### 2. In Home Assistant, for each device, enable "ESP-NOW Send Enabled" and #####
+##### "ESP-NOW Receive Enabled" controls #####🤖 Prompt for AI Agents
In `@TX-Ultimate-Easy-ESPHome_espnow_example.yaml` around lines 38 - 39, Update
the README instruction that tells users to enable a switch named "ESP-NOW
Enabled" to instead refer to the actual switch entities defined in espnow.yaml:
instruct users to enable "ESP-NOW Send Enabled" and "ESP-NOW Receive Enabled"
(or specify which of those two is needed per device) so they can find the
correct switches in Home Assistant; mention espnow.yaml and the exact switch
names "ESP-NOW Send Enabled" and "ESP-NOW Receive Enabled" to make locating them
unambiguous.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@ESPHome/TX-Ultimate-Easy-ESPHome_espnow.yaml`:
- Around line 313-315: The closing preprocessor comment after the `#endif` is
incorrect: the guard uses TX_ULTIMATE_EASY_HW_BUTTONS (in the `#ifndef`) but the
`#endif` comment currently reads TX_ULTIMATE_EASY_HW_LEDS; update the comment to
match the actual guard by changing the `#endif` trailing comment to //
TX_ULTIMATE_EASY_HW_BUTTONS so it correctly reflects the checked symbol and
avoids confusion.
- Around line 21-29: Remove trailing whitespace from the file: strip trailing
spaces on the ESP-NOW config lines (espnow_target_mac_button_2,
espnow_target_relay_button_2, espnow_target_mac_button_3,
espnow_target_relay_button_3) and from all flagged blank lines, and also remove
trailing spaces inside the hex-validation blocks after the character class
string '0123456789ABCDEFabcdef:' (lines referenced in CI). Ensure no lines end
with spaces so the YAML linter passes.
🧹 Nitpick comments (3)
.test/esphome_ard_espnow_example.yaml (1)
5-10: Consider quoting integer substitution values for consistency.
espnow_target_relay_button_*values are bare integers while the MAC addresses are quoted strings. ESPHome substitutions are always strings internally, so this works, but quoting them (e.g.,"1") would be more consistent with how other substitutions are expressed and avoids any YAML-type ambiguity.Suggested diff
- espnow_target_relay_button_1: 1 + espnow_target_relay_button_1: "1" espnow_target_mac_button_2: "AB:BC:CD:DE:EF:F0" - espnow_target_relay_button_2: 3 + espnow_target_relay_button_2: "3" espnow_target_mac_button_3: "01:12:23:34:45:56" - espnow_target_relay_button_3: 2 + espnow_target_relay_button_3: "2"ESPHome/TX-Ultimate-Easy-ESPHome_espnow.yaml (2)
127-129: Consider documenting the security posture ofauto_add_peer: true.With
auto_add_peer: trueand no encryption, any ESP-NOW device on the same Wi-Fi channel can send toggle commands to this device (when receive is enabled). This is standard for ESP-NOW home automation setups and mitigated by the receive switch defaulting to OFF, but it would be good to note indocs/espnow.mdthat ESP-NOW operates without authentication so users understand the trust boundary.
195-264: Compile-time validation doesn't warn when ESP-NOW is configured for buttons beyondgang_count.If a user configures
espnow_target_mac_button_3with a valid MAC on a 2-gang device, validation passes (MAC format is valid) but the button 3 send case is compiled out by the#if ${gang_count} >= 3guard. The configuration is silently ignored with no compile-time or runtime feedback. Consider adding a#ifguard that emits a#warningor#errorwhen a non-null MAC is configured for a button beyond the gang count.Example addition after the existing validation blocks
// Warn if ESP-NOW is configured for buttons beyond gang_count `#if` ${gang_count} < 2 && ${ESPNOW_BUTTON_2_IS_NULL} == 0 `#error` "espnow_target_mac_button_2 is configured but gang_count < 2" `#endif` `#if` ${gang_count} < 3 && ${ESPNOW_BUTTON_3_IS_NULL} == 0 `#error` "espnow_target_mac_button_3 is configured but gang_count < 3" `#endif` `#if` ${gang_count} < 4 && ${ESPNOW_BUTTON_4_IS_NULL} == 0 `#error` "espnow_target_mac_button_4 is configured but gang_count < 4" `#endif`
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@ESPHome/TX-Ultimate-Easy-ESPHome_espnow.yaml`:
- Around line 190-201: The validation block for button 3 incorrectly uses
TX_ULTIMATE_EASY_ESPNOW_BUTTON_2_MAC_INVALID; update the MAC-format check to use
TX_ULTIMATE_EASY_ESPNOW_BUTTON_3_MAC_INVALID inside the button 3 validation
block (the section guarded by TX_ULTIMATE_EASY_ESPNOW_BUTTON_3_MAC_DEFINED) so
that invalid MACs for button 3 trigger the intended `#error` and button 3
validation is independent of button 2.
- Around line 90-93: The build flags for
TX_ULTIMATE_EASY_ESPNOW_BUTTON_X_MAC_INVALID are wrong because
ESPNOW_BUTTON_X_MAC_VALID is a string ('0' or '1') and Jinja treats any
non-empty string as truthy; update each expression to perform an explicit string
or integer comparison (e.g., use ESPNOW_BUTTON_1_MAC_VALID == "1" or
ESPNOW_BUTTON_1_MAC_VALID|int) so that
TX_ULTIMATE_EASY_ESPNOW_BUTTON_1_MAC_INVALID,
TX_ULTIMATE_EASY_ESPNOW_BUTTON_2_MAC_INVALID,
TX_ULTIMATE_EASY_ESPNOW_BUTTON_3_MAC_INVALID and
TX_ULTIMATE_EASY_ESPNOW_BUTTON_4_MAC_INVALID are set to 1 when the corresponding
ESPNOW_BUTTON_X_MAC_VALID is "0" and 0 when it is "1".
🧹 Nitpick comments (1)
ESPHome/TX-Ultimate-Easy-ESPHome_espnow.yaml (1)
95-97: No encryption on ESP-NOW — any nearby device can toggle relays.
auto_add_peer: truewith no PMK/LMK encryption means any ESP32 in radio range can craft a 2-byte payload and toggle relays. This may be acceptable for a V1 home automation feature, but consider documenting the threat model and adding encryption support in a follow-up.
Later I can transfer part of this code to the component to save a bit of memory and clean-up this code a bit.
To make it easier to maintain
Switches can toggle relays on other TX Ultimate Easy devices over ESP-NOW (no Home Assistant).
Per-button target MAC and relay via YAML substitutions; omit for local-only.
MAC shown in HA via “ESP-NOW MAC Address” text sensor; send/receive toggles in HA.
Docs in docs/espnow.md, linked from README.
Summary by CodeRabbit
New Features
Documentation
Examples
Diagnostics
Tests / CI
Style