Skip to content

Commit

Permalink
Change naming of MQTT entities to correspond with HA guidelines (#95159)
Browse files Browse the repository at this point in the history
* Set has_entity_name if device_name is set

* revert unneeded formatting change

* Add image platform

* Follow up comment

* Don't set `has_entity_name` without device name

* Only set has_entity_name if a valid name is set

* Follow device_class name and add tests

* Follow up comments add extra tests

* Move to helper - Log a warning

* fix test

* Allow to assign None as name explictly

* Refactor

* Log info messages when device name is not set

* Revert scene schema change - no device link

* Always set has_entity_name with device mapping

* Always set `_attr_has_entity_name`

* Cleanup
  • Loading branch information
jbouwh authored Jul 21, 2023
1 parent 747f4d4 commit 447fbf5
Show file tree
Hide file tree
Showing 36 changed files with 433 additions and 66 deletions.
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
33 changes: 29 additions & 4 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 @@ -999,7 +1004,9 @@ class MqttEntity(
):
"""Representation of an MQTT entity."""

_attr_has_entity_name = True
_attr_should_poll = False
_default_name: str | None
_entity_id_format: str

def __init__(
Expand All @@ -1016,8 +1023,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 @@ -1058,8 +1065,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 @@ -1107,14 +1114,32 @@ 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)
# Only set _attr_name if it is needed
if entity_name is not UNDEFINED:
self._attr_name = entity_name
elif not self._default_to_device_class_name():
# Assign the default name
self._attr_name = self._default_name
if CONF_DEVICE in config:
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
3 changes: 2 additions & 1 deletion homeassistant/components/mqtt/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
vol.Optional(CONF_EXPIRE_AFTER): cv.positive_int,
vol.Optional(CONF_FORCE_UPDATE, default=DEFAULT_FORCE_UPDATE): cv.boolean,
vol.Optional(CONF_LAST_RESET_VALUE_TEMPLATE): cv.template,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_NAME): vol.Any(cv.string, None),
vol.Optional(CONF_SUGGESTED_DISPLAY_PRECISION): cv.positive_int,
vol.Optional(CONF_STATE_CLASS): vol.Any(STATE_CLASSES_SCHEMA, None),
vol.Optional(CONF_UNIT_OF_MEASUREMENT): vol.Any(cv.string, None),
Expand Down Expand Up @@ -126,6 +126,7 @@ async def _async_setup_entity(
class MqttSensor(MqttEntity, RestoreSensor):
"""Representation of a sensor that can be updated using MQTT."""

_default_name = DEFAULT_NAME
_entity_id_format = ENTITY_ID_FORMAT
_attr_last_reset: datetime | None = None
_attributes_extra_blocked = MQTT_SENSOR_ATTRIBUTES_BLOCKED
Expand Down
Loading

0 comments on commit 447fbf5

Please sign in to comment.