Sympapaのスマートホーム日記

スマートなんとかはスマートじゃない方法でつくられている

Home Assistant: Androidタブレットで家のコントロールパネルを作る(3) [東芝IoLIFE対応洗濯機との連携]

Sympapaです。
今回は「Androidタブレットで家のコントロールパネルを作る」シリーズの第3回です。
せっかく家のコントロールパネルを作り常時稼働のAndroidタブレットが存在するので、APIが非公開だったりHome Assistantに統合出来ないサービスもタブレットを介して連携させてやりたいと思っています。特にやりたかったのは、東芝のIoLIFEというサービスと連携させドラム式洗濯乾燥機の状態をHome Assistantから取得することです。
洗濯乾燥機は洗濯が終わったところで一部の洗濯物を取り出して残りを乾燥させるとか、洗濯完了後にすぐに取り出して干したいという場合も多く、状態をリアルタイムに知ることが出来るのは便利なので意外にIoT化が活きる家電ではないかと思います。

■とりあえず「Androidタブレットで家のコントロールパネルを作る」記事のまとめ

これまでのAndroidタブレットで家のコントロールパネルを作るシリーズ記事まとめ
Androidタブレットで家のコントロールパネルを作る(1): 「Fully Kiosk Browser導入」
Androidタブレットで家のコントロールパネルを作る(2): 「TaskerとTaskerプラグインの導入」
Androidタブレットで家のコントロールパネルを作る(3) : 「東芝IoLIFE対応洗濯機との連携]」←今回
以降はネタが多すぎてどうやって分けるかは未定(笑)

■家のコントロールパネルとして使っているタブレット

家のコントロールパネルとしてキッチンの壁に固定して使っているタブレットは"Huawei MediaPad m5 Lite 8 JDN2-W09"です。
2019年の秋頃に発売されHuaweiAndroid末期のモデルでOSはAndroid 9です。
現在は新品は買えませんが2020年夏ごろには新品が20,000円前後で売られておりFull HDのタブレットとしては安価でした。
人気だったようでメルカリでもたくさん出品されています。
私は2021年12月にメルカリで中古の美品を12,000円くらいで購入しました。
CPUはKirin 710で廉価モデルながらサクサクです。新品であることやAndroid OSのバージョンにこだわらないのであれば、2022年1月現在、25,000円以下の新品Androidタブレットを買うよりも中古でコレを買う方がおススメです。
バックグラウンドのタスクを積極的にキルする点とUSB端子がmicro-Bで端の方にある点と環境光センサーが付いていないのがややマイナスポイントです。

■家のコントロールパネル用タブレットにインストールしている関連アプリ

家のコントロールパネル用タブレットにインストールしているアプリの内、今回の記事に関係するものを紹介します。

- Fully kiosk Browser:
Kiosk端末を想定したブラウザです。Home AssistantのフロントエンドUI: Lovelace UIの表示にはこれを使います。
play.google.com


-Home Assistantアプリ:
Lovelace UIの表示にはFully kioskを使いますが、Home AssistantアプリがあるとHome Assistantから通知を送れるのでインストールしています。
play.google.com


- Tasker:
Androidで定番の自動化アプリです。スクリプトを組んで色々自動化できます。
play.google.com


- Auto input:
Taskerのプラグインです。Taskerからタップ操作やテキスト入力を自動化できるようになります。
play.google.com


- Notification Listener:
Taskerのプラグインです。通知をTaskerのトリガーにしたり、Taskerから通知をタップしたり消去したりといった操作を自動化出来るようになります。
play.google.com


- Io Life:
東芝のIoT対応白物家電用アプリです。Google Playでは超低評価です(汗
play.google.com

■Home Assistantにインストールしているカスタムコンポーネント

Home Assistantでユーザー変数が使えるようになるカスタムコンポーネント: home-assistant-variablesをインストールしています。
今回もこの変数を使って構築していきます。
github.com

■IoLIFEとは何か?


ひとことで言うと東芝のIoT対応白物家電スマホアプリやGoogle Home,Alexaからコントロールしたり情報取得するためのサービスです。APIは日本の大手家電メーカーらしく(?)公開されていません。
我が家のドラム式洗濯乾燥機の場合だと、洗濯機の状態や警告がアプリに通知されたり、アプリで洗濯の残り時間を確認出来たり、Google Home,Alexaから音声で状態を確認出来たりする程度ですが、乾燥が開始したり運転が終了したことをお知らせしてくれるだけでもなかなか便利です。
しかし下記のとおりなかなかの糞仕様です。


-Google Homeから呼び出す場合面倒すぎる
私「アイオーライフと話したい」→AIお姉さん「はい、何をお手伝いしましょうか?」→私「洗濯機の状態は?」→AIお姉さん「洗濯中です」的な2往復のやりとりを必要とします。しかもレスポンスがすこぶる悪いです。
ちなみにシャープ製のエアコンも、私「エアコンをつけて」→AIお姉さん「○○のエアコンをオンですね?よろしいですか?」→私「はい」→AIお姉さん「○○のエアコンをオンにします」と同様に2往復のやりとりを必要とします。
これじゃちっとも便利じゃない。日本の大手家電メーカーさんは解っていないようです。


-アプリが気が付くと勝手にログアウトしている
結構な頻度でアプリが勝手にログアウトし、ログインを要求されることが多いです。
端末2台で確認済みで、Google Playのアプリのレビューにも以前から同じ報告が多数ありますが放置プレイのようです。

これらの糞仕様も踏まえた上でHome Assistantとの連携を構築していかなくてはいけません。

■構想

家のコントロールパネル用タブレットには普段はHome AssistantのLove Lace UIが表示されています。
今回やりたいことは下記のとおりです。

1)洗濯開始時にキッチンのNest HUBが「洗濯を開始しました」と喋りIoLifeのアプリが開いて洗濯機の状態を表示する。20秒後にHome AssistantのLove Lace UIに自動的に戻る。Love Lace UI上に表示された洗濯機の状態が「洗濯中」になる。
2)乾燥開始時にキッチンのNest HUBが「乾燥を開始しました」と喋りIoLifeのアプリが開いて洗濯機の状態を表示する。20秒後にHome AssistantのLove Lace UIに自動的に戻る。Love Lace UI上に表示された洗濯機の状態が「乾燥中」になる。
3)運転終了時にキッチンのNest HUBが「洗濯を完了しました」と喋りIoLifeのアプリが開いて洗濯機の状態を表示する。20秒後にHome AssistantのLove Lace UIに自動的に戻る。Love Lace UI上に表示された洗濯機の状態が「完了」になる。
4)Home AssistantのLove Lace UIに表示されたボタンを押すとIoLifeのアプリが開いて洗濯機の状態を表示する。30秒後にHome AssistantのLove Lace UIに自動的に戻る。
※IoLIFEアプリは勝手にログアウトしていることが多いので、アプリを自動で開いた時にログアウトしていた場合は自動でログインするようにする。
※本当は洗濯が完了するまでの残り時間を取得したいが難易度が高いのでまた今度。

アプリで開くを押すとIoLIFEアプリが起動する


■TaskerのプロファイルとHome Assistantのオートメーション


1)IoLifeアプリの通知をキャッチしてHome AssistantへHttpをPOSTするTaskerプロファイル
まずは起点となるタブレット側の処理です。
IoLifeアプリからの通知のTextが「洗濯を開始しました」「乾燥を開始しました」「運転が終了しました」の場合に、Home AssistantへhttpをPOSTしWebhookを使ってオートメーションを発動させるプロファイルを組んでいます。HttpをPOSTした後は通知を消す処理もしています。
下の例は洗濯を開始した時のプロファイルですが、同様に乾燥開始時と運転終了時のプロファイルも組んでいます。

    Profile: 洗濯を開始
    Settings: Restore: no
    Event: Notification Listener [ Configuration:Event: Posted Apps: IoLIFE Text: 洗濯を開始しました]
   
    Enter Task: Anon
   
    A1: HTTP Post [
         Server:Port: http://192.168.x.x:8123/api/webhook/washing_st
         Timeout: 10 ]
   
    A2: Cancel notifications [
         Configuration: Delete by app: IoLIFE
         Timeout (Seconds): 0
         Structure Output (JSON, etc): On ]


2)洗濯機の状態をユーザー変数にsetするHomeAssistantオートメーション
Taskerからの1)のWebhookを受けてHome Assistant側で発動するオートメーションです。
ユーザー変数: var.washing_machineをそれぞれ「洗濯中」「乾燥中」「完了」にsetします。
このユーザー変数をLovelace UIに表示させています。
下の例は洗濯開始時のものですが、乾燥開始時、運転終了時のものも組んでいます。

alias: washing_start
description: ''
trigger:
  - platform: webhook
    webhook_id: washing_st
condition: []
action:
  - service: var.set
    data:
      entity_id: var.washing_machine
      value: 洗濯中
      icon: mdi:washing-machine
mode: single


3)洗濯機の状態の変数が変化したらタブレットへ通知しキッチンのNest HUBが喋るHome Assistantオートメーション
洗濯機の状態の変数: washing_machineが変化したらHome Assistantからタブレット側のHome Assistantアプリへ"call_iolife"という通知を送っています。この通知を受けるとタブレット側でIoLIFEのアプリが開くようにしているのですが、起点はタブレット側なのに往復する処理をしていてまどろっこしいですね(笑)
なんでこんな処理にしたっけ?と思いましたが、LoveLace UI上のボタンを押した時にIoLIFEアプリを開く処理(下の5) )と共通化したようです。
その後、キッチンのNest HUBが状態に応じて「洗濯を開始しました」「洗濯機が乾燥を開始しました」「洗濯が完了しました」と話すようにしています。

alias: washing_say_and_call_iolife
description: ''
trigger:
  - platform: state
    entity_id: var.washing_machine
    for:
      hours: 0
      minutes: 0
      seconds: 1
      milliseconds: 0
condition: []
action:
  - service: notify.mobile_app_jdn2_w09
    data:
      message: call_iolife
      title: call_iolife
  - choose:
      - conditions:
          - condition: state
            entity_id: var.washing_machine
            state: 洗濯中
        sequence:
          - service: tts.cloud_say
            data:
              entity_id: media_player.nesthub_gen2_kitchen
              message: 洗濯を開始しました
      - conditions:
          - condition: state
            entity_id: var.washing_machine
            state: 乾燥中
        sequence:
          - service: tts.cloud_say
            data:
              entity_id: media_player.nesthub_gen2_kitchen
              message: 洗濯機が乾燥を開始しました
      - conditions:
          - condition: state
            entity_id: var.washing_machine
            state: 完了
        sequence:
          - service: tts.cloud_say
            data:
              entity_id: media_player.nesthub_gen2_kitchen
              message: 洗濯が完了しました
    default: []
mode: single


4)Home Assistantアプリの通知を拾ってIoLIFEアプリを開くTaskerプロファイル
再びタブレット側の処理に戻ります。
Home Assistantアプリからの通知のTextが「call_iolife」・・・3)でHome Assistantから送った通知・・・の場合にIoLIFEアプリを開き洗濯機の状態を表示する処理をしています。
単純にIoLIFEアプリを開けば済むわけではなくて、洗濯機の状態を表示したいのでその画面へ辿り着かなくてはいけません。しかも時々勝手にログアウトしている問題もあります。
IoLIFEアプリを開いた時の状態として「ログイン画面」or「機器を選ぶ画面」or「洗濯機の状態表示」の3パターンがあります。本当はどの画面が表示されているのかを確認して処理を分岐させた方が良いのでしょうが、画面の表示を認識して判定させるのが難しいので、ログインの処理→機器を選ぶボタンを押すという一連の処理を全て実行するようにし、他の画面だった場合には何も起きない箇所をタップするよう設定して強引に処理しています。
パスワードはクリップボードに入力してペーストする方法を使っていますが、セキュリティ上のリスクはあります。
IoLIFEアプリで洗濯機の状態を20秒間表示したら、普段開いているFully Kiosk Browserを開いて完了です。

    Profile: Call Iolife
    Settings: Restore: no
    Event: Notification Listener [ Configuration:Event: Posted Apps: Home Assistant Text: call_iolife ] ←Home Assistantの通知のTextが"call_iolife"の時にトリガ
   

    Enter Task: Anon
    Settings: Abort Existing Task
   
    A1: Launch App [
         Package/App Name: IoLIFE ]
   
    A2: Wait [
         MS: 500
         Seconds: 2
         Minutes: 0
         Hours: 0
         Days: 0 ]
   
    A3: Set Clipboard [
         Text: password ]←クリップボードにパスワードを貼り付ける
   
    A4: AutoInput Action [
         Configuration: Type: Point
         Value: 320,280 ←機器選択画面で洗濯機のボタンを押す座標
         Action : Click ←機器選択画面で洗濯機のボタンを押す
         Is Tasker Action: true
         Manage Accessibility Service: Enable Before Action
         Timeout (Seconds): 5
         Structure Output (JSON, etc): On ]
     
    A5: Wait [
         MS: 0
         Seconds: 1
         Minutes: 0
         Hours: 0
         Days: 0 ]
   
    A6: AutoInput Action [
         Configuration: Type: Point
         Value: 710,630 ←ログイン画面のパスワード入力欄を選んでクリアする座標
         Action : Cut ←パスワード入力欄に入力済みのテキストをカット(2重入力防止)
         Manage Accessibility Service: Unchanged
         Timeout (Seconds): 5
         Structure Output (JSON, etc): On
         Continue Task After Error:On ]
   
    A7: Wait [
         MS: 0
         Seconds: 1
         Minutes: 0
         Hours: 0
         Days: 0 ]
   
    A8: AutoInput Action [
         Configuration: Type: Point
         Value: 710,630 ←ログイン画面でパスワードをペーストする座標
         Action : Paste ←パスワード入力欄にパスワードをペースト
         Manage Accessibility Service: Unchanged
         Timeout (Seconds): 5
         Structure Output (JSON, etc): On
         Continue Task After Error:On ]
   
    A9: Wait [
         MS: 0
         Seconds: 1
         Minutes: 0
         Hours: 0
         Days: 0 ]
   
    A10: AutoInput Action [
          Configuration: Type: Point
         Value: 720,860 ←ログイン画面でログインボタンを押す座標
         Action : Click ←ログインボタンをタップ
         Manage Accessibility Service: Unchanged
          Timeout (Seconds): 10
          Structure Output (JSON, etc): On ]
   
    A11: Wait [
          MS: 500
          Seconds: 3
          Minutes: 0
          Hours: 0
          Days: 0 ]
   
    A12: AutoInput Action [
          Configuration: Type: Point
         Value: 320,400 ←機器選択画面で洗濯機のボタンを押す座標
         Action : Click ←機器選択画面で洗濯機のボタンを押す
         Manage Accessibility Service: Enable just for this action
          Timeout (Seconds): 5
          Structure Output (JSON, etc): On ]
   
    A13: Cancel notifications [
          Configuration: Delete by app: Home Assistant ←IoLIFEアプリの通知を消す
          Timeout (Seconds): 0
          Structure Output (JSON, etc): On ]
   
    A14: Wait [
          MS: 0
          Seconds: 20
          Minutes: 0
          Hours: 0
          Days: 0 ]
   
    A15: Launch App [
          Package/App Name: Fully Kiosk Browser ]
   


5)Lovelace UI上のボタンを押すとタブレットへ通知するHome Assistantスクリプト
Lovelace UI上のボタンを押した場合にもIoLifeアプリが表示され20秒後にLovelace UIへ戻る処理をしています。
単純にタブレットのHome Assistantアプリへ"call_iolife"という通知を送るだけのスクリプトを作り、Lovelace UI上にボタンとして表示しています。
通知を受けたタブレット側では上の4)のプロファイルがトリガされます。

 sequence:
  - service: notify.mobile_app_jdn2_w09
    data:
      message: call_iolife
      title: call_iolife
mode: single
alias: call_IOLIFE


■まとめ

これでせっかくのIoT対応洗濯機が少しだけHome Assistantと連携出来るようになりました。
まぁ出来るようになったことはショボイんですがTaskerとHome Assistantの連携方法の勉強にはなったかな?(笑)
Androidタブレットで家のコントロールパネルを作る」シリーズはまだ続きます。
今回は長くなったので次回はコンパクトにまとまるネタにしようかな(汗

それでは。