📊

ESP Homeのディスプレイレンダリングエンジンについて

に公開

概要

ESPHomeを使用してHome Assistant用スマートホーム端末(ノード)を作る際に、ESPHomeの機能をチェックした時のノート。

https://zenn.dev/kojiro/articles/7586de585166de

ESP HomeでLCDに表示を行う場合、ディスプレイコンポーネントを使用する。

https://esphome.io/components/display/index.html

LCDに表示を行う仕組みとして2種類の手段が提供されている。

  • Display Rendering Engine
    ESP Home内蔵のレンダリングエンジン。基本的な形状やテキスト、イメージの描画が出来る。ESP Homeのlambda systemを使ってC++でAPIを呼び出してプログラムを記述する。
    https://esphome.io/components/display/index.html#display-rendering-engine
  • LVGL(Light and versatile graphics library)
    様々なUI部品やタッチ操作などに対応したオープンソースソフト。ESP HomeにはVersion8が組み込まれている。
    https://esphome.io/components/lvgl/

Display Rendering Engine

ESP Home内蔵のディスプレイレンダリングエンジンの使用方法。

  • YAMLのdisplay内のlambdaに描画命令を記載する。
  • ディスプレイ描画時にlambdaが呼び出され、呼び出される際はディスプレイが自動的にクリアされる。
  • lambdaにはitオブジェクトが渡され、itオブジェクトを使って描画する。
  • 座標は左上が0,0となる。

YAMLの例
Home Assistantと接続して日時や天気予報、室温のグラフを表示するサンプル。

spi:
  clk_pin: GPIO26
  mosi_pin: GPIO27

font:
  - file: "gfonts://Noto+Sans+JP"
    id: medium_font
    bpp: 4
    size: 14
  - file: "gfonts://Noto+Sans+JP"
    id: large_font
    bpp: 4
    size: 28

image:
  - file: mdi:weather-partly-cloudy
    id: weather_partly_cloudy
    type: grayscale
    transparency: alpha_channel
    resize: 40x40

graph:
  - id: single_temperature_graph
    sensor: living_node_living_room_temperature
    duration: 60sec
    width: 120
    height: 60

time:
  - platform: homeassistant
    id: hatime

display:
  - platform: ili9xxx
    model: ST7735
    dc_pin: GPIO14
    reset_pin: GPIO12
    cs_pin: GPIO13
    invert_colors: false
    rotation: 0
    lambda: |-
      it.strftime(4, 0, id(medium_font), TextAlign::TOP_LEFT, "%a %B %d, %Y", id(hatime).now());
      it.strftime(4, 15, id(large_font), TextAlign::TOP_LEFT, "%I:%M %p", id(hatime).now());
      it.image(4, 52, id(weather_partly_cloudy), ImageAlign::TOP_LEFT);
      it.printf(50, 52, id(medium_font), TextAlign::TOP_LEFT, "26°C");
      it.printf(50, 70, id(medium_font), TextAlign::TOP_LEFT, "32°C/16°C");
      it.graph(4, 90, id(single_temperature_graph));

テキスト描画

テキスト描画はESP Homeのフォントレンダラーと組み合わせて使用する。

フォント定義

まずはフォントレンダラーを使用して使用するフォントを定義する。

https://esphome.io/components/font

ESP HomeはESP32の限られたリソースで動作するために、搭載するフォントを最小限に制限する。
フォントファイルはローカルファイル、Google Fonts、Webサーバからロードすることが出来、Google FontsやWebサーバのフォントはコンパイル時にダウンロードし、キャッシュする。

使用例

font:
  - file: "gfonts://Noto+Sans+JP"
    id: medium_font
    bpp: 4
    size: 14
  - file: "gfonts://Noto+Sans+JP"
    id: large_font
    bpp: 4
    size: 28
  • ミディアムサイズとラージサイズの2種類のフォントを定義
  • Google FontsからNoto Sans Japaneseをダウンロードして使用
  • bppはアンチエイリアシング処理の深さの指定。デフォルトは1で、1の場合はアンチエイリアシングをかけずにフォントにビットマップがあればビットマップを使用する。それ以外はベクターデータから滑らかなフォントイメージを描画
  • sizeはフォントの高さ(pixel)を指定する。サイズが異なるフォントを定義する場合は、フォントサイズ毎にフォントオブジェクトが生成される。ビットマップフォントはサイズ指定出来ずにエラーとなる。

printfによる描画

printf関数では、以下の5種類のパラメータ指定に対応している。

printf (int x, int y, BaseFont *font, Color color, Color background, TextAlign align, const char *format,...)
printf (int x, int y, BaseFont *font, Color color, TextAlign align, const char *format,...)
printf (int x, int y, BaseFont *font, Color color, const char *format,...)
printf (int x, int y, BaseFont *font, TextAlign align, const char *format,...)
printf (int x, int y, BaseFont *font, const char *format,...) 

x: X座標
y: Y座標
font: フォントID
Color: 色指定
TextAlign: テキストのアライメント指定
*format: フォーマット指定可能な文字列

上記で定義したミディアムサイズのフォントで左寄せにテキストを表示する例。

it.printf(50, 52, id(medium_font), TextAlign::TOP_LEFT, "26°C");

strftimeによる日時描画

strftime関数を使用すると、フォーマットで指定した形式で日時や時刻などを以下のパラメータ指定で描画することが出来る。

strftime (int x, int y, BaseFont *font, Color color, Color background, TextAlign align, const char *format, ESPTime time)
strftime (int x, int y, BaseFont *font, Color color, TextAlign align, const char *format, ESPTime time)
strftime (int x, int y, BaseFont *font, Color color, const char *format, ESPTime time)
strftime (int x, int y, BaseFont *font, TextAlign align, const char *format, ESPTime time)
strftime (int x, int y, BaseFont *font, const char *format, ESPTime time)

strftime関数には実際の時間データが入ったESPTimeオブジェクトを渡す必要があるので、別途timeコンポーネントで定義する。時間データにはHome AssistantやSNTP、RTCなど指定することが出来る。

https://esphome.io/components/time/

Home Assistantの時間情報を使用する例:
https://esphome.io/components/time/homeassistant

time:
  - platform: homeassistant
    id: hatime

日時と時刻を表示する例:

it.strftime(4, 0, id(medium_font), TextAlign::TOP_LEFT, "%a %B %d, %Y", id(hatime).now());
it.strftime(4, 15, id(large_font), TextAlign::TOP_LEFT, "%I:%M %p", id(hatime).now());

フォーマットには以下のページの文字列を指定できる。
https://esphome.io/components/time/#strftime

グラフィック描画

image関数を使用することで、グラフィックイメージを描画することが出来る。

it.image(4, 52, id(weather_partly_cloudy), ImageAlign::TOP_LEFT);

Imagesコンポーネント

表示するイメージデータはImagesコンポーネントを使用して定義する。

https://esphome.io/components/image

イメージ定義例:

image:
  - file: mdi:weather-partly-cloudy
    id: weather_partly_cloudy
    type: grayscale
    transparency: alpha_channel
    resize: 40x40

file: 表示するデータを指定。ローカルファイルやMaterial Design Icons(mdi)、Webデータを指定出来る。

グラフ描画

graph関数を用いることで、簡易的なグラフ表示が行える。

it.graph(4, 90, id(single_temperature_graph));

Graphコンポーネント

表示するデータはGraphコンポーネントで定義する。
https://esphome.io/components/graph

graph定義例:

graph:
  - id: single_temperature_graph
    sensor: living_node_living_room_temperature
    duration: 60sec
    width: 120
    height: 60

sensor: 使用するデータを指定する。上記は温度センサーを指定。
duration: 表示間隔を指定。
width: 表示する幅を指定。
height: 表示する高さを指定。

Discussion