475 lines
13 KiB
YAML
475 lines
13 KiB
YAML
# ESPHome code for the LilyGO TTGO Display
|
|
# Copyright 2023 by Smart Home Junkie
|
|
#
|
|
# Visit my website at https://www.smarthomejunkie.net
|
|
# Watch the tutorial for this display and code at https://youtu.be/LJCeelAzlS0
|
|
|
|
substitutions:
|
|
esp_name: "ttgo-display"
|
|
|
|
esphome:
|
|
name: ${esp_name}
|
|
comment: ${esp_name}
|
|
|
|
# Enable Home Assistant API
|
|
api:
|
|
encryption:
|
|
key: !secret ttgo
|
|
|
|
# Define board type
|
|
esp32:
|
|
board: esp32dev
|
|
|
|
# Enable logging
|
|
logger:
|
|
|
|
ota:
|
|
password: !secret aqs1_ota_passwoord
|
|
|
|
wifi:
|
|
ssid: !secret wifi_ssid
|
|
password: !secret wifi_password
|
|
|
|
# Enable fallback hotspot (captive portal) in case wifi connection fails
|
|
ap:
|
|
ssid: ${esp_name} fallback
|
|
password: !secret fallback_password
|
|
|
|
captive_portal:
|
|
|
|
spi:
|
|
clk_pin: GPIO18
|
|
mosi_pin: GPIO19
|
|
|
|
# Define the rotate variable. This indicates if the pages should be rotated or not
|
|
globals:
|
|
- id: rotate
|
|
type: boolean
|
|
initial_value: "true"
|
|
|
|
# Define time sensor
|
|
time:
|
|
- platform: homeassistant
|
|
id: esptime
|
|
|
|
# Define binary sensors
|
|
binary_sensor:
|
|
- platform: gpio # Short Press button 0
|
|
pin:
|
|
number: GPIO0
|
|
inverted: true
|
|
mode:
|
|
input: true
|
|
pullup: true
|
|
name: "Short Press Button 0"
|
|
id: short_press_button_0
|
|
on_click:
|
|
min_length: 1ms
|
|
max_length: 1000ms
|
|
then:
|
|
- display.page.show_previous: my_display
|
|
- component.update: my_display
|
|
- platform: gpio # Long Press button 0
|
|
pin:
|
|
number: GPIO0
|
|
inverted: true
|
|
id: button_2
|
|
on_click:
|
|
min_length: 1001ms
|
|
max_length: 5000ms
|
|
then:
|
|
- switch.toggle: backlight
|
|
- platform: gpio # Short Press button 1
|
|
pin:
|
|
number: GPIO35
|
|
inverted: true
|
|
name: "Short Press Button 1"
|
|
id: short_press_button_1
|
|
on_click:
|
|
min_length: 1ms
|
|
max_length: 1000ms
|
|
then:
|
|
- display.page.show_next: my_display
|
|
- component.update: my_display
|
|
- platform: gpio # Long Press button 1
|
|
pin:
|
|
number: GPIO35
|
|
inverted: true
|
|
name: "Long Press Button 1"
|
|
id: long_press_button_1
|
|
on_click:
|
|
min_length: 1001ms
|
|
max_length: 5000ms
|
|
then:
|
|
- if:
|
|
condition:
|
|
lambda: |-
|
|
return id(rotate);
|
|
then:
|
|
globals.set:
|
|
id: rotate
|
|
value: "false"
|
|
else:
|
|
globals.set:
|
|
id: rotate
|
|
value: "true"
|
|
|
|
# Allow dimmable control of the backlight (pin GPIO4) - Currently not working
|
|
output:
|
|
- platform: ledc
|
|
pin: GPIO4
|
|
id: gpio4
|
|
|
|
light:
|
|
- platform: monochromatic
|
|
output: gpio4
|
|
name: "Backlight"
|
|
|
|
switch:
|
|
- platform: gpio
|
|
pin: GPIO4
|
|
id: backlight
|
|
internal: true
|
|
|
|
# Define all the numeric sensors used
|
|
sensor:
|
|
- platform: homeassistant
|
|
entity_id: sensor.subscriptions_short
|
|
id: subscriptions
|
|
- platform: homeassistant
|
|
entity_id: sensor.views
|
|
id: views
|
|
- platform: homeassistant
|
|
entity_id: sensor.ttgo_display_data
|
|
attribute: netto_power
|
|
id: nettopower
|
|
- platform: homeassistant
|
|
entity_id: sensor.Temperatuur_Zolder_Werkkamer
|
|
id: office_temperature
|
|
- platform: homeassistant
|
|
entity_id: sensor.humidity_zolder_werkkamer
|
|
id: office_humidity
|
|
- platform: homeassistant
|
|
entity_id: sensor.office_multi_sensor_pressure
|
|
id: office_pressure
|
|
- platform: homeassistant
|
|
entity_id: sensor.office_light_sensor
|
|
id: office_light_sensor
|
|
- platform: homeassistant
|
|
entity_id: sensor.ttgo_display_data
|
|
attribute: temperature
|
|
id: outside_temperature
|
|
- platform: homeassistant
|
|
entity_id: sensor.ttgo_display_data
|
|
attribute: wind_speed
|
|
id: wind_speed
|
|
- platform: homeassistant
|
|
entity_id: sensor.bitcoin
|
|
id: bitcoin
|
|
|
|
# Define all the string sensors used
|
|
text_sensor:
|
|
- platform: homeassistant
|
|
entity_id: sensor.ttgo_display_data
|
|
attribute: weather_condition_0
|
|
id: weather_condition
|
|
filters:
|
|
- to_upper:
|
|
|
|
# Define fonts. Use either Google fonts or stored fonts. Stored fonts are stored in esphome/fonts/
|
|
font:
|
|
- file:
|
|
type: gfonts
|
|
family: Lato
|
|
weight: 400
|
|
id: lato
|
|
size: 20
|
|
- file:
|
|
type: gfonts
|
|
family: Lato
|
|
weight: 700
|
|
id: latobold
|
|
size: 24
|
|
- file:
|
|
type: gfonts
|
|
family: Lato
|
|
weight: 900
|
|
id: latoblack
|
|
size: 30
|
|
- file:
|
|
type: gfonts
|
|
family: Lato
|
|
weight: 900
|
|
id: latoblackheading1
|
|
size: 50
|
|
- file: "fonts/bitcoin/Ubuntu-BoldItalic.ttf"
|
|
id: bitcoin_font
|
|
size: 30
|
|
|
|
# Define colors
|
|
color:
|
|
- id: RED
|
|
red: 100%
|
|
green: 0%
|
|
blue: 0%
|
|
- id: GREEN
|
|
red: 0%
|
|
green: 100%
|
|
blue: 0%
|
|
- id: BLUE
|
|
red: 0%
|
|
green: 0%
|
|
blue: 100%
|
|
- id: YELLOW
|
|
red: 100%
|
|
green: 100%
|
|
blue: 0%
|
|
- id: WHITE
|
|
red: 100%
|
|
green: 100%
|
|
blue: 100%
|
|
- id: ORANGE
|
|
red: 100%
|
|
green: 67%
|
|
blue: 20%
|
|
|
|
# Define all the images used. Store the images in the images folder within the esphome folder (esphome/images/)
|
|
image:
|
|
- file: "images/youtube.png"
|
|
id: youtube_image
|
|
resize: 80x80
|
|
type: RGB24
|
|
- file: "images/logo.jpg"
|
|
id: logo
|
|
resize: 120x120
|
|
type: RGB24
|
|
- file: "images/electricity-icon.png"
|
|
id: electricity_image
|
|
resize: 80x80
|
|
type: RGB24
|
|
- file: "images/bitcoin_logo.png"
|
|
id: bitcoin_logo
|
|
resize: 80x80
|
|
type: RGB24
|
|
- file: "images/wind_icon.png"
|
|
id: wind_icon
|
|
resize: 30x30
|
|
type: RGB24
|
|
- file: "images/thermometer_icon.png"
|
|
id: thermometer_icon
|
|
resize: 30x30
|
|
type: RGB24
|
|
|
|
# Define animations
|
|
animation:
|
|
- file: "images/weather.gif"
|
|
id: weather_animation
|
|
resize: 80x80
|
|
type: RGB24
|
|
|
|
# Define the graphs for sensors that you want to show on the display
|
|
graph:
|
|
- id: office_temperature_graph
|
|
sensor: office_temperature
|
|
duration: 4h
|
|
width: 220
|
|
height: 90
|
|
x_grid: 1h
|
|
y_grid: 5
|
|
min_range: 5
|
|
max_range: 35
|
|
min_value: 5
|
|
max_value: 35
|
|
color: GREEN
|
|
- id: office_humidity_graph
|
|
sensor: office_humidity
|
|
duration: 4h
|
|
width: 220
|
|
height: 90
|
|
x_grid: 1h
|
|
y_grid: 25
|
|
min_range: 1
|
|
max_range: 100
|
|
min_value: 1
|
|
max_value: 100
|
|
color: BLUE
|
|
- id: office_pressure_graph
|
|
sensor: office_pressure
|
|
duration: 4h
|
|
width: 220
|
|
height: 90
|
|
x_grid: 1h
|
|
y_grid: 100.0
|
|
color: YELLOW
|
|
- id: office_light_sensor_graph
|
|
duration: 4h
|
|
width: 220
|
|
height: 90
|
|
x_grid: 1h
|
|
traces:
|
|
- sensor: office_light_sensor
|
|
color: ORANGE
|
|
line_type: SOLID
|
|
line_thickness: 5
|
|
|
|
# Define qr code locations
|
|
qr_code:
|
|
- id: smarthomejunkie_website
|
|
value: smarthomejunkie.net
|
|
|
|
# Set up the display. This is the main part of the code
|
|
display:
|
|
- platform: st7789v
|
|
model: TTGO_TDISPLAY_135x240
|
|
backlight_pin: GPIO4
|
|
cs_pin: GPIO5
|
|
dc_pin: GPIO16
|
|
reset_pin: GPIO23
|
|
rotation: 90°
|
|
update_interval: 1s
|
|
id: my_display
|
|
pages: # Define the pages
|
|
# - id: showintro
|
|
# lambda: |-
|
|
# it.image(0, 10, id(logo));
|
|
# it.printf(135, 10, id(latoblack), WHITE, "SMART");
|
|
# it.printf(140, 50, id(latoblack), WHITE, "HOME");
|
|
# it.printf(130, 90, id(latoblack), WHITE, "JUNKIE");
|
|
- id: showtime
|
|
lambda: |-
|
|
it.strftime(45, 20, id(latoblack), "%d-%m-%Y", id(esptime).now());
|
|
it.strftime(25, 55, id(latoblackheading1), "%H:%M:%S", id(esptime).now());
|
|
# - id: showsubscribers
|
|
# lambda: |-
|
|
# it.printf(0,0,id(latoblack), WHITE, "SUBSCRIBERS");
|
|
# it.image(0, 40, id(youtube_image));
|
|
# if (id(subscriptions).has_state()) {
|
|
# it.printf(95, 60, id(latoblack), WHITE, "%.1fK", id(subscriptions).state);
|
|
# } else {
|
|
# it.printf(95, 65, id(lato), WHITE, "LOADING...");
|
|
# }
|
|
# - id: showviews
|
|
# lambda: |-
|
|
# it.printf(0,0,id(latoblack), WHITE, "VIEWS");
|
|
# it.image(0, 40, id(youtube_image));
|
|
# if (id(views).has_state()) {
|
|
# it.printf(95, 60, id(latoblack), WHITE, "%.0f", id(views).state);
|
|
# } else {
|
|
# it.printf(95, 65, id(lato), WHITE, "LOADING...");
|
|
# }
|
|
- id: shownettopower
|
|
lambda: |-
|
|
it.printf(0,0,id(latoblack), WHITE, "NETTO POWER");
|
|
it.image(0, 40, id(electricity_image));
|
|
if (id(nettopower).has_state()) {
|
|
if (id(nettopower).state > -1000) {
|
|
it.printf(95, 60, id(latoblack), WHITE, "%.0f Watt", id(nettopower).state);
|
|
} else {
|
|
it.printf(95, 60, id(latobold), WHITE, "%.0f Watt", id(nettopower).state);
|
|
}
|
|
} else {
|
|
it.printf(95, 65, id(lato), WHITE, "LOADING...");
|
|
}
|
|
# - id: showbitcoin
|
|
# lambda: |-
|
|
# it.printf(0,0,id(bitcoin_font), WHITE, "bitcoin");
|
|
# it.image(0, 40, id(bitcoin_logo));
|
|
# if (id(bitcoin).has_state()) {
|
|
# it.printf(95, 60, id(bitcoin_font), WHITE, "%.0f", id(bitcoin).state);
|
|
# } else {
|
|
# it.printf(95, 65, id(lato), WHITE, "LOADING...");
|
|
# }
|
|
- id: show_office_temperature_graph
|
|
lambda: |-
|
|
if (id(office_temperature).has_state()) {
|
|
it.printf(0,0,id(latoblack), WHITE, "TEMP: %.1f °C", id(office_temperature).state);
|
|
it.graph(10, 40, id(office_temperature_graph));
|
|
} else {
|
|
it.printf(0,0,id(latoblack), WHITE, "TEMPERATURE");
|
|
it.printf(80, 65, id(lato), WHITE, "LOADING...");
|
|
}
|
|
- id: show_office_humidity_graph
|
|
lambda: |-
|
|
if (id(office_humidity).has_state()) {
|
|
it.printf(0,0,id(latoblack), WHITE, "HUM: %.0f %%", id(office_humidity).state);
|
|
it.graph(10, 40, id(office_humidity_graph));
|
|
} else {
|
|
it.printf(0,0,id(latoblack), WHITE, "HUMIDITY");
|
|
it.printf(80, 65, id(lato), WHITE, "LOADING...");
|
|
}
|
|
# - id: show_office_pressure_graph
|
|
# lambda: |-
|
|
# if (id(office_pressure).has_state()) {
|
|
# it.printf(0,0,id(latoblack), WHITE, "PRS: %.0f hPA", id(office_pressure).state);
|
|
# it.graph(10, 40, id(office_pressure_graph));
|
|
# } else {
|
|
# it.printf(0,0,id(latoblack), WHITE, "PRESSURE");
|
|
# it.printf(80, 65, id(lato), WHITE, "LOADING...");
|
|
# }
|
|
# - id: show_office_light_sensor_graph
|
|
# lambda: |-
|
|
# if (id(office_light_sensor).has_state()) {
|
|
# it.printf(0,0,id(latoblack), WHITE, "LUX: %.0f lx", id(office_light_sensor).state);
|
|
# it.graph(10, 40, id(office_light_sensor_graph));
|
|
# } else {
|
|
# it.printf(0,0,id(latoblack), WHITE, "LUX");
|
|
# it.printf(80, 65, id(lato), WHITE, "LOADING...");
|
|
# }
|
|
- id: show_weather
|
|
lambda: |-
|
|
id(weather_animation).next_frame();
|
|
it.image(0, 0, id(weather_animation), COLOR_ON, COLOR_OFF);
|
|
if (id(weather_condition).state == "CLOUDY" ||
|
|
id(weather_condition).state == "RAINY" ||
|
|
id(weather_condition).state == "FOG" ||
|
|
id(weather_condition).state == "HAIL" ||
|
|
id(weather_condition).state == "SNOWY" ||
|
|
id(weather_condition).state == "SUNNY" ||
|
|
id(weather_condition).state == "WINDY" ) {
|
|
it.printf(110,0,id(latoblack), WHITE,"%s",id(weather_condition).state.c_str());
|
|
}
|
|
if (id(weather_condition).state == "LIGTNING" ||
|
|
id(weather_condition).state == "POURING" ) {
|
|
it.printf(110,0,id(latobold), WHITE,"%s",id(weather_condition).state.c_str());
|
|
}
|
|
if (id(weather_condition).state == "PARTLYCLOUDY") {
|
|
it.printf(110,0,id(latoblack), WHITE,"PARTLY");
|
|
it.printf(110,35,id(latoblack), WHITE,"CLOUDY");
|
|
}
|
|
if (id(weather_condition).state == "SNOWY-RAIN") {
|
|
it.printf(110,0,id(latoblack), WHITE,"SNOWY");
|
|
it.printf(110,35,id(latoblack), WHITE,"RAIN");
|
|
}
|
|
if (id(weather_condition).state == "LIGHTNING-RAINY") {
|
|
it.printf(110,0,id(latobold), WHITE,"LIGHTNING");
|
|
it.printf(110,35,id(latobold), WHITE,"RAINY");
|
|
}
|
|
if (id(weather_condition).state == "WINDY-VARIANT") {
|
|
it.printf(110,0,id(latoblack), WHITE,"WINDY");
|
|
}
|
|
if (id(weather_condition).state == "CLEAR-NIGHT") {
|
|
it.printf(110,0,id(latoblack), WHITE,"CLEAR");
|
|
it.printf(110,35,id(latoblack), WHITE,"NIGHT");
|
|
}
|
|
if (id(weather_condition).state == "EXCEPTIONAL") {
|
|
it.printf(110,0,id(latobold), WHITE,"EXCEPTIONAL");
|
|
}
|
|
it.image(0, 100, id(thermometer_icon));
|
|
it.printf(35,100,id(latobold), WHITE,"%.1f °C", id(outside_temperature).state);
|
|
it.image(110, 100, id(wind_icon));
|
|
it.printf(145,100,id(latobold), WHITE,"%.2f m/s", id(wind_speed).state);
|
|
# - id: showqrcode
|
|
# lambda: |-
|
|
# it.qr_code(60, 5, id(smarthomejunkie_website), WHITE, 5);
|
|
|
|
# Define the cycle interval of the pages.
|
|
interval:
|
|
- interval: 5s
|
|
then:
|
|
if:
|
|
condition:
|
|
lambda: 'return id(rotate);'
|
|
then:
|
|
- display.page.show_next: my_display
|
|
- component.update: my_display
|