diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..a1479b3 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,72 @@ +--- +name: Plugin bug report +about: Report a bug in one of the official plugins +title: '[] ' +labels: bug +assignees: '' + +--- + + + +## Plugin + +- **Plugin id**: +- **Plugin version** (from `manifest.json`): +- **Installed via**: + +## Describe the bug + + + +## Steps to reproduce + +1. +2. +3. + +## Expected behavior + + + +## Actual behavior + + + +## Plugin configuration + + + +```json +"": { + ... +} +``` + +## Logs + + + +``` +``` + +## Hardware + +- **Raspberry Pi model**: +- **LEDMatrix version**: +- **Display panels**: + +## Additional context + + diff --git a/.github/ISSUE_TEMPLATE/plugin_request.md b/.github/ISSUE_TEMPLATE/plugin_request.md new file mode 100644 index 0000000..bb5dddf --- /dev/null +++ b/.github/ISSUE_TEMPLATE/plugin_request.md @@ -0,0 +1,56 @@ +--- +name: Plugin request +about: Suggest a new plugin or a feature for an existing one +title: '[Plugin request] ' +labels: enhancement +assignees: '' + +--- + + + +## Is this a new plugin or a feature for an existing plugin? + +- [ ] Brand-new plugin +- [ ] Feature for an existing plugin: + +## What does it display? + + + +## Data source + + + +- **Source**: +- **API key required?**: +- **Rate limits**: + +## Display modes + + + +## Why is this useful? + + + +## Are you offering to build it? + +- [ ] Yes — see [SUBMISSION.md](../SUBMISSION.md) for the contributor flow +- [ ] No, just a suggestion +- [ ] Maybe, with some help + +## Similar plugins + + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..eddfc65 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,81 @@ +# Pull Request + +## Summary + + + +## Type of change + + + +- [ ] Bug fix in an existing plugin +- [ ] New plugin (also fill out the SUBMISSION.md checklist below) +- [ ] New feature for an existing plugin +- [ ] Documentation only +- [ ] Repo-wide change (registry script, hook, top-level docs) + +## Plugin(s) affected + + + +## Related issues + + + +## Test plan + + + +- [ ] Loaded the plugin in LEDMatrix on real hardware +- [ ] Loaded the plugin in LEDMatrix emulator mode + (`EMULATOR=true python3 run.py`) +- [ ] Rendered the plugin in the dev preview server + (`scripts/dev_server.py`) +- [ ] Verified the web UI configuration form against the schema +- [ ] N/A — repo-wide / docs-only change + +## Required for plugin changes + +- [ ] **Bumped `version` in `plugins//manifest.json`** + (the Plugin Store uses version comparison to ship updates — + forgetting this means users won't receive the change) +- [ ] `class_name` in `manifest.json` matches the actual class in + `manager.py` exactly (case-sensitive, no spaces) +- [ ] `entry_point` matches the real file (or is omitted to use + the `manager.py` default) +- [ ] Updated the plugin's `README.md` if config keys changed +- [ ] `config_schema.json` is the source of truth for the web UI + form — any new option is in the schema with a `default`, + `description`, and constraints +- [ ] Pre-commit hook ran successfully (auto-syncs `plugins.json`) + +## SUBMISSION checklist (new plugins only) + + + +- [ ] Plugin id matches the directory name and is unique +- [ ] `manifest.json` has all required fields (`id`, `name`, + `version`, `class_name`, `display_modes`) +- [ ] `manager.py` inherits from `BasePlugin` and implements + `update()` and `display()` +- [ ] `config_schema.json` exists and validates as JSON Schema Draft-7 +- [ ] `requirements.txt` lists all Python dependencies +- [ ] `README.md` documents what the plugin does, how to install, + and the configuration options +- [ ] `LICENSE` is GPL-3.0 (or compatible) +- [ ] No hardcoded API keys or secrets — secrets go in + `config/config_secrets.json` under the plugin id +- [ ] Tested on a real LEDMatrix setup (or in the emulator) + +## Checklist + +- [ ] My commits follow the message convention in `CONTRIBUTING.md` +- [ ] I read `CONTRIBUTING.md` and `CODE_OF_CONDUCT.md` +- [ ] I've not committed any secrets + +## Notes for reviewer + + diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..a1594b7 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,137 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official email address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +This includes the LEDMatrix Discord server, GitHub repositories owned by +ChuckBuilds, and any other forums hosted by or affiliated with the project. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement on the +[LEDMatrix Discord](https://discord.gg/uW36dVAtcT) (DM a moderator or +ChuckBuilds directly) or by opening a private GitHub Security Advisory if +the issue involves account safety. All complaints will be reviewed and +investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][FAQ]. Translations are available +at [https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..a443458 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,145 @@ +# Contributing to ledmatrix-plugins + +This is the official plugin monorepo for +[LEDMatrix](https://github.com/ChuckBuilds/LEDMatrix). Contributions are +welcome — bug reports, plugin updates, brand-new plugins, and +documentation fixes all help. + +## Quick links + +- **Plugin submission flow**: see [SUBMISSION.md](SUBMISSION.md) +- **Plugin verification checklist**: see [VERIFICATION.md](VERIFICATION.md) +- **Real-time discussion**: the + [LEDMatrix Discord](https://discord.gg/uW36dVAtcT) +- **Bugs / feature requests**: + [open an issue](https://github.com/ChuckBuilds/ledmatrix-plugins/issues) +- **Security issues**: see [SECURITY.md](SECURITY.md). Don't open + public issues for vulnerabilities. + +## Repository layout + +```text +ledmatrix-plugins/ +├── plugins/ +│ └── / +│ ├── manifest.json # Plugin metadata, entry point, class name +│ ├── manager.py # Plugin class (inherits from BasePlugin) +│ ├── config_schema.json # JSON Schema for the web UI form +│ ├── requirements.txt # Python deps +│ ├── README.md # User-facing docs +│ └── LICENSE # Per-plugin license (usually GPL-3.0) +├── plugins.json # Auto-generated registry consumed by the Plugin Store +├── update_registry.py # Syncs plugins.json from manifests +├── scripts/ +│ └── pre-commit # Git hook that auto-runs update_registry.py +└── docs/ # Plugin Store and contributor docs +``` + +## Setting up a development environment + +You'll typically work on a plugin alongside the main LEDMatrix repo: + +```bash +# Clone both repos +git clone https://github.com/ChuckBuilds/LEDMatrix.git +git clone https://github.com/ChuckBuilds/ledmatrix-plugins.git + +# Symlink the plugin you want to work on into LEDMatrix's +# plugin loader path. Default plugin location in LEDMatrix is +# plugin-repos/ (or plugins/ as a fallback for the dev workflow). +cd LEDMatrix +ln -s ../ledmatrix-plugins/plugins/ plugin-repos/ + +# Test without hardware +python3 scripts/dev_server.py # then open http://localhost:5001 +# Or test the plugin in the full emulator path +EMULATOR=true python3 run.py +``` + +For a more managed dev setup, LEDMatrix ships +`scripts/dev/dev_plugin_setup.sh` which automates the symlink + clone +flow. See LEDMatrix's +[`docs/PLUGIN_DEVELOPMENT_GUIDE.md`](https://github.com/ChuckBuilds/LEDMatrix/blob/main/docs/PLUGIN_DEVELOPMENT_GUIDE.md). + +## Working on an existing plugin + +1. **Open an issue first** if the change is non-trivial. This avoids + wasted work on PRs that don't fit the project direction. +2. **Branch off `main`**: `fix/-` or + `feat/-`. +3. **Make your changes** in `plugins//`. +4. **Bump the version in `manifest.json`.** This is critical — the + Plugin Store uses version comparison (manifest version vs + `plugins.json` `latest_version`) to decide whether to ship updates + to users. If you forget, users won't receive your fix. + - **Patch** (1.0.0 → 1.0.1): bug fixes, doc tweaks + - **Minor** (1.0.0 → 1.1.0): new features, schema additions + - **Major** (1.0.0 → 2.0.0): breaking config changes +5. **Update the plugin's README** if you added/changed config keys. + The web UI form is generated from `config_schema.json`, so the + schema is the source of truth — README tables should match. +6. **Commit.** The pre-commit hook automatically runs + `update_registry.py` and stages `plugins.json`. If the hook isn't + installed, run `cp scripts/pre-commit .git/hooks/pre-commit`. +7. **Open a PR** using the template in + `.github/PULL_REQUEST_TEMPLATE.md`. + +## Adding a new plugin + +See [SUBMISSION.md](SUBMISSION.md) for the full submission flow. The +short version: + +1. Copy the + [`plugins/hello-world/`](plugins/hello-world/) directory as a + starting template — it's intentionally tiny and well-commented. +2. Rename the directory to your plugin id (lowercase, hyphens, e.g. + `my-cool-plugin`). +3. Update `manifest.json`: + - `id` must match the directory name + - `class_name` must match the actual class name in `manager.py` + **exactly** (case-sensitive, no spaces — see + [VERIFICATION.md](VERIFICATION.md) for why this matters) + - Set `entry_point` (defaults to `manager.py` if omitted) + - Set `version`, `author`, `category`, `tags`, `display_modes` +4. Implement `update()` and `display()` in your plugin class. +5. Define the configuration schema in `config_schema.json`. The web + UI form is generated automatically from this — every key you want + users to be able to configure should be here with `default`, + `description`, and constraints. +6. Write a `README.md` covering: what the plugin does, install, + configuration, and any external service / API key requirements. +7. Add a `LICENSE` (usually a copy of the project GPL-3.0). +8. Test locally via the symlink + dev_server flow above. +9. Open a PR. + +## Commit message convention + +Conventional Commits is encouraged but not strictly enforced: + +- `feat(hockey-scoreboard): add power-play indicator` +- `fix(stocks): handle empty Yahoo Finance response` +- `docs(weather): document the radar zoom config key` +- `chore: bump masters-tournament to 2.0.1` + +Plugin-scoped prefixes help when you need to find the history of a +specific plugin later. + +## Testing + +Per-plugin tests live in the LEDMatrix repo at `test/plugins/`. If +you're adding a test for your plugin, open a corresponding PR in +LEDMatrix. The dev preview server (`scripts/dev_server.py` in +LEDMatrix) is the fastest way to iterate visually. + +## Code of Conduct + +This project follows the [Contributor Covenant](CODE_OF_CONDUCT.md). +By participating you agree to abide by its terms. + +## License + +ledmatrix-plugins is licensed under [GPL-3.0](LICENSE). By +submitting a contribution you agree to license it under the same terms +(the standard "inbound = outbound" rule that GitHub applies by +default). Individual plugins may ship their own `LICENSE` file but +should remain GPL-3.0 compatible. diff --git a/README.md b/README.md index fb4bb1a..26c7df5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LEDMatrix Official Plugins -[![Plugins](https://img.shields.io/badge/plugins-27-blue)](./plugins.json) +[![Plugins](https://img.shields.io/badge/plugins-30-blue)](./plugins.json) [![License](https://img.shields.io/badge/license-GPL--3.0-green)](LICENSE) [![Discord](https://img.shields.io/badge/Discord-community-5865F2?logo=discord&logoColor=white)](https://discord.gg/uW36dVAtcT) [![GitHub Stars](https://img.shields.io/github/stars/ChuckBuilds/ledmatrix-plugins?style=flat&color=yellow)](https://github.com/ChuckBuilds/ledmatrix-plugins) @@ -64,12 +64,13 @@ **Web Interface (Recommended):** 1. Open `http://your-pi-ip:5000` -2. Go to **Plugin Store** tab -3. Browse & click **Install** +2. Open the **Plugin Manager** tab +3. Find the plugin you want in the **Plugin Store** section and click + **Install** **API:** ```bash -curl -X POST http://your-pi-ip:5050/api/plugins/install \ +curl -X POST http://your-pi-ip:5000/api/v3/plugins/install \ -H "Content-Type: application/json" \ -d '{"plugin_id": "football-scoreboard"}' ``` @@ -78,7 +79,7 @@ curl -X POST http://your-pi-ip:5050/api/plugins/install \ ## Available Plugins -### Sports (9) +### Sports (12) | Plugin | Description | |--------|-------------| @@ -87,7 +88,10 @@ curl -X POST http://your-pi-ip:5050/api/plugins/install \ | [Basketball Scoreboard](./plugins/basketball-scoreboard/) | NBA, NCAA & WNBA live scores and schedules | | [Baseball Scoreboard](./plugins/baseball-scoreboard/) | MLB, MiLB & NCAA Baseball live scores | | [Soccer Scoreboard](./plugins/soccer-scoreboard/) | Premier League, La Liga, Bundesliga, Serie A, Ligue 1, MLS | +| [Lacrosse Scoreboard](./plugins/lacrosse-scoreboard/) | NCAA lacrosse live scores and schedules | +| [F1 Scoreboard](./plugins/f1-scoreboard/) | Formula 1 race results, schedules, and standings | | [UFC Scoreboard](./plugins/ufc-scoreboard/) | UFC/MMA live fights, fighter headshots, records, odds & results — *by [LegoGuy1000](https://github.com/legoguy1000)* | +| [Masters Tournament](./plugins/masters-tournament/) | Live Masters golf leaderboard, hole tracking, player cards | | [Odds Ticker](./plugins/odds-ticker/) | Betting odds & lines across NFL, NBA, MLB, NCAA | | [Sports Leaderboard](./plugins/ledmatrix-leaderboard/) | League standings, rankings, conference records | | [Olympics Countdown](./plugins/olympics/) | Countdown to next Olympics with live medal counts | @@ -196,14 +200,20 @@ The **Plugin Store** in the LEDMatrix web interface automatically fetches the la ### Manual Installation -Clone this repository and copy the plugin you want: +Clone this repository and copy the plugin you want into your LEDMatrix +installation's configured plugins directory (default `plugin-repos/`): ```bash git clone https://github.com/ChuckBuilds/ledmatrix-plugins.git cp -r ledmatrix-plugins/plugins/football-scoreboard /path/to/LEDMatrix/plugin-repos/ ``` -> **Note:** See individual plugin README files for detailed setup instructions and configuration. +The directory name on the destination must match the plugin's `id` in +its `manifest.json`. Restart the LEDMatrix display service afterward +so the loader picks up the new plugin. + +> **Note:** See individual plugin README files for detailed setup +> instructions and configuration. --- @@ -308,7 +318,12 @@ See the [manifest schema](https://github.com/ChuckBuilds/LEDMatrix/blob/main/sch 1. Review the [Plugin Development Guide](https://github.com/ChuckBuilds/LEDMatrix/blob/main/docs/PLUGIN_DEVELOPMENT_GUIDE.md) 2. Start with the [Hello World plugin](./plugins/hello-world/) as a template -3. Test with the emulator: `python run.py --emulator` +3. Test without hardware: run the LEDMatrix dev preview server + (`python3 scripts/dev_server.py` from the LEDMatrix repo, then open + `http://localhost:5001`) — see + [`docs/DEV_PREVIEW.md`](https://github.com/ChuckBuilds/LEDMatrix/blob/main/docs/DEV_PREVIEW.md). + Or run the full display in emulator mode with + `EMULATOR=true python3 run.py`. ### Submitting a Plugin @@ -332,6 +347,11 @@ GNU General Public License v3.0 — see [LICENSE](LICENSE) for details. - **Discord**: [Join the community](https://discord.gg/uW36dVAtcT) - **Issues**: [Report plugin issues](https://github.com/ChuckBuilds/ledmatrix-plugins/issues) +- **Security**: see [SECURITY.md](SECURITY.md) — please don't open + public issues for vulnerabilities +- **Contributing**: see [CONTRIBUTING.md](CONTRIBUTING.md) for the dev + setup and PR flow, or [SUBMISSION.md](SUBMISSION.md) for adding a + brand-new plugin - **LEDMatrix**: [Main repository](https://github.com/ChuckBuilds/LEDMatrix) ### Connect with ChuckBuilds diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..d833bdb --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,85 @@ +# Security Policy + +This file applies to **plugin code** in the `ledmatrix-plugins` +repository. For vulnerabilities in the LEDMatrix core (display +controller, plugin loader, web interface), see the +[LEDMatrix SECURITY.md](https://github.com/ChuckBuilds/LEDMatrix/blob/main/SECURITY.md). + +## Reporting a vulnerability + +If you've found a security issue in one of the official plugins, +**please don't open a public GitHub issue**. Disclose it privately so +we can fix it before it's exploited. + +### How to report + +Use one of these channels, in order of preference: + +1. **GitHub Security Advisories** (preferred) on this repo: + +2. **Discord DM** to a moderator on the + [LEDMatrix Discord](https://discord.gg/uW36dVAtcT). Don't post in + public channels. + +Please include: + +- Which plugin is affected (id and version) +- A description of the issue +- Steps to reproduce, ideally a minimal proof of concept +- The impact you can demonstrate +- Any suggested mitigation + +### What to expect + +- An acknowledgement within a few days (this is a hobby project, not + a 24/7 ops team). +- A discussion of the issue's severity and a plan for the fix. +- Once fixed, the affected plugin's `manifest.json` version is + bumped, the change is committed, and the Plugin Store delivers the + update to users on their next refresh. +- Credit in the plugin's CHANGELOG when the fix ships, unless you'd + prefer to remain anonymous. + +## Scope + +In scope for this policy: + +- Code in `plugins//` for plugins maintained in this repo +- The `update_registry.py` script and the `plugins.json` registry +- The pre-commit hook in `scripts/pre-commit` + +Out of scope (please report to the appropriate upstream): + +- Vulnerabilities in the LEDMatrix core → + [LEDMatrix repo](https://github.com/ChuckBuilds/LEDMatrix) +- Vulnerabilities in third-party plugins not maintained here → + the plugin's own repository +- Vulnerabilities in Python packages a plugin depends on → the + upstream package maintainer (e.g., `paho-mqtt`, `requests`, etc.) + +## Plugin security model + +Plugins shipped from this repo run inside the LEDMatrix display +service process with full file-system and network access. There is +no sandboxing. The same warning the LEDMatrix `SECURITY.md` makes +applies to every plugin here: + +- **Any plugin can read and write any file the LEDMatrix process + can reach**, including `config_secrets.json`. +- **Arbitrary outbound network requests are possible from any + loaded plugin.** +- **Because plugins run in the same Python process as the display + loop**, a crash in one plugin can take down the whole display. + +The official plugins in this repo go through a manual review (see +[VERIFICATION.md](VERIFICATION.md)) before being added to the +`plugins.json` registry. Third-party plugins installed via "Install +from GitHub" in the LEDMatrix web UI do **not** go through this +review and are flagged as **Custom** in the Plugin Store. + +## Supported versions + +Each plugin is independently versioned in its `manifest.json`. There +is no LTS branch — security fixes land on `main`, the version is +bumped, and users receive the update through the Plugin Store on +their next refresh. Older versions are not patched. diff --git a/SUBMISSION.md b/SUBMISSION.md index eac970e..409f8b4 100644 --- a/SUBMISSION.md +++ b/SUBMISSION.md @@ -47,7 +47,8 @@ If you prefer to maintain your own repo: 1. **Test Your Plugin** ```bash # Install via URL on your Pi - curl -X POST http://your-pi:5050/api/plugins/install-from-url \ + curl -X POST http://your-pi:5000/api/plugins/install-from-url \ + -H "Content-Type: application/json" \ -d '{"repo_url": "https://github.com/you/ledmatrix-your-plugin"}' ``` diff --git a/VERIFICATION.md b/VERIFICATION.md index b6bff4a..8ae6460 100644 --- a/VERIFICATION.md +++ b/VERIFICATION.md @@ -14,11 +14,42 @@ Use this checklist when reviewing plugin submissions. ## Manifest Validation -- [ ] All required fields present +- [ ] All required fields present (`id`, `name`, `version`, `class_name`, + `display_modes`) +- [ ] `class_name` matches the actual class name in the entry point + (case-sensitive, no spaces) — the loader does + `getattr(module, class_name)` and will fail with `AttributeError` + otherwise +- [ ] `entry_point` either matches the real file name or is omitted + (defaults to `manager.py`) +- [ ] `id` matches the directory name - [ ] Valid JSON syntax - [ ] Correct version format (semver) +- [ ] `version` field matches the latest entry in the `versions[]` array +- [ ] `last_updated` matches the release date of the latest version - [ ] Category is valid - [ ] Tags are descriptive +- [ ] **`display_modes` don't collide with any existing plugin's modes.** + The display controller stores modes in a flat dict keyed by mode + name (`src/display_controller.py:295`); a collision means + whichever plugin loads second silently overrides the first. + Quick check: + ```bash + python3 -c " + import json, os + modes = {} + for d in sorted(os.listdir('plugins')): + p = f'plugins/{d}/manifest.json' + if not os.path.isfile(p): continue + for mode in json.load(open(p)).get('display_modes', []): + modes.setdefault(mode, []).append(d) + for mode, pids in modes.items(): + if len(pids) > 1: print(f'COLLISION: {mode} → {pids}') + " + ``` + Prefix new plugins' modes with the plugin id or sport (e.g. + `lax_ncaa_mens_recent` rather than `ncaa_mens_recent`) to avoid + colliding with future plugins. ## Functionality @@ -36,6 +67,17 @@ Use this checklist when reviewing plugin submissions. - [ ] Configuration options documented - [ ] Examples provided - [ ] License specified +- [ ] **Per-plugin `LICENSE` file exists** in `plugins//`. + Every plugin must ship its own LICENSE (typically a short-form + GPL-3.0 notice — see `plugins/hello-world/LICENSE` as the + template). Without it, downstream users have no per-plugin + license declaration when they install via the Plugin Store. + Quick check: + ```bash + for d in plugins/*/; do + ls "$d"LICENSE >/dev/null 2>&1 || echo "MISSING: $d" + done + ``` ## Security diff --git a/docs/PLUGIN_STORE_IMPLEMENTATION_SUMMARY.md b/docs/PLUGIN_STORE_IMPLEMENTATION_SUMMARY.md index 176e4c0..bd7c16b 100644 --- a/docs/PLUGIN_STORE_IMPLEMENTATION_SUMMARY.md +++ b/docs/PLUGIN_STORE_IMPLEMENTATION_SUMMARY.md @@ -47,15 +47,15 @@ Updated and enhanced existing endpoints: | Endpoint | Method | Purpose | |----------|--------|---------| -| `/api/plugins/store/list` | GET | List all plugins in registry | -| `/api/plugins/store/search` | GET | Search plugins with filters | -| `/api/plugins/installed` | GET | List installed plugins | -| `/api/plugins/install` | POST | Install from registry | -| `/api/plugins/install-from-url` | POST | **Install from GitHub URL** | -| `/api/plugins/uninstall` | POST | Remove plugin | -| `/api/plugins/update` | POST | Update to latest version | -| `/api/plugins/toggle` | POST | Enable/disable plugin | -| `/api/plugins/config` | POST | Update plugin config | +| `/api/v3/plugins/store/list` | GET | List all plugins in registry | +| `/api/v3/plugins/store/search` | GET | Search plugins with filters | +| `/api/v3/plugins/installed` | GET | List installed plugins | +| `/api/v3/plugins/install` | POST | Install from registry | +| `/api/v3/plugins/install-from-url` | POST | **Install from GitHub URL** | +| `/api/v3/plugins/uninstall` | POST | Remove plugin | +| `/api/v3/plugins/update` | POST | Update to latest version | +| `/api/v3/plugins/toggle` | POST | Enable/disable plugin | +| `/api/v3/plugins/config` | POST | Update plugin config | ### 3. Testing & Documentation @@ -90,7 +90,7 @@ This is the **key feature** that enables community participation: 3. **Or via API:** ```bash - curl -X POST http://your-pi-ip:5050/api/plugins/install-from-url \ + curl -X POST http://your-pi-ip:5000/api/v3/plugins/install-from-url \ -H "Content-Type: application/json" \ -d '{"repo_url": "https://github.com/developer/ledmatrix-awesome-display"}' ``` @@ -149,12 +149,12 @@ This is the **key feature** that enables community participation: # 1. Develop plugin locally # 2. Push to GitHub # 3. Test on Pi via URL install -curl -X POST http://pi:5050/api/plugins/install-from-url \ +curl -X POST http://pi:5000/api/v3/plugins/install-from-url \ -d '{"repo_url": "https://github.com/me/my-plugin"}' # 4. Make changes, push # 5. Update on Pi -curl -X POST http://pi:5050/api/plugins/update \ +curl -X POST http://pi:5000/api/v3/plugins/update \ -d '{"plugin_id": "my-plugin"}' ``` @@ -261,13 +261,13 @@ python3 test/test_install_from_url.py python3 web_interface_v2.py # 2. Test API endpoints -curl http://localhost:5050/api/plugins/store/list -curl http://localhost:5050/api/plugins/store/search?q=clock -curl http://localhost:5050/api/plugins/installed +curl http://localhost:5000/api/v3/plugins/store/list +curl http://localhost:5000/api/v3/plugins/store/search?q=clock +curl http://localhost:5000/api/v3/plugins/installed # 3. Test installation (with existing hello-world plugin) # First, push hello-world to a test GitHub repo, then: -curl -X POST http://localhost:5050/api/plugins/install-from-url \ +curl -X POST http://localhost:5000/api/v3/plugins/install-from-url \ -H "Content-Type: application/json" \ -d '{"repo_url": "https://github.com/your-test-repo/ledmatrix-hello-world"}' ``` diff --git a/docs/PLUGIN_STORE_QUICK_REFERENCE.md b/docs/PLUGIN_STORE_QUICK_REFERENCE.md index a48ecdb..6918208 100644 --- a/docs/PLUGIN_STORE_QUICK_REFERENCE.md +++ b/docs/PLUGIN_STORE_QUICK_REFERENCE.md @@ -4,17 +4,17 @@ ### Install Plugin from Store ```bash -# Web UI: Plugin Store → Search → Click Install +# Web UI: Plugin Manager tab → Plugin Store section → Search → Click Install # API: -curl -X POST http://pi:5050/api/plugins/install \ +curl -X POST http://pi:5000/api/plugins/install \ -d '{"plugin_id": "clock-simple"}' ``` ### Install Plugin from GitHub URL ⭐ ```bash -# Web UI: Plugin Store → "Install from URL" → Paste URL +# Web UI: Plugin Manager tab → "Install from GitHub" section → Paste URL # API: -curl -X POST http://pi:5050/api/plugins/install-from-url \ +curl -X POST http://pi:5000/api/plugins/install-from-url \ -d '{"repo_url": "https://github.com/user/ledmatrix-plugin"}' ``` @@ -22,29 +22,29 @@ curl -X POST http://pi:5050/api/plugins/install-from-url \ ```bash # Web UI: Use search bar and filters # API: -curl "http://pi:5050/api/plugins/store/search?q=hockey&category=sports" +curl "http://pi:5000/api/plugins/store/search?q=hockey&category=sports" ``` ### List Installed ```bash -curl "http://pi:5050/api/plugins/installed" +curl "http://pi:5000/api/plugins/installed" ``` ### Enable/Disable ```bash -curl -X POST http://pi:5050/api/plugins/toggle \ +curl -X POST http://pi:5000/api/plugins/toggle \ -d '{"plugin_id": "clock-simple", "enabled": true}' ``` ### Update Plugin ```bash -curl -X POST http://pi:5050/api/plugins/update \ +curl -X POST http://pi:5000/api/plugins/update \ -d '{"plugin_id": "clock-simple"}' ``` ### Uninstall ```bash -curl -X POST http://pi:5050/api/plugins/uninstall \ +curl -X POST http://pi:5000/api/plugins/uninstall \ -d '{"plugin_id": "clock-simple"}' ``` diff --git a/docs/PLUGIN_STORE_USER_GUIDE.md b/docs/PLUGIN_STORE_USER_GUIDE.md index d77fd35..d0a402f 100644 --- a/docs/PLUGIN_STORE_USER_GUIDE.md +++ b/docs/PLUGIN_STORE_USER_GUIDE.md @@ -11,16 +11,17 @@ The LEDMatrix Plugin Store allows you to easily discover, install, and manage di The official plugin store contains curated, verified plugins that have been reviewed by maintainers. **Via Web UI:** -1. Open the web interface (http://your-pi-ip:5050) -2. Navigate to "Plugin Store" tab -3. Browse or search for plugins -4. Click "Install" on the plugin you want +1. Open the web interface (`http://your-pi-ip:5000`) +2. Open the **Plugin Manager** tab +3. Scroll to the **Plugin Store** section and browse or search +4. Click **Install** on the plugin you want 5. Wait for installation to complete -6. Restart the display to activate the plugin +6. Toggle the plugin on, then click **Restart Display Service** on the + **Overview** tab **Via API:** ```bash -curl -X POST http://your-pi-ip:5050/api/plugins/install \ +curl -X POST http://your-pi-ip:5000/api/plugins/install \ -H "Content-Type: application/json" \ -d '{"plugin_id": "clock-simple", "version": "latest"}' ``` @@ -45,18 +46,20 @@ Install any plugin directly from a GitHub repository, even if it's not in the of **Via Web UI:** 1. Open the web interface -2. Navigate to "Plugin Store" tab -3. Find the "Install from URL" section at the bottom -4. Paste the GitHub repository URL (e.g., `https://github.com/user/ledmatrix-my-plugin`) -5. Click "Install from URL" +2. Open the **Plugin Manager** tab +3. Scroll to the **Install from GitHub** section +4. Paste the GitHub repository URL (e.g., + `https://github.com/user/ledmatrix-my-plugin`) +5. Click **Install Single Plugin** (or **Load Registry** if it's a + monorepo of multiple plugins) 6. Review the warning about unverified plugins 7. Confirm installation 8. Wait for installation to complete -9. Restart the display +9. Restart the display service from the **Overview** tab **Via API:** ```bash -curl -X POST http://your-pi-ip:5050/api/plugins/install-from-url \ +curl -X POST http://your-pi-ip:5000/api/plugins/install-from-url \ -H "Content-Type: application/json" \ -d '{"repo_url": "https://github.com/user/ledmatrix-my-plugin"}' ``` @@ -84,13 +87,13 @@ else: **Via API:** ```bash # Search by query -curl "http://your-pi-ip:5050/api/plugins/store/search?q=hockey" +curl "http://your-pi-ip:5000/api/plugins/store/search?q=hockey" # Filter by category -curl "http://your-pi-ip:5050/api/plugins/store/search?category=sports" +curl "http://your-pi-ip:5000/api/plugins/store/search?category=sports" # Filter by tags -curl "http://your-pi-ip:5050/api/plugins/store/search?tags=nhl&tags=hockey" +curl "http://your-pi-ip:5000/api/plugins/store/search?tags=nhl&tags=hockey" ``` **Via Python:** @@ -119,7 +122,7 @@ results = store.search_plugins(tags=["nhl", "hockey"]) **Via API:** ```bash -curl "http://your-pi-ip:5050/api/plugins/installed" +curl "http://your-pi-ip:5000/api/plugins/installed" ``` **Via Python:** @@ -143,7 +146,7 @@ for plugin_id in installed: **Via API:** ```bash -curl -X POST http://your-pi-ip:5050/api/plugins/toggle \ +curl -X POST http://your-pi-ip:5000/api/plugins/toggle \ -H "Content-Type: application/json" \ -d '{"plugin_id": "clock-simple", "enabled": true}' ``` @@ -158,7 +161,7 @@ curl -X POST http://your-pi-ip:5050/api/plugins/toggle \ **Via API:** ```bash -curl -X POST http://your-pi-ip:5050/api/plugins/update \ +curl -X POST http://your-pi-ip:5000/api/plugins/update \ -H "Content-Type: application/json" \ -d '{"plugin_id": "clock-simple"}' ``` @@ -181,7 +184,7 @@ success = store.update_plugin('clock-simple') **Via API:** ```bash -curl -X POST http://your-pi-ip:5050/api/plugins/uninstall \ +curl -X POST http://your-pi-ip:5000/api/plugins/uninstall \ -H "Content-Type: application/json" \ -d '{"plugin_id": "clock-simple"}' ``` @@ -363,7 +366,7 @@ All API endpoints return JSON with this structure: ```bash # Install -curl -X POST http://192.168.1.100:5050/api/plugins/install \ +curl -X POST http://192.168.1.100:5000/api/plugins/install \ -H "Content-Type: application/json" \ -d '{"plugin_id": "clock-simple"}' @@ -386,12 +389,12 @@ sudo systemctl restart ledmatrix ```bash # Install your own plugin during development -curl -X POST http://192.168.1.100:5050/api/plugins/install-from-url \ +curl -X POST http://192.168.1.100:5000/api/plugins/install-from-url \ -H "Content-Type: application/json" \ -d '{"repo_url": "https://github.com/myusername/ledmatrix-my-custom-plugin"}' # Enable it -curl -X POST http://192.168.1.100:5050/api/plugins/toggle \ +curl -X POST http://192.168.1.100:5000/api/plugins/toggle \ -H "Content-Type: application/json" \ -d '{"plugin_id": "my-custom-plugin", "enabled": true}' @@ -409,10 +412,10 @@ https://github.com/yourusername/ledmatrix-awesome-plugin # Users install with: 1. Go to LEDMatrix web interface -2. Click "Plugin Store" tab -3. Scroll to "Install from URL" +2. Click "Plugin Manager" tab +3. Scroll to "Install from GitHub" 4. Paste: https://github.com/yourusername/ledmatrix-awesome-plugin -5. Click "Install from URL" +5. Click "Install from GitHub" ``` ## FAQ diff --git a/plugins.json b/plugins.json index 3f8d476..af9c6a7 100644 --- a/plugins.json +++ b/plugins.json @@ -1,12 +1,12 @@ { "version": "1.0.0", - "last_updated": "2026-04-06", + "last_updated": "2026-04-07", "plugins": [ { "id": "hello-world", "name": "Hello World", "description": "A simple test plugin that displays a customizable message", - "author": "LEDMatrix Team", + "author": "ChuckBuilds", "category": "demo", "tags": [ "demo", @@ -47,14 +47,19 @@ { "id": "weather", "name": "Weather Display", - "description": "Comprehensive weather display with current conditions, hourly forecast, daily forecast, UV index, wind direction, and weather icons. Features state caching, API counter tracking, and error handling. Powered by OpenWeatherMap API with beautiful weather icons.", + "description": "Comprehensive weather display with current conditions, hourly forecast, daily forecast, almanac (sunrise/sunset, moon phase), precipitation radar, weather alerts, UV index, wind direction, and weather icons. Powered by OpenWeatherMap + RainViewer APIs.", "author": "ChuckBuilds", "category": "weather", "tags": [ "weather", "forecast", "temperature", - "humidity" + "conditions", + "openweathermap", + "uv-index", + "wind", + "icons", + "caching" ], "repo": "https://github.com/ChuckBuilds/ledmatrix-plugins", "branch": "main", @@ -71,11 +76,12 @@ "name": "Static Image Display", "description": "Display static images on your LED matrix with automatic scaling, aspect ratio preservation, and transparency support. Perfect for logos, artwork, or custom graphics.", "author": "ChuckBuilds", - "category": "media", + "category": "display", "tags": [ "image", "static", "display", + "graphics", "logo" ], "repo": "https://github.com/ChuckBuilds/ledmatrix-plugins", @@ -90,14 +96,15 @@ }, { "id": "text-display", - "name": "Scrolling Text Display", + "name": "Text Display", "description": "Display custom scrolling or static text with configurable fonts, colors, and scroll speed. Perfect for announcements, messages, or custom displays.", "author": "ChuckBuilds", - "category": "text", + "category": "display", "tags": [ "text", "scroll", "message", + "display", "custom" ], "repo": "https://github.com/ChuckBuilds/ledmatrix-plugins", @@ -105,22 +112,23 @@ "plugin_path": "plugins/text-display", "stars": 0, "downloads": 0, - "last_updated": "2025-10-19", + "last_updated": "2026-04-07", "verified": true, "screenshot": "", - "latest_version": "1.0.1" + "latest_version": "1.0.2" }, { "id": "of-the-day", - "name": "Of The Day", + "name": "Of The Day Display", "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.", "author": "ChuckBuilds", - "category": "content", + "category": "information", "tags": [ "word", - "verse", "daily", - "quote" + "education", + "content", + "rotation" ], "repo": "https://github.com/ChuckBuilds/ledmatrix-plugins", "branch": "main", @@ -134,16 +142,16 @@ }, { "id": "music", - "name": "Music Player", - "description": "Displays 'Now Playing' information from Spotify or YouTube Music, including album art and scrolling text", + "name": "Music Player - Now Playing", + "description": "Real-time now playing display for Spotify and YouTube Music with album art, scrolling text, and progress bars", "author": "ChuckBuilds", "category": "media", "tags": [ "music", "spotify", - "youtube music", - "now playing", - "album art" + "youtube-music", + "now-playing", + "album-art" ], "repo": "https://github.com/ChuckBuilds/ledmatrix-plugins", "branch": "main", @@ -160,12 +168,13 @@ "name": "Google Calendar", "description": "Display upcoming events from Google Calendar with date, time, and event details. Shows next 1-3 events with automatic rotation and timezone support.", "author": "ChuckBuilds", - "category": "time", + "category": "productivity", "tags": [ "calendar", - "events", "google", - "schedule" + "events", + "schedule", + "appointments" ], "repo": "https://github.com/ChuckBuilds/ledmatrix-plugins", "branch": "main", @@ -199,7 +208,8 @@ "last_updated": "2026-02-25", "verified": true, "screenshot": "", - "latest_version": "1.2.4" + "latest_version": "1.2.4", + "icon": "fas fa-hockey-puck" }, { "id": "football-scoreboard", @@ -248,12 +258,13 @@ "last_updated": "2026-02-25", "verified": true, "screenshot": "", - "latest_version": "1.2.3" + "latest_version": "1.2.3", + "icon": "fas fa-fist-raised" }, { "id": "basketball-scoreboard", "name": "Basketball Scoreboard", - "description": "Live, recent, and upcoming basketball games across NBA, NCAA Men's, NCAA Women's, and WNBA with real-time scores and schedules", + "description": "Live, recent, and upcoming basketball games across NBA, NCAA Men's, NCAA Women's, and WNBA with real-time scores, schedules, and March Madness tournament support", "author": "ChuckBuilds", "category": "sports", "tags": [ @@ -304,7 +315,7 @@ { "id": "soccer-scoreboard", "name": "Soccer Scoreboard", - "description": "Live, recent, and upcoming soccer games across multiple leagues including Premier League, La Liga, Bundesliga, Serie A, Ligue 1, MLS, and more", + "description": "Live, recent, and upcoming soccer games across multiple leagues including Premier League, La Liga, Bundesliga, Serie A, Ligue 1, MLS, Liga Portugal, and more", "author": "ChuckBuilds", "category": "sports", "tags": [ @@ -436,17 +447,15 @@ }, { "id": "stocks", - "name": "Stocks Ticker", - "description": "Displays scrolling stock tickers with prices, changes, and optional charts for stocks and cryptocurrencies", - "author": "ChuckBuilds", - "category": "financial", + "name": "Stock & Crypto Ticker", + "description": "Displays stock tickers with prices, changes, and optional charts for stocks and cryptocurrencies. Supports scroll and switch display modes.", + "author": "LEDMatrix Team", + "category": "finance", "tags": [ "stocks", - "financial", - "ticker", "crypto", - "market", - "charts", + "finance", + "ticker", "scrolling" ], "repo": "https://github.com/ChuckBuilds/ledmatrix-plugins", @@ -457,12 +466,13 @@ "last_updated": "2026-03-04", "verified": true, "screenshot": "", - "latest_version": "2.2.0" + "latest_version": "2.2.0", + "icon": "fas fa-chart-line" }, { "id": "ledmatrix-flights", "name": "Flight Tracker", - "description": "Real-time aircraft tracking with ADS-B data, map backgrounds, flight plans, and proximity alerts", + "description": "Real-time aircraft tracking with ADS-B/FlightRadar24/OpenSky data, map backgrounds, area mode, flight tracking, anchor airport, and flight records", "author": "ChuckBuilds", "category": "custom", "tags": [ @@ -471,8 +481,7 @@ "ads-b", "skyaware", "aviation", - "map", - "tracker" + "map" ], "repo": "https://github.com/ChuckBuilds/ledmatrix-plugins", "branch": "main", @@ -487,15 +496,14 @@ { "id": "christmas-countdown", "name": "Christmas Countdown", - "description": "Display a festive countdown to Christmas with a stylized Christmas tree logo and stacked text. Features split-screen layout with large tree on left and countdown text on right. Shows 'MERRY CHRISTMAS' on and after December 25th.", + "description": "Display a countdown to Christmas with a stylized Christmas tree logo and festive text", "author": "ChuckBuilds", "category": "holiday", "tags": [ "christmas", "countdown", "holiday", - "seasonal", - "festive" + "seasonal" ], "repo": "https://github.com/ChuckBuilds/ledmatrix-plugins", "branch": "main", @@ -509,16 +517,18 @@ }, { "id": "olympics", - "name": "Olympics Countdown", - "description": "Display a countdown to the next Olympics (summer or winter) with an Olympics logo. Automatically determines the next Olympics and counts down to the opening ceremony. Once the Olympics starts, switches to countdown to the closing ceremony. Supports Olympics through 2032.", + "name": "Olympics", + "description": "Enhanced Olympics plugin with live medal counts, upcoming events, results, and countdown. Supports Vegas scroll mode and regular display mode.", "author": "ChuckBuilds", "category": "sports", "tags": [ "olympics", - "countdown", + "medals", "sports", - "summer", - "winter" + "winter", + "events", + "results", + "vegas" ], "repo": "https://github.com/ChuckBuilds/ledmatrix-plugins", "branch": "main", @@ -533,7 +543,7 @@ { "id": "youtube-stats", "name": "YouTube Stats", - "description": "Display YouTube channel statistics including subscriber count, total views, and channel name on your LED matrix. Features YouTube logo, auto-refresh, and efficient caching.", + "description": "Display YouTube channel statistics including subscriber count, total views, and channel name on your LED matrix", "author": "ChuckBuilds", "category": "social", "tags": [ @@ -541,9 +551,7 @@ "social", "stats", "display", - "channel", - "subscribers", - "views" + "channel" ], "repo": "https://github.com/ChuckBuilds/ledmatrix-plugins", "branch": "main", @@ -622,22 +630,22 @@ "last_updated": "2026-03-06", "verified": true, "screenshot": "", - "latest_version": "2.0.0" + "latest_version": "2.0.0", + "icon": "fa-clock" }, { "id": "f1-scoreboard", "name": "F1 Scoreboard", - "description": "Comprehensive Formula 1 racing display with driver standings, constructor standings, race results, qualifying (Q1/Q2/Q3), free practice, sprint results, upcoming race countdown with circuit outline, and season calendar. Supports favorite team/driver filtering and team color accent bars.", + "description": "Formula 1 racing plugin showing driver/constructor standings, race results, qualifying breakdowns, practice standings, sprint results, upcoming races, and race calendar with team-colored displays and favorite driver/team support", "author": "ChuckBuilds", "category": "sports", "tags": [ "f1", "formula1", "racing", + "motorsport", "sports", - "standings", - "scoreboard", - "motorsport" + "scoreboard" ], "repo": "https://github.com/ChuckBuilds/ledmatrix-plugins", "branch": "main", @@ -675,7 +683,7 @@ { "id": "masters-tournament", "name": "Masters Tournament", - "description": "Masters Tournament display with ESPN leaderboards, Augusta National hole layouts, fun facts, past champions, course tour, countdown, and more", + "description": "Broadcast-quality Masters Tournament display with real ESPN player headshots, accurate Augusta National hole layouts, fun facts, past champions, live leaderboards, and pixel-perfect LED matrix rendering", "author": "ChuckBuilds", "category": "sports", "tags": [ @@ -739,7 +747,8 @@ "last_updated": "2026-04-06", "verified": true, "screenshot": "", - "latest_version": "1.0.3" + "latest_version": "1.0.3", + "icon": "fas fa-baseball-ball" } ] } diff --git a/plugins/7-segment-clock/LICENSE b/plugins/7-segment-clock/LICENSE new file mode 100644 index 0000000..e653a0c --- /dev/null +++ b/plugins/7-segment-clock/LICENSE @@ -0,0 +1,17 @@ +GNU GENERAL PUBLIC LICENSE +Version 3, 29 June 2007 + +Copyright (C) 2025 LEDMatrix Team + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . diff --git a/plugins/7-segment-clock/README.md b/plugins/7-segment-clock/README.md index 5e13faf..6cd22de 100644 --- a/plugins/7-segment-clock/README.md +++ b/plugins/7-segment-clock/README.md @@ -17,8 +17,9 @@ A retro-style 7-segment clock plugin for LEDMatrix that displays time using digi ### From Plugin Store (Recommended) 1. Open the LEDMatrix web interface (`http://your-pi-ip:5000`) -2. Go to **Plugin Store** -3. Find **7-Segment Clock** and click **Install** +2. Open the **Plugin Manager** tab +3. Find **7-Segment Clock** in the **Plugin Store** section and click + **Install** ### Manual Installation diff --git a/plugins/7-segment-clock/manifest.json b/plugins/7-segment-clock/manifest.json index 2f14a94..cf95191 100644 --- a/plugins/7-segment-clock/manifest.json +++ b/plugins/7-segment-clock/manifest.json @@ -22,6 +22,13 @@ ], "update_interval": 60, "default_duration": 15, - "config_schema": "config_schema.json" + "config_schema": "config_schema.json", + "versions": [ + { + "version": "1.0.0", + "released": "2026-04-07", + "ledmatrix_min_version": "2.0.0" + } + ], + "last_updated": "2026-04-07" } - diff --git a/plugins/baseball-scoreboard/README.md b/plugins/baseball-scoreboard/README.md index a02477a..6471075 100644 --- a/plugins/baseball-scoreboard/README.md +++ b/plugins/baseball-scoreboard/README.md @@ -43,9 +43,9 @@ A plugin for LEDMatrix that displays live, recent, and upcoming baseball games a "enabled": true, "favorite_teams": ["NYY", "BOS", "LAD"], "display_modes": { - "live": true, - "recent": true, - "upcoming": true + "show_live": true, + "show_recent": true, + "show_upcoming": true }, "recent_games_to_show": 5, "upcoming_games_to_show": 10 @@ -61,9 +61,9 @@ A plugin for LEDMatrix that displays live, recent, and upcoming baseball games a "enabled": true, "favorite_teams": ["DUR", "SWB", "MEM"], "display_modes": { - "live": true, - "recent": true, - "upcoming": true + "show_live": true, + "show_recent": true, + "show_upcoming": true }, "recent_games_to_show": 5, "upcoming_games_to_show": 10 @@ -79,9 +79,9 @@ A plugin for LEDMatrix that displays live, recent, and upcoming baseball games a "enabled": true, "favorite_teams": ["LSU", "FLA", "VANDY"], "display_modes": { - "live": true, - "recent": true, - "upcoming": true + "show_live": true, + "show_recent": true, + "show_upcoming": true }, "recent_games_to_show": 5, "upcoming_games_to_show": 10 @@ -91,11 +91,15 @@ A plugin for LEDMatrix that displays live, recent, and upcoming baseball games a ## Display Modes -The plugin supports three display modes: +The plugin registers per-league granular modes in `manifest.json`. The +display controller rotates through any that are enabled: -1. **baseball_live**: Shows currently active games -2. **baseball_recent**: Shows recently completed games -3. **baseball_upcoming**: Shows scheduled upcoming games +**MLB:** `mlb_live`, `mlb_recent`, `mlb_upcoming` +**MiLB:** `milb_live`, `milb_recent`, `milb_upcoming` +**NCAA Baseball:** `ncaa_baseball_live`, `ncaa_baseball_recent`, `ncaa_baseball_upcoming` + +Toggle individual modes per league with the `show_live` / `show_recent` +/ `show_upcoming` flags inside each league's `display_modes` block. ## Team Abbreviations @@ -126,10 +130,18 @@ This plugin requires the main LEDMatrix installation and inherits functionality ## Installation -1. Copy this plugin directory to your `ledmatrix-plugins/plugins/` folder -2. Ensure the plugin is enabled in your LEDMatrix configuration -3. Configure your favorite teams and display preferences -4. Restart LEDMatrix to load the new plugin +The easiest way is the Plugin Store in the LEDMatrix web UI: + +1. Open `http://your-pi-ip:5000` +2. Open the **Plugin Manager** tab +3. Find **Baseball Scoreboard** in the **Plugin Store** section and click + **Install** +4. Open the plugin's tab in the second nav row to configure favorite + teams and per-league preferences + +Manual install: copy this directory into your LEDMatrix +`plugins_directory` (default `plugin-repos/`) and restart the display +service. ## Troubleshooting diff --git a/plugins/baseball-scoreboard/manifest.json b/plugins/baseball-scoreboard/manifest.json index ac85b54..801799e 100644 --- a/plugins/baseball-scoreboard/manifest.json +++ b/plugins/baseball-scoreboard/manifest.json @@ -33,87 +33,87 @@ { "released": "2026-03-30", "version": "1.6.0", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2026-03-29", "version": "1.5.6", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2026-03-29", "version": "1.5.5", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2026-03-02", "version": "1.5.4", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2026-02-24", "version": "1.5.3", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2026-02-24", "version": "1.5.2", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2026-02-24", "version": "1.5.1", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2026-02-24", "version": "1.5.0", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2026-02-20", "version": "1.4.0", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2026-02-17", "version": "1.3.1", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2026-02-15", "version": "1.3.0", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2026-02-14", "version": "1.2.0", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2026-02-13", "version": "1.1.0", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2026-02-12", "version": "1.0.5", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-20", "version": "1.0.4", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-20", "version": "1.0.3", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-19", "version": "1.0.2", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" } ], "last_updated": "2026-03-30", @@ -122,5 +122,8 @@ "verified": true, "screenshot": "", "class_name": "BaseballScoreboardPlugin", - "entry_point": "manager.py" + "entry_point": "manager.py", + "compatible_versions": [ + ">=2.0.0" + ] } diff --git a/plugins/basketball-scoreboard/README.md b/plugins/basketball-scoreboard/README.md index cf62aed..f2e34b1 100644 --- a/plugins/basketball-scoreboard/README.md +++ b/plugins/basketball-scoreboard/README.md @@ -304,10 +304,18 @@ This plugin requires the main LEDMatrix installation and inherits functionality ## Installation -1. Copy this plugin directory to your `ledmatrix-plugins/plugins/` folder -2. Ensure the plugin is enabled in your LEDMatrix configuration -3. Configure your favorite teams and display preferences -4. Restart LEDMatrix to load the new plugin +The easiest way is the Plugin Store in the LEDMatrix web UI: + +1. Open `http://your-pi-ip:5000` +2. Open the **Plugin Manager** tab +3. Find **Basketball Scoreboard** in the **Plugin Store** section and + click **Install** +4. Open the plugin's tab in the second nav row to configure favorite + teams and per-league preferences + +Manual install: copy this directory into your LEDMatrix +`plugins_directory` (default `plugin-repos/`) and restart the display +service. ## Game Limits Behavior diff --git a/plugins/basketball-scoreboard/STANDALONE.md b/plugins/basketball-scoreboard/STANDALONE.md index d5b32f9..069cb4f 100644 --- a/plugins/basketball-scoreboard/STANDALONE.md +++ b/plugins/basketball-scoreboard/STANDALONE.md @@ -8,7 +8,7 @@ The basketball plugin has been redesigned to be completely independent and not r ### Core Components -1. **`manager.py`** - Main plugin class (BasketballPluginManager) +1. **`manager.py`** - Main plugin class (BasketballScoreboardPlugin) - Only inherits from `BasePlugin` (plugin system requirement) - Contains all basketball-specific logic - Handles data fetching, game filtering, and display @@ -32,7 +32,7 @@ The basketball plugin has been redesigned to be completely independent and not r ### Before (with base classes) ```python -class BasketballPluginManager(BasePlugin, Basketball): +class BasketballScoreboardPlugin(BasePlugin, Basketball): # Inherited from Basketball base class: # - Font loading # - Logo loading @@ -43,7 +43,7 @@ class BasketballPluginManager(BasePlugin, Basketball): ### Now (standalone) ```python -class BasketballPluginManager(BasePlugin): +class BasketballScoreboardPlugin(BasePlugin): # Uses BasketballHelpers for: # - Font loading # - Logo loading @@ -73,7 +73,7 @@ python3 test_plugin_syntax.py Expected output: ``` ✓ Plugin imported successfully -✓ Class name: BasketballPluginManager +✓ Class name: BasketballScoreboardPlugin ✓ Base classes: (,) Plugin structure is valid! ``` @@ -108,13 +108,22 @@ All functionality from the old basketball managers is preserved: ## Configuration -Works exactly like the original, with per-league configuration: +Works with per-league nested configuration. The full schema lives in +[`config_schema.json`](config_schema.json); a minimal example: ```json { - "nba_enabled": true, - "nba_favorite_teams": ["LAL", "BOS"], - "nba_display_modes_live": true, - "ncaam_basketball_enabled": false + "nba": { + "enabled": true, + "favorite_teams": ["LAL", "BOS"], + "display_modes": { + "show_live": true, + "show_recent": true, + "show_upcoming": true + } + }, + "ncaam": { + "enabled": false + } } ``` diff --git a/plugins/basketball-scoreboard/TESTING.md b/plugins/basketball-scoreboard/TESTING.md index 9f970a1..7216f7c 100644 --- a/plugins/basketball-scoreboard/TESTING.md +++ b/plugins/basketball-scoreboard/TESTING.md @@ -16,7 +16,7 @@ python3 test_plugin_syntax.py Expected output: ``` ✓ Plugin imported successfully -✓ Class name: BasketballPluginManager +✓ Class name: BasketballScoreboardPlugin ✓ Base classes: (...) Plugin structure is valid! ``` @@ -49,7 +49,7 @@ The plugin is now **standalone** and does not depend on Basketball or Sports bas ## Plugin Features Tested - ✅ Plugin imports without errors -- ✅ Multiple inheritance works correctly (BasePlugin + Basketball) +- ✅ Inherits from BasePlugin only (no Basketball base class — see STANDALONE.md) - ✅ Configuration loading for all leagues (NBA, WNBA, NCAA M/W) - ✅ Display mode configuration (live, recent, upcoming) - ✅ League enable/disable functionality diff --git a/plugins/basketball-scoreboard/manifest.json b/plugins/basketball-scoreboard/manifest.json index 60b5cb9..dea42c8 100644 --- a/plugins/basketball-scoreboard/manifest.json +++ b/plugins/basketball-scoreboard/manifest.json @@ -1,99 +1,102 @@ { - "id": "basketball-scoreboard", - "name": "Basketball Scoreboard", - "version": "1.5.5", - "description": "Live, recent, and upcoming basketball games across NBA, NCAA Men's, NCAA Women's, and WNBA with real-time scores, schedules, and March Madness tournament support", - "author": "ChuckBuilds", - "category": "sports", - "tags": [ - "basketball", - "nba", - "ncaa", - "wnba", - "sports", - "scoreboard", - "live-scores" - ], - "repo": "https://github.com/ChuckBuilds/ledmatrix-plugins", - "branch": "main", - "plugin_path": "plugins/basketball-scoreboard", - "versions": [ - { - "released": "2026-03-30", - "version": "1.5.5", - "ledmatrix_min": "2.0.0" - }, - { - "released": "2026-03-02", - "version": "1.5.4", - "ledmatrix_min": "2.0.0" - }, - { - "released": "2026-02-24", - "version": "1.5.3", - "ledmatrix_min": "2.0.0" - }, - { - "version": "1.5.2", - "ledmatrix_min": "2.0.0", - "released": "2026-02-24" - }, - { - "version": "1.5.1", - "ledmatrix_min": "2.0.0", - "released": "2026-02-24" - }, - { - "version": "1.5.0", - "ledmatrix_min": "2.0.0", - "released": "2026-02-24" - }, - { - "version": "1.4.0", - "ledmatrix_min": "2.0.0", - "released": "2026-02-20" - }, - { - "version": "1.3.0", - "ledmatrix_min": "2.0.0", - "released": "2026-02-17" - }, - { - "version": "1.1.1", - "ledmatrix_min": "2.0.0", - "released": "2026-02-15" - }, - { - "version": "1.1.0", - "ledmatrix_min": "2.0.0", - "released": "2026-02-14" - }, - { - "version": "1.0.6", - "ledmatrix_min": "2.0.0", - "released": "2026-02-13" - } - ], - "stars": 0, - "downloads": 0, - "last_updated": "2026-03-02", - "verified": true, - "screenshot": "", - "display_modes": [ - "nba_recent", - "nba_upcoming", - "nba_live", - "wnba_recent", - "wnba_upcoming", - "wnba_live", - "ncaam_recent", - "ncaam_upcoming", - "ncaam_live", - "ncaaw_recent", - "ncaaw_upcoming", - "ncaaw_live" - ], - "dependencies": {}, - "entry_point": "manager.py", - "class_name": "BasketballScoreboardPlugin" + "id": "basketball-scoreboard", + "name": "Basketball Scoreboard", + "version": "1.5.5", + "description": "Live, recent, and upcoming basketball games across NBA, NCAA Men's, NCAA Women's, and WNBA with real-time scores, schedules, and March Madness tournament support", + "author": "ChuckBuilds", + "category": "sports", + "tags": [ + "basketball", + "nba", + "ncaa", + "wnba", + "sports", + "scoreboard", + "live-scores" + ], + "repo": "https://github.com/ChuckBuilds/ledmatrix-plugins", + "branch": "main", + "plugin_path": "plugins/basketball-scoreboard", + "versions": [ + { + "released": "2026-03-30", + "version": "1.5.5", + "ledmatrix_min_version": "2.0.0" + }, + { + "released": "2026-03-02", + "version": "1.5.4", + "ledmatrix_min_version": "2.0.0" + }, + { + "released": "2026-02-24", + "version": "1.5.3", + "ledmatrix_min_version": "2.0.0" + }, + { + "version": "1.5.2", + "released": "2026-02-24", + "ledmatrix_min_version": "2.0.0" + }, + { + "version": "1.5.1", + "released": "2026-02-24", + "ledmatrix_min_version": "2.0.0" + }, + { + "version": "1.5.0", + "released": "2026-02-24", + "ledmatrix_min_version": "2.0.0" + }, + { + "version": "1.4.0", + "released": "2026-02-20", + "ledmatrix_min_version": "2.0.0" + }, + { + "version": "1.3.0", + "released": "2026-02-17", + "ledmatrix_min_version": "2.0.0" + }, + { + "version": "1.1.1", + "released": "2026-02-15", + "ledmatrix_min_version": "2.0.0" + }, + { + "version": "1.1.0", + "released": "2026-02-14", + "ledmatrix_min_version": "2.0.0" + }, + { + "version": "1.0.6", + "released": "2026-02-13", + "ledmatrix_min_version": "2.0.0" + } + ], + "stars": 0, + "downloads": 0, + "last_updated": "2026-03-30", + "verified": true, + "screenshot": "", + "display_modes": [ + "nba_recent", + "nba_upcoming", + "nba_live", + "wnba_recent", + "wnba_upcoming", + "wnba_live", + "ncaam_recent", + "ncaam_upcoming", + "ncaam_live", + "ncaaw_recent", + "ncaaw_upcoming", + "ncaaw_live" + ], + "dependencies": {}, + "entry_point": "manager.py", + "class_name": "BasketballScoreboardPlugin", + "compatible_versions": [ + ">=2.0.0" + ] } diff --git a/plugins/calendar/README.md b/plugins/calendar/README.md index 8f10610..7a3bb4f 100644 --- a/plugins/calendar/README.md +++ b/plugins/calendar/README.md @@ -36,29 +36,30 @@ Display upcoming events from Google Calendar with automatic updates, event rotat ### 1. Create Google Cloud Project 1. Go to [Google Cloud Console](https://console.cloud.google.com/) -2. Create a new project or select existing one -3. Enable the Google Calendar API -4. Create OAuth 2.0 credentials - * Application type: TV and Limited Input Device +2. Create a new project or select an existing one +3. Enable the **Google Calendar API** -### 2. Download Credentials +### 2. Create OAuth credentials and download them -1. In Cloud Console, go to "Credentials" -2. Click "Create Credentials" → "OAuth client ID" -3. Choose "Desktop application" +1. In Cloud Console, go to **APIs & Services → Credentials** +2. Click **Create Credentials → OAuth client ID** +3. Choose **Desktop application** — the plugin uses + `InstalledAppFlow.run_local_server()` + (`plugins/calendar/manager.py:346-348`), which requires this client + type. "TV and Limited Input Device" will not work. 4. Download the JSON file -5. Save as `credentials.json` in the **calendar plugin directory** - - Path: `plugins/calendar/credentials.json` +5. Save it as `credentials.json` in the calendar plugin directory + (typically `plugin-repos/calendar/credentials.json`) ### 3. First-Time Authentication **Option A: Use Web Interface (Recommended)** -1. Open the LEDMatrix web interface -2. Navigate to the Plugins tab -3. Find the "Google Calendar" plugin and click "Configure" -4. Click the "Authenticate Google Calendar" button -5. Follow the OAuth flow in your browser -6. Token will be saved automatically +1. Open the LEDMatrix web interface (`http://your-pi-ip:5000`) +2. Open the **Calendar** tab in the second nav row (added once the + plugin is installed) +3. Click the **Authenticate Google Calendar** button +4. Follow the OAuth flow in your browser +5. The token is saved automatically into the plugin directory **Option B: Use Registration Script** ```bash diff --git a/plugins/calendar/manifest.json b/plugins/calendar/manifest.json index d98b9d9..db0435a 100644 --- a/plugins/calendar/manifest.json +++ b/plugins/calendar/manifest.json @@ -38,17 +38,20 @@ { "released": "2026-03-02", "version": "1.1.0", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-19", "version": "1.0.1", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" } ], "last_updated": "2026-03-02", "stars": 0, "downloads": 0, "verified": true, - "screenshot": "" + "screenshot": "", + "compatible_versions": [ + ">=2.0.0" + ] } diff --git a/plugins/christmas-countdown/LICENSE b/plugins/christmas-countdown/LICENSE new file mode 100644 index 0000000..e653a0c --- /dev/null +++ b/plugins/christmas-countdown/LICENSE @@ -0,0 +1,17 @@ +GNU GENERAL PUBLIC LICENSE +Version 3, 29 June 2007 + +Copyright (C) 2025 LEDMatrix Team + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . diff --git a/plugins/christmas-countdown/README.md b/plugins/christmas-countdown/README.md index ebc8206..2267578 100644 --- a/plugins/christmas-countdown/README.md +++ b/plugins/christmas-countdown/README.md @@ -34,14 +34,22 @@ Screenshot of Christmas Countdown: The plugin supports the following configuration options: -### Basic Settings - -- `enabled` (boolean, default: `false`): Enable or disable the plugin -- `display_duration` (number, default: `15`): How long to display the countdown in seconds (1-300) -- `update_interval` (integer, default: `3600`): How often to update the countdown in seconds (60-86400). Default is 1 hour since the countdown changes daily. - - -``` +### Configuration options + +Full schema lives in [`config_schema.json`](config_schema.json): + +| Key | Default | Notes | +|---|---|---| +| `enabled` | `false` | Master switch | +| `display_duration` | `15` | Seconds the plugin holds the screen (1–300) | +| `update_interval` | `3600` | Seconds between updates (60–86400). Default 1 hour since the countdown only changes daily. | +| `high_performance_transitions` | `false` | Use a faster path for transitions on weaker Pis | +| `transition.enabled` | `true` | Toggle transition animation between displays | +| `transition.type` | `"redraw"` | Transition style | +| `transition.speed` | `2` | Animation speed | +| `text_color` | `[255, 0, 0]` | RGB color for the countdown text (default red) | +| `tree_color` | `[0, 128, 0]` | RGB color for the programmatically-drawn tree (default green) | +| `tree_size` | _auto_ | Override the auto-sized tree height in pixels | ## Display Behavior diff --git a/plugins/christmas-countdown/manifest.json b/plugins/christmas-countdown/manifest.json index 3b5049e..c8a2392 100644 --- a/plugins/christmas-countdown/manifest.json +++ b/plugins/christmas-countdown/manifest.json @@ -20,12 +20,15 @@ { "released": "2025-01-27", "version": "1.0.0", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" } ], "last_updated": "2025-01-27", "stars": 0, "downloads": 0, "verified": true, - "screenshot": "" + "screenshot": "", + "compatible_versions": [ + ">=2.0.0" + ] } diff --git a/plugins/clock-simple/README.md b/plugins/clock-simple/README.md index f9693b0..d2d68a5 100644 --- a/plugins/clock-simple/README.md +++ b/plugins/clock-simple/README.md @@ -25,12 +25,14 @@ A simple, customizable clock display plugin for LEDMatrix that shows the current ## Installation -### From Plugin Store (Recommended) +### From the Plugin Store (recommended) -1. Open the LEDMatrix web interface -2. Navigate to the Plugin Store tab -3. Search for "Simple Clock" or browse the "time" category -4. Click "Install" +1. Open the LEDMatrix web interface (`http://your-pi-ip:5000`) +2. Open the **Plugin Manager** tab +3. Find **Simple Clock** in the **Plugin Store** section (it's in the + `time` category) and click **Install** +4. Toggle the plugin on, then click **Restart Display Service** on the + **Overview** tab ### Manual Installation @@ -79,16 +81,18 @@ Add the following to your `config/config.json`: | Option | Type | Default | Description | |--------|------|---------|-------------| -| `enabled` | boolean | `true` | Enable or disable the plugin | -| `timezone` | string | Inherits from global config | Timezone for display (e.g., `"America/New_York"`). If not specified, inherits from LEDMatrix global timezone setting | -| `time_format` | string | `"12h"` | Time format: `"12h"` or `"24h"` | -| `show_seconds` | boolean | `false` | Show seconds in time display | +| `enabled` | boolean | `false` | Enable or disable the plugin | +| `display_duration` | number | `15` | Seconds to hold the screen each rotation (1–300) | +| `update_interval` | integer | `1` | How often to redraw the clock, in seconds (1–60) | +| `timezone` | string \| null | `null` | IANA timezone name (e.g. `"America/New_York"`). When null, inherits the global LEDMatrix timezone | +| `time_format` | string | `"12h"` | `"12h"` or `"24h"` | +| `center_time_with_ampm` | boolean | `false` | Center the time + AM/PM as one block (12h only) | +| `show_seconds` | boolean | `false` | Include seconds in the time | | `show_date` | boolean | `true` | Show date below the time | -| `date_format` | string | `"OLD_CLOCK"` | Date format: `"MM/DD/YYYY"`, `"DD/MM/YYYY"`, `"YYYY-MM-DD"`, or `"OLD_CLOCK"` | -| `display_duration` | number | `15` | Display duration in seconds | -| `position_x` | integer | `0` | X position offset for display (pixels) | -| `position_y` | integer | `0` | Y position offset for display (pixels) | -| `customization` | object | See below | Nested configuration for display customization | +| `date_format` | string | `"OLD_CLOCK"` | One of `"MM/DD/YYYY"`, `"DD/MM/YYYY"`, `"YYYY-MM-DD"`, `"OLD_CLOCK"` (e.g. `Monday, January 1st`) | +| `position_x` | integer | `0` | X offset in pixels | +| `position_y` | integer | `0` | Y offset in pixels | +| `customization` | object | See below | Per-element font and color overrides | ### Customization Options @@ -172,21 +176,21 @@ plugins/clock-simple/ ### Testing -Test the plugin by running: +The fastest way to verify a change without restarting the full display +service is the LEDMatrix dev preview server, which renders this plugin in +your browser without any hardware: ```bash cd /path/to/LEDMatrix -python3 -c " -from src.plugin_system.plugin_manager import PluginManager -pm = PluginManager() -pm.discover_plugins() -pm.load_plugin('clock-simple') -plugin = pm.get_plugin('clock-simple') -plugin.update() -plugin.display() -" +python3 scripts/dev_server.py --extra-dir /path/to/ledmatrix-plugins/plugins/clock-simple +# then open http://localhost:5001 ``` +You can also render a single still frame to a PNG with +`scripts/render_plugin.py` — see +[`docs/DEV_PREVIEW.md`](https://github.com/ChuckBuilds/LEDMatrix/blob/main/docs/DEV_PREVIEW.md) +for details. + ## License GPL-3.0 License - feel free to modify and distribute. diff --git a/plugins/clock-simple/manifest.json b/plugins/clock-simple/manifest.json index 6e51917..b2d3363 100644 --- a/plugins/clock-simple/manifest.json +++ b/plugins/clock-simple/manifest.json @@ -19,12 +19,15 @@ { "released": "2025-10-19", "version": "1.0.4", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" } ], "last_updated": "2025-10-19", "stars": 0, "downloads": 0, "verified": true, - "screenshot": "" + "screenshot": "", + "compatible_versions": [ + ">=2.0.0" + ] } diff --git a/plugins/countdown/LICENSE b/plugins/countdown/LICENSE new file mode 100644 index 0000000..e653a0c --- /dev/null +++ b/plugins/countdown/LICENSE @@ -0,0 +1,17 @@ +GNU GENERAL PUBLIC LICENSE +Version 3, 29 June 2007 + +Copyright (C) 2025 LEDMatrix Team + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . diff --git a/plugins/countdown/README.md b/plugins/countdown/README.md index 42a70f8..c1f0c6e 100644 --- a/plugins/countdown/README.md +++ b/plugins/countdown/README.md @@ -18,8 +18,9 @@ Display customizable countdowns with images on your LED matrix. Perfect for birt ### From Plugin Store (Recommended) 1. Open the LEDMatrix web interface (`http://your-pi-ip:5000`) -2. Go to **Plugin Store** -3. Find **Countdown Display** and click **Install** +2. Open the **Plugin Manager** tab +3. Find **Countdown Display** in the **Plugin Store** section and click + **Install** ### Manual Installation @@ -35,7 +36,8 @@ Display customizable countdowns with images on your LED matrix. Perfect for birt ### Adding a Countdown 1. Open the LEDMatrix web UI -2. Navigate to Settings > Plugins > Countdown Display +2. Open the **Countdown Display** tab (second nav row, added once the + plugin is installed) 3. Click "Add Countdown" 4. Fill in the details: - **Name**: Display name (e.g., "Birthday", "Vacation") diff --git a/plugins/countdown/manifest.json b/plugins/countdown/manifest.json index 2c717fe..944de36 100644 --- a/plugins/countdown/manifest.json +++ b/plugins/countdown/manifest.json @@ -2,7 +2,7 @@ "id": "countdown", "name": "Countdown Display", "version": "2.0.0", - "author": "Charles", + "author": "ChuckBuilds", "description": "Create and manage customizable countdowns with images. Perfect for birthdays, holidays, events, and special occasions.", "entry_point": "manager.py", "class_name": "CountdownPlugin", @@ -24,12 +24,12 @@ { "released": "2026-03-06", "version": "2.0.0", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2026-03-06", "version": "1.0.2", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" } ], "update_interval": 60, diff --git a/plugins/f1-scoreboard/LICENSE b/plugins/f1-scoreboard/LICENSE new file mode 100644 index 0000000..e653a0c --- /dev/null +++ b/plugins/f1-scoreboard/LICENSE @@ -0,0 +1,17 @@ +GNU GENERAL PUBLIC LICENSE +Version 3, 29 June 2007 + +Copyright (C) 2025 LEDMatrix Team + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . diff --git a/plugins/f1-scoreboard/README.md b/plugins/f1-scoreboard/README.md new file mode 100644 index 0000000..3e97a99 --- /dev/null +++ b/plugins/f1-scoreboard/README.md @@ -0,0 +1,98 @@ +# F1 Scoreboard Plugin + +A Formula 1 plugin for LEDMatrix that displays driver and constructor +standings, race results, qualifying and practice times, sprint results, +upcoming races, and the season calendar — with team-colored visuals and +favorite-driver/team highlighting. + +Data comes from the public ESPN F1 endpoints; no API key is required. + +## Features + +- **Driver standings** with optional always-show-favorite +- **Constructor standings** with team colors +- **Recent races** with podium and your favorite's finish +- **Upcoming race** card with countdown and session times +- **Qualifying** results (Q1 / Q2 / Q3 with gaps) +- **Practice** sessions (FP1 / FP2 / FP3) with configurable depth +- **Sprint** results +- **Season calendar** with optional sprint/qualifying flags +- Per-element font and color customization +- No API key required + +## Installation + +1. Open the LEDMatrix web interface (`http://your-pi-ip:5000`) +2. Open the **Plugin Manager** tab +3. Find **F1 Scoreboard** in the **Plugin Store** section and click + **Install** +4. Open the plugin's tab in the second nav row to configure your + favorite driver/team and toggle which sections appear + +## Display Modes + +The plugin registers eight granular modes in `manifest.json`. The +display controller rotates through any that are enabled in your config: + +| Mode | Section | +|---|---| +| `f1_driver_standings` | Driver standings | +| `f1_constructor_standings` | Constructor standings | +| `f1_recent_races` | Recent race results | +| `f1_upcoming` | Next race card with countdown | +| `f1_qualifying` | Qualifying session results | +| `f1_practice` | Practice session standings | +| `f1_sprint` | Sprint race results | +| `f1_calendar` | Season schedule overview | + +## Configuration + +The full schema lives in +[`config_schema.json`](config_schema.json) — the web UI form is generated +from it. The most-used keys: + +| Key | Default | Notes | +|---|---|---| +| `enabled` | `true` | Master switch | +| `display_duration` | `30` | Seconds per section | +| `update_interval` | `3600` | Seconds between data fetches | +| `favorite_team` | `""` | Constructor abbreviation (e.g. `MER`, `RBR`) | +| `favorite_driver` | `""` | Driver code (e.g. `VER`, `HAM`, `LEC`) | +| `driver_standings.enabled` | `true` | Toggle driver standings mode | +| `driver_standings.top_n` | `10` | How many drivers to show | +| `driver_standings.always_show_favorite` | `true` | Always include your favorite even if outside top N | +| `constructor_standings.*` | mirrors `driver_standings.*` | | +| `recent_races.number_of_races` | `3` | How many past races to cycle through | +| `recent_races.top_finishers` | `3` | Top N finishers per race | +| `upcoming.show_session_times` | `true` | Show practice/qualifying/race times | +| `upcoming.countdown_enabled` | `true` | Live countdown to next race | +| `qualifying.show_q1` / `show_q2` / `show_q3` | `true` | Toggle each Q session | +| `qualifying.show_gaps` | `true` | Show gap to pole | +| `practice.sessions_to_show` | `["FP1","FP2","FP3"]` | Which practice sessions to render | +| `practice.top_n` | `10` | Drivers per practice session | +| `sprint.top_finishers` | `10` | Sprint result depth | +| `calendar.max_events` | `5` | Races per calendar view | +| `calendar.show_practice` / `show_qualifying` / `show_sprint` | varies | Calendar detail toggles | +| `dynamic_duration.enabled` | `true` | Cycle through more content per slot | +| `dynamic_duration.max_duration_seconds` | `120` | Cap for dynamic-duration sessions | +| `scroll.scroll_speed` / `scroll.scroll_delay` | `1` / `0.03` | Scroll tuning | +| `customization.*` | various | Per-element font and color overrides | + +### Driver / team codes + +Use the standard F1 three-letter codes: + +- **Drivers**: `VER`, `HAM`, `LEC`, `NOR`, `RUS`, `SAI`, `PER`, `ALO`, etc. +- **Constructors**: `MER` (Mercedes), `RBR` (Red Bull), `FER` (Ferrari), + `MCL` (McLaren), `AST` (Aston Martin), `ALP` (Alpine), `WIL` (Williams), + `STA` (Stake), `RB`, `HAA` (Haas) + +## Data source + +ESPN's public Formula 1 endpoints. No API key required. Cached locally +to keep request volume low — adjust `update_interval` if you need fresher +data. + +## License + +GPL-3.0, same as the LEDMatrix project. diff --git a/plugins/f1-scoreboard/manifest.json b/plugins/f1-scoreboard/manifest.json index 2d6b26d..d5abe6d 100644 --- a/plugins/f1-scoreboard/manifest.json +++ b/plugins/f1-scoreboard/manifest.json @@ -31,28 +31,28 @@ "versions": [ { "version": "1.2.3", - "ledmatrix_min": "2.0.0", - "released": "2026-03-08" + "released": "2026-03-08", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.2.2", - "ledmatrix_min": "2.0.0", - "released": "2026-03-02" + "released": "2026-03-02", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.2.1", - "ledmatrix_min": "2.0.0", - "released": "2026-02-24" + "released": "2026-02-24", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.2.0", - "ledmatrix_min": "2.0.0", - "released": "2026-02-24" + "released": "2026-02-24", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.1.0", - "ledmatrix_min": "2.0.0", - "released": "2026-02-17" + "released": "2026-02-17", + "ledmatrix_min_version": "2.0.0" } ], "last_updated": "2026-03-08", @@ -60,5 +60,8 @@ "downloads": 0, "verified": true, "screenshot": "", - "config_schema": "config_schema.json" + "config_schema": "config_schema.json", + "compatible_versions": [ + ">=2.0.0" + ] } diff --git a/plugins/football-scoreboard/README.md b/plugins/football-scoreboard/README.md index c59ca01..f026dc2 100644 --- a/plugins/football-scoreboard/README.md +++ b/plugins/football-scoreboard/README.md @@ -264,74 +264,7 @@ The plugin supports fine-tuning element positioning for custom display sizes. Al #### Accessing Layout Settings Layout customization is available in the web UI under the plugin configuration section: -1. Navigate to **Plugins** → **Football Scoreboard** → **Configuration** -2. Expand the **Customization** section -3. Find the **Layout Positioning** subsection - -#### Offset Values - -- **Positive values**: Move element right (x_offset) or down (y_offset) -- **Negative values**: Move element left (x_offset) or up (y_offset) -- **Default (0)**: No change from calculated position - -#### Available Elements - -- **home_logo**: Home team logo position (x_offset, y_offset) -- **away_logo**: Away team logo position (x_offset, y_offset) -- **score**: Game score position (x_offset, y_offset) -- **status_text**: Status/period text position (x_offset, y_offset) -- **date**: Game date position (x_offset, y_offset) -- **time**: Game time position (x_offset, y_offset) -- **records**: Team records/rankings position (away_x_offset, home_x_offset, y_offset) - -#### Example Adjustments - -**Move logos inward for smaller displays:** -```json -{ - "customization": { - "layout": { - "home_logo": { "x_offset": -5 }, - "away_logo": { "x_offset": 5 } - } - } -} -``` - -**Adjust score position:** -```json -{ - "customization": { - "layout": { - "score": { "x_offset": 0, "y_offset": -2 } - } - } -} -``` - -**Shift records upward:** -```json -{ - "customization": { - "layout": { - "records": { "y_offset": -3 } - } - } -} -``` - -#### Display Size Compatibility - -Layout offsets work across different display sizes. The plugin calculates default positions based on your display dimensions, and offsets are applied relative to those defaults. This ensures compatibility with various LED matrix configurations. - -### Layout Customization - -The plugin supports fine-tuning element positioning for custom display sizes. All offsets are relative to the default calculated positions, allowing you to adjust elements without breaking the layout. - -#### Accessing Layout Settings - -Layout customization is available in the web UI under the plugin configuration section: -1. Navigate to **Plugins** → **Football Scoreboard** → **Configuration** +1. Open the **Football Scoreboard** tab (second nav row) 2. Expand the **Customization** section 3. Find the **Layout Positioning** subsection @@ -431,12 +364,13 @@ This plugin reuses the proven code from the main LEDMatrix project: ## 📦 Installation -### From Plugin Store (Recommended) -1. Open LEDMatrix web interface -2. Navigate to Plugin Store -3. Search for "Football Scoreboard" -4. Click Install -5. Configure your favorite teams and preferences +### From the Plugin Store (recommended) +1. Open the LEDMatrix web interface (`http://your-pi-ip:5000`) +2. Open the **Plugin Manager** tab +3. Find **Football Scoreboard** in the **Plugin Store** section and click + **Install** +4. Open the **Football Scoreboard** tab in the second nav row to configure + your favorite teams and per-league preferences ## ⚙️ Configuration diff --git a/plugins/football-scoreboard/manifest.json b/plugins/football-scoreboard/manifest.json index 6788729..a4dc817 100644 --- a/plugins/football-scoreboard/manifest.json +++ b/plugins/football-scoreboard/manifest.json @@ -27,217 +27,217 @@ { "released": "2026-03-02", "version": "2.3.4", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2026-02-24", "version": "2.3.3", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "version": "2.3.2", - "ledmatrix_min": "2.0.0", - "released": "2026-02-24" + "released": "2026-02-24", + "ledmatrix_min_version": "2.0.0" }, { "version": "2.3.1", - "ledmatrix_min": "2.0.0", - "released": "2026-02-24" + "released": "2026-02-24", + "ledmatrix_min_version": "2.0.0" }, { "version": "2.3.0", - "ledmatrix_min": "2.0.0", - "released": "2026-02-24" + "released": "2026-02-24", + "ledmatrix_min_version": "2.0.0" }, { "version": "2.2.0", - "ledmatrix_min": "2.0.0", - "released": "2026-02-20" + "released": "2026-02-20", + "ledmatrix_min_version": "2.0.0" }, { "version": "2.1.1", - "ledmatrix_min": "2.0.0", - "released": "2026-02-15" + "released": "2026-02-15", + "ledmatrix_min_version": "2.0.0" }, { "version": "2.1.0", - "ledmatrix_min": "2.0.0", - "released": "2026-02-14" + "released": "2026-02-14", + "ledmatrix_min_version": "2.0.0" }, { "version": "2.0.7", - "ledmatrix_min": "2.0.0", - "released": "2025-11-05" + "released": "2025-11-05", + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-11-06", "version": "2.0.6", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-27", "version": "2.0.5", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-21", "version": "2.0.4", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-21", "version": "2.0.3", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-21", "version": "2.0.2", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-21", "version": "2.0.1", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-20", "version": "1.6.0", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-20", "version": "1.5.2", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-20", "version": "1.5.1", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-20", "version": "1.5.0", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-20", "version": "1.4.1", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-20", "version": "1.4.0", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-20", "version": "1.3.0", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-20", "version": "1.2.2", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-20", "version": "1.2.1", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-20", "version": "1.2.0", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-20", "version": "1.1.9", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-20", "version": "1.1.8", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-20", "version": "1.1.7", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-20", "version": "1.1.6", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-20", "version": "1.1.5", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-20", "version": "1.1.4", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-20", "version": "1.1.3", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-19", "version": "1.1.2", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-19", "version": "1.1.1", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-19", "version": "1.1.0", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-19", "version": "1.0.10", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-19", "version": "1.0.9", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-19", "version": "1.0.8", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-19", "version": "1.0.7", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-19", "version": "1.0.6", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-19", "version": "1.0.5", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-19", "version": "1.0.4", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-19", "version": "1.0.3", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" } ], "last_updated": "2026-03-02", @@ -246,5 +246,8 @@ "verified": true, "screenshot": "", "config_schema": "config_schema.json", - "entry_point": "manager.py" + "entry_point": "manager.py", + "compatible_versions": [ + ">=2.0.0" + ] } diff --git a/plugins/hello-world/QUICK_START.md b/plugins/hello-world/QUICK_START.md index 0fc447b..451defc 100644 --- a/plugins/hello-world/QUICK_START.md +++ b/plugins/hello-world/QUICK_START.md @@ -2,7 +2,13 @@ ## 🚀 Enable the Plugin -Add this to your `config/config.json`: +The easiest way is the Plugin Store in the LEDMatrix web UI: open the +**Plugin Manager** tab, find **Hello World** in the **Plugin Store** +section, and click **Install**. The configuration form for the plugin +then appears in the second nav row. + +If you prefer to edit the config file directly, add this to your +`config/config.json`: ```json { @@ -28,31 +34,26 @@ All plugin system tests passed: ## 📋 Verify Plugin is Working -### 1. Check Plugin Discovery (Windows) -```bash -python test/test_plugin_system.py -``` - -### 2. Check on Raspberry Pi +### 1. Check on Raspberry Pi ```bash # SSH into your Pi -ssh pi@your-pi-ip +ssh ledpi@your-pi-ip # Check if plugin is discovered sudo journalctl -u ledmatrix -n 50 | grep "hello-world" -# Should see: -# Discovered plugin: hello-world v1.0.0 +# Should see something like: +# Discovered plugin: hello-world v1.0.2 # Loaded plugin: hello-world ``` -### 3. Via Web API +### 2. Via Web API ```bash # List installed plugins -curl http://localhost:5001/api/plugins/installed +curl http://localhost:5000/api/v3/plugins/installed # Enable the plugin -curl -X POST http://localhost:5001/api/plugins/toggle \ +curl -X POST http://localhost:5000/api/v3/plugins/toggle \ -H "Content-Type: application/json" \ -d '{"plugin_id": "hello-world", "enabled": true}' ``` @@ -127,5 +128,7 @@ plugins/hello-world/ --- -**Need Help?** Check the main [README.md](README.md) or [Plugin System Documentation](../../docs/PLUGIN_PHASE_1_SUMMARY.md) +**Need Help?** Check the main [README.md](README.md) or the +[Plugin Development Guide](https://github.com/ChuckBuilds/LEDMatrix/blob/main/docs/PLUGIN_DEVELOPMENT_GUIDE.md) +in the LEDMatrix repo. diff --git a/plugins/hello-world/README.md b/plugins/hello-world/README.md index 5098108..9ba1e03 100644 --- a/plugins/hello-world/README.md +++ b/plugins/hello-world/README.md @@ -1,61 +1,56 @@ # Hello World Plugin -A simple test plugin for the LEDMatrix plugin system. Displays a customizable greeting message with optional time display. +A minimal LEDMatrix plugin that displays a customizable greeting and the +current time. It's primarily here as a working starter template you can +copy when building your own plugin. -## Purpose +## What it does -This plugin serves as: -- **Test plugin** for validating the plugin system works correctly -- **Example plugin** for developers creating their own plugins -- **Simple demonstration** of the BasePlugin interface - -## Features - -- ✅ Customizable greeting message -- ✅ Optional time display -- ✅ Configurable text colors -- ✅ Proper error handling -- ✅ Configuration validation +- Displays a configurable message +- Optionally shows the current time underneath +- Lets you set the colors of both lines ## Installation -This plugin is included as a test plugin. To enable it: +The Hello World plugin ships with the default Plugin Store, so the easiest +way to install it is from the LEDMatrix web UI: -1. Edit `config/config.json` and add: +1. Open the web interface (`http://your-pi-ip:5000`) +2. Open the **Plugin Manager** tab +3. Find **Hello World** in the **Plugin Store** section and click **Install** +4. Toggle it on, then click **Restart Display Service** on the **Overview** + tab -```json -{ - "hello-world": { - "enabled": true, - "message": "Hello, World!", - "show_time": true, - "color": [255, 255, 255], - "time_color": [0, 255, 255], - "display_duration": 10 - } -} -``` - -2. Restart the display: +If you'd rather install it from source for local development, copy this +directory into your LEDMatrix installation's configured plugins +directory (default `plugin-repos/`): ```bash +cp -r plugins/hello-world ~/LEDMatrix/plugin-repos/ sudo systemctl restart ledmatrix ``` -## Configuration Options +## Configuration + +Once installed, configuration lives in the plugin's tab in the web UI. +Under the hood it's stored in `config/config.json` under the `hello-world` +key. | Option | Type | Default | Description | -|--------|------|---------|-------------| +|---|---|---|---| | `enabled` | boolean | `true` | Enable/disable the plugin | -| `message` | string | `"Hello, World!"` | The greeting message to display | +| `message` | string | `"Hello, World!"` | The greeting message (1–50 chars) | | `show_time` | boolean | `true` | Show current time below message | -| `color` | array | `[255, 255, 255]` | RGB color for message (white) | -| `time_color` | array | `[0, 255, 255]` | RGB color for time (cyan) | -| `display_duration` | number | `10` | Display time in seconds | +| `color` | `[r, g, b]` | `[255, 255, 255]` | RGB color for the message (white) | +| `time_color` | `[r, g, b]` | `[0, 255, 255]` | RGB color for the time (cyan) | +| `display_duration` | number | `10` | Seconds the plugin holds the screen (1–300) | + +The full schema lives in [`config_schema.json`](config_schema.json) and is +what the web UI's form is generated from. -## Examples +### Examples -### Minimal Configuration +**Minimal:** ```json { "hello-world": { @@ -64,7 +59,7 @@ sudo systemctl restart ledmatrix } ``` -### Custom Message +**Custom message and color:** ```json { "hello-world": { @@ -76,7 +71,7 @@ sudo systemctl restart ledmatrix } ``` -### Message Only (No Time) +**Message only, no time:** ```json { "hello-world": { @@ -88,98 +83,70 @@ sudo systemctl restart ledmatrix } ``` -## Testing the Plugin +## Verifying the plugin loaded -### 1. Check Plugin Discovery +The fastest way is the **Plugin Manager** tab — installed plugins show up +under **Installed Plugins** and a tab for `hello-world` appears in the +plugin row at the top. -After adding the configuration, check the logs: +From SSH you can also tail the display log: ```bash sudo journalctl -u ledmatrix -f | grep hello-world ``` -You should see: -``` -Discovered plugin: hello-world v1.0.0 +You should see something like: + +```text +Discovered plugin: hello-world v1.0.2 Loaded plugin: hello-world Hello World plugin initialized with message: 'Hello, World!' ``` -### 2. Test via Web API +To run the plugin once on demand instead of waiting for it in the +rotation, open its tab in the web UI and click **Run On-Demand**. -Check if the plugin is installed: -```bash -curl http://localhost:5001/api/plugins/installed | jq '.plugins[] | select(.id=="hello-world")' -``` +## Using this as a template -### 3. Watch It Display +Hello World is intentionally tiny so you can read the whole thing in one +sitting. -The plugin will appear in the normal display rotation based on your `display_duration` setting. +- [`manager.py`](manager.py) — `HelloWorldPlugin` class implementing + `update()` and `display()` from `BasePlugin` +- [`manifest.json`](manifest.json) — plugin metadata, entry point, and + class name (must match the class in `manager.py` exactly) +- [`config_schema.json`](config_schema.json) — JSON Schema that drives + the web UI configuration form +- [`requirements.txt`](requirements.txt) — Python dependencies the + plugin loader will install on first run -## Development Notes +To start a new plugin, copy this directory, rename it, update +`manifest.json` (especially `id`, `class_name`, and `entry_point`), and +replace the body of `update()` / `display()`. -This plugin demonstrates: +For deeper details see the LEDMatrix docs: -### BasePlugin Interface -```python -class HelloWorldPlugin(BasePlugin): - def __init__(self, plugin_id, config, display_manager, cache_manager, plugin_manager): - super().__init__(plugin_id, config, display_manager, cache_manager, plugin_manager) - # Initialize your plugin - - def update(self): - # Fetch/update data - pass - - def display(self, force_clear=False): - # Render to display - pass -``` - -### Configuration Validation -```python -def validate_config(self): - # Validate configuration values - return True -``` - -### Error Handling -```python -try: - # Plugin logic -except Exception as e: - self.logger.error(f"Error: {e}", exc_info=True) -``` +- [Plugin Development Guide](https://github.com/ChuckBuilds/LEDMatrix/blob/main/docs/PLUGIN_DEVELOPMENT_GUIDE.md) +- [Plugin API Reference](https://github.com/ChuckBuilds/LEDMatrix/blob/main/docs/PLUGIN_API_REFERENCE.md) +- [Plugin Architecture Spec](https://github.com/ChuckBuilds/LEDMatrix/blob/main/docs/PLUGIN_ARCHITECTURE_SPEC.md) ## Troubleshooting -### Plugin Not Loading -- Check that `manifest.json` is valid JSON -- Verify `enabled: true` in config.json -- Check logs for error messages -- Ensure Python path is correct +**Plugin doesn't appear in the rotation** +- Make sure it's enabled in **Plugin Manager** and that you restarted the + display service afterward. +- Check the **Logs** tab in the web UI (or `journalctl -u ledmatrix`) for + errors mentioning `hello-world`. -### Display Issues -- Verify display_manager is initialized -- Check that colors are valid RGB arrays -- Ensure message isn't too long for display +**`Class HelloWorldPlugin not found in module`** +- The `class_name` field in `manifest.json` must exactly match the class + defined in `manager.py`. They are case-sensitive and must not contain + spaces. -### Configuration Errors -- Validate JSON syntax in config.json -- Check that all color arrays have 3 values (RGB) -- Ensure display_duration is a positive number +**Colors look wrong** +- Each color value must be a 3-element array of integers from `0` to + `255`. The form rejects anything else. ## License -GPL-3.0 License - Same as LEDMatrix project - -## Contributing - -This is a reference plugin included with LEDMatrix. Feel free to use it as a template for your own plugins! - -## Support - -For plugin system questions, see: -- [LEDMatrix Plugin Documentation](https://github.com/ChuckBuilds/LEDMatrix) -- [Plugin Architecture Spec](https://github.com/ChuckBuilds/LEDMatrix/blob/main/PLUGIN_ARCHITECTURE_SPEC.md) - +GPL-3.0, same as the LEDMatrix project. diff --git a/plugins/hello-world/manifest.json b/plugins/hello-world/manifest.json index 7421596..458d07e 100644 --- a/plugins/hello-world/manifest.json +++ b/plugins/hello-world/manifest.json @@ -5,7 +5,7 @@ "author": "ChuckBuilds", "description": "A simple test plugin that displays a customizable message", "entry_point": "manager.py", - "class_name": "HelloWorld Plugin", + "class_name": "HelloWorldPlugin", "category": "demo", "tags": [ "demo", @@ -16,13 +16,18 @@ "hello-world" ], "versions": [ + { + "released": "2026-04-06", + "version": "1.0.2", + "ledmatrix_min_version": "2.0.0" + }, { "released": "2025-10-19", "version": "1.0.1", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" } ], - "last_updated": "2025-10-19", + "last_updated": "2026-04-06", "stars": 0, "downloads": 0, "verified": true, diff --git a/plugins/hockey-scoreboard/README.md b/plugins/hockey-scoreboard/README.md index 42f5a11..6c40258 100644 --- a/plugins/hockey-scoreboard/README.md +++ b/plugins/hockey-scoreboard/README.md @@ -79,7 +79,7 @@ The plugin registers granular display modes directly in `manifest.json`. The dis ### How Rotation Works -The display controller rotates through all registered modes in the order they appear in `manifest.json`. Each mode can have its own `display_duration` configured in the plugin config. +The display controller rotates through all registered modes in the order they appear in `manifest.json`. Each mode's duration is configured under `.display_durations.{base,live,recent,upcoming}` (or the cross-league fallback `defaults.display_duration`). **Default Rotation Order:** 1. `nhl_recent` @@ -241,12 +241,35 @@ Specify team abbreviations for each league: #### Display Settings -- **`prioritize_favorites`**: Show favorite team games first (default: true) -- **`show_shots_on_goal`**: Display SOG statistics (default: false) -- **`show_powerplay`**: Highlight power play situations (default: true) -- **`update_interval`**: Data refresh interval in seconds (15-300, default: 60) -- **`display_duration`**: How long to show each game in seconds (5-60, default: 15) -- **`request_priority`**: Set the request priority from 1 to 5, where 1 is highest (default: 2) +The full set of options lives in +[`config_schema.json`](config_schema.json) — the schema is the source of +truth and is what generates the web UI. The most commonly tweaked keys: + +- **`enabled`** (boolean, default `false`) — master switch for the plugin +- **`defaults.display_duration`** (5–60s, default `15`) — fallback per-game + duration when a league doesn't override it +- **`defaults.show_records`** (boolean, default `false`) — show team + records (W-L) +- **`defaults.show_shots_on_goal`** (boolean, default `false`) — show SOG + during live games +- **`defaults.show_powerplay`** (boolean, default `true`) — highlight power + play situations +- **`defaults.update_interval_seconds`** (30–86400s, default `3600`) — + default base poll interval. Per-league `update_intervals.*` overrides + this. + +Each league (`nhl`, `ncaa_mens`, `ncaa_womens`) then has its own block with +finer-grained controls: + +- `.update_intervals.{base,live,recent,upcoming,odds}` — how often + to poll ESPN for each kind of data. Live games default to 30s; recent + and upcoming default to 3600s. +- `.display_durations.{base,live,recent,upcoming}` — per-mode + display duration overrides for that league. +- `.display_options.{show_records,show_ranking,show_odds,...}` — + per-league overrides of the cross-league defaults. +- `.live_priority` (boolean) — let this league's live games take + over the rotation when one is in progress. ## Display Mode Details @@ -277,12 +300,14 @@ Shows scheduled games for the next X hours with: ### 1. Install Plugin -Install from the Plugin Store in the LEDMatrix Web UI: +Install from the Plugin Store in the LEDMatrix web UI: -1. Go to Plugin Store tab -2. Search for "Hockey Scoreboard" -3. Click Install -4. Configure via Plugin Configuration page +1. Open `http://your-pi-ip:5000` +2. Open the **Plugin Manager** tab +3. Find **Hockey Scoreboard** in the **Plugin Store** section and click + **Install** +4. The plugin appears in **Installed Plugins** above and gets its own tab + in the second nav row — open that tab to configure it ### 2. Configure Leagues @@ -294,12 +319,12 @@ Enable the leagues you want to track: ### 3. Add Favorite Teams -Add your favorite team abbreviations to the `favorite_teams` object for each league. Games involving these teams will be shown first if `prioritize_favorites` is enabled. +Add your favorite team abbreviations to the `favorite_teams` object for each league. Games involving these teams will be shown first when `.live_priority` is enabled. ### 4. Adjust Display Settings -- Set `display_duration` based on how many games you expect (shorter = more games shown) -- Adjust `update_interval` based on desired freshness (60s recommended for live games) +- Set `.display_durations.{base,live,recent,upcoming}` (or the fallback `defaults.display_duration`) based on how many games you expect (shorter = more games shown) +- Adjust `.update_intervals.{base,live,recent,upcoming,odds}` (or the fallback `defaults.update_interval_seconds`) based on desired freshness (30s live poll recommended) - Enable/disable display modes based on preference ### 5. Enable Plugin @@ -316,14 +341,14 @@ Make sure `enabled: true` in the configuration and the plugin is activated in th - Ensure internet connection is working **Games not updating:** -- Check `update_interval` setting +- Check `.update_intervals.*` (or `defaults.update_interval_seconds`) settings - Verify API is responding (check logs) - Try clearing cache: restart plugin or clear cache manually - Check background service is enabled **Favorite teams not showing:** - Verify team abbreviations are correct (case-sensitive) -- Ensure `prioritize_favorites` is true +- Ensure `.live_priority` is true - Check that favorite teams have games in current time window **Logos not displaying:** @@ -336,7 +361,7 @@ Make sure `enabled: true` in the configuration and the plugin is activated in th - Verify ESPN API includes situation data (may not be available for all leagues) **SOG not accurate:** -- Enable `show_shots_on_goal` in config +- Enable `defaults.show_shots_on_goal` (or the per-league override `.display_options.show_shots_on_goal`) in config - ESPN API may have delayed SOG updates - Some leagues may not provide SOG data @@ -372,8 +397,8 @@ The plugin supports fine-tuning element positioning for custom display sizes. Al #### Accessing Layout Settings -Layout customization is available in the web UI under the plugin configuration section: -1. Navigate to **Plugins** → **Hockey Scoreboard** → **Configuration** +Layout customization is available in the plugin's tab in the web UI: +1. Open the **Hockey Scoreboard** tab (second nav row) 2. Expand the **Customization** section 3. Find the **Layout Positioning** subsection @@ -475,16 +500,26 @@ This plugin uses the **ESPN public API** for all hockey data: "favorite_teams": { "nhl": ["TB", "TOR", "BOS"] }, + "defaults": { + "update_interval_seconds": 60, + "display_duration": 15 + }, "nhl": { "enabled": true, "display_modes": { "live": true, "recent": true, "upcoming": false + }, + "update_intervals": { + "base": 60, + "live": 30 + }, + "display_durations": { + "base": 15, + "live": 20 } - }, - "update_interval": 60, - "display_duration": 15 + } } ``` @@ -507,10 +542,12 @@ This plugin uses the **ESPN public API** for all hockey data: "live": true, "recent": true, "upcoming": true - } - }, - "upcoming_games_hours": 168, - "update_interval": 120 + }, + "update_intervals": { + "base": 120 + }, + "upcoming_games_hours": 168 + } } ``` @@ -529,11 +566,13 @@ This plugin uses the **ESPN public API** for all hockey data: "ncaa_mens": ["MICH"], "ncaa_womens": ["WISC"] }, - "prioritize_favorites": true, - "show_shots_on_goal": true, - "show_powerplay": true, + "defaults": { + "show_shots_on_goal": true, + "show_powerplay": true + }, "nhl": { "enabled": true, + "live_priority": true, "display_modes": { "live": true, "recent": true, @@ -591,9 +630,12 @@ Uses LEDMatrix's `BackgroundDataService` for: ### Resource Usage - **CPU**: Low (background fetching, cached data) -- **Memory**: ~5-10MB for game data -- **Network**: ~1-5 KB per API call per league -- **API Calls**: 3 leagues × 12 calls/hour = 36 calls/hour (max) +- **Memory**: ~5–10 MB for game data +- **Network**: ~1–5 KB per API call per league +- **API calls**: depends on how many leagues are enabled and which + `update_intervals` you set. With defaults (NHL only, base 60s, live 30s, + recent/upcoming 3600s) and no live games, expect about one ESPN call per + minute per enabled league. ### Optimization Tips @@ -609,13 +651,13 @@ GPL-3.0 License - see main LEDMatrix repository for details. ## Support - **Issues**: [GitHub Issues](https://github.com/ChuckBuilds/ledmatrix-plugins/issues) -- **Documentation**: [LEDMatrix Wiki](https://github.com/ChuckBuilds/LEDMatrix/wiki) +- **Documentation**: see the LEDMatrix + [`docs/`](https://github.com/ChuckBuilds/LEDMatrix/tree/main/docs) directory - **Community**: [Discussions](https://github.com/ChuckBuilds/LEDMatrix/discussions) --- -**Version**: 1.0.0 -**Author**: ChuckBuilds -**Category**: Sports -**Tags**: hockey, nhl, ncaa, sports, scoreboard, live-scores +For the current version, author, category and tags see +[`manifest.json`](manifest.json) — that's the source of truth and is +what the Plugin Store reads. diff --git a/plugins/hockey-scoreboard/manifest.json b/plugins/hockey-scoreboard/manifest.json index ab22236..13f42f3 100644 --- a/plugins/hockey-scoreboard/manifest.json +++ b/plugins/hockey-scoreboard/manifest.json @@ -20,7 +20,6 @@ "compatible_versions": [ ">=2.0.0" ], - "ledmatrix_version": "2.0.0", "requires": { "python": ">=3.9", "display_size": { @@ -58,80 +57,80 @@ { "released": "2026-03-02", "version": "1.2.4", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2026-02-24", "version": "1.2.3", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "version": "1.2.2", - "ledmatrix_min": "2.0.0", - "released": "2026-02-24" + "released": "2026-02-24", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.2.1", - "ledmatrix_min": "2.0.0", - "released": "2026-02-24" + "released": "2026-02-24", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.2.0", - "ledmatrix_min": "2.0.0", - "released": "2026-02-24" + "released": "2026-02-24", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.1.1", - "ledmatrix_min": "2.0.0", - "released": "2026-02-15" + "released": "2026-02-15", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.1.0", - "ledmatrix_min": "2.0.0", - "released": "2026-02-14" + "released": "2026-02-14", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.0.8", - "ledmatrix_min": "2.0.0", - "released": "2025-11-06" + "released": "2025-11-06", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.0.7", - "ledmatrix_min": "2.0.0", - "released": "2025-11-06" + "released": "2025-11-06", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.0.6", - "ledmatrix_min": "2.0.0", - "released": "2025-11-05" + "released": "2025-11-05", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.0.5", - "ledmatrix_min": "2.0.0", - "released": "2025-11-05" + "released": "2025-11-05", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.0.4", - "ledmatrix_min": "2.0.0", - "released": "2025-11-05" + "released": "2025-11-05", + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-26", "version": "1.0.3", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-22", "version": "1.0.2", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-22", "version": "1.0.1", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" } ], - "last_updated": "2026-02-24", + "last_updated": "2026-03-02", "stars": 0, "downloads": 0, "verified": true, diff --git a/plugins/lacrosse-scoreboard/README.md b/plugins/lacrosse-scoreboard/README.md index 335e3b4..3ca4f63 100644 --- a/plugins/lacrosse-scoreboard/README.md +++ b/plugins/lacrosse-scoreboard/README.md @@ -2,6 +2,18 @@ Live, recent, and upcoming NCAA Men's and Women's Lacrosse games on your LEDMatrix display. Real-time scores, schedules, favorite-team filtering, live-game priority, poll-rank badges, and both switch and scroll display modes — modeled on the existing hockey scoreboard plugin. +> ⚠️ **Known conflict with `hockey-scoreboard`.** This plugin's display +> modes are named `ncaa_mens_recent` / `ncaa_mens_upcoming` / +> `ncaa_mens_live` / `ncaa_womens_recent` / `ncaa_womens_upcoming` / +> `ncaa_womens_live` — the **same names** the hockey scoreboard plugin +> uses for its NCAA hockey divisions. The display controller stores +> modes in a flat dict keyed by mode name +> (`src/display_controller.py:295`), so if you install both plugins, +> whichever loads second silently overrides the first one's NCAA modes. +> Track the issue at the LEDMatrix repo. Until it's fixed in a +> version-bumped release that renames lacrosse's modes (e.g. +> `lax_ncaa_mens_*`), enable only one of the two plugins at a time. + ## Features - **NCAA Men's Lacrosse** (Inside Lacrosse D1 Poll — top 20) @@ -27,17 +39,29 @@ No API key is required. ## Installation -The plugin is installable from the LEDMatrix plugin store — search for **Lacrosse Scoreboard** and enable it. On first launch, team logos for any teams appearing in the current scoreboard window will be downloaded to `assets/sports/ncaa_logos/` automatically. +The easiest way is the Plugin Store in the LEDMatrix web UI: + +1. Open `http://your-pi-ip:5000` +2. Open the **Plugin Manager** tab +3. Find **Lacrosse Scoreboard** in the **Plugin Store** section and click + **Install** +4. Open the plugin's tab in the second nav row to configure favorite + teams + +On first launch, team logos for any teams in the current scoreboard +window will be downloaded to `assets/sports/ncaa_logos/` automatically. -To install manually from source: +Manual install from source: ```bash cd /path/to/LEDMatrix python -m pip install --user pillow requests pytz # see requirements.txt -cp -r /path/to/ledmatrix-plugins/plugins/lacrosse-scoreboard plugins/ +cp -r /path/to/ledmatrix-plugins/plugins/lacrosse-scoreboard plugin-repos/ +sudo systemctl restart ledmatrix ``` -Then add a `lacrosse-scoreboard` entry to your LEDMatrix `config.json` (see **Configuration** below) and restart the LEDMatrix service. +Then add a `lacrosse-scoreboard` entry to your LEDMatrix `config.json` +(see **Configuration** below) — or just use the web UI to configure it. ## Dependencies diff --git a/plugins/lacrosse-scoreboard/manifest.json b/plugins/lacrosse-scoreboard/manifest.json index 803caff..60bb5f3 100644 --- a/plugins/lacrosse-scoreboard/manifest.json +++ b/plugins/lacrosse-scoreboard/manifest.json @@ -19,7 +19,6 @@ "compatible_versions": [ ">=2.0.0" ], - "ledmatrix_version": "2.0.0", "requires": { "python": ">=3.9", "display_size": { @@ -53,18 +52,18 @@ "versions": [ { "version": "1.0.3", - "ledmatrix_min": "2.0.0", - "released": "2026-04-06" + "released": "2026-04-06", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.0.2", - "ledmatrix_min": "2.0.0", - "released": "2026-04-06" + "released": "2026-04-06", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.0.1", - "ledmatrix_min": "2.0.0", - "released": "2026-04-06" + "released": "2026-04-06", + "ledmatrix_min_version": "2.0.0" } ], "last_updated": "2026-04-06", diff --git a/plugins/ledmatrix-flights/LICENSE b/plugins/ledmatrix-flights/LICENSE new file mode 100644 index 0000000..e653a0c --- /dev/null +++ b/plugins/ledmatrix-flights/LICENSE @@ -0,0 +1,17 @@ +GNU GENERAL PUBLIC LICENSE +Version 3, 29 June 2007 + +Copyright (C) 2025 LEDMatrix Team + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . diff --git a/plugins/ledmatrix-flights/README.md b/plugins/ledmatrix-flights/README.md index 06229cf..29f235f 100644 --- a/plugins/ledmatrix-flights/README.md +++ b/plugins/ledmatrix-flights/README.md @@ -35,8 +35,9 @@ Real-time aircraft tracking plugin for LEDMatrix with ADS-B data, map background ### From Plugin Store (Recommended) 1. Open the LEDMatrix web interface (`http://your-pi-ip:5000`) -2. Go to **Plugin Store** -3. Find **Flight Tracker** and click **Install** +2. Open the **Plugin Manager** tab +3. Find **Flight Tracker** in the **Plugin Store** section and click + **Install** ### Manual Installation diff --git a/plugins/ledmatrix-flights/manifest.json b/plugins/ledmatrix-flights/manifest.json index 51f841b..e40d96f 100644 --- a/plugins/ledmatrix-flights/manifest.json +++ b/plugins/ledmatrix-flights/manifest.json @@ -1,56 +1,55 @@ { - "id": "ledmatrix-flights", - "name": "Flight Tracker", - "version": "1.3.0", - "description": "Real-time aircraft tracking with ADS-B/FlightRadar24/OpenSky data, map backgrounds, area mode, flight tracking, anchor airport, and flight records", - "author": "ChuckBuilds", - "entry_point": "manager.py", - "class_name": "FlightTrackerPlugin", - "api_version": "1.0.0", - "display_modes": [ - "flight_tracker" - ], - "update_interval": 5, - "dependencies": [ - "requests", - "pillow" - ], - "config_schema": "config_schema.json", - "requirements_file": "requirements.txt", - "tags": [ - "flight", - "aircraft", - "ads-b", - "skyaware", - "aviation", - "map" - ], - "homepage": "https://github.com/ChuckBuilds/ledmatrix-plugins/tree/main/plugins/ledmatrix-flights", - "website": "https://github.com/ChuckBuilds/ledmatrix-plugins/tree/main/plugins/ledmatrix-flights", - "license": "MIT", - "compatible_versions": [ - ">=2.0.0" - ], - "ledmatrix_version": "2.0.0", - "min_ledmatrix_version": "2.0.0", - "max_ledmatrix_version": "3.0.0", - "versions": [ - { - "released": "2026-03-30", - "version": "1.3.0", - "ledmatrix_min": "2.0.0" - }, - { - "version": "1.2.0", - "ledmatrix_min": "2.0.0", - "released": "2026-03-29", - "notes": "FlightWall enhancements: area mode, flight tracking, OpenSky, airline logos, animated radar" - }, - { - "version": "1.1.0", - "ledmatrix_min": "2.0.0", - "released": "2026-02-24" - } - ], - "last_updated": "2026-03-30" + "id": "ledmatrix-flights", + "name": "Flight Tracker", + "version": "1.3.0", + "description": "Real-time aircraft tracking with ADS-B/FlightRadar24/OpenSky data, map backgrounds, area mode, flight tracking, anchor airport, and flight records", + "author": "ChuckBuilds", + "entry_point": "manager.py", + "class_name": "FlightTrackerPlugin", + "api_version": "1.0.0", + "display_modes": [ + "flight_tracker" + ], + "update_interval": 5, + "dependencies": [ + "requests", + "pillow" + ], + "config_schema": "config_schema.json", + "requirements_file": "requirements.txt", + "tags": [ + "flight", + "aircraft", + "ads-b", + "skyaware", + "aviation", + "map" + ], + "homepage": "https://github.com/ChuckBuilds/ledmatrix-plugins/tree/main/plugins/ledmatrix-flights", + "website": "https://github.com/ChuckBuilds/ledmatrix-plugins/tree/main/plugins/ledmatrix-flights", + "license": "MIT", + "compatible_versions": [ + ">=2.0.0" + ], + "min_ledmatrix_version": "2.0.0", + "max_ledmatrix_version": "3.0.0", + "versions": [ + { + "released": "2026-03-30", + "version": "1.3.0", + "ledmatrix_min_version": "2.0.0" + }, + { + "version": "1.2.0", + "released": "2026-03-29", + "notes": "FlightWall enhancements: area mode, flight tracking, OpenSky, airline logos, animated radar", + "ledmatrix_min_version": "2.0.0" + }, + { + "version": "1.1.0", + "released": "2026-02-24", + "ledmatrix_min_version": "2.0.0" + } + ], + "last_updated": "2026-03-30" } diff --git a/plugins/ledmatrix-leaderboard/README.md b/plugins/ledmatrix-leaderboard/README.md index 90b264d..74dfe28 100644 --- a/plugins/ledmatrix-leaderboard/README.md +++ b/plugins/ledmatrix-leaderboard/README.md @@ -183,10 +183,18 @@ This plugin requires the main LEDMatrix installation and uses the cache manager ## Installation -1. Copy this plugin directory to your `ledmatrix-plugins/plugins/` folder -2. Ensure the plugin is enabled in your LEDMatrix configuration -3. Configure your preferred leagues and display options -4. Restart LEDMatrix to load the new plugin +The easiest way is the Plugin Store in the LEDMatrix web UI: + +1. Open `http://your-pi-ip:5000` +2. Open the **Plugin Manager** tab +3. Find **Sports Leaderboard** in the **Plugin Store** section and click + **Install** +4. Open the plugin's tab in the second nav row to configure leagues and + display options + +Manual install: copy this directory into your LEDMatrix +`plugins_directory` (default `plugin-repos/`) and restart the display +service. ## Troubleshooting diff --git a/plugins/ledmatrix-leaderboard/manifest.json b/plugins/ledmatrix-leaderboard/manifest.json index 73a378c..42f6c76 100644 --- a/plugins/ledmatrix-leaderboard/manifest.json +++ b/plugins/ledmatrix-leaderboard/manifest.json @@ -33,29 +33,32 @@ "versions": [ { "version": "1.2.0", - "ledmatrix_min": "2.0.0", - "released": "2026-04-03" + "released": "2026-04-03", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.1.0", - "ledmatrix_min": "2.0.0", - "released": "2026-02-17" + "released": "2026-02-17", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.0.6", - "ledmatrix_min": "2.0.0", - "released": "2026-02-12" + "released": "2026-02-12", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.0.5", - "ledmatrix_min": "2.0.0", - "released": "2025-11-06" + "released": "2025-11-06", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.0.4", - "ledmatrix_min": "2.0.0", - "released": "2025-11-06" + "released": "2025-11-06", + "ledmatrix_min_version": "2.0.0" } ], - "last_updated": "2026-02-17" + "last_updated": "2026-04-03", + "compatible_versions": [ + ">=2.0.0" + ] } diff --git a/plugins/ledmatrix-music/README.md b/plugins/ledmatrix-music/README.md index a837e2b..dc6073d 100644 --- a/plugins/ledmatrix-music/README.md +++ b/plugins/ledmatrix-music/README.md @@ -66,14 +66,19 @@ Use Web Ui to configure Add to `config/config_secrets.json`: ```json { - "music": { - "SPOTIFY_CLIENT_ID": "your_client_id_here", - "SPOTIFY_CLIENT_SECRET": "your_client_secret_here", - "SPOTIFY_REDIRECT_URI": "http://localhost:8080/callback" + "ledmatrix-music": { + "spotify_client_id": "your_client_id_here", + "spotify_client_secret": "your_client_secret_here", + "spotify_redirect_uri": "http://localhost:8080/callback" } } ``` + > Older configs that put these under a `"music"` key with + > `SPOTIFY_CLIENT_ID` (uppercase) still work — `spotify_client.py` + > falls back to that legacy form — but new installs should use the + > `"ledmatrix-music"` key with lowercase names shown above. + 3. **Run Authentication**: ```bash cd plugins/ledmatrix-music diff --git a/plugins/ledmatrix-music/manifest.json b/plugins/ledmatrix-music/manifest.json index 0469a29..fbde4e6 100644 --- a/plugins/ledmatrix-music/manifest.json +++ b/plugins/ledmatrix-music/manifest.json @@ -32,7 +32,6 @@ "compatible_versions": [ ">=2.0.0" ], - "ledmatrix_version": "2.0.0", "min_ledmatrix_version": "2.0.0", "max_ledmatrix_version": "3.0.0", "web_ui_actions": [ @@ -69,23 +68,23 @@ "versions": [ { "version": "1.0.5", - "ledmatrix_min": "2.0.0", - "released": "2026-03-21" + "released": "2026-03-21", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.0.4", - "ledmatrix_min": "2.0.0", - "released": "2026-03-01" + "released": "2026-03-01", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.0.3", - "ledmatrix_min": "2.0.0", - "released": "2025-11-05" + "released": "2025-11-05", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.0.0", - "ledmatrix_min": "2.0.0", - "released": "2025-01-16" + "released": "2025-01-16", + "ledmatrix_min_version": "2.0.0" } ], "last_updated": "2026-03-21", diff --git a/plugins/ledmatrix-stocks/LICENSE b/plugins/ledmatrix-stocks/LICENSE new file mode 100644 index 0000000..e653a0c --- /dev/null +++ b/plugins/ledmatrix-stocks/LICENSE @@ -0,0 +1,17 @@ +GNU GENERAL PUBLIC LICENSE +Version 3, 29 June 2007 + +Copyright (C) 2025 LEDMatrix Team + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . diff --git a/plugins/ledmatrix-stocks/README.md b/plugins/ledmatrix-stocks/README.md index 652a096..f2bb2e8 100644 --- a/plugins/ledmatrix-stocks/README.md +++ b/plugins/ledmatrix-stocks/README.md @@ -1,215 +1,111 @@ ------------------------------------------------------------------------------------ -### Connect with ChuckBuilds +# Stock & Crypto Ticker Plugin -- Show support on Youtube: https://www.youtube.com/@ChuckBuilds -- Stay in touch on Instagram: https://www.instagram.com/ChuckBuilds/ -- Want to chat or need support? Reach out on the ChuckBuilds Discord: https://discord.com/invite/uW36dVAtcT -- Feeling Generous? Support the project: - - Github Sponsorship: https://github.com/sponsors/ChuckBuilds - - Buy Me a Coffee: https://buymeacoffee.com/chuckbuilds - - Ko-fi: https://ko-fi.com/chuckbuilds/ - ------------------------------------------------------------------------------------ - -# Stocks Ticker Plugin - -A plugin for LEDMatrix that displays scrolling stock tickers with prices, changes, and optional charts for stocks and cryptocurrencies. +A scrolling ticker for the LEDMatrix display showing live stock and +cryptocurrency prices, percent changes, and optional inline price charts. +Data comes from Yahoo Finance — no API key required. ## Features -- **Stock Price Tracking**: Real-time stock prices and changes -- **Cryptocurrency Support**: Bitcoin, Ethereum, and other crypto prices -- **Change Indicators**: Color-coded positive/negative changes -- **Percentage Display**: Show percentage changes alongside dollar amounts -- **Optional Charts**: Toggle chart display for visual price trends -- **Market Data**: Volume and market cap information -- **Configurable Display**: Adjustable scroll speed, colors, and timing -- **Background Data Fetching**: Efficient API calls without blocking display - -## Configuration - -### Global Settings - -- `display_duration`: How long to show the ticker (10-300 seconds, default: 30) -- `scroll_speed`: Scrolling speed multiplier (0.5-5, default: 1) -- `scroll_delay`: Delay between scroll steps (0.001-0.1 seconds, default: 0.01) -- `dynamic_duration`: Enable dynamic duration based on content width (default: true) -- `min_duration`: Minimum display duration (10-300 seconds, default: 30) -- `max_duration`: Maximum display duration (30-600 seconds, default: 300) -- `toggle_chart`: Enable chart display toggle (default: false) -- `font_size`: Font size for stock information (8-16, default: 10) - -### Stock Settings - -#### Stock Symbols - -```json -{ - "stocks": { - "stock_symbols": ["AAPL", "GOOGL", "MSFT", "TSLA", "AMZN", "META"] - } -} -``` +- Live stock and crypto prices via Yahoo Finance (no API key) +- Color-coded gain/loss with positive/negative colors +- Optional inline mini chart per symbol (`display.toggle_chart`) +- Two display modes: continuous scroll, or one symbol at a time +- Independent stock and crypto symbol lists +- Per-element font and color customization -#### Display Options - -```json -{ - "stocks": { - "show_change": true, - "show_percentage": true, - "show_volume": false, - "show_market_cap": false, - "text_color": [255, 255, 255], - "positive_color": [0, 255, 0], - "negative_color": [255, 0, 0] - } -} -``` - -### Cryptocurrency Settings +## Installation -#### Enable Crypto Tracking +1. Open the LEDMatrix web interface (`http://your-pi-ip:5000`) +2. Open the **Plugin Manager** tab +3. Find **Stock Ticker** in the **Plugin Store** section and click + **Install** +4. Open the plugin's tab in the second nav row to configure it -```json -{ - "crypto": { - "enabled": true, - "crypto_symbols": ["BTC", "ETH", "ADA", "SOL", "DOT"] - } -} -``` +## Configuration -#### Crypto Display Options +The full schema lives in +[`config_schema.json`](config_schema.json) — what you see in the web UI is +generated from it. The most-used keys, with their actual nesting: -```json -{ - "crypto": { - "show_change": true, - "show_percentage": true, - "text_color": [255, 215, 0], - "positive_color": [0, 255, 0], - "negative_color": [255, 0, 0] - } -} -``` +### Top level -## Display Format +| Key | Default | Notes | +|---|---|---| +| `enabled` | `false` | Master switch | +| `update_interval` | `600` | Seconds between Yahoo Finance fetches for stocks | -The stocks ticker displays information in a scrolling format showing: +### `display.*` — how the ticker scrolls -- **Symbol**: Stock/crypto ticker symbol -- **Price**: Current price (e.g., "$150.25") -- **Change**: Dollar change with color coding (green for positive, red for negative) -- **Percentage**: Percentage change (e.g., "+2.5%") -- **Additional Info**: Volume and market cap (if enabled) +| Key | Default | Notes | +|---|---|---| +| `display.display_mode` | `"scroll"` | `"scroll"` or `"switch"` | +| `display.switch_duration` | `15` | Seconds per symbol in switch mode | +| `display.scroll_speed` | `1.0` | Scroll speed multiplier | +| `display.scroll_delay` | `0.02` | Per-step delay (smaller = smoother but more CPU) | +| `display.toggle_chart` | `true` | Show an inline mini-chart per symbol | +| `display.dynamic_duration` | `true` | Let the controller pick a duration based on content width | +| `display.min_duration` | `30` | Floor for dynamic duration (seconds) | +| `display.max_duration` | `300` | Ceiling for dynamic duration (seconds) | +| `display.duration_buffer` | `0.1` | Padding factor on dynamic duration | +| `display.stock_gap` | `32` | Pixels of space between symbols | -## Stock Symbol Format +### `stocks.*` -Stock symbols should be in uppercase format: +| Key | Default | Notes | +|---|---|---| +| `stocks.enabled` | `true` | Enable the stocks list | +| `stocks.symbols` | `["ASTS","SCHD","INTC","NVDA","T","VOO","SMCI"]` | Yahoo Finance ticker symbols | +| `stocks.display_format` | `"{symbol}: ${price} ({change}%)"` | Placeholders: `{symbol}`, `{price}`, `{change}` | -- **AAPL**: Apple Inc. -- **GOOGL**: Alphabet Inc. -- **MSFT**: Microsoft Corporation -- **TSLA**: Tesla Inc. -- **AMZN**: Amazon.com Inc. -- **META**: Meta Platforms Inc. -- **NFLX**: Netflix Inc. +### `crypto.*` -## Cryptocurrency Symbols +| Key | Default | Notes | +|---|---|---| +| `crypto.enabled` | `false` | Enable the crypto list | +| `crypto.update_interval` | `600` | Seconds between crypto fetches | +| `crypto.symbols` | `["BTC-USD","ETH-USD"]` | Yahoo Finance pair symbols (always end in `-USD` etc.) | +| `crypto.display_format` | `"{symbol}: ${price} ({change}%)"` | Same placeholders as stocks | -Common cryptocurrency symbols: +### `customization.*` -- **BTC**: Bitcoin -- **ETH**: Ethereum -- **ADA**: Cardano -- **SOL**: Solana -- **DOT**: Polkadot -- **AVAX**: Avalanche -- **MATIC**: Polygon -- **LINK**: Chainlink - -## Background Service - -The plugin uses background data fetching for efficient API calls: - -- Requests timeout after 30 seconds (configurable) -- Up to 5 retries for failed requests -- Priority level 2 (medium priority) -- Updates every minute by default (configurable) +Per-element font, size, and color overrides for stocks and crypto. Each +of `symbol`, `price`, and `price_delta` has its own `font`, `font_size`, +and color settings. Defaults use `PressStart2P-Regular.ttf` at size 8, +with green for positive deltas and red for negative. -## Data Sources +## Symbol format -The plugin can fetch from: - -1. **Financial APIs**: Stock and crypto price data (requires API keys in practice) -2. **Market Data Feeds**: Real-time market information -3. **Placeholder Data**: Mock data for demonstration (current implementation) - -## Dependencies +The plugin uses Yahoo Finance symbols directly: -This plugin requires the main LEDMatrix installation and uses the cache manager for data storage. +- **Stocks**: plain ticker, e.g. `AAPL`, `GOOGL`, `MSFT`, `TSLA`, + `AMZN`, `META`, `NVDA` +- **Crypto**: pair with the quote currency, e.g. `BTC-USD`, `ETH-USD`, + `SOL-USD`, `DOGE-USD`. Without the `-USD` suffix Yahoo returns no data. -## Installation +## Pairing with the Stock News plugin -1. Copy this plugin directory to your `ledmatrix-plugins/plugins/` folder -2. Ensure the plugin is enabled in your LEDMatrix configuration -3. Configure your stock symbols and display preferences -4. Restart LEDMatrix to load the new plugin +This plugin pairs naturally with the [`stock-news`](../stock-news/) +plugin: prices on one rotation slot, related headlines on another. ## Troubleshooting -- **No data showing**: Check if symbols are valid and APIs are accessible -- **API errors**: Verify API keys and rate limits (for real implementations) -- **Slow scrolling**: Adjust scroll speed and delay settings -- **Network errors**: Check your internet connection and API availability - -## Advanced Features - -- **Chart Toggle**: Option to display price charts alongside tickers -- **Color Coding**: Visual indicators for price movements -- **Volume Display**: Show trading volume information -- **Market Cap**: Display market capitalization -- **Dual Mode**: Separate display modes for stocks and crypto - -## Integration Notes - -This plugin is designed to work alongside the stock-news plugin for comprehensive financial display: - -- **Stocks Plugin**: Price tickers and market data -- **Stock News Plugin**: Financial headlines and updates -- **Combined Use**: Show tickers while news scrolls in background - -## Performance Notes - -- The plugin is designed to be lightweight and not impact display performance -- Price data fetching happens in background to avoid blocking -- Configurable update intervals balance freshness vs. API load -- Caching reduces unnecessary network requests - -## Chart Display (Future Feature) - -When chart toggle is enabled, the plugin can display: - -- **Price Charts**: Simple line charts showing price trends -- **Candlestick Charts**: OHLC candlestick representations -- **Volume Bars**: Trading volume visualization -- **Time Periods**: Multiple timeframe options - -## API Integration (Future Implementation) +**No data showing** +- Confirm the symbols are valid on + [finance.yahoo.com](https://finance.yahoo.com) — typos return empty data. +- Check the **Logs** tab for HTTP errors. Yahoo occasionally rate-limits; + raising `update_interval` usually fixes it. -For production use, this plugin would integrate with: +**Scroll feels choppy** +- Lower `display.scroll_delay` (default 0.02) toward 0.01 for smoother + motion at the cost of CPU. +- Or switch `display.display_mode` to `"switch"` to step through one + symbol at a time instead of scrolling. -- **Alpha Vantage API**: Stock and forex data -- **CoinGecko API**: Cryptocurrency data -- **Yahoo Finance API**: Financial market data -- **Twelve Data API**: Real-time and historical data +**Chart isn't drawing** +- Set `display.toggle_chart` to `true`. +- Charts need enough horizontal room next to each symbol. On a 64×32 + panel they may be cropped — try a wider chain. -## Example Display +## License -``` -AAPL: $150.25 +2.50 (+1.7%) -GOOGL: $2750.80 -15.20 (-0.5%) -BTC: $43250.00 +1250.00 (+3.0%) -ETH: $2850.75 -75.25 (-2.6%) -``` +GPL-3.0, same as the LEDMatrix project. diff --git a/plugins/ledmatrix-stocks/manifest.json b/plugins/ledmatrix-stocks/manifest.json index 405e8c2..ac24122 100644 --- a/plugins/ledmatrix-stocks/manifest.json +++ b/plugins/ledmatrix-stocks/manifest.json @@ -41,31 +41,31 @@ "versions": [ { "version": "2.2.0", - "ledmatrix_min": "2.0.0", - "released": "2026-03-31" + "released": "2026-03-31", + "ledmatrix_min_version": "2.0.0" }, { "version": "2.1.0", - "ledmatrix_min": "2.0.0", - "released": "2026-03-04" + "released": "2026-03-04", + "ledmatrix_min_version": "2.0.0" }, { "version": "2.0.3", - "ledmatrix_min": "2.0.0", - "released": "2026-03-02" + "released": "2026-03-02", + "ledmatrix_min_version": "2.0.0" }, { "version": "2.0.2", - "ledmatrix_min": "2.0.0", - "released": "2026-02-12" + "released": "2026-02-12", + "ledmatrix_min_version": "2.0.0" }, { "version": "2.0.1", - "ledmatrix_min": "2.0.0", - "released": "2026-02-11" + "released": "2026-02-11", + "ledmatrix_min_version": "2.0.0" } ], - "last_updated": "2026-03-04", + "last_updated": "2026-03-31", "stars": 0, "downloads": 0, "verified": true, diff --git a/plugins/ledmatrix-weather/README.md b/plugins/ledmatrix-weather/README.md index 490c728..358d09b 100644 --- a/plugins/ledmatrix-weather/README.md +++ b/plugins/ledmatrix-weather/README.md @@ -31,60 +31,88 @@ Daily Forecast: ## Features -- **Current Weather**: Temperature, conditions, humidity, wind speed -- **Hourly Forecast**: Next 24-48 hours of weather data -- **Daily Forecast**: 7-day forecast with high/low temperatures -- **Weather Icons**: Beautiful icons matching current conditions -- **UV Index**: UV radiation levels for sun safety -- **Automatic Updates**: Configurable update intervals -- **Error Handling**: Robust retry logic and error recovery +- **Current conditions**: temperature, conditions icon, humidity, wind, + feels-like, dew point, visibility, pressure (extra metrics need height ≥48px) +- **Hourly forecast**: next 24 hours +- **Daily forecast**: 3–7 day high/low +- **Almanac**: sunrise/sunset, moon phase, day length +- **Precipitation radar**: live RainViewer imagery — no API key required for this part +- **Weather alerts**: when active, takes priority in the rotation ## Requirements -- OpenWeatherMap API key (free tier available) -- Internet connection for API access -- Display size: minimum 64x32 pixels recommended +- A **One Call API 3.0** subscription from OpenWeatherMap (free tier + available) — see API Key below +- Internet connection for OpenWeatherMap and RainViewer +- Display size: 64x32 minimum; 64x48 or larger to see the extra current- + conditions metrics ## Configuration ### API Key -This plugin requires a **One Call API 3.0** subscription from [OpenWeatherMap](https://openweathermap.org/api) (free tier: 1,000 calls/day): - -1. Sign up for an account at https://openweathermap.org -2. Navigate to API Keys section and generate a new API key -3. **Subscribe to One Call API 3.0** — this is a separate step from getting an API key: - - Go to https://openweathermap.org/api - - Find "One Call API 3.0" and click Subscribe - - The free tier requires adding payment info but will not charge you - - A standard API key alone will **not** work; you must subscribe to One Call 3.0 -4. Add the API key to your plugin configuration - - -### Configuration Options - -- `enabled`: Enable/disable the plugin -- `api_key`: Your OpenWeatherMap API key (required) -- `location`: City, state, and country for weather data -- `units`: Temperature units (`imperial` for Fahrenheit, `metric` for Celsius) -- `update_interval`: Seconds between API updates (minimum 300, recommended 1800) -- `display_modes`: Enable/disable specific display modes -- `display_duration`: Seconds to display each mode - -## Display Modes - -### weather -Shows current conditions with temperature, condition text, and humidity. - -### hourly_forecast -Displays next 4-24 hours of forecasted weather with temperatures. - -### daily_forecast -Shows 3-7 day forecast with daily high/low temperatures. +This plugin requires the **One Call API 3.0** product from OpenWeatherMap. +A standard OpenWeatherMap API key on its own will **not** work — One Call 3.0 +is a separate subscription you must enable on your account. + +1. Sign up at https://openweathermap.org +2. Generate an API key under **API Keys** +3. Go to https://openweathermap.org/api, find **One Call API 3.0**, click + **Subscribe**. The free tier requires entering payment info but does not + charge you below 1,000 calls/day. +4. Open the **Weather** tab in the LEDMatrix web UI (or edit + `config/config_secrets.json`) and paste the key into `api_key`. + +### Configuration options + +The plugin's full schema lives in +[`config_schema.json`](config_schema.json) — what you see in the web UI is +generated from it. The keys you'll touch most often: + +| Key | Default | Notes | +|---|---|---| +| `enabled` | `false` | Master switch | +| `api_key` | _required_ | One Call 3.0 key (store in `config_secrets.json`) | +| `location_city` | `"Dallas"` | City name | +| `location_state` | `"Texas"` | State/province (optional, helps US disambiguation) | +| `location_country` | `"US"` | ISO 3166-1 alpha-2 code | +| `units` | `"imperial"` | `"imperial"` (°F) or `"metric"` (°C) | +| `display_duration` | `30` | Seconds per mode (5–300) | +| `update_interval` | `1800` | Seconds between OpenWeatherMap fetches (min 300) | +| `display_format` | `"{temp}°F\n{condition}"` | Placeholders: `{temp}`, `{condition}`, `{humidity}`, `{wind}` | +| `show_current_weather` | `true` | Toggle current conditions mode | +| `show_hourly_forecast` | `true` | Toggle hourly mode | +| `show_daily_forecast` | `true` | Toggle daily mode | +| `show_almanac` | `true` | Toggle almanac mode (sun/moon) | +| `show_radar` | `true` | Toggle precipitation radar mode | +| `show_alerts` | `true` | Show active weather alerts (preempts rotation) | +| `show_feels_like` / `show_dew_point` / `show_visibility` / `show_pressure` | `true` | Extra current-conditions metrics (need height ≥ 48px) | +| `radar_zoom` | `6` | 4 (regional) to 8 (very close) | +| `radar_line_color` | `[0, 130, 70]` | RGB for state outlines | +| `radar_fill_color` | `[15, 25, 15]` | RGB for land fill (`[0,0,0]` = outlines only) | +| `radar_update_interval` | `600` | RainViewer refresh seconds (300–1800) | + +## Display modes + +The plugin registers these modes in `manifest.json` and the display +controller rotates through them in order: + +| Mode | Description | +|---|---| +| `weather` | Current conditions: temperature, icon, humidity, wind, plus optional feels-like / dew point / visibility / pressure on taller displays | +| `hourly_forecast` | Next ~24 hours | +| `daily_forecast` | 3–7 day high/low forecast | +| `almanac` | Sunrise, sunset, moon phase, day length | +| `radar` | Live precipitation radar from RainViewer | + +When an active weather alert is available and `show_alerts` is true, the +alert takes priority over the normal rotation. ## Usage -The plugin automatically rotates through enabled display modes based on the `display_duration` setting. +The plugin auto-rotates through enabled display modes based on +`display_duration`. Toggle individual modes on or off with the +`show_*` keys above (or the matching toggles in the web UI). ## Troubleshooting @@ -100,13 +128,18 @@ The plugin automatically rotates through enabled display modes based on the `dis - API has rate limits, respect the minimum update interval - Free tier allows 1000 calls/day -## API Rate Limits +## API rate limits -OpenWeatherMap free tier provides: -- 1,000 API calls per day +OpenWeatherMap One Call 3.0 free tier: +- 1,000 calls per day - 60 calls per minute -With default settings (1800s = 30 min intervals), this plugin uses ~48 calls per day. +With the default `update_interval` of 1800s (30 minutes), this plugin +makes about 48 calls per day. Lower the interval if you want fresher +data — just keep it ≥ 300s and watch your daily total. + +The radar mode uses RainViewer separately and has no API key, but obeys +`radar_update_interval` (default 600s) to avoid hammering their CDN. ## License diff --git a/plugins/ledmatrix-weather/manifest.json b/plugins/ledmatrix-weather/manifest.json index 564f0f4..2660f82 100644 --- a/plugins/ledmatrix-weather/manifest.json +++ b/plugins/ledmatrix-weather/manifest.json @@ -25,45 +25,55 @@ "radar" ], "versions": [ + { + "version": "2.2.2", + "released": "2026-04-07", + "note": "Added during docs audit; intermediate 2.2.0/2.2.1 release dates were not recorded.", + "ledmatrix_min_version": "2.0.0" + }, { "version": "2.1.2", - "ledmatrix_min": "2.0.0", - "released": "2026-02-24" + "released": "2026-02-24", + "ledmatrix_min_version": "2.0.0" }, { "version": "2.1.1", - "ledmatrix_min": "2.0.0", - "released": "2026-02-15" + "released": "2026-02-15", + "ledmatrix_min_version": "2.0.0" }, { "version": "2.1.0", - "ledmatrix_min": "2.0.0", - "released": "2026-02-13" + "released": "2026-02-13", + "ledmatrix_min_version": "2.0.0" }, { "version": "2.0.9", - "ledmatrix_min": "2.0.0", - "released": "2025-11-05" + "released": "2025-11-05", + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-19", "version": "2.0.8", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-19", "version": "2.0.7", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-19", "version": "2.0.6", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" } ], - "last_updated": "2026-02-24", + "last_updated": "2026-04-07", "stars": 0, "downloads": 0, "verified": true, - "screenshot": "" + "screenshot": "", + "compatible_versions": [ + ">=2.0.0" + ], + "entry_point": "manager.py" } diff --git a/plugins/masters-tournament/LICENSE b/plugins/masters-tournament/LICENSE new file mode 100644 index 0000000..e653a0c --- /dev/null +++ b/plugins/masters-tournament/LICENSE @@ -0,0 +1,17 @@ +GNU GENERAL PUBLIC LICENSE +Version 3, 29 June 2007 + +Copyright (C) 2025 LEDMatrix Team + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . diff --git a/plugins/masters-tournament/README.md b/plugins/masters-tournament/README.md index 209eeb1..3e16fdd 100644 --- a/plugins/masters-tournament/README.md +++ b/plugins/masters-tournament/README.md @@ -48,11 +48,12 @@ Authentic Augusta National visual identity: ### Via Plugin Store (Recommended) -1. Open LEDMatrix Web UI -2. Navigate to **Plugins** → **Plugin Store** -3. Find "Masters Tournament" -4. Click **Install** -5. Configure and enable +1. Open the LEDMatrix web interface (`http://your-pi-ip:5000`) +2. Open the **Plugin Manager** tab +3. Find **Masters Tournament** in the **Plugin Store** section and click + **Install** +4. Open the **Masters Tournament** tab in the second nav row to enable + and configure it ### Manual Installation diff --git a/plugins/masters-tournament/manifest.json b/plugins/masters-tournament/manifest.json index 019010e..3ca62e0 100644 --- a/plugins/masters-tournament/manifest.json +++ b/plugins/masters-tournament/manifest.json @@ -26,7 +26,14 @@ "display_duration": 20, "requires_api_key": false, "config_schema": "config_schema.json", - "tags": ["sports", "golf", "tournament", "leaderboard", "masters", "augusta"], + "tags": [ + "sports", + "golf", + "tournament", + "leaderboard", + "masters", + "augusta" + ], "min_display_size": { "width": 32, "height": 16 @@ -34,5 +41,16 @@ "recommended_display_size": { "width": 128, "height": 64 - } + }, + "versions": [ + { + "version": "2.0.0", + "released": "2026-04-07", + "ledmatrix_min_version": "2.0.0" + } + ], + "last_updated": "2026-04-07", + "compatible_versions": [ + ">=2.0.0" + ] } diff --git a/plugins/mqtt-notifications/README.md b/plugins/mqtt-notifications/README.md index f707116..6948e8b 100644 --- a/plugins/mqtt-notifications/README.md +++ b/plugins/mqtt-notifications/README.md @@ -13,9 +13,13 @@ # MQTT Notifications Plugin -##This plugin is still under heavy development and may not work. +> ⚠️ **Alpha**: This plugin is still under active development and may not +> work reliably yet. Expect rough edges and configuration changes. -Display text or images from HomeAssistant via MQTT. This plugin supports dynamic topic configuration with wildcard support, allowing you to send notifications from any MQTT topic that interrupt the normal display rotation to show important messages. +Display text or images from Home Assistant (or any MQTT publisher) by +subscribing to configurable MQTT topics. Incoming notifications interrupt +the normal display rotation via the on-demand display system to show +important messages. ## Features @@ -28,9 +32,13 @@ Display text or images from HomeAssistant via MQTT. This plugin supports dynamic ## Installation -1. The plugin will be automatically discovered by LEDMatrix -2. Dependencies will be installed automatically from `requirements.txt` -3. Configure the plugin in `config/config.json` +1. Open the LEDMatrix web interface (`http://your-pi-ip:5000`) +2. Open the **Plugin Manager** tab +3. Find **MQTT Notifications** in the **Plugin Store** section and click + **Install**. Dependencies (`paho-mqtt`, etc.) install automatically + from `requirements.txt` on first load. +4. Open the plugin's tab in the second nav row to configure your MQTT + broker, credentials, and topic subscriptions. ## Configuration diff --git a/plugins/mqtt-notifications/manifest.json b/plugins/mqtt-notifications/manifest.json index 0b81fa6..8d09c28 100644 --- a/plugins/mqtt-notifications/manifest.json +++ b/plugins/mqtt-notifications/manifest.json @@ -21,12 +21,15 @@ { "released": "2025-01-20", "version": "1.0.0", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" } ], "last_updated": "2025-01-20", "stars": 0, "downloads": 0, "verified": true, - "screenshot": "" + "screenshot": "", + "compatible_versions": [ + ">=2.0.0" + ] } diff --git a/plugins/mqtt-notifications/requirements.txt b/plugins/mqtt-notifications/requirements.txt index 0727a57..17624c2 100644 --- a/plugins/mqtt-notifications/requirements.txt +++ b/plugins/mqtt-notifications/requirements.txt @@ -1,2 +1,3 @@ paho-mqtt>=1.6.0 Pillow>=10.0.0 +freetype-py>=2.4.0 diff --git a/plugins/news/README.md b/plugins/news/README.md index 8f134d1..03251b7 100644 --- a/plugins/news/README.md +++ b/plugins/news/README.md @@ -30,19 +30,25 @@ A plugin for LEDMatrix that displays scrolling news headlines from RSS feeds inc ### Global Settings -- `display_duration`: How long to show the ticker (10-300 seconds, default: 30) -- `display.scroll_speed`: Scrolling speed in pixels per frame (0.5-5.0, default: 1.0) - **Recommended format** -- `display.scroll_delay`: Delay between scroll steps in seconds (0.001-0.1, default: 0.01) - **Recommended format** -- `target_fps`: Target frames per second for scrolling (30-200, default: 100) -- `dynamic_duration`: Enable dynamic duration based on content width (default: true) - - `enabled`: Enable/disable dynamic duration (default: true) - - `min_duration_seconds`: Minimum display duration (10-300 seconds, default: 30) - - `max_duration_seconds`: Maximum display duration (30-600 seconds, default: 300) - - `buffer_ratio`: Extra buffer applied to calculated duration (0.01-1.0, default: 0.1) -- `rotation_enabled`: Enable headline rotation (default: true) -- `rotation_threshold`: Cycles before rotating headlines (1-10, default: 3) -- `headlines_per_feed`: Headlines to fetch per feed (1-10, default: 2) -- `font_size`: Font size for headlines (8-20, default: 12) +All scrolling/timing/font settings live under the `global.*` namespace +in [`config_schema.json`](config_schema.json) — that file is the source +of truth. The keys you'll touch most often: + +- `global.display_duration`: How long to show the ticker (10–300s, default 30) +- `global.update_interval`: Seconds between RSS fetches (default 300) +- `global.display.scroll_speed`: Pixels per frame (0.5–5.0, default 1.0) +- `global.display.scroll_delay`: Sleep between scroll steps in seconds (0.001–0.1, default 0.01) +- `global.target_fps`: Target frames per second cap (30–200, default 100) +- `global.font_size`: Headline font size (8–20, default 12) +- `global.font_path`: Path to TTF/BDF font (default `assets/fonts/PressStart2P-Regular.ttf`) +- `global.dynamic_duration`: Object — `enabled` (default `true`), + `min_duration_seconds` (default `30`), `max_duration_seconds` + (default `300`), `buffer_ratio` (default `0.1`) +- `global.rotation_enabled`: Enable headline rotation (default `true`) +- `global.rotation_threshold`: Cycles before rotating headlines (1–10, default 3) +- `global.headlines_per_feed`: Headlines to fetch per feed (1–10, default 2) +- `global.background_service.*`: Background fetch tuning — + `enabled`, `request_timeout`, `max_retries`, `priority` ### Feed Settings diff --git a/plugins/news/manifest.json b/plugins/news/manifest.json index efe04df..2c01b84 100644 --- a/plugins/news/manifest.json +++ b/plugins/news/manifest.json @@ -5,7 +5,14 @@ "description": "Displays scrolling news headlines from RSS feeds including sports news from ESPN, NCAA updates, and custom RSS sources", "author": "ChuckBuilds", "category": "content", - "tags": ["news", "headlines", "rss", "sports", "ticker", "scrolling"], + "tags": [ + "news", + "headlines", + "rss", + "sports", + "ticker", + "scrolling" + ], "entry_point": "manager.py", "class_name": "NewsTickerPlugin", "config_schema": "config_schema.json", @@ -15,18 +22,18 @@ "versions": [ { "version": "1.0.4", - "ledmatrix_min": "2.0.0", - "released": "2026-02-17" + "released": "2026-02-17", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.0.3", - "ledmatrix_min": "2.0.0", - "released": "2026-02-12" + "released": "2026-02-12", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.0.2", - "ledmatrix_min": "2.0.0", - "released": "2025-10-19" + "released": "2025-10-19", + "ledmatrix_min_version": "2.0.0" } ], "stars": 0, @@ -41,5 +48,8 @@ "managers": [ "cache_manager" ] - } + }, + "compatible_versions": [ + ">=2.0.0" + ] } diff --git a/plugins/odds-ticker/README.md b/plugins/odds-ticker/README.md index 3e5c2bb..96fcca3 100644 --- a/plugins/odds-ticker/README.md +++ b/plugins/odds-ticker/README.md @@ -162,10 +162,18 @@ This plugin requires the main LEDMatrix installation and uses the OddsManager fo ## Installation -1. Copy this plugin directory to your `ledmatrix-plugins/plugins/` folder -2. Ensure the plugin is enabled in your LEDMatrix configuration -3. Configure your favorite teams and display preferences -4. Restart LEDMatrix to load the new plugin +The easiest way is the Plugin Store in the LEDMatrix web UI: + +1. Open `http://your-pi-ip:5000` +2. Open the **Plugin Manager** tab +3. Find **Odds Ticker** in the **Plugin Store** section and click + **Install** +4. Open the plugin's tab in the second nav row to configure leagues, + favorite teams, and display preferences + +Manual install: copy this directory into your LEDMatrix +`plugins_directory` (default `plugin-repos/`) and restart the display +service. ## Troubleshooting diff --git a/plugins/odds-ticker/manifest.json b/plugins/odds-ticker/manifest.json index 2657d8a..4a09adc 100644 --- a/plugins/odds-ticker/manifest.json +++ b/plugins/odds-ticker/manifest.json @@ -5,40 +5,50 @@ "description": "Displays scrolling odds and betting lines for upcoming games across multiple sports leagues including NFL, NBA, MLB, NCAA Football, and more", "author": "ChuckBuilds", "category": "sports", - "tags": ["odds", "betting", "ticker", "sports", "nfl", "nba", "mlb", "ncaa", "scrolling"], + "tags": [ + "odds", + "betting", + "ticker", + "sports", + "nfl", + "nba", + "mlb", + "ncaa", + "scrolling" + ], "repo": "https://github.com/ChuckBuilds/ledmatrix-plugins", "branch": "main", "plugin_path": "plugins/odds-ticker", "versions": [ { "version": "1.1.3", - "ledmatrix_min": "2.0.0", - "released": "2026-03-29" + "released": "2026-03-29", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.1.2", - "ledmatrix_min": "2.0.0", - "released": "2026-03-29" + "released": "2026-03-29", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.1.1", - "ledmatrix_min": "2.0.0", - "released": "2026-02-23" + "released": "2026-02-23", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.1.0", - "ledmatrix_min": "2.0.0", - "released": "2026-02-17" + "released": "2026-02-17", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.0.3", - "ledmatrix_min": "2.0.0", - "released": "2026-02-12" + "released": "2026-02-12", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.0.2", - "ledmatrix_min": "2.0.0", - "released": "2025-10-19" + "released": "2025-10-19", + "ledmatrix_min_version": "2.0.0" } ], "stars": 0, @@ -52,5 +62,9 @@ "class_name": "OddsTickerPlugin", "dependencies": { "managers": [] - } + }, + "compatible_versions": [ + ">=2.0.0" + ], + "entry_point": "manager.py" } diff --git a/plugins/odds-ticker/requirements.txt b/plugins/odds-ticker/requirements.txt index 62a405a..189f942 100644 --- a/plugins/odds-ticker/requirements.txt +++ b/plugins/odds-ticker/requirements.txt @@ -1,10 +1,10 @@ # Odds Ticker Plugin Requirements -# Core dependencies (handled by main LEDMatrix) -# requests - for API calls -# Pillow - for image manipulation - -# These are already included in the main LEDMatrix requirements -# but listed here for reference: -# requests>=2.25.0 -# Pillow>=8.0.0 +# Hard imports in manager.py — must be installed even though some +# overlap with the LEDMatrix core deps. The plugin loader installs +# this file on first load, so listing them explicitly avoids +# ImportError on hosts where the host environment is minimal. +numpy>=1.20.0 +pytz>=2023.3 +requests>=2.25.0 +Pillow>=8.0.0 diff --git a/plugins/of-the-day/README.md b/plugins/of-the-day/README.md index f811e9b..e9f2f0d 100644 --- a/plugins/of-the-day/README.md +++ b/plugins/of-the-day/README.md @@ -17,18 +17,17 @@ Display daily featured content like Word of the Day, Bible verses, or custom dai This plugin is fully configurable through the LEDMatrix web interface: -1. Navigate to the **Plugins** tab in the web UI -2. Find "Of The Day Display" in the installed plugins list -3. Click **Configure** to open the plugin's configuration tab -4. Adjust settings using the auto-generated form: - - Enable/disable the plugin - - Configure update intervals - - Set display rotation timings - - Manage categories (enable/disable, set display names) - - Adjust display duration -5. Click **Save Configuration** to apply changes - -The web UI automatically generates a configuration form from the plugin's `config_schema.json`, including support for nested category configurations with collapsible sections. +1. Open the LEDMatrix web interface (`http://your-pi-ip:5000`) +2. Open the **Plugin Manager** tab and install **Of The Day Display** + from the **Plugin Store** section if it isn't already +3. Open the **Of The Day Display** tab in the second nav row +4. Adjust settings using the auto-generated form (enable/disable + categories, update intervals, rotation timings, display duration) +5. Click **Save** + +The web UI form is generated directly from +[`config_schema.json`](config_schema.json), including the nested +category configurations with collapsible sections. ### Example Configuration diff --git a/plugins/of-the-day/manifest.json b/plugins/of-the-day/manifest.json index 4e90795..9ca8a52 100644 --- a/plugins/of-the-day/manifest.json +++ b/plugins/of-the-day/manifest.json @@ -24,7 +24,7 @@ { "released": "2025-10-19", "version": "1.0.1", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" } ], "last_updated": "2025-10-19", diff --git a/plugins/of-the-day/requirements.txt b/plugins/of-the-day/requirements.txt index 9992dae..b2e58ff 100644 --- a/plugins/of-the-day/requirements.txt +++ b/plugins/of-the-day/requirements.txt @@ -1,2 +1,2 @@ Pillow>=10.0.0 - +freetype-py>=2.4.0 diff --git a/plugins/olympics/LICENSE b/plugins/olympics/LICENSE new file mode 100644 index 0000000..e653a0c --- /dev/null +++ b/plugins/olympics/LICENSE @@ -0,0 +1,17 @@ +GNU GENERAL PUBLIC LICENSE +Version 3, 29 June 2007 + +Copyright (C) 2025 LEDMatrix Team + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . diff --git a/plugins/olympics/README.md b/plugins/olympics/README.md index a1f5ad8..1bbc952 100644 --- a/plugins/olympics/README.md +++ b/plugins/olympics/README.md @@ -35,8 +35,9 @@ Screenshot Preview: ### From Plugin Store (Recommended) 1. Open the LEDMatrix web interface (`http://your-pi-ip:5000`) -2. Go to **Plugin Store** -3. Find **Olympics Countdown** and click **Install** +2. Open the **Plugin Manager** tab +3. Find **Olympics Countdown** in the **Plugin Store** section and click + **Install** ### Manual Installation diff --git a/plugins/olympics/manifest.json b/plugins/olympics/manifest.json index 9ba957e..ad5d0ca 100644 --- a/plugins/olympics/manifest.json +++ b/plugins/olympics/manifest.json @@ -40,18 +40,21 @@ { "released": "2026-02-08", "version": "2.0.0", - "ledmatrix_min": "2.0.0", - "changelog": "Major update with live medals, events, results, and Vegas mode support" + "changelog": "Major update with live medals, events, results, and Vegas mode support", + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-01-27", "version": "1.0.0", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" } ], "last_updated": "2026-02-08", "stars": 0, "downloads": 0, "verified": true, - "screenshot": "" + "screenshot": "", + "compatible_versions": [ + ">=2.0.0" + ] } diff --git a/plugins/soccer-scoreboard/README.md b/plugins/soccer-scoreboard/README.md index e38b4e6..7a81f0d 100644 --- a/plugins/soccer-scoreboard/README.md +++ b/plugins/soccer-scoreboard/README.md @@ -217,10 +217,18 @@ This plugin requires the main LEDMatrix installation and uses the plugin system ## Installation -1. Copy this plugin directory to your `ledmatrix-plugins/plugins/` folder -2. Ensure the plugin is enabled in your LEDMatrix configuration -3. Configure your favorite teams and display preferences -4. Restart LEDMatrix to load the new plugin +The easiest way is the Plugin Store in the LEDMatrix web UI: + +1. Open `http://your-pi-ip:5000` +2. Open the **Plugin Manager** tab +3. Find **Soccer Scoreboard** in the **Plugin Store** section and click + **Install** +4. Open the plugin's tab in the second nav row to configure leagues and + favorite teams + +Manual install: copy this directory into your LEDMatrix +`plugins_directory` (default `plugin-repos/`) and restart the display +service. ## Troubleshooting diff --git a/plugins/soccer-scoreboard/manifest.json b/plugins/soccer-scoreboard/manifest.json index 9ecfb86..5643004 100644 --- a/plugins/soccer-scoreboard/manifest.json +++ b/plugins/soccer-scoreboard/manifest.json @@ -27,55 +27,55 @@ { "released": "2026-03-31", "version": "1.6.0", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2026-03-27", "version": "1.5.2", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2026-03-02", "version": "1.4.4", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2026-02-24", "version": "1.4.3", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "version": "1.4.2", - "ledmatrix_min": "2.0.0", - "released": "2026-02-24" + "released": "2026-02-24", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.4.1", - "ledmatrix_min": "2.0.0", - "released": "2026-02-24" + "released": "2026-02-24", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.4.0", - "ledmatrix_min": "2.0.0", - "released": "2026-02-24" + "released": "2026-02-24", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.3.1", - "ledmatrix_min": "2.0.0", - "released": "2026-02-15" + "released": "2026-02-15", + "ledmatrix_min_version": "2.0.0" }, { "released": "2026-02-14", "version": "1.3.0", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-19", "version": "1.0.1", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" } ], - "last_updated": "2026-02-24", + "last_updated": "2026-03-31", "stars": 0, "downloads": 0, "verified": true, @@ -88,5 +88,8 @@ "script": "custom-leagues.js", "description": "Custom soccer league editor with ESPN validation" } + ], + "compatible_versions": [ + ">=2.0.0" ] } diff --git a/plugins/static-image/README.md b/plugins/static-image/README.md index 8110f99..6432d43 100644 --- a/plugins/static-image/README.md +++ b/plugins/static-image/README.md @@ -26,12 +26,14 @@ Display static images on your LED matrix with automatic scaling, aspect ratio pr ## Configuration -### Example Configuration +### Single image ```json { "enabled": true, - "image_path": "assets/static_images/my_logo.png", + "images": [ + { "id": "logo", "path": "assets/static_images/my_logo.png" } + ], "fit_to_display": true, "preserve_aspect_ratio": true, "background_color": [0, 0, 0], @@ -39,14 +41,52 @@ Display static images on your LED matrix with automatic scaling, aspect ratio pr } ``` +### Multiple images with rotation + +```json +{ + "enabled": true, + "images": [ + { "id": "logo_a", "path": "assets/static_images/logo_a.png" }, + { "id": "logo_b", "path": "assets/static_images/logo_b.png" }, + { "id": "logo_c", "path": "assets/static_images/logo_c.png" } + ], + "image_config": { + "mode": "multiple", + "rotation_mode": "sequential" + }, + "rotation_settings": { + "sequential_loop": true + }, + "image_rotation_interval": 15, + "fit_to_display": true, + "preserve_aspect_ratio": true, + "background_color": [0, 0, 0], + "display_duration": 30 +} +``` + ### Configuration Options -- `enabled`: Enable/disable the plugin -- `image_path`: Path to image file (relative or absolute) -- `fit_to_display`: Automatically fit image to display dimensions -- `preserve_aspect_ratio`: Maintain image proportions when scaling -- `background_color`: RGB color for transparent areas [R, G, B] -- `display_duration`: Seconds to display the image +The full schema lives in +[`config_schema.json`](config_schema.json) — the web UI form is generated +from it. Key options: + +| Key | Default | Notes | +|---|---|---| +| `enabled` | `false` | Master switch | +| `images` | `[]` | Array of image paths (relative to LEDMatrix root or absolute) | +| `image_config.mode` | `"single"` | How images are presented | +| `image_config.rotation_mode` | `"sequential"` | `"sequential"` or `"random"` when multiple images | +| `rotation_settings.sequential_loop` | `true` | Loop back to the first image after the last | +| `rotation_settings.random_seed` | `null` | Optional fixed seed for reproducible random order | +| `rotation_settings.time_intervals.enabled` | `false` | Tie image changes to wall-clock intervals | +| `rotation_settings.time_intervals.interval_seconds` | `3600` | Wall-clock interval when enabled | +| `image_rotation_interval` | `15` | Seconds between images during rotation | +| `fit_to_display` | `true` | Scale image to display dimensions | +| `preserve_aspect_ratio` | `true` | Don't stretch when scaling | +| `background_color` | `[0, 0, 0]` | RGB fill behind transparent pixels | +| `display_duration` | `10` | Seconds the plugin holds the screen each rotation | ## Usage @@ -93,20 +133,9 @@ plugin.reload_image() ### Multiple Images -To rotate through multiple images, create multiple plugin instances with different IDs: - -```json -{ - "static-image-1": { - "enabled": true, - "image_path": "assets/static_images/image1.png" - }, - "static-image-2": { - "enabled": true, - "image_path": "assets/static_images/image2.png" - } -} -``` +Put all the images you want to cycle through into the `images` array (see +the multi-image example above) and set `image_config.mode` to +`"multiple"`. ## Troubleshooting @@ -135,7 +164,9 @@ To rotate through multiple images, create multiple plugin instances with differe ```json { "enabled": true, - "image_path": "assets/static_images/company_logo.png", + "images": [ + { "id": "company_logo", "path": "assets/static_images/company_logo.png" } + ], "fit_to_display": true, "preserve_aspect_ratio": true, "background_color": [0, 0, 0] @@ -146,7 +177,9 @@ To rotate through multiple images, create multiple plugin instances with differe ```json { "enabled": true, - "image_path": "assets/static_images/pixel_art.png", + "images": [ + { "id": "pixel_art", "path": "assets/static_images/pixel_art.png" } + ], "fit_to_display": false, "preserve_aspect_ratio": true, "background_color": [0, 0, 50] @@ -157,7 +190,9 @@ To rotate through multiple images, create multiple plugin instances with differe ```json { "enabled": true, - "image_path": "assets/static_images/photo.jpg", + "images": [ + { "id": "photo", "path": "assets/static_images/photo.jpg" } + ], "fit_to_display": true, "preserve_aspect_ratio": false, "background_color": [0, 0, 0] diff --git a/plugins/static-image/manifest.json b/plugins/static-image/manifest.json index a9a6b75..cb42359 100644 --- a/plugins/static-image/manifest.json +++ b/plugins/static-image/manifest.json @@ -20,18 +20,21 @@ "versions": [ { "version": "1.0.2", - "ledmatrix_min": "2.0.0", - "released": "2025-11-05" + "released": "2025-11-05", + "ledmatrix_min_version": "2.0.0" }, { "released": "2025-10-19", "version": "1.0.1", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" } ], "last_updated": "2025-11-05", "stars": 0, "downloads": 0, "verified": true, - "screenshot": "" + "screenshot": "", + "compatible_versions": [ + ">=2.0.0" + ] } diff --git a/plugins/stock-news/manifest.json b/plugins/stock-news/manifest.json index 1c89c42..db8310c 100644 --- a/plugins/stock-news/manifest.json +++ b/plugins/stock-news/manifest.json @@ -4,6 +4,8 @@ "version": "1.0.2", "author": "ChuckBuilds", "description": "Displays scrolling stock-specific news headlines and financial updates from RSS feeds, focused on market news and company updates", + "entry_point": "manager.py", + "class_name": "StockNewsTickerPlugin", "category": "financial", "tags": [ "stock", @@ -25,7 +27,7 @@ { "released": "2025-10-19", "version": "1.0.2", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" } ], "last_updated": "2025-10-19", @@ -37,5 +39,8 @@ "managers": [ "cache_manager" ] - } + }, + "compatible_versions": [ + ">=2.0.0" + ] } diff --git a/plugins/text-display/README.md b/plugins/text-display/README.md index 72cfced..34b4c60 100644 --- a/plugins/text-display/README.md +++ b/plugins/text-display/README.md @@ -36,8 +36,11 @@ Display custom scrolling or static text messages on your LED matrix with configu "font_path": "assets/fonts/PressStart2P-Regular.ttf", "font_size": 8, "scroll": true, - "scroll_speed": 30, + "scroll_speed": 1, + "scroll_delay": 0.01, + "scroll_loop": true, "scroll_gap_width": 32, + "target_fps": 120, "text_color": [255, 0, 0], "background_color": [0, 0, 0], "display_duration": 10 @@ -46,16 +49,26 @@ Display custom scrolling or static text messages on your LED matrix with configu ### Configuration Options -- `enabled`: Enable/disable the plugin -- `text`: The message to display -- `font_path`: Path to TTF or BDF font file -- `font_size`: Font size in pixels (4-32) -- `scroll`: Enable scrolling animation -- `scroll_speed`: Scroll speed in pixels per second (1-200) -- `scroll_gap_width`: Gap between scroll repetitions in pixels -- `text_color`: RGB text color [R, G, B] -- `background_color`: RGB background color [R, G, B] -- `display_duration`: Display duration in seconds +The full schema lives in +[`config_schema.json`](config_schema.json) — the web UI form is generated +from it. Key options: + +| Key | Default | Notes | +|---|---|---| +| `enabled` | `false` | Master switch | +| `text` | `"Subscribe to ChuckBuilds"` | The message to display | +| `font_path` | `assets/fonts/PressStart2P-Regular.ttf` | Path to TTF or BDF font file | +| `font_size` | `8` | Font size in pixels | +| `scroll` | `true` | Enable horizontal scrolling animation | +| `scroll_speed` | `1` | Speed multiplier (≈ pixels per frame). Higher = faster. | +| `scroll_delay` | `0.01` | Sleep between scroll steps in seconds. Lower = smoother but more CPU | +| `scroll_loop` | `true` | Loop the text instead of stopping after one pass | +| `scroll_gap_width` | `32` | Pixels of space between scroll loops | +| `target_fps` | `120` | Target frames per second cap for scroll rendering | +| `text_color` | `[255, 255, 255]` | RGB text color | +| `background_color` | `[0, 0, 0]` | RGB background color | +| `display_duration` | `10` | Seconds the plugin holds the screen | +| `update_interval` | `60` | Seconds between plugin update ticks | ## Usage @@ -119,9 +132,14 @@ Optimized for LED matrices: ### For Scrolling Text -1. **Adjust speed for readability**: Slower speeds (20-40) are more readable -2. **Set appropriate gap**: Use gap equal to display width for smooth loops -3. **Test message length**: Very long messages may need speed adjustment +1. **Adjust speed for readability**: `scroll_speed` is a multiplier, not px/s. + Values around `1`–`2` are typical; higher values scroll faster. +2. **Tune smoothness with `scroll_delay`**: lower (0.005) = smoother but + more CPU; higher (0.05) = choppier but lighter. +3. **Set appropriate gap**: a `scroll_gap_width` equal to your display width + produces clean loops. +4. **Test message length**: very long messages benefit from a higher + `target_fps` cap and lower `scroll_delay`. ### For Static Text @@ -152,7 +170,7 @@ Optimized for LED matrices: { "text": "Breaking News: LED matrices are awesome! Stay tuned for more...", "scroll": true, - "scroll_speed": 35 + "scroll_speed": 1.5 } ``` @@ -161,7 +179,7 @@ Optimized for LED matrices: { "text": "Subscribe to ChuckBuilds on YouTube!", "scroll": true, - "scroll_speed": 40, + "scroll_speed": 2, "text_color": [255, 0, 0] } ``` @@ -174,8 +192,8 @@ Optimized for LED matrices: - Check font_path points to valid font file **Scrolling too fast/slow:** -- Adjust scroll_speed value -- Try values between 20-50 for best readability +- Adjust `scroll_speed` (multiplier, default `1`). Try values between `0.5` and `3`. +- For finer control, also tune `scroll_delay` and `target_fps`. **Font not loading:** - Verify font_path is correct @@ -190,9 +208,10 @@ Optimized for LED matrices: ## Performance Notes -- Scrolling text uses pre-rendered cache for smooth animation -- Update interval is 0.033s (~30 FPS) for smooth scrolling -- Text cache is created once and reused for efficiency +- Scrolling text uses a pre-rendered cache for smooth animation +- The render loop targets `target_fps` (default 120) and sleeps + `scroll_delay` between steps +- Text cache is created once at first render and reused - Font loading happens once at initialization ## License diff --git a/plugins/text-display/manager.py b/plugins/text-display/manager.py index 3a8bc42..11f82a4 100644 --- a/plugins/text-display/manager.py +++ b/plugins/text-display/manager.py @@ -51,7 +51,10 @@ def __init__(self, plugin_id: str, config: Dict[str, Any], super().__init__(plugin_id, config, display_manager, cache_manager, plugin_manager) # Configuration - self.text = config.get('text', 'Hello, World!') + # Default kept in sync with config_schema.json — the schema is what + # the auto-generated web UI form populates from, so the code default + # must match what the form prefill shows. + self.text = config.get('text', 'Subscribe to ChuckBuilds') self.font_path = config.get('font_path', 'assets/fonts/PressStart2P-Regular.ttf') self.font_size = config.get('font_size', 8) self.scroll_enabled = config.get('scroll', True) diff --git a/plugins/text-display/manifest.json b/plugins/text-display/manifest.json index 0b4d15b..bdabc33 100644 --- a/plugins/text-display/manifest.json +++ b/plugins/text-display/manifest.json @@ -1,7 +1,7 @@ { "id": "text-display", "name": "Text Display", - "version": "1.0.1", + "version": "1.0.2", "author": "ChuckBuilds", "description": "Display custom scrolling or static text with configurable fonts, colors, and scroll speed. Perfect for announcements, messages, or custom displays.", "category": "display", @@ -18,15 +18,23 @@ "entry_point": "manager.py", "class_name": "TextDisplayPlugin", "versions": [ + { + "released": "2026-04-07", + "version": "1.0.2", + "ledmatrix_min_version": "2.0.0" + }, { "released": "2025-10-19", "version": "1.0.1", - "ledmatrix_min": "2.0.0" + "ledmatrix_min_version": "2.0.0" } ], - "last_updated": "2025-10-19", + "last_updated": "2026-04-07", "stars": 0, "downloads": 0, "verified": true, - "screenshot": "" + "screenshot": "", + "compatible_versions": [ + ">=2.0.0" + ] } diff --git a/plugins/ufc-scoreboard/LICENSE b/plugins/ufc-scoreboard/LICENSE new file mode 100644 index 0000000..e653a0c --- /dev/null +++ b/plugins/ufc-scoreboard/LICENSE @@ -0,0 +1,17 @@ +GNU GENERAL PUBLIC LICENSE +Version 3, 29 June 2007 + +Copyright (C) 2025 LEDMatrix Team + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . diff --git a/plugins/ufc-scoreboard/README.md b/plugins/ufc-scoreboard/README.md new file mode 100644 index 0000000..245871e --- /dev/null +++ b/plugins/ufc-scoreboard/README.md @@ -0,0 +1,78 @@ +# UFC Scoreboard Plugin + +A UFC/MMA plugin for LEDMatrix that displays live, recent, and upcoming +fights with fighter headshots, records, odds, and results. + +> Originally contributed by Alex Resnick +> ([@legoguy1000](https://github.com/legoguy1000)) — see +> [PR #137](https://github.com/ChuckBuilds/LEDMatrix/pull/137). + +## Features + +- **Live fight tracking** — current fights with round and time remaining +- **Recent fights** — results from completed events +- **Upcoming fights** — scheduled cards with start times +- **Fighter headshots** downloaded automatically on first display +- **Records and odds** alongside fighter info +- **Favorite fighters and weight classes** for prioritized display +- No API key required + +## Installation + +1. Open the LEDMatrix web interface (`http://your-pi-ip:5000`) +2. Open the **Plugin Manager** tab +3. Find **UFC Scoreboard** in the **Plugin Store** section and click + **Install** +4. Open the plugin's tab in the second nav row to configure favorite + fighters and weight classes + +## Display Modes + +The plugin registers three modes in `manifest.json`: + +| Mode | Description | +|---|---| +| `ufc_live` | Currently active fights with round/time remaining | +| `ufc_recent` | Recently completed fights with method/round of finish | +| `ufc_upcoming` | Scheduled fights with cards and start times | + +## Configuration + +The full schema lives in +[`config_schema.json`](config_schema.json) — the web UI form is generated +from it. The most-used keys: + +| Key | Default | Notes | +|---|---|---| +| `enabled` | `true` | Master switch | +| `display_duration` | `30` | Seconds per mode | +| `update_interval` | `3600` | Seconds between data fetches | +| `game_display_duration` | `15` | Seconds per individual fight in switch mode | +| `ufc.enabled` | `true` | Toggle UFC content | +| `ufc.favorite_fighters` | `[]` | Array of fighter names to prioritize (e.g. `["Jon Jones", "Islam Makhachev"]`) | +| `ufc.favorite_weight_classes` | `[]` | Weight class abbreviations to prioritize (e.g. `["HW", "LW"]`; see `config_schema.json` for the full list: `LW`, `HW`, `WW`, `MW`, `FW`, `BW`, `FLW`, `LHW`, `WSW`, `WFW`, `WBW`, `WFLW`) | +| `ufc.display_modes.show_live` | `true` | Toggle live mode | +| `ufc.display_modes.show_recent` | `true` | Toggle recent mode | +| `ufc.display_modes.show_upcoming` | `true` | Toggle upcoming mode | +| `ufc.display_modes.live_display_mode` | `"switch"` | `"switch"` (one fight at a time) or `"scroll"` | +| `ufc.display_modes.recent_display_mode` | `"switch"` | Same options for recent mode | + +For the full set of nested keys (scroll tuning, display durations, +update intervals, customization fonts/colors), see +[`config_schema.json`](config_schema.json). + +## Fighter headshots + +On first display the plugin downloads fighter headshots into +`assets/sports/ufc_fighters/`. This requires write access to the +LEDMatrix assets directory and an internet connection. If a headshot +fails to download, the plugin falls back to a placeholder icon. + +## Data source + +ESPN's public MMA endpoints. No API key required. Be mindful of +`update_interval` — the default of 3600s is suitable for normal use. + +## License + +GPL-3.0, same as the LEDMatrix project. diff --git a/plugins/ufc-scoreboard/manifest.json b/plugins/ufc-scoreboard/manifest.json index 63b936c..8fb9655 100644 --- a/plugins/ufc-scoreboard/manifest.json +++ b/plugins/ufc-scoreboard/manifest.json @@ -34,49 +34,52 @@ "versions": [ { "version": "1.2.3", - "ledmatrix_min": "2.0.0", - "released": "2026-03-02" + "released": "2026-03-02", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.2.2", - "ledmatrix_min": "2.0.0", - "released": "2026-02-24" + "released": "2026-02-24", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.2.1", - "ledmatrix_min": "2.0.0", - "released": "2026-02-24" + "released": "2026-02-24", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.2.0", - "ledmatrix_min": "2.0.0", - "released": "2026-02-24" + "released": "2026-02-24", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.1.1", - "ledmatrix_min": "2.0.0", "released": "2026-02-16", - "changelog": "Update author attribution to LegoGuy1000" + "changelog": "Update author attribution to LegoGuy1000", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.1.0", - "ledmatrix_min": "2.0.0", - "released": "2026-02-15" + "released": "2026-02-15", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.0.1", - "ledmatrix_min": "2.0.0", - "released": "2026-02-14" + "released": "2026-02-14", + "ledmatrix_min_version": "2.0.0" }, { "version": "1.0.0", - "ledmatrix_min": "2.0.0", - "released": "2026-02-12" + "released": "2026-02-12", + "ledmatrix_min_version": "2.0.0" } ], - "last_updated": "2026-02-24", + "last_updated": "2026-03-02", "stars": 0, "downloads": 0, "verified": true, - "screenshot": "" + "screenshot": "", + "compatible_versions": [ + ">=2.0.0" + ] } diff --git a/plugins/web-ui-info/LICENSE b/plugins/web-ui-info/LICENSE new file mode 100644 index 0000000..e653a0c --- /dev/null +++ b/plugins/web-ui-info/LICENSE @@ -0,0 +1,17 @@ +GNU GENERAL PUBLIC LICENSE +Version 3, 29 June 2007 + +Copyright (C) 2025 LEDMatrix Team + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . diff --git a/plugins/web-ui-info/README.md b/plugins/web-ui-info/README.md index 14ed9ab..414864f 100644 --- a/plugins/web-ui-info/README.md +++ b/plugins/web-ui-info/README.md @@ -39,9 +39,10 @@ The plugin will automatically be discovered and loaded when the LEDMatrix system To enable/disable the plugin: 1. Open the web UI at `http://[your-device]:5000` -2. Navigate to the Plugins tab -3. Find "Web UI Info" in the plugin list -4. Toggle the enable/disable checkbox +2. Open the **Plugin Manager** tab +3. Find **Web UI Info** in the **Installed Plugins** list and toggle it + on or off +4. Restart the display service from the **Overview** tab ## Device ID diff --git a/plugins/web-ui-info/manifest.json b/plugins/web-ui-info/manifest.json index 63b226f..f4e4a5e 100644 --- a/plugins/web-ui-info/manifest.json +++ b/plugins/web-ui-info/manifest.json @@ -17,6 +17,16 @@ "web_ui_info" ], "update_interval": 300, - "default_duration": 10 + "default_duration": 10, + "versions": [ + { + "version": "1.0.0", + "released": "2026-04-07", + "ledmatrix_min_version": "2.0.0" + } + ], + "last_updated": "2026-04-07", + "compatible_versions": [ + ">=2.0.0" + ] } - diff --git a/plugins/youtube-stats/LICENSE b/plugins/youtube-stats/LICENSE new file mode 100644 index 0000000..e653a0c --- /dev/null +++ b/plugins/youtube-stats/LICENSE @@ -0,0 +1,17 @@ +GNU GENERAL PUBLIC LICENSE +Version 3, 29 June 2007 + +Copyright (C) 2025 LEDMatrix Team + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . diff --git a/plugins/youtube-stats/manifest.json b/plugins/youtube-stats/manifest.json index 650ec4e..4b56ab9 100644 --- a/plugins/youtube-stats/manifest.json +++ b/plugins/youtube-stats/manifest.json @@ -31,5 +31,16 @@ "url": "https://developers.google.com/youtube/v3", "rate_limit": "10,000 units per day (default quota)" } + ], + "versions": [ + { + "version": "1.0.1", + "released": "2026-04-07", + "ledmatrix_min_version": "2.0.0" + } + ], + "last_updated": "2026-04-07", + "compatible_versions": [ + ">=2.0.0" ] } diff --git a/update_registry.py b/update_registry.py index 852c4e8..59bf168 100644 --- a/update_registry.py +++ b/update_registry.py @@ -96,13 +96,29 @@ def update_registry(registry_path: str = "plugins.json", dry_run: bool = False) print(f" {plugin_id}: {registry_version} -> {manifest_version}") if not dry_run: plugin["latest_version"] = manifest_version - plugin["last_updated"] = datetime.now().strftime("%Y-%m-%d") + # Prefer the manifest's last_updated if present (matches the + # plugin's actual release date); fall back to today. + plugin["last_updated"] = manifest.get("last_updated") or datetime.now().strftime("%Y-%m-%d") updates_made = True elif parse_version(manifest_version) < parse_version(registry_version): print(f" {plugin_id}: manifest ({manifest_version}) < registry ({registry_version}), skipping") else: print(f" {plugin_id}: up to date ({registry_version})") + # Sync user-visible metadata fields from the manifest. The manifest + # is the source of truth per the module docstring, so the registry + # should never disagree with it on the fields the Plugin Store + # actually renders to users. + synced_fields = [] + for field in ("name", "description", "author", "category", "tags", "icon"): + if field in manifest and plugin.get(field) != manifest[field]: + if not dry_run: + plugin[field] = manifest[field] + synced_fields.append(field) + updates_made = True + if synced_fields: + print(f" synced fields: {', '.join(synced_fields)}") + if updates_made and not dry_run: registry["last_updated"] = datetime.now().strftime("%Y-%m-%d") with open(registry_file, "w", encoding="utf-8") as f: