ボストンに引っ越しました。
こちらのアパートは日本と違って各部屋のエアコンというものはなく、全室空調になっています。
その温度設定をするのがサーモスタットと言われているこういうコントローラ。
要するに、室温をセンサで読み取って、設定値より高く or 低くなると、暖房/冷房に繋がった線を短絡させて空調を作動させる装置です。
で、こいつは交換可能になっていて、時間によってプログラムした温度に調整してくれるとか、Wi-Fi経由でiPhoneから設定ができるとか、高機能なものに付け替えることができます。
そういうわけで、さっそくWi-Fi対応のものに交換してみました。Honeywellという会社のRTH6580WFというのを使いました。交換方法はメーカーがYouTubeで解説してくれています。
取り付けると最初はWi-Fiアクセスポイントとして機能して、そこに接続してWebページからWi-Fiルータへの接続設定を行います。すると、Honeywellのサーバに接続した状態になり、このサーバ経由でWebやiPhone/Androidアプリから各種設定ができるようになります。
ただ単に公式アプリを使って設定できるというだけでは面白くないので、iPhoneの音声アシスタント「Siri」を使って室温などを変更できるようにしてみました。
設定変更用のコマンドを用意する
まず、Webサイトを通じて温度設定や暖房/冷房/オフを切り替えるためのコマンドを用意します。
適当にWebサイトとの通信を眺めて、それをシェルスクリプトに切り出しました。*1
https://gist.github.com/NeoCat/5279143
SiriProxyをセットアップする
SiriProxyをインストールします。今回はMacをサーバにしました。インストール方法はREADMEにある通り、ruby1.9か2.0を入れて、gem install siriproxyする感じです。
適当に検索するとより細かいインストール方法も出てきます。
ただし、現在のSiriProxyはDNS機能を搭載したので、dnsmasqは不要になっている点に注意。
インストールしたら、設定ファイル ~/.siriproxy/config.yml に次のように記入します。pluginsについては後述します。
listen: 0.0.0.0 port: 443 log_level: 1 upstream_dns: [8.8.8.8, 8.8.4.4] server_ip: 192.168.1.112 ← MacのIPアドレス plugins: - name: 'RemoteControl' path: '/Users/NeoCat/Applications/SiriProxy/SiriProxy-RemoteControl'
上記のように、server_ip にMacの(iPhoneから見える)IPアドレスを書いてあげることで、DNS機能が有効になります。このDNSサーバでAppleのSiriサーバの代わりにSiriProxyに接続するように誘導する仕組みです。
SiriProxyのプラグインを書く
こちらの記事を参考に、サーモスタット制御用のプラグインを書きます。
SiriProxyのプラグインとしてSiriで家電を操作するSiriProxy-iRemocon - blog.katsuma.tv
SiriProxy/plugins/siriproxy-example を丸っとコピーして別のディレクトリ*2に移し、Gemfileを適当に変更し、lib/siriproxy-example.rb (適当に改名してもok) の内容を下記のように編集します。そして、設定ファイルに自分のプラグインのパスを書き加えておきます。
# -*- coding: utf-8 -*- require 'cora' require 'siri_objects' require 'pp' require 'json' require 'net/http' class SiriProxy::Plugin::RemoteControl < SiriProxy::Plugin def initialize(config) end listen_for /(?:部屋の温度|室温)は?/ do |mode,temp| set_temp(nil, nil) request_completed end listen_for /(暖房|冷房)の(?:設定)?温度を?(\d+)度に(?:設定)?/ do |mode,temp| say "#{mode}の温度を#{temp}度に設定します" mode = mode == "暖房" ? "-h" : "-c" set_temp(mode, temp) request_completed end listen_for /(暖房|冷房).*(?:(?:自動|オン)に?(?:設定)?|つけて)?/ do |mode| say "#{mode}の温度を自動設定にします" mode = mode == "暖房" ? "-h" : "-c" set_temp(mode, nil) request_completed end listen_for /(暖房|冷房|空調|エアコン)を?(?:停止|ストップ|オフに|止めて|切って)?/ do |mode| say "#{mode}をオフにします" set_temp('-o', nil) request_completed end private def set_temp(mode, temp) ret = nil IO.popen "/Users/NeoCat/bin/honeywell_set_temp.sh #{mode||''} #{temp||(mode ? 'schedule' : '')}" do |result| while line = result.gets puts line ret = line end ret = JSON.parse ret end if ret['success'] say "#{temp ? temp.to_s+'度に設定しました。' : mode == '-o' ? 'オフにしました。' : mode ? '自動に設定しました。' : ''}現在の室温は#{ret['latestData']['uiData']['DispTemperature'].to_i}度です" else say "設定に失敗しました" end ret end end
iPhoneにCAルート証明書をインストール
SiriProxy用のCAルート証明書をiPhoneに登録します。
% siriproxy gencerts
を実行すると、 ~/.siriproxy/ca.pem というファイルができるので、これをメールに添付してiPhoneに送り、インストールします。(アンインストールは設定のプロファイルから行えます。)
SiriProxyを起動
SiriProxyを起動します。
% sudo siriproxy server [Info - Configuration] Loading plugins -- If any fail to load, run `siriproxy bundle` (not `bundle install`) to resolve. [Info - Server] DNS Server started, tainting 'guzzoni.apple.com' with 192.168.1.112 [Notice - Server] ======================= WARNING: Running as root ============================= [Notice - Server] You should use -l or the config.yml to specify and non-root user to run under [Notice - Server] Running the server as root is dangerous. [Notice - Server] ============================================================================== [Info - Server] Starting SiriProxy on 0.0.0.0:443... [Info - Server] SiriProxy up and running.
rootで動かしてしまっているので警告が出ていますが、とりあえずこれで。。
Siriに向かってしゃべる
暖房の温度設定を変更してみます。ちなみに温度は華氏です。ほんとSIじゃない単位やめてほしいよね。
「暖房の温度を〜」ていってるつもりなんだけど「を」を拾ってくれない(--; でもこれくらいの揺らぎは正規表現でがんばって吸収しています。
出来上がり
やってみたら意外と簡単にできました。
ただSiriProxyはこのままだとMacと同じWi-Fiの中でないと使えません。外から家のMacと通信するためには、たとえばVPNを張る必要があるでしょう。
そこまでする手間を考えると、外では公式アプリで十分かな…
*1:毎度おなじみのリバースエンジニアリング(?)
*2:最初 plugins/ の中で作業しようとしていましたが、プラグインは一つのgemになっていることが前提になっているため、siriproxy本体の外に移さないとうまく行きませんでした。