PHPackages                             dle79/open-meteo - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [HTTP &amp; Networking](/categories/http)
4. /
5. dle79/open-meteo

ActiveLibrary[HTTP &amp; Networking](/categories/http)

dle79/open-meteo
================

Typed PHP 8.4 client for the Open-Meteo API

v0.9.2(1mo ago)00MITPHPPHP ^8.4CI passing

Since Mar 18Pushed 1mo agoCompare

[ Source](https://github.com/orionphp/open-meteo)[ Packagist](https://packagist.org/packages/dle79/open-meteo)[ RSS](/packages/dle79-open-meteo/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (3)Dependencies (10)Versions (5)Used By (0)

Orionphp Open-Meteo Client
==========================

[](#orionphp-open-meteo-client)

[![CI](...)](...)[![Latest Stable Version](https://camo.githubusercontent.com/f7b1d91110763fad1500a70e72eae70b9c4e933d11ef46d62441374afe68095c/68747470733a2f2f706f7365722e707567782e6f72672f646c6537392f6f70656e2d6d6574656f2f762f737461626c65)](https://packagist.org/packages/dle79/open-meteo)[![PHP Version Require](https://camo.githubusercontent.com/d22196b98bf9a08b260650aec2ae2e4fd71efa6afdc2fd7a6839a73c33760439/68747470733a2f2f706f7365722e707567782e6f72672f646c6537392f6f70656e2d6d6574656f2f726571756972652f706870)](https://packagist.org/packages/dle79/open-meteo)[![License: MIT](https://camo.githubusercontent.com/fdf2982b9f5d7489dcf44570e714e3a15fce6253e0cc6b5aa61a075aac2ff71b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d79656c6c6f772e737667)](LICENSE)

A typed PHP 8.4 client for the [Open-Meteo](https://open-meteo.com/) weather API — free, no API key required.

Supports:

- current conditions
- 15-minute intervals
- hourly forecasts
- daily forecasts
- 14+ global and regional weather models

---

Requirements
------------

[](#requirements)

- PHP **8.4+**
- A [PSR-18](https://www.php-fig.org/psr/psr-18/) HTTP client (e.g. Guzzle, Symfony HttpClient)
- A [PSR-17](https://www.php-fig.org/psr/psr-17/) request factory (e.g. `nyholm/psr7`)

---

Installation
------------

[](#installation)

```
composer require orionphp/open-meteo
```

You also need a PSR-18 client and a PSR-17 factory. If you don't have one yet:

```
composer require guzzlehttp/guzzle nyholm/psr7
```

---

Quick Start
-----------

[](#quick-start)

```
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\HttpFactory;
use Orionphp\OpenMeteo\OpenMeteoClient;
use Orionphp\OpenMeteo\Request\ForecastRequestBuilder;
use Orionphp\OpenMeteo\Enum\WeatherModel;
use Orionphp\OpenMeteo\Enum\CurrentField;
use Orionphp\OpenMeteo\Enum\HourlyField;

$httpFactory = new HttpFactory();
$client = new OpenMeteoClient(
    httpClient: new Client(),
    requestFactory: $httpFactory,
);

$request = ForecastRequestBuilder::create(52.52, 13.41)         // Berlin coordinates
    ->models(WeatherModel::ICON_D2)     // required: at least one model
    ->timezone('Europe/Berlin')
    ->current(CurrentField::TEMPERATURE_2M, CurrentField::WEATHER_CODE)
    ->hourly(HourlyField::TEMPERATURE_2M, HourlyField::PRECIPITATION)
    ->build();

$forecast = $client->forecast($request);

// Current conditions
$current = $forecast->current;
echo $current->field(CurrentField::TEMPERATURE_2M)->value();   // e.g. 14.3
echo $current->field(CurrentField::TEMPERATURE_2M)->unit();    // °C

// Hourly data
$hourly = $forecast->hourly;
$temps  = $hourly->field(HourlyField::TEMPERATURE_2M)->values(WeatherModel::ICON_D2);
$times  = $hourly->time(); // list of ISO 8601 strings
```

---

Building a Forecast Request
---------------------------

[](#building-a-forecast-request)

All requests are created through `ForecastRequestBuilder`. Coordinates are validated on creation — invalid values throw `InvalidCoordinatesException`.

```
$request = ForecastRequestBuilder::create(float $latitude, float $longitude)
    ->models(WeatherModel ...$models)       // required: at least one model
    ->timezone(string $timezone)            // optional: valid PHP timezone string
    ->current(CurrentField ...$fields)
    ->minutely15(Minutely15Field ...$fields)
    ->hourly(HourlyField ...$fields)
    ->daily(DailyField ...$fields)
    ->build();
```

Every field setter accepts PHP variadic enums. Duplicate entries are deduplicated automatically.

---

Weather Models
--------------

[](#weather-models)

```
use Orionphp\OpenMeteo\Enum\WeatherModel;
```

ConstantValueRegion`BEST_MATCH``best_match`Auto-select (recommended)`ECMWF_IFS``ecmwf_ifs`Global`GFS``gfs`Global`ICON_GLOBAL``icon_global`Global`GEM_GLOBAL``gem_global`Global`JMA_GSM``jma_gsm`Global`UKMO_GLOBAL``ukmo_global`Global`ICON_EU``icon_eu`Europe`ICON_D2``icon_d2`Germany / Central Europe`METEOFRANCE_ARPEGE``meteofrance_arpege`Europe`METEOFRANCE_AROME``meteofrance_arome`France`DMI_HARMONIE_AROME_EUROPE``dmi_harmonie_arome_europe`Europe`KNMI_HARMONIE_AROME_NETHERLANDS``knmi_harmonie_arome_netherlands`Netherlands`HRRR``hrrr`United States`NAM_CONUS``nam_conus`United States### Model helpers

[](#model-helpers)

```
// Automatically select the most precise models for a coordinate
$models = WeatherModel::recommendedFor(52.52, 13.41);

// Get only the single best model
$model = WeatherModel::bestFor(52.52, 13.41);

// Introspect a model
WeatherModel::ICON_D2->isGlobal();    // false
WeatherModel::ICON_D2->isEuropean();  // true
WeatherModel::ICON_D2->isRegional();  // true
```

### Combining multiple models

[](#combining-multiple-models)

When you request more than one model, each field in the response carries per-model value arrays:

```
$request = ForecastRequestBuilder::create(48.85, 2.35)   // Paris
    ->models(WeatherModel::METEOFRANCE_AROME, WeatherModel::ECMWF_IFS)
    ->hourly(HourlyField::TEMPERATURE_2M)
    ->build();

$forecast = $client->forecast($request);
$field    = $forecast->hourly->field(HourlyField::TEMPERATURE_2M);

$aromeTemps = $field->values(WeatherModel::METEOFRANCE_AROME);
$ecmwfTemps = $field->values(WeatherModel::ECMWF_IFS);
```

---

Forecast Intervals
------------------

[](#forecast-intervals)

### Current conditions

[](#current-conditions)

```
use Orionphp\OpenMeteo\Enum\CurrentField;

// Available fields
CurrentField::TEMPERATURE_2M
CurrentField::APPARENT_TEMPERATURE
CurrentField::WEATHER_CODE
CurrentField::RELATIVE_HUMIDITY_2M
CurrentField::WIND_SPEED_10M
CurrentField::WIND_DIRECTION_10M
CurrentField::WIND_GUSTS_10M
CurrentField::PRECIPITATION
CurrentField::RAIN
CurrentField::SNOWFALL
CurrentField::SNOW_DEPTH
CurrentField::CLOUD_COVER
CurrentField::PRESSURE_MSL
CurrentField::SURFACE_PRESSURE
CurrentField::VISIBILITY
CurrentField::UV_INDEX
CurrentField::DEW_POINT_2M
CurrentField::IS_DAY
CurrentField::PRECIPITATION_PROBABILITY
CurrentField::SHOWERS

// Usage
$current = $forecast->current;          // ?CurrentData
$current->time();                        // e.g. "2026-03-17T12:00"
$data = $current->field(CurrentField::TEMPERATURE_2M);
$data->value();                          // float|int|string|null
$data->unit();                           // e.g. "°C"
```

### 15-minute intervals

[](#15-minute-intervals)

```
use Orionphp\OpenMeteo\Enum\Minutely15Field;

$minutely = $forecast->minutely15;       // ?Minutely15Data
$minutely->time();                       // list
$minutely->field(Minutely15Field::PRECIPITATION)->values(WeatherModel::ICON_D2);
```

Available fields: `TEMPERATURE_2M`, `APPARENT_TEMPERATURE`, `RELATIVE_HUMIDITY_2M`, `DEW_POINT_2M`, `PRECIPITATION`, `RAIN`, `SNOWFALL`, `SHOWERS`, `WEATHER_CODE`, `CLOUD_COVER`, `WIND_SPEED_10M`, `WIND_DIRECTION_10M`, `WIND_GUSTS_10M`, `VISIBILITY`, `SHORTWAVE_RADIATION`, `DIRECT_RADIATION`, `DIFFUSE_RADIATION`, `DIRECT_NORMAL_IRRADIANCE`

### Hourly

[](#hourly)

```
use Orionphp\OpenMeteo\Enum\HourlyField;

$hourly = $forecast->hourly;             // ?HourlyData
$hourly->time();                         // list
$hourly->field(HourlyField::UV_INDEX)->values(WeatherModel::ECMWF_IFS);
$hourly->availableFields();              // list
```

Available fields include: `TEMPERATURE_2M`, `APPARENT_TEMPERATURE`, `WEATHER_CODE`, `RELATIVE_HUMIDITY_2M`, `DEW_POINT_2M`, `PRECIPITATION`, `PRECIPITATION_PROBABILITY`, `RAIN`, `SHOWERS`, `SNOWFALL`, `SNOW_DEPTH`, `CLOUD_COVER`, `WIND_SPEED_10M`, `WIND_DIRECTION_10M`, `WIND_GUSTS_10M`, `PRESSURE_MSL`, `SURFACE_PRESSURE`, `VISIBILITY`, `UV_INDEX`, `SHORTWAVE_RADIATION`, `DIRECT_RADIATION`, `DIFFUSE_RADIATION`, `DIRECT_NORMAL_IRRADIANCE`, `EVAPOTRANSPIRATION`, `ET0_FAO_EVAPOTRANSPIRATION`, `VAPOUR_PRESSURE_DEFICIT`, `CAPE`, and soil temperature fields at 0 cm, 6 cm, 18 cm, 54 cm.

### Daily

[](#daily)

```
use Orionphp\OpenMeteo\Enum\DailyField;

$daily = $forecast->daily;               // ?DailyData
$daily->time();                          // list — one entry per day
$daily->field(DailyField::TEMPERATURE_2M_MAX)->values(WeatherModel::ICON_D2);
```

Available fields: `WEATHER_CODE`, `TEMPERATURE_2M_MAX`, `TEMPERATURE_2M_MIN`, `APPARENT_TEMPERATURE_MAX`, `APPARENT_TEMPERATURE_MIN`, `PRECIPITATION_SUM`, `PRECIPITATION_PROBABILITY_MAX`, `RAIN_SUM`, `SHOWERS_SUM`, `SNOWFALL_SUM`, `SNOW_DEPTH_MAX`, `WIND_SPEED_10M_MAX`, `WIND_GUSTS_10M_MAX`, `WIND_DIRECTION_10M_DOMINANT`, `SUNRISE`, `SUNSET`, `SUNSHINE_DURATION`, `UV_INDEX_MAX`, `SHORTWAVE_RADIATION_SUM`, `ET0_FAO_EVAPOTRANSPIRATION`

---

Weather Code Translations
-------------------------

[](#weather-code-translations)

WMO weather codes returned by the API can be translated to human-readable strings in multiple languages.

```
use Orionphp\OpenMeteo\Enum\WeatherCode;
use Orionphp\OpenMeteo\Enum\Locale;
use Orionphp\OpenMeteo\Translation\WeatherCodeTranslation;

$translator = new WeatherCodeTranslation();

$code = WeatherCode::fromInt(63); // ModerateRain
$translator->translate($code, Locale::EN); // "Moderate rain"
$translator->translate($code, Locale::DE); // "Mäßiger Regen"
$translator->translate($code, Locale::FR); // "Pluie modérée"
$translator->translate($code, Locale::ES); // "Lluvia moderada"
```

**Supported locales:** `de`, `en`, `es`, `fr`

Translation files are plain PHP arrays. You can supply your own locale directory:

```
$translator = new WeatherCodeTranslation('/path/to/your/locales');
```

A locale file must return an `array` keyed by WMO weather code integer.

---

Logging
-------

[](#logging)

`OpenMeteoClient` accepts any [PSR-3](https://www.php-fig.org/psr/psr-3/) logger as an optional third constructor argument. When omitted, a `NullLogger` is used.

```
use Monolog\Logger;
use Monolog\Handler\StreamHandler;

$logger = new Logger('open-meteo');
$logger->pushHandler(new StreamHandler('php://stdout'));

$client = new OpenMeteoClient(
    httpClient: new Client(),
    requestFactory: $httpFactory,
    logger: $logger,
);
```

Logged events:

LevelEvent`info`Outgoing request URL`error`HTTP client exception`error`Non-2xx response status`error`Invalid or unexpected JSON---

Error Handling
--------------

[](#error-handling)

All exceptions extend `OpenMeteoException`. Catch specifically or broadly as needed:

```
use Orionphp\OpenMeteo\Exception\OpenMeteoException;
use Orionphp\OpenMeteo\Exception\InvalidCoordinatesException;
use Orionphp\OpenMeteo\Exception\InvalidTimezoneException;
use Orionphp\OpenMeteo\Exception\InvalidWeatherModelException;

try {
    $forecast = $client->forecast($request);
} catch (InvalidCoordinatesException $e) {
    // Latitude/longitude out of valid range
} catch (InvalidTimezoneException $e) {
    // Timezone string not recognized by PHP
} catch (InvalidWeatherModelException $e) {
    // WeatherModel::fromString() called with unknown value
} catch (OpenMeteoException $e) {
    // HTTP error, non-2xx status, or malformed JSON response
}
```

---

Development
-----------

[](#development)

```
# Install dependencies
composer install

# Run the full check suite (code style + static analysis + tests)
composer check

# Individual tools
composer cs          # Fix code style (PHP-CS-Fixer)
composer cs-check    # Dry-run code style check
composer stan        # PHPStan level 9
composer test        # PHPUnit
```

CI runs automatically on every push and pull request via GitHub Actions.

---

License
-------

[](#license)

MIT — see [LICENSE](LICENSE) for details.

###  Health Score

38

—

LowBetter than 84% of packages

Maintenance96

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity44

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

3

Last Release

50d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/9df3f3a3956fe05067dee583539f1dbe53d505c239b49579595978383b16695f?d=identicon)[orionphp](/maintainers/orionphp)

---

Top Contributors

[![orionphp](https://avatars.githubusercontent.com/u/264121518?v=4)](https://github.com/orionphp "orionphp (15 commits)")

---

Tags

phppsr-18api clientweatherforecastphp-api-clientweather forecastopen-meteoopenmeteometeorologyfree-apiweather apiweather-dataweather-modelweathercodefree weather api

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/dle79-open-meteo/health.svg)

```
[![Health](https://phpackages.com/badges/dle79-open-meteo/health.svg)](https://phpackages.com/packages/dle79-open-meteo)
```

###  Alternatives

[aporat/store-receipt-validator

PHP receipt validator for Apple App Store and Amazon Appstore

6503.9M9](/packages/aporat-store-receipt-validator)[phpro/http-tools

HTTP tools for developing more consistent HTTP implementations.

28137.8k](/packages/phpro-http-tools)[claude-php/claude-php-sdk

A universal, framework-agnostic PHP SDK for the Anthropic Claude API with PSR compliance

13920.7k2](/packages/claude-php-claude-php-sdk)[art4/requests-psr18-adapter

Use WordPress/Requests as a PSR-18 HTTP client

153.3k](/packages/art4-requests-psr18-adapter)[chillerlan/php-httpinterface

A PSR-7/17/18 http message/client implementation

1417.1k5](/packages/chillerlan-php-httpinterface)[segrax/open-policy-agent

Open Policy Agent client and PSR-7, PSR-15 Authorization Middleware

212.0k](/packages/segrax-open-policy-agent)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
