[display] Warn when show_test_card is used with update_interval: never (#20887)

Co-authored-by: J. Nick Koston <nick@home-assistant.io>
This commit is contained in:
PanoplianandJ. Nick Koston authored and GitHub committed 2026-10-26 11:12:41 -10:00
1 parent 98706c594b
commit 4e68f1d324
2 files changed
+96 -4

No files matched your search

+15 -4
View File
@@ -1,4 +1,5 @@
from dataclasses import dataclass
import logging
from typing import Any, Protocol
from esphome import automation, core, pins
@@ -34,6 +35,8 @@ from esphome.types import ConfigType
DOMAIN = "display"
IS_PLATFORM_COMPONENT = True
_LOGGER = logging.getLogger(__name__)
display_ns = cg.esphome_ns.namespace("display")
Display = display_ns.class_("Display", cg.PollingComponent)
DisplayBuffer = display_ns.class_("DisplayBuffer", Display)
@@ -102,13 +105,21 @@ BASIC_DISPLAY_SCHEMA = cv.Schema(
).extend(cv.polling_component_schema("1s"))
def _validate_test_card(config):
def _validate_test_card(config: ConfigType) -> ConfigType:
if (
config.get(CONF_SHOW_TEST_CARD, False)
and config.get(CONF_UPDATE_INTERVAL, False) == SCHEDULER_DONT_RUN
and (update_interval := config.get(CONF_UPDATE_INTERVAL)) is not None
and update_interval.total_milliseconds == SCHEDULER_DONT_RUN
):
raise cv.Invalid(
f"`{CONF_SHOW_TEST_CARD}: True` cannot be used with `{CONF_UPDATE_INTERVAL}: never` because this combination will not show a test_card."
# Only a warning: something else can still update the display, for example
# component.update, and the test card is drawn then.
display_id = config.get(CONF_ID)
_LOGGER.warning(
"%s`%s: True` is used with `%s: never`, so the test card is only drawn "
"when something updates the display (for example component.update)",
f"{display_id.id}: " if display_id is not None and display_id.id else "",
CONF_SHOW_TEST_CARD,
CONF_UPDATE_INTERVAL,
)
return config
@@ -0,0 +1,81 @@
"""Tests for the show_test_card and update_interval check in the display schema."""
import logging
import pytest
from esphome.components.display import FULL_DISPLAY_SCHEMA, _validate_test_card
import esphome.config_validation as cv
from esphome.core import ID
from esphome.types import ConfigType
WARNING = "`show_test_card: True` is used with `update_interval: never`"
def test_test_card_with_update_interval_never_warns(
caplog: pytest.LogCaptureFixture,
) -> None:
"""The test card is only drawn when something else updates the display."""
with caplog.at_level(logging.WARNING, logger="esphome.components.display"):
FULL_DISPLAY_SCHEMA({"show_test_card": True, "update_interval": "never"})
assert WARNING in caplog.text
def test_warning_names_the_display(caplog: pytest.LogCaptureFixture) -> None:
"""With several displays the warning says which one it is about."""
config = {
"id": ID("status_epaper", is_declaration=True),
"show_test_card": True,
"update_interval": cv.update_interval("never"),
}
with caplog.at_level(logging.WARNING, logger="esphome.components.display"):
_validate_test_card(config)
assert f"status_epaper: {WARNING}" in caplog.text
def test_warning_without_display_id_has_no_prefix(
caplog: pytest.LogCaptureFixture,
) -> None:
"""A generated id is unset at validation time, so the warning starts with the message."""
config = {
"id": ID(None, is_declaration=True),
"show_test_card": True,
"update_interval": cv.update_interval("never"),
}
with caplog.at_level(logging.WARNING, logger="esphome.components.display"):
_validate_test_card(config)
assert WARNING in caplog.text
assert f": {WARNING}" not in caplog.text
@pytest.mark.parametrize(
"config",
[
pytest.param(
{"show_test_card": True, "update_interval": "1s"}, id="test_card_1s"
),
pytest.param({"show_test_card": True}, id="test_card_default_interval"),
pytest.param(
{"show_test_card": False, "update_interval": "never"},
id="no_test_card_never",
),
pytest.param({"update_interval": "never"}, id="never_only"),
],
)
def test_other_combinations_do_not_warn(
config: ConfigType, caplog: pytest.LogCaptureFixture
) -> None:
"""Only the test card together with `update_interval: never` warns."""
with caplog.at_level(logging.WARNING, logger="esphome.components.display"):
FULL_DISPLAY_SCHEMA(config)
assert WARNING not in caplog.text
def test_test_card_without_update_interval_accepted(
caplog: pytest.LogCaptureFixture,
) -> None:
"""Platforms such as epaper_spi may leave update_interval unset at this stage."""
config = {"show_test_card": True}
with caplog.at_level(logging.WARNING, logger="esphome.components.display"):
assert _validate_test_card(config) is config
assert WARNING not in caplog.text