mirror of
https://github.com/home-assistant/core.git
synced 2025-11-20 16:26:57 +00:00
Compare commits
2 Commits
setpoint_c
...
mqtt-suben
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
466fb0131e | ||
|
|
d479bba351 |
@@ -239,6 +239,7 @@ from .const import (
|
||||
CONF_OSCILLATION_COMMAND_TOPIC,
|
||||
CONF_OSCILLATION_STATE_TOPIC,
|
||||
CONF_OSCILLATION_VALUE_TEMPLATE,
|
||||
CONF_PATTERN,
|
||||
CONF_PAYLOAD_ARM_AWAY,
|
||||
CONF_PAYLOAD_ARM_CUSTOM_BYPASS,
|
||||
CONF_PAYLOAD_ARM_HOME,
|
||||
@@ -465,6 +466,7 @@ SUBENTRY_PLATFORMS = [
|
||||
Platform.SENSOR,
|
||||
Platform.SIREN,
|
||||
Platform.SWITCH,
|
||||
Platform.TEXT,
|
||||
]
|
||||
|
||||
_CODE_VALIDATION_MODE = {
|
||||
@@ -819,6 +821,16 @@ TEMPERATURE_UNIT_SELECTOR = SelectSelector(
|
||||
mode=SelectSelectorMode.DROPDOWN,
|
||||
)
|
||||
)
|
||||
TEXT_MODE_SELECTOR = SelectSelector(
|
||||
SelectSelectorConfig(
|
||||
options=[TextSelectorType.TEXT.value, TextSelectorType.PASSWORD.value],
|
||||
mode=SelectSelectorMode.DROPDOWN,
|
||||
translation_key="text_mode",
|
||||
)
|
||||
)
|
||||
TEXT_SIZE_SELECTOR = NumberSelector(
|
||||
NumberSelectorConfig(min=0, max=255, step=1, mode=NumberSelectorMode.BOX)
|
||||
)
|
||||
|
||||
|
||||
@callback
|
||||
@@ -1151,6 +1163,22 @@ def validate_sensor_platform_config(
|
||||
return errors
|
||||
|
||||
|
||||
@callback
|
||||
def validate_text_platform_config(
|
||||
config: dict[str, Any],
|
||||
) -> dict[str, str]:
|
||||
"""Validate the text entity options."""
|
||||
errors: dict[str, str] = {}
|
||||
if (
|
||||
CONF_MIN in config
|
||||
and CONF_MAX in config
|
||||
and config[CONF_MIN] > config[CONF_MAX]
|
||||
):
|
||||
errors["text_advanced_settings"] = "max_below_min"
|
||||
|
||||
return errors
|
||||
|
||||
|
||||
ENTITY_CONFIG_VALIDATOR: dict[
|
||||
str,
|
||||
Callable[[dict[str, Any]], dict[str, str]] | None,
|
||||
@@ -1170,6 +1198,7 @@ ENTITY_CONFIG_VALIDATOR: dict[
|
||||
Platform.SENSOR: validate_sensor_platform_config,
|
||||
Platform.SIREN: None,
|
||||
Platform.SWITCH: None,
|
||||
Platform.TEXT: validate_text_platform_config,
|
||||
}
|
||||
|
||||
|
||||
@@ -1430,6 +1459,7 @@ PLATFORM_ENTITY_FIELDS: dict[Platform, dict[str, PlatformField]] = {
|
||||
selector=SWITCH_DEVICE_CLASS_SELECTOR, required=False
|
||||
),
|
||||
},
|
||||
Platform.TEXT: {},
|
||||
}
|
||||
PLATFORM_MQTT_FIELDS: dict[Platform, dict[str, PlatformField]] = {
|
||||
Platform.ALARM_CONTROL_PANEL: {
|
||||
@@ -3298,6 +3328,58 @@ PLATFORM_MQTT_FIELDS: dict[Platform, dict[str, PlatformField]] = {
|
||||
CONF_RETAIN: PlatformField(selector=BOOLEAN_SELECTOR, required=False),
|
||||
CONF_OPTIMISTIC: PlatformField(selector=BOOLEAN_SELECTOR, required=False),
|
||||
},
|
||||
Platform.TEXT: {
|
||||
CONF_COMMAND_TOPIC: PlatformField(
|
||||
selector=TEXT_SELECTOR,
|
||||
required=True,
|
||||
validator=valid_publish_topic,
|
||||
error="invalid_publish_topic",
|
||||
),
|
||||
CONF_COMMAND_TEMPLATE: PlatformField(
|
||||
selector=TEMPLATE_SELECTOR,
|
||||
required=False,
|
||||
validator=validate(cv.template),
|
||||
error="invalid_template",
|
||||
),
|
||||
CONF_STATE_TOPIC: PlatformField(
|
||||
selector=TEXT_SELECTOR,
|
||||
required=False,
|
||||
validator=valid_subscribe_topic,
|
||||
error="invalid_subscribe_topic",
|
||||
),
|
||||
CONF_VALUE_TEMPLATE: PlatformField(
|
||||
selector=TEMPLATE_SELECTOR,
|
||||
required=False,
|
||||
validator=validate(cv.template),
|
||||
error="invalid_template",
|
||||
),
|
||||
CONF_RETAIN: PlatformField(selector=BOOLEAN_SELECTOR, required=False),
|
||||
CONF_MIN: PlatformField(
|
||||
selector=TEXT_SIZE_SELECTOR,
|
||||
required=True,
|
||||
default=0,
|
||||
section="text_advanced_settings",
|
||||
),
|
||||
CONF_MAX: PlatformField(
|
||||
selector=TEXT_SIZE_SELECTOR,
|
||||
required=True,
|
||||
default=255,
|
||||
section="text_advanced_settings",
|
||||
),
|
||||
CONF_MODE: PlatformField(
|
||||
selector=TEXT_MODE_SELECTOR,
|
||||
required=True,
|
||||
default=TextSelectorType.TEXT.value,
|
||||
section="text_advanced_settings",
|
||||
),
|
||||
CONF_PATTERN: PlatformField(
|
||||
selector=TEXT_SELECTOR,
|
||||
required=False,
|
||||
validator=validate(cv.is_regex),
|
||||
error="invalid_regular_expression",
|
||||
section="text_advanced_settings",
|
||||
),
|
||||
},
|
||||
}
|
||||
MQTT_DEVICE_PLATFORM_FIELDS = {
|
||||
ATTR_NAME: PlatformField(selector=TEXT_SELECTOR, required=True),
|
||||
|
||||
@@ -138,6 +138,7 @@ CONF_OSCILLATION_COMMAND_TOPIC = "oscillation_command_topic"
|
||||
CONF_OSCILLATION_COMMAND_TEMPLATE = "oscillation_command_template"
|
||||
CONF_OSCILLATION_STATE_TOPIC = "oscillation_state_topic"
|
||||
CONF_OSCILLATION_VALUE_TEMPLATE = "oscillation_value_template"
|
||||
CONF_PATTERN = "pattern"
|
||||
CONF_PAYLOAD_ARM_AWAY = "payload_arm_away"
|
||||
CONF_PAYLOAD_ARM_CUSTOM_BYPASS = "payload_arm_custom_bypass"
|
||||
CONF_PAYLOAD_ARM_HOME = "payload_arm_home"
|
||||
|
||||
@@ -970,6 +970,21 @@
|
||||
"temperature_state_topic": "The MQTT topic to subscribe for changes of the target temperature. [Learn more.]({url}#temperature_state_topic)"
|
||||
},
|
||||
"name": "Target temperature settings"
|
||||
},
|
||||
"text_advanced_settings": {
|
||||
"data": {
|
||||
"max": "Maximum length",
|
||||
"min": "Mininum length",
|
||||
"mode": "Mode",
|
||||
"pattern": "Pattern"
|
||||
},
|
||||
"data_description": {
|
||||
"max": "Maximum length of the text input",
|
||||
"min": "Mininum length of the text input",
|
||||
"mode": "Mode of the text input",
|
||||
"pattern": "A valid regex pattern"
|
||||
},
|
||||
"name": "Advanced text settings"
|
||||
}
|
||||
},
|
||||
"title": "Configure MQTT device \"{mqtt_device}\""
|
||||
@@ -1387,7 +1402,8 @@
|
||||
"select": "[%key:component::select::title%]",
|
||||
"sensor": "[%key:component::sensor::title%]",
|
||||
"siren": "[%key:component::siren::title%]",
|
||||
"switch": "[%key:component::switch::title%]"
|
||||
"switch": "[%key:component::switch::title%]",
|
||||
"text": "[%key:component::text::title%]"
|
||||
}
|
||||
},
|
||||
"set_ca_cert": {
|
||||
@@ -1424,6 +1440,12 @@
|
||||
"none": "No target temperature",
|
||||
"single": "Single target temperature"
|
||||
}
|
||||
},
|
||||
"text_mode": {
|
||||
"options": {
|
||||
"password": "[%key:common::config_flow::data::password%]",
|
||||
"text": "[%key:component::text::entity_component::_::state_attributes::mode::state::text%]"
|
||||
}
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
|
||||
@@ -27,7 +27,14 @@ from homeassistant.helpers.typing import ConfigType, VolSchemaType
|
||||
|
||||
from . import subscription
|
||||
from .config import MQTT_RW_SCHEMA
|
||||
from .const import CONF_COMMAND_TEMPLATE, CONF_COMMAND_TOPIC, CONF_STATE_TOPIC
|
||||
from .const import (
|
||||
CONF_COMMAND_TEMPLATE,
|
||||
CONF_COMMAND_TOPIC,
|
||||
CONF_MAX,
|
||||
CONF_MIN,
|
||||
CONF_PATTERN,
|
||||
CONF_STATE_TOPIC,
|
||||
)
|
||||
from .entity import MqttEntity, async_setup_entity_entry_helper
|
||||
from .models import (
|
||||
MqttCommandTemplate,
|
||||
@@ -42,12 +49,7 @@ _LOGGER = logging.getLogger(__name__)
|
||||
|
||||
PARALLEL_UPDATES = 0
|
||||
|
||||
CONF_MAX = "max"
|
||||
CONF_MIN = "min"
|
||||
CONF_PATTERN = "pattern"
|
||||
|
||||
DEFAULT_NAME = "MQTT Text"
|
||||
DEFAULT_PAYLOAD_RESET = "None"
|
||||
|
||||
MQTT_TEXT_ATTRIBUTES_BLOCKED = frozenset(
|
||||
{
|
||||
|
||||
@@ -600,6 +600,23 @@ MOCK_SUBENTRY_SWITCH_COMPONENT = {
|
||||
"optimistic": True,
|
||||
},
|
||||
}
|
||||
MOCK_SUBENTRY_TEXT_COMPONENT = {
|
||||
"09261f6feed443e7b7d5f3fbe2a47413": {
|
||||
"platform": "text",
|
||||
"name": "MOTD",
|
||||
"entity_category": None,
|
||||
"command_topic": "test-topic",
|
||||
"command_template": "{{ value }}",
|
||||
"state_topic": "test-topic",
|
||||
"min": 0.0,
|
||||
"max": 10.0,
|
||||
"mode": "password",
|
||||
"pattern": "^[a-z_]*$",
|
||||
"value_template": "{{ value_json.value }}",
|
||||
"retain": False,
|
||||
"entity_picture": "https://example.com/09261f6feed443e7b7d5f3fbe2a47413",
|
||||
},
|
||||
}
|
||||
|
||||
MOCK_SUBENTRY_AVAILABILITY_DATA = {
|
||||
"availability": {
|
||||
@@ -725,6 +742,10 @@ MOCK_SWITCH_SUBENTRY_DATA = {
|
||||
"device": MOCK_SUBENTRY_DEVICE_DATA | {"mqtt_settings": {"qos": 0}},
|
||||
"components": MOCK_SUBENTRY_SWITCH_COMPONENT,
|
||||
}
|
||||
MOCK_TEXT_SUBENTRY_DATA = {
|
||||
"device": MOCK_SUBENTRY_DEVICE_DATA | {"mqtt_settings": {"qos": 0}},
|
||||
"components": MOCK_SUBENTRY_TEXT_COMPONENT,
|
||||
}
|
||||
MOCK_SUBENTRY_DATA_BAD_COMPONENT_SCHEMA = {
|
||||
"device": MOCK_SUBENTRY_DEVICE_DATA | {"mqtt_settings": {"qos": 0}},
|
||||
"components": MOCK_SUBENTRY_NOTIFY_BAD_SCHEMA,
|
||||
|
||||
@@ -62,6 +62,7 @@ from .common import (
|
||||
MOCK_SENSOR_SUBENTRY_DATA_STATE_CLASS,
|
||||
MOCK_SIREN_SUBENTRY_DATA,
|
||||
MOCK_SWITCH_SUBENTRY_DATA,
|
||||
MOCK_TEXT_SUBENTRY_DATA,
|
||||
)
|
||||
|
||||
from tests.common import MockConfigEntry, MockMqttReasonCode, get_schema_suggested_value
|
||||
@@ -3720,6 +3721,65 @@ async def test_migrate_of_incompatible_config_entry(
|
||||
"Milk notifier Outlet",
|
||||
id="switch",
|
||||
),
|
||||
pytest.param(
|
||||
MOCK_TEXT_SUBENTRY_DATA,
|
||||
{"name": "Milk notifier", "mqtt_settings": {"qos": 0}},
|
||||
{"name": "MOTD"},
|
||||
{},
|
||||
(),
|
||||
{
|
||||
"command_topic": "test-topic",
|
||||
"command_template": "{{ value }}",
|
||||
"state_topic": "test-topic",
|
||||
"value_template": "{{ value_json.value }}",
|
||||
"retain": False,
|
||||
"text_advanced_settings": {
|
||||
"min": 0,
|
||||
"max": 10,
|
||||
"mode": "password",
|
||||
"pattern": "^[a-z_]*$",
|
||||
},
|
||||
},
|
||||
(
|
||||
(
|
||||
{"command_topic": "test-topic#invalid"},
|
||||
{"command_topic": "invalid_publish_topic"},
|
||||
),
|
||||
(
|
||||
{
|
||||
"command_topic": "test-topic",
|
||||
"state_topic": "test-topic#invalid",
|
||||
},
|
||||
{"state_topic": "invalid_subscribe_topic"},
|
||||
),
|
||||
(
|
||||
{
|
||||
"command_topic": "test-topic",
|
||||
"text_advanced_settings": {
|
||||
"min": 20,
|
||||
"max": 10,
|
||||
"mode": "password",
|
||||
"pattern": "^[a-z_]*$",
|
||||
},
|
||||
},
|
||||
{"text_advanced_settings": "max_below_min"},
|
||||
),
|
||||
(
|
||||
{
|
||||
"command_topic": "test-topic",
|
||||
"text_advanced_settings": {
|
||||
"min": 0,
|
||||
"max": 10,
|
||||
"mode": "password",
|
||||
"pattern": "(",
|
||||
},
|
||||
},
|
||||
{"text_advanced_settings": "invalid_regular_expression"},
|
||||
),
|
||||
),
|
||||
"Milk notifier MOTD",
|
||||
id="text",
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_subentry_configflow(
|
||||
|
||||
Reference in New Issue
Block a user