Philips hueを天気予報と連動させる

th_hue-weather-1 th_hue-weather-2 th_hue-weather-3

前回、hueをWeb APIで制御するところまでやりました。次は外部サービスの天気予報情報と連動させてhueを制御したいと思います。

具体的には、自分が朝起きる少し前に、その日の天気が晴れだったらオレンジ色、雨だったら青色、みたいな感じで弱く光らせておく、というのをやってみたいと思います。今自分はhueの電球をデスクのサブのライトとして設置しているので、起きた時にその光が目に入ってきておよその天気がわかると、ちょっとスマートかなと。

hueと天気予報を連動させる一番簡単なやり方は、おそらくIFTTTを使うやり方だと思います。こちらの方がレシピの作り方を詳細に書いてくださっています。ただ、このやり方だと、以下の2点において、自分の要求を満たすことができません。

  • 基本的に遅延が発生する。自分は6時30分に起きて数分以内には寝室からリビングに移動してしまうので、あんまり遅れると照明の色を確認できない。
  • IFTTTだと照明の色と明るさを同時に設定できない。基本的に明るさMaxで点灯するため、上記の遅延を加味して早めの時間にIFTTT連携を設定してしまうと、眩しすぎて目が覚めてしまう。

というわけで、ちょっと面倒ですが自前で連動サービスを作ります。

やり方としては、Raspberry Piが定時になったら外部Webサービスから天気予報情報を引っ張ってきて、その結果を見てhueの制御パラメータを設定してWeb APIを叩く、というものになります。

天気予報の外部Webサービスですが、過去に一度使ったことのあるWeather Hacksを使います。Web APIでアクセスできて結果もJSONで返ってくるので、扱いやすいのです。Web APIのアクセス方法とJSONの戻り値の扱い方は、上記のリンクをご参考いただければと思います。

以下は、自分の書いたプログラムから、今回必要と思われるところを抜粋したものです(自分の元々のプログラムは、ラピロ制御用のプログラムも入っているのでもう少し複雑です)。

# coding: utf-8
import requests
import datetime
import time

weather_location_id = 270000
WEATHER_SUNNY  = '{"on":true,"bri":24,"xy":[0.52,0.42],"sat":128,"effect":"none"}'
WEATHER_CLOUDY = '{"on":true,"bri":24,"xy":[0.33,0.30],"sat":128,"effect":"none"}'
WEATHER_RAINY  = '{"on":true,"bri":24,"xy":[0.15,0.15],"sat":128,"effect":"none"}'
WEATHER_SNOWY  = '{"on":true,"bri":48,"xy":[0.33,0.30],"sat":128,"effect":"colorloop"}'

date  = datetime.datetime.today()
today = date.strftime('%Y-%m-%d')
now   = date.strftime('%H:%M')
weekday = date.strftime('%a')

if (now == '06:30') and (weekday in ['Mon','Tue','Wed','Thu','Fri','Sat']):
  print("Weather Report")
  weather_data = requests.get('http://weather.livedoor.com/forecast/webservice/json/v1?city=%s' % weather_location_id).json()
  weather_today = weather_data['forecasts'][0]['telop'].encode('utf-8')
  print(weather_today)
  if '雪' in weather_today:
    print("Snowy")
    requests.put('http://<bridge ip address>/api/<username>/lights/<ID>/state',WEATHER_SNOWY)
  elif '雨' in weather_today:
    print("Rainy")
    requests.put('http://<bridge ip address>/api/<username>/lights/<ID>/state',WEATHER_RAINY)
  elif '晴れ' == weather_today:
    print("Sunny")
    requests.put('http://<bridge ip address>/api/<username>/lights/<ID>/state',WEATHER_SUNNY)
  else:
    print("Cloudy")
    requests.put('http://<bridge ip address>/api/<username>/lights/<ID>/state',WEATHER_CLOUDY)

ちなみに、Python 3系の場合は”encode(‘utf-8’)”の部分は不要です。

このプログラムを1分ごとに定期実行させてやればよいので、crontabを設定します。こんな感じで。

$ crontab -e
* * * * * python /home/pi/bottle/weather_report.py

crontabでの時刻設定方法は、例えばこちらなどが参考になるかと思います。あとは、Raspberry Piを再起動してつけっぱなしにしておけばOKです。hueの自動消灯については、hue公式アプリでタイマー設定してしまう方が簡単なので、ここでは設定していません。

 

以下、少しだけ上記プログラムの補足です。

天気は「晴れ」「曇り」「雨」「雪」の4つに分けて、それぞれ以下のようにhueのパラメータを設定しました。

  • 晴れ:{“on”:true, “bri”:24, “xy”:[0.52,0.42], “sat”:128, “effect”:”none”}
  • 曇り:{“on”:true, “bri”:24, “xy”:[0.33,0.30], “sat”:128, “effect”:”none”}
  • 雨: {“on”:true, “bri”:24, “xy”:[0.15,0.15], “sat”:128, “effect”:”none”}
  • 雪:{“on”:true, “bri”:48, “xy”:[0.33,0.30], “sat”:128, “effect”:”colorloop”}

晴れはオレンジっぽく、曇りは白っぽく、雨は青っぽくしています。雪は白くすると曇りと区別がつかないのでちょっと迷いましたが、まあ自分の住んでいる地域だと滅多にないことなので、「珍しいことが起きてるよ!」というのを知らせる意味で、次々と色が変わるcolorloopを設定しました。また、睡眠をできるだけ阻害しないよう、明るさは全体的に抑えめにしています。

それから、ちょっと考えないといけなかったのは、天気の優先順位です。Weather Hacksのtelopの値は「晴れ」「雨」のようなものだけでなく、「晴のち曇」や「晴時々曇」、「曇のち雨」のようなものも含まれています。これを正確にhueに表現させるのはちょっと難しそうなので、以下のように優先順位を決めます。

  1. 「雪」が含まれていたら、雪用設定
  2. 「雨」が含まれていたら、雨用設定
  3. 「晴れ」のみだったら、晴用設定
  4. 上記のどれにも該当しない場合は、曇用設定

基本的に雪か雨になるときのみ、普段の行動と変えなきゃいけないことがある(洗濯物の取り込みとか傘を持って行くとか)ので、その可能性があることを知れるかどうかが一番大事です。あとは、終日晴れであることがわかるならちょっと嬉しい、ぐらいなもんなので、基本は曇りになるように設定しました。

ちなみに、実際に2〜3週間ぐらいtelopの値を記録してみた結果、こんな感じでした。

  • 晴時々曇
  • 晴時々曇
  • 晴れ
  • 曇時々晴
  • 晴れ
  • 曇時々晴
  • 晴時々曇
  • 晴のち曇
  • 曇り
  • 曇時々晴
  • 曇時々晴
  • 晴時々曇
  • 曇時々晴
  • 曇のち晴
  • 曇時々晴
  • 晴時々曇
  • 晴時々曇
  • 晴れ

ということで、大抵の日は白っぽく光り、たまにオレンジに光ってたらちょっと嬉しい、ぐらいです。まだ一度も雨になったことがありません。ありがたいことですが。

 

こんな感じで、思ったよりはお手軽に、自分の思い通りにhueと天気予報を連動させることができました。「IFTTTが思いどおりに動いてくれなくてイライラするぜ!」という方にはオススメです。