Sympapaのスマートホーム日記

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

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

こんにちはSympapaです。

トイレの照明のON/OFF自動化は最も一般的な部類に入るホームオートメーションではないでしょうか?
多くのスーパーなどのトイレでも照明のON/OFFが自動化されているし思いつきやすいですよね。
というわけで家のトイレの照明も自動化をしようと考えるわけです。

最も単純かつ最初に思いつくのは人感センサーを使って人感検出で照明ON、人感を検出しなくなったら照明OFFってする方法ですが、ウンチくんをしている間に照明が消えてしまいその後頭を振りながらウンチくんをする経験をしたことがある人も少なくないでしょう。
スーパーのトイレならまだしも家のトイレは最もリラックスできる空間のひとつですので、快適にウンチくんをしたいものです。

さて、そうすると人感センサーに加えてドアの開閉センサーをトリガーや条件に組み合わせすればいいなと思いつくわけです。
話は逸れますが、我が家ではAqaraのDoorセンサーが活躍しています。
小さいのに動作が確実。使い始めて1ヶ月でバッテリー残量が70%くらいになっているので電池持ちが少々不安ではありますが(^^;
f:id:sympapa:20210905161257j:plain
で最初に組んだシーケンスは、人感検出で照明ON、その後ドアが閉まり再びドアを開けたら照明OFFというものでした。
人感センサーはドアを開けたら検出される場所に取り付けました。
しかしこれだと「ドアを開けたはいいけどやっぱりトイレに入らない」というフェイントをかますと照明はONのままになり、次にトイレに入ろうとすると照明がOFFになってしまいます。
うーむ。

そもそもドアセンサーがあるのに人感センサーで人感を検出してONにするのもアレですね。
ということで人感センサーは照明をONにするためではなくてトイレに入ったか否かを検出するのに使うことにして、以下のようなシーケンスを組んでみました。
人感センサーは下図のようにトイレのドアから便座までの間を通ると検出しトイレの中に入るまでは検出しないように設置します。
用を足している最中も検出したりしなかったりするので、そこいらへんには気を付けてシーケンスを組みました。
f:id:sympapa:20210905153015p:plain

[シーケンス1]
トリガー: ドアを開く
条件: トイレ前の廊下の人感センサーが人感を検出している(トイレの外から中へ入るのを識別するため)
1)電気をONにする
2)ドアが閉まった時にトイレに入っているかの変数:toilet_occupiedがoffだったら照明をOFFにする(ドアを開けたけどトイレに入らなかった場合の対応)

[シーケンス2]
トリガー:ドアを開ける
条件: 変数:toilet_occupiedが"on"である
1)[オートメーション1]を無効にする(そうしないとトイレの外へ出た時にシーケンス1が発動する場合がある)
2)照明をOFFにする
3)ドアが閉まったら[オートメーション1]を有効にする
4)変数:toilet_occupiedを"off"にする

[シーケンス3]
トリガー: 人感が検出される
1)トイレに入っているかの変数:toilet_occupiedを"on"にする

こうやって書くと単純ですがHome Assistantのオートメーションは分岐やGoto的なジャンプが出来ない(私が方法を知らないだけかも?)ので結構複雑になります。
尚、Home Assistantは標準ではユーザー変数が使えないのでこのカスタムコンポーネントを使っています。
そんなワケで以下のようになりました。

■オートメーション1

alias: トイレの照明をON
description: ''
trigger:
  - platform: state
    entity_id: binary_sensor.door_sensor_1_on_off(トイレのドアセンサー)
    from: 'off'
    to: 'on'
condition:
  - type: is_occupied
    condition: device
    device_id: uuuuu(廊下の人感センサー)
    entity_id: binary_sensor.motion_sensor_2_occupancy
    domain: binary_sensor
action:
  - service: script.light_toilet_on(照明をONにするスクリプトを実行)
  - condition: state
    entity_id: var.toilet_occupied(変数)
    state: 'off'
  - service: light.turn_off
    target:
      device_id: zzzzz(トイレの電球)
mode: single

■オートメーション2

alias: トイレの照明をOFF
description: ''
trigger:
  - platform: state
    entity_id: binary_sensor.door_sensor_on_off(トイレのドアセンサー)
    from: 'off'
    to: 'on'
condition:
  - condition: state
    entity_id: var.toilet_occupied(変数)
    state: 'on'
action:
  - service: automation.turn_off
    target:
      entity_id: automation.オートメーション1
  - service: light.turn_off
    target:
      device_id: zzzzz(電球)
    data:
      transition: 2
  - wait_for_trigger:
      - type: not_opened
        platform: device
        device_id: xxxxx(ドアセンサー)
        entity_id: binary_sensor.door_sensor_on_off
        domain: binary_sensor
    timeout: '30'
  - service: automation.turn_on
    target:
      entity_id: automation.オートメーション1
  - service: var.set(変数をセット)
    data:
      entity_id: var.toilet_occupied
      value: 'off'
      icon: mdi:human-handsdown
mode: single

■オートメーション3

alias: トイレに入ったら変数をonにする
description: ''
trigger:
  - type: motion
    platform: device
    device_id: yyyyy(トイレの人感センサー)
    entity_id: binary_sensor.motion_sensor_ias_zone
    domain: binary_sensor
condition: []
action:
  - service: var.set(変数をセット)
    data:
      entity_id: var.toilet_occupied
      value: 'on'
      icon: mdi:human-handsup
mode: single

これでイレギュラーな行動にもほぼ対応できたんじゃないかと思います。
まだ「鍵をかけずに用を足していて家族が入って来た」なんてイレギュラーには対応しきれてませんが(笑)

とか書いたそばから、「トイレに入ってドアを閉めずに出ていくイレギュラー」と「用を足してドアを開けたけどやっぱりもう少ししたい(笑)ってイレギュラー」を思いついたので、また修正予定です。
では。