ラズパイに時刻と天気予報(横浜)をしゃべらせてみる

シェアする

Pocket

1.時刻・天気を喋らせる

60爺は、raspberrypiに、時刻と天気をしゃべらせてみることにしました。
下記のページに、ちょうど良いプログラムが載っています。

Raspberry Piに現在時刻と、天気をしゃべらせてみた(Python)

◆ 地域を変える

内容を全く変えずにしゃべらせても良かったのですが、地域を変えられるので、「横浜」でやってみることにしました。

上記のページで、『地域IDは全国の地点定義表(RSS) の「cityタグ」のidを参照して下さい。』と出ていますが、このページに行っても、「cityタグ」を見つけることができません。

60爺は、いろいろと指定ページからめぐってみましたが、さっぱりわかりません。で、たどり着いたのが、以下のページです。ここには、主だった都市が一覧で載っているので簡単ですよ。

livedoor Weather Hacks APIで、お天気データのJSONを取得するための1次細分区(cityタグ)の地域id一覧まとめ

横浜140010を設定して動かしてみます。

pi@raspberrypi:~/python_pg/open_jtalk $ python talk_weather.py
jsay 7月13日、13時13分32秒
jsay '神奈川県 横浜 の天気 今日の天気は曇時々晴です。 明日の天気は晴時々曇です。 明日の予想最高気温、31度、予想最低気温、25度です。'

おーー。見事に動きましたね。ちゃんと、スピーカから声が流れます。printされてから声が出るまでに時差はありますが・・・。

2.python3で動かす

(1) エラー発生

さて、ここまでは、上述の記事の焼き直しです。それだけではつまらないので、ここで、60爺は、少しですが、オリジナルな部分を追加してみます。

Python3で実行してみます。PythonとPython3では、だいぶ手直しが入っていますので、Python3で動かしてみましょう。

さっそく、エラーが発生です。

pi@raspberrypi:~/python_pg/open_jtalk $ python3 talk_weather.py
File "talk_weather.py", line 23 print text ^ SyntaxError: Missing parentheses in call to 'print'

python3では、print文が大きく変わっていて、()でくくらなくてはいけません。
print文が2箇所あるので、両方とも()でくくります。

(2) またまたエラー

修正後、再実行。すると、新たなエラーが発生しました。

Traceback (most recent call last):
File "talk_weather.py", line 9, in <module>
import urllib2 ImportError: No module named 'urllib2'

Python2では、urllib2を使えばよいですが、Python3では、urllib.requestを使用するそうです。

(Pythonでurllib2を使ってインターネット上のリソースを取得する方法)

ではでは、urllib2 を urllib.request に修正しました。

(3) 3回目のエラー

実行してみると、おー、日付と時間が print されました。よーし、あれ、時間がかかってるぞ・・・。あ、またまたエラーが発生ですね。

pi@raspberrypi:~/python_pg/open_jtalk $ python3 talk_weather.py
jsay 7月13日、11時16分14秒
Traceback (most recent call last):
File "talk_weather.py", line 68, in <module>
main()
File "talk_weather.py", line 16, in main
say_weather()
File "talk_weather.py", line 37, in say_weather
obj = json.loads( unicode(r.read()) )
NameError: name 'unicode' is not defined

unicode を str に変更しました。

(4) 止まらないエラー

再実行。またまた、変なエラーが出ましたねエ。

pi@raspberrypi:~/python_pg/open_jtalk $ python3 talk_weather.py
jsay 7月13日、11時32分42秒 Traceback (most recent call last):
File "talk_weather.py", line 68, in <module>
main()
File "talk_weather.py", line 16, in main
say_weather()
File "talk_weather.py", line 37, in say_weather
obj = json.loads( str(r.read()) )
File "/usr/lib/python3.4/json/__init__.py", line 318, in loads
return _default_decoder.decode(s)
File "/usr/lib/python3.4/json/decoder.py", line 343, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python3.4/json/decoder.py", line 361, in raw_decode
raise ValueError(errmsg("Expecting value", s, err.value)) from None
ValueError: Expecting value: line 1 column 1 (char 0)

根本的にstrにしたのがダメみたい。いろいろ調べてみました。

ふむふむ、unicode が python3 で消去されたので、単純に str に変えたのですが、それではだめで、下記を参考に対応しました。プログラムを見ると、最後に decode してますので、さきほどの json.loads のところでやってみるとよさそうです。

Python3 で JSON の読み書きをする方法(WebAPI にも対応) ? サンプルコード付

(5) ようやくエラー収束

さて、say_weather の部分を切り出して、テストしてみました。

jsay '神奈川県 横浜 の天気 今日の天気は曇時々晴です。 明日の天気は晴時々曇です。 明日の予想最高気温、31度、予想最低気温、25度です。'

ちゃんと出力されました。
それでは、ここで修正した内容を本体ににも施します。修正したソースで再実行します。

pi@raspberrypi:~/python_pg/open_jtalk $ python3 talk_weather_3.py
jsay 7月14日、22時11分56秒
jsay '神奈川県 横浜 の天気 今日の天気は晴れです。 明日の天気は晴のち曇です。 明 日の予想最高気温、33度、予想最低気温、24度です。'

やったね!
ちゃんと、声も出ています。

3.ソースコード

最後に、python3 のソースを載せて今回の記事を終わります。

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import shlex
import subprocess

from datetime import datetime

import  urllib.request
import json

CMD_SAY = 'jsay'

def main():
    say_datetime()
    say_weather()
    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)
    text = '/usr/local/bin/' + text
    print (text)
    proc = subprocess.Popen(shlex.split(text))
    proc.communicate()
    return

def say_weather():
    city = '140010'; # Yokohama
    json_url = 'http://weather.livedoor.com/forecast/webservice/json/v1' #API URL

    weather_text = u'%sの天気は%sです。'
    temperature_text = u'%sの予想最高気温、%s度、予想最低気温、%s度です。'

    try:
        r =  urllib.request.urlopen('%s?city=%s' % (json_url, city) )
        obj = json.loads( r.read().decode('utf-8') )

        title = obj['title']
        forecasts = obj['forecasts']

        # TODAY
        cast = forecasts[0]
        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'])
        tommorow_t_txt = temperature_text % (cast['dateLabel'], temperature['max']['celsius'], temperature['min']['celsius'])

        # SAY
        weather_str = title + ' ' + today_w_txt + ' ' + tommorow_w_txt + ' ' + tommorow_t_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


### Execute
if __name__ == "__main__":
    main()

4.お決まりの時間に喋らせる

さて最後に、crontabを使用して、決まった時間にお天気予報を喋ってもらうようにしました。

0 8,12,15,20 * * * python3 /home/pi/python_pg/open_jtalk/talk_weather_3.py
スポンサーリンク

シェアする

フォローする