esphome:
name: aztouch
platform: ESP32
board: esp32dev
# Enable logging
logger:
# Enable Home Assistant API
api:
services:
- service: play_rtttl
variables:
song_str: string
then:
- rtttl.play:
rtttl: !lambda 'return song_str;'
ota:
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# domain: !secret wifi_domain
ap:
ssid: "aztouch"
password: !secret fallpass
captive_portal:
spi:
clk_pin: 18
mosi_pin: 23
miso_pin: 19
i2c:
sda: 33
scl: 25
xpt2046:
id: touchscreen
cs_pin: 14
irq_pin: 27
update_interval: 50ms
report_interval: 1s
dimension_x: 240
dimension_y: 320
calibration_x_min: 237
calibration_x_max: 3873
calibration_y_min: 3800
calibration_y_max: 352
swap_x_y: false
on_state:
- lambda: |-
if (touched)
ESP_LOGI("cal", "x=%d, y=%d, x_raw=%d, y_raw=%d",
id(touchscreen).x,
id(touchscreen).y,
id(touchscreen).x_raw,
id(touchscreen).y_raw
);
globals:
- id: x
type: int
restore_value: no
initial_value: '0'
- id: y
type: int
restore_value: no
initial_value: '0'
- id: xx
type: int
restore_value: no
initial_value: '0'
- id: yy
type: int
restore_value: no
initial_value: '150'
substitutions:
icon_xy: '80x80'
image:
#0-default.png
- file: "images/0-default.png"
id: wpng_0
type: RGB24
resize: ${icon_xy}
#1-clear-night.png
- file: "images/1-clear-night.png"
id: wpng_1
type: RGB24
resize: ${icon_xy}
#2-cloudy.png
- file: "images/2-cloudy.png"
id: wpng_2
type: RGB24
resize: ${icon_xy}
#3-fog.png
- file: "images/3-fog.png"
id: wpng_3
type: RGB24
resize: ${icon_xy}
#4-hail.png
- file: "images/4-hail.png"
id: wpng_4
type: RGB24
resize: ${icon_xy}
#5-lightning.png
- file: "images/5-lightning.png"
id: wpng_5
type: RGB24
resize: ${icon_xy}
#6-lightning-rainy.png
- file: "images/6-lightning-rainy.png"
id: wpng_6
type: RGB24
resize: ${icon_xy}
#7-partlycloudy.png
- file: "images/7-partlycloudy.png"
id: wpng_7
type: RGB24
resize: ${icon_xy}
#8-pouring.png // rgb565
- file: "images/8-pouring.png"
id: wpng_8
type: RGB24
resize: ${icon_xy}
#9-rainy.png
- file: "images/9-rainy.png"
id: wpng_9
type: RGB24
resize: ${icon_xy}
#10-snowy.png
- file: "images/10-snowy.png"
id: wpng_10
type: RGB24
resize: ${icon_xy}
#11-snowy-rainy.png // TODO: renable-when-RGB565-supported
- file: "images/11-snowy-rainy.png"
id: wpng_11
type: RGB24
resize: ${icon_xy}
#12-sunny.png
- file: "images/12-sunny.png"
id: wpng_12
type: RGB24
resize: ${icon_xy}
#13-windy.png
- file: "images/13-windy.png"
id: wpng_13
type: RGB24
resize: ${icon_xy}
#14-windy-variant.png // TODO: renable-when-RGB565-supported
- file: "images/14-windy-variant.png"
id: wpng_14
type: RGB24
resize: ${icon_xy}
#15-exceptional.png // TODO: renable-when-RGB565-supported
- file: "images/15-exceptional.png"
id: wpng_15
type: RGB24
resize: ${icon_xy}
- file: "images/dany.png"
id: dany
type: RGB24
resize: 110x100
- file: "images/raffa.png"
id: raffa
type: RGB24
resize: 110x100
color:
- id: my_red
red: 100%
green: 0%
blue: 0%
- id: my_yellow
red: 100%
green: 100%
blue: 0%
- id: my_green
red: 0%
green: 100%
blue: 0%
- id: my_blue
red: 0%
green: 0%
blue: 100%
- id: my_gray
red: 50%
green: 50%
blue: 50%
font:
- file: 'fonts/Arial-Black.ttf'
id: font1
size: 20
- file: 'fonts/BebasNeue-Regular.ttf'
id: font2
size: 48
- file: 'fonts/Arial-Black.ttf'
id: font3
size: 30
- file: 'fonts/BebasNeue-Regular.ttf'
id: font4
size: 40
- file: 'fonts/Arial-Black.ttf'
id: font5
size: 22
- file: 'fonts/arial.ttf'
id: font6
size: 22
- file: 'fonts/BebasNeue-Regular.ttf'
id: font7
size: 80
- file: 'fonts/arial.ttf'
id: font8
size: 18
- file: 'fonts/Arial-Black.ttf'
id: my_font_small
size: 20
- file: 'fonts/materialdesignicons-webfont.ttf'
id: casa_font
size: 20
glyphs:
- "\U000F02DC" # A casa
- "\U000F0F9B" # Fuori Casa
- "\U000F059D" # Vento
- "\U000F050F" # Temperatura
- "\U000F04C5" # Pressione
- "\U000F058E" # Umidita
- file: 'fonts/materialdesignicons-webfont.ttf'
id: weather_font
size: 49
glyphs: [
# Weather
"", # mdi-weather-sunny
"", # mdi-weather-night
"", # mdi-weather-cloudy
"", # mdi-weather-pouring
"", # mdi-weather-snowy-rainy
"s", # mdi-weather-snowy-heavy
"", # mdi-weather-windy-variant
"", # mdi-weather-fog
"n", # mdi-weather-night-partly-cloudy
"", # mdi-weather-partly-cloudy
]
output:
- platform: ledc
pin: 15
id: gpio_32_backlight_pwm
inverted: true
- platform: ledc
pin: GPIO21
id: rtttl_out
# Define a monochromatic, dimmable light for the backlight
light:
- platform: monochromatic
output: gpio_32_backlight_pwm
name: "ILI9341 Display Backlight"
id: back_light
restore_mode: ALWAYS_ON
rtttl:
output: rtttl_out
time:
- platform: homeassistant
id: esptime
binary_sensor:
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_key_next
x_min: 196
x_max: 240
y_min: 245
y_max: 318
on_press:
- display.page.show_next: tft_ha
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_key_previous
x_min: 4
x_max: 80
y_min: 255
y_max: 315
on_press:
- display.page.show_previous: tft_ha
sensor:
- platform: homeassistant
id: weather_temperature
entity_id: sensor.esphome_current_weather_temperature
internal: true
- platform: homeassistant
id: gradicasa
entity_id: sensor.temperatura
internal: true
- platform: homeassistant
id: vento
entity_id: weather.casa
attribute: wind_speed
internal: true
- platform: homeassistant
id: vento_gradi
entity_id: weather.casa
attribute: wind_bearing
internal: true
text_sensor:
- platform: homeassistant
id: weather_location
entity_id: sensor.esphome_current_weather_location
internal: true
- platform: homeassistant
id: forecast_test
entity_id: weather.casa
attribute: forecast
name: Forecast test
internal: no
- platform: homeassistant
id: forecast1
name: Forecast1
entity_id: sensor.forecast1_hass
internal: true
- platform: homeassistant
id: forecast2
name: Forecast2
entity_id: sensor.forecast2_hass
internal: true
- platform: homeassistant
id: forecast3
name: Forecast3
entity_id: sensor.forecast3_hass
internal: true
- platform: homeassistant
id: weather_condition
entity_id: sensor.esphome_current_weather_condition
internal: true
on_value:
lambda: |-
//Icon
if (x == "clear-night")
{
id(tempo).publish_state("Notte serena");
}
else if (x == "cloudy")
{
id(tempo).publish_state("Nuvoloso");
}
else if (x == "fog")
{
id(tempo).publish_state("Nebbia");
}
else if (id(weather_condition).state == "hail")
{
id(tempo).publish_state("Grandine");
}
else if (id(weather_condition).state == "lightning")
{
id(tempo).publish_state("Fulmini");
}
else if (id(weather_condition).state == "lightning-rainy")
{
id(tempo).publish_state("Pioggia/Fulmini");
}
else if (id(weather_condition).state == "partlycloudy")
{
id(tempo).publish_state("Parz. nuvoloso");
}
else if (id(weather_condition).state == "pouring")
{
id(tempo).publish_state("Rovescio");
}
else if (id(weather_condition).state == "rainy")
{
id(tempo).publish_state("Pioggia");
}
else if (id(weather_condition).state == "snowy")
{
id(tempo).publish_state("Neve");
}
else if (id(weather_condition).state == "snowy-rainy")
{
id(tempo).publish_state("Neve/pioggia");
}
else if (id(weather_condition).state == "sunny")
{
id(tempo).publish_state("Soleggiato");;
}
else if (id(weather_condition).state == "windy")
{
id(tempo).publish_state("Vento");
}
else if (id(weather_condition).state == "windy-variant")
{
id(tempo).publish_state("Vento forte");
}
else if (id(weather_condition).state == "exceptional")
{
id(tempo).publish_state("Eccezionale");
}
else
{
id(tempo).publish_state("Nessun dato");
}
- platform: homeassistant
id: unit_of_measurement
entity_id: sensor.esphome_current_weather_temperature_units
internal: true
- platform: homeassistant
id: statod
entity_id: person.daniele
internal: true
- platform: homeassistant
id: stator
entity_id: person.raffa
internal: true
- platform: template
id: tempo
internal: true
- platform: homeassistant
id: w_fivedays
entity_id: sensor.weather_fivedays
display:
- platform: ili9341
model: TFT 2.4
cs_pin: 5
dc_pin: 4
led_pin: 15
reset_pin: 22
# rotation: 90
id: tft_ha
pages:
- id: page1
lambda: |-
if (id(weather_condition).state == "clear-night")
{
it.image(id(x), id(y), id(wpng_1));
}
else if (id(weather_condition).state == "cloudy")
{
it.image(id(x), id(y), id(wpng_2));
}
else if (id(weather_condition).state == "fog")
{
it.image(id(x), id(y), id(wpng_3));
}
else if (id(weather_condition).state == "hail")
{
it.image(id(x), id(y), id(wpng_4));
}
else if (id(weather_condition).state == "lightning")
{
it.image(id(x), id(y), id(wpng_5));
}
else if (id(weather_condition).state == "lightning-rainy")
{
it.image(id(x), id(y), id(wpng_6));
}
else if (id(weather_condition).state == "partlycloudy")
{
it.image(id(x), id(y), id(wpng_7));
}
else if (id(weather_condition).state == "pouring")
{
it.image(id(x), id(y), id(wpng_8));
}
else if (id(weather_condition).state == "rainy")
{
it.image(id(x), id(y), id(wpng_9));
}
else if (id(weather_condition).state == "snowy")
{
it.image(id(x), id(y), id(wpng_10));
}
else if (id(weather_condition).state == "snowy-rainy")
{
it.image(id(x), id(y), id(wpng_11));
}
else if (id(weather_condition).state == "sunny")
{
it.image(id(x), id(y), id(wpng_12));
}
else if (id(weather_condition).state == "windy")
{
it.image(id(x), id(y), id(wpng_13));
}
else if (id(weather_condition).state == "windy-variant")
{
it.image(id(x), id(y), id(wpng_14));
}
else if (id(weather_condition).state == "exceptional")
{
it.image(id(x), id(y), id(wpng_15));
}
else
{
it.image(id(x), id(y), id(wpng_0));
}
//Temperature
if (id(weather_temperature).has_state())
{
//Tempo
it.printf(0, (it.get_height()/3-15), id(font8), TextAlign::BASELINE_LEFT, "%s", id(tempo).state.c_str());
// it.printf(0, (it.get_height()/3-15), id(font8), TextAlign::BASELINE_LEFT, "%s", id(forecast_test)[1].state.c_str(), 'condition';
//Gradi
it.printf((it.get_width()/3+5), 10, id(font2), id(my_blue), TextAlign::TOP_LEFT, "%.0f°", id(weather_temperature).state);
}
//Location
if (id(weather_location).has_state())
{
it.printf((it.get_width()/3+5), 0, id(font8), TextAlign::TOP_LEFT, "%s", id(weather_location).state.c_str());
}
//Temperatura casa
if (id(gradicasa).has_state())
{
it.printf((it.get_width()-10), 0, id(font8), TextAlign::TOP_RIGHT, "Casa");
it.printf(it.get_width(), 10, id(font2), id(my_red), TextAlign::TOP_RIGHT, "%.0f°", id(gradicasa).state);
}
//Vento
if (id(vento).has_state())
{
it.printf((it.get_width()-60), (it.get_height()/3-15), id(casa_font), id(my_yellow), TextAlign::BASELINE_RIGHT, "\U000F059D");
it.printf(it.get_width(), (it.get_height()/3-15), id(font8), id(my_blue), TextAlign::BASELINE_RIGHT, "%.0f km/h", id(vento).state);
}
//Time
it.strftime(0, it.get_height(), id(font1), TextAlign::BASELINE_LEFT, "%H:%M:%S", id(esptime).now());
it.strftime(it.get_width(), it.get_height(), id(font1), TextAlign::BASELINE_RIGHT, "%d-%m-%Y", id(esptime).now());
//lines
it.line(0, (it.get_height()/3-5), it.get_width(), (it.get_height()/3-5));
//Forecast 1
if (id(forecast1).state == "clear-night")
{
it.image(id(xx), (it.get_height()/3), id(wpng_1));
}
else if (id(forecast1).state == "cloudy")
{
it.image(id(xx), (it.get_height()/3), id(wpng_2));
}
else if (id(forecast1).state == "fog")
{
it.image(id(xx), (it.get_height()/3), id(wpng_3));
}
else if (id(forecast1).state == "hail")
{
it.image(id(xx), (it.get_height()/3), id(wpng_4));
}
else if (id(forecast1).state == "lightning")
{
it.image(id(xx), (it.get_height()/3), id(wpng_5));
}
else if (id(forecast1).state == "lightning-rainy")
{
it.image(id(xx), (it.get_height()/3), id(wpng_6));
}
else if (id(forecast1).state == "partlycloudy")
{
it.image(id(xx), (it.get_height()/3), id(wpng_7));
}
else if (id(forecast1).state == "pouring")
{
it.image(id(xx), (it.get_height()/3), id(wpng_8));
}
else if (id(forecast1).state == "rainy")
{
it.image(id(xx), (it.get_height()/3), id(wpng_9));
}
else if (id(forecast1).state == "snowy")
{
it.image(id(xx), (it.get_height()/3), id(wpng_10));
}
else if (id(forecast1).state == "snowy-rainy")
{
it.image(id(xx), (it.get_height()/3), id(wpng_11));
}
else if (id(forecast1).state == "sunny")
{
it.image(id(xx), (it.get_height()/3), id(wpng_12));
}
else if (id(forecast1).state == "windy")
{
it.image(id(xx), (it.get_height()/3), id(wpng_13));
}
else if (id(forecast1).state == "windy-variant")
{
it.image(id(xx), (it.get_height()/3), id(wpng_14));
}
else if (id(forecast1).state == "exceptional")
{
it.image(id(xx), (it.get_height()/3), id(wpng_15));
}
else
{
it.image(id(xx), (it.get_height()/3), id(wpng_0));
}
- id: page2
lambda: |-
it.strftime(50, 10, id(font7), "%H:%M", id(esptime).now());
it.strftime(50, 80, id(font4), "%d/%m/%Y", id(esptime).now());
- id: page3
lambda: |-
it.image(0, 0, id(dany));
if (id(statod).state == "home")
{
it.printf(40, 100, id(casa_font), id(my_green), "\U000F02DC");
}
else
{
it.printf(40, 100, id(casa_font), id(my_red), "\U000F0F9B");
}
it.image(130, 0, id(raffa));
if (id(stator).state == "home")
{
it.printf(165, 100, id(casa_font), id(my_green), "\U000F02DC");
}
else
{
it.printf(165, 100, id(casa_font), id(my_red), "\U000F0F9B");
}
- id: page4
lambda: |-
//Temp
it.printf(0, 0, id(casa_font), id(my_red), "\U000F050F");
it.printf(40, 0, id(font4), id(my_red), "Temperatura");
//press
it.printf(0, 32, id(casa_font), id(my_red), "\U000F04C5");
it.printf(40, 32, id(font4), id(my_red), "Pressione");
//Umidita
it.printf(0, 64, id(casa_font), id(my_red), "\U000F058E");
it.printf(40, 64, id(font4), id(my_red), "Umidita");
//Vento
it.printf(0, 96, id(casa_font), id(my_red), "\U000F059D");
it.printf(40, 96, id(font4), id(my_red), "Vento");
- id: page5
lambda: |-
it.printf(0, 0, id(font1), id(forecast1).state.c_str());
- id: page6
lambda: |-
fivedays = id(w_fivedays).state;
//ESP_LOGD("%s", fivedays.c_str());
five.clear();
int count = 0;
int wx = 0; // start positio x
int wy = 0; // start position y
token = strtok (&fivedays[0],"#");
// this while splits the string (I believe, I "found" the code)
while (token != NULL)
{
five.push_back(token);
token = strtok (NULL, "#");
}
// here we loop the days
for ( std::string fiv : five ) {
it.rectangle(0, wy, 128, 59); // adds a border around the "day"
it.rectangle(1, wy+1, 126, 57);
str = "";
str = fiv;
//ESP_LOGD("test: ", "String to Vector: %s", str.c_str());
v.clear();
token = strtok (&str[0],";");
while (token != NULL)
{
v.push_back(token);
token = strtok (NULL, ";");
}
// this is the loop for each value in the "day"
for ( std::string s : v ) {
if(count == 0){
// Day (Mon/Tue...)
it.printf(wx +7, wy, id(my_font_small), "%s", s.c_str());
}else if(count == 1){
// Temperature
it.printf(wx +7, wy+18, id(my_font_small), "%s", s.c_str());
}else if(count == 2){
// Precipitation
it.printf(wx +7, wy+35, id(my_font_small), "%s", s.c_str());
}else if(count == 3){
// weather icon
it.printf(123, wy+5, id(weather_font), TextAlign::TOP_RIGHT, "%s", s.c_str());
}
//ESP_LOGD("test: ", "String to Vector: %s", s.c_str());
count += 1;
}
count = 0;
wy += 59; // move down 59 pixels and output next day
}
The relevant part is on page 6.