Skip to content

Add button/input_button detail page#63

Merged
edwardtfn merged 3 commits intomainfrom
v9999.99.9
Mar 24, 2026
Merged

Add button/input_button detail page#63
edwardtfn merged 3 commits intomainfrom
v9999.99.9

Conversation

@edwardtfn
Copy link
Copy Markdown
Owner

@edwardtfn edwardtfn commented Mar 24, 2026

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

Summary by CodeRabbit

  • New Features

    • Added a new interactive "button" page with visual press feedback and integration for button/input_button entities across NSPanel UI and ESPHome flows.
    • Panels now emit button press events and update the button page state.
  • Documentation

    • API docs updated to list button and input_button as supported domains.
  • Chores

    • Raised minimum blueprint/display version requirements and bumped display version metadata.

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
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 24, 2026

📝 Walkthrough

Walkthrough

Adds 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 button/input_button domains, and raises blueprint/TFT version minima and HMI version tags.

Changes

Cohort / File(s) Summary
Compile-time page registry
components/nspanel_easy/pages.h
Appended "button" to page_names[] and added a static_assert ensuring get_page_id("button") is valid.
ESPHome API & display flow
esphome/nspanel_esphome_api.yaml, esphome/nspanel_esphome_hw_display.yaml, docs/api.md
Normalize input_buttonbutton in entity-details flow, treat button pages as excluded from generic display events and from detailed-entity resets, and document button/input_button support.
New button page package
esphome/nspanel_esphome_page_button.yaml, esphome/nspanel_esphome_standard.yaml
Added page handler blueprint (NSPANEL_EASY_PAGE_BUTTON build flag), event validation and service-event construction for button presses, page_button script and standard package inclusion.
Blueprint & routing
nspanel_easy_blueprint.yaml
Bumped blueprint version to 12; added pages.button, included button page in routing and entity-refresh flows; allowed button/input_button domains in relevant allowlists.
HMI page assets (many locales)
hmi/dev/*/button.txt, hmi/dev/*/boot.txt (multiple files)
hmi/dev/nspanel_CJK_eu_code/button.txt, .../CJK_us_code/button.txt, .../CJK_us_land_code/button.txt, .../eu_code/button.txt, .../us_code/button.txt, .../us_land_code/button.txt, plus multiple boot.txt files
Added new Page button HMI definitions for all locale variants (touch hotspot, immediate local draw on press, timer-based render, and UART/localevent emission). Updated global version text index from 12→13 in boot files.
Version metadata
esphome/nspanel_esphome_version.yaml
Raised min_blueprint_version 11→12 and min_tft_version 12→13 (affects version check logic).

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
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

Poem

🐰 I hopped a new page into the frame,
A ring of color, a press to name.
UART whispers, ESPHome hears,
Button wakes the panel gears.
Version bumped — the rabbit cheers! 🥕✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding a new button/input_button detail page to the NSPanel interface.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch v9999.99.9

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@edwardtfn edwardtfn marked this pull request as ready for review March 24, 2026 15:58
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 -1 represents "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

📥 Commits

Reviewing files that changed from the base of the PR and between 666244e and e8c6f26.

📒 Files selected for processing (35)
  • components/nspanel_easy/pages.h
  • docs/api.md
  • esphome/nspanel_esphome_api.yaml
  • esphome/nspanel_esphome_hw_display.yaml
  • esphome/nspanel_esphome_page_button.yaml
  • esphome/nspanel_esphome_standard.yaml
  • esphome/nspanel_esphome_version.yaml
  • hmi/dev/nspanel_CJK_eu_code/boot.txt
  • hmi/dev/nspanel_CJK_eu_code/button.txt
  • hmi/dev/nspanel_CJK_us_code/boot.txt
  • hmi/dev/nspanel_CJK_us_code/button.txt
  • hmi/dev/nspanel_CJK_us_land_code/boot.txt
  • hmi/dev/nspanel_CJK_us_land_code/button.txt
  • hmi/dev/nspanel_easy_landscape/boot.txt
  • hmi/dev/nspanel_eu_code/boot.txt
  • hmi/dev/nspanel_eu_code/button.txt
  • hmi/dev/nspanel_us_code/boot.txt
  • hmi/dev/nspanel_us_code/button.txt
  • hmi/dev/nspanel_us_land_code/boot.txt
  • hmi/dev/nspanel_us_land_code/button.txt
  • hmi/nspanel_CJK_eu.HMI
  • hmi/nspanel_CJK_eu.tft
  • hmi/nspanel_CJK_us.HMI
  • hmi/nspanel_CJK_us.tft
  • hmi/nspanel_CJK_us_land.HMI
  • hmi/nspanel_CJK_us_land.tft
  • hmi/nspanel_easy_landscape.hmi
  • hmi/nspanel_easy_landscape.tft
  • hmi/nspanel_eu.HMI
  • hmi/nspanel_eu.tft
  • hmi/nspanel_us.HMI
  • hmi/nspanel_us.tft
  • hmi/nspanel_us_land.HMI
  • hmi/nspanel_us_land.tft
  • nspanel_easy_blueprint.yaml

Comment thread hmi/dev/nspanel_CJK_us_code/button.txt
Comment thread hmi/dev/nspanel_CJK_us_land_code/button.txt
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 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.w is reduced later, inner_r can 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

📥 Commits

Reviewing files that changed from the base of the PR and between e8c6f26 and 6ee484d.

📒 Files selected for processing (12)
  • hmi/dev/nspanel_CJK_eu_code/button.txt
  • hmi/dev/nspanel_CJK_us_land_code/button.txt
  • hmi/dev/nspanel_eu_code/button.txt
  • hmi/dev/nspanel_us_land_code/button.txt
  • hmi/nspanel_CJK_eu.HMI
  • hmi/nspanel_CJK_eu.tft
  • hmi/nspanel_CJK_us_land.HMI
  • hmi/nspanel_CJK_us_land.tft
  • hmi/nspanel_eu.HMI
  • hmi/nspanel_eu.tft
  • hmi/nspanel_us_land.HMI
  • hmi/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

@edwardtfn edwardtfn merged commit f110053 into main Mar 24, 2026
33 checks passed
@edwardtfn edwardtfn deleted the v9999.99.9 branch March 24, 2026 17:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant