公式サイトの作例を参考に、OpenWeatherMapの天気APIを使って、Scrachで天気情報を表示するプログラムを作ってみました(Raspberry PiのScratch 1.4です)。Scratchから直接APIを呼ぶことができないので、Pythonのプログラムを間に挟んでいます
先日作った作例と似ていますが、今回は自分の知りたい都市の天候が取得できます

必要なソフトを準備
Python 3のscratchとpyowmライブラリをインストールします。pyownはPythonからOpenWeatherMapにアクセスしやすくするためのライブラリです
sudo pip3 install --pre scratch sudo pip3 install pyowm
OpenWeatherMapに登録する
Sign Upから無料でユーザー登録できます
OpenWeatherMap
ユーザー名とメールアドレスとパスワードを入力します
ユーザー登録するとAPIキーが表示されます。これをコピーします
Scratchの準備
Scratch 1.4を開きます
カテゴリ「調べる」の「スライダーセンサーの値」ブロックを右クリックして「遠隔センサー接続を有効にする」をクリックします。ここまで完成したら、プロジェクトに「magic-window」という名前をつけて保存します
次に、Pythonプログラムをダウンロードします
weather.py
import pyowm import scratch s = scratch.Scratch() def listen(): while True: try: yield s.receive() except scratch.ScratchError: raise StopIteration for msg in listen(): if 'key' in msg['sensor-update']: key = msg['sensor-update']['key'] owm = pyowm.OWM(key) if 'location' in msg['sensor-update']: location = msg['sensor-update']['location'] observation = owm.weather_at_place(location) w = observation.get_weather() temperature = w.get_temperature()['temp'] rain = w.get_rain() if '1h' in rain: rainfall = rain['1h'] else: rainfall = 0 wind = w.get_wind() if 'speed'in wind: wind_speed = wind['speed'] else: wind_speed = 0 if 'deg' in wind: wind_direction = wind['deg'] else: wind_direction = 0 clouds = w.get_clouds() s.sensorupdate({'temperature': temperature - 273}) s.sensorupdate({'rainfall': rainfall}) s.sensorupdate({'wind_speed': wind_speed}) s.sensorupdate({'wind_direction': wind_direction}) s.sensorupdate({'clouds': clouds})
Python3(IDLE)を起動して、ダウンロードしたweather.pyを開き実行します
もしくは、LXTerminalから
python3 weather.py
を実行します
景色を変更する
「ステージ」をクリックして選んで、自分の好きな背景に変更します
これが窓から見える景色になります
変数を作る
カテゴリ「変数」を選んで「新しい変数をつくる」を押します(ねこのスプライトは使わないので削除してください)
- key
- location
の2つの変数を作ります
keyにOpenWeatherMapのAPIキーをセットするスクリプトをステージに作成します。このAPIキーがPythonスクリプトに送信され、PythonスクリプトはOpenWeatherMapに送信します
「ずっと」ループを作り、天気を取得したい都市をユーザー入力から取得するようにします
APIのテスト
緑の旗をクリックしてスクリプトを実行します
文字入力のボックスが表示されるので、都市と国コードを入力します。国コードと都市はカンマで区切ります。国コードは2文字の略語です
このように入力します
- Tokyo,jp
- Kyoeo,jp
- London,uk
- Nassau,bs
- Sofia,bg
- Berlin,de
- Pyongyang,kp
- Lusaka,ze
都市のリストファイル(city.list.json.gz)はこちらからダウンロードできます
http://bulk.openweathermap.org/sample/
「(スライダー)センサーの値」のスライダー部分のプルダウンをクリックすると
- clouds
- rainfall
- temperature
- wind_direction
- wind_speed
の追加が確認できます。変更してブロックをタップするとその値が表示されます
気温を太陽で表す
この太陽の画像を保存して、インポートしてスプライトにします
気温を太陽の大きさで表現します
「ずっと」ループに
temperatureセンサーの値 + 60
にスプライトのサイズを変更するブロックを入れます。ループに入れることで、都市を切り替えても正しい値に更新されます
雲の量を透明度で表す
この雲の画像を保存して、インポートしてスプライトにします
色が白だとわかりにくいので黒く塗りつぶします
雲の透明度を
100 – 「clouds センサーの値」
にします
風量を雲の動きで表す
雲が「wind_speed センサーの値」だけ動くようにします
雲が端に当たった時に上下がひっくり返らないように、回転しないようにします
風の向きを矢印で表す
スプライトライブラリーに矢印があるので、それを読み込みます
「(wind_direction センサーの値)度に向ける」ブロックで、矢印を風の方向に回転させます
雨を降らせる
雨情報ですが、取得APIに問題があるようで、なぜかrainの値が0になります
Raspberry Pi • View topic – learning worksheet problem
次のPythonの確認プログラムを実行して、Rainの値が空ならScratchで表示することができません。何度か試しましたがRainの値は空っぽでした
import pyowm owm = pyowm.OWM('自分のAPIキーに変更') observation = owm.weather_at_place('Tokyo,jp') weather = observation.get_weather() print(weather) rain = weather.get_rain() wind = weather.get_wind() humidity = weather.get_humidity() temp = weather.get_temperature('celsius') clouds = weather.get_clouds() print ("Rain:", rain, " Wind:", wind, " Humidity:", humidity, "Temp:", temp, "Clouds:", clouds)
もし作業を進める場合は、以下の作業を行って下さい
雨の画像ファイルはこちらからダウンロードできます
rain.zipを解凍して作成される8つのpngファイルをコスチュームとして1つずつインポートします
このようになります
rainの値は、雨が降っていない場合は0なのでスプライトを隠します。降雨量が0より大きい場合はスプライトを表示し、コスチュームを変更してアニメーションします。雨が多い場合はアニメーションのスピードを早くします
最後に窓枠のスプライトを描けば完成です!
この 作品 は クリエイティブ・コモンズ 表示 – 継承 4.0 国際 ライセンスの下に提供されています。