Conversation
Adds a new `button` detail page to the Nextion TFT, providing a dedicated press UI for `button` and `input_button` domain entities. ## Changes - New Nextion page `button` with circle drawn entirely with `cirs` primitives (no image assets required) - Supports all panel models via `touch_area` component positioning: - EU and US landscape: 80×80 centered at (226, 160) - US portrait: 80×80 centered at (160, 240) - Two visual states driven by `state` variable: - `0` (available): colored fill (`color_idle`), touch enabled - `-1` (unavailable/unknown): muted fill (`color_unavail`), touch disabled - Press feedback driven entirely by Nextion (`codesdown`): - Sets `state=1`, draws `color_pressed` immediately - Sends `button,press` event to ESPHome via `localevent` - Blueprint resets `state=0` and enables `render` to revert - Fixed neutral gray ring (`color_ring`) always visible regardless of state - Icon rendered via `xstr` inside the circle, always white - All colors configurable by ESPHome (`color_idle`, `color_pressed`, `color_unavail`, `color_ring`) - Both `button` and `input_button` domains route to this page - Blueprint maps `unavailable` → `-1`, all other states → `0` ## Notes - Requires coordinated ESPHome, TFT and Blueprint update
📝 WalkthroughWalkthroughAdds a new "button" page: registers it at compile time, implements HMI page files for multiple locales that emit localevent presses, wires ESPHome handlers and blueprint logic to accept Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant HMI as NSPanel HMI
participant ESP as ESPHome (localevent handler)
participant HA as Home Assistant
participant Panel as NSPanel UI
User->>HMI: touch press (button)
HMI->>ESP: UART localevent "button,press"
ESP->>ESP: validate params, map `input_button`→`button`
ESP->>HA: fire event / call service (`button.<action>` with entity + state)
HA-->>ESP: event/state update
ESP->>Panel: trigger page refresh / page_button->execute()
Panel-->>User: render pressed state / updated UI
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 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: 2
🧹 Nitpick comments (1)
nspanel_easy_blueprint.yaml (1)
8583-8583: Consider including "unknown" state in the unavailable check.Per the PR description, state
-1represents "unavailable/unknown", but the current condition only checks for"unavailable". If entities can also report"unknown"state, this should be included.- val: '{{ -1 if is_state(entity_id, "unavailable") else 0 }}' + val: '{{ -1 if is_state(entity_id, ["unavailable", "unknown"]) else 0 }}'🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@nspanel_easy_blueprint.yaml` at line 8583, Update the value expression that currently uses is_state(entity_id, "unavailable") so it also treats "unknown" as unavailable; change the condition on is_state for the val expression to include an OR check for "unknown" (i.e., check is_state(entity_id, "unavailable") OR is_state(entity_id, "unknown") and return -1 in that case, otherwise 0) so both unavailable and unknown states map to -1.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@hmi/dev/nspanel_CJK_us_code/button.txt`:
- Around line 217-231: The current touch handler gates presses with state.val==0
which permanently locks the control if the external reset to 0 is missed; change
the gating to allow presses for any state except the explicit unavailable/locked
sentinel (use state.val != -1) so the control remains interactive even if the
external reset is delayed, while still reserving -1 as the single disable/lock
state; keep the local visual update (state.val=1, cirs, xstr, color_pressed.val)
and the outgoing printh/prints sequence unchanged so the press is still drawn
and the event sent.
In `@hmi/dev/nspanel_CJK_us_land_code/button.txt`:
- Around line 90-96: The icon variable's Max. Text Size is set to 3 in this
variant but 4 in nspanel_us_code/button.txt; update the local variable named
"icon" (ID 15) in this file to use Max. Text Size: 4 so UTF-8 MDI icons have
sufficient byte capacity, mirroring the other variant for consistency.
---
Nitpick comments:
In `@nspanel_easy_blueprint.yaml`:
- Line 8583: Update the value expression that currently uses is_state(entity_id,
"unavailable") so it also treats "unknown" as unavailable; change the condition
on is_state for the val expression to include an OR check for "unknown" (i.e.,
check is_state(entity_id, "unavailable") OR is_state(entity_id, "unknown") and
return -1 in that case, otherwise 0) so both unavailable and unknown states map
to -1.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 702080c1-b04c-403b-b370-a46d0d3e9f20
📒 Files selected for processing (35)
components/nspanel_easy/pages.hdocs/api.mdesphome/nspanel_esphome_api.yamlesphome/nspanel_esphome_hw_display.yamlesphome/nspanel_esphome_page_button.yamlesphome/nspanel_esphome_standard.yamlesphome/nspanel_esphome_version.yamlhmi/dev/nspanel_CJK_eu_code/boot.txthmi/dev/nspanel_CJK_eu_code/button.txthmi/dev/nspanel_CJK_us_code/boot.txthmi/dev/nspanel_CJK_us_code/button.txthmi/dev/nspanel_CJK_us_land_code/boot.txthmi/dev/nspanel_CJK_us_land_code/button.txthmi/dev/nspanel_easy_landscape/boot.txthmi/dev/nspanel_eu_code/boot.txthmi/dev/nspanel_eu_code/button.txthmi/dev/nspanel_us_code/boot.txthmi/dev/nspanel_us_code/button.txthmi/dev/nspanel_us_land_code/boot.txthmi/dev/nspanel_us_land_code/button.txthmi/nspanel_CJK_eu.HMIhmi/nspanel_CJK_eu.tfthmi/nspanel_CJK_us.HMIhmi/nspanel_CJK_us.tfthmi/nspanel_CJK_us_land.HMIhmi/nspanel_CJK_us_land.tfthmi/nspanel_easy_landscape.hmihmi/nspanel_easy_landscape.tfthmi/nspanel_eu.HMIhmi/nspanel_eu.tfthmi/nspanel_us.HMIhmi/nspanel_us.tfthmi/nspanel_us_land.HMIhmi/nspanel_us_land.tftnspanel_easy_blueprint.yaml
There was a problem hiding this comment.
🧹 Nitpick comments (1)
hmi/dev/nspanel_eu_code/button.txt (1)
250-252: Consider clamping radius math defensively for future touch-area changes.Today’s 80×80 hotspot is safe, but if
touch_area.wis reduced later,inner_rcan become negative and produce invalid draw calls.Suggested defensive clamp
- outer_r.val=sys0 - inner_r.val=outer_r.val-4 + outer_r.val=sys0 + if(outer_r.val<4) + { + outer_r.val=4 + } + inner_r.val=outer_r.val-4🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@hmi/dev/nspanel_eu_code/button.txt` around lines 250 - 252, Clamp the radius calculation to avoid negative values: compute outer_r.val as before, then set inner_r.val = max(0, outer_r.val - 4) (or use a clamp function) and compute inner_d.val from that clamped inner_r.val so inner_d never becomes negative; ensure any references to inner_r (e.g., in draw calls) use the clamped value to prevent invalid drawing when touch_area.w changes.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@hmi/dev/nspanel_eu_code/button.txt`:
- Around line 250-252: Clamp the radius calculation to avoid negative values:
compute outer_r.val as before, then set inner_r.val = max(0, outer_r.val - 4)
(or use a clamp function) and compute inner_d.val from that clamped inner_r.val
so inner_d never becomes negative; ensure any references to inner_r (e.g., in
draw calls) use the clamped value to prevent invalid drawing when touch_area.w
changes.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: a0472ec5-8fc8-4567-bd14-746dedaeff7e
📒 Files selected for processing (12)
hmi/dev/nspanel_CJK_eu_code/button.txthmi/dev/nspanel_CJK_us_land_code/button.txthmi/dev/nspanel_eu_code/button.txthmi/dev/nspanel_us_land_code/button.txthmi/nspanel_CJK_eu.HMIhmi/nspanel_CJK_eu.tfthmi/nspanel_CJK_us_land.HMIhmi/nspanel_CJK_us_land.tfthmi/nspanel_eu.HMIhmi/nspanel_eu.tfthmi/nspanel_us_land.HMIhmi/nspanel_us_land.tft
✅ Files skipped from review due to trivial changes (1)
- hmi/dev/nspanel_CJK_us_land_code/button.txt
🚧 Files skipped from review as they are similar to previous changes (1)
- hmi/dev/nspanel_us_land_code/button.txt
Adds a new
buttondetail page to the Nextion TFT, providing a dedicated press UI forbuttonandinput_buttondomain entities.Changes
buttonwith circle drawn entirely withcirsprimitives (no image assets required)touch_areacomponent positioning:statevariable:0(available): colored fill (color_idle), touch enabled-1(unavailable/unknown): muted fill (color_unavail), touch disabledcodesdown):state=1, drawscolor_pressedimmediatelybutton,pressevent to ESPHome vialocaleventstate=0and enablesrenderto revertcolor_ring) always visible regardless of statexstrinside the circle, always whitecolor_idle,color_pressed,color_unavail,color_ring)buttonandinput_buttondomains route to this pageunavailable→-1, all other states →0Notes
Summary by CodeRabbit
New Features
Documentation
buttonandinput_buttonas supported domains.Chores