mirror of
https://github.com/esphome/esphome.git
synced 2026-11-01 02:46:39 +00:00
[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:
1 parent
98706c594b
commit
4e68f1d324
2 files changed
+96
-4
No files matched your search
@@ -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
|
||||
Reference in new issue
Block a user