-
-
Save Cadair/7db53154a8d353eb304bcc515a9273bb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
substitutions: | |
esp_name: ESP Display | |
esp_hostname: esp-display | |
ha_climate_component: climate.central_heating | |
esphome: | |
name: ${esp_hostname} | |
platformio_options: | |
upload_speed: 1500000 | |
esp32: | |
board: esp32dev | |
framework: | |
type: arduino | |
spi: | |
clk_pin: 18 | |
mosi_pin: 23 | |
#external_components: | |
# - source: github://tiaanv/esphome-components | |
# components: ["t547"] | |
# Partial refresh but bleeds | |
external_components: | |
- source: | |
type: git | |
url: https://github.com/vbaksa/esphome | |
ref: dev | |
components: [lilygo_t5_47_display] | |
refresh: 5s | |
logger: | |
api: | |
ota: | |
wifi: | |
networks: | |
- ssid: "cadair" | |
password: !secret wifi_password | |
time: | |
- platform: sntp | |
id: ntp | |
sun: | |
latitude: !secret home_lat | |
longitude: !secret home_lon | |
binary_sensor: | |
- platform: gpio | |
pin: | |
number: GPIO39 | |
inverted: true | |
name: "${esp_name} Button 5" | |
on_state: | |
then: | |
- delay: 0.2s | |
- script.execute: refresh_display | |
- platform: gpio | |
pin: | |
number: GPIO34 | |
inverted: true | |
name: "${esp_name} Button 4" | |
on_state: | |
then: | |
- delay: 0.2s | |
- script.execute: refresh_display | |
- platform: gpio | |
pin: | |
number: GPIO35 | |
inverted: true | |
name: "${esp_name} Button 3" | |
on_state: | |
then: | |
- delay: 0.2s | |
- script.execute: refresh_display | |
- platform: homeassistant | |
id: backdoor_locked | |
entity_id: binary_sensor.backdoor_locked | |
internal: true | |
- platform: homeassistant | |
id: backdoor | |
entity_id: binary_sensor.backdoor | |
internal: true | |
on_state: | |
then: | |
- component.update: t5_display | |
- platform: homeassistant | |
id: dryer | |
entity_id: binary_sensor.dryer | |
internal: true | |
- platform: homeassistant | |
id: washer | |
entity_id: binary_sensor.washer | |
internal: true | |
sensor: | |
- platform: adc | |
pin: GPIO36 | |
name: "${esp_name} Battery Voltage" | |
id: batt_volt | |
attenuation: 11db | |
filters: | |
- multiply: 2 | |
- platform: template | |
name: "${esp_name} Battery" | |
id: batt | |
unit_of_measurement: "%" | |
accuracy_decimals: 0 | |
device_class: battery | |
lambda: |- | |
int y = (1-(4.1-id(batt_volt).state)/(4.1-3.3))*100; | |
if (y < 100) {return y;} else {return 100;}; | |
- platform: homeassistant | |
id: climate_set_point | |
entity_id: "${ha_climate_component}" | |
attribute: temperature | |
internal: true | |
- platform: homeassistant | |
id: climate_current_temp | |
entity_id: "${ha_climate_component}" | |
attribute: current_temperature | |
internal: true | |
- platform: homeassistant | |
id: forecast_temp_high | |
entity_id: sensor.openweathermap_forecast_temperature | |
internal: true | |
- platform: homeassistant | |
id: forecast_temp_low | |
entity_id: sensor.openweathermap_forecast_temperature_low | |
internal: true | |
- platform: homeassistant | |
id: forecast_percip_prob | |
entity_id: sensor.holmfirth_probability_of_precipitation | |
internal: true | |
- platform: homeassistant | |
id: forecast_wind_speed | |
entity_id: sensor.holmfirth_wind_speed | |
internal: true | |
- platform: homeassistant | |
id: next_bin_days | |
entity_id: sensor.next_bin_timedelta | |
internal: true | |
- platform: homeassistant | |
id: landing_humidity | |
entity_id: sensor.lumi_lumi_weather_28025d04_humidity | |
internal: true | |
- platform: homeassistant | |
id: fish_tank_temperature | |
entity_id: sensor.fish_tank_temperature | |
internal: true | |
text_sensor: | |
- platform: sun | |
name: Sun Next Sunrise | |
type: sunrise | |
id: sunrise | |
- platform: sun | |
name: Sun Next Sunset | |
type: sunset | |
id: sunset | |
# Sensors read from homeassistant | |
- platform: homeassistant | |
entity_id: sensor.next_bin_collection | |
id: next_bin | |
internal: true | |
- platform: homeassistant | |
entity_id: "${ha_climate_component}" | |
attribute: hvac_action | |
id: climate_state | |
internal: true | |
- platform: homeassistant | |
entity_id: sensor.charging_status | |
id: car_charging_status | |
internal: true | |
- platform: homeassistant | |
entity_id: sensor.holmfirth_weather | |
id: fc_weather | |
internal: true | |
filters: | |
# Convert the text to the MDI icon | |
- map: | |
- clear-night -> | |
- cloudy -> | |
- partlycloudy -> | |
- fog -> | |
- hail -> | |
- lightning -> | |
- lightning-rainy -> | |
- pouring -> | |
- rainy -> | |
- snowy -> | |
- snowy-rainy -> | |
- sunny -> | |
- windy -> | |
- windy-variant -> | |
- exceptional -> | |
script: | |
- id: refresh_display | |
then: | |
- component.update: t5_display | |
font: | |
- file: "SourceSansPro-Regular.ttf" | |
id: font_footer | |
size: 28 | |
- file: "SourceSansPro-Regular.ttf" | |
id: font_value | |
size: 56 | |
- file: "SourceSansPro-Bold.ttf" | |
id: font_name | |
size: 42 | |
- file: 'materialdesignicons-webfont.ttf' | |
id: font_icons_footer | |
size: 28 | |
glyphs: | |
- "\U000F058E" # Water percent | |
- "\U000F0E02" # Thermometer down | |
- "\U000F0E03" # Thermometer up | |
- "\U000F059D" # Windy | |
- file: 'materialdesignicons-webfont.ttf' | |
id: font_icons | |
size: 160 | |
glyphs: | |
- "\U000F0594" # clear-night | |
- "\U000F0590" # cloudy | |
- "\U000F0595" # partlycloudy | |
- "\U000F0591" # fog | |
- "\U000F0592" # hail | |
- "\U000F0593" # lightning | |
- "\U000F067E" # lightning-rainy | |
- "\U000F0596" # pouring | |
- "\U000F0597" # rainy | |
- "\U000F0F36" # snowy | |
- "\U000F067F" # snowy-rainy | |
- "\U000F0599" # sunny | |
- "\U000F059D" # windy | |
- "\U000F059E" # windy-variant | |
- "\U000F0F38" # exceptional | |
- file: 'materialdesignicons-webfont.ttf' | |
id: font_icons_small | |
size: 56 | |
glyphs: | |
- "\U000F10C2" # Temperature High | |
- "\U000F10C3" # Temperature Low | |
- "\U000F0E04" # Thermometer Minus | |
- "\U000F0E05" # Thermometer Plus | |
- "\U000F0510" # Thermometer Lines | |
- "\U000F051F" # Timer sand | |
- "\U000F0438" # Heater On | |
- "\U000F0AD7" # Heater Disabled | |
- "\U000F0AD8" # Heater Off | |
- "\U000F081B" # Door Closed | |
- "\U000F10AF" # Door Closed Locked | |
- "\U000F081C" # Door Open | |
- "\U000F0130" # Empty circle | |
- "\U000F11BB" # Dryer Off | |
- "\U000F0917" # Dryer On | |
- "\U000F11BD" # Washing Machine Off | |
- "\U000F072A" # Washing Machine On | |
- "\U000F05F1" # Ev Station | |
- "\U000F151E" # Type 2 Connector | |
- "\U000F059C" # Sun | |
- "\U000F059B" # Sun | |
- "\U000F1011" # Blind Open | |
- "\U000F00AC" # Blind Closed | |
graph: | |
# Show bare-minimum auto-ranged graph | |
- id: house_temperature_graph | |
duration: 6h | |
width: 250 | |
height: 125 | |
border: false | |
y_grid: 1.0 | |
traces: | |
- sensor: climate_set_point | |
line_type: DASHED | |
line_thickness: 3 | |
- sensor: climate_current_temp | |
line_type: SOLID | |
line_thickness: 3 | |
display: | |
- platform: lilygo_t5_47_display | |
id: t5_display | |
rotation: 90 | |
update_interval: 5s | |
lambda: |- | |
#define xres 540 | |
#define yres 960 | |
// Pixel locations of the buttons (from bottom [not USB-C end] to top) | |
#define button_1_y yres - 245 | |
#define button_delta 67 | |
#define button_2_y button_1_y - button_delta | |
#define button_3_y button_2_y - button_delta | |
#define button_4_y button_3_y - button_delta | |
#define button_5_y button_4_y - button_delta | |
#define x_pad 10 // border padding | |
#define y_pad 10 // border padding | |
#define cat_pad 85 // padding before category | |
#define val_pad 70 // padding before value | |
#define icon_pad 40 //padding after icons | |
#define x1n 20 //x position 1st column name | |
#define x1v 25 //x position 1st column value | |
#define x1i 50 //x position 1st column icon | |
#define x2n xres/2 //x position 2nd column name | |
#define x2v xres/2 //x position 2nd column value | |
#define x2i xres/2 //x position 1st column icon | |
#define icon_large 160 // height of large icon | |
#define icon_small 56 // height of large icon | |
#define icon_footer 28 // height of large icon | |
#define div_thickness 2 | |
int y = 0; | |
// Date | |
it.strftime(xres/2, y+y_pad, id(font_name), TextAlign::TOP_CENTER, "%A %d %b %Y", id(ntp).now()); | |
y+=val_pad+cat_pad+y_pad+10; | |
// Weather Icon | |
#define weather_icon_x xres/4 - icon_large/2 | |
int weather_row = icon_footer + y_pad; | |
int weather_y = y + icon_large/2 - 20; | |
it.printf(weather_icon_x, weather_y, id(font_icons), TextAlign::BASELINE_LEFT, "%s", id(fc_weather).state.c_str()); | |
weather_y += weather_row; | |
it.printf(weather_icon_x, weather_y, id(font_icons_footer), TextAlign::BASELINE_LEFT, "\U000F0E03"); | |
it.printf(weather_icon_x + icon_footer + 5, weather_y, id(font_footer), TextAlign::BASELINE_LEFT, "%.0f °C", id(forecast_temp_high).state); | |
weather_row = icon_footer + y_pad/2; | |
weather_y += weather_row; | |
it.printf(weather_icon_x, weather_y, id(font_icons_footer), TextAlign::BASELINE_LEFT, "\U000F0E02"); | |
it.printf(weather_icon_x + icon_footer + 5, weather_y, id(font_footer), TextAlign::BASELINE_LEFT, "%.0f °C", id(forecast_temp_low).state); | |
weather_y += weather_row; | |
// small shift in x for relative icon widths | |
it.printf(weather_icon_x-5, weather_y, id(font_icons_footer), TextAlign::BASELINE_LEFT, "\U000F058E"); | |
it.printf(weather_icon_x + icon_footer + 5, weather_y, id(font_footer), TextAlign::BASELINE_LEFT, "%.0f %%", id(forecast_percip_prob).state); | |
weather_y += weather_row; | |
it.printf(weather_icon_x-2, weather_y, id(font_icons_footer), TextAlign::BASELINE_LEFT, "\U000F059D"); | |
it.printf(weather_icon_x + icon_footer + 5, weather_y, id(font_footer), TextAlign::BASELINE_LEFT, "%.0f mph", id(forecast_wind_speed).state); | |
// Heating Status | |
#define climate_x xres / 2 + x_pad*2 + icon_small / 2 | |
#define climate_y y - 40 | |
if (id(climate_state).state == "heating") { | |
it.printf(climate_x, climate_y, id(font_icons_small), TextAlign::CENTER, "\U000F0438"); | |
} else if (id(climate_state).state == "off") { | |
it.printf(climate_x, climate_y, id(font_icons_small), TextAlign::CENTER, "\U000F0AD8"); | |
} else { | |
it.printf(climate_x, climate_y, id(font_icons_small), TextAlign::CENTER, "\U000F0AD7"); | |
} | |
it.printf(climate_x + icon_pad, climate_y+25, id(font_value), TextAlign::BASELINE_LEFT, "%.1f °C", id(climate_set_point).state); | |
y+=val_pad; | |
it.printf(climate_x, climate_y, id(font_icons_small), TextAlign::CENTER, "\U000F10C3"); | |
it.printf(climate_x + icon_pad, climate_y+18, id(font_value), TextAlign::BASELINE_LEFT, "%.1f °C", id(climate_current_temp).state); | |
y+=20; | |
it.graph(xres / 2 + 10, y, id(house_temperature_graph)); | |
// Inline with top button | |
// Row one | |
#define icon_x_1 icon_small/2 + xres / 3 | |
#define icon_x_2 icon_x_1 + (xres / 3) + icon_small/2 | |
#define sensor_y_shift icon_small + icon_footer + y_pad*4 | |
y = button_5_y + icon_small/4; | |
if (!id(backdoor_locked).state) { | |
it.printf(icon_x_1, y, id(font_icons_small), TextAlign::CENTER, "\U000F10AF"); | |
} else if (!id(backdoor).state) { | |
it.printf(icon_x_1, y, id(font_icons_small), TextAlign::CENTER, "\U000F081B"); | |
} else { | |
it.printf(icon_x_1, y, id(font_icons_small), TextAlign::CENTER, "\U000F081C"); | |
} | |
it.printf(icon_x_1, y + icon_small/2 + y_pad, id(font_footer), TextAlign::CENTER, "Backdoor"); | |
// column 2 | |
if (id(car_charging_status).state == "connected") { | |
it.printf(icon_x_2, y, id(font_icons_small), TextAlign::CENTER, "\U000F151E"); | |
} else if (id(car_charging_status).state == "charging") { | |
it.printf(icon_x_2, y, id(font_icons_small), TextAlign::CENTER, "\U000F05F1"); | |
} else { | |
it.printf(icon_x_2, y, id(font_icons_small), TextAlign::CENTER, "\U000F0130"); | |
} | |
it.printf(icon_x_2, y + icon_small/2 + y_pad, id(font_footer), TextAlign::CENTER, "Car"); | |
// Second Row | |
y += sensor_y_shift; | |
// Washer | |
if (id(washer).state) { | |
it.printf(icon_x_1, y, id(font_icons_small), TextAlign::CENTER, "\U000F072A"); | |
} else { | |
it.printf(icon_x_1, y, id(font_icons_small), TextAlign::CENTER, "\U000F11BD"); | |
} | |
it.printf(icon_x_1, y + icon_small/2 + y_pad, id(font_footer), TextAlign::CENTER, "Washer"); | |
// column 2 | |
// Dryer | |
if (id(dryer).state) { | |
it.printf(icon_x_2, y, id(font_icons_small), TextAlign::CENTER, "\U000F0917"); | |
} else { | |
it.printf(icon_x_2, y, id(font_icons_small), TextAlign::CENTER, "\U000F11BB"); | |
} | |
it.printf(icon_x_2, y + icon_small/2 + y_pad, id(font_footer), TextAlign::CENTER, "Dryer"); | |
// Third Row | |
y += sensor_y_shift; | |
it.printf(icon_x_1, y, id(font_value), TextAlign::CENTER, "%.0f", id(next_bin_days).state); | |
it.printf(icon_x_1, y + icon_small/2 + y_pad, id(font_footer), TextAlign::CENTER, "days til %s bin", id(next_bin).state.c_str()); | |
// column 2 | |
it.printf(icon_x_2, y, id(font_value), TextAlign::CENTER, "%.0f %%", id(landing_humidity).state); | |
it.printf(icon_x_2, y + icon_small/2 + y_pad, id(font_footer), TextAlign::CENTER, "Humidity"); | |
// Forth Row | |
y += sensor_y_shift; | |
it.printf(icon_x_1, y, id(font_icons_small), TextAlign::CENTER, "\U000F059C"); | |
it.printf(icon_x_1, y + icon_small/2 + y_pad, id(font_footer), TextAlign::CENTER, "%s", id(sunrise).state.c_str()); | |
it.printf(icon_x_2, y, id(font_icons_small), TextAlign::CENTER, "\U000F059B"); | |
it.printf(icon_x_2, y + icon_small/2 + y_pad, id(font_footer), TextAlign::CENTER, "%s", id(sunset).state.c_str()); | |
// Buttons | |
it.printf(x1n, button_5_y + icon_small/2 - 5, id(font_icons_small), TextAlign::BASELINE_LEFT, "\U000F0510"); | |
it.printf(x1n, button_4_y + icon_small/2 - 5, id(font_icons_small), TextAlign::BASELINE_LEFT, "\U000F1011"); | |
it.printf(x1n, button_3_y + icon_small/2 - 5, id(font_icons_small), TextAlign::BASELINE_LEFT, "\U000F00AC"); | |
// Vertical Divider | |
it.filled_rectangle(x1n + 70, button_5_y - icon_small / 2, div_thickness, icon_small * 3 + y_pad * 3); | |
// Footer | |
it.strftime(x_pad, yres-y_pad/2, id(font_footer), TextAlign::BASELINE_LEFT, "Updated: %H:%M", id(ntp).now()); | |
it.printf(xres-x_pad, yres-y_pad/2, id(font_footer), TextAlign::BASELINE_RIGHT, "%.2fV/%.0f%%", id(batt_volt).state, id(batt).state); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment