Sympapaのスマートホーム日記

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

Home Assistant: テレビの電源をHome Assistantと同期する

Sympapaです。

我が家ではHome Assistant+Andriodタブレットで家のコントロールパネルを作り、キッチンとリビングの照明やテレビ,エアコンを操作できるようにしています。
電源がオンなのかオフなのかもコントロールパネル上のアイコンの色で判るようにしたい(既に照明はそうしている)のですが、家電付属の赤外線リモコンで操作した場合はHome Assistantへ操作したことを伝達できず同期ができないという課題があります。


また、Home Assistantから照明やテレビ,エアコンを操作する時は見かけ上同期出来ますが、スマートIRリモコン: Nature Remoを経由しているのでIR信号が100%家電に届いて指示どおり動作しているとは限りません。(まぁ実際は100%動いてますけど)
他にも、Nature RemoなどのスマートIRリモコンを使って自動化をする場合、家電付属のリモコンがテレビのようにトグルボタンになっているとスマートIRリモコンでもトグルボタンのIR信号しか用意できない場合も多く、例えば「テレビの電源状態に関わらず確実にオフにする」シーケンスを作るには、電源の状態を取得して電源がオンであることを条件に電源ボタンのIR信号を発射するような工夫をする必要が出てくる場合もあります。


このように、スマートホーム化を進めると、どうしても家電がオンなのかオフなのかをHome Assistantなどのスマートホームシステム上で取得したい場面が出てきます。


家電の電源がオンかオフかを検出する方法として思いつくのは、①電力(電流)を取得し閾値を設定する、➁(照明やディスプレイや電源インジケータなどの)照度を取得し閾値を設定する、③物理的動作を何らかのセンサーで検出する、の3つくらいかなと思います。
先日、消費電力を取得できるスマートプラグを入手したので、今回はそれを使って消費電力を取得しHome Assistantとテレビの電源状態を同期したいと思います。


■使用するスマートプラグ

使用するスマートプラグはSengled E1C-NB7です。
Home AssistantとはZigBeeで接続し消費電力(W)と電力量(kWh)を取得が出来ます。消費電力取得のタイムラグが1~3秒くらいあるのとテレビを電源オンにしてから消費電力が立ち上がるまでので時間もあるので、それも考慮して設定していきましょう。

sympapa.hatenablog.com



■とりあえず今回のゴール

今回のゴールは以下のとおりです。

  • 家のコントロールパネルにテレビの電源のトグルボタンを表示し、テレビの電源がオンの時はアイコンの色が変わるようにする
  • Home Assistantから, Google Homeから, テレビ付属のリモコンから、いずれの方法でテレビの電源をオンオフしても上記アイコンの色が変わるようにする


■Home Assistantの設定

単純そうで意外と悩みました。
我が家ではHome AssistantやGoogle HomeからテレビをコントロールするのにスマートIRリモコン:Nature Remoを使っています。
Home AssistantとGoogle Homeからテレビの電源をオンオフする時はIR信号を発射しなくてはいけませんが、テレビ付属のリモコンから電源をオンオフし同期を取った時はIR信号を発射して欲しくない。
最初は「オンオフ状態の保持」と「Home Assistantからのテレビ操作」を切り離してしまい、消費電力の変化だけで「保持しているオンオフ状態」をオンオフすればいいんでしょと思いました。しかし、家のコントロールパネル上のボタンを押して操作した時はアイコンの色が即変化しないと違和感を感じますが消費電力の取得には数秒のタイムラグがあります。
じゃあ「テレビのSwitch」そのものをボタンとして家のコントロールパネルに表示したらどうなるかというと、ボタンを押した時はIR信号が発射されなきゃいけないんですが、消費電力の変化で「テレビのSwitch」をオンオフした時にはIR信号を発射しないようにする処理をしなくてはいけません。消費電力取得のタイムラグがあるので「消費電力」と「テレビのSwitch」の整合性を条件にしてIR信号を発射するか否かを決めてもうまくいきません。
「オンオフ状態の保持」と「Home Assistantからのテレビ操作」を分けておいて、家のコントロールパネルのボタンを押した時は「テレビのSwitch」の操作、ボタンに表示されているアイコンは「保持されているオンオフ状態」という操作と表示が別々のボタンを作れればいいんですが、やり方が判りません(汗


まぁ他にも悩んだ点は多数ですが文章で書いても解りにくい長文になるだけなので(略
とりあえず今回は、現状の私のスキルでも出来る方法で設定していきましょう。


1.Switchの作成

今まではHome Assistantからテレビをコントロールする場合、直接rest_commandでIR信号を発射しているだけでした。
今回は電源オンオフの状態を保持しなくてはいけないので、まずはconfiguration.yaml上でテレビ用のSwitch"switch.kitchen_tv"を作ります。
それと、消費電力の変化で"switch.kitchen_tv"を操作する場合にIR信号を発射しないフラグ用として"switch.kitchen_tv_switch_by_sensor"も作ります。
私にはコードを書くスキルがないので"switch.kitchen_tv"をオンオフしたら後の処理はスクリプトに丸投げするように設定しておいて、あとはオートメーションとスクリプトの方で何とかしています(汗



【configuration.yaml

input_boolean:
  kitchen_tv:
    name: kitchen_tv
  kitchen_tv_switch_by_sensor:
    name: kitchen_tv_switch_by_sensor

switch:
  - platform: template
    switches:
      kitchen_tv:
        value_template: "{{ states('input_boolean.kitchen_tv') }}"
        turn_on:
          - service: input_boolean.turn_on
            entity_id: input_boolean.kitchen_tv
          - service: script.bravia_on
        turn_off:
          - service: input_boolean.turn_off
            entity_id: input_boolean.kitchen_tv
          - service: script.bravia_off
     kitchen_tv_switch_by_sensor:
        value_template: "{{ states('input_boolean.kitchen_tv_switch_by_sensor') }}"
        turn_on:
          - service: input_boolean.turn_on
            entity_id: input_boolean.kitchen_tv_switch_by_sensor
        turn_off:
          - service: input_boolean.turn_off
            entity_id: input_boolean.kitchen_tv_switch_by_sensor

rest_command:
  bravia_on:
    url: 'http://192.168.11.x/messages'
    method: POST
    headers:
      Accept: 'application/json'
      Content-Type: 'application/json'
      X-Requested-With: 'curl'
      Expect: ''
    payload: '{"format":"us","freq":38,"data":[2411,580,610,610,(略),36180]}'

  bravia_off:
    url: 'http://192.168.11.x/messages'
    method: POST
    headers:
      Accept: 'application/json'
      Content-Type: 'application/json'
      X-Requested-With: 'curl'
      Expect: ''
    payload: '{"format":"us","freq":38,"data":[2411,580,1220,580,(略),36180]}'


2.スマートプラグの消費電力変化でSwitchをオンオフするオートメーション作成

次は、スマートプラグがモニターしている消費電力が変化したら"switch.kitchen_tv"をオンオフするオートメーションを作ります。
トリガーは「消費電力が21W以上になった時または消費電力が20W以下になった時」です。
消費電力が21W以上でかつ"switch.kitchen_tv"がオフの場合に"switch.kitchen_tv"をオンにし、消費電力が20W以下でかつ"switch.kitchen_tv"がオンの場合に"switch.kitchen_tv"をオフにするようにしました。
また"switch .kitchen_tv"をオンオフする前に"switch.kitchen_tv_switch_by_sensor"をオンにして「これは消費電力による"switch.kitchen_tv"の操作ですよ」というフラグを立てています。(フラグの処理については後述)

alias: Bravia_get_power_status_by_sengled
description: ''
trigger:
  - type: power
    platform: device
    device_id: スマートプラグのID
    entity_id: sensor.sengled_e1c_nb7_bravia_power
    domain: sensor
    above: 21
    for:
      hours: 0
      minutes: 0
      seconds: 1
  - type: power
    platform: device
    device_id: スマートプラグのID
    entity_id: sensor.sengled_e1c_nb7_bravia_power
    domain: sensor
    below: 20
    for:
      hours: 0
      minutes: 0
      seconds: 1
condition: []
action:
  - choose:
      - conditions:
          - type: is_power
            condition: device
            device_id: スマートプラグのID
            entity_id: sensor.sengled_e1c_nb7_bravia_power
            domain: sensor
            above: 21
          - condition: state
            entity_id: switch.kitchen_tv
            state: 'off'
        sequence:
          - service: switch.turn_on
            data: {}
            target:
              entity_id: switch.kitchen_tv_switch_by_sensor
          - service: switch.turn_on
            target:
              entity_id: switch.kitchen_tv
            data: {}
      - conditions:
          - type: is_power
            condition: device
            device_id: スマートプラグのID
            entity_id: sensor.sengled_e1c_nb7_bravia_power
            domain: sensor
            below: 20
          - condition: state
            entity_id: switch.kitchen_tv
            state: 'on'
        sequence:
          - service: switch.turn_on
            data: {}
            target:
              entity_id: switch.kitchen_tv_switch_by_sensor
          - service: switch.turn_off
            target:
              entity_id: switch.kitchen_tv
            data: {}
    default: []
mode: single


3.Switchが操作されたら実行するスクリプトの作成

次に"switch.kitchen_tv”が操作されたら実行するスクリプトを作成します。
"switch.kitchen_tv”がオンになった時に実行するスクリプトでは、消費電力による操作であることのフラグ"switch.kitchen_tv_switch_by_sensor"がオフの時にのみテレビをオンにするIR信号をNature Remoが発射するrest_command:を実行します。
タイムラグにより家のコントロールパネルのボタンを連打すると不整合が生じるので、その後6秒後に"switch.kitchen_tv"と消費電力の整合をチェックし不整合があった場合は、消費電力に合わせてIR信号を発射せずに"switch.kitchen_tv”操作するようにしています。
ちょっと処理がループする懸念がありますけど、2回目のループでは条件の不整合は無いはずなので大丈夫なはず、たぶん。
同様に"switch.kitchen_tv”がオフになった時に実行するスクリプトも作成しました。


【Switchがオンになった時に実行するスクリプト

alias: Bravia_on
sequence:
  - service: script.turn_off
    data: {}
    target:
      entity_id:
        - script.bravia_off
  - choose:
      - conditions:
          - condition: state
            entity_id: switch.kitchen_tv_switch_by_sensor
            state: 'off'
        sequence:
          - service: rest_command.bravia_on
            data: {}
    default: []
  - service: switch.turn_off
    data: {}
    target:
      entity_id: switch.kitchen_tv_switch_by_sensor
  - delay:
      hours: 0
      minutes: 0
      seconds: 6
      milliseconds: 0
  - choose:
      - conditions:
          - type: is_power
            condition: device
            device_id: スマートプラグのID
            entity_id: sensor.sengled_e1c_nb7_bravia_power
            domain: sensor
            above: 21
          - condition: state
            entity_id: switch.kitchen_tv
            state: 'off'
        sequence:
          - service: switch.turn_on
            data: {}
            target:
              entity_id: switch.kitchen_tv_switch_by_sensor
          - service: switch.turn_on
            data: {}
            target:
              entity_id: switch.kitchen_tv
      - conditions:
          - type: is_power
            condition: device
            device_id: スマートプラグのID
            entity_id: sensor.sengled_e1c_nb7_bravia_power
            domain: sensor
            below: 20
          - condition: state
            entity_id: switch.kitchen_tv
            state: 'on'
        sequence:
          - service: switch.turn_on
            data: {}
            target:
              entity_id: switch.kitchen_tv_switch_by_sensor
          - service: switch.turn_off
            data: {}
            target:
              entity_id: switch.kitchen_tv
    default: []
mode: restart



【Switchがオフになった時に実行するスクリプト

alias: Bravia_off
sequence:
  - service: script.turn_off
    data: {}
    target:
      entity_id: script.bravia_on
  - choose:
      - conditions:
          - condition: state
            entity_id: switch.kitchen_tv_switch_by_sensor
            state: 'off'
        sequence:
          - service: rest_command.bravia_off
            data: {}
    default: []
  - service: switch.turn_off
    data: {}
    target:
      entity_id: switch.kitchen_tv_switch_by_sensor
  - delay:
      hours: 0
      minutes: 0
      seconds: 6
      milliseconds: 0
  - choose:
      - conditions:
          - type: is_power
            condition: device
            device_id: スマートプラグのID
            entity_id: sensor.sengled_e1c_nb7_bravia_power
            domain: sensor
            above: 21
          - condition: state
            entity_id: switch.kitchen_tv
            state: 'off'
        sequence:
          - service: switch.turn_on
            data: {}
            target:
              entity_id: switch.kitchen_tv_switch_by_sensor
          - service: switch.turn_on
            data: {}
            target:
              entity_id: switch.kitchen_tv
      - conditions:
          - type: is_power
            condition: device
            device_id: スマートプラグのID
            entity_id: sensor.sengled_e1c_nb7_bravia_power
            domain: sensor
            below: 20
          - condition: state
            entity_id: switch.kitchen_tv
            state: 'on'
        sequence:
          - service: switch.turn_on
            data: {}
            target:
              entity_id: switch.kitchen_tv_switch_by_sensor
          - service: switch.turn_off
            data: {}
            target:
              entity_id: switch.kitchen_tv
    default: []
mode: restart


4.家のコントロールパネルの設定

最後に家のコントロールパネルの設定です。
今まではテレビの電源はオンとオフを別々のボタンにしていましたが、Switchのトグルボタンに変更しました。
テレビがオフの時はアイコンが黒色で、オンになると赤色に変化します。
このボタンで操作した時はアイコンの色はすぐに変化するので違和感なく操作することが出来、もし、操作したとおりにテレビの電源がオンオフされていなかった場合は6秒後に実際の状態が反映されます。


■まとめ

そんなワケで今回は、消費電力モニター機能付きスマートプラグを使ってテレビの電源状態をHome Assistantと同期させてみました。
まぁ同期したというだけなので言わなきゃ家族も気づかないだろうし完全に自己満足ですけどね(笑)
それにしてもtemplateを使えるようになれば、今回みたいなグチャグチャな処理はしなくていいんだろうなと思いました(汗
今度は照度センサーを使ってHome Assistantとシーリング照明の電源状態を同期させたいと思っていますが、今回のテレビの同期をブラッシュアップしてからかな。。。
エアコンの同期もやりたいんですが、エアコンは電源じゃなくて運転モードとか設定温度を同期しないと意味ないか。。。これは無理そう(>


それでは。