mirror of
https://github.com/esphome/esphome.git
synced 2026-10-05 18:41:32 +00:00
Merge remote-tracking branch 'upstream/dev' into integration
This commit is contained in:
@@ -11,3 +11,4 @@ display:
|
||||
dc_pin: 21
|
||||
reset_pin: 22
|
||||
invert_colors: false
|
||||
data_rate: 10MHz
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
esp32_ble_tracker:
|
||||
|
||||
sensor:
|
||||
- platform: bthome_mithermometer
|
||||
mac_address: A4:C1:38:4E:16:78
|
||||
temperature:
|
||||
name: "BTHome Temperature"
|
||||
humidity:
|
||||
name: "BTHome Humidity"
|
||||
battery_level:
|
||||
name: "BTHome Battery"
|
||||
battery_voltage:
|
||||
name: "BTHome Battery Voltage"
|
||||
signal_strength:
|
||||
name: "BTHome Signal"
|
||||
@@ -0,0 +1,4 @@
|
||||
packages:
|
||||
ble: !include ../../test_build_components/common/ble/esp32-idf.yaml
|
||||
|
||||
<<: !include common.yaml
|
||||
@@ -9,6 +9,7 @@ display:
|
||||
invert_colors: True
|
||||
cs_pin: 20
|
||||
dc_pin: 21
|
||||
data_rate: 20MHz
|
||||
pages:
|
||||
- id: page1
|
||||
lambda: |-
|
||||
|
||||
@@ -6,6 +6,7 @@ display:
|
||||
dc_pin: 13
|
||||
reset_pin: 21
|
||||
invert_colors: false
|
||||
data_rate: 20MHz
|
||||
lambda: |-
|
||||
// Draw an analog clock in the center of the screen
|
||||
int centerX = it.get_width() / 2;
|
||||
|
||||
@@ -11,6 +11,7 @@ display:
|
||||
cs_pin: ${cs_pin1}
|
||||
dc_pin: ${dc_pin1}
|
||||
reset_pin: ${reset_pin1}
|
||||
data_rate: 20MHz
|
||||
lambda: |-
|
||||
it.rectangle(0, 0, it.get_width(), it.get_height());
|
||||
- platform: ili9xxx
|
||||
@@ -27,5 +28,6 @@ display:
|
||||
reset_pin: ${reset_pin2}
|
||||
auto_clear_enabled: false
|
||||
rotation: 90
|
||||
data_rate: 20MHz
|
||||
lambda: |-
|
||||
it.fill(Color::WHITE);
|
||||
|
||||
@@ -9,6 +9,7 @@ display:
|
||||
cs_pin: 20
|
||||
dc_pin: 21
|
||||
reset_pin: 22
|
||||
data_rate: 20MHz
|
||||
invert_colors: true
|
||||
|
||||
<<: !include common.yaml
|
||||
|
||||
@@ -8,6 +8,7 @@ display:
|
||||
spi_id: spi_bus
|
||||
id: main_lcd
|
||||
model: ili9342
|
||||
data_rate: 20MHz
|
||||
cs_pin: 20
|
||||
dc_pin: 17
|
||||
reset_pin: 21
|
||||
|
||||
@@ -5,6 +5,7 @@ display:
|
||||
cs_pin: ${cs_pin}
|
||||
dc_pin: ${dc_pin}
|
||||
reset_pin: ${reset_pin}
|
||||
data_rate: 500kHz
|
||||
invert_colors: false
|
||||
lambda: |-
|
||||
// Draw a QR code in the center of the screen
|
||||
|
||||
@@ -6,6 +6,7 @@ display:
|
||||
cs_pin: ${disp_cs_pin}
|
||||
dc_pin: ${dc_pin}
|
||||
reset_pin: ${reset_pin}
|
||||
data_rate: 20MHz
|
||||
invert_colors: false
|
||||
lambda: |-
|
||||
it.rectangle(0, 0, it.get_width(), it.get_height());
|
||||
|
||||
@@ -502,3 +502,60 @@ def test_only_with_user_value_overrides_default() -> None:
|
||||
|
||||
result = schema({"mqtt_id": "custom_id"})
|
||||
assert result.get("mqtt_id") == "custom_id"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value", ("hello", "Hello World", "test_name", "温度"))
|
||||
def test_string_no_slash__valid(value: str) -> None:
|
||||
actual = config_validation.string_no_slash(value)
|
||||
assert actual == value
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value", ("has/slash", "a/b/c", "/leading", "trailing/"))
|
||||
def test_string_no_slash__slash_rejected(value: str) -> None:
|
||||
with pytest.raises(Invalid, match="cannot contain '/' character"):
|
||||
config_validation.string_no_slash(value)
|
||||
|
||||
|
||||
def test_string_no_slash__long_string_allowed() -> None:
|
||||
# string_no_slash doesn't enforce length - use cv.Length() separately
|
||||
long_value = "x" * 200
|
||||
assert config_validation.string_no_slash(long_value) == long_value
|
||||
|
||||
|
||||
def test_string_no_slash__empty() -> None:
|
||||
assert config_validation.string_no_slash("") == ""
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value", ("Temperature", "Living Room Light", "温度传感器"))
|
||||
def test_validate_entity_name__valid(value: str) -> None:
|
||||
actual = config_validation._validate_entity_name(value)
|
||||
assert actual == value
|
||||
|
||||
|
||||
def test_validate_entity_name__slash_rejected() -> None:
|
||||
with pytest.raises(Invalid, match="cannot contain '/' character"):
|
||||
config_validation._validate_entity_name("has/slash")
|
||||
|
||||
|
||||
def test_validate_entity_name__max_length() -> None:
|
||||
# 120 chars should pass
|
||||
assert config_validation._validate_entity_name("x" * 120) == "x" * 120
|
||||
|
||||
# 121 chars should fail
|
||||
with pytest.raises(Invalid, match="too long.*121 chars.*Maximum.*120"):
|
||||
config_validation._validate_entity_name("x" * 121)
|
||||
|
||||
|
||||
def test_validate_entity_name__none_without_friendly_name() -> None:
|
||||
# When name is "None" and friendly_name is not set, it should fail
|
||||
CORE.friendly_name = None
|
||||
with pytest.raises(Invalid, match="friendly_name is not set"):
|
||||
config_validation._validate_entity_name("None")
|
||||
|
||||
|
||||
def test_validate_entity_name__none_with_friendly_name() -> None:
|
||||
# When name is "None" but friendly_name is set, it should return None
|
||||
CORE.friendly_name = "My Device"
|
||||
result = config_validation._validate_entity_name("None")
|
||||
assert result is None
|
||||
CORE.friendly_name = None # Reset
|
||||
|
||||
Reference in New Issue
Block a user