From 0b442652322edc8f704ff0409dcce14735f0f9db Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Tue, 27 Jul 2021 00:22:21 +0200 Subject: [PATCH] Add description classes to entity components (#53521) * Add description classes to entity components * An -> A * Add StateVacuumEntityDescription --- .../alarm_control_panel/__init__.py | 9 +++++++- .../components/binary_sensor/__init__.py | 9 +++++++- homeassistant/components/climate/__init__.py | 9 +++++++- homeassistant/components/cover/__init__.py | 9 +++++++- homeassistant/components/fan/__init__.py | 10 ++++++++- .../components/humidifier/__init__.py | 9 +++++++- homeassistant/components/light/__init__.py | 8 ++++++- homeassistant/components/lock/__init__.py | 9 +++++++- .../components/media_player/__init__.py | 9 +++++++- homeassistant/components/number/__init__.py | 9 +++++++- homeassistant/components/remote/__init__.py | 9 +++++++- homeassistant/components/select/__init__.py | 9 +++++++- homeassistant/components/sensor/__init__.py | 2 +- homeassistant/components/siren/__init__.py | 9 +++++++- homeassistant/components/switch/__init__.py | 9 +++++++- homeassistant/components/vacuum/__init__.py | 22 ++++++++++++++++++- .../components/water_heater/__init__.py | 9 +++++++- homeassistant/components/weather/__init__.py | 9 +++++++- homeassistant/helpers/entity.py | 8 ++++++- 19 files changed, 157 insertions(+), 19 deletions(-) diff --git a/homeassistant/components/alarm_control_panel/__init__.py b/homeassistant/components/alarm_control_panel/__init__.py index 1032150649e..50317e97f2b 100644 --- a/homeassistant/components/alarm_control_panel/__init__.py +++ b/homeassistant/components/alarm_control_panel/__init__.py @@ -1,6 +1,7 @@ """Component to interface with an alarm control panel.""" from __future__ import annotations +from dataclasses import dataclass from datetime import timedelta import logging from typing import Any, Final, final @@ -22,7 +23,7 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant import homeassistant.helpers.config_validation as cv from homeassistant.helpers.config_validation import make_entity_service_schema -from homeassistant.helpers.entity import Entity +from homeassistant.helpers.entity import Entity, EntityDescription from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.typing import ConfigType @@ -117,9 +118,15 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await component.async_unload_entry(entry) +@dataclass +class AlarmControlPanelEntityDescription(EntityDescription): + """A class that describes alarm control panel entities.""" + + class AlarmControlPanelEntity(Entity): """An abstract class for alarm control entities.""" + entity_description: AlarmControlPanelEntityDescription _attr_changed_by: str | None = None _attr_code_arm_required: bool = True _attr_code_format: str | None = None diff --git a/homeassistant/components/binary_sensor/__init__.py b/homeassistant/components/binary_sensor/__init__.py index ff97e9af601..2bd5de34d51 100644 --- a/homeassistant/components/binary_sensor/__init__.py +++ b/homeassistant/components/binary_sensor/__init__.py @@ -1,6 +1,7 @@ """Component to interface with binary sensors.""" from __future__ import annotations +from dataclasses import dataclass from datetime import timedelta import logging from typing import Any, final @@ -14,7 +15,7 @@ from homeassistant.helpers.config_validation import ( # noqa: F401 PLATFORM_SCHEMA, PLATFORM_SCHEMA_BASE, ) -from homeassistant.helpers.entity import Entity +from homeassistant.helpers.entity import Entity, EntityDescription from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.typing import ConfigType, StateType @@ -149,9 +150,15 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await component.async_unload_entry(entry) +@dataclass +class BinarySensorEntityDescription(EntityDescription): + """A class that describes binary sensor entities.""" + + class BinarySensorEntity(Entity): """Represent a binary sensor.""" + entity_description: BinarySensorEntityDescription _attr_is_on: bool | None = None _attr_state: None = None diff --git a/homeassistant/components/climate/__init__.py b/homeassistant/components/climate/__init__.py index cc26bcc9bcc..6a46c1986b8 100644 --- a/homeassistant/components/climate/__init__.py +++ b/homeassistant/components/climate/__init__.py @@ -1,6 +1,7 @@ """Provides functionality to interact with climate devices.""" from __future__ import annotations +from dataclasses import dataclass from datetime import timedelta import functools as ft import logging @@ -26,7 +27,7 @@ from homeassistant.helpers.config_validation import ( # noqa: F401 PLATFORM_SCHEMA_BASE, make_entity_service_schema, ) -from homeassistant.helpers.entity import Entity +from homeassistant.helpers.entity import Entity, EntityDescription from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.temperature import display_temp as show_temp from homeassistant.helpers.typing import ConfigType @@ -169,9 +170,15 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await component.async_unload_entry(entry) +@dataclass +class ClimateEntityDescription(EntityDescription): + """A class that describes climate entities.""" + + class ClimateEntity(Entity): """Base class for climate entities.""" + entity_description: ClimateEntityDescription _attr_current_humidity: int | None = None _attr_current_temperature: float | None = None _attr_fan_mode: str | None diff --git a/homeassistant/components/cover/__init__.py b/homeassistant/components/cover/__init__.py index 110dd09098e..00fef5c6485 100644 --- a/homeassistant/components/cover/__init__.py +++ b/homeassistant/components/cover/__init__.py @@ -1,6 +1,7 @@ """Support for Cover devices.""" from __future__ import annotations +from dataclasses import dataclass from datetime import timedelta import functools as ft import logging @@ -30,7 +31,7 @@ from homeassistant.helpers.config_validation import ( # noqa: F401 PLATFORM_SCHEMA, PLATFORM_SCHEMA_BASE, ) -from homeassistant.helpers.entity import Entity +from homeassistant.helpers.entity import Entity, EntityDescription from homeassistant.helpers.entity_component import EntityComponent from homeassistant.loader import bind_hass @@ -170,9 +171,15 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await component.async_unload_entry(entry) +@dataclass +class CoverEntityDescription(EntityDescription): + """A class that describes cover entities.""" + + class CoverEntity(Entity): """Base class for cover entities.""" + entity_description: CoverEntityDescription _attr_current_cover_position: int | None = None _attr_current_cover_tilt_position: int | None = None _attr_is_closed: bool | None diff --git a/homeassistant/components/fan/__init__.py b/homeassistant/components/fan/__init__.py index 248e7d095d0..1d0caa3231b 100644 --- a/homeassistant/components/fan/__init__.py +++ b/homeassistant/components/fan/__init__.py @@ -1,6 +1,7 @@ """Provides functionality to interact with fans.""" from __future__ import annotations +from dataclasses import dataclass from datetime import timedelta import functools as ft import logging @@ -22,7 +23,7 @@ from homeassistant.helpers.config_validation import ( # noqa: F401 PLATFORM_SCHEMA, PLATFORM_SCHEMA_BASE, ) -from homeassistant.helpers.entity import ToggleEntity +from homeassistant.helpers.entity import ToggleEntity, ToggleEntityDescription from homeassistant.helpers.entity_component import EntityComponent from homeassistant.loader import bind_hass from homeassistant.util.percentage import ( @@ -224,9 +225,16 @@ def _fan_native(method): return method +@dataclass +class FanEntityDescription(ToggleEntityDescription): + """A class that describes fan entities.""" + + class FanEntity(ToggleEntity): """Base class for fan entities.""" + entity_description: FanEntityDescription + @_fan_native def set_speed(self, speed: str) -> None: """Set the speed of the fan.""" diff --git a/homeassistant/components/humidifier/__init__.py b/homeassistant/components/humidifier/__init__.py index 7839eeec799..d15f70f181a 100644 --- a/homeassistant/components/humidifier/__init__.py +++ b/homeassistant/components/humidifier/__init__.py @@ -1,6 +1,7 @@ """Provides functionality to interact with humidifier devices.""" from __future__ import annotations +from dataclasses import dataclass from datetime import timedelta import logging from typing import Any, final @@ -21,7 +22,7 @@ from homeassistant.helpers.config_validation import ( # noqa: F401 PLATFORM_SCHEMA, PLATFORM_SCHEMA_BASE, ) -from homeassistant.helpers.entity import ToggleEntity +from homeassistant.helpers.entity import ToggleEntity, ToggleEntityDescription from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.typing import ConfigType from homeassistant.loader import bind_hass @@ -101,9 +102,15 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await component.async_unload_entry(entry) +@dataclass +class HumidifierEntityDescription(ToggleEntityDescription): + """A class that describes humidifier entities.""" + + class HumidifierEntity(ToggleEntity): """Base class for humidifier entities.""" + entity_description: HumidifierEntityDescription _attr_available_modes: list[str] | None _attr_max_humidity: int = DEFAULT_MAX_HUMIDITY _attr_min_humidity: int = DEFAULT_MIN_HUMIDITY diff --git a/homeassistant/components/light/__init__.py b/homeassistant/components/light/__init__.py index e92999f4d21..68e30b39a61 100644 --- a/homeassistant/components/light/__init__.py +++ b/homeassistant/components/light/__init__.py @@ -25,7 +25,7 @@ from homeassistant.helpers.config_validation import ( # noqa: F401 PLATFORM_SCHEMA_BASE, make_entity_service_schema, ) -from homeassistant.helpers.entity import ToggleEntity +from homeassistant.helpers.entity import ToggleEntity, ToggleEntityDescription from homeassistant.helpers.entity_component import EntityComponent from homeassistant.loader import bind_hass import homeassistant.util.color as color_util @@ -638,9 +638,15 @@ class Profiles: params.setdefault(ATTR_TRANSITION, profile.transition) +@dataclasses.dataclass +class LightEntityDescription(ToggleEntityDescription): + """A class that describes binary sensor entities.""" + + class LightEntity(ToggleEntity): """Base class for light entities.""" + entity_description: LightEntityDescription _attr_brightness: int | None = None _attr_color_mode: str | None = None _attr_color_temp: int | None = None diff --git a/homeassistant/components/lock/__init__.py b/homeassistant/components/lock/__init__.py index e98202a1ee5..860778d61f3 100644 --- a/homeassistant/components/lock/__init__.py +++ b/homeassistant/components/lock/__init__.py @@ -1,6 +1,7 @@ """Component to interface with locks that can be controlled remotely.""" from __future__ import annotations +from dataclasses import dataclass from datetime import timedelta import functools as ft import logging @@ -28,7 +29,7 @@ from homeassistant.helpers.config_validation import ( # noqa: F401 PLATFORM_SCHEMA_BASE, make_entity_service_schema, ) -from homeassistant.helpers.entity import Entity +from homeassistant.helpers.entity import Entity, EntityDescription from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.typing import ConfigType, StateType @@ -84,9 +85,15 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await component.async_unload_entry(entry) +@dataclass +class LockEntityDescription(EntityDescription): + """A class that describes lock entities.""" + + class LockEntity(Entity): """Base class for lock entities.""" + entity_description: LockEntityDescription _attr_changed_by: str | None = None _attr_code_format: str | None = None _attr_is_locked: bool | None = None diff --git a/homeassistant/components/media_player/__init__.py b/homeassistant/components/media_player/__init__.py index ffdabe6fed7..6978b90c897 100644 --- a/homeassistant/components/media_player/__init__.py +++ b/homeassistant/components/media_player/__init__.py @@ -5,6 +5,7 @@ import asyncio import base64 import collections from contextlib import suppress +from dataclasses import dataclass import datetime as dt import functools as ft import hashlib @@ -61,7 +62,7 @@ from homeassistant.helpers.config_validation import ( # noqa: F401 PLATFORM_SCHEMA_BASE, datetime, ) -from homeassistant.helpers.entity import Entity +from homeassistant.helpers.entity import Entity, EntityDescription from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.network import get_url from homeassistant.loader import bind_hass @@ -371,9 +372,15 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await component.async_unload_entry(entry) +@dataclass +class MediaPlayerEntityDescription(EntityDescription): + """A class that describes media player entities.""" + + class MediaPlayerEntity(Entity): """ABC for media player entities.""" + entity_description: MediaPlayerEntityDescription _access_token: str | None = None _attr_app_id: str | None = None diff --git a/homeassistant/components/number/__init__.py b/homeassistant/components/number/__init__.py index cbfdea7fa11..88ba5cf8b41 100644 --- a/homeassistant/components/number/__init__.py +++ b/homeassistant/components/number/__init__.py @@ -1,6 +1,7 @@ """Component to allow numeric input for platforms.""" from __future__ import annotations +from dataclasses import dataclass from datetime import timedelta import logging from typing import Any, final @@ -13,7 +14,7 @@ from homeassistant.helpers.config_validation import ( # noqa: F401 PLATFORM_SCHEMA, PLATFORM_SCHEMA_BASE, ) -from homeassistant.helpers.entity import Entity +from homeassistant.helpers.entity import Entity, EntityDescription from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.typing import ConfigType @@ -66,9 +67,15 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await component.async_unload_entry(entry) +@dataclass +class NumberEntityDescription(EntityDescription): + """A class that describes number entities.""" + + class NumberEntity(Entity): """Representation of a Number entity.""" + entity_description: NumberEntityDescription _attr_max_value: float = DEFAULT_MAX_VALUE _attr_min_value: float = DEFAULT_MIN_VALUE _attr_state: None = None diff --git a/homeassistant/components/remote/__init__.py b/homeassistant/components/remote/__init__.py index 0fc4255615e..e67a4eda9a9 100644 --- a/homeassistant/components/remote/__init__.py +++ b/homeassistant/components/remote/__init__.py @@ -2,6 +2,7 @@ from __future__ import annotations from collections.abc import Iterable +from dataclasses import dataclass from datetime import timedelta import functools as ft import logging @@ -24,7 +25,7 @@ from homeassistant.helpers.config_validation import ( # noqa: F401 PLATFORM_SCHEMA_BASE, make_entity_service_schema, ) -from homeassistant.helpers.entity import ToggleEntity +from homeassistant.helpers.entity import ToggleEntity, ToggleEntityDescription from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.typing import ConfigType from homeassistant.loader import bind_hass @@ -142,9 +143,15 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await cast(EntityComponent, hass.data[DOMAIN]).async_unload_entry(entry) +@dataclass +class RemoteEntityDescription(ToggleEntityDescription): + """A class that describes remote entities.""" + + class RemoteEntity(ToggleEntity): """Base class for remote entities.""" + entity_description: RemoteEntityDescription _attr_activity_list: list[str] | None = None _attr_current_activity: str | None = None _attr_supported_features: int = 0 diff --git a/homeassistant/components/select/__init__.py b/homeassistant/components/select/__init__.py index 4ec8c46ef05..d5c70c76cd0 100644 --- a/homeassistant/components/select/__init__.py +++ b/homeassistant/components/select/__init__.py @@ -1,6 +1,7 @@ """Component to allow selecting an option from a list as platforms.""" from __future__ import annotations +from dataclasses import dataclass from datetime import timedelta import logging from typing import Any, final @@ -14,7 +15,7 @@ from homeassistant.helpers.config_validation import ( # noqa: F401 PLATFORM_SCHEMA, PLATFORM_SCHEMA_BASE, ) -from homeassistant.helpers.entity import Entity +from homeassistant.helpers.entity import Entity, EntityDescription from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.typing import ConfigType @@ -57,9 +58,15 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await component.async_unload_entry(entry) +@dataclass +class SelectEntityDescription(EntityDescription): + """A class that describes select entities.""" + + class SelectEntity(Entity): """Representation of a Select entity.""" + entity_description: SelectEntityDescription _attr_current_option: str | None _attr_options: list[str] _attr_state: None = None diff --git a/homeassistant/components/sensor/__init__.py b/homeassistant/components/sensor/__init__.py index 59bda470c63..e36640b1c1d 100644 --- a/homeassistant/components/sensor/__init__.py +++ b/homeassistant/components/sensor/__init__.py @@ -98,7 +98,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: @dataclass class SensorEntityDescription(EntityDescription): - """An class that describes sensor entities.""" + """A class that describes sensor entities.""" state_class: str | None = None last_reset: datetime | None = None diff --git a/homeassistant/components/siren/__init__.py b/homeassistant/components/siren/__init__.py index 68770daf835..565e8ca0b7a 100644 --- a/homeassistant/components/siren/__init__.py +++ b/homeassistant/components/siren/__init__.py @@ -1,6 +1,7 @@ """Component to interface with various sirens/chimes.""" from __future__ import annotations +from dataclasses import dataclass from datetime import timedelta import logging from typing import Any, TypedDict, cast, final @@ -15,7 +16,7 @@ from homeassistant.helpers.config_validation import ( # noqa: F401 PLATFORM_SCHEMA, PLATFORM_SCHEMA_BASE, ) -from homeassistant.helpers.entity import ToggleEntity +from homeassistant.helpers.entity import ToggleEntity, ToggleEntityDescription from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.typing import ConfigType, HomeAssistantType @@ -121,9 +122,15 @@ async def async_unload_entry(hass: HomeAssistantType, entry: ConfigEntry) -> boo return await component.async_unload_entry(entry) +@dataclass +class SirenEntityDescription(ToggleEntityDescription): + """A class that describes siren entities.""" + + class SirenEntity(ToggleEntity): """Representation of a siren device.""" + entity_description: SirenEntityDescription _attr_available_tones: list[int | str] | None = None @final diff --git a/homeassistant/components/switch/__init__.py b/homeassistant/components/switch/__init__.py index 1ef48fed620..0abbc6d9f97 100644 --- a/homeassistant/components/switch/__init__.py +++ b/homeassistant/components/switch/__init__.py @@ -1,6 +1,7 @@ """Component to interface with switches that can be controlled remotely.""" from __future__ import annotations +from dataclasses import dataclass from datetime import timedelta import logging from typing import Any, final @@ -19,7 +20,7 @@ from homeassistant.helpers.config_validation import ( # noqa: F401 PLATFORM_SCHEMA, PLATFORM_SCHEMA_BASE, ) -from homeassistant.helpers.entity import ToggleEntity +from homeassistant.helpers.entity import ToggleEntity, ToggleEntityDescription from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.typing import ConfigType from homeassistant.loader import bind_hass @@ -84,9 +85,15 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await component.async_unload_entry(entry) +@dataclass +class SwitchEntityDescription(ToggleEntityDescription): + """A class that describes switch entities.""" + + class SwitchEntity(ToggleEntity): """Base class for switch entities.""" + entity_description: SwitchEntityDescription _attr_current_power_w: float | None = None _attr_today_energy_kwh: float | None = None diff --git a/homeassistant/components/vacuum/__init__.py b/homeassistant/components/vacuum/__init__.py index 36cc632d932..87d8d6f49f8 100644 --- a/homeassistant/components/vacuum/__init__.py +++ b/homeassistant/components/vacuum/__init__.py @@ -1,4 +1,5 @@ """Support for vacuum cleaner robots (botvacs).""" +from dataclasses import dataclass from datetime import timedelta from functools import partial import logging @@ -24,7 +25,12 @@ from homeassistant.helpers.config_validation import ( # noqa: F401 PLATFORM_SCHEMA_BASE, make_entity_service_schema, ) -from homeassistant.helpers.entity import Entity, ToggleEntity +from homeassistant.helpers.entity import ( + Entity, + EntityDescription, + ToggleEntity, + ToggleEntityDescription, +) from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.icon import icon_for_battery_level from homeassistant.loader import bind_hass @@ -258,9 +264,16 @@ class _BaseVacuum(Entity): ) +@dataclass +class VacuumEntityDescription(ToggleEntityDescription): + """A class that describes vacuum entities.""" + + class VacuumEntity(_BaseVacuum, ToggleEntity): """Representation of a vacuum cleaner robot.""" + entity_description: VacuumEntityDescription + @property def status(self): """Return the status of the vacuum cleaner.""" @@ -338,9 +351,16 @@ class VacuumDevice(VacuumEntity): ) +@dataclass +class StateVacuumEntityDescription(EntityDescription): + """A class that describes vacuum entities.""" + + class StateVacuumEntity(_BaseVacuum): """Representation of a vacuum cleaner robot that supports states.""" + entity_description: StateVacuumEntityDescription + @property def state(self): """Return the state of the vacuum cleaner.""" diff --git a/homeassistant/components/water_heater/__init__.py b/homeassistant/components/water_heater/__init__.py index fcee7a446e0..85d6a791d7f 100644 --- a/homeassistant/components/water_heater/__init__.py +++ b/homeassistant/components/water_heater/__init__.py @@ -1,6 +1,7 @@ """Support for water heater devices.""" from __future__ import annotations +from dataclasses import dataclass from datetime import timedelta import functools as ft import logging @@ -27,7 +28,7 @@ from homeassistant.helpers.config_validation import ( # noqa: F401 PLATFORM_SCHEMA, PLATFORM_SCHEMA_BASE, ) -from homeassistant.helpers.entity import Entity +from homeassistant.helpers.entity import Entity, EntityDescription from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.temperature import display_temp as show_temp from homeassistant.util.temperature import convert as convert_temperature @@ -135,9 +136,15 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await component.async_unload_entry(entry) +@dataclass +class WaterHeaterEntityEntityDescription(EntityDescription): + """A class that describes water heater entities.""" + + class WaterHeaterEntity(Entity): """Base class for water heater entities.""" + entity_description: WaterHeaterEntityEntityDescription _attr_current_operation: str | None = None _attr_current_temperature: float | None = None _attr_is_away_mode_on: bool | None = None diff --git a/homeassistant/components/weather/__init__.py b/homeassistant/components/weather/__init__.py index b737129e69e..7d5f7a99d40 100644 --- a/homeassistant/components/weather/__init__.py +++ b/homeassistant/components/weather/__init__.py @@ -1,6 +1,7 @@ """Weather component that handles meteorological data for your location.""" from __future__ import annotations +from dataclasses import dataclass from datetime import timedelta import logging from typing import Final, TypedDict, final @@ -12,7 +13,7 @@ from homeassistant.helpers.config_validation import ( # noqa: F401 PLATFORM_SCHEMA, PLATFORM_SCHEMA_BASE, ) -from homeassistant.helpers.entity import Entity +from homeassistant.helpers.entity import Entity, EntityDescription from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.temperature import display_temp as show_temp @@ -97,9 +98,15 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await component.async_unload_entry(entry) +@dataclass +class WeatherEntityDescription(EntityDescription): + """A class that describes weather entities.""" + + class WeatherEntity(Entity): """ABC for weather data.""" + entity_description: WeatherEntityDescription _attr_attribution: str | None = None _attr_condition: str | None _attr_forecast: list[Forecast] | None = None diff --git a/homeassistant/helpers/entity.py b/homeassistant/helpers/entity.py index e66624cd15a..8c134226f69 100644 --- a/homeassistant/helpers/entity.py +++ b/homeassistant/helpers/entity.py @@ -181,7 +181,7 @@ class DeviceInfo(TypedDict, total=False): @dataclass class EntityDescription: - """An class that describes Home Assistant entities.""" + """A class that describes Home Assistant entities.""" # This is the key identifier for this entity key: str @@ -857,9 +857,15 @@ class Entity(ABC): self.parallel_updates.release() +@dataclass +class ToggleEntityDescription(EntityDescription): + """A class that describes toggle entities.""" + + class ToggleEntity(Entity): """An abstract class for entities that can be turned on and off.""" + entity_description: ToggleEntityDescription _attr_is_on: bool _attr_state: None = None