If you want ESPHome, then i dont think theres an alternative to display…
@nickrout - pasted the hardware that needs to be worked out, display screens are from Figma, nothing finished in ESPHome yet, but nothing too hard:
font:
- file: 'fonts/Roboto-Regular.ttf'
glyphs: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ°.:/+- ' #ABCDEFGHIJKLMNOPQRSTUVWXYZ°
id: regular
size: 24
- file: 'fonts/Roboto-Regular.ttf'
glyphs: ' -0123456789°Cecohi' #C
id: huge
size: 80
- file: 'fonts/Roboto-Regular.ttf'
glyphs: ' -0123456789°Cecohi' #C
id: medium
size: 60
- file: "fonts/fa-light.ttf"
glyphs: "\uf06c\uf7ae\uf79a\uf06d\uf1eb\ue137\uf011\ue487\uf293\ue00d\uf015\ue1b0\uf624\ue3b0\ue1a7\uf2dc\ue004\uf775\uf2f1\uf863\uf750\uf017"
display: # 240 x 320
- platform: st7789v
id: ${device_name}_display
model: Custom
width: 240
height: 320
offset_height: 0
offset_width: 0
###
eightbitcolor: true # OR IT BREAKS
### backlight_pin: GPIO35 ## breaks color
update_interval: 20s
cs_pin: GPIO34
dc_pin: GPIO13
reset_pin: GPIO21
on_page_change:
then:
- light.turn_on: ${device_name}_backlight
pages:
- id: page_boot
lambda: |-
int w = it.get_width();
int h = it.get_height();
auto icon = "\ue1a7"; // hand-wave //
auto color = id(gray);
it.print(w/2, h/2 , id(huge), random_color, TextAlign::CENTER, "hi");
it.print(w/2, w, id(symbol), random_color, TextAlign::CENTER, icon);
it.print(w/2, h - 20, id(regular), random_color, TextAlign::CENTER, "nESP");
- id: page_qr_wifi
lambda: |-
int w = it.get_width();
int h = it.get_height();
auto icon = "\uf1eb"; // \uf293 = bluetooth // \uf1eb = wifi
auto color = id(gray);
it.qr_code(w/3.5, h/4, id(qr_hotspot), random_color, 4);
it.print(w/2, w, id(symbol), random_color, TextAlign::CENTER, icon);
it.printf(w/2, h - 20, id(regular), random_color, TextAlign::CENTER, "nESP" );
- id: page_climate
lambda: |-
// canvas
int w = it.get_width();
int h = it.get_height();
int h2 = h / 2;
int w2 = w / 2;
int yheader = h / 3;
int yfooter = h - 20;
int radius = w2;
// font sizes
auto main_font = id(huge);
// text values
std::string huge_text = "x";
auto get_mode = id(hvac_mode).state;
auto get_hvac_action = id(hvac_action).state;
auto get_preset_mode = id(preset_mode).state;
// bools
auto dual = false;
// numeric
float get_target_temp_low = id(target_temp_low).state;
float get_target_temp_high = id(target_temp_high).state;
float get_target_temperature = id(target_temperature).state;
// check for dual mode
if (isnan(get_target_temperature) ){
dual = true;
get_target_temperature = round((get_target_temp_low + get_target_temp_high) / 2);
}
float get_current_temperature = id(current_temperature).state;
float minTemp = 15.0;
float maxTemp = 30.0;
// COLORS
auto color_neutral = id(graydark);
auto color_main = id(graydark);
auto color_accent = color_main;
auto color_background = id(black);
auto linecolor = id(graydarker);
// ICON
auto icon = "\uf624";
// hvac_mode (state)
if ( get_mode == "heat" ){
color_main = id(mode_heat);
icon = "\uf06d"; // fire
}
else if (get_mode == "cool") {
color_main = id(mode_cool);
icon = "\uf2dc"; // snowflake
}
else if (get_mode == "dry") {
color_main = id(mode_dry);
icon = "\uf750"; // droplet-percent
}
else if (get_mode == "fan_only") {
color_main = id(mode_fan);
icon = "\uf863"; // fan
}
else if (get_mode == "heat_cool") {
color_main = id(mode_heat_cool);
icon = "\uf2f1"; // rotate
}
// heat_cool hvac_action options: idle, cooling, heating
if (get_hvac_action == "idle") {
if (get_mode == "heat_cool"){
color_main = id(mode_heat_cool);
}
else if (get_mode == "heat"){
color_main = id(mode_heat);
}
else if (get_mode == "cool"){
color_main = id(mode_cool);
}
else{
color_main = id(mode_idle);
icon = "\uf017"; // clock
}
icon = "\uf017"; // clock
color_accent = id(mode_idle);
}
if ( (get_mode == "off") || (get_hvac_action == "off") ){
color_main = id(graydarker);
color_accent = id(graydark);
linecolor = id(graydarker);
icon = "\uf011"; // power-off
}
// Draw filled circle if not off or idle
if ( (get_hvac_action == "heating") || (get_hvac_action == "cooling") || (get_hvac_action == "drying") || (get_hvac_action == "fan" ) ) {
// stripeLength = stripeLength + w / 40;
radius = radius - w / 40;
it.filled_circle(w2, h2, w2, color_main);
linecolor = id(white);
color_accent = color_main;
it.print(w2, yheader, id(regular), color_background, TextAlign::CENTER, get_hvac_action.c_str() );
}
if (get_preset_mode == "eco") {
huge_text = "eco";
color_main = id(mode_eco);
} else {
char buffer[32];
float value = round(get_target_temperature);
if (value != 0 && !isnan(value) ){
snprintf(buffer, sizeof(buffer), "%.0f", value); // Convert float to a C-style string
huge_text = buffer;
}
}
if ( dual ){
main_font = id(medium);
float value_low = round(get_target_temp_low);
float value_high = round(get_target_temp_high);
std::string separator = " - ";
huge_text = std::to_string((int)value_low) + separator + std::to_string((int)value_high);
}
else {
float value = round(get_target_temperature);
if (value != 0 && !isnan(value) ){
huge_text = std::to_string((int)value);
}
}
// Draw current temperature at bottom
it.printf(w2, yfooter, id(regular), color_neutral, TextAlign::CENTER, "%.0f", get_current_temperature );
// dual gauge mode:
// it.printf(w2, yfooter, id(regular), color_main, TextAlign::CENTER, "%.0f - %.0f", get_target_temp_low, get_target_temp_high);
// invert colors for filled background
if ( (get_hvac_action == "heating") || (get_hvac_action == "cooling") || (get_hvac_action == "drying") || (get_hvac_action == "fan" ) ) {
auto hold = color_accent;
color_accent = color_background;
color_main = color_background;
color_background = hold;
}
// Draw icon
it.print(w2, w, id(symbol), color_main, TextAlign::CENTER, icon);
// draw set at center
it.print(w2, h2 , main_font, color_accent, TextAlign::CENTER, huge_text.c_str() );