Skip to main content

TRMNL 7.5inch(OG) DIY Kit ESPHomeとの連携


Home Assistantの紹介

Home Assistantは、スマートホームデバイスを単一の統合インターフェースから制御・監視できる強力なオープンソースホームオートメーションプラットフォームです。スマートホームの中央ハブとして機能し、ルーチンの自動化、センサーの監視、より知的な生活空間の構築を可能にします。

なぜHome Assistantなのか?

  • ローカル制御: 多くのクラウドベースソリューションとは異なり、Home Assistantはネットワーク上でローカルに動作するため、データのプライバシーが保たれ、インターネット接続がなくても自動化が機能します。

  • 豊富なデバイスサポート: Home Assistantは数千種類のスマートホームデバイスやサービスと統合でき、高い汎用性と将来性を提供します。

  • 強力な自動化: 時間、デバイス状態、センサー読み取り値など、さまざまなトリガーに応答する高度な自動化ルールを作成できます。

  • カスタマイズ可能なダッシュボード: 最も重要な情報を表示する独自のユーザーインターフェースを設計できます。

なぜTRMNL 7.5inch(OG) DIY KitとHome Assistantなのか?

TRMNL 7.5inch(OG) DIY KitがHome Assistantの優れたコンパニオンである理由はいくつかあります:

  1. 省エネルギー: e-paperディスプレイはコンテンツ更新時のみ電力を消費するため、天気予報、カレンダーイベント、システム状態などの持続的な情報表示に最適です。

  2. 優れた視認性: LCDスクリーンとは異なり、e-paperディスプレイは直射日光を含むあらゆる照明条件で読みやすく、壁掛けホームコントロールパネルに理想的です。

  3. 長いバッテリー寿命: ディープスリープモードと組み合わせることで、一目で価値ある情報を提供しながら、単一のバッテリー充電で数ヶ月間動作できます。

  4. 柔軟な統合: ESPHomeを通じて、ディスプレイはHome Assistantとシームレスに統合され、スマートホームシステムからのあらゆるデータをエレガントで常時表示可能な形式で表示できます。

これらの利点により、TRMNL 7.5inch(OG) DIY KitはHome Assistantセットアップ用の省エネルギーで常時オンの情報ディスプレイを作成するのに理想的な選択肢となります。

ESPHome統合

ESPHomeは、ESP8266/ESP32デバイス専用に設計されたオープンソースファームウェア作成ツールです。シンプルなYAML設定ファイルを使用してカスタムファームウェアを作成し、デバイスにフラッシュできます。TRMNL 7.5inch(OG) DIY Kitにとって、ESPHomeはデバイスとHome Assistant間の通信を可能にする重要なミドルウェアとして機能します。

このシステムは、YAML設定をESPデバイス上で動作する完全機能のファームウェアに変換することで動作します。このファームウェアは、ネットワークへの接続、Home Assistantとの通信、ePaperディスプレイの制御といった複雑なタスクをすべて処理します。Home Assistantと組み合わせることで、ESPHomeは高度なホームオートメーションディスプレイとコントロールを作成するための堅牢なプラットフォームを提供します。

セットアップ方法とこの多用途ディスプレイを最大限に活用する方法を探ってみましょう。

はじめに

この記事のチュートリアル内容を始める前に、以下のハードウェアを準備する必要があります。

必要な材料

TRMNL 7.5inch(OG) DIY KitHome Assistant Green

Home Assistant Greenは、ホームオートメーションを実現する最も簡単でプライバシーに配慮した方法です。簡単なセットアップを提供し、すべてのスマートデバイスを単一のシステムで制御でき、すべてのデータはデフォルトでローカルに保存されます。このボードは活発なHome Assistantエコシステムの恩恵を受け、オープンソースにより毎月改善されています。

このチュートリアルでは、Home Assistant GreenをHome Assistantホストとして使用することをお勧めしますが、Supervisorを備えた任意のHome Assistantホストを使用することもできます。

Home Assistantのインストール

Seeed Studio製品の一部にHome Assistantをインストールする方法も書いていますので、参考にしてください。

Seeed Studio製品を使用していない場合は、Home Assistant公式ウェブサイトで他の製品にHome Assistantをインストールする方法を確認して学習することもできます。

機器の設置

ステップ1. ディスプレイをドライバーボードに接続
FPCケーブルをXIAO ePaper Display Boardのコネクタに合わせ、ラッチを固定して確実な接続を確保します。

tip

FPCケーブルの金属面は上向きにする必要があります。そうでないと、コンテンツが表示されません。

以下のインストールチュートリアルに従ってください。多くの人が間違えます。

ステップ2. バッテリーの取り付け
バッテリーケーブルをドライバーボードのJSTコネクタに接続し、正しい極性(赤線を+、黒線を-)を確認します。

ステップ3. エンクロージャーの組み立て(オプション)

tip

スクリーンのフレキシブルケーブルは非常に壊れやすいことに注意してください。操作時は注意してください。損傷すると、スクリーン全体が動作しなくなります。

リソース部分からオープンソースエンクロージャー部品を印刷し、内部にコンポーネントを組み立てます。

まず、ドライバーボードとバッテリーを組み立てます。

TRMNLキットが正常に動作するかテストします。

スクリーンをケースに差し込み、FPCを外に出します。

FPC延長ケーブルを接続し、ケース全体を組み立てます。

L字型エンクロージャーも非常に似ています。

tip

TRMNLキットがルーターから遠い場合は、アンテナをケースの外に移動できます。より良いパフォーマンスが得られます。

ステップ1. ESPHomeのインストール

すでにESPHomeをインストールしている場合は、このステップをスキップできます。

Settings -> Add-ons -> ADD-ON STOREに移動します

ESPHomeを検索してクリックします。INSTALLSTARTをクリックします。

tip

アドオンストアでESPHomeが見つからない場合は、アドオンをサポートするHome Assistantインストール(Home Assistant OSまたは監視付きインストールなど)を使用していることを確認してください。他のインストールタイプ(Home Assistant Containerなど)の場合、DockerでESPHome Device Builderを独立して実行する必要がある場合があります。詳細については、公式ESPHomeドキュメントを参照してください。

その後、ESPHome Builderがサイドバーに表示されます。

ステップ2. 新しいデバイスを追加

ESPHomeに移動し、NEW DEVICEをクリックします。

デバイスに好きな名前を付け、チップタイプにESP32-S3を選択し、SKIPをクリックします。

新しいデバイスを作成した後、EDITをクリックします。

デフォルトで生成されたコード内で、esp32のフレームワークがesp-idfになっている場合がありますが、これをarduinoに変更する必要があります。

ステップ3. ファームウェアのインストール

これは非常に基本的な例で、ディスプレイに「Hello World!」を表示します。

主な目的は、デバイスにファームウェアをインストールするさまざまな方法を示すことです。

以下のコードをコピーして、下図のようにcaptive_portalの後に貼り付けることができます。

# define font to display words
font:
- file: "gfonts://Inter@700"
id: font1
size: 24

# define SPI interface
spi:
clk_pin: GPIO7
mosi_pin: GPIO9

display:
- platform: waveshare_epaper
model: 7.50inv2
cs_pin: GPIO44
dc_pin: GPIO10
reset_pin: GPIO38
busy_pin:
number: GPIO4
inverted: true
update_interval: 30s
lambda: |-
it.print(0, 0, id(font1), "Hello World!");

INSTALLをクリックしてコードをデバイスにインストールすると、以下の画像が表示されます。

tip

Home Assistantホスト(Raspberry PI/Green/Yellowなど)が遠くにある場合は、この方法をお勧めします。手元にあるコンピューターでインストールできます。

まず、Manual downloadをクリックしてコンパイル済みファームウェアをダウンロードする必要があります。

このウェブサイトを開き、ファームウェアをePaperパネルにアップロードします。

ESPHomeに戻ってファームウェアをダウンロードします。

Factory formatを選択します。

USBケーブルを使用してePaperパネルをコンピューターに接続し、CONNECTをクリックします。

usbmodemxxx(WindowsではCOMxxx)を選択し、connectをクリックします。問題が発生しましたか?こちらをクリック。

INSTALLをクリックし、先ほどダウンロードしたファームウェアを選択します。

しばらく待つと、ディスプレイに「Hello world!」が表示されます~

基本的な使用方法

1. 図形の表示

この例では、ディスプレイに図形を表示します。

以下のコードをコピーして、下図のようにcaptive_portal部分に貼り付けることができます。

spi:
clk_pin: GPIO7
mosi_pin: GPIO9

display:
- platform: waveshare_epaper
model: 7.50inv2
cs_pin: GPIO44
dc_pin: GPIO10
reset_pin: GPIO38
busy_pin:
number: GPIO4
inverted: true
update_interval: 5min
lambda: |-
it.rectangle(10, 10, 100, 50);
it.rectangle(150, 10, 50, 50);
it.circle(250, 35, 25);

it.filled_rectangle(10, 80, 100, 50);
it.filled_rectangle(150, 80, 50, 50);
it.filled_circle(250, 105, 25);

以下の画像のようなフィードバックが表示されると、コードが正常に実行されていることを意味します。

より多くの使用方法については、こちらをクリックしてください。

2. HAの情報を表示

この例では、HAの情報をディスプレイに表示します。

まず最初に、このデバイスをHAに追加する必要があります。そうしないと、HAから情報を取得できません。

HAがデバイスを表示しない場合は、まず上記のデモを実行する必要があります。上記のデモを実行した後、HAでデバイスを確認できます。

その後、SUBMITFINISHをクリックします。

ESPHomeをインストールして新しいデバイスを追加した後、以下のコードをコピーして、下図のようにcaptive_portalの後に貼り付けることができます。

# Define font to show info
font:
- file: "gfonts://Inter@700"
id: myFont
size: 24

# Get info from HA, as string format
text_sensor:
- platform: homeassistant
entity_id: weather.forecast_home
id: myWeather
internal: true
- platform: homeassistant
entity_id: weather.forecast_home
id: myTemperature
attribute: "temperature"
internal: true

# Get info from HA, as float format
sensor:
- platform: homeassistant
entity_id: weather.forecast_home
id: myPressure
attribute: "pressure"
internal: true

# Display info via SPI
spi:
clk_pin: GPIO7
mosi_pin: GPIO9

display:
- platform: waveshare_epaper
model: 7.50inv2
cs_pin: GPIO44
dc_pin: GPIO10
reset_pin: GPIO38
busy_pin:
number: GPIO4
inverted: true
update_interval: 30s
lambda: |-
//print info in log
ESP_LOGD("epaper", "weather: %s", id(myWeather).state.c_str());
ESP_LOGD("epaper", "temperature: %s", id(myTemperature).state.c_str());
ESP_LOGD("epaper", "pressure: %.1f", id(myPressure).state);
//display info in epaper screen
it.printf(100, 100, id(myFont), "%s", id(myWeather).state.c_str());
it.printf(100, 150, id(myFont), "%s", id(myTemperature).state.c_str());
it.printf(100, 200, id(myFont), "%.1f", id(myPressure).state);

これらのコードをデバイスにインストールします。

このコードの機能は、HAから天気温度気圧を取得してディスプレイに表示することです。

tip

Home Assistantに天気関連のコンポーネントがない場合は、統合機能からOpen-Meteoという統合をダウンロードできます。

以下の画像のようなフィードバックが表示されれば、コードが正常に実行されていることを意味します。

3. アイコンの表示

この例では、ディスプレイにアイコンを表示します。

まず、File Editorアドオンをインストールする必要があります。Studio Code Serverを検索してクリックします。INSTALLをクリックしてSTARTします。

そしてfontsという新しいフォルダを作成し、このファイルをダウンロードしてfontsフォルダに入れます

以下のコードをコピーして、下図のようにcaptive_portalの後に貼り付けることができます。

font:
- file: 'fonts/materialdesignicons-webfont.ttf' #here is the directory to save ttf file
id: font_mdi_large
size: 200 # big size icon
glyphs: &mdi-weather-glyphs
- "\U000F0595" # weather cloudy
- "\U000F0592" # weather hail
- file: 'fonts/materialdesignicons-webfont.ttf'
id: font_mdi_medium # small size icon
size: 40
glyphs: *mdi-weather-glyphs

spi:
clk_pin: GPIO7
mosi_pin: GPIO9

display:
- platform: waveshare_epaper
model: 7.50inv2
cs_pin: GPIO44
dc_pin: GPIO10
reset_pin: GPIO38
busy_pin:
number: GPIO4
inverted: true
update_interval: 30s
lambda: |-
it.printf(100, 200, id(font_mdi_medium), TextAlign::CENTER, "\U000F0595");
it.printf(400, 200, id(font_mdi_large), TextAlign::CENTER, "\U000F0592");

以下の画像のようなフィードバックが表示されれば、コードが正常に実行されていることを意味します。

他のアイコンを使用したい場合は、下のボタンをクリックして詳細を確認できます。

使用したいアイコンを選択します。

コードをコピーして、以下の画像のようにcaptive_portal部分に貼り付けます。

4. 画像の表示

この例では、お好みの画像をディスプレイに表示します。

前の例と同様に、Studio Code Serverをインストールし、画像を保存するためにimageという新しいフォルダを作成する必要があります。

そして、imageフォルダに画像を入れます。試しに画像をダウンロードするには、下のボタンをクリックしてください。

以下のコードをコピーして、下図のようにcaptive_portalの後に貼り付けることができます。

image:
- file: /config/esphome/image/wifi.jpg # the path where you save the image, png or jpg format
id: myImage
type: BINARY
resize: 800x480 # how big you want to show, the biggest size should be as same as ePaper Penal pixel(800x480)
invert_alpha: true # invert color

spi:
clk_pin: GPIO7
mosi_pin: GPIO9

display:
- platform: waveshare_epaper
model: 7.50inv2
cs_pin: GPIO44
dc_pin: GPIO10
reset_pin: GPIO38
busy_pin:
number: GPIO4
inverted: true
update_interval: 30s
lambda: |-
it.image(0, 0, id(myImage));

以下の画像のようなフィードバックが表示されれば、コードが正常に実行されていることを意味します。

デモ 1. Home Assistantダッシュボードのスクリーンショットを撮る

この例では、HAのスクリーンショットをディスプレイに表示します。

まず、スクリーンショットアドオンPuppetをインストールする必要があります。こちらをクリックしてインストールしてください。

バージョンは1.11.4以上である必要があることに注意してください。インストール後、Configuration pageに移動します。このアドオン用のaccess_tokenを作成する必要があります。

次のステップでトークンを作成し、ここに貼り付けてください。

Security pageの下部に移動してトークンを作成し、それをコピーしてPuppetアドオンに貼り付けます。

Puppetアドオンを再起動することを忘れないでください。

アドオンを開始すると、ポート10000で新しいサーバーが起動します。リクエストしたパスは、そのページのスクリーンショットを返します。必要なビューポートサイズを指定する必要があります。

例えば、デフォルトダッシュボードの1000px x 1000pxのスクリーンショットを取得するには、以下を取得します:

# http://192.168.1.191:10000/lovelace/0?viewport=1000x1000(My address)

http://homeassistant.local:10000/lovelace/0?viewport=1000x1000

E Ink®ディスプレイのカラーパレットを削減するには、einkパラメータを追加できます。値は使用する色数(黒を含む)を表します。例えば、2色のE Ink®ディスプレイの場合:

http://homeassistant.local:10000/lovelace/0?viewport=1000x1000&eink=2

eink=2を使用している場合、invertパラメータを追加して色を反転することもできます:

http://homeassistant.local:10000/lovelace/0?viewport=1000x1000&eink=2&invert

また、他のページのスクリーンショットも撮ることができます。例えば、HAのTo-do listsページ:

http://192.168.1.191:10000/todo?viewport=800x480&eink=2&invert

このリンクをブラウザに入力することで、スクリーンショットの効果を確認できます。

以下のコードをコピーして、下図のようにcaptive_portalの後に貼り付けることができます。

http_request:
verify_ssl: false
timeout: 10s
watchdog_timeout: 15s

online_image:
- id: dashboard_image
format: PNG
type: BINARY
buffer_size: 30000
url: http://192.168.1.191:10000/todo?viewport=800x480&eink=2&invert #change this link to your screenshot link
update_interval: 30s
on_download_finished:
- delay: 0ms
- component.update: main_display

spi:
clk_pin: GPIO7
mosi_pin: GPIO9

display:
- platform: waveshare_epaper
id: main_display
model: 7.50inv2
cs_pin: GPIO44
dc_pin: GPIO10
reset_pin: GPIO38
busy_pin:
number: GPIO4
inverted: true
update_interval: never
lambda: |-
it.image(0, 0, id(dashboard_image));

以下の画像のようなフィードバックが表示されたら、コードが正常に実行されていることを意味します。

デモ2. ディープスリープモード

tip

ディープスリープモード中は、デバイスに直接コードをアップロードできません。ダウンロードモードに入る必要があります。Q3にジャンプするにはここをクリック

この例では、ディープスリープモードを使用して電力を節約する方法を示します。6時間ごとに情報を更新します。

以下のコードをコピーして、下図のようにcaptive_portalの後に貼り付けることができます。

globals:
- id: sleep_counter
type: int
restore_value: yes # key parameter, to use RTC storage
initial_value: '0'

# Here is deep sleep part
deep_sleep:
id: deep_sleep_1
run_duration: 30s # Device wake up and run 30s (enough to display)
sleep_duration: 3min # deep sleep for 3min

interval:
- interval: 29s # run this command before the end of run_duration
then:
- logger.log: "Entering deep sleep now..."

font:
- file: "gfonts://Inter@700"
id: font1
size: 24

spi:
clk_pin: GPIO7
mosi_pin: GPIO9

display:
- platform: waveshare_epaper
model: 7.50inv2
cs_pin: GPIO44
dc_pin: GPIO10
reset_pin: GPIO38
busy_pin:
number: GPIO4
inverted: true
update_interval: 3min
lambda: |-
id(sleep_counter) += 1;
ESP_LOGD("main", "Wakeup count: %d", id(sleep_counter));
it.printf(100, 100, id(font1), "Wakeup count: %d", id(sleep_counter));

カウンターが表示されます。起動するたびに1つずつ増加します。

デモ3. 包括的な例

tip

より良く理解するために、まず上記の基本的な使用方法を実行することを強くお勧めします。

この例では、TRMNL 7.5インチe-paper DIYキット用の包括的なESPHome設定を示します。YAMLコードは複数の機能を統合して、Home Assistantとシームレスに連携するスマートでインタラクティブなディスプレイパネルを作成します。

目的と機能:

  • この設定により、デバイスはWi-FiとHome Assistantに接続し、簡単な管理のためにAPIとOTAアップデートの両方をサポートします。

  • 物理ボタンで制御される2つの切り替え可能なページで、e-paperディスプレイにさまざまなタイプの情報を表示するように設定します。

  • デバイスはバッテリー電圧を読み取り、バッテリーの割合を計算し、対応するバッテリーアイコンと値を表示します。

  • 天気の状況と温度はHome Assistantから取得され、適切なアイコンと単位で表示されます。

  • 現在の時刻と日付も表示され、Home Assistantと同期されます。

この例では、センサー読み取り値、Home Assistantデータ、ユーザー入力を組み合わせて、ESPHomeとTRMNL 7.5インチe-paperキットを使用して機能豊富な常時オンスマートディスプレイを構築する方法を紹介します。

完全なコードをプレビューするにはここをクリック
esphome:
name: obdy
friendly_name: obdy
on_boot:
priority: 600
then:
- output.turn_on: bsp_battery_enable
- delay: 200ms
- component.update: battery_voltage
- component.update: battery_level

esp32:
board: esp32-s3-devkitc-1
framework:
type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:
encryption:
key: "j0V30kuJ6Zdij9SU6Ee+7ruwid+7SQOxtinjld2PRc0="

ota:
- platform: esphome
password: "db786195ae6f9748f5b57ea9bd1d4161"

wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password

# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Obdy Fallback Hotspot"
password: "IOfapF7hXq55"

captive_portal:

# Deep-sleep, wake by GPIO4
# deep_sleep:
# id: deep_sleep_1
# run_duration: 1min
# sleep_duration: 60min
# wakeup_pin: GPIO4
# wakeup_pin_mode: INVERT_WAKEUP

spi:
clk_pin: GPIO7
mosi_pin: GPIO9

# Fonts
font:
- file: "gfonts://Inter@700"
id: small_font
size: 24
- file: "gfonts://Inter@700"
id: mid_font
size: 36
- file: "gfonts://Inter@700"
id: big_font
size: 180
- file: "gfonts://Inter@700"
id: time_font
size: 96 # for the big time display
- file: 'fonts/materialdesignicons-webfont.ttf'
id: font_bat_icon
size: 24
glyphs:
- "\U000F007A" # mdi-battery-10
- "\U000F007B" # mdi-battery-20
- "\U000F007C" # mdi-battery-30
- "\U000F007D" # mdi-battery-40
- "\U000F007E" # mdi-battery-50
- "\U000F007F" # mdi-battery-60
- "\U000F0080" # mdi-battery-70
- "\U000F0081" # mdi-battery-80
- "\U000F0082" # mdi-battery-90
- "\U000F0079" # mdi-battery
- file: "fonts/materialdesignicons-webfont.ttf" # <-- 替换成你的字体文件路径
id: weather_icon_font
size: 100
glyphs:
- "\U000F0599" # weather-sunny
- "\U000F0595" # weather-partly-cloudy
- "\U000F0F2F" # weather-cloudy
- "\U000F0597" # weather-rainy
- "\U000F0598" # weather-snowy
- "\U000F059B" # weather-windy
- "\U000F0594" # weather-fog
- "\U000F0596" # weather-lightning

globals:
- id: page_index
type: int
restore_value: true
initial_value: '0'
- id: battery_glyph
type: std::string
restore_value: no
initial_value: "\"\\U000F0079\"" # default full battery

sensor:
- platform: adc
pin: GPIO1
name: "Battery Voltage"
id: battery_voltage
update_interval: 60s
attenuation: 12db
filters:
- multiply: 2.0
- platform: template
name: "Battery Level"
id: battery_level
unit_of_measurement: "%"
icon: "mdi:battery"
device_class: battery
state_class: measurement
lambda: 'return id(battery_voltage).state;'
update_interval: 60s
on_value:
then:
- lambda: |-
int pct = int(x);
if (pct <= 10) id(battery_glyph) = "\U000F007A";
else if (pct <= 20) id(battery_glyph) = "\U000F007B";
else if (pct <= 30) id(battery_glyph) = "\U000F007C";
else if (pct <= 40) id(battery_glyph) = "\U000F007D";
else if (pct <= 50) id(battery_glyph) = "\U000F007E";
else if (pct <= 60) id(battery_glyph) = "\U000F007F";
else if (pct <= 70) id(battery_glyph) = "\U000F0080";
else if (pct <= 80) id(battery_glyph) = "\U000F0081";
else if (pct <= 90) id(battery_glyph) = "\U000F0082";
else id(battery_glyph) = "\U000F0079";
filters:
- calibrate_linear:
- 4.15 -> 100.0
- 3.96 -> 90.0
- 3.91 -> 80.0
- 3.85 -> 70.0
- 3.80 -> 60.0
- 3.75 -> 50.0
- 3.68 -> 40.0
- 3.58 -> 30.0
- 3.49 -> 20.0
- 3.41 -> 10.0
- 3.30 -> 5.0
- 3.27 -> 0.0
- clamp:
min_value: 0
max_value: 100

output:
- platform: gpio
pin: GPIO6
id: bsp_battery_enable

binary_sensor:
- platform: gpio # Next page KEY1
pin:
number: GPIO2
mode: INPUT_PULLUP
inverted: true
id: key1
name: "Key1"
on_press:
then:
- lambda: |-
id(page_index) = (id(page_index) + 1) % 2;
id(epaper_display).update();

- platform: gpio # Prev page KEY2
pin:
number: GPIO3
mode: INPUT_PULLUP
inverted: true
id: key2
name: "Key2"
on_press:
then:
- lambda: |-
id(page_index) = (id(page_index) - 1 + 2) % 2;
id(epaper_display).update();

# - platform: gpio
# pin:
# number: GPIO5 # KEY3
# mode: INPUT_PULLUP
# inverted: true
# id: key2
# name: "Key2"
# on_press:
# then:

# Home Assistant time
time:
- platform: homeassistant
id: ha_time

text_sensor:
- platform: homeassistant
entity_id: weather.home
id: myWeather
- platform: homeassistant
entity_id: weather.home
id: temp
attribute: "temperature"

display:
- platform: waveshare_epaper
id: epaper_display
model: 7.50inv2
cs_pin: GPIO44
dc_pin: GPIO10
reset_pin: GPIO38
busy_pin:
number: GPIO4
inverted: true
update_interval: never
lambda: |-
// ---------- PAGE 0 ----------
if (id(page_index) == 0) {
// Screen dimension constants for easy adjustment
const int scr_w = 800;
const int scr_h = 480;
const int center_x = scr_w / 2; // Center X-coordinate of the screen (400)

// --- Top-right: Battery Info ---
// Display the battery icon using an icon font
it.printf(scr_w - 130, 13, id(font_bat_icon), "%s", id(battery_glyph).c_str());
// Display the battery percentage text
it.printf(scr_w - 100, 10, id(small_font), "%.0f%%", id(battery_level).state);

// --- Draw the vertical separator line ---
// Draw a vertical line in the middle to separate left and right areas
it.filled_rectangle(center_x, 100, 2, 280);

// ==================================================
// LEFT AREA: WEATHER INFO
// ==================================================
// Calculate the center X-coordinate of the left area for alignment
const int left_center_x = center_x / 2; // 200

// 1. Display the title "Weather" at the top of the left area
it.printf(left_center_x, 110, id(mid_font), TextAlign::TOP_CENTER, "Weather");

// 2. Get the weather condition and select the corresponding icon
std::string weather_condition = id(myWeather).state;
std::string weather_icon = "\U000F0599"; // Default icon (sunny), as a fallback for unknown states

if (weather_condition == "partlycloudy") {
weather_icon = "\U000F0595"; // weather-partly-cloudy
} else if (weather_condition == "cloudy") {
weather_icon = "\U000F0F2F"; // weather-cloudy
} else if (weather_condition == "rainy") {
weather_icon = "\U000F0597"; // weather-rainy
} else if (weather_condition == "snowy") {
weather_icon = "\U000F0598"; // weather-snowy
} else if (weather_condition == "windy") {
weather_icon = "\U000F059B"; // weather-windy
} else if (weather_condition == "fog") {
weather_icon = "\U000F0594"; // weather-fog
} else if (weather_condition == "lightning") {
weather_icon = "\U000F0596"; // weather-lightning
}
// Display the weather icon in the center of the left area
it.printf(left_center_x, 240, id(weather_icon_font), TextAlign::CENTER, "%s", weather_icon.c_str());

// 3. Display the weather condition text below the icon
it.printf(left_center_x, 400, id(mid_font), TextAlign::BOTTOM_CENTER, "%s", weather_condition.c_str());


// ==================================================
// RIGHT AREA: TEMPERATURE INFO
// ==================================================
// Calculate the center X-coordinate of the right area for alignment
const int right_center_x = center_x + (center_x / 2); // 600

// 1. Display the title "Temperature" at the top of the right area
it.printf(right_center_x, 110, id(mid_font), TextAlign::TOP_CENTER, "Temperature");

// 3. Display the temperature reading below the icon, with one decimal place
float temp_c = stof(id(temp).state);
double temp_f = temp_c * 9.0 / 5.0 + 32.0;
it.printf(right_center_x, 250, id(mid_font), TextAlign::CENTER, "%.0f°F", temp_f);
it.printf(right_center_x, 380, id(mid_font), TextAlign::CENTER, "%.1f°C", temp_c);
}
// ---------- PAGE 1 ----------
else{
// Battery top-right
it.printf(670, 13, id(font_bat_icon), "%s", id(battery_glyph).c_str());
it.printf(700, 10, id(small_font), "%.0f%%", id(battery_level).state);

auto now = id(ha_time).now();
struct tm timeinfo = now.to_c_tm();

// centering time HH:MM
char timeStr[6];
strftime(timeStr, sizeof(timeStr), "%H:%M", &timeinfo);
it.printf(400, 180, id(time_font), TextAlign::CENTER, timeStr);

// Date: Day of week
const char *weekday[] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
const char *wday = weekday[timeinfo.tm_wday];

// Date: month - day
char dateStr[12];
strftime(dateStr, sizeof(dateStr), "%b %d", &timeinfo); // e.g. Jun 15

// Day of the week + date below the time
it.printf(400, 280, id(mid_font), TextAlign::CENTER, "%s, %s", wday, dateStr);
}

以下の画像のようなフィードバックが表示されたら、コードが正常に実行されていることを意味します。

FAQ

Q1: データが表示されないのはなぜですか?

この場合、Settings -> Devices & Services -> Integrations に移動してデバイスをRECONGFIGUREする必要があります。ePaper Penalが見つからない場合は、HAを再起動してみてください。

Q2: Home Assistantでこれらのデータを取得できないのはなぜですか?

この場合、Settings -> Devices & Services -> Integrations に移動してデバイスをHAにADDする必要があります。

Q3: デバイスがディープスリープモードの時に新しいプログラムをアップロードするにはどうすればよいですか?

デバイスがディープスリープモードの時は、直接新しいプログラムをアップロードすることはできません。

  1. まず、デバイスの電源が入っていることを確認してください。次に、XIAO ESP32-S3 PlusのUSB-Cポートの隣にあるBootボタンを長押しします。

  2. Bootボタンを押したまま、Resetボタンを一度押してから、Bootボタンを離します。

  3. その後、バッテリースイッチをオフにして、電源ケーブルを抜きます。

  4. 最後に、ケーブルを再接続して新しいプログラムをアップロードします。

Q4: TRMNL 7.5inch(OG) DIY Kitがコンピューターに接続できませんか?

何度か抜き差しを試すか、プロンプトに従ってドライバーをインストールしてください。

Q5: Wi-Fiプログラムのアップロードが失敗しましたか?

この場合、epaperパネルがオフラインまたはディープスリープモードになっています。オンラインにするか、起動してください。

技術サポート & 製品ディスカッション

弊社製品をお選びいただき、ありがとうございます!弊社製品での体験が可能な限りスムーズになるよう、さまざまなサポートを提供いたします。さまざまな好みやニーズに対応するため、複数のコミュニケーションチャンネルを用意しています。

Loading Comments...