### The problem
After upgrading to 2023.7.0 - device using ili9xxx component pr…ints warning in log:
Component ili9xxx.display took a long time for an operation (0.50 s).
Components should block for at most 20-30ms.
This starts as soon as the component is initialised and continues as long as the device is up, log example below
No apparent negative impact except of course the resources this continual logging is using.
### Which version of ESPHome has the issue?
2023.7.0
### 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
ESP32-DEVKIT-C WROVER 4MB PSRAM
### Component causing the issue
ili9xxx
### Example YAML snippet
```yaml
display:
- platform: ili9xxx
model: ili9488
id: my_display
rotation: 180
dc_pin: GPIO02
cs_pin: GPIO15
reset_pin: GPIO04
# Page 1 - main display. Pages 2-5 are for anti burn-in
pages:
- id: page1
lambda: |-
// Colours - used for visiual indication of wind strength
auto red = Color(255, 0, 0);
auto green = Color(0, 255, 0);
auto light_blue = Color(135, 237, 232);
auto orange = Color(255, 170, 43);
auto white = Color(255, 255, 255);
auto purple = Color(97, 15, 219);
auto grey = Color(100, 135, 135);
// history arrays for trend display
static float hist_wind[30];
static int hist_dir[30];
static int index=0;
static int prev_index=29;
// Convert wind direction to int, speed to float
int dir = atoi(id(wind_dir).state.c_str());
float speed = atof(id(wind_speed).state.c_str());
// Calculate xy position to plot wind indicator
int x = 120 + (90 * (cos((dir-90)*PI/180)));
int y = 150 + (90 * (sin((dir-90)*PI/180)));
// Store in array
if ((hist_wind[prev_index]!=speed || hist_dir[prev_index]!=dir) && speed!=0) {
hist_wind[index] = speed;
hist_dir[index] = dir;
index += 1;
prev_index += 1;
if (index==30) { index = 0; }
if (prev_index==30) { prev_index = 0; }
}
// Trend maximum for last 30
float max = hist_wind[0];
for (size_t i = 0; i < 30; ++i) {
if (hist_wind[i] > max) {
max = hist_wind[i];
}
}
// Weather data
it.strftime(5, 10, id(calibri_25), TextAlign::TOP_LEFT, "%H:%M", id(my_time).now());
it.printf(235, 10, id(calibri_25), TextAlign::TOP_RIGHT, "%s °C", id(temp).state.c_str());
it.printf(5, 290, id(calibri_20), TextAlign::BOTTOM_LEFT, "G %s km/h", id(gust).state.c_str());
it.printf(5, 310, id(calibri_20), TextAlign::BOTTOM_LEFT, "TM %2.1f km/h", max);
it.printf(235, 290, id(calibri_20), TextAlign::BOTTOM_RIGHT, "%s mm", id(total_rain).state.c_str());
it.printf(235, 310, id(calibri_20), TextAlign::BOTTOM_RIGHT, "%s hPa", id(pressure).state.c_str());
// Display trend data
for (size_t i = 0; i < 30; ++i) {
if (hist_wind[i]>0) {
int a = 120 + ((90-(70*hist_wind[i]/max)) * (cos((hist_dir[i]-90)*PI/180)));
int b = 150 + ((90-(70*hist_wind[i]/max)) * (sin((hist_dir[i]-90)*PI/180)));
int c = 120 + (90 * (cos((hist_dir[i]-90)*PI/180)));
int d = 150 + (90 * (sin((hist_dir[i]-90)*PI/180)));
it.line(a, b, c, d, grey);
}
}
// Compass rose
it.circle(120, 150, 90);
it.print(120, 50, id(calibri_20), red, TextAlign::BOTTOM_CENTER, "N");
it.print(120, 250, id(calibri_20), red, TextAlign::TOP_CENTER, "S");
it.print(20, 150, id(calibri_20), red, TextAlign::CENTER_RIGHT, "W");
it.print(220, 150, id(calibri_20), red, TextAlign::CENTER_LEFT, "E");
// Wind pointer
if (speed<=11) { it.filled_circle(x, y, 7, light_blue); }
else {
if (speed>11 && speed<=30) { it.filled_circle(x, y, 7, green); }
else {
if (speed>30 && speed<=60) { it.filled_circle(x, y, 7, orange); }
else {
if (speed>60) { it.filled_circle(x, y, 7, red); }
} } }
// Wind details
it.printf(120, 130, id(calibri_25), TextAlign::BOTTOM_CENTER, "%s", id(named_dir).state.c_str());
if (speed<10) { it.printf(120, 175, id(calibri_40), TextAlign::BOTTOM_CENTER, "%2.1f", speed); }
else { it.printf(120, 175, id(calibri_40), TextAlign::BOTTOM_CENTER, "%2.0f", round(speed));
}
it.print(120, 175, id(calibri_20), TextAlign::TOP_CENTER, "km/h");
it.line(239, 5, 239, 315, light_blue);
// list of condition for forecast icons
std::string conditions[7] = { id(icon0).state.c_str(),
id(icon1).state.c_str(),
id(icon2).state.c_str(),
id(icon3).state.c_str(),
id(icon4).state.c_str(),
id(icon5).state.c_str(),
id(icon6).state.c_str() };
// days of week for forecast text
std::string weekday[14] = { "Today", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri" };
int wd = id(my_time).now().day_of_week;
std::string forecast[7] = { "",
(weekday[wd+1] + ": " + id(min1).state + "°/" + id(max1).state + "° " + id(forecast1).state
+ " " + id(rainchance1).state +"% chance of " + id(rainrange1).state +"mm ").c_str(),
(weekday[wd+2] + ": " + id(min2).state + "°/" + id(max2).state + "° " + id(forecast2).state
+ " " + id(rainchance2).state +"% chance of " + id(rainrange2).state +"mm ").c_str(),
(weekday[wd+3] + ": " + id(min3).state + "°/" + id(max3).state + "° " + id(forecast3).state
+ " " + id(rainchance3).state +"% chance of " + id(rainrange3).state +"mm ").c_str(),
(weekday[wd+4] + ": " + id(min4).state + "°/" + id(max4).state + "° " + id(forecast4).state
+ " " + id(rainchance4).state +"% chance of " + id(rainrange4).state +"mm ").c_str(),
(weekday[wd+5] + ": " + id(min5).state + "°/" + id(max5).state + "° " + id(forecast5).state
+ " " + id(rainchance5).state +"% chance of " + id(rainrange5).state +"mm ").c_str(),
(weekday[wd+6] + ": " + id(min6).state + "°/" + id(max6).state + "° " + id(forecast6).state
+ " " + id(rainchance6).state +"% chance of " + id(rainrange6).state +"mm ").c_str()};
// map conditions to icons
std::map<std::string, std::string> weather_state {
{ "clear", "" },
{ "cloudy", "" },
{ "cyclone", "" },
{ "dust", "" },
{ "dusty", "" },
{ "fog", "" },
{ "frost", "" },
{ "haze", "" },
{ "hazy", "" },
{ "heavy_shower", "" },
{ "heavy_showers", "" },
{ "light_rain", "" },
{ "light_shower", "" },
{ "light_showers", "" },
{ "mostly_sunny", "" },
{ "partly_cloudy", "" },
{ "rain", "" },
{ "shower", "" },
{ "showers", "" },
{ "snow", "" },
{ "storm", "" },
{ "storms", "" },
{ "sunny", "" },
{ "tropical_cyclone", "" },
{ "wind", "" },
{ "windy", "" }
};
// map conditions to icons after sunset
std::map<std::string, std::string> weather_state_night {
{ "clear", "" },
{ "cloudy", "" },
{ "cyclone", "" },
{ "dust", "" },
{ "dusty", "" },
{ "fog", "" },
{ "frost", "" },
{ "haze", "" },
{ "hazy", "" },
{ "heavy_shower", "" },
{ "heavy_showers", "" },
{ "light_rain", "" },
{ "light_shower", "" },
{ "light_showers", "" },
{ "mostly_sunny", "" },
{ "partly_cloudy", "" },
{ "rain", "" },
{ "shower", "" },
{ "showers", "" },
{ "snow", "" },
{ "storm", "" },
{ "storms", "" },
{ "sunny", "" },
{ "tropical_cyclone", "" },
{ "wind", "" },
{ "windy", "" }
};
// select icon from approriate map (daytime / nighttime)
if (id(sun_elevation).state <= 0) {
it.printf(245, 2, id(weather_22), "%s", (weather_state_night[conditions[0]]).c_str());
} else {
it.printf(245, 2, id(weather_22), "%s", (weather_state[conditions[0]]).c_str());
}
// print today's forecast
std::string f0 = "";
if (id(min0).state == "unknown") {
f0 = ("Remainder of today: " + id(max0).state + "° " + id(forecast0).state) + " ";
} else {
f0 = ("Today: " + id(min0).state + "°/" + id(max0).state + "° " + id(forecast0).state) + " ";
}
// Wrap at last space before 36 characters
// don't wrap last line
std::string line = "";
int pos = 0;
int end = 35;
for (int i = 1; i <= 4; i++) {
end = f0.find_last_of(" ", end);
line = f0.substr(pos, end-pos);
pos = end + 1;
end = end + 36;
it.printf(280, ((i-1)*13+9), id(calibri_12), "%s", line.c_str());
}
it.printf(280, ((4)*13+9), id(calibri_12), "%s", f0.substr(pos, 999).c_str());
// daily short forecasts
for (int i = 1; i < 7; i++) {
it.line(260, (i*38+43), 460, (i*38+43), light_blue);
it.printf(245, (i*38+45), id(weather_22), "%s", (weather_state[conditions[i]]).c_str());
line = "";
pos = 0;
end = 35;
// Wrap at last space before 36 characters
for (int j = 1; j <= 2; j++) {
end = forecast[i].find_last_of(" ", end);
line = forecast[i].substr(pos, end-pos);
pos = end + 1;
end = end + 36;
it.printf(280, (i*38+51+(j-1)*13), id(calibri_12), "%s", line.c_str());
}
}
- id: page2
lambda: |-
// fill screen red
auto red = Color(255, 0, 0);
it.fill(red);
- id: page3
lambda: |-
// Fill screen green
auto green = Color(0, 255, 0);
it.fill(green);
- id: page4
lambda: |-
// Fill screen white
auto white = Color(255, 255, 255);
it.fill(white);
- id: page5
lambda: |-
it.fill(COLOR_OFF);
# Page 7 - Extended 2 day forecast data
- id: page7
lambda: |-
// Colours - used for visiual indication of wind strength
auto red = Color(255, 0, 0);
auto green = Color(0, 255, 0);
auto light_blue = Color(135, 237, 232);
auto orange = Color(255, 170, 43);
auto white = Color(255, 255, 255);
auto purple = Color(97, 15, 219);
auto grey = Color(100, 135, 135);
// history arrays for trend display
static float hist_wind[30];
static int hist_dir[30];
static int index=0;
static int prev_index=29;
// Convert wind direction to int, speed to float
int dir = atoi(id(wind_dir).state.c_str());
float speed = atof(id(wind_speed).state.c_str());
// Calculate xy position to plot wind indicator
int x = 120 + (90 * (cos((dir-90)*PI/180)));
int y = 150 + (90 * (sin((dir-90)*PI/180)));
// Store in array
if ((hist_wind[prev_index]!=speed || hist_dir[prev_index]!=dir) && speed!=0) {
hist_wind[index] = speed;
hist_dir[index] = dir;
index += 1;
prev_index += 1;
if (index==30) { index = 0; }
if (prev_index==30) { prev_index = 0; }
}
// Trend maximum for last 30
float max = hist_wind[0];
for (size_t i = 0; i < 30; ++i) {
if (hist_wind[i] > max) {
max = hist_wind[i];
}
}
// Weather data
it.strftime(5, 10, id(calibri_25), TextAlign::TOP_LEFT, "%H:%M", id(my_time).now());
it.printf(235, 10, id(calibri_25), TextAlign::TOP_RIGHT, "%s °C", id(temp).state.c_str());
it.printf(5, 290, id(calibri_20), TextAlign::BOTTOM_LEFT, "G %s km/h", id(gust).state.c_str());
it.printf(5, 310, id(calibri_20), TextAlign::BOTTOM_LEFT, "TM %2.1f km/h", max);
it.printf(235, 290, id(calibri_20), TextAlign::BOTTOM_RIGHT, "%s mm", id(total_rain).state.c_str());
it.printf(235, 310, id(calibri_20), TextAlign::BOTTOM_RIGHT, "%s hPa", id(pressure).state.c_str());
// Display trend data
for (size_t i = 0; i < 30; ++i) {
if (hist_wind[i]>0) {
int a = 120 + ((90-(70*hist_wind[i]/max)) * (cos((hist_dir[i]-90)*PI/180)));
int b = 150 + ((90-(70*hist_wind[i]/max)) * (sin((hist_dir[i]-90)*PI/180)));
int c = 120 + (90 * (cos((hist_dir[i]-90)*PI/180)));
int d = 150 + (90 * (sin((hist_dir[i]-90)*PI/180)));
it.line(a, b, c, d, grey);
}
}
// Compass rose
it.circle(120, 150, 90);
it.print(120, 50, id(calibri_20), red, TextAlign::BOTTOM_CENTER, "N");
it.print(120, 250, id(calibri_20), red, TextAlign::TOP_CENTER, "S");
it.print(20, 150, id(calibri_20), red, TextAlign::CENTER_RIGHT, "W");
it.print(220, 150, id(calibri_20), red, TextAlign::CENTER_LEFT, "E");
// Wind pointer
if (speed<=11) { it.filled_circle(x, y, 7, light_blue); }
else {
if (speed>11 && speed<=30) { it.filled_circle(x, y, 7, green); }
else {
if (speed>30 && speed<=60) { it.filled_circle(x, y, 7, orange); }
else {
if (speed>60) { it.filled_circle(x, y, 7, red); }
} } }
// Wind details
it.printf(120, 130, id(calibri_25), TextAlign::BOTTOM_CENTER, "%s", id(named_dir).state.c_str());
if (speed<10) { it.printf(120, 175, id(calibri_40), TextAlign::BOTTOM_CENTER, "%2.1f", speed); }
else { it.printf(120, 175, id(calibri_40), TextAlign::BOTTOM_CENTER, "%2.0f", round(speed));
}
it.print(120, 175, id(calibri_20), TextAlign::TOP_CENTER, "km/h");
it.line(239, 5, 239, 315, light_blue);
// list of condition for forecast icons
std::string conditions[7] = { id(icon0).state.c_str(),
id(icon1).state.c_str(),
id(icon2).state.c_str(),
id(icon3).state.c_str(),
id(icon4).state.c_str(),
id(icon5).state.c_str(),
id(icon6).state.c_str() };
// days of week for forecast text
std::string weekday[14] = { "Today", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri" };
int wd = id(my_time).now().day_of_week;
// map conditions to icons
std::map<std::string, std::string> weather_state {
{ "clear", "" },
{ "cloudy", "" },
{ "cyclone", "" },
{ "dust", "" },
{ "dusty", "" },
{ "fog", "" },
{ "frost", "" },
{ "haze", "" },
{ "hazy", "" },
{ "heavy_shower", "" },
{ "heavy_showers", "" },
{ "light_rain", "" },
{ "light_shower", "" },
{ "light_showers", "" },
{ "mostly_sunny", "" },
{ "partly_cloudy", "" },
{ "rain", "" },
{ "shower", "" },
{ "showers", "" },
{ "snow", "" },
{ "storm", "" },
{ "storms", "" },
{ "sunny", "" },
{ "tropical_cyclone", "" },
{ "wind", "" },
{ "windy", "" }
};
// map conditions to icons after sunset
std::map<std::string, std::string> weather_state_night {
{ "clear", "" },
{ "cloudy", "" },
{ "cyclone", "" },
{ "dust", "" },
{ "dusty", "" },
{ "fog", "" },
{ "frost", "" },
{ "haze", "" },
{ "hazy", "" },
{ "heavy_shower", "" },
{ "heavy_showers", "" },
{ "light_rain", "" },
{ "light_shower", "" },
{ "light_showers", "" },
{ "mostly_sunny", "" },
{ "partly_cloudy", "" },
{ "rain", "" },
{ "shower", "" },
{ "showers", "" },
{ "snow", "" },
{ "storm", "" },
{ "storms", "" },
{ "sunny", "" },
{ "tropical_cyclone", "" },
{ "wind", "" },
{ "windy", "" }
};
// select icon from approriate map (daytime / nighttime)
if (id(sun_elevation).state <= 0) {
it.printf(245, 2, id(weather_22), "%s", (weather_state_night[conditions[0]]).c_str());
} else {
it.printf(245, 2, id(weather_22), "%s", (weather_state[conditions[0]]).c_str());
}
// print today's forecast
std::string f0 = "";
if (id(min0).state == "unknown") {
f0 = ("Remainder of today: " + id(max0).state + "° " + id(forecast0).state) + " " + id(rainchance0).state +"% chance of " + id(rainrange0).state + "mm ";
} else {
f0 = ("Today: " + id(min0).state + "°/" + id(max0).state + "° " + id(forecast0).state) + " " + id(rainchance0).state +"% chance of " + id(rainrange0).state + "mm ";
}
// Wrap at last space before 35 characters
// don't wrap last line
std::string line = "";
int pos = 0;
int end = 35;
for (int i = 1; i <= 10; i++) {
end = f0.find_last_of(" ", end);
line = f0.substr(pos, end-pos);
pos = end + 1;
end = end + 35;
it.printf(280, ((i-1)*13+10), id(calibri_12), "%s", line.c_str());
}
it.printf(280, ((10)*13+10), id(calibri_12), "%s", f0.substr(pos, 999).c_str());
it.line(260, 160, 460, 160, light_blue);
// print tomorrow's forecast
it.printf(245, 172, id(weather_22), "%s", (weather_state[conditions[1]]).c_str());
f0 = ("Tomorrow: " + id(min1).state + "°/" + id(max1).state + "° " + id(forecast1e).state) + " " + id(rainchance0).state +"% chance of " + id(rainrange0).state +"mm ";
// Wrap at last space before 35 characters
// don't wrap last line
line = "";
pos = 0;
end = 35;
for (int i = 1; i <= 10; i++) {
end = f0.find_last_of(" ", end);
line = f0.substr(pos, end-pos);
pos = end + 1;
end = end + 35;
it.printf(280, ((i-1)*13+170), id(calibri_12), "%s", line.c_str());
}
it.printf(280, ((10)*13+170), id(calibri_12), "%s", f0.substr(pos, 999).c_str());
```
### Anything in the logs that might be useful for us?
```txt
[19:54:07][C][wifi:384]: Hostname: 'weather'
[19:54:07][C][wifi:386]: Signal strength: -38 dB ▂▄▆█
[19:54:07][C][wifi:390]: Channel: 9
[19:54:07][C][wifi:391]: Subnet: 255.255.255.0
[19:54:07][C][wifi:392]: Gateway: 192.168.0.1
[19:54:07][C][wifi:393]: DNS1: 192.168.1.1
[19:54:07][C][wifi:394]: DNS2: 192.168.1.1
[19:54:07][C][logger:301]: Logger:
[19:54:07][C][logger:302]: Level: DEBUG
[19:54:07][C][logger:303]: Log Baud Rate: 115200
[19:54:07][C][logger:305]: Hardware UART: UART0
[19:54:07][C][spi:125]: SPI bus:
[19:54:07][C][spi:126]: CLK Pin: GPIO18
[19:54:07][C][spi:127]: MISO Pin: GPIO19
[19:54:07][C][spi:128]: MOSI Pin: GPIO23
[19:54:07][C][spi:130]: Using HW SPI: YES
[19:54:07][C][ledc.output:160]: LEDC Output:
[19:54:07][C][ledc.output:161]: Pin GPIO32
[19:54:07][C][ledc.output:162]: LEDC Channel: 0
[19:54:07][C][ledc.output:163]: PWM Frequency: 1000.0 Hz
[19:54:07][C][ledc.output:164]: Bit depth: 16
[19:54:07][C][ili9xxx:047]: ili9xxx
[19:54:07][C][ili9xxx:047]: Rotations: 180 °
[19:54:07][C][ili9xxx:047]: Dimensions: 480px x 320px
[19:54:07][C][ili9xxx:053]: Color mode: 16bit
[19:54:07][C][ili9xxx:060]: 18-Bit Mode: YES
[19:54:07][C][ili9xxx:063]: Reset Pin: GPIO4
[19:54:07][C][ili9xxx:064]: DC Pin: GPIO2
[19:54:07][C][ili9xxx:070]: Update Interval: 1.0s
[19:54:08][W][component:204]: Component ili9xxx.display took a long time for an operation (0.50 s).
[19:54:08][W][component:205]: Components should block for at most 20-30ms.
...
...
...
[19:54:55][W][component:204]: Component ili9xxx.display took a long time for an operation (0.52 s).
[19:54:55][W][component:205]: Components should block for at most 20-30ms.
[19:54:56][W][component:204]: Component ili9xxx.display took a long time for an operation (0.52 s).
[19:54:56][W][component:205]: Components should block for at most 20-30ms.
[19:54:57][W][component:204]: Component ili9xxx.display took a long time for an operation (0.52 s).
[19:54:57][W][component:205]: Components should block for at most 20-30ms.
[19:54:58][W][component:204]: Component ili9xxx.display took a long time for an operation (0.52 s).
[19:54:58][W][component:205]: Components should block for at most 20-30ms.
[19:54:59][W][component:204]: Component ili9xxx.display took a long time for an operation (0.52 s).
[19:54:59][W][component:205]: Components should block for at most 20-30ms.
[19:55:00][W][component:204]: Component ili9xxx.display took a long time for an operation (0.52 s).
[19:55:00][W][component:205]: Components should block for at most 20-30ms.
[19:55:01][W][component:204]: Component ili9xxx.display took a long time for an operation (0.52 s).
[19:55:01][W][component:205]: Components should block for at most 20-30ms.
[19:55:02][W][component:204]: Component ili9xxx.display took a long time for an operation (0.52 s).
[19:55:02][W][component:205]: Components should block for at most 20-30ms.
[19:55:03][W][component:204]: Component ili9xxx.display took a long time for an operation (0.52 s).
[19:55:03][W][component:205]: Components should block for at most 20-30ms.
[19:55:04][W][component:204]: Component ili9xxx.display took a long time for an operation (0.52 s).
[19:55:04][W][component:205]: Components should block for at most 20-30ms.
[19:55:05][W][component:204]: Component ili9xxx.display took a long time for an operation (0.52 s).
```
### Additional information
_No response_