ラズパイ:Pythonで明日の天気をしゃべらせる

ラズベリーパイB Raspberry Pi

2022-01-09 管理人注記

本記事で紹介しているライブドアお天気サービスAPIはすでに利用できなくなっています。
そのため、本記事で紹介しているプログラムは動作しません。

新しく書いた以下の記事を参考にしてください。

わたしは自宅のラズパイに毎朝6時、今日の天気と最高気温、最低気温をしゃべらせています。
この記事では、ラズパイのPython3を使って明日の天気をしゃべらせてみます。

ライブドアのお天気サービスAPIを使うと日本全国の天気を取り出すことができます。
どんなデータが取得できるかは、以下をクリックしてみてください。

取得できるデータのサンプル

このデータはJSON形式といってJavaScript Object Notationの略です。(JOの部分は、頭文字で分かりますが、個人的に最後のONの部分がどこ?と思ってしまいます)
ウェブ上でよく利用されているデータ形式の1つです。今回は、このデータの必要部分を取り出して文字列として整形しています。

ライブドアお天気WebサービスのJSONデータの中身や使い方をきちんと知りたい方は以下をご覧ください。

ライブドアお天気Webサービス仕様
http://weather.livedoor.com/weather_hacks/webservice

JavaScriptでも以前はJSONデータを取り出せたのですが、ブラウザのセキュリティが上がったため出来なくなりました。

ライブドアお天気WebサービスからJSONデータを取り出すプログラム

JSONデータを取り出す部分は関数化してあります。
ライブドアお天気Webサービスは、

http://weather.livedoor.com/forecast/webservice/json/v1?city=400040

のようなURLで天気情報にアクセスします。
最後のcity=XXXXXの部分が都市番号です。以下のサンプルでは水戸市の番号080010になっているのでライブドアお天気Webサービス仕様のサイトから確認してご自分で好きな都市に設定してください。

# -*- coding: utf-8 -*-

import urllib.request, urllib.parse
import json, sys, os

def getWeather():
	jsonUrl = "http://weather.livedoor.com/forecast/webservice/json/v1?"
	city = "080010"
	url = jsonUrl + "city=" + city
	site = urllib.request.urlopen(url)
	jsonData = json.loads(site.read().decode("utf-8"))
	return jsonData

JSONデータを整形する

JSONデータを

水戸地方、明日の天気は曇り時々晴でしょう。最高気温は、21度。最低気温は、13度でしょう。

のような文章に整形してみます。

JSONデータは、基本的には配列のようなものなのでライブドアお天気Webサービス仕様と下のプログラムを照らし合わせてみるとイメージがつくと思います。

お天気Webサービスでは、今日、明日、明後日の天気データが取得できます。
ただし時間帯によっては、今日と明後日のデータは不完全な場合が多いです。(最高気温データがなかったりとか)そのため例外処理は必要です。
また、forecastsは配列の0,1,2今日、明日、明後日に対応しています。

例えばdata[“forecasts”][1][“telop”]の部分をdata[“forecasts”][0][“telop”]にすると今日の天気が表示されます。

JSONデータを整形している部分

if __name__ == "__main__":
	data = getWeather()
	#print(data)
	# お天気データを整形
	try:
		weather = data["location"]["city"] + "地方、明日の天気は" + data["forecasts"][1]["telop"] + "でしょう。"
		weather = weather.replace("曇", "曇り")	# AquesTalkPiで読むとき変になるため変換
		tempMax = data["forecasts"][1]["temperature"]["max"]["celsius"]
		weather += "最高気温は、" + tempMax + "度。"
		tempMin = data["forecasts"][1]["temperature"]["min"]["celsius"]
		tempMin = tempMin.replace("-", "マイナス")
		weather += "最低気温は、" + tempMin + "度でしょう。"
	except TypeError:
		pass

	print(weather)

ラズパイに天気をしゃべらせる

文字に整形できれば、しゃべる部分は割と簡単です。
AquesTalk Piというプログラムを使います。以下からダウンロードできます。

AquesTalk Pi
https://www.a-quest.com/products/aquestalkpi.html

インストールするとターミナルから

./AquesTalkPi "おっす!おら悟空。" | aplay

などとラズパイにしゃべらせてみることができます。(もちろんスピーカをつないでください)

Pythonからしゃべらせるにはos命令を使って簡単にできます。
os命令は通常ターミナルからできることをPython側から呼び出すことが出来る命令です。

#しゃべる
cmd = "/home/pi/aquestalkpi/AquesTalkPi " + weather + " -s 90 | aplay"
os.popen(cmd).readline().strip()

プログラム全体

今回のプログラム全体を以下に示します。

31行目の
cmd = “/home/pi/aquestalkpi/AquesTalkPi ” + weather + ” -s 90 | aplay”
の部分は、インストールしたAquesTalk Piの場所に合わせて変更してください。
# -*- coding: utf-8 -*-

import urllib.request, urllib.parse
import json, sys, os

def getWeather():
	jsonUrl = "http://weather.livedoor.com/forecast/webservice/json/v1?"
	city = "080010"
	url = jsonUrl + "city=" + city
	site = urllib.request.urlopen(url)
	jsonData = json.loads(site.read().decode("utf-8"))
	return jsonData

if __name__ == "__main__":
	data = getWeather()
	#print(data)
	# お天気データを整形
	try:
		weather = data["location"]["city"] + "地方、明日の天気は" + data["forecasts"][1]["telop"] + "でしょう。"
		weather = weather.replace("曇", "曇り")	# AquesTalkPiで読むとき変になるため変換
		tempMax = data["forecasts"][1]["temperature"]["max"]["celsius"]
		weather += "最高気温は、" + tempMax + "度。"
		tempMin = data["forecasts"][1]["temperature"]["min"]["celsius"]
		tempMin = tempMin.replace("-", "マイナス")
		weather += "最低気温は、" + tempMin + "度でしょう。"
	except TypeError:
		pass

	print(weather)
	#しゃべる
	cmd = "/home/pi/aquestalkpi/AquesTalkPi " + weather + " -s 90 | aplay"
	os.popen(cmd).readline().strip()

以上、ラズパイを使ったPythonで明日の天気をしゃべらせるでした。

スポンサーリンク

 

コメント

タイトルとURLをコピーしました