Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change naming of MQTT entities to correspond with HA guidelines #95159

Merged
merged 17 commits into from
Jul 21, 2023
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion homeassistant/components/mqtt/alarm_control_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
CONF_COMMAND_TEMPLATE, default=DEFAULT_COMMAND_TEMPLATE
): cv.template,
vol.Required(CONF_COMMAND_TOPIC): valid_publish_topic,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_NAME): vol.Any(cv.string, None),
vol.Optional(CONF_PAYLOAD_ARM_AWAY, default=DEFAULT_ARM_AWAY): cv.string,
vol.Optional(CONF_PAYLOAD_ARM_HOME, default=DEFAULT_ARM_HOME): cv.string,
vol.Optional(CONF_PAYLOAD_ARM_NIGHT, default=DEFAULT_ARM_NIGHT): cv.string,
Expand Down Expand Up @@ -136,6 +136,7 @@ async def _async_setup_entity(
class MqttAlarm(MqttEntity, alarm.AlarmControlPanelEntity):
"""Representation of a MQTT alarm status."""

_default_name = DEFAULT_NAME
_entity_id_format = alarm.ENTITY_ID_FORMAT
_attributes_extra_blocked = MQTT_ALARM_ATTRIBUTES_BLOCKED

Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/mqtt/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
vol.Optional(CONF_DEVICE_CLASS): vol.Any(DEVICE_CLASSES_SCHEMA, None),
vol.Optional(CONF_EXPIRE_AFTER): cv.positive_int,
vol.Optional(CONF_FORCE_UPDATE, default=DEFAULT_FORCE_UPDATE): cv.boolean,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_NAME): vol.Any(cv.string, None),
vol.Optional(CONF_OFF_DELAY): cv.positive_int,
vol.Optional(CONF_PAYLOAD_OFF, default=DEFAULT_PAYLOAD_OFF): cv.string,
vol.Optional(CONF_PAYLOAD_ON, default=DEFAULT_PAYLOAD_ON): cv.string,
Expand Down Expand Up @@ -97,6 +97,7 @@ async def _async_setup_entity(
class MqttBinarySensor(MqttEntity, BinarySensorEntity, RestoreEntity):
"""Representation a binary sensor that is updated by MQTT."""

_default_name = DEFAULT_NAME
_entity_id_format = binary_sensor.ENTITY_ID_FORMAT
_expired: bool | None
_expire_after: int | None
Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/mqtt/button.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
vol.Optional(CONF_COMMAND_TEMPLATE): cv.template,
vol.Required(CONF_COMMAND_TOPIC): valid_publish_topic,
vol.Optional(CONF_DEVICE_CLASS): vol.Any(DEVICE_CLASSES_SCHEMA, None),
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_NAME): vol.Any(cv.string, None),
vol.Optional(CONF_PAYLOAD_PRESS, default=DEFAULT_PAYLOAD_PRESS): cv.string,
vol.Optional(CONF_RETAIN, default=DEFAULT_RETAIN): cv.boolean,
}
Expand Down Expand Up @@ -70,6 +70,7 @@ async def _async_setup_entity(
class MqttButton(MqttEntity, ButtonEntity):
"""Representation of a switch that can be toggled using MQTT."""

_default_name = DEFAULT_NAME
_entity_id_format = button.ENTITY_ID_FORMAT

def __init__(
Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/mqtt/camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@

PLATFORM_SCHEMA_BASE = MQTT_BASE_SCHEMA.extend(
{
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_NAME): vol.Any(cv.string, None),
vol.Required(CONF_TOPIC): valid_subscribe_topic,
vol.Optional(CONF_IMAGE_ENCODING): "b64",
}
Expand Down Expand Up @@ -80,6 +80,7 @@ async def _async_setup_entity(
class MqttCamera(MqttEntity, Camera):
"""representation of a MQTT camera."""

_default_name = DEFAULT_NAME
_entity_id_format: str = camera.ENTITY_ID_FORMAT
_attributes_extra_blocked: frozenset[str] = MQTT_CAMERA_ATTRIBUTES_BLOCKED

Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/mqtt/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ def valid_humidity_state_configuration(config: ConfigType) -> ConfigType:
): cv.ensure_list,
vol.Optional(CONF_MODE_STATE_TEMPLATE): cv.template,
vol.Optional(CONF_MODE_STATE_TOPIC): valid_subscribe_topic,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_NAME): vol.Any(cv.string, None),
vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean,
vol.Optional(CONF_PAYLOAD_ON, default="ON"): cv.string,
vol.Optional(CONF_PAYLOAD_OFF, default="OFF"): cv.string,
Expand Down Expand Up @@ -597,6 +597,7 @@ async def async_set_temperature(self, **kwargs: Any) -> None:
class MqttClimate(MqttTemperatureControlEntity, ClimateEntity):
"""Representation of an MQTT climate device."""

_default_name = DEFAULT_NAME
_entity_id_format = climate.ENTITY_ID_FORMAT
_attributes_extra_blocked = MQTT_CLIMATE_ATTRIBUTES_BLOCKED

Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/mqtt/cover.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ def validate_options(config: ConfigType) -> ConfigType:
vol.Optional(CONF_COMMAND_TOPIC): valid_publish_topic,
vol.Optional(CONF_DEVICE_CLASS): vol.Any(DEVICE_CLASSES_SCHEMA, None),
vol.Optional(CONF_GET_POSITION_TOPIC): valid_subscribe_topic,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_NAME): vol.Any(cv.string, None),
vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean,
vol.Optional(CONF_PAYLOAD_CLOSE, default=DEFAULT_PAYLOAD_CLOSE): vol.Any(
cv.string, None
Expand Down Expand Up @@ -236,6 +236,7 @@ async def _async_setup_entity(
class MqttCover(MqttEntity, CoverEntity):
"""Representation of a cover that can be controlled using MQTT."""

_default_name = DEFAULT_NAME
_entity_id_format: str = cover.ENTITY_ID_FORMAT
_attributes_extra_blocked: frozenset[str] = MQTT_COVER_ATTRIBUTES_BLOCKED

Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/mqtt/device_tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def valid_config(config: ConfigType) -> ConfigType:
{
vol.Optional(CONF_STATE_TOPIC): valid_subscribe_topic,
vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
vol.Optional(CONF_NAME): cv.string,
vol.Optional(CONF_NAME): vol.Any(cv.string, None),
vol.Optional(CONF_PAYLOAD_HOME, default=STATE_HOME): cv.string,
vol.Optional(CONF_PAYLOAD_NOT_HOME, default=STATE_NOT_HOME): cv.string,
vol.Optional(CONF_PAYLOAD_RESET, default=DEFAULT_PAYLOAD_RESET): cv.string,
Expand Down Expand Up @@ -104,6 +104,7 @@ async def _async_setup_entity(
class MqttDeviceTracker(MqttEntity, TrackerEntity):
"""Representation of a device tracker using MQTT."""

_default_name = None
_entity_id_format = device_tracker.ENTITY_ID_FORMAT
_value_template: Callable[..., ReceivePayloadType]

Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/mqtt/fan.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ def valid_preset_mode_configuration(config: ConfigType) -> ConfigType:

_PLATFORM_SCHEMA_BASE = MQTT_RW_SCHEMA.extend(
{
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_NAME): vol.Any(cv.string, None),
vol.Optional(CONF_COMMAND_TEMPLATE): cv.template,
vol.Optional(CONF_DIRECTION_COMMAND_TOPIC): valid_publish_topic,
vol.Optional(CONF_DIRECTION_COMMAND_TEMPLATE): cv.template,
Expand Down Expand Up @@ -215,6 +215,7 @@ async def _async_setup_entity(
class MqttFan(MqttEntity, FanEntity):
"""A MQTT fan component."""

_default_name = DEFAULT_NAME
_entity_id_format = fan.ENTITY_ID_FORMAT
_attributes_extra_blocked = MQTT_FAN_ATTRIBUTES_BLOCKED

Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/mqtt/humidifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ def valid_humidity_range_configuration(config: ConfigType) -> ConfigType:
vol.Optional(CONF_MODE_COMMAND_TEMPLATE): cv.template,
vol.Optional(CONF_MODE_STATE_TOPIC): valid_subscribe_topic,
vol.Optional(CONF_MODE_STATE_TEMPLATE): cv.template,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_NAME): vol.Any(cv.string, None),
vol.Optional(CONF_PAYLOAD_OFF, default=DEFAULT_PAYLOAD_OFF): cv.string,
vol.Optional(CONF_PAYLOAD_ON, default=DEFAULT_PAYLOAD_ON): cv.string,
vol.Optional(CONF_STATE_VALUE_TEMPLATE): cv.template,
Expand Down Expand Up @@ -207,6 +207,7 @@ async def _async_setup_entity(
class MqttHumidifier(MqttEntity, HumidifierEntity):
"""A MQTT humidifier component."""

_default_name = DEFAULT_NAME
_entity_id_format = humidifier.ENTITY_ID_FORMAT
_attributes_extra_blocked = MQTT_HUMIDIFIER_ATTRIBUTES_BLOCKED

Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/mqtt/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def validate_topic_required(config: ConfigType) -> ConfigType:
PLATFORM_SCHEMA_BASE = MQTT_BASE_SCHEMA.extend(
{
vol.Optional(CONF_CONTENT_TYPE): cv.string,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_NAME): vol.Any(cv.string, None),
vol.Exclusive(CONF_URL_TOPIC, "image_topic"): valid_subscribe_topic,
vol.Exclusive(CONF_IMAGE_TOPIC, "image_topic"): valid_subscribe_topic,
vol.Optional(CONF_IMAGE_ENCODING): "b64",
Expand Down Expand Up @@ -102,6 +102,7 @@ async def _async_setup_entity(
class MqttImage(MqttEntity, ImageEntity):
"""representation of a MQTT image."""

_default_name = DEFAULT_NAME
_entity_id_format: str = image.ENTITY_ID_FORMAT
_last_image: bytes | None = None
_client: httpx.AsyncClient
Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/mqtt/light/schema_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@
vol.Optional(CONF_HS_VALUE_TEMPLATE): cv.template,
vol.Optional(CONF_MAX_MIREDS): cv.positive_int,
vol.Optional(CONF_MIN_MIREDS): cv.positive_int,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_NAME): vol.Any(cv.string, None),
vol.Optional(CONF_ON_COMMAND_TYPE, default=DEFAULT_ON_COMMAND_TYPE): vol.In(
VALUES_ON_COMMAND_TYPE
),
Expand Down Expand Up @@ -242,6 +242,7 @@ async def async_setup_entity_basic(
class MqttLight(MqttEntity, LightEntity, RestoreEntity):
"""Representation of a MQTT light."""

_default_name = DEFAULT_NAME
_entity_id_format = ENTITY_ID_FORMAT
_attributes_extra_blocked = MQTT_LIGHT_ATTRIBUTES_BLOCKED
_topic: dict[str, str | None]
Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/mqtt/light/schema_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ def valid_color_configuration(config: ConfigType) -> ConfigType:
vol.Optional(CONF_HS, default=DEFAULT_HS): cv.boolean,
vol.Optional(CONF_MAX_MIREDS): cv.positive_int,
vol.Optional(CONF_MIN_MIREDS): cv.positive_int,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_NAME): vol.Any(cv.string, None),
vol.Optional(CONF_QOS, default=DEFAULT_QOS): vol.All(
vol.Coerce(int), vol.In([0, 1, 2])
),
Expand Down Expand Up @@ -180,6 +180,7 @@ async def async_setup_entity_json(
class MqttLightJson(MqttEntity, LightEntity, RestoreEntity):
"""Representation of a MQTT JSON light."""

_default_name = DEFAULT_NAME
_entity_id_format = ENTITY_ID_FORMAT
_attributes_extra_blocked = MQTT_LIGHT_ATTRIBUTES_BLOCKED

Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/mqtt/light/schema_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@
vol.Optional(CONF_GREEN_TEMPLATE): cv.template,
vol.Optional(CONF_MAX_MIREDS): cv.positive_int,
vol.Optional(CONF_MIN_MIREDS): cv.positive_int,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_NAME): vol.Any(cv.string, None),
vol.Optional(CONF_RED_TEMPLATE): cv.template,
vol.Optional(CONF_STATE_TEMPLATE): cv.template,
}
Expand Down Expand Up @@ -128,6 +128,7 @@ async def async_setup_entity_template(
class MqttLightTemplate(MqttEntity, LightEntity, RestoreEntity):
"""Representation of a MQTT Template light."""

_default_name = DEFAULT_NAME
_entity_id_format = ENTITY_ID_FORMAT
_attributes_extra_blocked = MQTT_LIGHT_ATTRIBUTES_BLOCKED
_optimistic: bool
Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/mqtt/lock.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
{
vol.Optional(CONF_CODE_FORMAT): cv.is_regex,
vol.Optional(CONF_COMMAND_TEMPLATE): cv.template,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_NAME): vol.Any(cv.string, None),
vol.Optional(CONF_PAYLOAD_LOCK, default=DEFAULT_PAYLOAD_LOCK): cv.string,
vol.Optional(CONF_PAYLOAD_UNLOCK, default=DEFAULT_PAYLOAD_UNLOCK): cv.string,
vol.Optional(CONF_PAYLOAD_OPEN): cv.string,
Expand Down Expand Up @@ -126,6 +126,7 @@ async def _async_setup_entity(
class MqttLock(MqttEntity, LockEntity):
"""Representation of a lock that can be toggled using MQTT."""

_default_name = DEFAULT_NAME
_entity_id_format = lock.ENTITY_ID_FORMAT
_attributes_extra_blocked = MQTT_LOCK_ATTRIBUTES_BLOCKED

Expand Down
46 changes: 41 additions & 5 deletions homeassistant/components/mqtt/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,12 @@
async_track_device_registry_updated_event,
async_track_entity_registry_updated_event,
)
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from homeassistant.helpers.typing import (
UNDEFINED,
ConfigType,
DiscoveryInfoType,
UndefinedType,
)
from homeassistant.util.json import json_loads

from . import debug_info, subscription
Expand Down Expand Up @@ -205,7 +210,7 @@ def validate_device_has_at_least_one_identifier(value: ConfigType) -> ConfigType
),
vol.Optional(CONF_MANUFACTURER): cv.string,
vol.Optional(CONF_MODEL): cv.string,
vol.Optional(CONF_NAME): cv.string,
vol.Optional(CONF_NAME): vol.Any(cv.string, None),
jbouwh marked this conversation as resolved.
Show resolved Hide resolved
vol.Optional(CONF_HW_VERSION): cv.string,
vol.Optional(CONF_SW_VERSION): cv.string,
vol.Optional(CONF_VIA_DEVICE): cv.string,
Expand Down Expand Up @@ -1008,6 +1013,7 @@ class MqttEntity(
"""Representation of an MQTT entity."""

_attr_should_poll = False
jbouwh marked this conversation as resolved.
Show resolved Hide resolved
_default_name: str | None
jbouwh marked this conversation as resolved.
Show resolved Hide resolved
_entity_id_format: str

def __init__(
Expand All @@ -1024,8 +1030,8 @@ def __init__(
self._sub_state: dict[str, EntitySubscription] = {}

# Load config
self._setup_common_attributes_from_config(self._config)
self._setup_from_config(self._config)
self._setup_common_attributes_from_config(self._config)

# Initialize entity_id from config
self._init_entity_id()
Expand Down Expand Up @@ -1066,8 +1072,8 @@ async def discovery_update(self, discovery_payload: MQTTDiscoveryPayload) -> Non
async_handle_schema_error(discovery_payload, err)
return
self._config = config
self._setup_common_attributes_from_config(self._config)
self._setup_from_config(self._config)
self._setup_common_attributes_from_config(self._config)

# Prepare MQTT subscriptions
self.attributes_prepare_discovery_update(config)
Expand Down Expand Up @@ -1115,14 +1121,44 @@ async def async_publish(
def config_schema() -> vol.Schema:
"""Return the config schema."""

def _set_entity_name(self, config: ConfigType) -> None:
"""Help setting the entity name if needed."""
entity_name: str | None | UndefinedType = config.get(CONF_NAME, UNDEFINED)
jbouwh marked this conversation as resolved.
Show resolved Hide resolved
# Only set _attr_name if it is needed
if entity_name is not UNDEFINED:
self._attr_name = entity_name
elif not (use_device_class_name := self._default_to_device_class_name()):
# Assign the default name
self._attr_name = self._default_name
elif use_device_class_name:
# Follow name of device class
self._attr_has_entity_name = True
if CONF_DEVICE in config and CONF_NAME not in config[CONF_DEVICE]:
_LOGGER.info(
jbouwh marked this conversation as resolved.
Show resolved Hide resolved
"MQTT device information always needs to include a name, got %s, "
"if device information is shared between multiple entities, the device "
"name must be included in each entity's device configuration",
config,
)
return
jbouwh marked this conversation as resolved.
Show resolved Hide resolved
if CONF_DEVICE in config:
self._attr_has_entity_name = True
jbouwh marked this conversation as resolved.
Show resolved Hide resolved
if CONF_NAME not in config[CONF_DEVICE]:
_LOGGER.info(
"MQTT device information always needs to include a name, got %s, "
"if device information is shared between multiple entities, the device "
"name must be included in each entity's device configuration",
)

def _setup_common_attributes_from_config(self, config: ConfigType) -> None:
"""(Re)Setup the common attributes for the entity."""
self._attr_entity_category = config.get(CONF_ENTITY_CATEGORY)
self._attr_entity_registry_enabled_default = bool(
config.get(CONF_ENABLED_BY_DEFAULT)
)
self._attr_icon = config.get(CONF_ICON)
self._attr_name = config.get(CONF_NAME)
# Set the entity name if needed
self._set_entity_name(config)

def _setup_from_config(self, config: ConfigType) -> None:
"""(Re)Setup the entity."""
Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/mqtt/number.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def validate_config(config: ConfigType) -> ConfigType:
vol.Optional(CONF_MAX, default=DEFAULT_MAX_VALUE): vol.Coerce(float),
vol.Optional(CONF_MIN, default=DEFAULT_MIN_VALUE): vol.Coerce(float),
vol.Optional(CONF_MODE, default=NumberMode.AUTO): vol.Coerce(NumberMode),
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_NAME): vol.Any(cv.string, None),
vol.Optional(CONF_PAYLOAD_RESET, default=DEFAULT_PAYLOAD_RESET): cv.string,
vol.Optional(CONF_STEP, default=DEFAULT_STEP): vol.All(
vol.Coerce(float), vol.Range(min=1e-3)
Expand Down Expand Up @@ -134,6 +134,7 @@ async def _async_setup_entity(
class MqttNumber(MqttEntity, RestoreNumber):
"""representation of an MQTT number."""

_default_name = DEFAULT_NAME
_entity_id_format = number.ENTITY_ID_FORMAT
_attributes_extra_blocked = MQTT_NUMBER_ATTRIBUTES_BLOCKED

Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/mqtt/scene.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
{
vol.Required(CONF_COMMAND_TOPIC): valid_publish_topic,
vol.Optional(CONF_ICON): cv.icon,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_NAME): cv.string,
vol.Optional(CONF_PAYLOAD_ON): cv.string,
vol.Optional(CONF_UNIQUE_ID): cv.string,
vol.Optional(CONF_RETAIN, default=DEFAULT_RETAIN): cv.boolean,
Expand Down Expand Up @@ -77,6 +77,7 @@ class MqttScene(
):
"""Representation of a scene that can be activated using MQTT."""

_default_name = DEFAULT_NAME
_entity_id_format = scene.DOMAIN + ".{}"

def __init__(
Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/mqtt/select.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
PLATFORM_SCHEMA_MODERN = MQTT_RW_SCHEMA.extend(
{
vol.Optional(CONF_COMMAND_TEMPLATE): cv.template,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_NAME): vol.Any(cv.string, None),
vol.Required(CONF_OPTIONS): cv.ensure_list,
vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
},
Expand Down Expand Up @@ -89,6 +89,7 @@ async def _async_setup_entity(
class MqttSelect(MqttEntity, SelectEntity, RestoreEntity):
"""representation of an MQTT select."""

_default_name = DEFAULT_NAME
_entity_id_format = select.ENTITY_ID_FORMAT
_attributes_extra_blocked = MQTT_SELECT_ATTRIBUTES_BLOCKED
_command_template: Callable[[PublishPayloadType], PublishPayloadType]
Expand Down
Loading