fix(ledmatrix-elections): load fixtures as UTF-8, and finish the docs - #441
Merged
Conversation
check_plugin.py reported 16 FAIL of 32 on Windows. manager.py loaded the bundled NYT fixture with a bare open(), so Python used the platform default encoding -- cp1252 -- and the read raised part-way through: test_mode: NYT fixture load failed: 'charmap' codec can't decode byte 0x9d in position 1744733 The fixture is UTF-8 and carries non-ASCII candidate names. The exception was caught and logged, test_mode then found no races, and every panel rendered blank. On Linux the default is UTF-8, so the path works and nothing is visible -- which is why it survived. Confirmed pre-existing on main by stashing. Both call sites, manager.py and test_elections.py's load() helper, now pass encoding="utf-8". The harness goes 16 FAIL -> 0 FAIL. Filed as #440. The README's only image was a placeholder pointing at "#". It now carries real renders of both display modes and of four panel sizes. Twelve settings were undocumented or absent from the table -- the two district numbers, both scroll knobs, and the eight provider endpoints -- so all 35 schema leaves are now covered, verified by a token audit. Also recorded: test_mode and providers.ca_sos.override_nyt_votes are read by the code but declared nowhere in config_schema.json, so they never reach the web UI and can only be set by hand. Both work; the README now says they are hand-edit only rather than implying the form offers them. The renders replay a small NYT-shaped feed rather than seeding plugin state, because the plugin parses that JSON into Race and Candidate dataclasses and the renderer uses attribute access -- a dict pushed onto self.races would not survive. So the images exercise the real parse. Rendering the scrolling ticker needed one tooling change: the frame runner took no --display-mode, so a multi-mode plugin could not have a scrolling shot. It now accepts one, with the same TypeError fallback render_plugin.py uses. 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 | 18 |
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.
ChuckBuilds
added a commit
that referenced
this pull request
Sep 4, 2026
…renders (#442) The README explained the MQTT side well -- payload format, topic wildcards, five Home Assistant examples -- but never listed the plugin's own settings, and had no images. All 20 schema leaves are now documented, verified by a token audit, with three renders. The five that were missing: mqtt.client_id, mqtt.keepalive, text.scroll_gap_width, update_interval and display_duration. display_duration is worth its own note. The core reads it as a plugin's screen time (base_plugin.py:406), but this plugin overrides get_display_duration() and returns display.default_duration instead, so setting the root key alone changes nothing. The two defaults agree at 10s, which hides it until someone sets one and not the other. The README now says which one to set. update_interval, by contrast, is live: the core schedules update() from it (plugin_manager.py:809). Both looked dead to a grep of the plugin alone -- neither name appears in manager.py -- and grepping the core is what separated the two. Also documented: the two font routes. text.font_path takes any path, customization.message_text.font offers the bundled faces as a dropdown, and the customization block wins when its font loads. Colours come from text either way, since customization carries no colour keys. check_plugin.py passes 8/8 with no FAIL. Carries the docs-tooling changes from #423 and the frame-runner --display-mode change from #441, which these renders depend on. 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
check_plugin.pyreported 16 FAIL of 32 on Windows.manager.pyloaded the bundled NYT fixture with a bareopen(), so Python used the platform default encoding — cp1252 — and the read raised part-way through:The fixture is UTF-8 and carries non-ASCII candidate names. The exception is caught and logged,
test_modethen finds no races, and every panel renders blank. On Linux the default is UTF-8, so the path works and nothing is visible — which is why it survived.Confirmed pre-existing on
mainby stashing: the same 16 failures. Both call sites (manager.py, andtest_elections.py'sload()helper) now passencoding="utf-8". The harness goes 16 FAIL → 0 FAIL. Filed as #440.Docs
The README's only image was a placeholder pointing at
#. It now has real renders of both display modes and of four panel sizes.Twelve settings were missing from the configuration table — the two district numbers, both scroll knobs, and the eight provider endpoints. All 35 schema leaves are now documented (token audit: 0 undocumented).
Two settings the code reads are declared nowhere in
config_schema.json:test_mode(manager.py:64) andproviders.ca_sos.override_nyt_votes(manager.py:80). Both work, but neither reaches the web UI, so they are hand-edit only. The old README documented both as if the form offered them; it now says otherwise. Same class as #427 and #429.How the renders work
They replay a small NYT-shaped feed rather than seeding plugin state, because the plugin parses that JSON into
RaceandCandidatedataclasses and the renderer uses attribute access — a dict pushed ontoself.raceswould not survive. So the images exercise the real provider parse, including thefirst_name/last_nameextraction (my first attempt usedname_displayand the cards rendered candidate ids).One tooling change
_docs_frame_runner.pytook no--display-mode, so a multi-mode plugin could not have a scrolling shot — the ticker failed withunrecognized arguments. It now accepts one, with the sameTypeErrorfallbackrender_plugin.pyuses. Same shape as the earlier--skip-updatefix.Checks
check_plugin.py: 32/32 PASS, zero FAIL (was 16 FAIL)plugins.jsonregenerated🤖 Generated with Claude Code