ESP Homeのディスプレイレンダリングエンジンについて
概要
ESPHomeを使用してHome Assistant用スマートホーム端末(ノード)を作る際に、ESPHomeの機能をチェックした時のノート。
ESP HomeでLCDに表示を行う場合、ディスプレイコンポーネントを使用する。
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のフォントレンダラーと組み合わせて使用する。
フォント定義
まずはフォントレンダラーを使用して使用するフォントを定義する。
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など指定することが出来る。
Home Assistantの時間情報を使用する例:
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());
フォーマットには以下のページの文字列を指定できる。
グラフィック描画
image関数を使用することで、グラフィックイメージを描画することが出来る。
it.image(4, 52, id(weather_partly_cloudy), ImageAlign::TOP_LEFT);
Imagesコンポーネント
表示するイメージデータはImagesコンポーネントを使用して定義する。
イメージ定義例:
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コンポーネントで定義する。
graph定義例:
graph:
- id: single_temperature_graph
sensor: living_node_living_room_temperature
duration: 60sec
width: 120
height: 60
sensor: 使用するデータを指定する。上記は温度センサーを指定。
duration: 表示間隔を指定。
width: 表示する幅を指定。
height: 表示する高さを指定。
Discussion