The Danish Meteorological Institute (DMI) does unfortunately not offer an official API (yet).
This package is (in some form) a workaround for that. It collects all weather data (forecasts and archived) from the official DMI website and turns it into structured data objects.
Note: Since the data is being extracted from a the website, there is a risk of the package could stop working, if the website does any breaking changes.
Should this happen, please don't hesitate to create an issue and I will look into it as quickly as possible
As part of the danish governments desire to become one of the digital frontrunners, they have decided that the Danish Meteorological Institute (DMI) has to make all of their data available to the public.
The data will be released in multiple stages over the next 3 years, starting from Q3 in 2019 until Q4 in 2022. Unfortunately there is not much information on how the data will be released.
Depending on how the data will be released, this package will be subject to changes in the future.
Since the data is not officially released, this package is made available under a very strict license, which prohibits any use other than personal.
When DMI releases the data publicly, the license will be changed to a more open source-friendly (MIT) version.
Name | Description | Supported |
---|---|---|
National forecasts | National descriptive forecasts (incl. 7 days forecast) | ✅ |
Search | Search pre-defined locations | ✅ |
Location | Weather data/forecast for a pre-defined location | ✅ |
Location by coordinate | Weather data/forecast for a location based on coordinates (latitude/longitude) | ✅ |
Weather warnings | National weather warnings | ✅ |
Sun times | Time of sunrise and sunset | ✅ |
UV index | Current UV index | ✅ |
Pollen | Current Pollen measurements | ✅ |
Sea stations | All national sea stations and their observations and forecasts | ✅ |
Sea station by ID | Observations and forecasts from a specific sea station | ✅ |
Archive | Hourly, daily, monthly and yearly data from the DMI archive | ✅ |
Satellite | Satellite imagery | ❌ |
Maritime forecasts | Forecasts around the coasts of Denmark, Greenland & Faroe Islands | ❌ |
Ice charts | Ice charts along the coasts of Greenland | ❌ |
You can install the package via Composer, by using the following command:
composer require rugaard/dmi
This package comes with a out-of-the-box Service Provider for the Laravel framework.
If you're using a newer version of Laravel (>= 5.5
) then the service provider will loaded automatically.
Are you using an older version, then you need to manually add the service provider to the config/app.php
file:
'providers' => [
Rugaard\DMI\Providers\Laravel\ServiceProvider::class,
]
First thing you need to do, is to instantiate the DMI
client
# Instantiate the DMI client.
$dmi = new \Rugaard\DMI\DMI;
Once you've done that, you're able to request one or more of the supported features:
# National forecast.
$forecast = $dmi->forecast();
# Location by coordinate.
$location = $dmi->locationByCoordinate(55.67594, 12.56553);
# National warnings.
$warnings = $dmi->warnings();
The DMI client which handles all request DMI.
new DMI(?int $defaultLocationId, ?Client $httpClient);
Parameter | Type | Default | Description |
---|---|---|---|
$defaultLocationId |
int |
null |
Set default location ID |
$httpClient |
\GuzzleHttp\ClientInterface |
null |
Replace the default underlying HTTP Client |
Get the latest national descriptive forecast.
forecast();
Get the extended (7-days) national descriptive forecast.
extendedForecast();
Search locations by name.
search(string $query, int $limit);
Parameter | Type | Default | Description |
---|---|---|---|
$query |
string |
- | Search query |
$limit |
int |
20 |
Max. number of locations to return. |
Get current weather condition and latest forecast for a pre-defined location.
Note: $includeRegional
is required to get municipality
and region
of location.
location(?int $locationId, bool $includeRegional, bool $includeWarnings);
Parameter | Type | Default | Description |
---|---|---|---|
$locationId |
int |
null |
ID of location (If null , it'll use the default location ID from the DMI client.) |
$includeRegional |
bool |
true |
Include regional data and forecast for location * |
$includeWarnings |
bool |
true |
Include weather warnings specific for location * |
*
Makes additional request to DMI.
Get current weather condition and latest forecast for a location specified by coordinates.
Note: $includeRegional
is required to get municipality
and region
of location.
locationByCoordinate(float $latitude, float $longitude, bool $includeRegional, bool $includeWarnings);
Parameter | Type | Default | Description |
---|---|---|---|
$latitude |
float |
- | Latitude part of coordinate |
$longitude |
float |
- | Longitude part of coordinate |
$includeRegional |
bool |
true |
Include regional data and forecast for location * |
$includeWarnings |
bool |
true |
Include weather warnings specific for location * |
*
Makes additional request to DMI.
Get national weather warnings.
warnings();
Get time of the sunrise and sunset, for the next 14 days, for a pre-defined location.
sunTimes(?int $locationId);
Parameter | Type | Default | Description |
---|---|---|---|
$locationId |
int |
null |
ID of location (If null , it'll use the default location ID from the DMI client.) |
Get the current UV index for a pre-defined location.
uv(?int $locationId);
Parameter | Type | Default | Description |
---|---|---|---|
$locationId |
int |
null |
ID of location (If null , it'll use the default location ID from the DMI client.) |
Get the current national pollen measurements.
pollen();
Get all sea stations belonging to DMI.
seaStations(bool $withObservations, bool $withForecast);
Parameter | Type | Default | Description |
---|---|---|---|
$withObservations |
bool |
false |
Include observation data from each station * |
$withForecast |
bool |
false |
Include forecast data for each station * |
*
Makes additional request to DMI.
Get a specific sea stations.
seaStation(int $stationId, bool $withObservations, bool $withForecast);
Parameter | Type | Default | Description |
---|---|---|---|
$stationId |
int |
- | ID of sea station |
$withObservations |
bool |
false |
Include observation data from each station * |
$withForecast |
bool |
false |
Include forecast data for each station * |
*
Makes additional request to DMI.
Get archived weather data.
archive(string $measurement, string $frequency, $period, ?int $municipalityId, string $country);
Parameter | Type | Default | Description |
---|---|---|---|
$measurement |
string |
- | temperature , precipitation , wind , wind-direction , humidity , pressure , sun , drought , lightning or snow |
$frequency |
string |
- | hourly , daily , monthly or yearly |
$period |
string or DateTime |
- | hourly /daily = YYYY-mm-dd , monthly = YYYY-mm or yearly = YYYY |
$municipalityId |
int |
null |
Limit archived data to a specific municipality. See the full list of available municipality IDs |
$country |
string |
DK |
DK = Denmark, GL = Greenland, FO = Faroe Islands |
When getting weather data from a location, the response will contain an $icon
value. The purpose of this value is to determine which icon represents the current weather conditions.
In the table below is a list of all possible icons and values. Each icon is associated with a suggested emoji or image.
I would recommend downloading the free icon pack from Pixel Perfect, since it's one of the few ones, that both contains a day and night version of each condition - while still being free.
Denmark is split into 98 municipalities. In the list below are all the municipalities and their corresponding ID.
Name | ID | Name | ID | Name | ID | Name | ID |
---|---|---|---|---|---|---|---|
Albertslund | 165 | Allerød | 201 | Assens | 420 | Ballerup | 151 |
Billund | 530 | Bornholm | 400 | Brøndby | 153 | Brønderslev | 810 |
Dragør | 155 | Egedal | 240 | Esbjerg | 561 | Fanø | 563 |
Favrskov | 710 | Faxe | 320 | Fredensborg | 210 | Fredericia | 607 |
Frederiksberg | 147 | Frederikshavn | 813 | Frederikssund | 250 | Furesø | 190 |
Faaborg-Midtfyn | 430 | Gentofte | 157 | Gladsaxe | 159 | Glostrup | 161 |
Greve | 253 | Gribskov | 270 | Guldborgsund | 376 | Haderslev | 510 |
Halsnæs | 260 | Hedensted | 766 | Helsingør | 217 | Herlev | 163 |
Herning | 657 | Hillerød | 219 | Hjørring | 860 | Holbæk | 316 |
Holstebro | 661 | Horsens | 615 | Hvidovre | 167 | Høje-Taastrup | 169 |
Hørsholm | 223 | Ikast-Brande | 756 | Ishøj | 183 | Jammerbugt | 849 |
Kalundborg | 326 | Kerteminde | 440 | Kolding | 621 | København | 101 |
Køge | 259 | Langeland | 482 | Lejre | 350 | Lemvig | 665 |
Lolland | 360 | Lyngby-Taarbæk | 173 | Læsø | 825 | Mariagerfjord | 846 |
Middelfart | 410 | Morsø | 773 | Norddjurs | 707 | Nordfyns | 480 |
Nyborg | 450 | Næstved | 390 | Odder | 727 | Odense | 461 |
Odsherred | 306 | Randers | 730 | Rebild | 840 | Ringkøbing-Skjern | 760 |
Ringsted | 329 | Roskilde | 265 | Rudersdal | 230 | Rødovre | 175 |
Samsø | 741 | Silkeborg | 740 | Skanderborg | 746 | Skive | 779 |
Slagelse | 330 | Solrød | 269 | Sorø | 340 | Stevns | 336 |
Struer | 671 | Svendborg | 479 | Syddjurs | 706 | Sønderborg | 540 |
Thisted | 787 | Tønder | 550 | Tårnby | 185 | Vallensbæk | 187 |
Varde | 573 | Vejen | 575 | Vejle | 630 | Vesthimmerland | 820 |
Viborg | 791 | Vordingborg | 390 | Ærø | 492 | Aabenraa | 580 |
Aalborg | 851 | Aarhus |
There are two ways to find it:
-
Use this package's search endpoint.
-
Go to DMI's website and use the search feature in the top right corner. If your desired location pops up; click on it and you will be directed to the locations page. You can now copy/paste the ID from the locations URL.
https://www.dmi.dk/lokation/show/DK/
2618425
/København/
All endpoints returns data within a Tightenco\Collect\Support\Collection
class. The class is a port of the popular Collection
class from Laravel.
Please refer to Laravel's detailed documentation, to learn more about how you work with a Collection
:
https://laravel.com/docs/master/collections
Some endpoints, like National forecasts, sunrise and sunset and pollen measurements are endpoints which doesn't change/update very often.
By implementing some form of internal caching, we could cache these kind of endpoints. This would increase the response time and we would avoid making unnecessary requests to DMI.
This package is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 (CC BY-NC-ND 4.0).