親子IoTワークショップ

マイコンとクラウドを使ってIoTとプログラミングを学ぼう

[ トップ | 開催予定・概要 | 2024-12開催 | お知らせ | Facebook ]

天気情報の取得

ここでは、Pythonを使って天気情報(現在の天気や天気予報)を取得する方法を説明します。

OpenWeather

以下では、OpenWeatherの天気情報を利用します。OpenWeatherは、無料の天気情報サービスです。1秒に1回以上の頻度でアクセスすると有料になりますが、ラズパイを使ったホビー・プロジェクトでこの制限が問題なることはまずありません。

OpenWeatherから天気情報をダウンロードするには、「API Key」というものを作る必要があります。まずは、OpenWeatherのWebサイトで自分のアカウントを作成してください。その後ログインし、ページ右上に表示される自分のユーザ名をクリックすると、以下の写真にあるような「API Keys」というメニューが現れます。それをクリックしてください。

次に、ページ右側にある「Create key」というところで「Generate」というボタンをクリックしてAPI Keyを生成します。生成するAPI Keyに名前をつけるボックスがありますが、適当な名前をつけておいてください(名前自体は重要ではありません)。

ページ左側に、アルファベットと数字をランダムに並べたような文字列が表示されます。それがAPI Keyです。のちほどこれを使います。

OpenWeatherから現在の天気情報を取得する

weather-temp.pyopenweather.pyをラズパイ上のThonnyへコピーして保存してください。この2つのファイルは同じフォルダの中に保存してください。weather-temp.pyは、OpenWeatherから天気情報をダウンロードして現在の気温と湿度を読みとるプログラムです。

OpenWeatherから天気情報をダウンロードするには、以下の行をプログラムの先頭部分に書きます。詳細は避けますが、天気情報を読みとるための「おまじない」だと思っておいてください。

from openweather import *

そして、3行目の

weatherApiKey = ""

を書き換えます。先ほど作ったAPI keyを変数weatherApiKeyに入れてください。例えば、API keyが「1234abcd」なら、

weatherApiKey = "1234abcd"

とします。これでプログラムが実行可能になります。

続いて5-9行目では、緯度(latitude)と経度(longitude)を使ってOpenWeatherから天気情報をダウンロードしています。

# Latitude and longitude of Logan airport
latitude = 42.3656
longitude = -71.0096

weatherData = getLatLonWeather(latitude, longitude, "imperial", weatherApiKey)

Pythonは、「#」から始まる行を「プログラムではない」と解釈して無視します。したがって、上記の最初の行を、Pythonは「プログラムではないもの」として無視します。このように「#」から始まる行のことを「コメント」といいます。Pythonにとっては無意味でも人間には役立つようなこと(メモのようなもの)を「コメント」として残すことがあります。上記のコメントは、「緯度42.3656度、経度-71.0096というのはローガン空港の位置ですよ」というメモです。

上記の例のように、緯度と経度を使って天気情報を検索、ダウンロードするには関数getLatLonWeather()を使います。getLatLonWeather()に渡すデータは、緯度(小数)、経度(小数)、単位系(”metric”か”imperial”)、OpenWeatherのAPI key(文字)です。単位系の「metric」はメートル、摂氏など、日本や世界の多くの国で採用されているもので、「imperial」はマイル、華氏など、アメリカなどで採用されているものです。なじみのある方を使ってください。

関数getLatLonWeather()は、OpenWeatherからダウンロードした天気情報を返します。上記の例では、この天気情報は変数weatherDataに格納されています。そして、それを使って別の関数getCurrentTempHumidity()を呼びます。

temp, feelsLike, humidity = getCurrentTempHumidity(weatherData)

getCurrentTempHumidity()は、3つのデータを返します。順に、

です。

次に、18-20行目では、アメリカの都市名と州名を使ってOpenWeatherから天気情報をダウンロードしています。

cityName = "Boston"
stateCode = "MA"
weatherData = getUsWeather(cityName, stateCode, "metric", weatherApiKey)

アメリカの都市名と州名を使って天気情報を検索、ダウンロードするには関数getUsWeather()を使います。getUsWeather()に渡すデータは、都市名(文字)、州名(文字)、単位系(”metric”か”imperial”)、OpenWeatherのAPI key(文字)です。州名には、2文字の州コードを使ってください。例えばマサチューセッツならMA、カリフォルニアならCAなど。州コードの一覧はこちら

関数getUsWeather()は、OpenWeatherからダウンロードした天気情報を返します。上記の例では、この天気情報は変数weatherDataに格納されています。そして、それを使って別の関数getCurrentTempHumidity()を呼びます。

temp, feelsLike, humidity = getCurrentTempHumidity(weatherData)

郵便番号(zipcode)を使って天気情報を検索、ダウンロードすることもできます(27-29行目)。関数getZipWeather()を使います。

zipCode = "02125"
countryCode = "US"
weatherData = getZipWeather(zipCode, countryCode, "imperial", weatherApiKey)

getZipWeather()に渡すデータは、郵便番号(文字)、国名(文字)、単位系(”metric”か”imperial”)、OpenWeatherのAPI key(文字)です。郵便番号は、数字ではなく文字で表現してください。つまり、例えば02125ではなく、”02125”としてください。国名には、2文字の国コードを使ってください。例えばアメリカならUS、日本ならJPなど。国コードの一覧はこちら

日本の郵便番号で天気情報を検索、ダウンロードする時には、郵便番号にはハイフン「-」を入れても、入れなくても構いません。例えば、”194-0013”でも”1940013”でも正常に動作します(45-47行目参照)。

アメリカ以外の国の都市名を使って天気情報を検索、ダウンロードすることもできます(36-38行目)。関数getIntlWeather()を使います。

cityName = "Sagamihara"
countryCode = "JP"
weatherData = getIntlWeather(cityName, countryCode, "metric", weatherApiKey)

getIntlWeather()に渡すデータは、都市名(文字)、国名(文字)、単位系(”metric”か”imperial”)、OpenWeatherのAPI key(文字)です。

まとめると、OpenWeatherから天気情報を検索、ダウンロードするには以下の4つの方法があります。

検索方法 使う関数
緯度と経度を使って検索 getLatLonWeather()を使う。この関数に渡すデータは、緯度(小数)、経度(小数)、単位系(”metric”か”imperial”)、OpenWeatherのAPI key(文字)。
アメリカの都市名と州名を使って検索 getUsWeather()を使う。この関数に渡すデータは、都市名(文字)、州名(文字)、単位系(”metric”か”imperial”)、OpenWeatherのAPI key(文字)。
郵便番号と国名を使って検索 getZipWeather()を使う。この関数に渡すデータは、郵便番号(文字)、国名(文字)、単位系(”metric”か”imperial”)、OpenWeatherのAPI key(文字)。
アメリカ以外の国の都市名と国名を使って検索 getIntlWeather()を使う。この関数に渡すデータは、都市名(文字)、国名(文字)、単位系(”metric”か”imperial”)、OpenWeatherのAPI key(文字)。

どの方法であれ、各関数が返すのは天気情報で、それを使ってgetCurrentTempHumidity()を呼べば、現在の気温、体感温度、湿度を取得できます。

気温、体感温度、湿度以外の天気情報を取得することもできます。weather-others.pyでは、以下の情報を取得しています。

取得したい情報に応じて、使う関数を関数を変えます。

取得する天気情報 使う関数
気象現況 getCurrentWeatherCondition()を使う。この関数が返すデータは、単語ひとつで表した気象現況(短い気象現況)と、もう少し長い(詳しい)気象現況、そして現況を表すアイコン(画像)のID。いずれも文字。短い気象状況は次のいずれか:Clear、Clouds、Drizzle、Rain、Snow、Thunderstorm、Mist、Smoke、Haze、Dust、Fog、Sand、Dust、Ash、Squall、Tornado。詳しい気象状況とアイコンについてはここを参照のこと。
気温、体感温度、湿度 getCurrentTempHumidity()を使う。この関数が返すデータは、気温(単位系がmetricなら摂氏、imperialなら華氏)、体感温度(単位系がmetricなら摂氏、imperialなら華氏)、湿度(単位系に関係なく単位は%)。いずれも小数。
風速、風向、突風 getCurrentWindを使う。この関数が返すデータは、風速(単位系がmetricならmeters/second、imperialならmiles/hour)、風向(風向角度)、突風(単位系がmetricならmeters/second、imperialならmiles/hour)。いずれも小数。風向角度は、北風(真北から真南へ吹く風)なら0度。真北を基準に東が90度、南が180度といったように時計回りで度数を表す。東風は90度、南風は180度、西風は270度。
UVインデックス(紫外線) getCurrentUvi()を使う。この関数が返すデータはUVインデックス(小数)。単位なし。
大気圧 getCurrentAtmosphericPressure()を使う。この関数が返すデータは大気圧(小数)。単位系に関係なく単位はヘクトパスカル(hPa)。
雲の量 getCurrentCloudiness()を使う。この関数が返すデータは雲の量(割合)。単位系に関係なく単位は%。整数。

現在の天気状況を表すアイコンをダウンロードする

先に説明したように、関数getCurrentWeatherCondition()を使うと、単語ひとつで表した気象現況(短い気象現況)と、もう少し長い(詳しい)気象現況、そして現況を表すアイコン(画像)のIDが返されます。ここでは3つめの「アイコンID」について説明します。サンプル・プログラムはweather-icons.pyです。

アイコンIDを関数getWeatherIconImage()に渡すと、そのアイコンの画像データが返されます。以下の例では、画像データが変数iconImageに入れられています。

mainCond, description, iconId = getCurrentWeatherCondition(weatherData)
iconImage = getWeatherIconImage(iconId, "2x")

getWeatherIconImage()を使うときには、

を渡してください。”2x”は小さいサイズの画像を要求し(100x100)、”4x”は大きいサイズの画像を要求します(200x200)。getWeatherIconImage()が返す画像データは、Pillowの画像(Image)です。Pillowは画像処理のためのモジュールです。Pillowについての詳細はここを読んでください。

getWeatherIconImage()が返す画像データを保存、表示するには以下のようにします。

iconImage.save("downloadedWeatherIcon.png")
iconImage.show()

save()を呼ぶときには、画像を保存するファイルの名前を指定します。実行しているプログラムと同じフォルダに画像ファイルが作られます。画像フォーマットはPNGがデフォルトです。JPEGなど、別の画像フォーマットで保存することもできますが、その方法についてはここを読んでください。

show()を呼ぶと、使っているOSデフォルトのアプリで画像を表示します。

OpenWeatherから天気予報を取得する

ここまでは、現在の天気情報を取得してきましたが、天気予報を取得することもできます。サンプルプログラムはweather-forecast.pyです。現在の天気情報を取得するのと同じように、まずは以下のいずれかの関数を使って天気情報を検索、ダウンロードします。

続いて、天気予報を取得する専用の関数を使います。

cityName = "Boston"
stateCode = "MA"
weatherData = getUsWeather(cityName, stateCode, "imperial", weatherApiKey)

daytimeTemp, minTemp, maxTemp, avgHumidity = getTempHumidityToday(weatherData)

daytimeTemp, minTemp, maxTemp, avgHumidity = getTempHumidityTomorrow(weatherData)

このように、今日の気温、湿度を取得するにはgetTempHumidityToday()を使います。この関数が返すのは、日中温度(の平均)、最低温度、最高温度、平均湿度です。また、明日の日中温度、最低温度、最高温度、平均湿度を取得するにはgetTempHumidityTomorrow()を使います。明日以降5日後までの予報は、次のようにして取得します。

daytimeTemp, minTemp, maxTemp, avgHumidity = getTempHumidityForecast(weatherData, 2)

getTempHumidityForecast()を使うときには、何日後の予報が欲しいかを指定してください。ここでは2日後の予報を取得しています。この関数は5日後までの予報を返すことができます。5以上の数字を指定するとエラーになります。

ちなみに、getTempHumidityToday(weatherData)とgetTempHumidityForecast(weatherData, 0)は同じ予報を返します。同様に、getTempHumidityTomorrow(weatherData)とgetTempHumidityForecast(weatherData, 1)は同じ予報を返します。

今日の体感温度を取得するにはgetFeelsLikeToday()を使います。この関数が返すのは、朝の体感温度、日中の体感温度、夕方の体感温度、夜の体感温度です。明日の体感温度を取得するにはgetFeelsLikeTomorrow()を使います。明日以降5日後までの予報はgetFeelsLikeForecast()を使ってください。

今日の気象状況を取得するにはgetWeatherConditionToday()を使います。この関数が返すのは、単語ひとつで表した気象予報と、もう少し長い(詳しい)気象予報、そして予報を表すアイコン(画像)のIDです。明日の気象状況を取得するにはgetWeatherConditionTomorrow()、明日以降5日後までの予報を取得するにはgetWeatherConditionForecast()を使ってください。

今日の雲の量を取得するにはgetCloudinessToday()、明日の雲の量はgetCloudinessTomorrow()、明日以降5日後までの予報はgetCloudinessForecast()を使ってください。

自習プロジェクトの目次に戻る