Add MQTT select subentry support (#153637)

This commit is contained in:
Jan Bouwhuis
2025-10-10 13:46:21 +02:00
committed by GitHub
parent 07f3e00f18
commit cdec29ffb7
4 changed files with 71 additions and 0 deletions

View File

@@ -458,6 +458,7 @@ SUBENTRY_PLATFORMS = [
Platform.LOCK,
Platform.NOTIFY,
Platform.NUMBER,
Platform.SELECT,
Platform.SENSOR,
Platform.SWITCH,
]
@@ -1141,6 +1142,7 @@ ENTITY_CONFIG_VALIDATOR: dict[
Platform.LOCK.value: None,
Platform.NOTIFY.value: None,
Platform.NUMBER.value: validate_number_platform_config,
Platform.SELECT: None,
Platform.SENSOR.value: validate_sensor_platform_config,
Platform.SWITCH.value: None,
}
@@ -1367,6 +1369,7 @@ PLATFORM_ENTITY_FIELDS: dict[str, dict[str, PlatformField]] = {
custom_filtering=True,
),
},
Platform.SELECT.value: {},
Platform.SENSOR.value: {
CONF_DEVICE_CLASS: PlatformField(
selector=SENSOR_DEVICE_CLASS_SELECTOR, required=False
@@ -3103,6 +3106,34 @@ PLATFORM_MQTT_FIELDS: dict[str, dict[str, PlatformField]] = {
),
CONF_RETAIN: PlatformField(selector=BOOLEAN_SELECTOR, required=False),
},
Platform.SELECT.value: {
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_OPTIONS: PlatformField(selector=OPTIONS_SELECTOR, required=True),
CONF_RETAIN: PlatformField(selector=BOOLEAN_SELECTOR, required=False),
},
Platform.SENSOR.value: {
CONF_STATE_TOPIC: PlatformField(
selector=TEXT_SELECTOR,

View File

@@ -346,6 +346,7 @@
"mode_state_template": "Operation mode value template",
"on_command_type": "ON command type",
"optimistic": "Optimistic",
"options": "Set options",
"payload_off": "Payload \"off\"",
"payload_on": "Payload \"on\"",
"payload_press": "Payload \"press\"",
@@ -393,6 +394,7 @@
"mode_state_template": "Defines a [template](https://www.home-assistant.io/docs/configuration/templating/#using-value-templates-with-mqtt) to extract the operation mode state. [Learn more.]({url}#mode_state_template)",
"on_command_type": "Defines when the payload \"on\" is sent. Using \"Last\" (the default) will send any style (brightness, color, etc) topics first and then a payload \"on\" to the command topic. Using \"First\" will send the payload \"on\" and then any style topics. Using \"Brightness\" will only send brightness commands instead of the payload \"on\" to turn the light on.",
"optimistic": "Flag that defines if the {platform} entity works in optimistic mode. [Learn more.]({url}#optimistic)",
"options": "List of options that can be selected.",
"payload_off": "The payload that represents the \"off\" state.",
"payload_on": "The payload that represents the \"on\" state.",
"payload_press": "The payload to send when the button is triggered.",
@@ -1334,6 +1336,7 @@
"lock": "[%key:component::lock::title%]",
"notify": "[%key:component::notify::title%]",
"number": "[%key:component::number::title%]",
"select": "[%key:component::select::title%]",
"sensor": "[%key:component::sensor::title%]",
"switch": "[%key:component::switch::title%]"
}

View File

@@ -517,6 +517,20 @@ MOCK_SUBENTRY_NUMBER_COMPONENT_NO_UNIT = {
"entity_picture": "https://example.com/f9261f6feed443e7b7d5f3fbe2a47414",
},
}
MOCK_SUBENTRY_SELECT_COMPONENT = {
"fa261f6feed443e7b7d5f3fbe2a47414": {
"platform": "select",
"name": "Mode",
"entity_category": None,
"command_topic": "test-topic",
"command_template": "{{ value }}",
"state_topic": "test-topic",
"options": ["beer", "milk"],
"value_template": "{{ value_json.value }}",
"retain": False,
"entity_picture": "https://example.com/fa261f6feed443e7b7d5f3fbe2a47414",
},
}
MOCK_SUBENTRY_SENSOR_COMPONENT = {
"e9261f6feed443e7b7d5f3fbe2a47412": {
"platform": "sensor",
@@ -668,6 +682,10 @@ MOCK_NUMBER_SUBENTRY_DATA_NO_UNIT = {
"device": MOCK_SUBENTRY_DEVICE_DATA | {"mqtt_settings": {"qos": 0}},
"components": MOCK_SUBENTRY_NUMBER_COMPONENT_NO_UNIT,
}
MOCK_SELECT_SUBENTRY_DATA = {
"device": MOCK_SUBENTRY_DEVICE_DATA | {"mqtt_settings": {"qos": 0}},
"components": MOCK_SUBENTRY_SELECT_COMPONENT,
}
MOCK_SENSOR_SUBENTRY_DATA_SINGLE = {
"device": MOCK_SUBENTRY_DEVICE_DATA | {"mqtt_settings": {"qos": 0}},
"components": MOCK_SUBENTRY_SENSOR_COMPONENT,

View File

@@ -53,6 +53,7 @@ from .common import (
MOCK_NUMBER_SUBENTRY_DATA_CUSTOM_UNIT,
MOCK_NUMBER_SUBENTRY_DATA_DEVICE_CLASS_UNIT,
MOCK_NUMBER_SUBENTRY_DATA_NO_UNIT,
MOCK_SELECT_SUBENTRY_DATA,
MOCK_SENSOR_SUBENTRY_DATA_SINGLE,
MOCK_SENSOR_SUBENTRY_DATA_SINGLE_LAST_RESET_TEMPLATE,
MOCK_SENSOR_SUBENTRY_DATA_SINGLE_STATE_CLASS,
@@ -3553,6 +3554,24 @@ async def test_migrate_of_incompatible_config_entry(
"Milk notifier Speed",
id="number_no_unit",
),
pytest.param(
MOCK_SELECT_SUBENTRY_DATA,
{"name": "Milk notifier", "mqtt_settings": {"qos": 0}},
{"name": "Mode"},
{},
(),
{
"command_topic": "test-topic",
"command_template": "{{ value }}",
"state_topic": "test-topic",
"options": ["beer", "milk"],
"value_template": "{{ value_json.value }}",
"retain": False,
},
(),
"Milk notifier Mode",
id="select",
),
pytest.param(
MOCK_SENSOR_SUBENTRY_DATA_SINGLE,
{"name": "Milk notifier", "mqtt_settings": {"qos": 0}},