Skip to content

Navigation Menu

Sign in
Sign up

Weather plugin for the live screen, fetched from its own repo - #797

Open
ChampionDesigns wants to merge 4 commits into
decentespresso:main from
ChampionDesigns:ben/weather-plugin
Open

Weather plugin for the live screen, fetched from its own repo #797
ChampionDesigns wants to merge 4 commits into
decentespresso:main from
ChampionDesigns:ben/weather-plugin

Conversation

@ChampionDesigns

@ChampionDesigns ChampionDesigns commented Sep 5, 2026
edited
Loading

Copy link
Copy Markdown
Collaborator

Summary

A weather plugin for the live screen: temperature now, rain split by part of the day, and today's
high and low. It emits on /ws/v1/plugins/weather.reaplugin/weather, which any skin can read.

Base: main. Independent.

Why the plugin does the arithmetic

Open-Meteo's daily answer carries one rain probability for the whole day, which is not the question
anyone asks standing at a machine. Its hourly answer carries a value per hour, so the plugin buckets
those into morning, afternoon and evening itself rather than showing a number nobody wanted.

timezone=auto is on the request, so the daily arrays are the location's days, not the
tablet's — which matters for a machine set to one timezone asking about another.

dayAt checks the type before the value. Number(null) is 0 and 0 degrees is a real temperature,
so a truthy test would send a missing high as a real zero. Absent is null, and a skin draws no range
rather than a wrong one.

Fetched, not committed — done as you asked

Your review: "please fetch instead of bundle. fetch allows updates from upstream github repo
without a new Decaid release."
The last commit on this branch does exactly that, so the PR now
takes the same route as #763's dcamp.

The plugin is published from
ChampionDesigns/decaid-weather-plugin
as a release ZIP, and scripts/fetch_weather_plugin.sh downloads a pinned tag, checks its SHA-256,
checks the manifest id, version, apiVersion and the four permissions, checks plugin.js has a
createPlugin entry point, and unpacks it into assets/plugins/. The generated directory is
gitignored beside dye2, shot-upload and dcamp, and the fetch is added to all fourteen
plugin-fetch blocks across develop-builds.yml, pr-checks.yml and release.yml.

584 lines of plugin source leave the Decaid tree. What stays is the wiring — the pubspec.yaml
asset entry, the plugin_loader_service bundled list, and the permissions test — because from the
app's side a fetched plugin and a committed one are the same thing.

bundledPluginRepos gains the repo, so an installed copy keeps receiving releases from it rather
than being frozen at whatever Decaid shipped. That is the point of the change.

One thing to decide. The source repo sits under ChampionDesigns, because that is where it was
published. The script honours a WEATHER_REPO override, so moving it to decentespresso is a
one-line change if you would rather own it. Say the word.

Wiring the fetch up for real found two defects in the plugin repo, both now fixed there: the v1.1.0
asset was packed flat, so Decaid unpacked two loose files instead of a weather.reaplugin/
directory; and plugin.js reported version 1.0.0 while its manifest declared 1.1.0, which
would let an update be offered and then not applied. The plugin repo now builds its release in CI
on a v* tag and fails if the two versions drift, matching the dcamp plugin's workflow.

Nothing upstream consumes it yet

Checked against all bundled skins: only Decal reads the weather event, and Decal is a separate
PR. On its own this plugin is inert — it installs, runs and emits, and nothing draws it. That costs
nothing and breaks nothing, and any skin author can adopt the event. Worth knowing before merging.

Linked Issue

N/A

Verification

  • flutter analyze — clean.

  • flutter testfull suite 3893 passed / 1 skipped, re-run on the fetch conversion,
    6 Sep 2026.

  • flutter testtest/plugins 243 passed, including bundled_plugin_permissions_test, which
    reads the fetched manifest, and a new provenance test pinning the canonical repo.

  • scripts/fetch_weather_plugin.sh — installs v1.1.0 clean from the release CI built, and the
    unpacked directory is correctly gitignored.

  • dart format — clean on every changed file.

  • The api permission is declared and now pinned by the test. The plugin fetches from
    Open-Meteo; without api the request is refused and it emits nothing — a plugin that installs,
    runs and silently never reports. The permissions test asserts containsAll, so a missing
    permission passed as long as the listed ones were present. api is now listed, with a note
    saying why.

  • Verified against the machine: high 22.9, low 11.9 for Tarragindi, read back off the plugin's
    own websocket after installing on the tablet.

  • Verified on hardware. This change ships in the Decaid-Canary build Ben runs on his own
    machine, and has been exercised in normal use rather than only under test.

Impact

  • User-visible: a new bundled plugin appears in the plugin list. It does nothing until a skin
    draws its output and a location is set.
  • Network: the plugin reaches Open-Meteo. No API key, and the location is looked up once and
    remembered. This is why it declares api.
  • API: none. It uses the existing plugin websocket and settings mechanisms.
  • Compatibility: additive.
  • Security: the plugin holds no credentials. Its only outbound call is to Open-Meteo.

Contributor Responsibility

AI-assisted development is allowed. The submitter remains responsible for the submitted work.

  • I have reviewed and understand all changes in this PR and take responsibility for their correctness, security, behavior, licensing, and provenance, including any AI-assisted or AI-generated work.

ChampionDesigns and others added 3 commits September 5, 2026 11:30
Local weather, emitted on a websocket channel a skin can read at
/ws/v1/plugins/weather.reaplugin/weather. Ben asked for it on the live
screen's bottom-right corner: temperature now, and rain split by part of
the day.
WHY THE PLUGIN DOES THE ARITHMETIC. Open-Meteo's daily answer carries one
rain probability for the whole day, which is not the question anyone asks
standing at a machine. Its hourly answer carries a value per hour, so the
parts of the day are bucketed here, where the location's own timezone is
already known and where one implementation serves every skin.
THREE PERIODS, EMITTED FORWARD ONLY, the running one first: AM 06-12,
PM 12-18, NIGHT 18-06. Ben's call, 30 Aug 2026 - "a rolling window with
current on the left and next on the right" - so the strip never shows a
period that is over. The night bucket wraps midnight, which is why it is
a start hour and a length rather than a pair of bounds: at 02:00 the
running night began at 18:00 YESTERDAY, and all four windows are proven
against a synthetic forecast whose probability equals the hour.
Peak across a bucket, not mean: one 90% hour inside a quiet afternoon is
exactly what the reader wanted warning of, and an average buries it.
Rainfall is summed, because that is what "how much" means over hours.
A failed fetch does not erase the cached reading - it keeps being
published with its true age, and the skin decides when it is too old to
show. A widget that blanks on one lost request is worse than one that
says how old its number is.
Settings are declared in the manifest, so the Plugins page generates the
form: location, refresh minutes, units. No new UI in the app.
Registered in all three places a bundled plugin must appear - pubspec
assets, plugin_loader_service's bundled list, and the permissions guard
that every other bundled plugin already has.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Ben, 30 August 2026, on the skin's weather corner: "its missing MIN/MAX temps
to the right of the temp in the weather." The corner had the room — its head
turned sideways when the bottom rail shortened — but the plugin was not asking
for the numbers.
One parameter: `daily=temperature_2m_max,temperature_2m_min`, read at index 0.
`timezone=auto` is already on the request, so the daily arrays are the
LOCATION's days rather than the tablet's, which matters for a machine set to
one timezone and asking about another.
`dayAt` checks the type before the value. `Number(null)` is 0 and 0 degrees is
a real temperature, so a truthy test would send a missing high as a real zero —
the same trap this plugin already guards for the temperature and the weather
code. Absent is null, and the skin draws no range at all rather than a dash.
Verified against the machine: high 22.9, low 11.9 for Tarragindi, read back off
the plugin's own websocket after installing 1.1.0 on the tablet.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The bundled copy was 1.0.0 and declared log, emit and pluginStorage. The
plugin fetches from Open-Meteo, so without `api` the request is refused and
it emits nothing — a plugin that installs, runs and silently never reports.
The permissions test did not catch it. It asserts `containsAll`, so a MISSING
permission passes as long as the listed ones are present, and `api` was not
listed. It is now, with a note saying why, so dropping it again fails the
build rather than the machine.
Version goes to 1.1.0, matching the daily high/low already in this lane.
Verified: flutter analyze clean, test/plugins 242 passed, dart format clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

tadelv commented Sep 5, 2026

Copy link
Copy Markdown
Member

please fetch instead of bundle. fetch allows updates from upstream github repo without a new Decaid release

Vid's review of the bundling PR: "please fetch instead of bundle. fetch
allows updates from upstream github repo without a new Decaid release."
So the plugin now follows the same route as dye2, shot-upload and dcamp.
It is published from ChampionDesigns/decaid-weather-plugin as a release
ZIP, and scripts/fetch_weather_plugin.sh downloads a pinned tag, checks
the SHA-256, checks the manifest id, version, apiVersion and the four
permissions it needs, checks plugin.js has a createPlugin entry point,
and unpacks it into assets/plugins/. The generated directory is
gitignored, exactly like the other three.
The 584 lines of plugin source leave the Decaid tree. What stays is the
wiring: the pubspec asset entry, the plugin_loader_service bundled list,
and the permissions test - all unchanged, because from the app's side a
fetched plugin and a committed one are the same thing.
bundledPluginRepos gains the repo, so an installed copy keeps receiving
releases from it rather than being frozen at whatever Decaid shipped.
That is the whole point of the change: the plugin can now be updated
without a Decaid release.
The fetch is added to all fourteen plugin-fetch blocks across
develop-builds.yml, pr-checks.yml and release.yml.
Note for the reviewer: the source repo sits under ChampionDesigns
because that is where it was published. The script honours a WEATHER_REPO
override, so moving it to decentespresso is a one-line change if you
would rather own it.
Verified: fetch_weather_plugin.sh installs v1.1.0 clean, flutter analyze
reports no issues, and test/plugins/ passes 243 tests - including the new
provenance test and the permissions test, which reads the fetched
manifest.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@ChampionDesigns ChampionDesigns changed the title (削除) feat(weather): a bundled weather plugin for the live screen (削除ここまで) (追記) Weather plugin for the live screen, fetched from its own repo (追記ここまで) Sep 5, 2026

Copy link
Copy Markdown
Collaborator Author

Converted to fetch, as you asked. The plugin is published from
ChampionDesigns/decaid-weather-plugin and scripts/fetch_weather_plugin.sh pulls a pinned tag,
checks the SHA-256, the manifest id, version, apiVersion and permissions, and the createPlugin
entry point — same shape as fetch_dcamp_plugin.sh. The unpacked directory is gitignored beside
the other three, and the fetch is added to all fourteen plugin-fetch blocks in the workflows.
bundledPluginRepos gains the repo, so an installed copy keeps receiving releases without a
Decaid release, which was your point.

Wiring it up found two defects in the plugin repo, both fixed there: the release ZIP was packed
flat, so Decaid unpacked two loose files instead of a weather.reaplugin/ directory; and
plugin.js reported version 1.0.0 while its manifest declared 1.1.0, so an update could be
offered and then not applied. The plugin repo now builds its release in CI on a v* tag and
fails if those drift.

One thing for you to decide: the repo sits under ChampionDesigns because that is where it was
published. The script honours a WEATHER_REPO override, so moving it to decentespresso is a
one-line change if you would rather own it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

AltStyle によって変換されたページ (->オリジナル) /