decalages/meteociel-api
Composer 安装命令:
composer require decalages/meteociel-api
包简介
PHP client for Météociel data (forecasts, soundings, stations)
README 文档
README
PHP client for scraping weather data from Météociel: forecasts, station observations, and upper air soundings.
Ported from the original Python package.
Requirements
- PHP 8.1+
- Extensions:
dom,json - Composer
Installation
composer require meteo-api/meteociel-api
Laravel
The package supports Laravel's package auto-discovery. No manual registration needed — the service provider and Meteociel facade are registered automatically.
Publish the config file (optional):
php artisan vendor:publish --tag=meteociel-config
This creates config/meteociel.php. You can then set values in your .env:
METEOCIEL_TIMEOUT=15 METEOCIEL_DATABASE_PATH=/absolute/path/to/cities_database.json
The database defaults to storage/app/meteociel/cities_database.json.
Quick start
Standalone PHP
<?php require 'vendor/autoload.php'; $api = new Meteociel\Meteociel();
Laravel
Inject the class via the service container:
use Meteociel\Meteociel; class WeatherController extends Controller { public function __construct(private Meteociel $meteociel) {} public function forecast() { $result = $this->meteociel->forecasts->forecast(cityName: 'Paris (75000)'); return response()->json($result['data']); } }
Or use the facade:
use Meteociel\Facades\Meteociel; $result = Meteociel::forecasts->forecast(cityName: 'Lyon (69000)');
Forecasts
Retrieve weather forecasts (up to 3 days) or trends (up to 10 days) for any city worldwide.
$result = $api->forecasts->forecast( cityName: 'Paris (75000)', mode: 'forecasts', // 'forecasts' (default) or 'trends' model: 'arome-1h' // see available models below ); echo $result['cityName']; // "paris" foreach ($result['data'] as $row) { echo $row['date'] . ' | '; echo $row['temperature'] . '°C | '; echo $row['wind_spd'] . ' km/h' . PHP_EOL; }
You can also search by city ID (takes precedence over name):
$result = $api->forecasts->forecast(cityId: '49679', mode: 'trends');
Each row in $result['data'] contains:
| Key | Type | Description |
|---|---|---|
date |
string |
ISO datetime (Y-m-d H:i:s) |
temperature |
float|null |
Temperature (°C) |
windchill |
float|null |
Feels-like temperature (°C) |
wind_dir |
float|null |
Wind direction (°) |
wind_spd |
float|null |
Wind speed (km/h) |
wind_gust |
float|null |
Wind gust (km/h) |
rain |
float|null |
Precipitation (mm) |
humidity |
float|null |
Relative humidity (%) |
pressure |
float|null |
Pressure (hPa) |
Available models
| Model | Coverage | Resolution |
|---|---|---|
gfs (default) |
Global | 25 km |
wrf / wrf-1h |
Western Europe | 5 km |
arome / arome-1h |
France | 1 km |
arpege-1h |
Europe | 10 km |
iconeu |
Europe | 7 km |
icond2 |
Central Europe | 2.2 km |
Models with
-1hsuffix provide hourly data. Models are only applicable inforecastsmode; they are ignored intrendsmode.
Station observations
Retrieve intra-day station data for a city on a given date.
$result = $api->stations->station( new DateTime('2022-08-18'), 'Ajaccio' ); echo $result['cityName']; // "ajaccio" foreach ($result['data'] as $row) { echo $row['time (local)'] . ' | '; echo $row['temperature'] . '°C | '; echo $row['pressure'] . ' hPa' . PHP_EOL; }
Each row contains:
| Key | Type | Description |
|---|---|---|
time (local) or time (GMT) |
string |
Observation time |
visibility |
float|null |
Visibility (km) |
temperature |
float|null |
Temperature (°C) |
humidity |
float|null |
Relative humidity (%) |
dew_point |
float|null |
Dew point (°C) |
wind_dir |
string|null |
Wind direction |
wind_spd |
float|null |
Wind speed (km/h) |
wind_gust |
float|null |
Wind gust (km/h) |
pressure |
float|null |
Pressure (hPa) |
Upper air soundings
From observations
Available at 00:00, 06:00, 12:00, and 18:00 UTC only.
$result = $api->soundings->soundingObs( new DateTime('2022-08-18 00:00'), 'Ajaccio' ); echo $result['cityName']; // "ajaccio" foreach ($result['data'] as $row) { echo $row['altitude'] . ' m | '; echo $row['temperature'] . '°C | '; echo $row['pressure'] . ' hPa' . PHP_EOL; }
You must generate the cities database before using this method (see Cities database).
From AROME model
By city name:
$result = $api->soundings->soundingArome( cityName: 'Rennes', timestep: 6 // hours since the start of the AROME run );
By coordinates:
$result = $api->soundings->soundingArome(lon: 5.0, lat: 42.0, timestep: 12); echo $result['cityName']; // "42N-5E_..."
Each row contains:
| Key | Type | Description |
|---|---|---|
altitude |
float|null |
Altitude (m) |
pressure |
float|null |
Pressure (hPa) |
temperature |
float|null |
Temperature (°C) |
wetbulb_temperature |
float|null |
Wet-bulb temperature (°C) |
dew_point |
float|null |
Dew point (°C) |
humidity |
float|null |
Relative humidity (%) |
wind_u |
float|null |
U wind component (km/h) |
wind_v |
float|null |
V wind component (km/h) |
Cities database
The sounding observations module requires a local JSON database of cities. Generate it once (takes several seconds — fetches thousands of cities from Météociel):
$api->cities->generateDatabase(); // Creates cities_database.json in the current working directory
Searching for cities
// Search by name (fuzzy matching included) $matches = $api->cities->getCity('Ajaccio'); // Restrict to cities with upper air sounding data $matches = $api->cities->getCity('Ajaccio', keys: ['has-sounding' => true]); // Match all cities in France with a synop station $matches = $api->cities->getCity('', keys: [ 'has-station' => true, 'station-type' => 'synop', 'country' => 'france', ]); // Increase fuzzy tolerance (default: 2) $matches = $api->cities->getCity('Ajacio', maxDelta: 3);
getCity() returns an associative array keyed by city ID:
[
"7761" => [
"names" => ["ajaccio", "ajaccio - campo dell'oro"],
"has-sounding" => true,
"has-station" => true,
"station-type" => "synop",
"country" => "france",
],
...
]
Station types
| Type | Description |
|---|---|
synop |
Main weather station |
metar |
Aviation station |
secondaire |
Secondary station |
amateur |
Amateur station |
inactive |
No longer active |
Error handling
use Meteociel\Exceptions\CityNotFoundException; use Meteociel\Exceptions\TooManyCitiesException; use Meteociel\Exceptions\UnknownModeException; use Meteociel\Exceptions\UnknownModelException; try { $result = $api->forecasts->forecast(cityName: 'Springfield'); } catch (TooManyCitiesException $e) { // Multiple cities matched — refine the search echo $e->getMessage(); } catch (CityNotFoundException $e) { // No city found in the database echo $e->getMessage(); } catch (UnknownModeException | UnknownModelException $e) { echo $e->getMessage(); } catch (\RuntimeException $e) { // HTTP or parsing errors echo $e->getMessage(); }
Custom HTTP client
You can inject a pre-configured Guzzle client, for example to set a proxy or custom headers:
use GuzzleHttp\Client; $client = new Client([ 'timeout' => 30, 'proxy' => 'http://proxy.example.com:8080', 'headers' => ['User-Agent' => 'my-app/1.0'], ]); $api = new Meteociel\Meteociel($client);
License
MIT — see LICENSE.
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 1
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-06-22