秘密の本棚

気になることをなんでも書きます

雨雲の接近をGoogle Homeに通知する

今回やりたいこと

Raspberry PiGoogle Homeによるオートメーション第2弾。前回はパソコンの起動をさせました。
nexusuica.hatenablog.jp
今回は、ゲリラ豪雨の発生が予測されたら、前もって洗濯物が取り込めるようにGoogle Homeで通知する仕組みを作ってみたいと思います。

必要なステップに分解する

Raspberry Piが天気情報を取得して、Google Homeにしゃべらせるまでに必要なステップは、以下の4つです。

  • Raspberry PiYahoo! 気象情報APIを用いて降水量予測を取得
  • 雨が降り出しそうかどうかを判定
  • 雨が降り出しそうならGoogle Homeに通知する
  • 以上の手順を一定間隔で繰り返す

今回は降水予測のソースはYahoo!気象情報APIを用いることにしました。
developer.yahoo.co.jp
天気の情報を取得できるサービスはいくつかありますが、Yahoo!は雨雲レーダーで各地点の5分毎の降水量を予測しており、このデータを用いれば局地的なゲリラ豪雨も前もって通知できそうです。

Yahoo! 天気情報APIを用いて降水量予測を取得

まずはRaspberry PiAPIを叩かせて情報を取得します。アプリケーション登録を済ませれば、GETメソッドを呼ぶだけです。

import requests
import json
import subprocess
location = "<経度>,<緯度>"
appid = "<appid>"
url = "https://map.yahooapis.jp/weather/V1/place"

payload = {'coordinates':location, 'appid':appid, 'output':'json', 'interval' : '5'}
r = requests.get(url,params=payload)
data = json.loads(r.text)
data = data['Feature'][0]['Property']['WeatherList']['Weather']
print(data)

こうすると、指定した経度・緯度における現在から60分後までの降水量の予測データが取得できます。

雨が降り出しそうかどうかを判定

取得したデータをもとに、「雨が降り出しそうか」を判定します。今回は、「60分以内に0ミリより大きい降水量が予測され、かつ前回の情報取得時に降水が予測されていなかった」ことを基準とします。外部ファイルに降水が予想されているかどうかを記録しておけば、これを簡単に実現できます。

rain = False
for x in data:
    if x['Rainfall']>0:
        rain = True
pastRainState = False
try:
    fin = open('rain_state','rt')
    line = fin.read()
    fin.close()
    if line == 'True':
        pastRainState = True;
except FileNotFoundError:
    print('File not found.')
    fin = open('rain_state','wt')
    fin.write('False')
    fin.close()
print(str(rain)+' '+str(pastRainState))
if rain and (not pastRainState):
    fout = open('rain_state','wt')
    fout.write('True')
    fout.close()
    <ここにGoogle Homeに降水を通知する処理>
if (not rain) and pastRainState:
    fout = open('rain_state','wt')
    fout.write('False')
    fout.close()

雨が降り出しそうならGoogle Homeに通知する

次に、降水が予測された場合にGoogle Homeに音声で通知させます。まず、Raspberry PiからGoogle Homeに喋らせるためにはgoogle-home-notifierのインストールが必要です。以下の記事に従ってセットアップします。
qiita.com
そして、コマンドライン引数に喋らせる内容を入れれば喋ってくれるようなプログラムを書きます。

const googlehome = require('google-home-notifier');
const language = 'ja';
googlehome.device("<Google Homeのデバイス名>", language);
googlehome.ip("<Google HomeのIPアドレス>");
message = process.argv[2];
googlehome.notify(message, function(res) {
      console.log(res);
});

こうすれば、あとは先ほどの降水判定のプログラムのところで

subprocess.call('node googlehome.js まもなく雨が降り出します。',shell=True)

とすれば、pythonからJavaScriptを動かしてGoogle Homeを喋らせることができます。

以上の手順を一定間隔で繰り返す

以上のプログラムでは、一回天気情報を取得して降水を判定するだけです。あとはこれを定期的に実行して、天気を監視させます。これにはcronを使います。以下の記事を参考に、さきほどのpythonプログラムを10分毎に実行させるように設定しました。
make.bcde.jp
これですべて完了です。ゲリラ豪雨のときも通知してくれれば安心ですね。