diff --git a/homeassistant/components/zha/cover.py b/homeassistant/components/zha/cover.py index 2a61c5b4bc8..413e7e9ae09 100644 --- a/homeassistant/components/zha/cover.py +++ b/homeassistant/components/zha/cover.py @@ -203,8 +203,8 @@ class Shade(ZhaEntity, CoverEntity): super().__init__(unique_id, zha_device, channels, **kwargs) self._on_off_channel = self.cluster_channels[CHANNEL_ON_OFF] self._level_channel = self.cluster_channels[CHANNEL_LEVEL] - self._position = None - self._is_open = None + self._position: int | None = None + self._is_open: bool | None = None @property def current_cover_position(self): diff --git a/homeassistant/components/zha/entity.py b/homeassistant/components/zha/entity.py index fb1a35ff72b..f70948eb04a 100644 --- a/homeassistant/components/zha/entity.py +++ b/homeassistant/components/zha/entity.py @@ -128,9 +128,9 @@ class BaseZhaEntity(LogMixin, entity.Entity): @callback def async_accept_signal( self, - channel: ZigbeeChannel, + channel: ZigbeeChannel | None, signal: str, - func: Callable[[], Any], + func: Callable[..., Any], signal_override=False, ): """Accept a signal from a channel.""" @@ -138,6 +138,7 @@ class BaseZhaEntity(LogMixin, entity.Entity): if signal_override: unsub = async_dispatcher_connect(self.hass, signal, func) else: + assert channel unsub = async_dispatcher_connect( self.hass, f"{channel.unique_id}_{signal}", func ) @@ -305,7 +306,7 @@ class ZhaGroupEntity(BaseZhaEntity): if self._change_listener_debouncer is None: self._change_listener_debouncer = Debouncer( self.hass, - self, + _LOGGER, cooldown=UPDATE_GROUP_FROM_CHILD_DELAY, immediate=False, function=functools.partial(self.async_update_ha_state, True), @@ -325,6 +326,7 @@ class ZhaGroupEntity(BaseZhaEntity): def async_state_changed_listener(self, event: Event): """Handle child updates.""" # Delay to ensure that we get updates from all members before updating the group + assert self._change_listener_debouncer self.hass.create_task(self._change_listener_debouncer.async_call()) async def async_will_remove_from_hass(self) -> None: diff --git a/homeassistant/components/zha/light.py b/homeassistant/components/zha/light.py index 520916d469b..7c9e8d738a4 100644 --- a/homeassistant/components/zha/light.py +++ b/homeassistant/components/zha/light.py @@ -340,13 +340,13 @@ class BaseLight(LogMixin, light.LightEntity): class Light(BaseLight, ZhaEntity): """Representation of a ZHA or ZLL light.""" - _attr_supported_color_modes: set(ColorMode) + _attr_supported_color_modes: set[ColorMode] _REFRESH_INTERVAL = (45, 75) def __init__(self, unique_id, zha_device: ZHADevice, channels, **kwargs): """Initialize the ZHA light.""" super().__init__(unique_id, zha_device, channels, **kwargs) - self._on_off_channel = self.cluster_channels.get(CHANNEL_ON_OFF) + self._on_off_channel = self.cluster_channels[CHANNEL_ON_OFF] self._state = bool(self._on_off_channel.on_off) self._level_channel = self.cluster_channels.get(CHANNEL_LEVEL) self._color_channel = self.cluster_channels.get(CHANNEL_COLOR) @@ -391,6 +391,7 @@ class Light(BaseLight, ZhaEntity): if len(self._attr_supported_color_modes) == 1: self._color_mode = next(iter(self._attr_supported_color_modes)) else: # Light supports color_temp + hs, determine which mode the light is in + assert self._color_channel if self._color_channel.color_mode == Color.ColorMode.Color_temperature: self._color_mode = ColorMode.COLOR_TEMP else: @@ -440,6 +441,7 @@ class Light(BaseLight, ZhaEntity): async def async_will_remove_from_hass(self) -> None: """Disconnect entity object when removed.""" + assert self._cancel_refresh_handle self._cancel_refresh_handle() await super().async_will_remove_from_hass() diff --git a/homeassistant/components/zha/select.py b/homeassistant/components/zha/select.py index 231120ba806..83bbcdca580 100644 --- a/homeassistant/components/zha/select.py +++ b/homeassistant/components/zha/select.py @@ -64,7 +64,7 @@ class ZHAEnumSelectEntity(ZhaEntity, SelectEntity): """Representation of a ZHA select entity.""" _attr_entity_category = EntityCategory.CONFIG - _enum: Enum = None + _enum: type[Enum] def __init__( self, @@ -87,7 +87,7 @@ class ZHAEnumSelectEntity(ZhaEntity, SelectEntity): return None return option.name.replace("_", " ") - async def async_select_option(self, option: str | int) -> None: + async def async_select_option(self, option: str) -> None: """Change the selected option.""" self._channel.data_cache[self._attr_name] = self._enum[option.replace(" ", "_")] self.async_write_ha_state() @@ -116,7 +116,7 @@ class ZHADefaultToneSelectEntity( ): """Representation of a ZHA default siren tone select entity.""" - _enum: Enum = IasWd.Warning.WarningMode + _enum = IasWd.Warning.WarningMode @CONFIG_DIAGNOSTIC_MATCH(channel_names=CHANNEL_IAS_WD) @@ -125,7 +125,7 @@ class ZHADefaultSirenLevelSelectEntity( ): """Representation of a ZHA default siren level select entity.""" - _enum: Enum = IasWd.Warning.SirenLevel + _enum = IasWd.Warning.SirenLevel @CONFIG_DIAGNOSTIC_MATCH(channel_names=CHANNEL_IAS_WD) @@ -134,14 +134,14 @@ class ZHADefaultStrobeLevelSelectEntity( ): """Representation of a ZHA default siren strobe level select entity.""" - _enum: Enum = IasWd.StrobeLevel + _enum = IasWd.StrobeLevel @CONFIG_DIAGNOSTIC_MATCH(channel_names=CHANNEL_IAS_WD) class ZHADefaultStrobeSelectEntity(ZHANonZCLSelectEntity, id_suffix=Strobe.__name__): """Representation of a ZHA default siren strobe select entity.""" - _enum: Enum = Strobe + _enum = Strobe class ZCLEnumSelectEntity(ZhaEntity, SelectEntity): @@ -149,7 +149,7 @@ class ZCLEnumSelectEntity(ZhaEntity, SelectEntity): _select_attr: str _attr_entity_category = EntityCategory.CONFIG - _enum: Enum + _enum: type[Enum] @classmethod def create_entity( @@ -198,7 +198,7 @@ class ZCLEnumSelectEntity(ZhaEntity, SelectEntity): option = self._enum(option) return option.name.replace("_", " ") - async def async_select_option(self, option: str | int) -> None: + async def async_select_option(self, option: str) -> None: """Change the selected option.""" await self._channel.cluster.write_attributes( {self._select_attr: self._enum[option.replace(" ", "_")]} @@ -213,7 +213,7 @@ class ZHAStartupOnOffSelectEntity( """Representation of a ZHA startup onoff select entity.""" _select_attr = "start_up_on_off" - _enum: Enum = OnOff.StartUpOnOff + _enum = OnOff.StartUpOnOff class AqaraMotionSensitivities(types.enum8): @@ -229,4 +229,4 @@ class AqaraMotionSensitivity(ZCLEnumSelectEntity, id_suffix="motion_sensitivity" """Representation of a ZHA on off transition time configuration entity.""" _select_attr = "motion_sensitivity" - _enum: Enum = AqaraMotionSensitivities + _enum = AqaraMotionSensitivities diff --git a/homeassistant/components/zha/sensor.py b/homeassistant/components/zha/sensor.py index e579967345c..e66f1569b81 100644 --- a/homeassistant/components/zha/sensor.py +++ b/homeassistant/components/zha/sensor.py @@ -118,7 +118,7 @@ class Sensor(ZhaEntity, SensorEntity): SENSOR_ATTR: int | str | None = None _decimals: int = 1 _divisor: int = 1 - _multiplier: int = 1 + _multiplier: int | float = 1 _unit: str | None = None def __init__( @@ -455,7 +455,7 @@ class SmartEnergyMetering(Sensor): return self._channel.demand_formatter(value) @property - def native_unit_of_measurement(self) -> str: + def native_unit_of_measurement(self) -> str | None: """Return Unit of measurement.""" return self.unit_of_measure_map.get(self._channel.unit_of_measurement) @@ -760,6 +760,7 @@ class RSSISensor(Sensor, id_suffix="rssi"): _attr_device_class: SensorDeviceClass = SensorDeviceClass.SIGNAL_STRENGTH _attr_entity_category = EntityCategory.DIAGNOSTIC _attr_entity_registry_enabled_default = False + unique_id_suffix: str @classmethod def create_entity( diff --git a/homeassistant/components/zha/switch.py b/homeassistant/components/zha/switch.py index 1926b08fc60..fe7526586f9 100644 --- a/homeassistant/components/zha/switch.py +++ b/homeassistant/components/zha/switch.py @@ -29,7 +29,6 @@ from .entity import ZhaEntity, ZhaGroupEntity if TYPE_CHECKING: from .core.channels.base import ZigbeeChannel - from .core.channels.general import OnOffChannel from .core.device import ZHADevice STRICT_MATCH = functools.partial(ZHA_ENTITIES.strict_match, Platform.SWITCH) @@ -72,7 +71,7 @@ class Switch(ZhaEntity, SwitchEntity): ) -> None: """Initialize the ZHA switch.""" super().__init__(unique_id, zha_device, channels, **kwargs) - self._on_off_channel: OnOffChannel = self.cluster_channels.get(CHANNEL_ON_OFF) + self._on_off_channel = self.cluster_channels[CHANNEL_ON_OFF] @property def is_on(self) -> bool: diff --git a/mypy.ini b/mypy.ini index 1cc40dd3daf..26314c5bcad 100644 --- a/mypy.ini +++ b/mypy.ini @@ -3020,21 +3020,3 @@ ignore_errors = true [mypy-homeassistant.components.zha.core.store] ignore_errors = true - -[mypy-homeassistant.components.zha.cover] -ignore_errors = true - -[mypy-homeassistant.components.zha.entity] -ignore_errors = true - -[mypy-homeassistant.components.zha.light] -ignore_errors = true - -[mypy-homeassistant.components.zha.select] -ignore_errors = true - -[mypy-homeassistant.components.zha.sensor] -ignore_errors = true - -[mypy-homeassistant.components.zha.switch] -ignore_errors = true diff --git a/script/hassfest/mypy_config.py b/script/hassfest/mypy_config.py index 5a53323deb7..6a4ff9d8cdf 100644 --- a/script/hassfest/mypy_config.py +++ b/script/hassfest/mypy_config.py @@ -156,12 +156,6 @@ IGNORED_MODULES: Final[list[str]] = [ "homeassistant.components.zha.core.helpers", "homeassistant.components.zha.core.registries", "homeassistant.components.zha.core.store", - "homeassistant.components.zha.cover", - "homeassistant.components.zha.entity", - "homeassistant.components.zha.light", - "homeassistant.components.zha.select", - "homeassistant.components.zha.sensor", - "homeassistant.components.zha.switch", ] # Component modules which should set no_implicit_reexport = true.