mirror of
https://github.com/esphome/esphome.git
synced 2026-10-07 11:26:39 +00:00
[uart] Validate parity and stop bits correctly (#20161)
This commit is contained in:
@@ -489,7 +489,8 @@ def final_validate_device_schema(
|
||||
return value
|
||||
|
||||
def validate_stop_bits(value):
|
||||
if value != stop_bits:
|
||||
# usb_uart channels store stop bits as strings ("1", "1.5", "2").
|
||||
if float(value) != stop_bits:
|
||||
raise cv.Invalid(
|
||||
f"Component {name} requires {stop_bits} stop bits for the uart referenced by {uart_bus}"
|
||||
)
|
||||
|
||||
@@ -155,7 +155,22 @@ class USBUartChannelBase : public uart::UARTComponent, public Parented<USBUartCo
|
||||
// Re-apply the current line settings (baud, parity, etc) to this already-open channel.
|
||||
void load_settings(bool dump_config) override;
|
||||
using UARTComponent::load_settings; // also bring in the no-arg overload for convenience
|
||||
void set_parity(UARTParityOptions parity) { this->parity_ = parity; }
|
||||
void set_parity(UARTParityOptions parity) {
|
||||
this->parity_ = parity;
|
||||
// Keep the base-class parity in sync so uart::UARTComponent::get_parity() reports the configured value.
|
||||
// MARK/SPACE have no uart:: equivalent and report as NONE.
|
||||
switch (parity) {
|
||||
case UART_CONFIG_PARITY_EVEN:
|
||||
uart::UARTComponent::set_parity(uart::UART_CONFIG_PARITY_EVEN);
|
||||
break;
|
||||
case UART_CONFIG_PARITY_ODD:
|
||||
uart::UARTComponent::set_parity(uart::UART_CONFIG_PARITY_ODD);
|
||||
break;
|
||||
default:
|
||||
uart::UARTComponent::set_parity(uart::UART_CONFIG_PARITY_NONE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
void set_debug(bool debug) { this->debug_ = debug; }
|
||||
void set_dummy_receiver(bool dummy_receiver) { this->dummy_receiver_ = dummy_receiver; }
|
||||
void set_debug_prefix(const char *prefix) { this->debug_prefix_ = StringRef(prefix); }
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
"""Tests for final validation of UART device requirements against usb_uart channels."""
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from esphome import config, yaml_util
|
||||
from esphome.core import CORE
|
||||
|
||||
USB_UART_CONFIG = """
|
||||
esphome:
|
||||
name: usb-uart-final-validate
|
||||
esp32:
|
||||
variant: esp32s3
|
||||
framework:
|
||||
type: esp-idf
|
||||
usb_uart:
|
||||
- type: ch340
|
||||
channels:
|
||||
- id: meter_uart
|
||||
baud_rate: 1200
|
||||
stop_bits: {stop_bits}
|
||||
sensor:
|
||||
- platform: kamstrup_kmp
|
||||
uart_id: meter_uart
|
||||
heat_energy:
|
||||
name: Heat energy
|
||||
"""
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("stop_bits", "valid"), [("2", True), ("1", False), ("1.5", False)]
|
||||
)
|
||||
def test_stop_bits_requirement_on_usb_uart_channel(
|
||||
stop_bits: str, valid: bool, tmp_path: Path
|
||||
) -> None:
|
||||
"""usb_uart stores stop bits as strings; they must still satisfy a numeric requirement."""
|
||||
path = tmp_path / "usb_uart.yaml"
|
||||
path.write_text(USB_UART_CONFIG.format(stop_bits=stop_bits), encoding="utf-8")
|
||||
CORE.config_path = path
|
||||
result = config.validate_config(yaml_util.load_yaml(path), {})
|
||||
errors = [str(err) for err in result.errors]
|
||||
if valid:
|
||||
assert errors == []
|
||||
else:
|
||||
assert any("requires 2 stop bits" in err for err in errors), errors
|
||||
Reference in New Issue
Block a user