esphome / issues

Issue Tracker for ESPHome
https://esphome.io/
291 stars 36 forks source link

Platform xpt2046 and binary sensor platform touchscreen not working anymore #6429

Open TegameTD opened 1 day ago

TegameTD commented 1 day ago

The problem

Hi, I have several Aztouch devices that use that touchscreen platform, for years they have always worked even with esphome updates, I have just updated two of these devices from version 2024.6.6 to the latest available and in both devices the binary sensors configured for the touchscreen stopped working, downgrading solves the problem.

Here is the relevant part of my configuration:

#This enable the touch screen
touchscreen:
  platform: xpt2046
  id: xpt2046_touch
  cs_pin: 14 
  interrupt_pin: 27 
  update_interval: 50ms
  transform:
    mirror_x: false
    mirror_y: false
    swap_xy: true
  calibration: 
    x_min: 3575
    x_max: 368
    y_min: 3800
    y_max: 441
  #When the screen is touched turn on the backlight
  on_touch:
    - script.stop: backlight_timer
    - script.execute: backlight_timer
#  Uncomment for calibrations
    - lambda: |-
        ESP_LOGI("cal", "x=%d, y=%d, x_raw=%d, y_raw=%0d",
          touch.x,
          touch.y,
          touch.x_raw,
          touch.y_raw
           );
binary_sensor:

#Touch key minus
  - platform: touchscreen
    id: touch_key_minus
    x_min: 10
    x_max: 60
    y_min: 240
    y_max: 320
    on_press:
      - climate.control:
          id: termostato1
          target_temperature: !lambda return (id(termostato1).target_temperature - `0.5);

When I click the virtual button in the logs I see that x and y at the point where I touched are exactly inside the virtual square declared in the binary sensor but in fact it doesn't work, the binary sensor is not triggered. Do you know why? Is there anything I can do to fix it?

Thank You.

Which version of ESPHome has the issue?

2024.10.3

What type of installation are you using?

Home Assistant Add-on

Which version of Home Assistant has the issue?

No response

What platform are you using?

ESP32

Board

Azdelivery Aztouch

Component causing the issue

No response

Example YAML snippet

No response

Anything in the logs that might be useful for us?

No response

Additional information

No response

clydebarrow commented 1 day ago

I tested this and can't find an issue. You didn't show your display config - it matters. Also attach some logs showing the touch report.

TegameTD commented 12 hours ago

Now I'm out as soon as I can I'll send you log and complete configuration. However, I saw that by deactivating swap xy and reprogramming the keys with the "wrong" coordinates (I have the monitor in landscape mode) the key in question starts working again, strange that you haven't had the problem, maybe you don't use swap_xy? Last night I tried to update the third working aztouch to the latest version of esphome and that too stopped working without me having changed any code in the yaml, so we are at 3 out of 3 broken key setups, I don't think it's just a coincidence .

TegameTD commented 10 hours ago

Here the complete code:

esphome:
  name: termostato-meteo
  platform: ESP32
  board: esp32dev
  on_boot:

#If you want to start thermostat in heat mode when it loose power uncomment the bottom lines
#    - climate.control:
#        id: termostato1
#        mode: HEAT

#This command starts the backlight subsystem
    - script.execute: backlight_timer

#Substitutions
substitutions:
#Set here your entities
# Heater entity from Home Assistant. In my case, I used a Shelly 1v3 to control the gas heater's on/off status
#You can also use a relay connected to a gpio but I do not recommend it especially if the load is alternating current the absorption peaks could glue the contacts of the cheap relays.
#I also noticed that the electromagnetic peak sometimes crashes the esp32. Since we are talking about a delicated system like a gas heater, it is better to opt for a certified device.
  heater: switch.shelly_caldaia
# Weather entity from home assistant
  weather_entity: weather.casa
# Total consumption sensor imported from Home Assistant. I use a Shelly EM with two CT sensors. This first sensor measures the main phase of my home's electrical grid
  tc: sensor.consumo_totale_power
# Partial consumption entity, such as a washing machine, imported from Home Assistant. This second CT sensor measures the garage's electrical phase
  pc: sensor.consumo_cantina_power
#Weather now icon size
  icon_xy: '65x65'

# Enable logging
logger:
  logs:
    component: ERROR

# Enable Home Assistant API
api:
  services:
  # Receive sound from homeassistant as service (only buzzer rtttl)
    - service: play_rtttl
      variables:
        song_str: string
      then:
        - rtttl.play:
            rtttl: !lambda 'return song_str;'

# Buzzer
rtttl:
  output: rtttl_out

# This enable firmware upload via ota
ota:
  platform: esphome

#This is the wifi block connection, change your wifi credential in secrets.yaml before tryng a firmware upload
wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  ap:
    ssid: "Meteo-thermo"
    password: !secret fallpass 

# Enables the captive portal. If the ESP32 cannot connect to the existing WiFi network, it creates an access point with the 'Meteo-thermo' SSID.
# Users can connect to this AP and configure the WiFi credentials through the portal
captive_portal:

#This import arduinojson library for extract weather forecasts
json:

#This enable spi bus for diplay
spi:
 clk_pin: 18
 mosi_pin: 23
 miso_pin: 19

#This enable i2c bus for bme280 sensor
i2c:
  - id: bus_a
    sda: 32
    scl: 25

#This create the climate entity
climate:
  - platform: thermostat
    visual:
      min_temperature: 16 °C
      max_temperature: 30 °C
    name: Termostato
    id: termostato1
    sensor: temp_int
    min_heating_off_time: 30s
    min_heating_run_time: 30s
    min_idle_time: 30s
    #This service toggles the Shelly 1v3 actuator on and off.
    heat_action:
      homeassistant.service:
        service: switch.turn_on
        data: {entity_id: $heater}
    idle_action:
      homeassistant.service:
        service: switch.turn_off
        data: {entity_id: $heater}

#This enable the touch screen
touchscreen:
  platform: xpt2046
  id: xpt2046_touch
  cs_pin: 14 
  interrupt_pin: 27 
  update_interval: 50ms
  transform:
    mirror_x: false
    mirror_y: false
    swap_xy: true
  calibration: 
    x_min: 3575
    x_max: 368
    y_min: 3800
    y_max: 441
  #When the screen is touched turn on the backlight
  on_touch:
    - script.stop: backlight_timer
    - script.execute: backlight_timer
#  Uncomment for calibrations
    - lambda: |-
        ESP_LOGI("cal", "x=%d, y=%d, x_raw=%d, y_raw=%0d",
          touch.x,
          touch.y,
          touch.x_raw,
          touch.y_raw
           );

output:
  #Backlight pwm section
  - platform: ledc
    pin: 15
    id: backlight_pwm
    inverted: true
  #Buzzer
  - platform: ledc
    pin: GPIO21
    id: rtttl_out

# Define a monochromatic, dimmable light for the backlight
light:
  - platform: monochromatic
    output: backlight_pwm
    name: "Luce termostato"
    id: back_light
    restore_mode: ALWAYS_ON
    internal: true

#This is the script for turn off the backlight after some seconds of inactivity
script:
  id: backlight_timer
  then:
  - light.turn_on:
      id: back_light
      brightness: 100%
  - delay: 20s
  - light.turn_on:
      id: back_light
      brightness: 50%
  - delay: 40s
  - light.turn_off: back_light

#Import current time from Home Assistant
time:
  - platform: homeassistant
    id: esptime

#In my device i add a motion sensor for turn on the backlight automatically when i try to read monitor
binary_sensor:
  - platform: gpio
    pin: 
      number: 26
      mode: INPUT_PULLUP
    device_class: motion    
    id: movimento
    name: Movimento
    on_press:
      - script.stop: backlight_timer
      - script.execute: backlight_timer
# Import Heater entity from Home Assistant. In my case, I used a Shelly 1v3 to control the gas heater's on/off status
  - platform: homeassistant
    name: "Caldaia"
    entity_id: $heater
    id: sensor_caldaia
    internal: true
#Virtual touch buttons on display
#Touch key plus
  - platform: touchscreen
    id: touch_key_plus
    x_min: 190
    x_max: 240
    y_min: 240
    y_max: 320
    on_click:
      - climate.control:
          id: termostato1
          target_temperature: !lambda return (id(termostato1).target_temperature + 0.5);
      - rtttl.play: 'one short:d=4,o=5,b=100:16e6'
#Touch key minus
  - platform: touchscreen
    id: touch_key_minus
    x_min: 0
    x_max: 60
    y_min: 240
    y_max: 320
    on_click:
      - climate.control:
          id: termostato1
          target_temperature: !lambda return (id(termostato1).target_temperature - 0.5);
      - rtttl.play: 'one short:d=4,o=5,b=100:16e6'
#Touch key climate on/off
  - platform: touchscreen
    id: touch_key_climate
    x_min: 95
    x_max: 150
    y_min: 240
    y_max: 320
    on_click:
    #Thermostat on
    - min_length: 0ms
      max_length: 500ms
      then:
        - climate.control:
            id: termostato1
            mode: "HEAT"
        - rtttl.play: 'one short:d=4,o=5,b=100:16e6'
    #Thermostat off
    - min_length: 550ms
      max_length: 5000ms
      then:
        - climate.control:
            id: termostato1
            mode: "OFF"
        - rtttl.play: 'one short:d=4,o=5,b=100:16e6'

#Int sensor section import and declarations
sensor:
#Import external temperature
  - platform: homeassistant
    id: weather_temperature
    entity_id: $weather_entity
    attribute: temperature
    internal: true
#Import Wind
  - platform: homeassistant
    id: vento
    entity_id: $weather_entity
    attribute: wind_speed
    internal: true
#Import external Humidity
  - platform: homeassistant
    id: umidita_ext
    entity_id: $weather_entity
    attribute: humidity
    internal: true
#Bme280 internal sensor
  - platform: bme280_i2c
    address: 0x76
    temperature:
      name: "Temperatura"
      id: temp_int
      oversampling: 16x
    pressure:
      name: "Pressione"
      id: pressione_int
    humidity:
      name: "Umidita"
      id: umidita_int
    update_interval: 20s
#Shelly em sensor for my home total absorpion
#Total energy in kw/h
  - platform: homeassistant
    id: consumo_t
    entity_id: $tc
    internal: true
#Shelly em washing machine absorpion
#Garage energy in kw/h
  - platform: homeassistant
    id: consumo_c
    entity_id: $pc
    internal: true

#String sensor import
text_sensor:
#Import Location
  - platform: homeassistant
    id: weather_location
    entity_id: $weather_entity
    attribute: friendly_name
    internal: true
#Import weather condition now
  - platform: homeassistant
    id: weather_condition
    entity_id: $weather_entity
    internal: true
#Import 5 day forecast
  - platform: homeassistant
    id: forecast_5
    entity_id: sensor.previsioni
    attribute: forecast
    internal: yes
#Import Sun state
  - platform: homeassistant
    id: sun_state
    entity_id: sun.sun
    internal: true

#Weather now images
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
  - 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
  - file: "images/14-windy-variant.png"
    id: wpng_14
    type: RGB24
    resize: ${icon_xy}
#15-exceptional.png
  - file: "images/15-exceptional.png"
    id: wpng_15
    type: RGB24
    resize: ${icon_xy}

#Color section for display rendering
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 declaration
font:
#font date
  - file: 'fonts/Arial-Black.ttf'
    id: font1
    size: 18
#Time
  - file: 'fonts/BebasNeue-Regular.ttf'
    id: font_clock
    size: 40
#Temperature
  - file: 'fonts/BebasNeue-Regular.ttf'
    id: font2
    size: 45
#Location sensors
  - file: 'fonts/arial.ttf'
    id: font8
    size: 18
# Day name in forecast
  - file: 'fonts/Arial-Black.ttf'
    id: font_small
    size: 12
#Forecast fonts
  - file: 'fonts/arial.ttf'
    id: font_small_1
    size: 12
#Font icon various sensor
  - file: 'fonts/materialdesignicons-webfont.ttf'
    id: sensor_font
    size: 18
    glyphs:
      - "\U000F059D" # Wind
      - "\U000F050F" # Temperature
      - "\U000F04C5" # Pression
      - "\U000F058E" # Humidity
      - "\U000F0238" # Fire
      - "\U000F0F55" # Home thermometer
#Big icons other home stuff
  - file: 'fonts/materialdesignicons-webfont.ttf'
    id: home_font
    size: 52
    glyphs:
      - "\U000F02DC" # At home
      - "\U000F0F9B" # Outside home
      - "\U000F0238" # Fire
      - "\U000F072A" # Washing machine on
      - "\U000F11BD" # Washing machine off
      - "\U000F0100" # Camera on
      - "\U000F05DF" # Camera off
      - "\U000F0241" # Flash
      - "\U000F0EF7" # Flash alert
      - "\U000F06D0" # Diocane
      - "\U000F0425" # OFF
      - "\U000F0415" # Plus
      - "\U000F0374" # Minus
#Forecast icons
  - file: 'fonts/materialdesignicons-webfont.ttf'
    id: weather_font
    size: 50
    glyphs:
      - "\U000F0590" # weather-cloudy
      - "\U000F0F2F" # weather-cloudy-alert
      - "\U000F0E6E" # weather-cloudy-arrow-right
      - "\U000F0591" # weather-fog
      - "\U000F0592" # weather-hail
      - "\U000F0F30" # weather-hazy
      - "\U000F0898" # weather-hurricane
      - "\U000F0593" # weather-lightning
      - "\U000F067E" # weather-lightning-rainy
      - "\U000F0594" # weather-night
      - "\U000F0F31" # weather-night-partly-cloudy
      - "\U000F0595" # weather-partly-cloudy
      - "\U000F0F32" # weather-partly-lightning
      - "\U000F0F33" # weather-partly-rainy
      - "\U000F0F34" # weather-partly-snowy
      - "\U000F0F35" # weather-partly-snowy-rainy
      - "\U000F0596" # weather-pouring
      - "\U000F0597" # weather-rainy
      - "\U000F0598" # weather-snowy
      - "\U000F0F36" # weather-snowy-heavy
      - "\U000F067F" # weather-snowy-rainy
      - "\U000F0599" # weather-sunny
      - "\U000F0F37" # weather-sunny-alert
      - "\U000F14E4" # weather-sunny-off
      - "\U000F059A" # weather-sunset
      - "\U000F059B" # weather-sunset-down
      - "\U000F059C" # weather-sunset-up
      - "\U000F0F38" # weather-tornado
      - "\U000F059D" # weather-windy
      - "\U000F059E" # weather-windy-variant

#This enable the lcd display and relative lambda program
#I addedd some map for helping translate some section like map condition and days of week
display:
  - platform: ili9xxx
    model: TFT 2.4
    cs_pin: 5 
    dc_pin: 4  
    reset_pin: 22 
    rotation: 90
    id: tft_ha
    invert_colors: false
    pages:
      - id: page1
        lambda: |-
         //Map icons//
         std::map<std::string, image::Image *> imgDict;
         imgDict["clear-night"] = id(wpng_1);
         imgDict["cloudy"] = id(wpng_2);
         imgDict["fog"] = id(wpng_3);
         imgDict["hail"] = id(wpng_4);
         imgDict["lightning"] = id(wpng_5);
         imgDict["lightning-rainy"] = id(wpng_6);
         imgDict["partlycloudy"] = id(wpng_7);
         imgDict["pouring"] = id(wpng_8);
         imgDict["rainy"] = id(wpng_9);
         imgDict["snowy"] = id(wpng_10);
         imgDict["snowy-rainy"] = id(wpng_11);
         imgDict["sunny"] = id(wpng_12);
         imgDict["windy"] = id(wpng_13);
         imgDict["windy-variant"] = id(wpng_14);
         imgDict["exceptional"] = id(wpng_15);
         imgDict[""] = id(wpng_0);

         //Map conditions//
         std::map<std::string, const char *> conDict;
         conDict["clear-night"] = "Notte serena";
         conDict["cloudy"] = "Nuvoloso";
         conDict["fog"] = "Nebbia";
         conDict["hail"] = "Nevischio";
         conDict["lightning"] = "Fulmini";
         conDict["lightning-rainy"] = "Fulmini/pioggia";
         conDict["partlycloudy"] = "Parz. Nuv.";
         conDict["pouring"] = "Rovescio";
         conDict["rainy"] = "Pioggia";
         conDict["snowy"] = "Neve";
         conDict["snowy-rainy"] = "Neve/pioggia";
         conDict["sunny"] = "Sereno";
         conDict["windy"] = "Vento";
         conDict["windy-variant"] = "Vento forte";
         conDict["exceptional"] = "Eccezionale";
         conDict[""] = "Sconosciuto";

         //Map weather fonts//
         std::map<std::string, const char *> fonDict;
         fonDict["clear-night"] = "\U000F0594";
         fonDict["cloudy"] = "\U000F0590";
         fonDict["fog"] = "\U000F0591";
         fonDict["hail"] = "\U000F0592";
         fonDict["lightning"] = "\U000F0593";
         fonDict["lightning-rainy"] = "\U000F067E";
         fonDict["partlycloudy"] = "\U000F0595";
         fonDict["pouring"] = "\U000F0596";
         fonDict["rainy"] = "\U000F0597";
         fonDict["snowy"] = "\U000F0598";
         fonDict["snowy-rainy"] = "\U000F067F";
         fonDict["sunny"] = "\U000F0599";
         fonDict["windy"] = "\U000F059D";
         fonDict["windy-variant"] = "\U000F059E";
         fonDict["exceptional"] = "";

         //Map days of week//
         std::map<int, const char *> dayDict;
         dayDict[1] = "Dom";
         dayDict[2] = "Lun";
         dayDict[3] = "Mar";
         dayDict[4] = "Mer";
         dayDict[5] = "Gio";
         dayDict[6] = "Ven";
         dayDict[7] = "Sab";

         //Map days of week extended//
         std::map<int, const char *> dayDict_ext;
         dayDict_ext[1] = "Domenica";
         dayDict_ext[2] = "Lunedi";
         dayDict_ext[3] = "Martedi";
         dayDict_ext[4] = "Mercoledi";
         dayDict_ext[5] = "Giovedi";
         dayDict_ext[6] = "Venerdi";
         dayDict_ext[7] = "Sabato";

         //Map month//
         std::map<int, const char *> monDict;
         monDict[1] = "Gennaio";
         monDict[2] = "Febbraio";
         monDict[3] = "Marzo";
         monDict[4] = "Aprile";
         monDict[5] = "Maggio";
         monDict[6] = "Giugno";
         monDict[7] = "Luglio";
         monDict[8] = "Agosto";
         monDict[9] = "Settembre";
         monDict[10] = "Ottobre";
         monDict[11] = "Novembre";
         monDict[12] = "Dicembre";

         //Today weekday as number
         int day = id(esptime).now().day_of_week;
         //Month as number
         auto month = id(esptime).now().month;
         //Day of month as number
         auto dom = id(esptime).now().day_of_month;

         //Position Y 1 day of week, day of month, month
         int h1 = 0;
         //Position Y 2 time
         int h2 = 5;
         //Position Y 3 weather icons, location, home name
         int h3 = 18;
         //Position Y 4 temperature ext, int, 
         int h4 = 30;
         //Position Y 6 humidity ext, int
         int h6 = 50;
         //Position Y 7 wind, Pressure int
         int h7 = 65;
         //Position Y wy forecast
         int wy = 85;
         //Position X wx forecast
         int wx = 32;
         //Position X 1 Weather location name, outside temp
         int w1 = 70;
         //Position Y 2 Outside sensor icon
         int w2 = 115;  
         //Position X 3 Home name, home temperature
         int w3 = 200;
         //Position X 4 Home sensor icon
         int w4 = 250;

         //Begin print to screen
         // Time
         it.printf((it.get_width() / 2), h1, id(font1), id(my_gray), TextAlign::TOP_CENTER, "%s %i %s", dayDict[day], dom, monDict[month]);
         it.strftime(it.get_width(), h2, id(font_clock), TextAlign::TOP_RIGHT, "%H:%M", id(esptime).now());

         // Weather now if it's night and sunny for display night icon
         if (id(sun_state).state == "below_horizon" && id(weather_condition).state == "sunny") {
            // Icon of weather condition night
            it.image(0, h3, imgDict["clear-night"]);
            // Translated weather condition state as text
            it.printf(0, h1, id(font_small), id(my_gray), "%s", conDict["clear-night"]);
         } else {
            // Check if weather_condition has a known state in the dictionary to prevent a crash
            if (conDict.count(id(weather_condition).state) > 0) {
               // Weather now for other cases
               // Icon of weather condition now
               it.image(0, h3, imgDict[id(weather_condition).state]);
               // Translated weather condition state as text
               it.printf(0, h1, id(font_small), id(my_gray), "%s", conDict[id(weather_condition).state]);
            } else {
               // This is printed in case weather_condition has another or unknown state
               it.image(0, h3, imgDict["exceptional"]);
               // Translated weather condition state as text
               it.printf(0, h1, id(font_small), id(my_gray), "%s", conDict["exceptional"]);
            }
         }

         // Outside temp
         if (id(weather_temperature).has_state()) {
            it.printf(w1, h4, id(font2), id(my_blue), "%.0f°", id(weather_temperature).state);
         }

         // Location
         if (id(weather_location).has_state()) {
            it.printf(w1, h3, id(font8), id(my_blue), "%s", id(weather_location).state.c_str());
         }

         // Inside temp
         if (id(temp_int).has_state()) {
            it.printf(w3, h3, id(font8), id(my_red), "Casa");
            it.printf(w3, h4, id(font2), id(my_red), "%.0f°", id(temp_int).state);
         }

         // Today wind
         if (id(vento).has_state()) {
            it.printf(w2, h7, id(sensor_font), "\U000F059D");
            it.printf(w2 + 20, h7, id(font8), id(my_gray), "%.0f km/h", id(vento).state);
         }

         // External humidity
         if (id(umidita_ext).has_state()) {
            it.printf(w2, h6, id(sensor_font), "\U000F058E");
            it.printf(w2 + 20, h6, id(font8), id(my_gray), "%.0f%%", id(umidita_ext).state);
         }

         // Internal humidity
         if (id(umidita_int).has_state()) {
            it.printf(w4, h6, id(sensor_font), "\U000F058E");
            it.printf(it.get_width(), h6, id(font8), id(my_gray), TextAlign::TOP_RIGHT, "%.0f%%", id(umidita_int).state);
         }

         // Atmospheric pressure
         if (id(pressione_int).has_state()) {
            it.printf(w4, h7, id(sensor_font), "\U000F04C5");
            it.printf(it.get_width(), h7, id(font8), id(my_gray), TextAlign::TOP_RIGHT, "%.0fb", id(pressione_int).state);
         }

         // Imported forecast json deserialization
         if (id(forecast_5).has_state()) {
            //ESP_LOGD("JSON", "Received: %s", id(forecast_5).state.c_str());
            int wxx = 0;
            int wyy = 0;
            int forday = 1;
            DynamicJsonDocument doc(2048);
            deserializeJson(doc, (id(forecast_5).state.c_str()));
            JsonArray root = doc.as<JsonArray>();
            for (int i = 0; i <= 3; ++i) {
               JsonObject root_x = root[i];
               if (i == 0) {
                     wxx = wx;
                     wyy = wy;
                     forday = (id(esptime).now().day_of_week + 1);
               }
               if (forday == 8) {
                     forday = 1;
               }
               // Day 3-4 go down
               // if (i == 2) {wyy += 38;}
               // if (i == 2) {wxx = 0;}
               std::string root_0_condition = root_x["condition"];
               float root_0_precipitation = root_x["precipitation"];
               float root_0_temperature = root_x["temperature"];
               float root_0_templow = root_x["templow"];

               // Print to screen
               // Translated day
               it.printf(wxx, wyy, id(font_small), id(my_green), TextAlign::TOP_CENTER, "%s", dayDict_ext[forday]);
               // Icon condition
               if (fonDict.count(root_0_condition) > 0) {
                     it.printf(wxx, wyy + 12, id(weather_font), TextAlign::TOP_CENTER, "%s", fonDict[root_0_condition.c_str()]);
               }
               // Temp max
               it.printf(wxx, wyy + 60, id(font_small_1), TextAlign::TOP_CENTER, "max %.0f°", root_0_temperature);
               // Temp min
               it.printf(wxx, wyy + 70, id(font_small_1), TextAlign::TOP_CENTER, "min %.0f°", root_0_templow);
               // Rain in mm
               it.printf(wxx, wyy + 80, id(font_small_1), TextAlign::TOP_CENTER, "%.0f mm", root_0_precipitation);
               // lines
               it.line(0, wy, it.get_width(), wy);
               it.line(0, wy + 95, it.get_width(), wy + 95);
               wxx += 85;
               forday += 1;
            }
         }
         // Heater icon
         if ((id(termostato1).mode) == 0) {
            it.printf((it.get_width() / 2), (it.get_height() - 15), id(home_font), id(my_gray), TextAlign::BASELINE_CENTER, "\U000F0425");
         } else {
            if (id(sensor_caldaia).state) {
               it.printf((it.get_width() / 2), (it.get_height() - 15), id(home_font), id(my_red), TextAlign::BASELINE_CENTER, "\U000F0238");
            } else {
               it.printf((it.get_width() / 2), (it.get_height() - 15), id(home_font), id(my_gray), TextAlign::BASELINE_CENTER, "\U000F0238");
            }
         }

         // Display thermostat desired temperature
         it.printf((it.get_width() / 2), it.get_height(), id(font8), id(my_red), TextAlign::BASELINE_CENTER, "%.1f°", id(termostato1).target_temperature);

         // When the motion sensor sees something, draw 2 eyes
         if (id(movimento).state) {
            it.printf(it.get_width(), it.get_height(), id(home_font), id(my_red), TextAlign::BASELINE_RIGHT, "\U000F06D0");
            it.printf(0, it.get_height(), id(home_font), id(my_red), TextAlign::BASELINE_LEFT, "\U000F06D0");
         } else {
            // Plus Key
            it.printf(it.get_width(), it.get_height(), id(home_font), id(my_gray), TextAlign::BASELINE_RIGHT, "\U000F0415");
            // Minus key
            it.printf(0, it.get_height(), id(home_font), id(my_gray), TextAlign::BASELINE_LEFT, "\U000F0374");
         }

         // Total absorption icon and value
         if (id(consumo_t).has_state()) {
            if (id(consumo_t).state < 2800) {
               it.printf((it.get_width() / 2 - 65), (it.get_height() - 15), id(home_font), id(my_gray), TextAlign::BASELINE_CENTER, "\U000F0241");
               it.printf((it.get_width() / 2 - 65), it.get_height(), id(font8), id(my_blue), TextAlign::BASELINE_CENTER, "%.0f W", id(consumo_t).state);
            } else {
               it.printf((it.get_width() / 2 - 65), (it.get_height() - 15), id(home_font), id(my_red), TextAlign::BASELINE_CENTER, "\U000F0241");
               it.printf((it.get_width() / 2 - 65), it.get_height(), id(font8), id(my_red), TextAlign::BASELINE_CENTER, "%.0f W", id(consumo_t).state);
            }
         }

         // Washing machine status and absorption value
         if (id(consumo_c).has_state()) {
            if (id(consumo_c).state > 20) {
               it.printf((it.get_width() / 2 + 65), (it.get_height() - 15), id(home_font), id(my_red), TextAlign::BASELINE_CENTER, "\U000F072A");
               it.printf((it.get_width() / 2 + 65), it.get_height(), id(font8), id(my_red), TextAlign::BASELINE_CENTER, "%.0f W", id(consumo_c).state);
            } else {
               it.printf((it.get_width() / 2 + 65), (it.get_height() - 15), id(home_font), id(my_gray), TextAlign::BASELINE_CENTER, "\U000F11BD");
               it.printf((it.get_width() / 2 + 65), it.get_height(), id(font8), id(my_blue), TextAlign::BASELINE_CENTER, "%.0f W", id(consumo_c).state);
            }
         }

Here the log:

INFO ESPHome 2024.10.3
INFO Reading configuration /root/config/termostato-meteo-git.yaml...
WARNING GPIO15 is a strapping PIN and should only be used for I/O with care.
Attaching external pullup/down resistors to strapping pins can cause unexpected failures.
See https://esphome.io/guides/faq.html#why-am-i-getting-a-warning-about-strapping-pins
INFO Detected timezone 'Europe/Rome'
WARNING GPIO5 is a strapping PIN and should only be used for I/O with care.
Attaching external pullup/down resistors to strapping pins can cause unexpected failures.
See https://esphome.io/guides/faq.html#why-am-i-getting-a-warning-about-strapping-pins
INFO Starting log output from 192.168.1.15 using esphome API
INFO Successfully connected to termostato-meteo @ 192.168.1.15 in 0.068s
INFO Successful handshake with termostato-meteo @ 192.168.1.15 in 0.045s
[18:24:03][I][app:100]: ESPHome version 2024.10.2 compiled on Oct 27 2024, 20:57:26
[18:24:03][C][wifi:600]: WiFi:
[18:24:03][C][wifi:428]:   Local MAC: 24:6F:28:7B:BD:34
[18:24:03][C][wifi:433]:   SSID: [redacted]
[18:24:03][C][wifi:436]:   IP Address: 192.168.1.15
[18:24:03][C][wifi:440]:   BSSID: [redacted]
[18:24:03][C][wifi:441]:   Hostname: 'termostato-meteo'
[18:24:03][C][wifi:443]:   Signal strength: -77 dB ▂▄▆█
[18:24:03][C][wifi:447]:   Channel: 1
[18:24:03][C][wifi:448]:   Subnet: 255.255.255.0
[18:24:03][C][wifi:449]:   Gateway: 192.168.1.1
[18:24:03][C][wifi:450]:   DNS1: 192.168.1.1
[18:24:03][C][wifi:451]:   DNS2: 0.0.0.0
[18:24:03][C][logger:185]: Logger:
[18:24:03][C][logger:186]:   Level: DEBUG
[18:24:03][C][logger:188]:   Log Baud Rate: 115200
[18:24:03][C][logger:189]:   Hardware UART: UART0
[18:24:03][C][logger:193]:   Level for 'component': ERROR
[18:24:03][C][spi:064]: SPI bus:
[18:24:03][C][spi:065]:   CLK Pin: GPIO18
[18:24:03][C][spi:066]:   SDI Pin: GPIO19
[18:24:03][C][spi:067]:   SDO Pin: GPIO23
[18:24:03][C][spi:072]:   Using HW SPI: SPI
[18:24:03][C][i2c.arduino:071]: I2C Bus:
[18:24:03][C][i2c.arduino:072]:   SDA Pin: GPIO32
[18:24:03][C][i2c.arduino:073]:   SCL Pin: GPIO25
[18:24:03][C][i2c.arduino:074]:   Frequency: 50000 Hz
[18:24:03][C][i2c.arduino:086]:   Recovery: bus successfully recovered
[18:24:03][I][i2c.arduino:096]: Results from i2c bus scan:
[18:24:03][I][i2c.arduino:102]: Found i2c device at address 0x76
[18:24:03][C][ledc.output:180]: LEDC Output:
[18:24:03][C][ledc.output:181]:   Pin GPIO15
[18:24:03][C][ledc.output:182]:   LEDC Channel: 0
[18:24:03][C][ledc.output:183]:   PWM Frequency: 1000.0 Hz
[18:24:03][C][ledc.output:184]:   Phase angle: 0.0°
[18:24:03][C][ledc.output:185]:   Bit depth: 16
[18:24:03][C][ledc.output:180]: LEDC Output:
[18:24:03][C][ledc.output:181]:   Pin GPIO21
[18:24:03][C][ledc.output:182]:   LEDC Channel: 1
[18:24:03][C][ledc.output:183]:   PWM Frequency: 1000.0 Hz
[18:24:03][C][ledc.output:184]:   Phase angle: 0.0°
[18:24:03][C][ledc.output:185]:   Bit depth: 16
[18:24:03][C][gpio.binary_sensor:015]: GPIO Binary Sensor 'Movimento'
[18:24:03][C][gpio.binary_sensor:015]:   Device Class: 'motion'
[18:24:03][C][gpio.binary_sensor:016]:   Pin: GPIO26
[18:24:03][C][ili9xxx:094]: ili9xxx
[18:24:03][C][ili9xxx:094]:   Rotations: 90 °
[18:24:03][C][ili9xxx:094]:   Dimensions: 320px x 240px
[18:24:03][C][ili9xxx:095]:   Width Offset: 0
[18:24:03][C][ili9xxx:096]:   Height Offset: 0
[18:24:03][C][ili9xxx:105]:   Color mode: 8bit 332 mode
[18:24:03][C][ili9xxx:111]:   Data rate: 40MHz
[18:24:03][C][ili9xxx:113]:   Reset Pin: GPIO22
[18:24:03][C][ili9xxx:114]:   CS Pin: GPIO5
[18:24:03][C][ili9xxx:115]:   DC Pin: GPIO4
[18:24:03][C][ili9xxx:117]:   Color order: BGR
[18:24:03][C][ili9xxx:118]:   Swap_xy: NO
[18:24:03][C][ili9xxx:119]:   Mirror_x: YES
[18:24:03][C][ili9xxx:120]:   Mirror_y: NO
[18:24:03][C][ili9xxx:121]:   Invert colors: NO
[18:24:03][C][ili9xxx:126]:   Update Interval: 1.0s
[18:24:03][C][light:103]: Light 'Luce termostato'
[18:24:03][C][light:105]:   Default Transition Length: 1.0s
[18:24:03][C][light:106]:   Gamma Correct: 2.80
[18:24:03][C][rtttl:029]: Rtttl
[18:24:03][C][thermostat.climate:1296]: Thermostat 'Termostato'
[18:24:03][C][thermostat.climate:1301]:   Start-up Delay Enabled: NO
[18:24:03][C][thermostat.climate:1317]:   Heating Parameters:
[18:24:03][C][thermostat.climate:1318]:     Deadband: 0.5°C
[18:24:03][C][thermostat.climate:1319]:     Overrun: 0.5°C
[18:24:03][C][thermostat.climate:1326]:     Minimum Off Time: 30s
[18:24:03][C][thermostat.climate:1328]:     Minimum Run Time: 30s
[18:24:03][C][thermostat.climate:1343]:   Minimum Idle Time: 30s
[18:24:03][C][thermostat.climate:1344]:   Supports AUTO: NO
[18:24:03][C][thermostat.climate:1345]:   Supports HEAT/COOL: NO
[18:24:03][C][thermostat.climate:1346]:   Supports COOL: NO
[18:24:03][C][thermostat.climate:1347]:   Supports DRY: NO
[18:24:03][C][thermostat.climate:1348]:   Supports FAN_ONLY: NO
[18:24:03][C][thermostat.climate:1350]:   Supports FAN_ONLY_ACTION_USES_FAN_MODE_TIMER: NO
[18:24:03][C][thermostat.climate:1351]:   Supports FAN_ONLY_COOLING: NO
[18:24:03][C][thermostat.climate:1356]:   Supports FAN_WITH_HEATING: NO
[18:24:03][C][thermostat.climate:1358]:   Supports HEAT: YES
[18:24:03][C][thermostat.climate:1359]:   Supports FAN MODE ON: NO
[18:24:03][C][thermostat.climate:1360]:   Supports FAN MODE OFF: NO
[18:24:03][C][thermostat.climate:1361]:   Supports FAN MODE AUTO: NO
[18:24:03][C][thermostat.climate:1362]:   Supports FAN MODE LOW: NO
[18:24:03][C][thermostat.climate:1363]:   Supports FAN MODE MEDIUM: NO
[18:24:03][C][thermostat.climate:1364]:   Supports FAN MODE HIGH: NO
[18:24:03][C][thermostat.climate:1365]:   Supports FAN MODE MIDDLE: NO
[18:24:03][C][thermostat.climate:1366]:   Supports FAN MODE FOCUS: NO
[18:24:03][C][thermostat.climate:1367]:   Supports FAN MODE DIFFUSE: NO
[18:24:03][C][thermostat.climate:1368]:   Supports FAN MODE QUIET: NO
[18:24:04][C][thermostat.climate:1369]:   Supports SWING MODE BOTH: NO
[18:24:04][C][thermostat.climate:1370]:   Supports SWING MODE OFF: NO
[18:24:04][C][thermostat.climate:1371]:   Supports SWING MODE HORIZONTAL: NO
[18:24:04][C][thermostat.climate:1372]:   Supports SWING MODE VERTICAL: NO
[18:24:04][C][thermostat.climate:1373]:   Supports TWO SET POINTS: NO
[18:24:04][C][thermostat.climate:1375]:   Supported PRESETS: 
[18:24:04][C][thermostat.climate:1383]:   Supported CUSTOM PRESETS: 
[18:24:04][C][thermostat.climate:1391]:   On boot, restore from: MEMORY
[18:24:04][C][xpt2046:062]: XPT2046:
[18:24:04][C][xpt2046:064]:   IRQ Pin: GPIO27
[18:24:04][C][xpt2046:065]:   X min: 368
[18:24:04][C][xpt2046:066]:   X max: 3575
[18:24:04][C][xpt2046:067]:   Y min: 441
[18:24:04][C][xpt2046:068]:   Y max: 3800
[18:24:04][C][xpt2046:070]:   Swap X/Y: YES
[18:24:04][C][xpt2046:071]:   Invert X: YES
[18:24:04][C][xpt2046:072]:   Invert Y: YES
[18:24:04][C][xpt2046:074]:   threshold: 400
[18:24:04][C][xpt2046:076]:   Update Interval: 0.050s
[18:24:04][C][homeassistant.time:010]: Home Assistant Time:
[18:24:04][C][homeassistant.time:011]:   Timezone: 'CET-1CEST,M3.5.0,M10.5.0/3'
[18:24:04][C][bme280_i2c.sensor:025]:   Address: 0x76
[18:24:04][C][bme280.sensor:182]: BME280:
[18:24:04][C][bme280.sensor:194]:   IIR Filter: OFF
[18:24:04][C][bme280.sensor:195]:   Update Interval: 20.0s
[18:24:04][C][bme280.sensor:197]:   Temperature 'Temperatura'
[18:24:04][C][bme280.sensor:197]:     Device Class: 'temperature'
[18:24:04][C][bme280.sensor:197]:     State Class: 'measurement'
[18:24:04][C][bme280.sensor:197]:     Unit of Measurement: '°C'
[18:24:04][C][bme280.sensor:197]:     Accuracy Decimals: 1
[18:24:04][C][bme280.sensor:198]:     Oversampling: 16x
[18:24:04][C][bme280.sensor:199]:   Pressure 'Pressione'
[18:24:04][C][bme280.sensor:199]:     Device Class: 'pressure'
[18:24:04][C][bme280.sensor:199]:     State Class: 'measurement'
[18:24:04][C][bme280.sensor:199]:     Unit of Measurement: 'hPa'
[18:24:04][C][bme280.sensor:199]:     Accuracy Decimals: 1
[18:24:04][C][bme280.sensor:200]:     Oversampling: 16x
[18:24:04][C][bme280.sensor:201]:   Humidity 'Umidita'
[18:24:04][C][bme280.sensor:201]:     Device Class: 'humidity'
[18:24:04][C][bme280.sensor:201]:     State Class: 'measurement'
[18:24:04][C][bme280.sensor:201]:     Unit of Measurement: '%'
[18:24:04][C][bme280.sensor:201]:     Accuracy Decimals: 1
[18:24:04][C][bme280.sensor:202]:     Oversampling: 16x
[18:24:04][C][psram:020]: PSRAM:
[18:24:04][C][psram:021]:   Available: NO
[18:24:04][C][captive_portal:089]: Captive Portal:
[18:24:04][C][mdns:116]: mDNS:
[18:24:04][C][mdns:117]:   Hostname: termostato-meteo
[18:24:04][C][esphome.ota:073]: Over-The-Air updates:
[18:24:04][C][esphome.ota:074]:   Address: termostato-meteo.local:3232
[18:24:04][C][esphome.ota:075]:   Version: 2
[18:24:04][C][safe_mode:018]: Safe Mode:
[18:24:04][C][safe_mode:020]:   Boot considered successful after 60 seconds
[18:24:04][C][safe_mode:021]:   Invoke after 10 boot attempts
[18:24:04][C][safe_mode:023]:   Remain in safe mode for 300 seconds
[18:24:04][C][api:140]: API Server:
[18:24:04][C][api:141]:   Address: termostato-meteo.local:6053
[18:24:04][C][api:145]:   Using noise encryption: NO
[18:24:04][C][homeassistant.binary_sensor:039]: Homeassistant Binary Sensor 'Caldaia'
[18:24:04][C][homeassistant.binary_sensor:040]:   Entity ID: 'switch.shelly_caldaia'
[18:24:04][C][homeassistant.sensor:030]: Homeassistant Sensor 'weather_temperature'
[18:24:04][C][homeassistant.sensor:030]:   State Class: ''
[18:24:04][C][homeassistant.sensor:030]:   Unit of Measurement: ''
[18:24:04][C][homeassistant.sensor:030]:   Accuracy Decimals: 1
[18:24:04][C][homeassistant.sensor:031]:   Entity ID: 'weather.casa'
[18:24:04][C][homeassistant.sensor:033]:   Attribute: 'temperature'
[18:24:04][C][homeassistant.sensor:030]: Homeassistant Sensor 'vento'
[18:24:04][C][homeassistant.sensor:030]:   State Class: ''
[18:24:04][C][homeassistant.sensor:030]:   Unit of Measurement: ''
[18:24:04][C][homeassistant.sensor:030]:   Accuracy Decimals: 1
[18:24:04][C][homeassistant.sensor:031]:   Entity ID: 'weather.casa'
[18:24:04][C][homeassistant.sensor:033]:   Attribute: 'wind_speed'
[18:24:04][C][homeassistant.sensor:030]: Homeassistant Sensor 'umidita_ext'
[18:24:04][C][homeassistant.sensor:030]:   State Class: ''
[18:24:04][C][homeassistant.sensor:030]:   Unit of Measurement: ''
[18:24:04][C][homeassistant.sensor:030]:   Accuracy Decimals: 1
[18:24:04][C][homeassistant.sensor:031]:   Entity ID: 'weather.casa'
[18:24:04][C][homeassistant.sensor:033]:   Attribute: 'humidity'
[18:24:04][C][homeassistant.sensor:030]: Homeassistant Sensor 'consumo_t'
[18:24:04][C][homeassistant.sensor:030]:   State Class: ''
[18:24:04][C][homeassistant.sensor:030]:   Unit of Measurement: ''
[18:24:04][C][homeassistant.sensor:030]:   Accuracy Decimals: 1
[18:24:04][C][homeassistant.sensor:031]:   Entity ID: 'sensor.consumo_totale_power'
[18:24:04][C][homeassistant.sensor:030]: Homeassistant Sensor 'consumo_c'
[18:24:04][C][homeassistant.sensor:030]:   State Class: ''
[18:24:04][C][homeassistant.sensor:030]:   Unit of Measurement: ''
[18:24:04][C][homeassistant.sensor:030]:   Accuracy Decimals: 1
[18:24:04][C][homeassistant.sensor:031]:   Entity ID: 'sensor.consumo_cantina_power'
[18:24:04][C][homeassistant.text_sensor:023]: Homeassistant Text Sensor 'weather_location'
[18:24:04][C][homeassistant.text_sensor:024]:   Entity ID: 'weather.casa'
[18:24:04][C][homeassistant.text_sensor:026]:   Attribute: 'friendly_name'
[18:24:04][C][homeassistant.text_sensor:023]: Homeassistant Text Sensor 'weather_condition'
[18:24:04][C][homeassistant.text_sensor:024]:   Entity ID: 'weather.casa'
[18:24:04][C][homeassistant.text_sensor:023]: Homeassistant Text Sensor 'forecast_5'
[18:24:04][C][homeassistant.text_sensor:024]:   Entity ID: 'sensor.previsioni'
[18:24:04][C][homeassistant.text_sensor:026]:   Attribute: 'forecast'
[18:24:04][C][homeassistant.text_sensor:023]: Homeassistant Text Sensor 'sun_state'
[18:24:04][C][homeassistant.text_sensor:024]:   Entity ID: 'sun.sun'
[18:24:05][D][homeassistant.sensor:024]: 'sensor.consumo_totale_power': Got state 255.28
[18:24:05][D][sensor:094]: 'consumo_t': Sending state 255.28000  with 1 decimals of accuracy
[18:24:06][D][binary_sensor:036]: 'Movimento': Sending state ON
[18:24:06][D][light:036]: 'Luce termostato' Setting:
[18:24:06][D][light:047]:   State: ON
[18:24:06][D][light:051]:   Brightness: 100%
[18:24:06][D][light:085]:   Transition length: 1.0s
[18:24:11][D][xpt2046:055]: Touchscreen Update [900, 3537], z = 670
[18:24:11][D][binary_sensor:036]: 'Movimento': Sending state OFF
[18:24:14][D][binary_sensor:036]: 'Movimento': Sending state ON
[18:24:14][D][light:036]: 'Luce termostato' Setting:
[18:24:14][D][light:051]:   Brightness: 100%
[18:24:14][D][light:085]:   Transition length: 1.0s
[18:24:17][D][binary_sensor:036]: 'Movimento': Sending state OFF
[18:24:17][D][homeassistant.sensor:024]: 'sensor.consumo_totale_power': Got state 190.48
[18:24:17][D][sensor:094]: 'consumo_t': Sending state 190.48000  with 1 decimals of accuracy
[18:24:20][D][sensor:094]: 'Temperatura': Sending state 18.40676 °C with 1 decimals of accuracy
[18:24:20][D][climate:396]: 'Termostato' - Sending state:
[18:24:20][D][climate:399]:   Mode: HEAT
[18:24:20][D][climate:401]:   Action: HEATING
[18:24:21][D][climate:419]:   Current Temperature: 18.41°C
[18:24:21][D][climate:425]:   Target Temperature: 19.00°C
[18:24:21][D][sensor:094]: 'Pressione': Sending state 950.63782 hPa with 1 decimals of accuracy
[18:24:21][D][sensor:094]: 'Umidita': Sending state 40.40625 % with 1 decimals of accuracy
[18:24:21][D][binary_sensor:036]: 'Movimento': Sending state ON
[18:24:21][D][light:036]: 'Luce termostato' Setting:
[18:24:21][D][light:051]:   Brightness: 100%
[18:24:21][D][light:085]:   Transition length: 1.0s
[18:24:23][D][homeassistant.sensor:024]: 'sensor.consumo_totale_power': Got state 201.51
[18:24:23][D][sensor:094]: 'consumo_t': Sending state 201.50999  with 1 decimals of accuracy
[18:24:24][D][xpt2046:055]: Touchscreen Update [677, 3650], z = 440
[18:24:24][D][light:036]: 'Luce termostato' Setting:
[18:24:24][D][light:051]:   Brightness: 100%
[18:24:24][D][light:085]:   Transition length: 1.0s
[18:24:24][I][cal:131]: x=14, y=216, x_raw=677, y_raw=3650 <-When i click "minus key"

Nothing happen the log not reporting anything, no binary sensor message.