
公式サイトの作例を参考に、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 国際 ライセンスの下に提供されています。





