diff --git a/homeassistant/components/template/alarm_control_panel.py b/homeassistant/components/template/alarm_control_panel.py index af2e432c61e..2cac5d74a7a 100644 --- a/homeassistant/components/template/alarm_control_panel.py +++ b/homeassistant/components/template/alarm_control_panel.py @@ -154,8 +154,8 @@ class AlarmControlPanelTemplate(TemplateEntity, AlarmControlPanelEntity): name = self._attr_name self._template = config.get(CONF_VALUE_TEMPLATE) self._disarm_script = None - self._code_arm_required: bool = config[CONF_CODE_ARM_REQUIRED] - self._code_format: TemplateCodeFormat = config[CONF_CODE_FORMAT] + self._attr_code_arm_required: bool = config[CONF_CODE_ARM_REQUIRED] + self._attr_code_format = config[CONF_CODE_FORMAT].value if (disarm_action := config.get(CONF_DISARM_ACTION)) is not None: self._disarm_script = Script(hass, disarm_action, name, DOMAIN) self._arm_away_script = None @@ -183,14 +183,6 @@ class AlarmControlPanelTemplate(TemplateEntity, AlarmControlPanelEntity): self._state: str | None = None - @property - def state(self) -> str | None: - """Return the state of the device.""" - return self._state - - @property - def supported_features(self) -> AlarmControlPanelEntityFeature: - """Return the list of supported features.""" supported_features = AlarmControlPanelEntityFeature(0) if self._arm_night_script is not None: supported_features = ( @@ -221,18 +213,12 @@ class AlarmControlPanelTemplate(TemplateEntity, AlarmControlPanelEntity): supported_features = ( supported_features | AlarmControlPanelEntityFeature.TRIGGER ) - - return supported_features + self._attr_supported_features = supported_features @property - def code_format(self) -> CodeFormat | None: - """Regex for code format or None if no code is required.""" - return self._code_format.value - - @property - def code_arm_required(self) -> bool: - """Whether the code is required for arm actions.""" - return self._code_arm_required + def state(self) -> str | None: + """Return the state of the device.""" + return self._state @callback def _update_state(self, result): diff --git a/homeassistant/components/template/binary_sensor.py b/homeassistant/components/template/binary_sensor.py index ca0ed583d86..427fe6221cd 100644 --- a/homeassistant/components/template/binary_sensor.py +++ b/homeassistant/components/template/binary_sensor.py @@ -14,7 +14,6 @@ from homeassistant.components.binary_sensor import ( DOMAIN as BINARY_SENSOR_DOMAIN, ENTITY_ID_FORMAT, PLATFORM_SCHEMA, - BinarySensorDeviceClass, BinarySensorEntity, ) from homeassistant.config_entries import ConfigEntry @@ -236,9 +235,7 @@ class BinarySensorTemplate(TemplateEntity, BinarySensorEntity, RestoreEntity): ENTITY_ID_FORMAT, object_id, hass=hass ) - self._device_class: BinarySensorDeviceClass | None = config.get( - CONF_DEVICE_CLASS - ) + self._attr_device_class = config.get(CONF_DEVICE_CLASS) self._template = config[CONF_STATE] self._state: bool | None = None self._delay_cancel = None @@ -321,11 +318,6 @@ class BinarySensorTemplate(TemplateEntity, BinarySensorEntity, RestoreEntity): """Return true if sensor is on.""" return self._state - @property - def device_class(self) -> BinarySensorDeviceClass | None: - """Return the sensor class of the binary sensor.""" - return self._device_class - class TriggerBinarySensorEntity(TriggerEntity, BinarySensorEntity, RestoreEntity): """Sensor entity based on trigger data.""" diff --git a/homeassistant/components/template/cover.py b/homeassistant/components/template/cover.py index 3a8e536f7f5..5daa4531109 100644 --- a/homeassistant/components/template/cover.py +++ b/homeassistant/components/template/cover.py @@ -12,7 +12,6 @@ from homeassistant.components.cover import ( DEVICE_CLASSES_SCHEMA, ENTITY_ID_FORMAT, PLATFORM_SCHEMA, - CoverDeviceClass, CoverEntity, CoverEntityFeature, ) @@ -155,7 +154,7 @@ class CoverTemplate(TemplateEntity, CoverEntity): self._template = config.get(CONF_VALUE_TEMPLATE) self._position_template = config.get(CONF_POSITION_TEMPLATE) self._tilt_template = config.get(CONF_TILT_TEMPLATE) - self._device_class: CoverDeviceClass | None = config.get(CONF_DEVICE_CLASS) + self._attr_device_class = config.get(CONF_DEVICE_CLASS) self._open_script = None if (open_action := config.get(OPEN_ACTION)) is not None: self._open_script = Script(hass, open_action, friendly_name, DOMAIN) @@ -182,6 +181,15 @@ class CoverTemplate(TemplateEntity, CoverEntity): self._is_closing = False self._tilt_value = None + supported_features = CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE + if self._stop_script is not None: + supported_features |= CoverEntityFeature.STOP + if self._position_script is not None: + supported_features |= CoverEntityFeature.SET_POSITION + if self._tilt_script is not None: + supported_features |= TILT_FEATURES + self._attr_supported_features = supported_features + @callback def _async_setup_templates(self) -> None: """Set up templates.""" @@ -318,27 +326,6 @@ class CoverTemplate(TemplateEntity, CoverEntity): """ return self._tilt_value - @property - def device_class(self) -> CoverDeviceClass | None: - """Return the device class of the cover.""" - return self._device_class - - @property - def supported_features(self) -> CoverEntityFeature: - """Flag supported features.""" - supported_features = CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE - - if self._stop_script is not None: - supported_features |= CoverEntityFeature.STOP - - if self._position_script is not None: - supported_features |= CoverEntityFeature.SET_POSITION - - if self._tilt_script is not None: - supported_features |= TILT_FEATURES - - return supported_features - async def async_open_cover(self, **kwargs: Any) -> None: """Move the cover up.""" if self._open_script: diff --git a/homeassistant/components/template/fan.py b/homeassistant/components/template/fan.py index c07c680887b..d39fa56775a 100644 --- a/homeassistant/components/template/fan.py +++ b/homeassistant/components/template/fan.py @@ -195,6 +195,8 @@ class TemplateFan(TemplateEntity, FanEntity): if self._direction_template: self._attr_supported_features |= FanEntityFeature.DIRECTION + self._attr_assumed_state = self._template is None + @property def speed_count(self) -> int: """Return the number of speeds the fan supports.""" @@ -467,8 +469,3 @@ class TemplateFan(TemplateEntity, FanEntity): ", ".join(_VALID_DIRECTIONS), ) self._direction = None - - @property - def assumed_state(self) -> bool: - """State is assumed, if no template given.""" - return self._template is None diff --git a/homeassistant/components/template/light.py b/homeassistant/components/template/light.py index 09f5054ed51..b3f276240b5 100644 --- a/homeassistant/components/template/light.py +++ b/homeassistant/components/template/light.py @@ -197,6 +197,12 @@ class LightTemplate(TemplateEntity, LightEntity): if len(self._supported_color_modes) == 1: self._fixed_color_mode = next(iter(self._supported_color_modes)) + self._attr_supported_features = LightEntityFeature(0) + if self._effect_script is not None: + self._attr_supported_features |= LightEntityFeature.EFFECT + if self._supports_transition is True: + self._attr_supported_features |= LightEntityFeature.TRANSITION + @property def brightness(self) -> int | None: """Return the brightness of the light.""" @@ -253,16 +259,6 @@ class LightTemplate(TemplateEntity, LightEntity): """Flag supported color modes.""" return self._supported_color_modes - @property - def supported_features(self) -> LightEntityFeature: - """Flag supported features.""" - supported_features = LightEntityFeature(0) - if self._effect_script is not None: - supported_features |= LightEntityFeature.EFFECT - if self._supports_transition is True: - supported_features |= LightEntityFeature.TRANSITION - return supported_features - @property def is_on(self) -> bool | None: """Return true if device is on.""" @@ -644,4 +640,7 @@ class LightTemplate(TemplateEntity, LightEntity): if render in (None, "None", ""): self._supports_transition = False return + self._attr_supported_features &= LightEntityFeature.EFFECT self._supports_transition = bool(render) + if self._supports_transition: + self._attr_supported_features |= LightEntityFeature.TRANSITION diff --git a/homeassistant/components/template/lock.py b/homeassistant/components/template/lock.py index d8c7127f0e6..de483971ac6 100644 --- a/homeassistant/components/template/lock.py +++ b/homeassistant/components/template/lock.py @@ -90,11 +90,7 @@ class TemplateLock(TemplateEntity, LockEntity): self._command_lock = Script(hass, config[CONF_LOCK], name, DOMAIN) self._command_unlock = Script(hass, config[CONF_UNLOCK], name, DOMAIN) self._optimistic = config.get(CONF_OPTIMISTIC) - - @property - def assumed_state(self) -> bool: - """Return true if we do optimistic updates.""" - return bool(self._optimistic) + self._attr_assumed_state = bool(self._optimistic) @property def is_locked(self) -> bool: diff --git a/homeassistant/components/template/sensor.py b/homeassistant/components/template/sensor.py index cdd14921bc1..e757f561a7e 100644 --- a/homeassistant/components/template/sensor.py +++ b/homeassistant/components/template/sensor.py @@ -42,6 +42,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.trigger_template_entity import TEMPLATE_SENSOR_BASE_SCHEMA from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType +from . import TriggerUpdateCoordinator from .const import ( CONF_ATTRIBUTE_TEMPLATES, CONF_AVAILABILITY_TEMPLATE, @@ -274,6 +275,17 @@ class TriggerSensorEntity(TriggerEntity, RestoreSensor): domain = SENSOR_DOMAIN extra_template_keys = (CONF_STATE,) + def __init__( + self, + hass: HomeAssistant, + coordinator: TriggerUpdateCoordinator, + config: ConfigType, + ) -> None: + """Initialize.""" + super().__init__(hass, coordinator, config) + self._attr_state_class = config.get(CONF_STATE_CLASS) + self._attr_native_unit_of_measurement = config.get(CONF_UNIT_OF_MEASUREMENT) + async def async_added_to_hass(self) -> None: """Restore last state.""" await super().async_added_to_hass() @@ -293,16 +305,6 @@ class TriggerSensorEntity(TriggerEntity, RestoreSensor): """Return state of the sensor.""" return self._rendered.get(CONF_STATE) - @property - def state_class(self) -> str | None: - """Sensor state class.""" - return self._config.get(CONF_STATE_CLASS) - - @property - def native_unit_of_measurement(self) -> str | None: - """Return the unit of measurement of the sensor, if any.""" - return self._config.get(CONF_UNIT_OF_MEASUREMENT) - @callback def _process_data(self) -> None: """Process new data.""" diff --git a/homeassistant/components/template/switch.py b/homeassistant/components/template/switch.py index 39270d3fc6d..5e75eafe233 100644 --- a/homeassistant/components/template/switch.py +++ b/homeassistant/components/template/switch.py @@ -113,6 +113,7 @@ class SwitchTemplate(TemplateEntity, SwitchEntity, RestoreEntity): self._on_script = Script(hass, config[ON_ACTION], friendly_name, DOMAIN) self._off_script = Script(hass, config[OFF_ACTION], friendly_name, DOMAIN) self._state: bool | None = False + self._attr_assumed_state = self._template is None @callback def _update_state(self, result): @@ -168,8 +169,3 @@ class SwitchTemplate(TemplateEntity, SwitchEntity, RestoreEntity): if self._template is None: self._state = False self.async_write_ha_state() - - @property - def assumed_state(self) -> bool: - """State is assumed, if no template given.""" - return self._template is None