# OpenMeteo TESTING ETM CONSUMER Get current weather data for your location. The OpenMeteo plugin gives the box the **weather and solar forecasts** for your site: today's and tomorrow's weather, and the expected PV production for each roof orientation. The data come from the public [Open-Meteo](https://open-meteo.com) service, queried directly by the box — **no account, no API key**, and no detour through an ETM service. Package: `powersync-plugin-openmeteo`. ## 1. What the plugin publishes The plugin creates two kinds of objects: - a **site** (`Open-Meteo site`): weather at the location (temperature, clouds, wind, humidity…), forecast solar irradiance, sunrise and sunset, and a satellite observation of the past hour; - one or more **PV planes** (`Open-Meteo PV plane`), attached to the site — one per roof orientation. Each plane publishes the forecast irradiance on its modules and the expected production derived from it: for the current hour, the next 3, 6 and 12 hours, the rest of the day and tomorrow. The ETM-PowerSync app shows these forecasts next to the measurements (expected production on the charts, hour-by-hour weather). ## 2. Adding the site In installer mode, add an **Open-Meteo site** device (see [Adding a device](../../installation/application.md)) and enter: | Field | Content | | --- | --- | | `Latitude`, `Longitude` | Position of the site, in decimal degrees | | `Elevation (m, optional)` | Altitude of the site in metres. Optional: left at `0`, Open-Meteo uses the altitude of its own terrain model. Enter it in mountains or narrow valleys, where the forecast temperature depends on it. | The site is not discovered automatically: it is created by hand, once per location. ## 3. Adding the PV planes Once the site exists, add an **Open-Meteo PV plane** device: discovery offers one plane for each existing site. Create **one plane per orientation** — an east-west roof gives two planes. | Field | Content | | --- | --- | | `Tilt (deg, 0=horizontal)` | Tilt of the modules in degrees: `0` = flat, `90` = vertical | | `Azimuth (deg geographic, 180=South)` | Orientation, in **geographic convention**: `180` = south, `90` = east, `270` = west | | `Peak power kWp` | Peak power of the modules on this plane | | `Performance ratio (declared, not learned)` | Overall system efficiency, **declared** by the installer (the box does not learn it). Left at `1.0`, the expected production is overestimated. | Depending on the plugin version, two values from the module datasheet complete the plane: `Power temperature coefficient (%/K, declared, not learned)` (default −0.37 %/K) and `NOCT (°C, declared, not learned)` (default 45 °C). They correct the expected production when the modules heat up. !!! warning "Mind the azimuth" Other tools count the azimuth from south (`0` = south). Here, `0` is **north**: an azimuth of `0` entered for a due-south roof gives a heavily underestimated production forecast. ## 4. A forecast, never a measurement Everything this plugin publishes is a **weather forecast** converted into production, or a **satellite observation** about an hour old. It is never a measurement of your installation: the actual production is read from the inverter or the meter. This is why the values are named `forecast…` or `observed…` (satellite observation): there is no `pvPower` in this plugin, only `forecastPvPower`. The expected production is a simple calculation: forecast irradiance × peak power × declared efficiency. It **does not account for** shading, soiled modules or inverter clipping. The error therefore always goes the same way: **the forecast is optimistic**. 4 kW forecast is not 4 kW produced. The **weather spread** published for today and tomorrow (in %) says how uncertain the weather itself is. It says nothing about the accuracy of the expected production: on a clear, stable day it is low, precisely when the overestimate is at its highest. ## 5. Refresh and internet outage Weather models do not publish more often than this: the forecast and the satellite observation are fetched **every hour**, the spread **every 3 hours**. The site's `Refresh` action forces all three. If Open-Meteo does not answer, the plugin retries after 5 minutes, then 10, 20, 40… — never less often than the source's normal rate — and returns to its normal rate at the first answer. After **3 hours** without a forecast, `Forecast valid` turns false. An internet outage blocks nothing: the box keeps controlling with its measurements, safety is maintained, and only the forecasts degrade until the connection returns. ## 6. What leaves the box To get its forecasts, the box sends Open-Meteo **only**: - the site's coordinates, **rounded to two decimals** (about 1 km): precise enough for the weather, too blurred to point to an address; - the site's altitude, if you entered it; - the tilt and azimuth of each PV plane. No measurement, no consumption and no usage data is sent. The peak power and the efficiency stay on the box: the conversion into production happens locally. ## 7. Commercial use: a dedicated Open-Meteo instance The public Open-Meteo API is for **non-commercial use** only. For a commercial deployment, the plugin settings can point to a self-hosted Open-Meteo instance (`Base URL (forecast)`, `Base URL (satellite radiation)`, `Base URL (ensemble spread)`) or take a key for Open-Meteo's commercial offer (`API key (commercial endpoint, optional)`). Unchanged, the plugin queries the public API. ## 8. Data sources Weather data by Météo-France, satellite radiation by EUMETSAT, provided through [Open-Meteo](https://open-meteo.com) under the CC-BY 4.0 licence. --- ## Reference !!! info "Application labels" The keys and labels below are the ones the application shows, **in English**. They are left verbatim so that you find them word for word on screen. **Manufacturer:** Open-Meteo **Plugin:** `OpenMeteo` #### Supported models | Model | Role | Transport | Pairing | Quantities | | --- | --- | --- | --- | --- | | **Open-Meteo site** | weather, daylightsensor | — | Manual | 29 | | **Open-Meteo PV plane** | — | — | Auto-discovery | 15 | #### Per-model detail ??? abstract "Open-Meteo site — `openMeteoSite`" _Settings:_ | Key | Label | Type | Range | Default | Read-only | | --- | --- | --- | --- | --- | --- | | `name` | Name | QString | — | — | no | | `latitude` | Latitude | double | — | `48.9` | no | | `longitude` | Longitude | double | — | `7.85` | no | | `elevation` | Elevation (m, optional) | double | — | `0` | no | _Measured quantities:_ | Key | Quantity | Type | Unit | | --- | --- | --- | --- | | `weatherDescription` | Weather description | QString | — | | `weatherCondition` | Weather condition | QString | — | | `updateTime` | Last update | int | UnixTime | | `temperature` | Temperature | double | DegreeCelsius | | `temperatureMin` | Minimum temperature (today) | double | DegreeCelsius | | `temperatureMax` | Maximum temperature (today) | double | DegreeCelsius | | `humidity` | Humidity | int | Percentage | | `pressure` | Pressure | double | HectoPascal | | `windSpeed` | Wind speed | double | MeterPerSecond | | `windDirection` | Wind direction | int | Degree | | `cloudiness` | Cloudiness | int | Percentage | | `snowfall` | Snowfall (preceding hour) | double | CentiMeter | | `forecastGhi` | GHI forecast (W/m²) | double | — | | `forecastDni` | DNI forecast (W/m²) | double | — | | `forecastDhi` | DHI forecast (W/m²) | double | — | | `terrestrialRadiation` | TOA radiation (W/m2) | double | — | | `forecastGhiSumToday` | GHI sum forecast today (kWh/m²) | double | — | | `observedGhi` | GHI observed, satellite (W/m²) | double | — | | `observedClearSkyGhi` | Clear-sky GHI observed, satellite (W/m²) | double | — | | `observedClearSkyIndex` | Clear-sky index kt (observed) | double | — | | `sunriseTime` | Sunrise time | int | UnixTime | | `sunsetTime` | Sunset time | int | UnixTime | | `daylight` | Daylight | bool | — | | `forecastModel` | Forecast model that answered | QString | — | | `forecastValid` | Forecast valid | bool | — | | `forecastTendencyToday` | Sky tendency forecast today | QString | — | | `observedTime` | Satellite sample time | int | UnixTime | | `forecastIssuedAt` | Model run initialisation — revision key | int | UnixTime | | `forecastAvailableAt` | Model run publication — informational, never a revision key | int | UnixTime | ??? abstract "Open-Meteo PV plane — `openMeteoPvPlane`" _Settings:_ | Key | Label | Type | Range | Default | Read-only | | --- | --- | --- | --- | --- | --- | | `name` | Name | QString | — | — | no | | `tilt` | Tilt (deg, 0=horizontal) | double | 0–90 | `30` | no | | `azimuth` | Azimuth (deg geographic, 180=South) | double | 0–360 | `180` | no | | `kwp` | Peak power kWp | double | — | `0` | no | | `performanceRatio` | Performance ratio (declared, not learned) | double | 0.1–1.0 | `1.0` | no | _Measured quantities:_ | Key | Quantity | Type | Unit | | --- | --- | --- | --- | | `forecastGtiSource` | GTI forecast, source quantity (W/m²) | double | — | | `updateTime` | Last update | int | UnixTime | | `forecastPvPower` | PV power forecast | double | Watt | | `forecastEnergyNext3h` | PV energy forecast, next 3 h (rolling, may cross midnight) | double | KiloWattHour | | `forecastEnergyNext6h` | PV energy forecast, next 6 h (rolling, may cross midnight) | double | KiloWattHour | | `forecastEnergyNext12h` | PV energy forecast, next 12 h (rolling, may cross midnight) | double | KiloWattHour | | `forecastEnergyRestOfDay` | PV energy forecast, now until sunset | double | KiloWattHour | | `forecastEnergyTomorrow` | PV energy forecast, tomorrow | double | KiloWattHour | | `forecastPeakTime` | Forecast peak irradiance time today | int | UnixTime | | `observedGti` | GTI observed, satellite (W/m²) | double | — | | `observedGtiTime` | Satellite sample time | int | UnixTime | | `forecastWeatherSpreadTodayPercent` | GTI weather spread today — qualifies weather only, not PV accuracy | double | Percentage | | `forecastWeatherSpreadTomorrowPercent` | GTI weather spread tomorrow — qualifies weather only, not PV accuracy | double | Percentage | | `forecastSpreadModel` | Ensemble model used for spread | QString | — | | `forecastCurveTransport` | Forecast curve — transport channel, not a value | QVariantMap | — |