Lambda-based labels refactor + live WiFi icon, configurable accuracy, ESPHome 2026.6 compat - #16
Open
oxc wants to merge 7 commits into
Open
Lambda-based labels refactor + live WiFi icon, configurable accuracy, ESPHome 2026.6 compat#16oxc wants to merge 7 commits into
oxc wants to merge 7 commits into
Conversation
Instead of having each on_value handler know exactly how the label needs to be formatted and pushing text into it via lvgl.label.update, define the label text as a !lambda that reads the source state (rendering a placeholder while !has_state()), and have the sensor/text_sensor simply lvgl.widget.refresh the label. This centralizes formatting and makes labels show the correct value on boot/reconnect, not just after the first update. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Render sensor tile values from a label !lambda (consistent with the
label refactor) and make the number of decimals configurable via an
optional `accuracy` var (default 1), e.g. `accuracy: 0` for integers.
Also expose the coloured icon container via an id so a consumer can
pass a dynamic `color:` lambda and refresh it, and quote `${unit}` so
values like empty strings are handled safely.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Compute the top-bar WiFi icon from a label !lambda based on wifi_signal_percent (and a wifi_connected global toggled by the wifi on_connect/on_disconnect handlers), refreshing it on value change and connect/disconnect. When disconnected it shows the dedicated offline glyph. The SDL/host build has no WiFi hardware, so it stubs wifi_signal_percent and relies on the global default so the shared lambda still compiles and the preview shows a signal. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Drop the pinned esp-idf `version` / `platform_version` so ESPHome uses its recommended framework version. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add mdi:water-percent and mdi:weather-dust to the icons35 tile font for use as humidity / air-quality tile icons. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The pager dots are created by a script at runtime, but an explicit empty `widgets: []` is needed for the project to compile. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Newer ESPHome rejects show_test_card (along with auto_clear_enabled: true, lambda: and pages:) on a display driven by LVGL, since LVGL owns the framebuffer. This project always uses LVGL so the test card never rendered anyway; removing it lets the SDL/host dev build validate and run on current ESPHome. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR refactors LVGL label rendering to be lambda-driven (labels read source state directly and are updated via lvgl.widget.refresh), and builds new UI behavior on top of that (notably a live WiFi strength icon and configurable numeric precision), while also aligning configs with ESPHome/LVGL 2026.6 compatibility.
Changes:
- Migrate multiple labels from
lvgl.label.updateinon_valuehandlers totext: !lambda+lvgl.widget.refresh. - Add lambda-rendered sensor tiles with optional
accuracyand expose icon-containeridfor dynamic color refresh. - Implement a live WiFi icon (connected/offline + strength tiers), stubbed for SDL/host builds; remove
show_test_cardand unpin ESP-IDF version for 2026.6 compat.
Reviewed changes
Copilot reviewed 22 out of 22 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| HomeDicator/user_interface/templates/tiles/thermostat/wide.yaml | Thermostat value label now renders from a lambda instead of static text. |
| HomeDicator/user_interface/templates/tiles/thermostat/wide_half_height.yaml | Same lambda-based thermostat value label refactor. |
| HomeDicator/user_interface/templates/tiles/thermostat/wide_half_height_icon_right.yaml | Same lambda-based thermostat value label refactor. |
| HomeDicator/user_interface/templates/tiles/thermostat/square.yaml | Same lambda-based thermostat value label refactor. |
| HomeDicator/user_interface/templates/tiles/thermostat/helpers/on_value.yaml | Thermostat interaction handler switched from label updates to widget refresh + HA action. |
| HomeDicator/user_interface/templates/tiles/sensor/wide.yaml | Sensor tile uses lambda text with configurable accuracy; exposes icon container id. |
| HomeDicator/user_interface/templates/tiles/sensor/square.yaml | Same as wide sensor tile: lambda text + accuracy + icon container id. |
| HomeDicator/user_interface/pages/top_layer/wifi.yaml | WiFi icon is now computed dynamically from connection + signal percent. |
| HomeDicator/user_interface/pages/top_layer/time.yaml | Time label now formats itself via lambda (24h/12h). |
| HomeDicator/user_interface/pages/top_layer/bottom_pager.yaml | Pre-creates an explicit empty widgets: [] list for compatibility. |
| HomeDicator/user_interface/pages/about.yaml | ESPHome version label now reads the text sensor directly via lambda. |
| HomeDicator/device/sdl.yaml | Stubs wifi_signal_percent for host builds so shared UI lambdas compile. |
| HomeDicator/core/templates/sensor.yaml | HA sensor template now refreshes the widget instead of pushing formatted text. |
| HomeDicator/core/templates/climate_sensor.yaml | Climate sensor template now refreshes the value label instead of pushing formatted text. |
| HomeDicator/core/templates/climate_sensor_wide.yaml | Same refresh-based refactor for wide climate sensor template. |
| HomeDicator/core/config/device/seeed-sensecap-indicator/hardware.yaml | Unpins ESP-IDF version; adds WiFi connect/disconnect handling to refresh icon + track connected state. |
| HomeDicator/core/config/device/sdl/hardware.yaml | Drops show_test_card for ESPHome/LVGL 2026.6 compatibility. |
| HomeDicator/core/config/common/text_sensors/esphome_version.yaml | Text sensor now triggers widget refresh instead of updating label text directly. |
| HomeDicator/core/config/common/sensors/wifi_signal_percent.yaml | WiFi percent sensor now refreshes the icon widget instead of formatting the glyph in-place. |
| HomeDicator/core/config/common/scripts.yaml | update_time now refreshes the time widget rather than setting formatted text. |
| HomeDicator/core/config/common/globals.yaml | Adds wifi_connected global used by the WiFi icon lambda. |
| HomeDicator/core/config/common/fonts.yaml | Adds water-percent and weather-dust glyphs to the icon font. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
5
to
7
| then: | ||
| - lvgl.label.update: | ||
| id: lvgl_value_label_${hass_climate_id} | ||
| text: !lambda |- | ||
| char buffer[10]; | ||
| snprintf(buffer, sizeof(buffer), "%.0f", x); | ||
| return buffer; | ||
| - lvgl.widget.refresh: lvgl_value_label_${hass_climate_id} | ||
| - homeassistant.action: |
Comment on lines
+7
to
+8
| # Host build has no WiFi hardware; stub the sensor the shared WiFi icon | ||
| # lambda reads so it compiles and shows a signal in the preview. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Refactors how display labels are populated and builds a few features on top of it.
Instead of every sensor's
on_valuehandler formatting text and pushing it into alabel via
lvgl.label.update, each label now owns atext: !lambdathat reads thesource state directly, and the sensor just calls
lvgl.widget.refresh. Thiscentralizes formatting and makes labels show the correct value on boot/reconnect
rather than only after the first update.
AI Disclaimer
I had written those changes months ago before I had started using AI agents (at least
for esphome). I have now used Claude Code to polish things and re-create the commits
in the forked repo (I only had them in my esphome config).
Changes
climate templates, thermostat tiles, clock, About page and version labels now format
their own text; handlers just refresh.
from a lambda and accept an optional
accuracyvar (default1, e.g.accuracy: 0for integers). The coloured icon container is given an id so a consumer can pass a
dynamic
color:lambda and refresh it.from
wifi_signal_percentplus awifi_connectedglobal toggled on connect/disconnect, showing the dedicated offline glyph when disconnected. The SDL/host build
stubs the sensor so the shared lambda still compiles.
version/platform_version.tile icons.
widgets: []neededto compile.
framebuffer, so
show_test_cardis rejected on newer ESPHome; it never rendered hereanyway.
Points worth discussing
recommended one. Happy to split this into its own PR if you'd rather keep the pin.
accuracyuses a Jinja-filter substitution(
%.${accuracy | default(1)}f), so this raises the minimum ESPHome version. Combinedwith the unpin + the
show_test_cardfix, the tree now validates cleanly onESPHome 2026.6.4 (
Configuration is valid!).Testing
esphome config HomeDicator.yaml(SDL/host build) reports Configuration is valid!on ESPHome 2026.6.4.