From 0182cb187ec38eba914c84c2a04e1a5261ce67ee Mon Sep 17 00:00:00 2001 From: Chuck <33324927+ChuckBuilds@users.noreply.github.com> Date: Wed, 2 Sep 2026 17:22:54 -0400 Subject: [PATCH] docs(of-the-day): document every setting, with real renders Documentation only; no behaviour change. All 13 settings covered, plus the per-category block and the data-file format. Leads with why a fresh install shows "No Data": enabled is false, and the categories block is empty. The bundled word lists ship with the plugin but nothing points at them until a category is added, so the plugin looks broken rather than unconfigured. Corrects the data-file format. The old README said entries are keyed by YYYY-MM-DD; the bundled files and the loader both use the day-of-year number, "1" through "365". A file written with date keys loads without error and then shows nothing, because no key ever matches -- worth stating plainly since the failure is silent. Documents that the customization keys are font_size and text_color. The schema declares these elements through an x-style-elements block using the short names size and color, but that is the declaration format: the core expands it into font / font_size / text_color. I wrote size and color first, saw no change across four renders, and was about to record customization as broken -- it is not, the short names are just silently ignored. That is an easy mistake to make from reading the schema, so it is called out. auto_fit_text is demonstrated where it actually shows: 128x64 with body font_size 12, where shrinking gains a line. Verified by hashing renders that it is a genuine no-op at 128x32 and at 64x32, where one body line is all that fits either way, so the README says where it matters rather than implying it always does. Audits before opening: no config token dropped, all 13 schema leaves documented, no broken TOC anchors, and the section check surfaced the content-authoring tips, restored as a "writing your own list" section. Note: check_plugin reports golden drift on all eight sizes for this plugin. That is pre-existing on main -- identical figures with these changes stashed -- and confined to the body text line, which renders wider than the golden. Left alone deliberately: regenerating goldens here would bake this machine's font metrics in, and the 7-segment tRNS episode is a reminder that rasterisation can differ by dependency version. Co-Authored-By: Claude Opus 5 --- README.md | 2 +- docs/assets/of-the-day/auto-fit.png | Bin 0 -> 16711 bytes docs/assets/of-the-day/categories.png | Bin 0 -> 13486 bytes docs/assets/of-the-day/customization.png | Bin 0 -> 21151 bytes docs/assets/of-the-day/hero.png | Bin 0 -> 2036 bytes docs/assets/of-the-day/panel-sizes.png | Bin 0 -> 22900 bytes docs/assets/of-the-day/shots.json | 277 +++++++++++++ plugins.json | 4 +- plugins/of-the-day/README.md | 502 +++++++++++++---------- plugins/of-the-day/manifest.json | 11 +- 10 files changed, 577 insertions(+), 219 deletions(-) create mode 100644 docs/assets/of-the-day/auto-fit.png create mode 100644 docs/assets/of-the-day/categories.png create mode 100644 docs/assets/of-the-day/customization.png create mode 100644 docs/assets/of-the-day/hero.png create mode 100644 docs/assets/of-the-day/panel-sizes.png create mode 100644 docs/assets/of-the-day/shots.json diff --git a/README.md b/README.md index 9fae8532..4c9df95e 100644 --- a/README.md +++ b/README.md @@ -136,7 +136,7 @@ curl -X POST http://your-pi-ip:5000/api/v3/plugins/install \ | Plugin | Description | Preview | |--------|-------------|---------| | [News Ticker](./plugins/news/) | RSS news headlines from ESPN, NCAA, custom sources | | -| [Of The Day](./plugins/of-the-day/) | Daily quotes, Bible verses, word of the day | | +| [Of The Day](./plugins/of-the-day/) | Daily quotes, Bible verses, word of the day | of-the-day on an LED panel | ### Integrations (2) diff --git a/docs/assets/of-the-day/auto-fit.png b/docs/assets/of-the-day/auto-fit.png new file mode 100644 index 0000000000000000000000000000000000000000..9b0d79c73ab2fc812808bbb1f3ea759f4119fe7e GIT binary patch literal 16711 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 Af&c&j literal 0 HcmV?d00001 diff --git a/docs/assets/of-the-day/categories.png b/docs/assets/of-the-day/categories.png new file mode 100644 index 0000000000000000000000000000000000000000..6840b7bf85316984b876538d09ad625f606b9c5e GIT binary patch literal 13486 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 literal 0 HcmV?d00001 diff --git a/docs/assets/of-the-day/customization.png b/docs/assets/of-the-day/customization.png new file mode 100644 index 0000000000000000000000000000000000000000..5255d8ef51fc16533b235af3ff13436220d25f5c GIT binary patch literal 21151 zcmdU%c|6qX-|(l?uR5nqj&Kl)6DMnteXEm_ge*h$RLBU~chfm7NK%BXQz$!yu`{P+ zU#2kjAr&#LPq5Zl!eh^_a&{|??c-I}$IK0PzW6y`(TZ3I$ zp8g*E#Csd->3w?Nqk>P4i13Zx@L)?3IyQ;we=8WjT;-w?LG^a?ed}>@F4%bAN#zUs z_UZjY{e;9eJ%!N&xjyS3J*39Bm)Vz*>HZ9EOongfL`IrJqa=YU`tjYf&NKOug7vW@xbP&0D?8-LpOMvVF1 zMjK!Lw7HE<&2O}^x%rJY{-XI{Q&wB;1bLUmsUGxlHNR`$^iUALsvo>8u*0Akv{Q@~RYr68Qrb-pdX8Q+^Omc$cmx7zy7ut$V;5 zt~inY7O%nQa}{2M{eUyK*Z zF{+i>+093GAW%=GTjf)pKD{(IT;teReB4`yHhMJPmWz_e0;=<=wVE$Mhu?Mx=_D+V#XGC6P8Aqicp$B< zt=0E)a0m_5QVTF^Vy`;ya9TdOHVzBX#^GE^?ev?il$)bC787M*dEN?M3gY$bPV^d} z%{NKnpBx(*Ps8Y3XGL6MX;r2)2Yatky9RwHbAo@8y?$|Og7+e`ThL|O<|lI>Q^NUN z-m+Shd#({@1LYih3tdKPp(URT;@$)DpXT7BlomOR&sc1#Uj&hO7kPbBX^_?mE3v}A zKF8m>7qQP{tRZ{1$LzpbQJ<5;yQe4B54bfSD<1Hjl&hKxo1dQ_st#Ho=EVK-%P+yf zZ{EDwvUU3bpV3Eli5{Jq$gBw8lFo7Y|i3wb>H`s&dP8_K8^P29J5vUF0 z>B2g6jfAUJ`7O<;_%1wALkE&-_9}jS>Nis=Jm-2VNyTp&-Z9>HX-7zx}8Aun3oOxB?@TcuwK*?*S`>fk(B6*8!J5^~+|+b0;4x@W=xtCzu;(Q2fXdg{6MC zNFzxRk#iMVjFfOy#mVe~?Yn$mC;Du0e?yhr=_=M1CJ2QT8!8!yrv3LH<=?;c)?dT#FYdJqX=# z0p=Vn4WifK8|9O^m+Q``6GD2}JXSMK&;o> z)z;dnBti86zCnU1)DG90XqwCSFIL4R{=|zP6-Gf9XEn_LgO`Gbhxda#+RDnB5Ew z3O-Y{Iy37}R=Tx=Wv1=9mjB%Ct}6biRL#gF(5>K)9U1Lln^NXR>R7m>-YRcJc#?0k z>0BdZBGnVX^oGcJ2r-`L1gtKyJD)yVwyn3q$Bh(yZ~eSTp1DGhX@RY_dg1jRscOG8 zo2KZfm>4A`SPHzC?Q|RTj!n(nhZF@%(p?=9;+GeEt^I}ea8PTal3f?_4OqDc%JcQ0 zr=T3<>Egke&K$EEt&$?Jf^Ov2?R&V7J9LV@*Ecs$Xc#i2SC7N@@<36UYFHh_q6P*l zUdF+*dXJp)I-TOQW6Mp8mENwZqH?Rmz?E@n+vfT*azsSL^6*gJ+v#>;jDN&XW&7fE zUm`b5q?=5&p|oA=`3ja{uv}_WFROR%+Qp)>@UG9PT->7p1OiQNO=NX>f11++qzZ;V zxH_!RoWVG1thOb(C@XC09`jDKQJR30U7ZQZC^qaY>1~$s(&E4mh=a

Pl}L(zkrv3_lrTOLfC{Y(Q8x_uc#6w`m{58 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

?&5gq0TwuC6+~Efz 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 ps_:5000`, go to **Plugin Manager**, find **Of The Day** in the +**Plugin Store** section, and click **Install**. -When you download/install this plugin, everything it needs is included. When you delete it, no traces remain. +**Manually.** Copy this directory into your LEDMatrix `plugin-repos/` and +restart the display service. -## Data File Format +> **A fresh install shows "No Data".** Two things are off by default: +> `enabled` is `false`, and — more surprisingly — **the `categories` block is +> empty**. The bundled data files exist, but nothing points at them until you +> add a category. See below. -Each category uses a JSON file with daily entries: +--- -### Word of the Day Format +## Adding a Category -```json -{ - "2025-10-11": { - "word": "Ephemeral", - "pronunciation": "ih-FEM-er-uhl", - "type": "adjective", - "definition": "Lasting for a very short time; transitory", - "example": "The beauty of cherry blossoms is ephemeral, lasting only a week or two." - } -} -``` +The easiest route is the plugin's own tab in the web interface, which lists the +bundled files, lets you upload your own, and writes the config for you. -### Bible Verse Format +By hand, a category is an entry in the `categories` object keyed by an id of +your choosing: ```json { - "2025-10-11": { - "title": "John 3:16", - "content": "For God so loved the world that he gave his one and only Son...", - "reference": "John 3:16 (NIV)" + "of-the-day": { + "enabled": true, + "categories": { + "word_of_the_day": { + "enabled": true, + "data_file": "of_the_day/word_of_the_day.json", + "display_name": "Word of the Day" + } + }, + "category_order": ["word_of_the_day"] } } ``` -### Custom Format +| Key | Type | Default | What it does | +|-----|------|---------|--------------| +| `enabled` | boolean | `true` | Include this category in the rotation | +| `data_file` | string | — | Path to the JSON file, relative to the plugin directory | +| `display_name` | string | — | Label shown in the configuration UI | + +Two lists ship with the plugin: -You can create custom categories with any structure containing: -- `word` or `title`: Main heading -- `definition` or `content` or `text`: Main content -- Optional: `pronunciation`, `type`, `example`, etc. +![Two panels: the English word of the day, and the Slovenian +one](../../docs/assets/of-the-day/categories.png) -## Usage +| File | Contents | +|------|----------| +| `of_the_day/word_of_the_day.json` | An English word a day, with definition and example | +| `of_the_day/slovenian_word_of_the_day.json` | A Slovenian word a day, with its English meaning | -### Adding New Categories +`category_order` controls the order categories are shown in. A category listed +in `category_order` but missing from `categories` is skipped, and one present +in `categories` but absent from `category_order` is appended after the +listed ones. -1. Create a JSON data file in the plugin's `of_the_day/` directory - - Path: `plugins/of-the-day/of_the_day/my_custom.json` -2. Add entries for each date in YYYY-MM-DD format -3. Add category to config: +--- + +## The Data File Format + +A data file is a JSON object keyed by **day of the year as a string**, `"1"` +through `"365"`: ```json { - "categories": { - "my_custom_category": { - "enabled": true, - "data_file": "of_the_day/my_custom.json", - "display_name": "My Daily Item" - } + "1": { + "title": "Abstruse", + "subtitle": "Difficult to understand; obscure", + "description": "The philosopher's work was filled with abstruse concepts." }, - "category_order": ["my_custom_category", "word_of_the_day"] + "245": { + "title": "Opportune", + "subtitle": "Well-chosen or particularly favorable or appropriate", + "description": "She waited for an opportune moment to raise the subject." + } } ``` -### Display Behavior +| Field | Shown as | +|-------|----------| +| `title` | The underlined heading | +| `subtitle` | The first body line — a definition or short gloss | +| `description` | The second body line, rotated in after `display_rotate_interval` | + +Selection is by calendar date, not random: day 245 of any year shows entry +`"245"`. That makes the display stable — it will not change halfway through the +day — and means a file needs 365 entries for full coverage. Missing days are +skipped rather than erroring. + +Because it is keyed by day rather than date, the same file works every year. +For a leap year, day 366 has no entry unless you add one. + +> Earlier documentation described these files as keyed by `YYYY-MM-DD`. They are +> not — the bundled files and the loader both use the day-of-year number. A file +> written with date keys will load without error and then show nothing, because +> no key ever matches. + +### Writing your own list + +- **Keep the subtitle short.** It is the line most often shown, and on a 128×32 + panel roughly 24 characters survive before truncation. The description can be + longer since it only needs to fit when it takes its turn. +- **Use the same fields throughout.** An entry missing `subtitle` or + `description` simply shows less; it does not fall back to another field. +- **Cover all 365 days** if you want the category to appear every day. Gaps are + skipped, so a sparse file means the category quietly disappears on the missing + days. +- **Generate rather than type.** The format is a flat JSON object, so a + dictionary API, an RSS feed or a spreadsheet export can all be turned into one + with a short script. Nothing in the plugin cares how the file was produced — + drop the result in via the file manager. + +--- + +## Configuration Reference + +| Option | Type | Default | What it does | +|--------|------|---------|--------------| +| `enabled` | boolean | `false` | Whether the plugin runs at all | +| `categories` | object | *(empty)* | Your categories — see [above](#adding-a-category) | +| `category_order` | array | `["word_of_the_day", "slovenian_word_of_the_day"]` | Display order | +| `display_duration` | number | `40` | Seconds each category holds the panel | +| `display_rotate_interval` | number | `20` | Seconds between body elements within a category | +| `subtitle_rotate_interval` | number | `10` | Seconds between subtitle variants | +| `update_interval` | integer | `3600` | Seconds between checks for a new day | +| `auto_fit_text` | boolean | `true` | Shrink the body font so long text fits | +| `customization` | object | *(defaults)* | Fonts, sizes, colours and offsets | +| `file_manager` | — | — | Not a setting; the data-file widget in the web UI | + +### Rotation and timing + +Three intervals stack, from slowest to fastest: + +- **`display_duration`** (default `40`) — how long the whole category holds the + panel before the display controller moves on. +- **`display_rotate_interval`** (default `20`) — within that turn, how often the + body swaps between the entry's subtitle and description. At the defaults, a + 40-second turn shows each of the two for 20 seconds. +- **`subtitle_rotate_interval`** (default `10`) — how often the subtitle line + itself cycles, for entries carrying more than one. + +If you shorten `display_duration` below `display_rotate_interval`, the second +body element never appears — the turn ends first. + +`update_interval` is only a check for the date rolling over. Since entries +change once a day, the hourly default is already far more often than needed. + +### `auto_fit_text` + +When the body text will not fit at the configured size, this steps the font +down until it does — largest size that fits wins. Only scalable fonts can +shrink; a bitmap font is left alone. Text that still cannot fit at the smallest +size is cut to the lines that fit, with the last one ellipsized. + +![Two 128x64 panels with body font_size 12: with auto-fit the definition +shrinks and fits in three lines, without it the text is cut and ends in an +ellipsis](../../docs/assets/of-the-day/auto-fit.png) + +It has no visible effect when the text already fits, or when the panel has room +for only one body line whatever the size — on a 128×32 panel the result is the +same either way. It earns its keep on taller panels and with larger body fonts. + +### Fonts and colours + +Two elements are styled independently under `customization`: `title_text` and +`body_text`. + +![Four 128x64 panels: the default white-on-grey, an amber scheme, a cyan +scheme, and larger title and body +sizes](../../docs/assets/of-the-day/customization.png) + +| Element | `font` | `font_size` | `text_color` | +|---------|--------|-------------|--------------| +| `title_text` | `PressStart2P-Regular.ttf` | `8` (4–16) | `[255, 255, 255]` | +| `body_text` | `4x6-font.ttf` | `6` (4–12) | `[200, 200, 200]` | + +```json +{ + "customization": { + "title_text": { "text_color": [255, 176, 0], "font_size": 10 }, + "body_text": { "text_color": [200, 130, 0], "font_size": 8 } + } +} +``` -The plugin rotates through: -1. **Category rotation**: Changes every `display_rotate_interval` seconds -2. **Content rotation**: Within each category, alternates between: - - Title/word display with category name - - Definition/content display with word wrapping +> **The key names are `font_size` and `text_color`.** The schema declares these +> elements in an `x-style-elements` block that uses the short names `size` and +> `color`, but that is the *declaration* format — the core expands it into the +> config properties `font`, `font_size` and `text_color`. Writing `size` or +> `color` in your config is silently ignored, with no warning and no visible +> change. It is an easy mistake to make from reading the schema. -### Built-in Categories +Both elements also accept `x_offset` and `y_offset` for nudging position. -**word_of_the_day** -- Displays vocabulary words with definitions -- Shows pronunciation and part of speech -- Great for learning and education +Customization needs a LEDMatrix core with the element-style system. On an older +core the section is not offered and the classic styling above is used, which is +why an untouched config renders identically either way. -**bible_verse_of_the_day** -- Displays daily Bible verses -- Shows reference and translation -- Perfect for inspiration +--- -**slovenian_word_of_the_day** -- Example of foreign language words -- Can be adapted for any language +## Panel Sizes -## Plugin Isolation +![The same word on 64x32, 128x32, 128x64 and 256x32 +panels](../../docs/assets/of-the-day/panel-sizes.png) -This plugin is designed to be completely self-contained: +Height matters far more than width here, because the body wraps: -- ✅ All data files stored in plugin directory -- ✅ No external dependencies on main project structure -- ✅ Can be installed/uninstalled cleanly -- ✅ No traces left after deletion -- ✅ Easy to backup (just copy the plugin folder) -- ✅ Easy to share (distribute the entire plugin directory) +- **64×32** fits the title and a fragment of the definition. +- **128×32** fits the title and one truncated body line. +- **128×64** is where the plugin comes into its own — the definition wraps and + fits in full. +- **256×32** buys a longer single body line, but is still one line. -Data files are automatically loaded from `of_the_day/` subdirectory within the plugin. +If the definitions matter to you, 64 rows is worth more than 256 columns. -## Creating Data Files +--- -### Template Structure +## Troubleshooting -```json -{ - "2025-01-01": { - "word": "Example", - "definition": "A representative form or pattern", - "pronunciation": "ig-ZAM-puhl", - "type": "noun", - "example": "This is an example sentence." - }, - "2025-01-02": { - "word": "Another", - "definition": "One more; an additional", - ... - } -} -``` +**It says "No Data".** +The most likely cause is that no category is configured — the `categories` +block is empty on a fresh install even though the data files ship with the +plugin. Add one from the plugin's tab in the web UI, or by hand as +[shown above](#adding-a-category). -### Tips for Creating Content +**Nothing appears at all.** +`enabled` defaults to `false`. -1. **Date Format**: Always use YYYY-MM-DD -2. **Keep it Short**: Definitions should fit on 4-5 lines -3. **Clear Pronunciation**: Use phonetic spelling -4. **Good Examples**: Make them memorable and relevant -5. **Consistent Structure**: Use same fields across all entries +**A category is configured but never shows.** +Check its own `enabled` flag, that `data_file` resolves relative to the plugin +directory, and that the file has an entry for today's day-of-year number. -## Display Examples +**The definition is cut off.** +That is the panel height. Turn on `auto_fit_text` (it is on by default), reduce +`body_text.font_size`, or use a taller panel — see +[Panel Sizes](#panel-sizes). -### Title Display -``` - Word of the Day - - Ephemeral - - (ih-FEM-er-uhl) -``` +**I changed a colour or size and nothing happened.** +Check the key names: they are `font_size` and `text_color`, not `size` and +`color`. See [Fonts and colours](#fonts-and-colours). -### Content Display -``` -Lasting for a very -short time; transitory -The beauty of cherry -blossoms is ephemeral -``` +**The example sentence never appears.** +`display_duration` is probably shorter than `display_rotate_interval`, so the +turn ends before the body rotates. Raise the former or lower the latter. -## Advanced Usage +**The word did not change at midnight.** +`update_interval` decides how often the date is re-checked; at the default it +can be up to an hour late. -### Multiple Data Sources +--- -You can maintain separate data files for different purposes: -- Educational words -- Technical terms -- Inspirational quotes -- Historical facts -- Daily trivia +## Development -### Automated Updates +### Project structure -Data files can be updated automatically: -- From APIs (Merriam-Webster, etc.) -- From RSS feeds -- From custom scripts -- From database exports +```text +of-the-day/ +├── manifest.json # Plugin metadata and version history +├── manager.py # OfTheDayPlugin +├── config_schema.json # Settings schema; source of truth for defaults +├── of_the_day/ # Bundled data files +│ ├── word_of_the_day.json +│ └── slovenian_word_of_the_day.json +├── scripts/ # Backend actions for the web UI file manager +├── web_ui/ # The file-manager interface +├── test/ # Harness config and golden images +└── README.md +``` -## Troubleshooting +The `scripts/` directory holds the actions the file manager calls — +`list_files`, `get_file`, `save_file`, `create_file`, `delete_file`, +`upload_file`, `toggle_category` and `update_config`. They are invoked by the +web UI rather than run directly. -**No content displayed:** -- Verify data file path is correct -- Check that today's date exists in JSON file -- Ensure category is enabled in config -- Check file permissions +### Tests -**Content cut off:** -- Reduce text length in data file -- Adjust display dimensions -- Shorten definitions or examples +```bash +python plugins/of-the-day/test_text_fitting.py +python plugins/of-the-day/test_element_styles.py +``` -**Category not showing:** -- Verify it's in `category_order` -- Check that `enabled` is `true` -- Ensure data file exists and is valid JSON +### Regenerating the images in this README -**Wrong date content:** -- Check system date/time -- Verify date format in JSON (YYYY-MM-DD) -- Check timezone settings +```bash +python scripts/render_docs_assets.py --plugin of-the-day +``` -## Integration with Education +`--check` verifies the committed images still match what the plugin renders. +The clock is frozen in the shot list, which is what pins the entry to +"Opportune" — without that the images would change daily. -Perfect for: -- Vocabulary building -- Language learning -- Daily inspiration -- Historical facts -- Science concepts -- Programming terms +--- -## License +## Support -GPL-3.0 License - see main LEDMatrix repository for details. +- YouTube: +- Instagram: +- Discord: +- Sponsor: [GitHub Sponsors](https://github.com/sponsors/ChuckBuilds) · + [Buy Me a Coffee](https://buymeacoffee.com/chuckbuilds) · + [Ko-fi](https://ko-fi.com/chuckbuilds/) +Released under the GNU General Public License v3.0 — see [LICENSE](LICENSE). diff --git a/plugins/of-the-day/manifest.json b/plugins/of-the-day/manifest.json index 61c589a4..c8fcf6c4 100644 --- a/plugins/of-the-day/manifest.json +++ b/plugins/of-the-day/manifest.json @@ -1,7 +1,7 @@ { "id": "of-the-day", "name": "Of The Day Display", - "version": "1.4.1", + "version": "1.4.2", "author": "ChuckBuilds", "description": "Display daily featured content like Word of the Day, Bible verses, or custom daily items. Supports multiple categories with rotating display and configurable data sources.", "category": "information", @@ -21,6 +21,13 @@ "of_the_day" ], "versions": [ + { + "version": "1.4.2", + "released": "2026-09-02", + "ledmatrix_min_version": "2.0.0", + "notes": "Documentation only, no behaviour change. Rewrites the README around real rendered screenshots and documents all 13 settings. Leads with the reason a fresh install shows 'No Data': the categories block is empty by default, so the bundled data files exist but nothing points at them until a category is added. Corrects the data-file format, which the old README described as keyed by YYYY-MM-DD -- the files and the loader both use the day-of-year number, so a file written with date keys loads cleanly and then shows nothing. Documents that the customization keys are font_size and text_color, not the size and color used by the schema's x-style-elements declaration; the short names are silently ignored. Also separates the three rotation intervals and notes that auto_fit_text only has a visible effect where shrinking can gain a line.", + "changelog": "Documentation only, no behaviour change. Rewrites the README around real rendered screenshots and documents all 13 settings. Leads with the reason a fresh install shows 'No Data': the categories block is empty by default, so the bundled data files exist but nothing points at them until a category is added. Corrects the data-file format, which the old README described as keyed by YYYY-MM-DD -- the files and the loader both use the day-of-year number, so a file written with date keys loads cleanly and then shows nothing. Documents that the customization keys are font_size and text_color, not the size and color used by the schema's x-style-elements declaration; the short names are silently ignored. Also separates the three rotation intervals and notes that auto_fit_text only has a visible effect where shrinking can gain a line." + }, { "version": "1.4.1", "released": "2026-08-06", @@ -66,7 +73,7 @@ "ledmatrix_min": "2.0.0" } ], - "last_updated": "2026-08-06", + "last_updated": "2026-09-02", "stars": 0, "downloads": 0, "verified": true,