今回はソフトウェアの実装をまとめていきます。ソフトで実現すべきことは、
- 天気予報のAPIを叩いて明日の天気を取得する
- 取得した天気に応じてGPIOでLEDを点灯させる
これらを実現する方法はいくつもあると思いますが、ここではコンパイル不要で再修正も楽なPythonを使ってみることにします。Python用にRaspberry PiのGPIO操作ライブラリRPi.GPIOが提供されているので、ファイルIOで直接叩くよりも比較的シンプルに実装できます。
公式からダウンロードしたRaspbian wheezyのイメージにはデフォルトでRPi.GPIOがインストールされているはずです。もしモジュールのimportに失敗する場合はこちらの手順などを参考にインストールします。
OpenWeatherMap
インターネットで天気予報を提供するAPIのひとつに、OpenWeatherMapというものがあります。OpenWeatherMapは、天気を知りたい場所を指定してHTTPでリクエストを送ると、XMLまたはJSON形式でレスポンスを返してくれます。予報だけでなく、現在の天気を知ることもできます。取得したレスポンスを適当に処理して、天気とか気温とかを取り出します。まずは、試しにレスポンスを取得してみます。公式のAPIサンプルに、下記のリクエスト例が置いてあります。
- Seaching 7 days forecast by city name at XML format and metric units
api.openweathermap.org/data/2.5/forecast/daily?q=London&mode=xml&units=metric&cnt=7
これをベースに編集してみましょう。
地名はLondonからTokyoに変更、レスポンス形式はXMLからJSONへ、unitsはそのまま、cntは翌一日分のみで十分ですので1にします。
http://api.openweathermap.org/data/2.5/forecast/daily?q=Tokyo&mode=json&units=metric&cnt=1
こんな感じかな。試しにブラウザのURL欄に入力してみると、、
{"cod":"200","message":0.0176,"city":{"id":1850147,"name":"Tokyo","coord":{"lon":139.691711,"lat":35.689499},"country":"JP","population":8336599},"cnt":1,"list":[{"dt":1378605600,"temp":{"day":25.58,"min":19.64,"max":25.58,"night":19.64,"eve":20.69,"morn":25.58},"pressure":1018.16,"humidity":91,"weather":[{"id":502,"main":"Rain","description":"heavy intensity rain","icon":"10d"}],"speed":1.81,"deg":275,"clouds":92,"rain":16}]}
ってな感じでレスポンスが返ってきました。問題なさそうですね。では、このリクエストをPythonコードから投げて、レスポンスを取得してみましょう。 適当な作業ディレクトリにPythonファイルを作って編集していきます。 実行してみます。 ブラウザで表示させた時と同様、JSON形式のレスポンスが返ってきたでしょうか?
次に、このJSONレスポンスをスクレイピングして、天気の部分だけを取り出してみます。 これを実行すると、天気の部分のテキストだけが抽出されるはずです。 こんな風に↓
GPIO
続いてLEDを点灯させるためのGPIO操作をPythonプログラムに追加していきます。まずGPIO.setmode()でピン番号の指定方法を銘記します。これに合わせ、あらかじめR、G、B変数にはRPiボードのP1コネクタ上でのピン番号を入れておきます。続くGPIO.serwarnings()は、GPIOを再操作した時に、既に当該ピンが使用中である旨の警告が出るので、これを抑止するために書いておきます。次にGPIO.setmode()で各ピンを出力に設定。あとは、天気予報に合わせた色をRGBで各ピンに設定するだけです!
さて、天気をどの色で表現するか。ご所望の田無タワーが、どの天気のときにどの色で光るかを調べてみるわけですけどね。。
スカイタワー西東京さん(公式)によれば
曇りは緑、雨は水色に決定し、残りの紫が晴れ
Wikipedia先生によれば
晴れ=紫色 曇り=黄緑色 雨=青色
西東京市さんによれば
紫色:晴れ、緑色:曇り、青色:雨
と、若干矛盾系の殺伐とした雰囲気が感じられるんですが、とりあえずここでは
- 晴れ:R+Gで紫
- 曇り:Gで明るい緑
- 雨:G+Bで水色
最終的なPythonコードは下記のようになります。 では実行してみましょうか。 天気予報によって異なる色でLEDが点灯するのを確認できます。
「曇り」のとき
「晴れ」のとき
カメラの露出開けすぎた?なんだか眩しい・・・
(おまけ) Raspbian起動時に実行、定期的に実行
自動化してみたいと思います。上で作成したPythonファイルを、あらかじめ/usr/local/bin/にインストールしておきます。
それから、/usr/local/bin/getweather.pyの冒頭に次の1行(Shebang)を追加しておきます。 /usr/local/bin/にはPATHが通っているので、こうすることでgetweather.pyとだけコマンドすれば実行できるようになるわけです。
では、まずRPiの電源を入れてSDカードからRaspbianが立ち上がったときに一度実行させる方法。まず/etc/init.d/の下に適当な名前(ここではgetweather)でテキストファイルを作ります。
中身には次のスクリプトを書きます。
スクリプトファイルを実行可能に。
update-rc.dコマンドでスクリプトを登録します。今はinsserv使う方がナウいのかな?
次に、一定時間ごとに更新する方法。OpenWeatherMapの更新間隔というのもあると思いますが、ここでは単純に1時間おきのcronジョブを設定します。
rootのcrontabを編集します。この辺の扱いは諸説あると思いますが(crontab -eは間違えて-rで全消ししそうで危ないとか、直接エディタを使うのは行儀が悪いとか)、まぁ好みの方法でやったらいいと思います。
で、毎時0分に更新が行われるよう、下記の行を追加します。
参考情報
Free weather data API for developers - Open Weather MapWeather information from openweathermap.org JSON API by Python - Techdoc Blog
1: Getting Started with Raspberry Pi GPIO and Python - OPENMICROS.org
RPi Low-level peripherals - eLinux.org
How to add a program to run at startup in Ubuntu Linux Server edition - Temp Variable
最近raspberyPIとPythonをはじめた初心者です
返信削除質問
weatherと同じようにスクレイピングして最高気温, 最低気温, 湿度を表示させたいのですがどのようにすればよいのでしょうか?
そもそもスクレイピングの方法は分かりません
こんにちは。
削除返信が遅くなりすみません。
JSONのレスポンスに最高気温、最低気温、湿度も含まれています。
上記Pythonコード中で下記のようにすれば取得、表示できます。
試してみてください。
# 最高気温
max_temp = json.loads(line)['list'][0]['temp']['max']
print max_temp
# 最低気温
min_temp = json.loads(line)['list'][0]['temp']['min']
print min_temp
# 湿度
humidity = json.loads(line)['list'][0]['humidity']
print humidity