Raspberry Pi | お天気Webサービスは最高/最低気温がnullで返ってくることがある
こんにちは、tapunです。
昨日、Raspberry Pi に天気予報を喋ってもらう設定をしました。
課題
昨日はエラーなく天気予報を喋ってくれていたのですが、今日になってtalk_weather.pyを実行すると下記のようなエラーが返ってくるようになりました。
$ python weather_talk.py jsay 12月5日、12時55分31秒 Traceback (most recent call last): File "talk_weather.py", line 70, in <module> main() File "talk_weather.py", line 16, in main say_weather() File "talk_weather.py", line 46, in say_weather today_t_txt = temperature_text % (cast['dateLabel'], temperature['max']['celsius'], temperature['min']['celsius']) TypeError: 'NoneType' object has no attribute '__getitem__'
これでは日時しか喋ってもらえません。
原因は?
ちょっとね、プログラミング出来ないのでよく分かんないですが、最高気温と最低気温のところが問題のようです。
もう一度お天気Webサービスの仕様を見てみると、サンプルでも気温は”null”が返ってきていますね。
"forecasts" : [
{
"dateLabel" : "今日",
"telop" : "晴のち曇",
"date" : "2013-01-29",
"temperature" : {
"min" : null,
"max" : {
"celsius" : "11",
"fahrenheit" : "51.8"
}
暫定的な回避策
nullが返ってきたら別のテキストを出力したり、nullに何か代入できるといいんですけど、残念ながらその知識がないので一旦天気予報と気温予測を分けてjsayコマンドで喋らせるようにします。
talk_weather2.py
#!/usr/bin/env python # -*- coding:utf-8 -*- import shlex import subprocess from datetime import datetime import urllib2 import json CMD_SAY = 'jsay' def main(): say_datetime() say_weather() say_temperature() return def say_datetime(): d = datetime.now() text = '%s月%s日、%s時%s分%s秒' % (d.month, d.day, d.hour, d.minute, d.second) text = CMD_SAY + ' ' + text print text proc = subprocess.Popen(shlex.split(text)) proc.communicate() return def say_weather(): city = '130010'; # Tokyo json_url = 'http://weather.livedoor.com/forecast/webservice/json/v1' #API URL weather_text = u'%sの天気は%sです。' try: r = urllib2.urlopen('%s?city=%s' % (json_url, city) ) obj = json.loads( unicode(r.read()) ) title = obj['title'] forecasts = obj['forecasts'] # TODAY cast = forecasts[0] temperature = cast['temperature'] today_w_txt = weather_text % (cast['dateLabel'], cast['telop']) # TOMMOROW cast = forecasts[1] temperature = cast['temperature'] tommorow_w_txt = weather_text % (cast['dateLabel'], cast['telop']) # SAY weather_str = title + ' ' + today_w_txt + ' ' + tommorow_w_txt weather_str = weather_str.encode('utf-8') text = '''%s '%s' ''' % (CMD_SAY, weather_str) print text proc = subprocess.Popen(shlex.split(text)) proc.communicate() finally: r.close() return def say_temperature(): city = '130010'; # Tokyo json_url = 'http://weather.livedoor.com/forecast/webservice/json/v1' #API URL temperature_text = u'%sの予想最高気温、%s度、予想最低気温、%s度です。' try: r = urllib2.urlopen('%s?city=%s' % (json_url, city) ) obj = json.loads( unicode(r.read()) ) title = obj['title'] forecasts = obj['forecasts'] # TODAY cast = forecasts[0] temperature = cast['temperature'] today_t_txt = temperature_text % (cast['dateLabel'], temperature['max']['celsius'], temperature['min']['celsius']) # TOMMOROW cast = forecasts[1] temperature = cast['temperature'] tommorow_t_txt = temperature_text % (cast['dateLabel'], temperature['max']['celsius'], temperature['min']['celsius']) # SAY temperature_str = title + ' ' + today_t_txt + ' ' + tommorow_t_txt temperature_str = weather_str.encode('utf-8') text = '''%s '%s' ''' % (CMD_SAY, temperature_str) print text proc = subprocess.Popen(shlex.split(text)) proc.communicate() finally: r.close() return ### Execute if __name__ == "__main__": main()
これで、実行してみます。
$ python talk_weather2.py jsay 12月5日、19時44分18秒 jsay '東京都 東京 の天気 今日の天気は晴れです。 明日の天気は晴のち曇です。' Traceback (most recent call last): File "talk_weather2.py", line 105, in <module> main() File "talk_weather2.py", line 17, in main say_temperature() File "talk_weather2.py", line 83, in say_temperature today_t_txt = temperature_text % (cast['dateLabel'], temperature['max']['celsius'], temperature['min']['celsius']) TypeError: 'NoneType' object has no attribute '__getitem__'
一応天気まで喋ってくれるようになったので、今日のところはこれでよしとします。
まとめ
nullが返ってきたときに「気温の情報は取得できませんでした」と言って欲しいのですが、pythonの知識がなくて書けません!
ちょっと趣味として勉強しようかしら・・・
もし書き方が分かる人がいらっしゃったら、ご教授いただけると嬉しいです!!!
コメントを残す