Implements feature request: https://community.gladysassistant.com/t/scene-nouvea…u-declencheur-sur-la-meteo/10523
### Description
Run a scene from the weather itself, as requested by @Chris75 on the forum: close the blinds when the wind goes above 20 km/h, open them back on a calm sunny day, close the shutters and the pool on a storm, stop the watering when it rains, get an alert on frost.
Per the answer in the thread ("that's not what I planned, here we're going to make a dedicated weather trigger!"), the weather is **not** exposed as a device whose features would be usable everywhere — this adds a **dedicated scene trigger**. See the scope note below.
**Server**
- New `weather.matched` trigger type. Configuration: a house, the watched pivot property (`temperature`, `wind_speed`, `humidity`, `condition`) and the **`operator` / `value` couple already shared by the threshold triggers** (`=`, `!=`, `>`, `>=`, `<`, `<=`) — no new operator vocabulary, and only one new field in the scene Joi schema (`weather_field`).
- New scheduled job `check-weather-triggers` (every 15 min) built on the existing core weather provider loop (`weather.get`) — no new data source. Same doctrine as the existing weather-alert trigger: it is **gated** (it only calls a provider when at least one *active* scene carries the trigger, so users without such scenes cost their provider zero extra API calls), it guards against overlapping runs, and it is also relaunched by the existing external-integration freshness nudge.
- **No continuous re-firing**: the poll emits the current **and** the previous payload, and the matcher fires only on the transition — the rule matches now and did not match at the previous poll. So "wind > 20 km/h → close the blinds" runs once when the wind picks up, not every 15 minutes for as long as it blows. Because both payloads travel in the event the matcher stays stateless, so editing a scene or changing a threshold resets nothing. The first poll after a core start is a **baseline** (no event), exactly like `weather.alert-raised`, so a restart during a storm does not re-run every scene.
- Compared values: °C, %, the pivot condition enum as a string, and **km/h** for the wind speed — the pivot carries m/s, the trigger converts it like the dashboard widget does, because km/h is the unit users write their rules in. A property a provider does not expose never matches, and a numeric rule with an empty/unparseable value never matches.
**Front**: new `WeatherTrigger` editor component, the trigger registered in the trigger type list and the trigger card, i18n keys added in **en / fr / de**.
**Spec**: `docs/specs/external-integrations.md` B.18 gains point 7 describing the trigger, and point 5 (freshness nudge) is updated to mention both gated checks.
**Deliberately out of scope**: the weather **condition** (a check evaluated inside a running scene, as opposed to a trigger). It was explicitly split off into a separate feature request in the forum thread, so this PR keeps to the trigger only.
## Forum
Forum: https://community.gladysassistant.com/t/scene-nouveau-declencheur-sur-la-meteo/10523
### Checklist
- [x] Tests pass: new tests added at `server/test/lib/weather/weather.checkTriggers.test.js` and `server/test/lib/scene/triggers/scene.trigger.weather.test.js`, covering every operator path, the unit conversion, the transition/baseline semantics, the gating, the in-flight guard and the provider-failure path. The scene/weather/external-integration/scheduler/model/controller suites run green locally (992 passing, 0 failing). The full suite could not be run to completion in this sandbox (pre-existing environment failures: gateway backup/restore shelling out to the `sqlite3` CLI, Docker socket, network tests) — nothing touched by this PR fails. Cypress was not run (no browser binary available); `front/cypress/e2e/routes/scene/Scene.cy.js` was reviewed and is unaffected.
- [x] Linter and prettier pass on both front and server (`npm run eslint`, `npm run prettier` / `prettier-check`), plus `npm run compare-translations` and `npm run build` on the front.
- [x] No undocumented breaking change — the change is purely additive (a new trigger type, a new gated job, one new optional Joi field).
> ⚠️ This pull request was opened by an automated Claude Code run. It has not been tested against a real weather provider on a live instance, and **needs human review before merging**.
---
_Generated by [Claude Code](https://claude.ai/code/session_01BRdJPgpjHkz9LKu39n8fm8)_
## Summary by CodeRabbit
- **New Features**
- Added weather-condition scene triggers for temperature, wind speed, humidity, and conditions.
- Supports configurable operators, thresholds, metric and imperial units, and selected properties.
- Triggers scenes only when conditions newly become true.
- Added automatic weather-trigger checks every 15 minutes.
- **Improvements**
- Weather alerts and scene triggers now share weather data retrieval.
- Added German, English, and French translations for weather-trigger configuration.
- **Bug Fixes**
- Prevented duplicate or overlapping weather-trigger actions and handled provider failures more reliably.