OpenWeather as an external integration for
Gladys Assistant: a weather provider that feeds
the dashboard weather widget and the chat assistant, built on the JavaScript SDK
@gladysassistant/integration-sdk.
It is the port of the OpenWeather service that lives inside the Gladys core
(server/services/openweather), rewritten as a weather-type external
integration (manifest type: "weather", spec B.18). Installing it takes
precedence over the built-in service with zero configuration; stopping or
uninstalling it falls back to the built-in one automatically.
A weather integration is not a device integration: it exposes no device, publishes no state and answers no discovery. Its whole surface is a single SDK handler:
gladys.onWeatherGet(async ({ latitude, longitude, language, units }) => {
// ...call the provider, return the pivot weather format
});Gladys calls it whenever the weather widget or the chat assistant needs the weather, awaits the answer under 15 s, then normalizes and bounds the payload before using it. Throwing is a legitimate answer: the core acks the command as failed and its provider loop falls through to the next weather provider.
The generic integration page therefore only shows Configuration, Supervision and Logs — no Devices, no Discovery screens.
Two APIs are supported, chosen in the Configuration screen:
| Setting | Endpoints | Needs | What you get |
|---|---|---|---|
| Free (default) | /data/2.5/weather + /data/2.5/forecast |
any free account | current conditions, 24 h of 3-hourly forecast, 5 days |
| One Call 3.0 | /data/3.0/onecall |
the "One Call by Call" subscription (1000 free calls a day, card required) | the above plus real hourly detail, UV index, dew point and national weather alerts |
The free API is the default because it is the one the internal Gladys service uses: an existing OpenWeather key keeps working as-is. Everything the pivot format supports and the chosen API cannot provide is simply omitted — a provider never sends a field it does not have.
- Conditions. The internal service mapped
weather[0].main(8 coarse groups); this port maps the numeric condition code, which keeps the intensity the group name throws away:502→pouringrather thanrain,801→partly-cloudyrather thancloud,511/616→sleet. OpenWeather has no hail code, sohailis never emitted. - Day and night. The pivot's
weatherkeeps the meteorology and the strict booleanis_daydrives the day/night rendering variant (read from thed/nsuffix of the OpenWeather icon). A rainy night staysrain, never the deprecatednightcondition. - Units. Gladys sends the requesting user's preference (
metricorus) and the answer uses it. OpenWeather reports the visibility in metres and the precipitation in millimetres whatever the unit system, so those two are converted here (km/mi and mm/in), andpopbecomes a 0-100 percentage. - Alerts. OpenWeather relays the national meteorological office's wording
and provides neither a CAP severity nor a phenomenon type. The
typecomes from the OpenWeathertags, with theeventwording as a fallback; theseverityis read from the vigilance colour first ("Vigilance orange" / "Orange Wind warning" →severe, "Red warning" →extreme, "Yellow … warning" →minor), then from the severity words when the office publishes no colour ("Extreme Heat Warning" →extreme, "Frost Advisory" →minor), and defaults tomoderatewhen the wording does not say. The colour is read before anything else because MeteoAlarm names every alert a "warning", and the phenomenon labels are stripped first so that the "Extreme high temperature" phenomenon does not turn a yellow vigilance into an extreme one. Expired bulletins are dropped (OpenWeather keeps serving them past their end date), and a bulletin text already published is not repeated on the next alerts — a national office typically sends the same department bulletin as the description of every phenomenon it covers. Language: OpenWeather serves the alerteventanddescriptionin English whatever thelangparameter says ("National weather alerts are provided in English by default", One Call 3.0 documentation) — only the weatherdescriptionfield is translated, and this integration does not use it. What the widget can translate is the alert label of a typed alert, which is why the type detection covers the French and English wordings of every phenomenon of the pivot. - Cache. A short in-memory cache (10 minutes by default, configurable, 0 to disable) sits in front of OpenWeather: the widget and the chat both ask for the weather, and re-reading a two-minute-old forecast would burn quota for nothing.
.
├─ index.js # SDK bootstrap: onWeatherGet, actions, status
├─ src/
│ ├─ config.js # config defaults + normalization
│ ├─ weather.js # the provider: cache + request orchestration
│ └─ openweather/
│ ├─ client.js # the only place that talks HTTP to OpenWeather
│ ├─ conditions.js # condition codes -> the pivot enum, day/night
│ ├─ alerts.js # national alerts -> CAP severity + type
│ ├─ units.js # unit systems and conversions
│ ├─ pivot.js # helpers to assemble a pivot entry
│ ├─ formatFree.js # /data/2.5 -> pivot format
│ └─ formatOneCall.js # /data/3.0/onecall -> pivot format
├─ docs/
│ ├─ en.md # user documentation (re-hosted by Gladys,
│ └─ fr.md # linked from the Configuration screen)
├─ gladys-assistant-integration.json # manifest (name, config schema, image…)
├─ Dockerfile # Node 24 Alpine, read-only rootfs ready
├─ .github/workflows/release.yml # UI-driven release: bump + tag + build
├─ .github/workflows/build.yml # multi-arch build (git tag or called by release)
└─ cover.png # catalog cover, 800×534 px, ≤150 KB
- Node.js ≥ 20 (uses the built-in global
fetch; no HTTP dependency). @gladysassistant/integration-sdkwith the weather API —onWeatherGet,WEATHER_CONDITIONS,WEATHER_ALERT_SEVERITIES,WEATHER_ALERT_TYPES.- A Gladys with weather-integration support (spec B.18); the manifest
declares the range in
gladys_version.
⚠️ Temporary: the SDK is pinned to an unreleased commit. The SDK weather API (integration-sdk-js#19) and the Gladys core support (Gladys#2738) are both still open pull requests, so no published npm version carriesonWeatherGetyet. To keep this repository installable and its CI green,package.jsonpoints at the source archive of the exact commit of the SDK pull request:https://github.com/GladysAssistant/integration-sdk-js/archive/af9d20b0e92415c242265c5ee0647f5c618332ec.tar.gzAn https tarball rather than a
git+…dependency on purpose: npm rewrites GitHub git dependencies togit+ssh://in the lockfile, which then fails on any CI runner without an SSH key. The tarball resolves over plain https, is pinned to an immutable commit, carries an integrity hash and needs nogitin the Docker image.When the SDK ships the weather API, do these three things:
- set the dependency back to a plain version (
"^0.10.0") and runnpm installto refreshpackage-lock.json;- set
gladys_versionin the manifest to the Gladys release that carries B.18 (it currently guesses>=4.85.0);- re-run
npx github:GladysAssistant/integration-store .— the store schema only acceptstype: "weather"once Gladys#2738 has landed.
npm install
GLADYS_HOST_API_URL="http://localhost:1443" \
GLADYS_INTEGRATION_TOKEN="<token>" \
GLADYS_INTEGRATION_SELECTOR="openweather" \
LOG_LEVEL=debug \
npm startThe three GLADYS_* variables are injected by the Gladys supervisor when the
integration runs inside its sandboxed container. The SDK reads them
automatically.
npm run format:check # Prettier: is everything formatted?
npm run format # Prettier: format everything in place
npm run lint # ESLint: catch real mistakes
npm test # Unit tests, via the built-in `node --test` runnerTests live in test/ and use Node's native test runner. They cover the
condition mapping, the unit conversions, both formatters (against trimmed real
OpenWeather payloads), the alert classification, the cache and the
manifest/code consistency — no network access, fetch is stubbed.
npx github:GladysAssistant/integration-store .Runs the exact same checks as the store indexer — manifest JSON & schema, Docker image availability, cover image, code rules — and reports every problem at once.
- Add the GitHub topic
gladys-assistant-integrationto the repository. - Release from the GitHub UI: Actions → Release → Run workflow, pick
patch,minorormajor. The workflow bumps the version everywhere (package.json+ manifestversion/docker_image), pushes thevX.Y.Ztag and builds thelinux/amd64+linux/arm64image toghcr.io. - The decentralized indexer picks up the new manifest
versionand Gladys offers a one-click install / update.
Apache-2.0