HomeAssistantのバージョンアップ

寝室の照明を消そうとHome AssistantのAndroidアプリを立ち上げても、ウントもスントも言わなくなりました。
試しにブラウザからアクセスしても、上記のとおり・・・。
Home Assistantが起動していないのかしら? と思いps -ef | grep homeaを実行すると、やはり起動しておらず。
Home Assitantを起動してみるも、そもそもpythonが見つからない模様。
pythonのアップデートによって、シンボリックリンクが切れたようです。
今までのpythonは3.9

gentoo /home/homeassistant/bin $ ls -al
合計 208
drwxr-xr-x 3 homeassistant homeassistant 4096  91  2021 .
drwxr-xr-x 8 homeassistant homeassistant 4096 1111 03:58 ..
(中略)
lrwxrwxrwx 1 homeassistant homeassistant    7 124  2017 python -> python3
lrwxrwxrwx 1 homeassistant homeassistant   38  91  2021 python3 -> /usr/lib/python-exec/python3.9/python3
lrwxrwxrwx 1 homeassistant homeassistant    7  91  2021 python3.9 -> python3

pythonのアップデートは、昔の記事に書いてました。

gentoolinux.hatenablog.com

シンボリックリンクが置き換えられました。

gentoo /home/homeassistant/bin $ ls -al
合計 209
drwxr-xr-x 3 homeassistant homeassistant 4096  91  2021 .
drwxr-xr-x 8 homeassistant homeassistant 4096 1111 03:58 ..
(中略)
lrwxrwxrwx 1 homeassistant homeassistant    7 124  2017 python -> python3
lrwxrwxrwx 1 homeassistant homeassistant   39 129 11:22 python3 -> /usr/lib/python-exec/python3.11/python3
lrwxrwxrwx 1 homeassistant homeassistant    7 129 11:22 python3.11 -> python3
lrwxrwxrwx 1 homeassistant homeassistant    7  91  2021 python3.9 -> python3

これでめでたくHome Assistantを起動できる!!
と思ったものの、やはりウントもスントも言わない。
これはHome Assistantそのものをバージョンアップするしかない。と思ったら、いろいろハマりました。

gentoo /home/homeassistant/.homeassistant # sudo -u homeassistant -H /home/homeassistant/bin/hass
2023-12-09 12:10:12.817 ERROR (MainThread) [homeassistant.components.switch] Error while setting up command_line platform for switch
Traceback (most recent call last):
  File "/home/homeassistant/lib/python3.11/site-packages/homeassistant/helpers/entity_platform.py", line 361, in _async_setup_platform
    await asyncio.shield(task)
  File "/home/homeassistant/lib/python3.11/site-packages/homeassistant/components/command_line/switch.py", line 42, in async_setup_platform
    entities: dict[str, Any] = {slugify(discovery_info[CONF_NAME]): discovery_info}
                                        ~~~~~~~~~~~~~~^^^^^^^^^^^
TypeError: 'NoneType' object is not subscriptable

どうやらコンフィグが古くて動かない模様。
しかし、いつかやらなければならないコンフィグの改修。重い腰を上げました。

まず、拙宅のリビング照明はRaspberry Pi Zero WにWebIOPiをインストールし、GPIOにリレーを3つ繋いでおります。
gentoolinux.hatenablog.com
gentoolinux.hatenablog.com

それと、寝室にESP-Easy化したSONOFFを導入しています。
gentoolinux.hatenablog.com

これらは、最初にswitch:というインテグレーターセクションの中に、platform:command_lineと定義して記載していました。
gentoolinux.hatenablog.com

curlコマンドを使い、WebIOPiやESP-EasyのWebを叩きに行く、ということです。
value_template: で、スイッチがオンの時の値を定義します。

しかし、2023.12.1バージョンでは、エンティティ毎に定義するようで、まず先頭にswitchではないようです。
おそらく様々なswitchを定義できるようにしたのでしょう。
新旧で見ていきます。

switch:
  - platform: command_line
    switches:
      snowball:
       command_on: "/usr/bin/curl -X POST http://192.168.0.xxx:8000/GPIO/26/value/0"
       command_off: "/usr/bin/curl -X POST http://192.168.0.xxx:8000/GPIO/26/value/1"
       command_state: "/usr/bin/curl -X GET http://192.168.0.xxx:8000/GPIO/26/value"
       value_template: '{{ value == "0" }}'
       friendly_name: Living SnowBall
      ph5:
       command_on: "/usr/bin/curl -X POST http://192.168.0.xxx:8000/GPIO/6/value/0"
       command_off: "/usr/bin/curl -X POST http://192.168.0.xxx:8000/GPIO/6/value/1"
       command_state: "/usr/bin/curl -X GET http://192.168.0.xxx:8000/GPIO/6/value"
       value_template: '{{ value == "0" }}'
       friendly_name: Living PH5 Plus
      spot:
       command_on: "/usr/bin/curl -X POST http://192.168.0.xxx:8000/GPIO/19/value/0"
       command_off: "/usr/bin/curl -X POST http://192.168.0.xxx:8000/GPIO/19/value/1"
       command_state: "/usr/bin/curl -X GET http://192.168.0.xxx:8000/GPIO/19/value"
       value_template: '{{ value == "0" }}'
       friendly_name: Living Spot and Bracket
      bedroom:
       command_on: "/usr/bin/curl -X GET http://192.168.0.yyy/control?cmd=event,PowerOn"
       command_off: "/usr/bin/curl -X GET http://192.168.0.yyy/control?cmd=event,PowerOff"
       command_state: "/usr/bin/curl -X GET http://192.168.0.yyy/control?cmd=status,gpio,12"
       value_template: '{{ value_json.state == 1 }}'
       friendly_name: Bedroom Light

旧書式ではswitch:の下に、platformでどういったプロトコルで処理するかを定義し、switches:で複数のスイッチを定義しました。
switches:の下には、任意にエンティティ名を付与しましたが、これは特にHome Assistantで使われることもなく、friendly_nameでが使われました。
そして、switch:インテグレーションが廃止され、command_line:が先頭に来ることになりました。
さらに、switches:も廃止。
friendly_name: もname:に変わりました。
そうしてできた新書式がコチラ

command_line:
    - switch:
       command_on: "/usr/bin/curl -X POST  http://192.168.0.xxx:8000/GPIO/26/value/0"
       command_off: "/usr/bin/curl -X POST  http://192.168.0.xxx:8000/GPIO/26/value/1"
       command_state: "/usr/bin/curl -X GET  http://192.168.0.xxx:8000/GPIO/26/value"
       value_template: '{{ value == "0" }}'
       name: Living SnowBall

    - switch:
       command_on: "/usr/bin/curl -X POST  http://192.168.0.xxx:8000/GPIO/6/value/0"
       command_off: "/usr/bin/curl -X POST  http://192.168.0.xxx:8000/GPIO/6/value/1"
       command_state: "/usr/bin/curl -X GET  http://192.168.0.xxx:8000/GPIO/6/value"
       value_template: '{{ value == "0" }}'
       name: Living PH5 Plus

    - switch:
       command_on: "/usr/bin/curl -X POST  http://192.168.0.xxx:8000/GPIO/19/value/0"
       command_off: "/usr/bin/curl -X POST  http://192.168.0.xxx:8000/GPIO/19/value/1"
       command_state: "/usr/bin/curl -X GET  http://192.168.0.xxx:8000/GPIO/19/value"
       value_template: '{{ value == "0" }}'
       name: Living Spot and Bracket

    - switch:
       command_on: "/usr/bin/curl -X GET http://192.168.0.yyy/control?cmd=event,PowerOn"
       command_off: "/usr/bin/curl -X GET http://192.168.0.yyy/control?cmd=event,PowerOff"
       command_state: "/usr/bin/curl -X GET http://192.168.0.yyy/control?cmd=status,gpio,12"
       value_template: '{{ value_json.state == 1 }}'
       name: Bedroom Light

 これでめでたく各々の照明をコントロールできるようになります。
 エンティティ名が変更になったようで、ダッシュボードにエンティティを再登録する必要があります。

 続いて、センサーです。
 ESP-Easyに温湿度センサーを繋ぎ、jsonで値を返しています。
gentoolinux.hatenablog.com


 書式は間違ってなさそうですが、コネクションタイムアウトします。

2023-12-09 16:08:51.036 WARNING (MainThread) [homeassistant.components.sensor] Platform rest not ready yet: All connection attempts failed; Retrying in background in 30 seconds
2023-12-09 16:09:21.052 ERROR (MainThread) [homeassistant.components.rest.data] Error fetching data: http://192.168.0.zzz/json?tasknr=1 failed with All connection attempts failed

 ブラウザから見るとちゃんとjsonを返します。
 そこで考えられるのが、Home Assistantが同一URLを2つ同時にリクエストし、ESP-Easyが処理落ちしているのではないかということ。
 旧書式はこうでした。

sensor:
  - platform: rest
    resource: http://192.168.0.zzz/json?tasknr=1
    name: Living Temp
    value_template: "{{value_json.temperature}}"
    unit_of_measurement: "C"

  - platform: rest
    resource: http://192.168.0.zzz/json?tasknr=1
    name: Living Hum
    value_template: "{{value_json.humidity}}"
    unit_of_measurement: "%"

 ごくまれに、温度か湿度のどちらかだけ表示されることがあり、変だな?と、思っていたので、ここが怪しいです。
 RestAPIを使い、1つのリソースで2つ以上の値を取得するには、senser:ではなく、rest:インテグレーターで開始し、resourceを一つだけ書く、という風にすればよいようです。
 新書式はこうなります。

rest:
   resource: http://192.168.0.zzz/json?tasknr=1
   sensor:
    - name: Living Temp
      value_template: "{{value_json.temperature}}"
      device_class: temperature
      unit_of_measurement: "°C"
    - name: Living Hum
      value_template: "{{value_json.humidity}}"
      device_class: humidity
      unit_of_measurement: "%"

 だいぶスッキリしましたね。

 あと、フロントエンドで「国が設定されていない」と、設定画面に誘導されるのですが、設定画面では「設定がconfiguration.yamlに保存されているため、エディタが無効になっています。」と表示され、一切の編集や保存ができません。
 これはconfiguration.yamlの先頭にいろいろと定義を入れているからだそうです。
 どんどんコメントアウトします。

 旧書式

homeassistant:
  # Name of the location where Home Assistant is running
  name: Sample_home
  # Location required to calculate the time the sun rises and sets
  latitude: 42.0000
  longitude: 141.0000
  # Impacts weather/sunrise data (altitude above sea level in meters)
  elevation: 20
  # metric for Metric, imperial for Imperial
  unit_system: metric
  # Pick yours from here: http://en.wikipedia.org/wiki/List_of_tz_database_time_zones
  time_zone: Asia/Tokyo
  # Customization file
  customize: !include customize.yaml

 新書式

homeassistant:
  # Name of the location where Home Assistant is running
  #name: Sample_home
  # Location required to calculate the time the sun rises and sets
  #latitude: 42.0000
  #longitude: 141.0000
  # Impacts weather/sunrise data (altitude above sea level in meters)
  #elevation: 20
  # metric for Metric, imperial for Imperial
  #unit_system: metric
  # Pick yours from here: http://en.wikipedia.org/wiki/List_of_tz_database_time_zones
  #time_zone: Asia/Tokyo
  # Customization file
  #customize: !include customize.yaml

 その代わり、Home Assistantの名称なども、イチから設定しなおしになります。
 ブラウザからフロントエンドにアクセスして設定するだけなので簡単です。

 さ、これでHome Assistantをデーモンとして起動しよう!
 と、思ったら、起動しない。
 デーモンではなく、通常のプロセスとしては起動するのです。
 どうやら、--daemon や --pid-fileなどのオプションが廃止されたようです。
 拙宅ではHome AssistantをGentooで動かしています。なので、Gentooのお作法に則って/etc/local.d/homeassistant.startに起動処理を、/etc/local.d/homeassistant.stopに停止処理を記載しています。
 単なるバックグラウンド起動は&を付ければよいのですが、pid番号をファイルに記載しておかなければ、停止時にpidがわかりません。
 そこで、start-stop-daemonから起動してもらうことにしました。

 旧/etc/local.d/homeassistant.start

#!/bin/sh

sudo -u homeassistant -H /home/homeassistant/bin/hass --pid-file /home/homeassistant/hass.pid --log-file /var/log/home-assistant.log 2>&1
echo "Homeassistant Started"

 新/etc/local.d/homeassistant.start

#!/bin/sh

USER=homeassistant
DAEMON=/home/homeassistant/bin/hass
PIDFILE=/home/homeassistant/hass.pid
start-stop-daemon --start --quiet --chuid $USER --user $USER --background --pidfile $PIDFILE --make-pidfile --exec $DAEMON

echo "Homeassistant Started"

 本当は、リターンコードを判断してif文で起動失敗時にはその旨メッセージを出す必要があるのでしょうが、面倒なのでヤメます。

 これでめでたくHome Assistantで照明のスイッチをパチパチできます。

 あと、特に不便は感じてませんが、フロントエンドから各スイッチやセンサーのエンティティを編集しようとしても、読み取り専用となっており、「このエンティティ ('switch.bedroom_light') にはユニークなIDがないため、UIから設定を管理構成できません。詳しくは、ドキュメント を参照してください。」と出てきます。ユニークなIDですか・・・。