mirror of
https://github.com/esphome/esphome.git
synced 2026-10-21 21:36:14 +00:00
[ld6002b] Check each area_config setting on its own for duplicates, and test the check
This commit is contained in:
@@ -6,7 +6,7 @@ from esphome.const import CONF_ID, CONF_PLATFORM, CONF_WAKEUP_PIN
|
||||
import esphome.final_validate as fv
|
||||
from esphome.types import ConfigType
|
||||
|
||||
from .const import CONF_AUTO_WAKE, CONF_LD6002B_ID, CONF_WAKEUP_PULSE
|
||||
from .const import CONF_AREA_CONFIG, CONF_AUTO_WAKE, CONF_LD6002B_ID, CONF_WAKEUP_PULSE
|
||||
|
||||
CODEOWNERS = ["@hepter"]
|
||||
DEPENDENCIES = ["uart"]
|
||||
@@ -84,11 +84,23 @@ def validate_unique_settings(domain: str, config: ConfigType) -> None:
|
||||
for entry in fv.full_config.get().get(domain, [])
|
||||
if entry.get(CONF_PLATFORM) == DOMAIN and entry.get(CONF_LD6002B_ID) == hub_id
|
||||
]
|
||||
for key in config:
|
||||
for key, value in config.items():
|
||||
if key in (CONF_PLATFORM, CONF_LD6002B_ID):
|
||||
continue
|
||||
if sum(key in entry for entry in entries) > 1:
|
||||
raise cv.Invalid(
|
||||
f"{key} is already set for this ld6002b in another {domain} block",
|
||||
path=[key],
|
||||
)
|
||||
# area_config groups six settings, so each one is checked on its own
|
||||
for path in (
|
||||
[[key, sub] for sub in value] if key == CONF_AREA_CONFIG else [[key]]
|
||||
):
|
||||
if sum(_has_path(entry, path) for entry in entries) > 1:
|
||||
raise cv.Invalid(
|
||||
f"{'.'.join(path)} is already set for this ld6002b in another {domain} block",
|
||||
path=path,
|
||||
)
|
||||
|
||||
|
||||
def _has_path(entry: ConfigType, path: list[str]) -> bool:
|
||||
for key in path:
|
||||
if key not in entry:
|
||||
return False
|
||||
entry = entry[key]
|
||||
return True
|
||||
|
||||
@@ -9,11 +9,17 @@ from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from esphome.components.ld6002b import validate_unique_settings
|
||||
from esphome.components.ld6002b.button import (
|
||||
CONFIG_SCHEMA as BUTTON_CONFIG_SCHEMA,
|
||||
FINAL_VALIDATE_SCHEMA as BUTTON_FINAL_VALIDATE_SCHEMA,
|
||||
)
|
||||
from esphome.components.ld6002b.const import CONF_AREA_CONFIG, CONF_Z_MIN
|
||||
from esphome.components.ld6002b.const import (
|
||||
CONF_AREA_CONFIG,
|
||||
CONF_HOLD_DELAY,
|
||||
CONF_Z_MAX,
|
||||
CONF_Z_MIN,
|
||||
)
|
||||
from esphome.components.ld6002b.number import (
|
||||
CONFIG_SCHEMA as NUMBER_CONFIG_SCHEMA,
|
||||
FINAL_VALIDATE_SCHEMA as NUMBER_FINAL_VALIDATE_SCHEMA,
|
||||
@@ -40,6 +46,7 @@ def _full_config(
|
||||
*,
|
||||
selects: list[ConfigType] | None = None,
|
||||
buttons: list[ConfigType] | None = None,
|
||||
numbers: list[ConfigType] | None = None,
|
||||
) -> Config:
|
||||
"""A full config carrying one ld6002b hub, as the ID pass leaves it.
|
||||
|
||||
@@ -57,6 +64,8 @@ def _full_config(
|
||||
full["select"] = selects
|
||||
if buttons is not None:
|
||||
full[CONF_BUTTON] = buttons
|
||||
if numbers is not None:
|
||||
full["number"] = numbers
|
||||
return full
|
||||
|
||||
|
||||
@@ -214,3 +223,53 @@ def test_area_config_without_select_is_rejected(
|
||||
),
|
||||
):
|
||||
_validated_numbers(_area_numbers())
|
||||
|
||||
|
||||
def _number_block(**settings: ConfigType) -> ConfigType:
|
||||
"""A number platform block on the shared hub, as final validation sees it."""
|
||||
return {
|
||||
"platform": "ld6002b",
|
||||
"ld6002b_id": ID(HUB_ID, is_declaration=False, type="ld6002b"),
|
||||
**settings,
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("first", "second", "error"),
|
||||
[
|
||||
(
|
||||
{CONF_HOLD_DELAY: {"name": "A"}},
|
||||
{CONF_HOLD_DELAY: {"name": "B"}},
|
||||
r"^hold_delay is already set .* @ data\['hold_delay'\]$",
|
||||
),
|
||||
(
|
||||
{CONF_AREA_CONFIG: {CONF_Z_MIN: {"name": "A"}}},
|
||||
{CONF_AREA_CONFIG: {CONF_Z_MIN: {"name": "B"}}},
|
||||
r"^area_config\.z_min is already set .* @ data\['area_config'\]\['z_min'\]$",
|
||||
),
|
||||
(
|
||||
{CONF_AREA_CONFIG: {CONF_Z_MIN: {"name": "A"}}},
|
||||
{CONF_AREA_CONFIG: {CONF_Z_MAX: {"name": "B"}}},
|
||||
None,
|
||||
),
|
||||
({CONF_HOLD_DELAY: {"name": "A"}}, {CONF_Z_MIN: {"name": "B"}}, None),
|
||||
],
|
||||
)
|
||||
def test_setting_in_two_blocks_of_one_hub(
|
||||
set_core_config: SetCoreConfigCallable,
|
||||
first: ConfigType,
|
||||
second: ConfigType,
|
||||
error: str | None,
|
||||
) -> None:
|
||||
"""Each setting maps to one entity pointer, so two blocks cannot share one."""
|
||||
blocks = [_number_block(**first), _number_block(**second)]
|
||||
set_core_config(
|
||||
PlatformFramework.ESP32_IDF,
|
||||
full_config=_full_config(_hub(wakeup_pin=False), numbers=blocks),
|
||||
)
|
||||
|
||||
if error is None:
|
||||
validate_unique_settings("number", blocks[1])
|
||||
return
|
||||
with pytest.raises(cv.Invalid, match=error):
|
||||
validate_unique_settings("number", blocks[1])
|
||||
|
||||
Reference in New Issue
Block a user