Sympapaのスマートホーム日記

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

スマートホーム: トイレの照明自動化は奥が深い2023[ミリ波人感センサー"ZY-M100-S"を使ってやり直し]

Sympapaです。


このところ暑さの影響か、赤外線人感センサーの反応が鈍いのを体感するケースが増えました。赤外線の人感センサーは温度の動きで人を捉えるため、体温に近い室温になると反応が鈍くなります。
特に我が家のトイレの照明については複雑なロジックで自動化しており、影響は単純に「点灯するのが遅くなる」といったものではなく、少し前にセンサーの位置を調整したりオートメーションを調整したりしたのですが、抜本的改善には至らず。。。


そこで、ミリ波を使った人感センサーをトイレの照明自動化に組み込むことを検討してみることにしました。ミリ波を使った人感センサーならば室温に影響されない上「じっとしていると検出されない」という赤外線人感センサーの欠点もありません。
しかし、ミリ波を使った人感センサー"ZY-M100-S"を買ってみたら、意外とクセがあったというのが前回のお話。。。
そして、そのクセを踏まえた上でトイレに組み込んでやったというのが今回のお話です。


尚、"ZY-M100-S"にはブランド違いの亜種が存在するようです。
良く出回っているのは給電端子がMicro USB-B端子のものですが、今回使用するのはLoginovoブランドで販売されているもので給電がUSB-C端子、Zigbee2MQTTで"ZY-M100-S_1"として認識されるモデルです。初期レビューは前回の記事をご覧ください。
sympapa.hatenablog.com

■"ZY-M100-S"をトイレで活用する場合の気になるクセ

トイレに設置する場合は人が滞在する場所が便座に限定されていて"ZY-M100-S"をターゲットの1m以内の近距離に設置できるため、検出時の即応性や感度の面はあまり気にする必要がなく良好です。思っていたより"ZY-M100-S"の検出時の即応性は高く近距離であれば1秒以内に検出するので、 "detection_delay"はなるべく短く設定し、それを活かせるようオートメーションを組みたいと思います。
一方、「じっとしている時」の継続検出の信頼性はめちゃくちゃ高いわけではないので、"fading_time"(検出無しにするまでの時間)をある程度長めにしてその信頼性を確保する必要があり、それを考慮してオートメーションを組みたいと思います。とはいえ、トイレの場合はターゲットが近距離なので、"fading_time"をそこまで長く設定しなくても大丈夫かなとは思います。ちょっとテストした感じだと10秒ではじっとしているとたまに未検出になるので15秒くらいがいいのかな。
あと気になるのは「壁の向こう側を検出する」「裏側も検出する」点で、最終的にはこれらを考慮して設置位置、設置の向き、パラメータなどの調整を行う必要があると思います。

■デバイスの構成

バイス構成は以下のとおりになっています。
従来はドア開閉センサー1個と赤外線人感センサー2個を使用していましたが、人感センサーのひとつをミリ波人感センサーに変更した形です。
人感で照明を直接ON/OFFするのではなく、トイレに入ったかどうかを判定しその判定をもとにドアの開閉時に照明をON/OFFするという基本ロジックは変えていません。


[ハードウェア構成]
➀ドア開閉センサー (Aqura Door Window sensor MCCGQ11LM): トイレのドアの開閉をチェックします。
➁赤外線人感センサー (Aqura Motion sensor RTCGQ11LM改): ドアを開けたらすぐに検出してくれそうな位置に設置します。5秒更新3秒でリセットという改造仕様、特殊設定です。
③ミリ波人感センサー(Tuya ZY-M100-S): トイレの中に入るまでは検出されない位置に設置します。
 設定は以下のとおりとしました。
"detection_delay": 0.5 sec
"fading_time": 15.0 sec
"maximum_range": 1.2 m
"minimum_range": 0.15 m
"radar_sensitivity": 9
➃照明: LEDVANCEのZigbee接続スマート電球 Classic E26 Dimmerble

ZY-M100-Sの裏面側は子供の部屋ですが、2日間稼働させて1回だけ子供が部屋にいる時に検出されました。後日、ミリ波人感センサーの背面を金属で覆ってやろうと思います。

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

ミリ波人感センサーを使えば「じっとしていても人感検出される」ので単純にミリ波人感センサーの検出により照明をON/OFFすれば良さそうな気がしますが、「じっとしていても継続的に人感検出される」信頼性を上げるために"fading_time"を長く設定すると人感無しに切り替わるまでの時間が長くなるので、トイレから人が出て次の人がすぐにトイレに入った場合に対応できなくなってしまいます。
それに、我が家のトイレの照明自動化には「人がトイレに入るよりも先に照明を点灯させよ。トイレから出る瞬間に自動で消えることを人に認識させよ。」というワケのわからないポリシーがあり、更にあらゆるイレギュラーな人の動きに対応できるロジックを作ろうとするとそう単純ではありません。
結局、6個のオートメーションで構成されていた超複雑な自動化は、5個のオートメーションで構成されるやや複雑な自動化に生まれ変わりました(笑)
特にイレギュラー発生時に「人がいなくなった」ことを判定するロジックで頭を悩ませる必要がなくなりミリ波人感センサーの"presence"にお任せできるようになったので、オートメーションの個数こそ1つしか減らなかったものの中身は結構シンプルに出来ました。


処理の流れとしては以下のような感じです。


1)オートメーション2によって、「ドアを開けた時」又は「赤外線人感センサーが検出された時」又は「ミリ波人感センサーが検出された時」に「入室判定の仮想スイッチ」がOFFであれば照明を点けます。いつもちゃんとドアが閉まっていれば「ドアを開けた時」だけをトリガーにすれば良いのですがお行儀のわる(略)


2)オートメーション1によって、ミリ波人感センサーの検出が開始された5秒後にドアが閉まっている場合「トイレに入った」と判定し「入室判定の仮想スイッチをONにします。あと、イレギュラー対応として、用を足した後ドアを開けたが「やっぱりもう少し」とドアを閉めて戻った場合、ミリ波人感センサーはずっと検出されたままなのでトリガーして発動してくれないので、5秒更新3秒リセットの設定をしている赤外線人感センサーもトリガーに加えています。ただ、暑い時は発動しづらいかもしれません。


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


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


5)オートメーション5はイレギュラー対応です。ミリ波センサーの"Presence"が検出無しに切り替わった時には、「入室判定の仮想スイッチ」をOFFにしてトイレの照明を消灯します。


2日間ほど稼働させていい感じで動いています。あとは背面側の遮蔽対策ですね。
ちなみに気のせいかもしれませんが、用を足して水が流れタンクに給水されている間は「人感無し」に切り替わらないように思います。このあたりも場合によっては考慮が必要になるかもしれません。

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

一応コードものっけておきます。
オートメーション1の人感センサーのトリガーは、今回使用している人感センサーが人感をずっと検出していても「3秒間人感あり」→「2秒間人感無し」を繰り返す特殊な設定になっていて、人感をずっと検出している場合も5秒毎にトリガーが発動することで成り立っているので、普通の人感センサーを使った場合はまず発動しません。まぁイレギュラー対応なので無くてもそこまで困らんかなとは思いますが、Aqura Motion sensor (RTCGQ11LM)に簡単な改造をしてやることで実現可能です。
あと、”照明をONにするスクリプト”の呼び出しが照明ONに相当します。”照明をONにするスクリプト”では時間毎に照度と色温度を変えて点灯させています。


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

alias: オートメーション1_トイレに入ったら入室判定仮想スイッチをonにする
description: ""
trigger:
  - type: present
    platform: device
    device_id: ミリ波人感センサー
    entity_id: ミリ波人感センサー
    domain: binary_sensor
    for:
      hours: 0
      minutes: 0
      seconds: 5
  - type: motion
    platform: device
    device_id: 赤外線人感センサー
    entity_id: 赤外線人感センサー 
    domain: binary_sensor
condition:
  - condition: and
    conditions:
      - type: is_not_open
        condition: device
        device_id: ドア開閉センサー
        entity_id: ドア開閉センサー
        domain: binary_sensor
      - type: is_present
        condition: device
        device_id: ミリ波人感センサー
        entity_id: ミリ波人感センサー
        domain: binary_sensor
action:
  - service: automation.turn_off
    data:
      stop_actions: true
    target:
      entity_id:
        - automation.toilet_2f_door_open_to_light_turn_off
  - service: automation.turn_on
    data: {}
    target:
      entity_id:
        - automation.toilet_2f_door_open_to_light_turn_off
  - choose:
      - conditions:
          - condition: state
            entity_id: input_boolean.toilet_2f_occupied_booleans
            state: "off"
        sequence:
          - service: input_boolean.turn_on
            data: {}
            target:
              entity_id:
                - input_boolean.toilet_2f_occupied_booleans
  - choose:
      - conditions:
          - condition: device
            type: is_off
            device_id: 照明
            entity_id: 照明
            domain: light
        sequence:
          - service: >-
              script.トイレの照明をONにする
            data: {}
mode: single
alias: オートメーション2_ドアを開けたら照明をONにする
description: ""
trigger:
  - type: opened
    platform: device
    device_id: ドア開閉センサー
    entity_id: ドア開閉センサー
    domain: binary_sensor
  - type: motion
    platform: device
    device_id: 赤外線人感センサー
    entity_id: 赤外線人感センサー
    domain: binary_sensor
  - type: present
    platform: device
    device_id: ミリ波人感センサー
    entity_id: ミリ波人感センサー
    domain: binary_sensor
condition:
  - condition: state
    entity_id: input_boolean.toilet_2f_occupied_booleans
    state: "off"
action:
  - service: script.トイレの照明をONにする
    data: {}
mode: single
alias: オートメーション3_ドアを開けたら照明をOFFにする
description: ""
trigger:
  - type: opened
    platform: device
    device_id: ドア開閉センサー
    entity_id: ドア開閉センサー
    domain: binary_sensor
condition:
  - condition: state
    entity_id: input_boolean.toilet_2f_occupied_booleans
    state: "on"
action:
  - choose:
      - conditions:
          - condition: numeric_state
            entity_id: sensor.トイレの外の廊下の照度センサー
            below: "80"
        sequence:
          - service: >-
              script.廊下の照明をONにする
            data: {}
    default: []
  - service: automation.turn_off
    data: {}
    target:
      entity_id:
        - automation.オートメーション2_ドアを開けたら照明をONにする
  - service: light.turn_on
    data:
      transition: 1
      brightness_pct: 15
    target:
      device_id:
        - トイレの照明
  - wait_for_trigger:
      - type: not_opened
        platform: device
        device_id: ドア開閉センサー
        entity_id: ドア開閉センサー
        domain: binary_sensor
    timeout:
      hours: 0
      minutes: 0
      seconds: 20
      milliseconds: 0
  - service: input_boolean.turn_off
    data: {}
    target:
      entity_id:
        - input_boolean.toilet_2f_occupied_booleans
  - service: light.turn_off
    data:
      transition: 1
    target:
      device_id:
        - トイレの照明
  - service: automation.turn_on
    data: {}
    target:
      entity_id:
        - automation.オートメーション2_ドアを開けたら照明をONにする
mode: single
alias: オートメーション4_ドアを閉じて30秒後に入室判定OFFなら照明を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_2f_occupied_booleans
    state: "off"
  - service: light.turn_off
    data:
      transition: 1
    target:
      device_id:
        - トイレの照明
mode: single
alias: オートメーション5_ミリ波人感センサーのprecenceがfalseになったら照明をOFFにする
description: ""
trigger:
  - type: not_present
    platform: device
    device_id: ミリ波人感センサー
    entity_id: ミリ波人感センサー
    domain: binary_sensor
condition: []
action:
  - choose:
      - conditions:
          - condition: state
            entity_id: input_boolean.toilet_2f_occupied_booleans
            attribute: "on"
            state: ""
        sequence:
          - service: input_boolean.turn_off
            data: {}
            target:
              entity_id:
                - input_boolean.toilet_2f_occupied_booleans
  - choose:
      - conditions:
          - condition: device
            type: is_on
            device_id: トイレの照明
            entity_id: トイレの照明
            domain: light
        sequence:
          - service: light.turn_off
            target:
              device_id:
                - トイレの照明
            data:
              transition: 2
mode: single


再びそれでは(笑)