feat: Button pages drawn by the panel, panel-side icons and a much lighter Blueprint
Highlights
This is one of the biggest releases in the history of NSPanel Easy. The button pages and every entity details page are now drawn by the panel itself, the panel resolves entity icons on its own, and the Blueprint is a lot lighter, for every panel:
| Blueprint | Previous release | This release | Change |
|---|---|---|---|
| Distinct templates | 960 | 599 | -361 (-38%) |
| Template occurrences | 3,114 | 1,314 | -1,800 (-58%) |
| Expanded size (characters) | 886,403 | 535,517 | -350,886 (-40%) |
| Triggers | 147 | 82 | -65 |
What this means for Home Assistant:
- No automation runs on button state changes anymore. The 64 state triggers of the button pages are gone: the panel follows the button entities itself, through Home Assistant state subscriptions, and redraws the buttons on its own.
- A wider margin under Home Assistant's template cache (1,024 entries), which reduces the load on Home Assistant, especially on large systems with Spook enabled.
- Entity details pages drawn by the panel. For buttons, switches, selects, alarms, lights, fans, covers, climates, water heaters, humidifiers, timers, vacuums, lawn mowers and media players, the Blueprint now sends one snapshot of the entity, and the panel draws the page from it.
- A smaller automation in memory for every panel (about 40% smaller), and a much lighter session start.
We are also exploring a new tool for the display files: nxwright, which keeps the HMI as text in hmi/src/ and builds the HMI and TFT files from it, so display changes can be reviewed like any other code. The display files of this release were built with it, and match the ones from the Nextion Editor. As this is the first release with it, the Nextion2Text dump of the display files is kept one last time, to compare with the previous release (#704, #754).
Update notes
Update both the firmware and the Blueprint. The panel and the Blueprint exchange new messages (entity snapshots, button pages, icons), so the two must be on this version together: with only one of them updated, the panel does not finish its setup.
Expect one extra restart after the update. The panel stores its Home Assistant subscriptions in a new format, so it discards the stored ones once and restarts when the Blueprint sends them again. This happens only once.
From now on, changing which entity a button page button or a climate page custom button uses (or a button's State Indicator Entity, or adding or removing its icon override) restarts the panel about 10 seconds after the Blueprint is saved, as the chips already do. Changes to labels, State Values and confirmations apply without a restart.
The page_alarm action is kept for users calling it directly, but the Blueprint no longer uses it. The panel API version goes to 3.0, as the page_media_player, page_climate and button actions are removed (see Breaking changes). A TFT update is not required, but it is recommended for the landscape and portrait displays to get the graph page drawn in the right direction (#713).
Breaking changes
-
The
commandaction is removed (deprecated since May 2026). Automations or scripts callingesphome.<panel>_commandmust send the same raw Nextion command withcomponent_text_listto thecommandmemory variable instead:action: esphome.<your_panel_name>_component_text_list data: page: mem id: command txt_list: - page home
Each element of
txt_listis sent as one command, in order. The Blueprint no longer uses thecommandaction (#747). -
The
page_media_playeraction is removed. The media player page is now drawn by the panel from the entity snapshot sent by the Blueprint, so the action is no longer needed. It was only meant for the Blueprint; there is no replacement for calling it directly (#749). -
The
page_climateandbuttonactions are removed. The climate page of Home Assistant climates is now drawn by the panel from the entity snapshot, and the climate page custom buttons (the only remaining users ofbutton) from their state subscriptions. Both actions were only meant for the Blueprint; there is no replacement for calling them directly (#751). -
Empty page scripts are removed:
page_alarm,page_canvas,page_fan,page_keyb_num,page_light,page_media_player,page_select,page_timer,page_vacuumandpage_water_heater. They had no steps, as their pages are drawn from the entity snapshot or by the Blueprint. A customization extending one of them (id: !extend page_light, for example) no longer compiles;page_climateandpage_popup_selectare kept (#745).
Bug fixes
- While the display starts, its repeated acknowledgements no longer start several Blueprint settings pushes in parallel, which loaded Home Assistant at every panel boot (#755).
- The select picker now shows option changes made in Home Assistant while it is open on the panel, without jumping to another option page (#707).
- Using the select picker (picking an option, or changing the option page with the arrows or a swipe) no longer lets the panel fall back to the home page or dim while the picker is in use (#706).
- Clearing a notification while the notification page is showing, from an automation or with the accept button, no longer leaves the notification icon visible on the home page, and the notification page no longer opens empty (#700, closes #699).
- Visibility changes to home page components (custom buttons, notification icon, temperatures, values and the other home icons) are no longer lost when they arrive while the panel is switching to the home page (#701).
- After a panel or its entities were renamed, Home Assistant no longer reports that the panel's automation uses an unknown action after an automation reload or a restart while the panel is offline. The Blueprint now waits for the panel, which requests its settings as soon as it connects (#694).
- The utilities page now refreshes as soon as a line's flow starts in either direction, for example when solar production starts or the grid starts exporting. Previously it only refreshed when one of its displayed values changed (#690).
- The graph page no longer draws the line mirrored: the newest value is now on the right, matching the time axis. Requires the TFT update; an older TFT keeps the mirrored graph, but nothing else is affected (#713, closes #693).
- PID climate add-ons (
climate_pid_singleandclimate_pid_dual): a valve relay restored on after a reboot is now switched off when there is no heating demand, instead of staying on indefinitely (#723, closes #721). - PID climate add-ons: the stored integral, including
pid_starting_integralon the first boot, is no longer overwritten with 0 right after boot (#723, closes #722). nspanel_blank.tftis now compiled with Nextion Editor 1.68.2 (#708, closes #702).- When the panel boots while Home Assistant is unreachable, the home page keeps its layout (indoor and outdoor temperatures, buttons, values), so the indoor temperature that opens the embedded thermostat is shown and the climate controls stay reachable offline. The layout last received from the Blueprint is now stored on the panel (#736).
- Cover page: a position or tilt set with the slider now stays on the slider until the cover gets there, instead of jumping back to the old position and then stepping through the positions reported while the cover moves. The slider is also redrawn less often while the cover moves (#750).
Changes
- Button pages are drawn by the panel. The Blueprint sends the button settings once per session; the panel follows each button's entity (and its State Indicator Entity, value attribute, colour and icon) through state subscriptions and draws the buttons itself: labels, page title, pressed background, icon and colour, the value next to the icon (light brightness, fan speed, cover position, climate temperature, humidifier humidity) and the momentary flash of buttons, scenes, scripts and automations (#728).
- An entity's own
colorattribute is no longer used for button icons; a light's colour still is. - After a momentary flash, the icon goes straight back to its normal colour.
- A climate in the
unknownstate is now drawn off.
- An entity's own
- The panel resolves entity icons itself. Device class icons (for example a door open or closed, a valve opening) and domain defaults are now built into the firmware and follow the entity's actual state, also before Home Assistant connects. A
sunentity shows the night icon below the horizon. The full icon name list is sent to the panel once per session, so entities whose own icon changes at runtime (for example template entities) are updated on the panel without any automation run (#730, #732). - Entity details pages are drawn by the panel. The button, switch, select, alarm, light, fan, cover, climate, timer, vacuum / lawn mower, media player and water heater (also used for humidifiers) pages are rendered on the panel from a snapshot of the entity sent by the Blueprint: title and icon, state, sliders, effects and preset modes, speed buttons, the cover position and tilt, the timer countdown, the vacuum buttons and battery (from the device's battery sensor when the entity has no
battery_levelattribute), the media player track, artist, buttons, volume and progress, the climate temperatures, sliders, HVAC mode buttons and preset button, and the water heater and humidifier slider, values and mode buttons. Apart from the changes below, these pages look the same as before; they also work for entities opened throughentity_details_show(#734, #738, #739, #740, #742, #748, #749, #751, #752).- Climate page: the HVAC mode buttons of Home Assistant climates now use the same colors as the embedded thermostat, and modes the climate does not support are hidden. The custom buttons are drawn by the panel from their state subscriptions, without an automation run; changing which entity a custom button uses restarts the panel about 10 seconds after the Blueprint is saved, as on the button pages (#751).
- Water heater page: values use the display language's decimal separator, and the mode buttons follow the climate page colors (light gray for a supported mode that is not active, indigo for an active
off) (#752). - Media player page: changes reported by Home Assistant are shown right away, instead of at the next poll. While the page is open, the entity is still polled at Media player - Update interval, now only when it has not changed during that interval, and a poll that brings nothing new is not sent to the panel. The progress bar no longer moves forward while the media is paused (#749).
- While the clock is not set (after a power loss while Home Assistant is unavailable, and without SNTP), the home page shows
--:--for the time instead of staying blank, and so does the screensaver when it shows the time (#737). - The panel logs, once a minute, how many state updates Home Assistant sent for its subscriptions and which entities sent the most, to spot a chatty entity (#733).
- The Blueprint option Home page - Update in the background is now disabled by default. It only covers the four Home page entity states (Entity State 01 to 04); the rest of the Home page is always kept up to date. With the default, these four values are updated right after the Home page opens, so an outdated value may show for a moment. Panels where the option was set explicitly keep their setting (#716).
- After an automation reload or a Home Assistant restart, the current page (home, button pages and entity pages) is rendered again as if it had just been opened, including labels and icons, so name and icon changes in the Blueprint show without leaving the page (#715).
- Climate chip: while idle, the mode is now shown in gray (for example a gray fire in
Heat) instead of a thermometer, on the chip and the climate page for theheat,coolanddualadd-ons, and on the chip forpid_dual. The icon on the climate page no longer goes blank while the chip is hidden, and an unknown chip visibility value now hides the chip. Thanks @meiser79 (#712, closes #667).
Performance
- The select page is now rendered by the panel from a snapshot of its entity, sent by the Blueprint through a single generic template, now shared by every entity details page. There is no visible change on the select page (#692).
- The value updates and value rendering of the home, climate, water heater and humidifier pages now share one Blueprint step each, and the page rendering after a reload reuses the page change handler (#711, #715, #720).
- Other Blueprint templates were consolidated: one refresh condition shared by all entity details pages (#689), the forecast values of the day computed in one template (#691), every panel action named in the same way (#695), the entity variables flattened with each icon looked up once (#724), and redundant
is definedtests removed with consecutive template conditions merged (#726). - The button pages no longer need the Blueprint's button render, state triggers or re-render after a click, and the session push no longer computes icons for every binding (#728, #730, #732).
- The button, switch, select, alarm, light, fan, cover, climate, timer, vacuum / lawn mower, media player and water heater pages no longer run the Blueprint's entity variables and per-field templates: each sends one entity snapshot. The media player page no longer runs its own polling loop, the climate page custom buttons no longer have state triggers, and the humidifier presses on the water heater page are translated by the panel (#734, #738, #739, #740, #742, #748, #749, #751, #752).
- Firmware size: Home Assistant events are fired from a braced list of C strings instead of a map built at every call site, and the button page settings moved from internal RAM to PSRAM (#744, #745).
- Distinct templates go from 960 to 599, widening the margin under Home Assistant's template cache of 1,024 entries, which reduces the load on Home Assistant, especially with Spook enabled. The automation also takes about 40% less memory for every panel (see Highlights).
Documentation
- The climate add-on documentation now advises against floor cooling in humid rooms, such as bathrooms or kitchens, and in humid climates, since dew-point protection measures humidity at a single point (#687).
- The climate add-on documentation describes the climate page icon and the chip visibility (#712).
- The API subscriptions and entity snapshot documentation describe the button pages, the climate page custom buttons, the icon names and the pages drawn from the snapshot (#746, #756).
Development
- The ESPHome build CI on pull requests now builds only the tests affected by add-on changes, selected from each test's includes. Any C++ change still builds every test (#686).
- The Blueprint check now fails above 700 distinct templates, keeping a margin under Spook's template cache and the reductions from slipping back (#688, #753).
- The Blueprint's entity variables equivalence test now checks the default icon of every domain (#753).
- The Blueprint metrics and the ESPHome build sizes are posted as a single comment on each pull request, updated on later pushes (#727, #731).
- The firmware icon rules are generated from the Blueprint's icon tables, and CI fails when the two copies differ (#732).
- Every ESPHome build in CI checks its flash usage against its app partition: a warning at 85%, a failure at 90%. The Customizations build is not checked (#741).
- The ESPHome build jobs add a flash breakdown by archive, file and symbol to the job summary, to see where the flash goes (#743).
- The Blueprint on
devis marked with the development version9999.99.9, set automatically after each release (#698). - As a first step in exploring nxwright, the display files are now built from its source in
hmi/src/, which becomes the source of truth for the display. Pull requests build the HMI and TFT files as workflow artifacts only, anddevgets them committed after each merge that changes the source. Nextion2Text was removed; its text dump of the HMI files is kept one last time for this release, generated manually, to compare the display files with the previous release (#696, #697, #704, #754). - The climate add-ons now provide only the action of the climate chip, while the climate base renders it, so future chip changes apply to all climate add-ons (#712).
- Dependabot opens its pull requests against
dev, so dependency updates are batched with the next release (#719).
Thank you
This release was shaped by many people who reported, tested and contributed. Thank you:
- @quenthal for reporting the Home Assistant event loop blocking with several panels (#636), which started the Blueprint review behind most of this release, and @wejto, @stefanhintermayr and @bartbakels for the profiling, measurements and tests from your systems, which pointed to the template cache shared with Spook.
- @meiser79 for the PID climate add-ons and the climate chip work (#661, #712).
- @thomashf for the detailed reports on the PID add-ons (#721, #722).
- @rDeRYCeN for reporting the mirrored graph (#693).
- @bkbartk for reporting the notification icon that stayed on the home page (#699).
- @nixiewright for nxwright, the display toolchain we are now exploring.
Related to #636, #657 and #661.
What's Changed
Bug Fixes
- fix: Hide the notification icon when clearing from the notification page by @panel-easy-assistant[bot] in #700
- fix: Apply home visibility changes made while the page was loading by @panel-easy-assistant[bot] in #701
CI & Automation
- ci: bump mikefarah/yq from 4.54.1 to 4.54.2 in the actions-versioning group by @dependabot[bot] in #718
Dependency Updates
- build: bump clang-format from 23.1.3 to 23.1.5 in /.github by @dependabot[bot] in #717
Other Changes
- ci: Build only the ESPHome tests affected by add-on changes by @panel-easy-assistant[bot] in #686
- docs: Advise against floor cooling in humid rooms and climates by @panel-easy-assistant[bot] in #687
- ci: Fail the Blueprint check above 980 distinct templates by @panel-easy-assistant[bot] in #688
- improve: Share one refresh condition across the entity details pages by @panel-easy-assistant[bot] in #689
- fix: Let the utilities line reference triggers fire by @panel-easy-assistant[bot] in #690
- improve: Compute the forecast values of the day in one template by @panel-easy-assistant[bot] in #691
- fix: Skip the reload settings request while the panel's device name is unknown by @panel-easy-assistant[bot] in #694
- improve: Name every panel action from action_prefix by @edwardtfn in #695
- ci: Add nxwright HMI text dump alongside Nextion2Text by @panel-easy-assistant[bot] in #696
- ci: Mark the Blueprint on dev with the development version 9999.99.9 by @panel-easy-assistant[bot] in #698
- fix: Reset the page timers while using the picker by @panel-easy-assistant[bot] in #706
- fix: Show option changes from Home Assistant on the open select picker by @panel-easy-assistant[bot] in #707
- feat: Render the select page from an entity snapshot by @panel-easy-assistant[bot] in #692
- chore: Compile
nspanel_blank.tftwith latest editor by @edwardtfn in #708 - improve: Share one value update across the home, climate and water heater pages by @panel-easy-assistant[bot] in #711
- fix: Graph line drawn mirrored by @panel-easy-assistant[bot] in #713
- improve: Disable the Home page background update by default by @panel-easy-assistant[bot] in #716
- ci: Remove Nextion2Text in favor of nxwright by @panel-easy-assistant[bot] in #697
- improve: Render the current page again after a reload through the page change handler by @panel-easy-assistant[bot] in #715
- feat(hmi): Build the display files from the nxwright source by @panel-easy-assistant[bot] in #704
- ci: Open Dependabot pull requests against dev by @panel-easy-assistant[bot] in #719
- refactor: Let climate add-ons provide only the action of the climate chip by @meiser79 in #712
- improve: Render the home, climate and water heater page values in one shared step by @panel-easy-assistant[bot] in #720
- fix: PID add-ons drive the valve relay after boot and keep the starting integral by @panel-easy-assistant[bot] in #723
- refactor: Flatten the Variable Entity anchor outputs and look up each icon once by @panel-easy-assistant[bot] in #724
- fix: Restore the entity details title and pages guarded by the removed entity variable by @panel-easy-assistant[bot] in #725
- refactor: Remove redundant is defined tests and merge consecutive template conditions by @panel-easy-assistant[bot] in #726
- ci: Post Blueprint metrics as a PR comment by @panel-easy-assistant[bot] in #727
- feat: Render the button pages on the panel from subscriptions by @panel-easy-assistant[bot] in #728
- feat: Resolve entity icons on the panel from the Blueprint icon table by @panel-easy-assistant[bot] in #730
- ci: Post ESPHome build sizes as a PR comment by @panel-easy-assistant[bot] in #731
- feat: Hard-code the icon rules in the firmware by @panel-easy-assistant[bot] in #732
- feat: Log the traffic of the API subscriptions by @panel-easy-assistant[bot] in #733
- feat: Render the button, switch and select pages titles and states on the panel by @panel-easy-assistant[bot] in #734
- fix: Restore the home page layout when booting without Home Assistant by @panel-easy-assistant[bot] in #736
- feat: Show a placeholder for the time while the clock is not set by @panel-easy-assistant[bot] in #737
- feat: Render the alarm page on the panel from the entity snapshot by @panel-easy-assistant[bot] in #738
- feat: Render the light page on the panel from the entity snapshot by @panel-easy-assistant[bot] in #739
- feat: Render the fan and timer pages on the panel from the entity snapshot by @panel-easy-assistant[bot] in #740
- ci: Guard the flash usage of the ESPHome builds by @panel-easy-assistant[bot] in #741
- feat: Render the vacuum and lawn mower page on the panel from the entity snapshot by @panel-easy-assistant[bot] in #742
- perf: Fire Home Assistant events from a braced list of C strings by @panel-easy-assistant[bot] in #744
- ci: Break the flash usage of the ESPHome builds down by archive and file by @panel-easy-assistant[bot] in #743
- perf: Remove the empty page scripts and keep the button page settings in PSRAM by @panel-easy-assistant[bot] in #745
- docs: Bring the API subscriptions and entity snapshot documentation up to date by @panel-easy-assistant[bot] in #746
- feat!: Remove the deprecated
commandaction by @panel-easy-assistant[bot] in #747 - feat: Render the cover page on the panel from the entity snapshot by @panel-easy-assistant[bot] in #748
- feat: Render the media player page on the panel from the entity snapshot by @panel-easy-assistant[bot] in #749
- fix: Keep the position set on the cover page on screen while the cover moves by @panel-easy-assistant[bot] in #750
- feat: Render the climate page on the panel from the entity snapshot by @panel-easy-assistant[bot] in #751
- feat: Render the water heater page on the panel from the entity snapshot by @panel-easy-assistant[bot] in #752
- chore: Bring back the Nextion2Text dump of the HMI files for this release by @panel-easy-assistant[bot] in #754
- ci: Lower the Blueprint template limit and test every domain's default icon by @panel-easy-assistant[bot] in #753
- fix: Skip the repeated display acknowledgements while booting by @panel-easy-assistant[bot] in #755
- docs: Describe the climate page custom buttons drawn from API subscriptions by @panel-easy-assistant[bot] in #756
- feat: Button and entity pages drawn by the panel, panel-side icons and a much lighter Blueprint by @edwardtfn in #710
Full Changelog: v2026.11.15...v2026.11.16