2019/05/25

自宅の HomeKit 化計画(2)

画像

まずは前回のおさらい。HomeKit は魅力的だけど現状は Phillips Hue 以外に目立った(役に立つ)対応機器がほぼないこと、ただし家にちょっとしたサーバー(ラズパイとかミニマムなものでいい)を置いて、Homebridge を動かして、Homebridge 用のプラグインを自分で書くなりなんなりして、それと Nature Remo なんかを連携させると便利に使えることまで書いた。

今回は実際にうちの自宅の話で進めていく。

Case 1 : エアコン - 概要

HomeKit にこだわらなければ、エアコンは Nature Remo(またはその他同じようなスマホから操作できる赤外線リモコンがいくらでもある)があればそれだけでもスマートデバイス化する。自分の場合はエアコンを HomeKit でいうところの Thermostat として操作したかったので、Homebridge 用のプラグイン "homebridge-thermostat" をベースにプラグインを実装して、バックエンドには Rails でサーバーアプリケーションを別に作った。

Rails アプリケーション側は homebridge-thermostat からエアコンをON/OFFする、モード(冷房、暖房など)を切り替える、設定温度を切り替える、こういった操作を受け付けて Nature Remo 側に送信してやる処理と、HomeKit 側に情報(現在ON/OFFのどちらか、現在のモード、現在の設定温度)を返してやる処理を作ってあげた。

Nature Remo で便利なのは、Nature Remo Cloud API を使ってやると現在のエアコンの設定が取得できるところだった。ただしこの API がちょっとクセモノで、HomeKit 側は Home.app とかを開いたタイミングでサーバー側に大量のリクエスト(どうやら現在の情報を得るためのリクエストがいろいろ別れて飛んできてるみたい)を送ってくるんだけど、Nature Remo Cloud API を連続して叩きまくると正しく応答しなくなった。

Rails アプリはこの中間レイヤーに入ってもらうことで、Nature Remo Cloud API から取れる情報をキャッシュしたりして、なんとかうまいこと動いてもらっている。

Case 1 : エアコン - 補足

HomeKit の Thermostat には以下のモードがある。

  • オフ
  • 暖房
  • 冷房
  • 自動

日本でよく普及しているタイプのエアコンだと「除湿/ドライ」みたいなのがある。ただこれは HomeKit の API には定義されていないので使えない。「除湿/ドライ」の切り替え設定は必要があれば「自動」と置き換えてやる(自分の場合なら Rails アプリ側から Nature Remo に「自動」の信号を送る代わり「除湿」の信号を送る)ことで・・・そんなに問題はない気がしている。

Case 2 : テレビ

最近リリースされた iOS 12.3 から HomeKit デバイスにスマートテレビが加わった。

ただドキュメントを読んだりしてみると、HomeKit 対応デバイスとしてのテレビは所謂スマートテレビ。例えば iPhone とかでテレビの ON/OFF は当たり前として、音量、あとは YouTube、Netflix とかに切り替える機能まで存分に使えるっぽかった。

でもこっちの持ち手は赤外線リモコンである Nature Remo のみ。

そんな高度なことはできないので、とりあえずテレビの ON/OFF ができればいいってことで作った。

ON/OFF の制御用には homebridge-http-switch をこれまたちょっとカスタマイズして使った。プラグイン名に http って付いているので察せる通り、他にサーバーを置いてスイッチ制御したい時とか情報を取得したい時はその用意したサーバーを使ってね、ってスタンス。

自分の場合はエアコンの時と同じ Rails サーバーにスイッチの状態(ON or OFF)の状態だけ記録しておくようにした。

サーバー側には OFF の状態になっているときに、HomeKit 以外の選択肢でテレビの電源を入れた場合、当然サーバーにある ON/OFF 情報と実態が乖離する。一応その応急処置的な対処法として、サーバー側からテレビに ON の信号を送れるのはサーバー側に OFF が記録されている時だけにするようにした。

要は・・・

  • ON の操作がされた場合、
    • サーバー側に OFF が記録されていたら ON/OFF 制御信号を送って OFF の記録を残す
    • サーバー側に ON が記録されていたら信号は送らず ON の記録を残す
  • OFF の操作がされた場合
    • サーバー側に ON が記録されていたら ON/OFF 制御信号を送って ON の記録を残す
    • サーバー側に OFF ga記録されていたら信号は送らず OFF の記録を残す

文字にすると微妙だけど、一応こんな感じで作ることで、途中で ON/OFF 情報が実態とサーバーでずれても、何度か操作するうちに一致するようにした。

ややこしいので実際のコードの一部も載せておく。

class Tv

  def on!
    set_state('ON')
  end

  def off!
    set_state('OFF')
  end

  private

  def tv_id
    'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxx'
  end

  def token
    "トークン"
  end

  def set_state( state )
    settings = {}
    uri = URI.parse("https://api.nature.global/1/appliances/#{tv_id}/tv")
    http = Net::HTTP::Persistent.new
    http.headers['accept'] = 'application/json'
    http.headers['Authorization'] = "Bearer #{token}"

    # キャッシュをロード
    cache = Television.first

    # 状態を保存
    case state
    when 'OFF'
      settings['button'] = 'power' if cache.state.eql?('ON')
    when 'ON'
      settings['button'] = 'power' if cache.state.eql?('OFF')
    end

    post = Net::HTTP::Post.new(uri)
    post.set_form_data( settings )
    response = http.request(uri, post)

    cache.state = state
    cache.synced_at = Time.now
    cache.save
  end

end

コード載せたはいいけど、これで伝わるんかいな・・・。ちなみに掲載するにあたってこの Tv クラスにまとめたけど、実際は token とかは他でも使いまわしているから、Tv クラス自体はそれのサブクラスなのだけ追記しておこう。

残すは PS4・・・

今回、エアコンと TV の制御については書いたんだけど、最後のデバイスである PS4 がまたやってることが特殊で、いろいろ書いてまとめないといけないことに気づいたので、今回はここまで。

次回は最後の PS4 の制御がらみについて書く・・・・けどあんま期待しないでね。

Tech
カテゴリ "Tech" の最近の記事。

About
nobu's homepage について

nobu's homepageサトウノブユキが自らのウェブ上でのアクティブな情報発信をひっそりと行うために運営している個人サイトです。Voice では自由な意見や各種レビュー、ニュース等を発信しています。趣味の写真のお気に入りは PhotosPhoto Journal で配信しています。

Biography
自己紹介。略歴程度。

1984年4月17日、新潟県新潟市(現中央区)出身、東京都在住。現職は 株式会社取締役、クリエイティブディレクター。本名は漢字で佐藤信之(大好きだったじーちゃんからもらった大切な名前)だけど、普段は堅苦しいからサトウノブユキってカタカナ表記を使ってる。気まぐれで Anonyz を作ったりしてる人。トレードマークになってるピンクや赤の髪の毛はサトウって苗字がありふれ過ぎているかが故に識別子として、が最初の理由。

Copyright © 2019 s.nobu All rights reserved.