1
0
mirror of https://github.com/esphome/esphome.git synced 2025-09-14 01:02:19 +01:00

Checks for pins used in multiple places (#5666)

This commit is contained in:
Clyde Stubbs
2023-12-05 10:56:53 +11:00
committed by GitHub
parent df5394d51c
commit d9792b0d92
27 changed files with 1335 additions and 575 deletions

View File

@@ -7,6 +7,7 @@ import re
from typing import Optional, Union
from contextlib import contextmanager
import contextvars
import voluptuous as vol
@@ -53,6 +54,7 @@ def iter_components(config):
ConfigPath = list[Union[str, int]]
path_context = contextvars.ContextVar("Config path")
def _path_begins_with(path: ConfigPath, other: ConfigPath) -> bool:
@@ -489,6 +491,7 @@ class SchemaValidationStep(ConfigValidationStep):
def run(self, result: Config) -> None:
if self.comp.config_schema is None:
return
token = path_context.set(self.path)
with result.catch_error(self.path):
if self.comp.is_platform:
# Remove 'platform' key for validation
@@ -507,6 +510,7 @@ class SchemaValidationStep(ConfigValidationStep):
validated = schema(self.conf)
result.set_by_path(self.path, validated)
path_context.reset(token)
result.add_validation_step(FinalValidateValidationStep(self.path, self.comp))
@@ -652,37 +656,24 @@ class FinalValidateValidationStep(ConfigValidationStep):
if self.comp.final_validate_schema is not None:
self.comp.final_validate_schema(conf)
fconf = fv.full_config.get()
def _check_pins(c):
for value in c.values():
if not isinstance(value, dict):
continue
for key, (
_,
_,
pin_final_validate,
) in pins.PIN_SCHEMA_REGISTRY.items():
if (
key != CORE.target_platform
and key in value
and pin_final_validate is not None
):
pin_final_validate(fconf, value)
# Check for pin configs and a final_validate schema in the pin registry
confs = conf
if not isinstance(
confs, list
): # Handle components like SPI that have a list instead of MULTI_CONF
confs = [conf]
for c in confs:
if c: # Some component have None or empty schemas
_check_pins(c)
fv.full_config.reset(token)
class PinUseValidationCheck(ConfigValidationStep):
"""Check for pin reuse"""
priority = -30 # Should happen after component final validations
def __init__(self) -> None:
pass
def run(self, result: Config) -> None:
if result.errors:
# If result already has errors, skip this step
return
pins.PIN_SCHEMA_REGISTRY.final_validate(result)
def validate_config(config, command_line_substitutions) -> Config:
result = Config()
@@ -778,6 +769,7 @@ def validate_config(config, command_line_substitutions) -> Config:
for domain, conf in config.items():
result.add_validation_step(LoadValidationStep(domain, conf))
result.add_validation_step(IDPassValidationStep())
result.add_validation_step(PinUseValidationCheck())
result.run_validation_steps()