コモノポリタン

コモノ、デジモノが好きなKomonopolitan住民 (はてなダイアリーからの引っ越しです)

【Home AssistantでDIY Smart Home】OMRON環境センサーの異常値を取り除け!

【Home Assistant(Hass.io)】
OMRON環境センサーの電池切れ異常値を除外する

「Home Assistant(Hass.io)でホームオートメーション 再起動!」シリーズです。
(書きかけ記事の消化強化期間中!!)

 OMRON環境センサー(WxBeacon2/Omron 2JCIE-BL01)は、様々なデータ(温度、湿度、気圧、騒音、照度)を観測出来て、まあ電池の持ちも良い(4ヵ月ぐらいはがんばる)のですが、電池切れかけるとデータが大きく変化(急に0になったり)するのが困りものです。

 こんな感じに下方向にスパイクが出てくると「ああ、電池が切れるな」というサイン。OMRON環境センサーは電圧も取得可能ですが、ゆったりと降下してゆくのと、気温による変動も大きくてなかなか目安にはならない感じです*1
f:id:maky_Ba:20220104210339j:plain:w200
 ということで、下方向のスパイクを取り除いてみましょう。

この記事の前提条件
Home Assistant core 2021.12.9
Home Assistant OS 7.1
Server Raspberry Pi 4(2GB)

 上記バージョンを前提とした手順です。 (最新版では動かないこともあるかもしれませんが、私が使っている限り、備忘録を兼ねて最新化してゆきたいとは思っています)

1. スパイク除去

 OMRON環境センサーの素のデータ(例えば、last_value_of_bathroom_temp浴室の室温)のスパイクを除去するセンサーを作りましょう。

1.1. スパイク除去版のセンサー作成

 不快指数や乾燥を計算した時に使ったtemplateプラットフォームをここでも使います。

 おぅ?!
 知らないうちにtemplateを使ったセンサーの設定(Configuration)の仕方が変わってますね。

sensors:
  - platform: template
      sensors:
      <sensor name>
      …

だったものが、

template:
  - sensor:
      - name: <sensor name>
      …

になりました。なおsensorだけでなくbinary_sensorも設定方法変わりました。

 温度のデータが下方向に大きく変化した時(今回観測間隔(=5分)で5度以上の降下)には、そのデータは無視するというセンサーを新しくつくりましょう。

(2022/1/25追記修正)
この記事に書きましたが、「下方向」だけでなく「上方向」にも異常値が出ることが分かったので、センサーのロジックを見直しました。

template:
  - sensor:
      # Low battery spike elimination for OMRON(Bathroom) 
      - name: last value of bathroom temp adj
        device_class: temperature
        unit_of_measurement: '°C'
        state: >
          {% set current = states('sensor.last_value_of_bathroom_temp') %}
          {% set result = 'unknown' %}
          {% if current != result %}
            {% set current = current | float(0) | round(1) %}
            {% set previous = states('sensor.last_value_of_bathroom_temp_adj') | float(0) %}
            {% set max_delta = 5.0 %}
            {% set result = current %}
            {% if previous %}
              {% if current < previous %}              # <--下振れ
                {% set lower_bound = previous - max_delta %}
                {% if current < lower_bound %}
                  {% set result = previous %}
                {% endif %}
              {% elif current > previous %}            # <--上振れ
                {% set upper_bound = previous + max_delta %}
                {% if current > upper_bound %}
                  {% set result = previous %}
                {% endif %}
              {% endif %}
            {% endif %}
          {% endif %}
          {{ result }}

1.2. スパイク除去の様子

 スパイク除去前がこちら。
f:id:maky_Ba:20220118202200j:plain:w300
(おう!-150℃!ここはどこ?地球上ではありませんね…)

 スパイク除去後がこちら。
f:id:maky_Ba:20220118204233j:plain:w300

 うまくいっている様子ですね。

2. 電池残量低下の警告

 ついでにと言ったら何ですが、スパイクを除去したのと同じアルゴリズムで異常値の発生を検知するセンサーをつくり、電池残量低下を検知したらHome Assistantの警報(alert)で通知を飛ばすようにしましょう。

2.1. 異常値検知センサーの作成

 下方向のスパイク除去と同じアルゴリズムで、下方向の異常値(5度以上の急激な低下)を検知した時にonになるbinary_sensorを作ります。

(2022/1/25追記修正)
こちらも記事のとおり「下方向」だけでなく「上方向」にも異常値が出ることに対応して、センサーのロジックを見直しました。

(前略) 
 - binary_sensor:
      # OMRON(Bathroom)
      - name: "Low Battery Detection Bathroom"
        state: >
          {% set current = states('sensor.last_value_of_bathroom_temp') %}
          {% set result = 'unknown' %}
          {% if current != result %}
            {% set result = 'off' %}
            {% set current = current | float(0) | round(1) %}
            {% set previous = states('sensor.last_value_of_bathroom_temp_adj') | float(0) %}
            {% set max_delta = 5.0 %}
            {% if previous %}
              {% if current < previous %}
                {% set lower_bound = previous - max_delta %}
                {% if current < lower_bound %}
                  {% set result = 'on' %}
                {% endif %}
              {% elif current > previous %}
                {% set upper_bound = previous + max_delta %}
                {% if current > upper_bound %}
                  {% set result = 'on' %}
                {% endif %}
              {% endif %}
            {% endif %}
          {% endif %}
          {{ result }}

(後略)

2.2. 通知設定

 Home Assistantでの通知の基本は「通知(Notifications)」インテグレーションです。緊急性の高いものをアプリなどを経由して通知する(notify)のが基本だと思います。似た機能としてWeb UIの左側の通知欄にバッヂ表示して忘れないように通知を出しておくという機能もあります。それが「永続通知(persistent_notification)」です。
 じつは実はこの「persistent notification」は、Home Assistantの通知のインテグレーションの基本である「notifications」とは微妙に異なる機能なのです!名前は似ているのに…。
 そのままでは「警報(alert)」インテグレーションで呼び出せないので、notifyインテグレーションのグループ設定を用いて「persistent notification」に一皮被せてsend_persistent_notificationという「通知」機能を作成します。

(前略)
#************************
# Notification
#************************
notify:
    name: send_persistent_notification
    platform: group
    services:
      - service: persistent_notification
(後略)

 つぎに「警報(alert)」インテグレーションで、電池残量低下の警告を通知できるようします。準備した電池残量低下を検知するサービスlow_battery_detection_bathroomonになったら、これまた先ほど作っておいたsend_persistent_notificationで通知するという設定をしましょう。

  • entity_id: 警報を発するために監視するサービスを指定
  • state: 警報を発する条件。onである間、繰り返し警報を発します。
  • repeat: 条件が満たされる間、警報を発する間隔。今の設定では15分以内にはスパイク状異常値から復帰していれば警報が1回だけ出されます。
  • can_acknowledge: これをtrueにすると読み終わったら通知を消せます。
  • skip_first: これをfalesにすることでonになった瞬間に警報を発することに出来ます
(前略)
#***********************
# Alert
#***********************
alert:
  battery_alert_omron_bathroom:
    name: omron bathroom battery is Low
    entity_id: binary_sensor.low_battery_detection_bathroom
    state: "on"
    repeat: 15
    title: "Battery Alert"
    message: "Battery(Bathroom) is Low!"
    can_acknowledge: true
    skip_first: false
    notifiers:
      - send_persistent_notification
(後略)

2.3. 通知の様子

 異常値を検知すると下記のように左下の通知欄にバッヂがつきます。
f:id:maky_Ba:20220119011824j:plain:w350

 通知を開くとこんな感じです。「消去」でこの通知を消せます。
f:id:maky_Ba:20220119011933j:plain:w350

3. おわりに

 今回は簡単。ただし5分間(測定間隔)に5度以上の本物の気温変化があったら困りものですが、それを含め、まあとりあえず様子見ですね。

maky-ba.hatenablog.com

*1:まあ、ある電圧以下になったらズバッとスパッと電池交換すれば良いだけの話ですが、貧乏性なのでぎりぎりを狙いたいのです。ダメ?