Tech Racho エンジニアの「?」を「!」に。
  • IT Tips

「OK Google、おやすみ」といったら朝までエアコンを間欠運転する

夏の睡眠中エアコン問題

こんにちは、えんどうです。
皆さん夏の寝ている間はエアコンどうしてますか?人によってさまざまだと思いますが、私は

  • つけっぱなしは寒い
  • タイマーは切れると暑くて起きる

というわけで、アナログなプログラムタイマーのようにOn/Offを繰り返したいと思いました。

そんなことしなくてもエアコンは設定温度を維持するように運転するでしょ?という突っ込みは聞こえますが、それだと寒いのです。ある程度温度が波打つような感じのほうがいいです。

そして動くものができたのですが、思いのほかスマートではない絡み合ったものができてしまったので仕様書を兼ねて書くことにしました。

用語・利用するアプリやサービス

この記事での使い方になります。

  • 間欠運転
    On/Offを繰り返すこと

  • Googleアシスタント
    OK Google をトリガーにしてコマンドを受け取るソフト。スマホやGoogle Nest Hubの上で動く。

  • Google Homeデバイス
    Googleアシスタントを動かすハード。Google Nestシリーズ、Googleアプリのインストールされたスマホなど。

  • routine
    Google Homeアプリで定義する複数のコマンドをまとめて呼び出し可能にする機能

  • Tasker
    何かの状態や時間などをトリガーに動作を行うAndroidアプリ。Android標準の「ルール」よりいろいろできる。

  • IFTTT
    Taskerのネットワーク版のようなサービス。何かをトリガーにWebhookを呼んだりできる。

  • タスク
    ここではTaskerでの処理をひとまとめにした関数のようなもの。

  • SwitchBot
    IoT製品のブランド。今回はWiFiモジュールと赤外線リモコンがセットになったSwitchBot Hub Miniを使用。

要件

イメージ

  • 声で間欠運転を開始する。曜日や時間で開始するのではなく、毎日時間のことなる「おやすみ」をトリガーにする。
  • エアコンがついている状態でも、そこから間欠運転に入る
  • スマホ、Google Nest Hubのどちらが声を拾っても同じように動作する

  • 間欠運転のOff状態は送風(冷房30度)1とする

これは考えない

  • 間欠運転を声で止めることは今は考えない
  • エアコン付属のリモコンでは操作しない
  • AndroidスマホとGoogleアシスタント以外は考えない

できあがったもの

順を追うと長くなりそうだったので、結論を先にします。

詳細

各種アカウント設定やSwitchBot Hubへのデバイス(リモコン)登録は割愛させていただきます。

SwitchBotAPIのトークンとデバイスIDの取得

APIドキュメント

  • APIキーの取得
    SwitchBotアプリのプロフィール画面の設定を開き、アプリバージョン を10回程度タップします(Android設定の開発者になる手順と同じ感じです)。

開発者向けオプション メニューが現れるので、タップするとトークンが取得できます。

  • デバイスIDの確認
    ドキュメント#デバイスIDの取得に従ってエアコンのデバイスIDを取得します。*部分はマスクしています。
    「エアコン」の名前で登録してあるので、body.infraredRemoteList[1].deviceId を控えておきます。

get-device-list_response:

{
  "statusCode": 100,
  "body": {
    "deviceList": [
      {
        "deviceId": "E***********",
        "deviceName": "SwitchBot Hub",
        "deviceType": "Hub Mini",
        "enableCloudService": false,
        "hubDeviceId": "**********"
      }
    ],
    "infraredRemoteList": [
      {
        "deviceId": "01-********-********",
        "deviceName": "ライト",
        "remoteType": "DIY Light",
        "hubDeviceId": "*********"
      },
      {
        "deviceId": "01-********-********",
        "deviceName": "エアコン",
        "remoteType": "Air Conditioner",
        "hubDeviceId": "*********"
      }
    ]
  },
  "message": "success"
}

send-device-control_request-body:

{
  "command": "setAll",
  "parameter": "30, 2, 1, on",
  "commandType": "command"
}

IFTTT設定

  • If
    Googleアシスタントに「エアコン夜間タイマー」「エアコンタイマー」「暑い」のいずれかを言うと発動します。

  • Then
    LINEのNotify用グループにメッセージを送ります「tasker:EnableAirconTimer」の文字が通知に出るのでそれをTaskerで読み取ります。

Taskerの設定

  • 変数設定
    命名規則のばらつきがありますが、sbdevidAircon, sbToken は定数で「SwitchBotAPIのトークンとデバイスIDの取得」で控えたものを設定。

airconIntSec, airconTimerUntil はそれぞれ間欠運転の長さ(秒)と何時に止めるかを設定。
他は制御用でTaskerによって設定&変更されます。

  • プロファイル
    • プロファイルのトリガーには %airconWillStartAt > now などの変数比較をするとポーリング方式になるようで、遅く確実性が下がるため時刻ベースのトリガーにしています。
    • 時刻ベースのトリガーでFromとToに同じ値を設定するとピンポイントのワンタイムになるのですが、何らかの理由で失敗したときにフローのループが切れてしまうため、3分毎に設定することでリトライできるようにしています。

おやすみroutineの設定

Google Homeアプリのroutineを編集して、次の3つをまとめてやってもらいます。

  • アラーム設定
  • 照明を消す
  • エアコンを間欠運転する

課題

  • 0時前に間欠運転を開始すると1サイクルで止まる(8時に止めるように設定してあるが今23時だから)->あまりないから気にしない。自動乾燥機能になって逆にいいかも。
  • 間欠運転を止める手段がない。リモコンで止めたり「エアコンを止めて」といっても、またOnになる。
  • Androidアプリ動いているコントローラの役割はクラウドに持っていきたい。
  • SwitchBotAPIを直接呼ぶのではなく、Googleアシスタントにコマンドを送れるとGoogleアシスタントにリンクしている機器に操作できるようになる。
  • LINEの通知が残る。

トライ&エラーの跡

TaskerからGoogle Homeアプリのroutineを起動できる?

「エアコンをつけて」&「1時間後にエアコンを止める」のroutineをTaskerから2時間ごとに呼び出せばできそう!

Voice Command からroutine名を入力させると起動できるが、画面上で操作をエミュレートしているだけでスマホ画面をOnにしてしまったり、逆にスリープ中は動かない場合もあった。

TaskerからGoogle Homeアプリの声を送る

上記と同じ動機。

Voice Command からGoogleアシスタントを起動してListen状態にして、さらにTaskerから読み上げ機能でしゃべらせるというデジタルなのにアナログな手法。
もちろん、寝ている間にスマホがしゃべりだすので却下。(環境音にも影響される)

GoogleアシスタントからTaskerタスクを起動する

Taskerのタスクを起動させれば間欠運転制御できるとして、どうやって声でTaskerタスクを実行しようか?を解決したい。

Googleアシスタントの言語に英語を追加して、OK Google, run ${TaskName} in tasker と言うと起動することはできた(いまいち不安定)
英語の発音に自信がないのでキーボードから文字入力する。
そもそも論だが、Taskerが動かないGoogle Nest Hubで声を拾うと動かないので却下。

IFTTTアプリの通知は遅い

ここまでで、声を拾ったGoogle Homeデバイスがそのまま処理を続けることは難しいことがわかったので、GoogleアシスタントのコマンドをトリガーにIFTTTを噛ませてスマホに通知すれば必ずスマホ起点になることに気が付く。

IFTTTのTHENnotificationを実行するとスマホのIFTTTアプリを経由して通知されるので、これをTaskerで検知しようと考えた。

IFTTTアプリへの通知はFCMを使っていない?ポーリングしてる?ような記述があり、とにかく遅い。THENでメールを送ることもできるが、1分程度待たされることがある。

代わりにLINEの通知をトリガーにした。

単純な「n時間後に止める」ならroutineでできる

それ以前にエアコンのタイマーでできる。
「1時間後に消して」&「2時間後につけて」&「3時間後に消して」...は無理。

「仕事の日」routineで時間を都度指定してもできる

曜日を選んで自動発動。たまに夜更かしするどうする?
時間と曜日が固定なので使いにくい。声で好きな時に発動したいので却下。



  1. エアコンが古く冷房運転後の自動送風機能がありません。On/Offの回数だけ冷たくなったフィン(熱変換器)に結露が付くことが繰り返されるのでカビ臭くなります。そこで、間欠運転といいながらOffの状態は送風にしました。(送風運転もなかったので冷房30度設定です) 

CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。