コモノポリタン

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

【Home AssistantでDIY Smart Home】おうちダッシュボード:家の状況を一覧する

【Home Assistant(Hass.io)】
FloorPlan改めpicture-elementsで家の状況を一覧表示する

「Home Assistant(Hass.io)でホームオートメーション 再起動!」シリーズです。

 そもそもHome Automationを導入した時から、ダッシュボードというのかコンソールというのか、家の状況を一覧する仕組みを作りたいと思っていました。窓やドアの開閉状況まで取れるようになったので、そろそろ気合を入れて仕組み導入したいと思います。

 私が導入した当時はFloor Planという名前の仕組みがあって(今もあるのかな)それを使えるようにチョビチョビ準備をしていました。lovelace UIより前の時代の話です。lovelace UIが出てきて一新されて、気が付けば「picture-elementsカード」という仕組みがFloor Planを実現する今の方法になったらしいです。よし、picture-elementsカードで「おうちダッシュボード」を作りましょう!

この記事の前提条件
Home Assistant 2021.3.2
HassOS 5.12
Server Raspberry Pi 4(2GB)

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

1. 「おうちダッシュボード」って何?

 家の平面図上に様々なセンサーの状態やスイッチなどを表示して、UIで把握・制御できるようにするものをイメージしています。Google"Home Assistant" floorplanをキーワードに画像を検索すると素敵なおうちダッシュボードが沢山見つかります*1
 今回設定した私の家のダッシュボードはまだまだ途上ではありますが、一部分ですがこんな感じです。とりあえず部屋ごと室温と電灯のオン・オフ、窓の開閉とロックの状況を表示しています。


2. 下準備

2.1. wwwフォルダの準備

 画像ファイルとかを表示するためには、Home Assistantサーバ上にwwwフォルダが必要です。以前、RFIDタグを使うときにすでに作りましたが、まだならfile editorなどでconfigフォルダの下にwwwというフォルダを作成して再起動すれば大丈夫です。

2.2. floorplan用フォルダ、iconフォルダの作成

 今回はwwwフォルダの下に、floorplan用のフォルダをいくつか掘りました。

フォルダ URL 用途
config\www\floorplan [base URL]/local/floorplan/ 間取り図
config\www\floorplan\icons [base URL]/local/floorplan/icons/ アイコン
config\www\floorplan\windows [base URL]/local/floorplan/windows/ 窓部品
config\www\floorplan\doors [base URL]/local/floorplan/doors/ ドア部品
config\www\floorplan\misc [base URL]/local/floorplan/misc/ その他部品
(今回未使用)

3. 間取り図を描く

3.1. ツール(Inkscape

 間取り図がなければ始まりません。lovelace UIのpicture-elementでは画像(.jpeg, .pngなど)であれば扱えそうなので、どんなツールを使っても描いてもかまいません。(1) 私は家の図面を下書きにして書きたい、(2)以前トライしていたFloorPlanがベクター画像の.svg形式しか受けつけなかった、という理由でフリーのsvgイメージエディタのInkscapeを使っています。
inkscape.org

 Inkscapeの画面はこんな感じです。とりあえず使いそうなツールは「レイヤー」と「PNGエクスポート」でしょうか。

3.2. 下書きをもとに描く

 Inkscapeではレイヤーを分けて重ねて表示したりできるので、部屋の図面をスキャナで取り込んで下書きとして使うことができます。まずは最初のレイヤーに[ファイル]-[インポート]で画像を選択して図面を読みます。
 レイヤー・ダイアログで「+」で見取り図を描くレイヤーを追加します。名前は適宜変えましょう。見取り図レイヤーが選択されていることを確認して(これを忘れると図面に書いちゃいます、ま、修正効きますが)、左でペンツールを選択してちみちみ線をなぞって壁、窓、ドアを描いていってください。注意点は壁は壁、窓は窓で別の矩形にすることです。

壁は塗りつぶしたり窓は水色にしたりと好みで仕上げます。スキャン図面のレイヤをオフにすると右のような感じになります。

3.3. 窓やドアを別レイヤーに

 窓やドアは、センサーの状態(state)にしたがって異なるイメージで表示したいので、別のレイヤに分離しておきます。左が背景に使う枠だけの図。右側は窓などが閉まっている図。この図を基に空いている窓の図を起こします。

3.4. 開いてる窓、ドアを描く

 最後に開いている状態の窓を描きます。左の図(閉じている窓の図)の窓の一部を動かして開いている感を出します。ただし窓のサイズが変わるとのちのち困るので、開いた方の窓は、点線で元の位置にコピーを残しておくと良いでしょう(右の図)。

 とりあえず下準備は終了かな。

(2024/03/03追記)
ドアや窓の開閉のイメージは縦横がそろっている(位置も含め)と扱いやすいと上や別の記事で書きました。で、そういうイメージの作り方を下記の記事に追記しましたので参考に。(もっぱら自分の備忘録ですが…)
maky-ba.hatenablog.com

4. picture-elementsの設定

4.1. ビューとカードの設定

 まずはビューを作ってパネルモードをオンにします。こうするとこのビューではpicture-elementsカード「だけ」が表示されるようになります。

 次にpicture-elementsカード(「ピクチャーエレメント」カード)を追加します。ほにゃらら.yamlファイルを直に編集することは少なくなりました。が、picture-elementsは自由度が高いのでlovelace UIのCard編集画面でも「ビジュアルエディタは使えないよん」と言われます。

4.2. picture-elementsの基本設定

 まずは描いた間取り図の枠部分を例えば「FloorPlan_1F_Background.png」という名前でPNGエクスポートして、floorplanフォルダに入れておきます。picture-elementsのエディタ画面でまずは下記のように始めます。.pngの後ろの「?v=0.50」はちょっとした小技用。本来はバージョンを示すのですが、ちょっと手を入れた「FloorPlan_1F_Background.png」ファイルを同じ名で置き換えたりすると読込んでくれない時があります。そんな時は、バージョンをちょびっと上げて「?v=0.51」なんかにすると読み直してくれます。本当に小技ですね。

type: picture-elements
image: /local/floorplan/FloorPlan_1F_Background.png?v=0.50
dark_mode_filter: invert(100%)
elements:
(この後ろに設定を記述してゆきます)

この背景画像の上に、次から紹介する'type: xxxxxx'でいろいろな部品を載せていくイメージです。

4.3. 状態(State)を表示

 まずはセンサーの値や扉の開閉状況などの状態(State)を表示します。

(前略)
elements:
(中略)
  - type: state-label
    title: 勉強部屋室温
    entity: sensor.xiaomi_lywsdcgq_no2_temperature
    style:
      top: 20%
      left: 24%

 type: state-labelは、entity:で指定した状態をラベルで(文字列で)表示するという部品の設定です。

  • title:はラベル表示の上にマウスを持って行ったときに表示されるtipの設定です。それよりこの表示部品が何だったかをこの設定エディタで分かりやすくするために必ずつけておきましょう。
  • style:で表示スタイルをCSSで設定できます。top: left:はラベルの表示位置を左上からの%位置で指定します。とりあえず設定してみて、表示させながら微調整します。元のファイルをSVGイメージエディタで表示して座標から%座標に変換しても良いのですが、まあ見ながら調整でも十分できると思います。

4.4. 状態をアイコンで表示

 次は状態に応じたアイコンが表示できて、クリック(タップ)して操作もできる部品を設定します。

(前略)
elements:
(中略)
  - type: state-icon
    title: 勉強部屋シーリングライト
    tap_action:
      action: toggle
    entity: light.ceilinglight_studyroom
    style:
      top: 67%
      left: 31%

 type: state-iconは、entity:で指定した状態を、そのentityに設定されているアイコンで表示するものです。

  • tap_action:はクリック(タップ)したときの動作を記述します。ここではライトのオンオフを指示するためにtoggleと設定しました。
  • 他は上のstate-labelと同じ


zigbeeデバイスの活用せよ!ライトセンサー編」でlight templateエンティティとして設定したとおりのアイコンで表示されます。消えている時は右側のアイコンですね。このアイコンをクリックするとライトセンサー編で設定した通りの電灯のオンオフ動作をします。
(ちなみに、なのですが、右側の電灯は実は赤外線リモコン対象外。センサーは仕込んでいるので、点いているか消えているかの表示はできます。それしかできません。ま、消し忘れのチェックはできますね)

4.5. 状態によって画像を変える

 次は窓が開いているか閉まっているかを見た目で分かるようにしましょう。先ほどInkscapeで準備した開いている窓と閉まっている窓のファイルから、必要な部分だけを選択して、選択したものをPNGでエクスポートします。それをHome Assistantサーバのwww\windowsフォルダに格納しておきます。

(前略)
elements:
(中略)
  - type: image
    title: 窓(勉強部屋)
    entity: binary_sensor.xiaomi_mccgq11m_no1_contact
    tap_action: none
    image: /local/floorplan/windows/Window_01_1F-StudyRoom_close.png
    state_image:
      'on': /local/floorplan/windows/Window_01_1F-StudyRoom_open.png
    style:
      top: 83%
      left: 31%
      width: 32%

 type: imageは、画像ファイルを表示する部品です。

  • image:は表示したいイメージファイルをwwwからのURLで指定
  • state_image:は条件で表示するファイルを変えたいときに指定
  • style:の中にwidth:があります。窓枠(壁の隙間)にぴったりはまるように幅を相対(%)で指定します。これをしておかないとpicture-elementsカードの表示を拡大・縮小した時に窓はみ出たりします。

state_image:にon/off両方記述すれば良いじゃないか」という声が聞こえてきますが、まあ、それでも動きます。というかそれが正しい使い方ですね。
 たまたま上記の様に記述すると、closeの時の画像が強制的にグレー(不活性)に変更されてちょうど良いかなと思って、こうしています。
 相変わらず状態とstateの対応関係は手探りです。"contact"センサーなので、窓が閉まる=マグネットが接触=onのような気がしますが、「zigbeeデバイスの活用せよ:鍵編(Door&Windowセンサー改造)」でみたように、接触でリードスイッチが切れる(off)なので、窓が閉まっている状態がoffなのです。ううむ。

4.5b. 状態によって画像を変える(その2)

 画像を切り出して、適切な位置に配置(style: top:, style: left:)して、適切な大きさ(style: width:)に調整して、ううむなんて面倒くさい。「3.4.」や「3.5.」あたりで壁にぴったりするように窓を描いたのだから、それを使えないかと思って色々トライしてみました。一応出来たので紹介。
 まずはInkscapeで新しい窓用のレイヤーを開用と閉用の2つ作ります。その時、既存の窓が沢山設定してあるレイヤーを「レイヤーの複製」して作ることがポイントです。開いた窓群のレイヤーを複製して開き窓用レイヤーを作り、閉じた窓群のレイヤを複製して閉じ窓用のレイヤーを作ります。それぞれのレイヤーから必要な窓以外はどんどん削除していきます。必要な窓だけを表示して、「ページ」でPNGエクスポートします。(ここでは、Window_01_1F-StudyRoom_Full_close.png、Window_01_1F-StudyRoom_Full_open.pngという名前でエクスポートすることを想定)

(前略)
elements:
  - type: image
    title: 窓(勉強部屋)
    entity: binary_sensor.xiaomi_mccgq11m_no1_contact
    tap_action: none
    image: /local/floorplan/windows/Window_01_1F-StudyRoom_Full_close.png
    state_image:
      'on': /local/floorplan/windows/Window_01_1F-StudyRoom_Full_open.png
    style:
      top: 50%
      left: 50%
      width: 100%

 ポイントは2つあります。
 ポイントその1は、elementsの冒頭に記述すること。後ろの方に記述するとは、画面いっぱいの(窓以外は透明でみえませんが)画像が立ちはだかってライトとかクリックできなくなります。
 ポイントその2は、背景と位置を一致させるために、位置はtop: 50%, left: 50%として、大きさはwidth: 100%とすることです。picture-elementsのCSS基本設定は、部品の中心座標をtop:, left:で指定するの形になっているので、これでぴったり合うようになります。

4.6. 状態によってアイコンを変える

 窓の鍵が閉まっている時と開いている時で、表示するアイコンを変えたいのですが、ここで問題発生。type: imageにはstate_image:があり状態(State)によって画像が切り替えられました。じゃtype: iconで同じようなことが出来るか、というそんな機能はなく、単にicon:でアイコン(mdi:xxxxxなど)が設定できるだけなのですが。
 そこでちょっと力技ですが、アイコンをダウンロードしておいて、それを「画像」として取り扱うことで疑似的にアイコンの切り替えを実現することに。

(前略)
elements:
(中略)
  - type: image
    title: 窓ロック(勉強部屋)
    entity: binary_sensor.xiaomi_mccgq11m_no2_contact
    tap_action: none
    state_image:
      'off': /local/floorplan/icons/icon_lock.png
    style:
      top: 81.5%
      left: 31%

 ということで、ほとんど上の「4.5. 状態によって画像を変える」と同じ話に。material design iconsからアイコンをダウンロードして、www\iconsフォルダに格納しておく、ぐらいでしょうか。この記述の様に、image:の記述をなくして、state_image:でもonの記述をなくすと、オンの時はアイコンが表示されなくなります。

5. おわりに

 あとは力仕事ですね。部屋の図や、窓やらドアやらの図を描きまくるだけですね。頑張ろう!

【おまけ】picture-elementsを使った方法では、最近の流行は「3D」らしいです。

 3Dモデルを作るのに使うツールはこの辺り(Sweet Home 3D)らしいです。
 面白そうだなぁ、とは思いますが、画面がガチャガチャするので私はしばらくは2次元かな…。

maky-ba.hatenablog.com

*1:英語の検索キーワードにしたfloorplanですが、そもそもfloorplanとは何でしょうか?floorplanは英語で「間取り図」のこと。検索結果を見ると、欧米の方の家は部屋数が多いですねぇ。ガレージもでかいし。