fix(on-air): find the real LEDMatrix root when loading the sign font - #386
Merged
Conversation
The sign looks for a TTF under the LEDMatrix assets folder, resolving the root
as two levels above the plugin file. That is right when the plugin sits at
<LEDMatrix>/plugin-repos/<id>, and wrong whenever the plugins directory is
configured somewhere else -- the search then finds nothing and the sign drops
to a built-in font a fraction of the intended size, with no error. It now asks
the imported core where it lives and keeps the old guess and the working
directory as fallbacks.
That is also what made this plugin impossible to document honestly: rendered
from this repo, the sign came out in tiny default lettering rather than the
80%-of-panel-height face a real install shows.
README: real rendered screenshots throughout, the config.json key for all 16
settings, and three corrections.
- "The label (max 16 chars) replaces ON AIR ... on panels 128px wide or larger
ON AIR appears as the header with your label as a subtitle below it" -- there
is no length bound and no header/subtitle layout in the code. The label is
drawn on its own, centred, scaled to fit.
- Five automation examples sent {"color": [255, 140, 0]} where they meant the
background. In a payload, "color" is the text colour and "bg" is the
background, so those examples produce orange lettering on the default red
rather than an amber sign. The payload reference already said this; the
examples contradicted it.
Tooling: shots can now declare "attrs", runtime state applied to the plugin
instance after the core's loader builds it. An event-driven plugin like this
one holds its interesting state in memory, put there by an MQTT message, so no
configuration reaches it and a documentation render would only ever show the
idle black frame.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Contributor
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Team Run ID: 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 |
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 25 |
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
This was referenced Sep 3, 2026
ChuckBuilds
added a commit
that referenced
this pull request
Sep 3, 2026
The README described the display with three hand-drawn text sketches:
03/15 2:30pm
Team Meeting
They are now real plugin output at the true panel size -- a timed event, an
all-day event, a long title being ellipsized, and the empty state -- plus a
panel-size sheet.
Also documents google_auth, the one setting the reference did not mention. It
is not a value you type: it is the web UI's "Connect Your Google Account"
button (x-widget: google-oauth). The two combined customization rows are split
so each key appears on its own, which takes the plugin to 13 of 13 settings
documented by key.
Rendering these needed the shots "attrs" seam from #386, which is not on main
yet; the identical change to sitecustomize.py and render_docs_assets.py is
included here so this branch can render on its own.
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
ChuckBuilds
added a commit
that referenced
this pull request
Sep 3, 2026
…390) The "Key options" table listed 7 of the 25 settings and pointed at config_schema.json for the rest, which meant the two thirds that shape what actually appears on a card -- show_dashboard, show_delivered, show_delivery_images, include_delivered, the scroll settings, the timezone override -- were undocumented. All 25 are now covered, grouped by connection, card contents, and rotation, with the advanced ones marked. The plugin had no images. It ships a mock provider precisely so the layout can be previewed without credentials, so every screenshot here comes from that: the three card types, four panel sizes, and before/after pairs for show_dashboard, highlight_today, show_carrier_logo and show_delivered. Each pair was hash-compared to confirm the setting actually changes the render. Adds the plugin to the root README, where it was missing (#385). That creates a Productivity section, which #384 also adds for pomodoro-timer -- whichever lands second needs the two rows merged into one section. Rendering used the shots "attrs" seam from #386, not yet on main; the identical tooling change is included so this branch renders on its own. Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
ChuckBuilds
added a commit
that referenced
this pull request
Sep 3, 2026
Both sides added an independent option to the documentation renderer, so the resolution keeps both: attrs (from #386, runtime state for event-driven plugins) and hostname (this branch, pinning socket.gethostname so a panel that prints the device name renders the same on any machine). Verified after resolving: --check reproduces this branch's four hostname-pinned images and on-air's four attrs-driven ones byte-identically, so neither seam was lost in the merge. Also added both options to the shot-key docstring, which listed neither. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
The bug
The sign picks a TTF out of the LEDMatrix
assets/fontsfolder and draws at 80% of panel height. It located that folder as two levels above the plugin file:That holds when the plugin sits at
<LEDMatrix>/plugin-repos/<id>. The plugins directory is configurable, though, and anywhere outside the core tree the search finds nothing, falls through to a built-in font, and the sign renders a fraction of its intended size — with adebuglog line and nothing else.It now asks the imported core where it lives (
Path(src.__file__).parent.parent), keeping the old guess and the working directory as fallbacks.This is also what made the plugin impossible to document honestly: rendered from this repo, every screenshot came out in the small fallback font rather than what a real install shows.
README
Real rendered screenshots throughout,
config.jsonkeys for all 16 settings, and three corrections found by reading the code against the prose.1. The label claims are not implemented. The README said:
There is no length bound anywhere in
manager.py(the schema caps the configured Sign Text at 32; a payload label is unbounded) and no header/subtitle layout —display()draws the label alone, centred, scaled to fit.2. Five automation examples set the wrong field. They send:
{"state": "on", "label": "IN MEETING", "color": [255, 140, 0]}In a payload,
coloris the text colour andbgis the background:So those examples produce orange lettering on the default red, not an amber sign. The Payload Reference section already documented this correctly; the Advanced examples contradicted it. Both are now
bg, and the README shows the difference:3. The off state. Documented for the first time — it draws a black frame rather than dropping out of the rotation, deliberately, so the display controller does not flash its "Initializing" screen while the stop request is processed.
Tooling
Shots can now declare
attrs: runtime state applied to the plugin instance after the core's loader builds it, via a wrapped loader in the docs shim. An event-driven plugin holds its interesting state in memory — put there by an MQTT message — so no configuration reaches it and a render would otherwise only ever show the idle frame. The same seam will covermqtt-notificationsand the other event-driven plugins.Checks
check_plugin.py: 8/8 pass (the harness renders the idle frame, so the font change does not move it)render_docs_assets.py --check: all five images reproduce1.2.5 → 1.2.6.
🤖 Generated with Claude Code