Sympapaのスマートホーム日記

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

スマートホーム: トイレの照明自動化は奥が深い 2023

Sympapaです。


2週間くらい前に私もチャンネル登録している”のりごとー"さんのYouTubeチャンネルでHome Assistantが紹介されていました。
youtu.be


普段、ガジェットからお洒落で便利なアイテムまで紹介されている”のりごとー"さんですが、ディープなHome Assistantの世界をとても楽しそうに熱く語られています。
そして動画のDescriptionにこのブログのリンクを貼っていただいてました\(^o^)/
”のりごとー"さんも動画の中で話されていましたがHome Assistantの日本語の情報は非常に少なく、日本でもっともっと普及して欲しいです。
英語での検索は適切な検索ワードをみつけるのが難しいですし、ソレがなんとかなっても日本で生活している以上どうしても日本特有のデバイスをHome Assistantへ接続したいケースが出てきます。日本特有のデバイスをHome Assistantへ接続するにはそのためのインテグレーションが必要になるので、それを開発するスキルを持っているHome Assistantユーザーさんが一人でも増えると嬉しいですし、もっともっと日本でHome Assistantが普及してくれることを願うばかりです。


さて本題(笑)
暑いせいか最近、トイレの照明を制御する人感センサーの反応がよろしくないので、センサーの位置を調整しました。
合わせて、人感センサーの反応が鈍くても許容できるようにオートメーションも少し見直ししたので、繰り返しネタになりますがトイレの照明の自動化についてブログに書いてみようかなと。


住宅系YouTuberさんは玄関や廊下の照明は自動化するよう勧めていることがほとんどですが、トイレの照明の自動化については意見が分かれています。
理由はそう、ウンチ君をしていると人があまり動かないので人感センサーが反応せずに照明が消えてしまう問題があるからですね。
家のトイレの照明が自動化されていない方も、スーパーや公共施設や会社などでウンチ君の最中に照明が消えてしまいヘッドバンキングして再度照明を点けた経験はきっとあるでしょう(笑)


しかしHome Assistantならそんな悩みも解決できます。
やり方は色々あると思いますが、例えば普通の赤外線を使った人感センサーを使わずミリ波などを使ったセンサーを使うとか、オートメーションのロジック側でなんとかするとか。
我が家ではドア開閉センサーと(普通の)人感センサー2個を使って「トイレに人が入ったか」を判定し「人が入っていない時にドアを開けたら照明ON」「人が入っている時にドアを開けたら照明OFF」というオートメーションを組んでいます。一回「トイレに入った」と判定すればドアを開けるまで照明が消えないようにすることで、人感センサーが検出しなくなっても照明が消えないようにしています。
トイレの照明の自動化はたぶんHome Assistantを使い始めてから一番工夫を重ねたオートメーションでもあるし、自動化以外の拘りも盛り込んだ超自己満仕様なので、何度もネタにしたいと思います(笑)

■トイレの照明関連デバイスの構成

Home Assistantの使い始めの頃に書いた記事がこちらになります。
sympapa.hatenablog.com
sympapa.hatenablog.com


現在のデバイス構成は以下のとおりになっています。
人感で照明を直接ON/OFFするのではなく、トイレに入ったかどうかを判定しその判定をもとにドアの開閉時に照明をON/OFFするという考え方は変わっていないのでハードの構成も基本的には変わってませんが、人感センサーAを追加しましたね。(元のセンサーが人感センサーB)


[構成]
➀ドア開閉センサー (Aqura Door Window sensor MCCGQ11LM): トイレのドアの開閉をチェックします。
➁人感センサーA (Aqura Motion sensor RTCGQ11LM): ドアを開けたらすぐに検出してくれそうな位置に設置。人感検出後60秒毎に更新されます。
③人感センサーB (Aqura Motion sensor RTCGQ11LM): トイレの中に入るまでは検出されない位置に設置。更新間隔が5秒になる改造をした上で、人感検出後3秒後には「人感検出無し」になり、人感検出後5秒毎に更新されるというちょっと特殊な設定をしています。
➃照明: LEDVANCEのZigbee接続スマート電球 Classic E26 Dimmerble

■オートメーションのフロー

トイレの照明の自動化は6個ものオートメーションで構成しています(汗)
まとめれば3個くらいにはなりそうですが、まとめると1個の中で処理を分岐させることになり結局複雑になってGUIでの編集がやりづらくなるのでどっちもどっちかなと思います。
処理の流れとしては以下のような感じです。オートメーション4~6はイレギュラーが起きた場合の対応用です。


1)オートメーション2によって、ドアを開けた時又は人感センサーAが検出された時に「入室判定の仮想スイッチ」がOFFであれば照明を点けます。


2)オートメーション1によって、人感センサーBが検出された時に、人感センサーAが検出状態でかつドアが閉まっている場合「トイレに入った」と判定し「入室判定の仮想スイッチをONにします。人感センサーAの検出を条件に入れているのは人感センサーのゴースト検出対策です。2つの人感センサーが検出されないと「入室判定の仮想スイッチ」がONになりません。


3)オートメーション3は用を足した後の消灯用です。ドアを開けた時に「入室判定の仮想スイッチ」がONであれば照明を暗くし、同時に周囲が暗い場合はトイレの外側の廊下の照明を点けます。その後ドアが閉まるのを待って「入室判定の仮想スイッチ」をOFFにしてトイレの照明を消灯しますが、ドアが閉まらなくても30秒後には「入室判定の仮想スイッチ」をOFFにしてトイレの照明を消灯します。ドアの閉め忘れ対策です。


4)オートメーション4はトイレに入ろうとドアを開けたが、やっぱり止めてドアを閉めた場合のイレギュラー対応です。ドアを閉めて30秒後に「入室判定の仮想スイッチ」をチェックしてOFFの場合は照明を消します。実際にトイレに入った場合は、ドアを閉めてから30秒以内にオートメーション1による入室判定が完了していないといけないということになり、30秒はその猶予のための時間です。今まではここを15秒にしていたのですが、暑くて人感センサーの反応が鈍っているので今回ここを調整しました。


5)オートメーション5ではイレギュラー対応として、2つの人感センサーのいずれも検出が2分間無かった時に「入室判定の仮想スイッチ」がOFFの場合は照明を消します。これはトイレに入ろうとしてドアを開け照明が点いたけど、やっぱり止めて出ていき、且つドアを閉めなかった場合を想定しています。


6)オートメーション6ではイレギュラー対応として、照明が30分間連続点灯した時に、2つの人感センサーの反応が25分間無い状態であった場合は消灯します。イレギュラーで入室していないのに「入室判定の仮想スイッチ」がONになってしまうという想定外を想定しています(笑)


拘りポイントのひとつめは、点灯はなるべく早いタイミングでさせるという点です。ドアを開け始めた時点でトイレの照明が点灯するので人感で点灯させるよりも点灯タイミングが早くなります。用を済ませた後もドアを開けた時点でトレイの外側の廊下の照明が点灯するようにしています。
一方、トイレの使用後は自動で照明が消えるということを人が認識できるよう、ドアを開けた時点で暗くなりドアを閉めると消灯するようにしています。
拘りポイントのふたつめは人のイレギュラーな動きにできるだけ対応できるようにしている点です。ドアの閉め忘れとか、ドアを開けたまま掃除するとか様々な想定される人の動きに対応するオートメーションを組み、最後は想定できない動きを強引にねじ伏せるオートメーションを組んでいます(笑)

■実際のオートメーション

誰かひとりでも参考にして貰えればということで、一応コードものっけておきます。普段はGUIでしか見ていないので、ブログに貼り付けることで違った視点でチェックできるという効果もありますし(笑)
オートメーション1については、トリガーとなっている人感センサーBが人感をずっと検出していても「3秒間人感あり」→「2秒間人感無し」を繰り返す特殊な設定になっていて、人感をずっと検出している場合も5秒毎にトリガーが発動してくれることでこのオートメーションのロジックが成立するので、フツーの人感センサーでは実現できません。
Aqura Motion sensor (RTCGQ11LM)に簡単な改造をしてやることで実現可能です。
フツーの人感センサーを使った場合でも、人感センサーBを「必ずドアを閉めてから検出される位置」に設置すればイケるはずです。
あと、”照明をonにするスクリプト”の呼び出しが照明ONに相当します。”照明をonにするスクリプト”では時間毎に照度と色温度を変えて点灯させています。


こんなところですがオートメーションが長いので、先にご挨拶しておきます。(笑)
それでは。

alias: オートメーション1_トイレ1Fに入ったらinput_booleanをonにする
description: ""
trigger:
  - type: motion
    platform: device
    device_id: 人感センサーB
    entity_id: 人感センサーB
    domain: binary_sensor
condition:
  - condition: and
    conditions:
      - type: is_motion
        condition: device
        device_id: 人感センサーA
        entity_id: binary_sensor.人感センサーA
        domain: binary_sensor
      - type: is_not_open
        condition: device
        device_id: ドア開閉センサーのid
        entity_id: binary_sensor.ドア開閉センサー
        domain: binary_sensor
action:
  - service: automation.turn_off
    data:
      stop_actions: true
    target:
      entity_id: automation.オートメーション3
  - service: automation.turn_on
    data: {}
    target:
      entity_id: automation.オートメーション3
  - service: input_boolean.turn_on
    data: {}
    target:
      entity_id: input_boolean.toilet_1f_occupied_booleans
  - condition: state
    entity_id: light.照明
    state: "off"
  - service: script.照明をonにするスクリプト
    data: {}
mode: single
alias: オートメーション2_トイレ1Fのドアを開けたら照明をONにする
description: ""
trigger:
  - type: opened
    platform: device
    device_id: ドア開閉センサー
    entity_id: ドア開閉センサー
    domain: binary_sensor
  - type: motion
    platform: device
    device_id: 人感センサーA
    entity_id: 人感センサーA
    domain: binary_sensor
condition:
  - condition: state
    entity_id: input_boolean.toilet_1f_occupied_booleans
    state: "off"
action:
  - service: script.照明をonにするスクリプト
    data: {}
  - service: automation.turn_off
    data: {}
    target:
      entity_id: >-
        automation.オートメーション6
  - service: automation.turn_on
    data: {}
    target:
      entity_id: >-
        automation.オートメーション6
mode: single
alias: オートメーション3_トイレ1Fのドアを開けたら照明をOFFにする
description: ""
trigger:
  - type: opened
    platform: device
    device_id: ドア開閉センサー
    entity_id: ドア開閉センサー
    domain: binary_sensor
    for:
      hours: 0
      minutes: 0
      seconds: 1
condition:
  - condition: state
    entity_id: input_boolean.toilet_1f_occupied_booleans
    state: "on"
action:
  - choose:
      - conditions:
          - condition: numeric_state
            entity_id: sensor.廊下の照度センサー
            below: "80"
        sequence:
          - service: script.廊下の照明を点灯するスクリプト
            data: {}
    default: []
  - service: automation.turn_off
    data: {}
    target:
      entity_id:
        - automation.オートメーション2
  - service: light.turn_on
    data:
      transition: 1
      brightness_pct: 15
    target:
      device_id:
        - 照明のid
  - wait_for_trigger:
      - type: not_opened
        platform: device
        device_id: ドア開閉センサーのid
        entity_id: binary_sensor.ドア開閉センサー
        domain: binary_sensor
    timeout:
      hours: 0
      minutes: 0
      seconds: 30
      milliseconds: 0
  - service: input_boolean.turn_off
    data: {}
    target:
      entity_id: input_boolean.toilet_1f_occupied_booleans
  - service: light.turn_off
    data:
      transition: 1
    target:
      device_id:
        - 照明のid
  - service: automation.turn_on
    data: {}
    target:
      entity_id:
        - automation.オートメーション2
mode: single
alias: オートメーション4_トイレ1Fのドアを閉じてトイレに人がいない場合照明をOFFにする
description: ""
trigger:
  - type: not_opened
    platform: device
    device_id: ドア開閉センサー
    entity_id: ドア開閉センサー
    domain: binary_sensor
condition: []
action:
  - delay:
      hours: 0
      minutes: 0
      seconds: 30
      milliseconds: 0
  - condition: state
    entity_id: input_boolean.toilet_1f_occupied_booleans
    state: "off"
  - service: light.turn_off
    data:
      transition: 1
    target:
      device_id:
        - 照明のid
mode: single
alias: オートメーション5_トイレ1Fの人感が2分間無しで人がいない場合は照明をOFFにする
description: ""
trigger:
  - type: no_motion
    platform: device
    device_id: 人感センサーA
    entity_id: 人感センサーA
    domain: binary_sensor
    for:
      hours: 0
      minutes: 2
      seconds: 0
  - type: no_motion
    platform: device
    device_id: 人感センサーB
    entity_id: 人感センサーB
    domain: binary_sensor
    for:
      hours: 0
      minutes: 2
      seconds: 0
condition:
  - condition: state
    entity_id: input_boolean.toilet_1f_occupied_booleans
    state: "off"
action:
  - service: light.turn_off
    target:
      device_id:
        - 照明のid
    data:
      transition: 2
mode: single
alias: オートメーション5_トイレ1Fの人感検出長時間無しで照明をOFFにするNEW
description: ""
trigger:
  - platform: device
    type: turned_on
    device_id: 照明
    entity_id: 照明
    domain: light
    for:
      hours: 0
      minutes: 30
      seconds: 0
condition:
  - type: is_no_motion
    condition: device
    device_id: 人感センサーAのid
    entity_id: binary_sensor.人感センサーA
    domain: binary_sensor
    for:
      hours: 0
      minutes: 25
      seconds: 0
  - type: is_no_motion
    condition: device
    device_id: 人感センサーBのid
    entity_id: binary_sensor.人感センサーB
    domain: binary_sensor
    for:
      hours: 0
      minutes: 25
      seconds: 0
action:
  - service: automation.turn_off
    target:
      entity_id:
        - automation.オートメーション2
    data: {}
  - service: light.turn_off
    target:
      device_id:
        - 照明のid
    data:
      transition: 2
  - service: input_boolean.turn_off
    data: {}
    target:
      entity_id: input_boolean.toilet_1f_occupied_booleans
  - service: automation.turn_on
    target:
      entity_id:
        - automation.オートメーション2
    data: {}
mode: single


再びそれでは(笑)