カレーのライスをtech忘れ

odmishienのtechメモ

OpenWeatherMapのWeatherAPIでFreeプランだけど明日の天気を取得したい

Freeプランでは明日の天気をDaily Forecastから取得できない

ちょっとハマったので記録を残しておく。 卒論生の作っているアプリでOpenWeatherMapのWeatherAPIを使っている。

openweathermap.org

今日の天気を取るのは簡単で、Current weather data - OpenWeatherMap を使えば良さそう。

問題は明日の天気の取り方で、Daily Forecast 16days を使えば簡単に取れるだろ〜とか思っていたら、Freeプランでは使えないAPIだった…。

>> curl http://api.openweathermap.org/data/2.5/forecast/daily?units=metric&q=Kobe&appid={YOUR_API_KEY}&cnt=1

{"cod":401, "message": "Invalid API key. Please see http://openweathermap.org/faq#error401 for more info."}

ちゃんとドキュメントに書いてあったので、ちゃんとドキュメント読もうねという気持ちになった。

openweathermap.org

解決方法その1: One Call APIを使う

openweathermap.org

大体必要そうな気象情報を返してくれる便利なエンドポイントで、無料アカウントでも利用することができる。ちなみに取得できる情報は

  • 現在の天気
  • 直近1時間分の分ごとの天気予報
  • 直近48時間分の時間ごとの天気予報
  • 直近7日分の日ごとの天気予報
  • 政府の出している気象警報
  • 5日前までの気象データ

である。この中の直近7日分の日ごとの天気予報を取ってくれば良さそう。

curl http://api.openweathermap.org/data/2.5/onecall?lat={lat}&lon={lon}&exclude=current,minutely,hourly,alerts&appid={YOUR_API_KEY}

exclude というパラメータに不要な項目を渡すことができる。あとはレスポンスからよしなに明日の天気を取り出すだけである。 注意すべきなのは 緯度軽度でしか検索ができない点である。都市の名前やZIPコードで検索したい場合は緯度経度への変換が必要になってしまうので、一手間かかる。

解決方法その2: 5 day weather forecast APIを使う

openweathermap.org

こちらも無料アカウントで利用できる。直近5日間の天気予報を返してくれるエンドポイントなのだが、注意すべきなのは3時間ごとにデータが区切られている点である。

今日のAM6:00をスタートとして、5日分の天気予報を3時間ごとに渡してくれる。cnt というパラメータを用いて、何個分のデータを取得するかを決められるようになっているので、明日の必要な時間までのデータを受け取るように cnt を指定する。例えば明日のAM9:00の天気は、今日のAM6時から27時間後のデータなので、 27 / 3 = 9 を cnt に指定する、といった具合である。(多分デフォルトで cnt は最大に設定されていそうなので、cnt を設定しなくても大丈夫そうではある。)

curl http://api.openweathermap.org/data/2.5/forecast?q={city name}&cnt=9&appid={YOUR_API_KEY}

{
  "cod": "200",
  "message": 0,
  "cnt": 40,
  "list": [
    {
      "dt": 1596564000,
      "main": {
        "temp": 293.55,
        "feels_like": 293.13,
        "temp_min": 293.55,
        "temp_max": 294.05,
        "pressure": 1013,
        "sea_level": 1013,
        "grnd_level": 976,
        "humidity": 84,
        "temp_kf": -0.5
      },
      "weather": [
        {
          "id": 500,
          "main": "Rain",
          "description": "light rain",
          "icon": "10d"
        }
      ],
      "clouds": {
        "all": 38
      },
      "wind": {
        "speed": 4.35,
        "deg": 309
      },
      "visibility": 10000,
      "pop": 0.49,
      "rain": {
        "3h": 0.53
      },
      "sys": {
        "pod": "d"
      },
      "dt_txt": "2020-08-04 18:00:00"
    },

    ...

"city": {
    "id": 2643743,
    "name": "London",
    "coord": {
      "lat": 51.5073,
      "lon": -0.1277
    },
    "country": "GB",
    "timezone": 0,
    "sunrise": 1578384285,
    "sunset": 1578413272
  }
}

data['list'] の中に3時間ごとのデータが入っているので、お目当ての 明日のAM9:00のデータは data['list'][10] に入っている。

エンドポイント多すぎて混乱するので、何か間違っているかもしれません.....。ご指摘お待ちしてます!!