mirror of
https://github.com/esphome/esphome.git
synced 2025-09-25 22:52:20 +01:00
Improve config final validation (#1917)
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
from typing import Optional
|
||||
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
import esphome.final_validate as fv
|
||||
from esphome import pins, automation
|
||||
from esphome.const import (
|
||||
CONF_BAUD_RATE,
|
||||
@@ -92,42 +95,6 @@ async def to_code(config):
|
||||
cg.add(var.set_parity(config[CONF_PARITY]))
|
||||
|
||||
|
||||
def validate_device(
|
||||
name, config, item_config, baud_rate=None, require_tx=True, require_rx=True
|
||||
):
|
||||
if not hasattr(config, "uart_devices"):
|
||||
config.uart_devices = {}
|
||||
devices = config.uart_devices
|
||||
|
||||
uart_config = config.get_config_by_id(item_config[CONF_UART_ID])
|
||||
|
||||
uart_id = uart_config[CONF_ID]
|
||||
device = devices.setdefault(uart_id, {})
|
||||
|
||||
if require_tx:
|
||||
if CONF_TX_PIN not in uart_config:
|
||||
raise ValueError(f"Component {name} requires parent uart to declare tx_pin")
|
||||
if CONF_TX_PIN in device:
|
||||
raise ValueError(
|
||||
f"Component {name} cannot use the same uart.{CONF_TX_PIN} as component {device[CONF_TX_PIN]} is already using it"
|
||||
)
|
||||
device[CONF_TX_PIN] = name
|
||||
|
||||
if require_rx:
|
||||
if CONF_RX_PIN not in uart_config:
|
||||
raise ValueError(f"Component {name} requires parent uart to declare rx_pin")
|
||||
if CONF_RX_PIN in device:
|
||||
raise ValueError(
|
||||
f"Component {name} cannot use the same uart.{CONF_RX_PIN} as component {device[CONF_RX_PIN]} is already using it"
|
||||
)
|
||||
device[CONF_RX_PIN] = name
|
||||
|
||||
if baud_rate and uart_config[CONF_BAUD_RATE] != baud_rate:
|
||||
raise ValueError(
|
||||
f"Component {name} requires parent uart baud rate be {baud_rate}"
|
||||
)
|
||||
|
||||
|
||||
# A schema to use for all UART devices, all UART integrations must extend this!
|
||||
UART_DEVICE_SCHEMA = cv.Schema(
|
||||
{
|
||||
@@ -135,6 +102,64 @@ UART_DEVICE_SCHEMA = cv.Schema(
|
||||
}
|
||||
)
|
||||
|
||||
KEY_UART_DEVICES = "uart_devices"
|
||||
|
||||
|
||||
def final_validate_device_schema(
|
||||
name: str,
|
||||
*,
|
||||
baud_rate: Optional[int] = None,
|
||||
require_tx: bool = False,
|
||||
require_rx: bool = False,
|
||||
):
|
||||
def validate_baud_rate(value):
|
||||
if value != baud_rate:
|
||||
raise cv.Invalid(
|
||||
f"Component {name} required baud rate {baud_rate} for the uart bus"
|
||||
)
|
||||
return value
|
||||
|
||||
def validate_pin(opt, device):
|
||||
def validator(value):
|
||||
if opt in device:
|
||||
raise cv.Invalid(
|
||||
f"The uart {opt} is used both by {name} and {device[opt]}, "
|
||||
f"but can only be used by one. Please create a new uart bus for {name}."
|
||||
)
|
||||
device[opt] = name
|
||||
return value
|
||||
|
||||
return validator
|
||||
|
||||
def validate_hub(hub_config):
|
||||
hub_schema = {}
|
||||
uart_id = hub_config[CONF_ID]
|
||||
devices = fv.full_config.get().data.setdefault(KEY_UART_DEVICES, {})
|
||||
device = devices.setdefault(uart_id, {})
|
||||
|
||||
if require_tx:
|
||||
hub_schema[
|
||||
cv.Required(
|
||||
CONF_TX_PIN,
|
||||
msg=f"Component {name} requires this uart bus to declare a tx_pin",
|
||||
)
|
||||
] = validate_pin(CONF_TX_PIN, device)
|
||||
if require_rx:
|
||||
hub_schema[
|
||||
cv.Required(
|
||||
CONF_RX_PIN,
|
||||
msg=f"Component {name} requires this uart bus to declare a rx_pin",
|
||||
)
|
||||
] = validate_pin(CONF_RX_PIN, device)
|
||||
if baud_rate is not None:
|
||||
hub_schema[cv.Required(CONF_BAUD_RATE)] = validate_baud_rate
|
||||
return cv.Schema(hub_schema, extra=cv.ALLOW_EXTRA)(hub_config)
|
||||
|
||||
return cv.Schema(
|
||||
{cv.Required(CONF_UART_ID): fv.id_declaration_match_schema(validate_hub)},
|
||||
extra=cv.ALLOW_EXTRA,
|
||||
)
|
||||
|
||||
|
||||
async def register_uart_device(var, config):
|
||||
"""Register a UART device, setting up all the internal values.
|
||||
|
Reference in New Issue
Block a user