From 8c870a5683107409f9dd02e6365977199d500764 Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Mon, 24 Jul 2023 08:07:07 +0200 Subject: [PATCH] Use EventType for state changed [m-z] (#97118) --- .../components/mold_indicator/sensor.py | 27 ++++++++++++------- homeassistant/components/plant/__init__.py | 16 ++++++----- homeassistant/components/statistics/sensor.py | 15 ++++++++--- .../components/switch_as_x/entity.py | 10 +++++-- .../components/threshold/binary_sensor.py | 13 ++++++--- .../components/trend/binary_sensor.py | 15 +++++++---- .../components/universal/media_player.py | 7 +++-- .../components/utility_meter/sensor.py | 19 +++++++------ homeassistant/components/zha/entity.py | 12 ++++++--- 9 files changed, 90 insertions(+), 44 deletions(-) diff --git a/homeassistant/components/mold_indicator/sensor.py b/homeassistant/components/mold_indicator/sensor.py index ee3ab9817ea..ce3844475c5 100644 --- a/homeassistant/components/mold_indicator/sensor.py +++ b/homeassistant/components/mold_indicator/sensor.py @@ -16,11 +16,14 @@ from homeassistant.const import ( STATE_UNKNOWN, UnitOfTemperature, ) -from homeassistant.core import HomeAssistant, callback +from homeassistant.core import HomeAssistant, State, callback import homeassistant.helpers.config_validation as cv from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.helpers.event import async_track_state_change_event -from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType +from homeassistant.helpers.event import ( + EventStateChangedData, + async_track_state_change_event, +) +from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType, EventType from homeassistant.util.unit_conversion import TemperatureConverter from homeassistant.util.unit_system import METRIC_SYSTEM @@ -117,11 +120,13 @@ class MoldIndicator(SensorEntity): """Register callbacks.""" @callback - def mold_indicator_sensors_state_listener(event): + def mold_indicator_sensors_state_listener( + event: EventType[EventStateChangedData], + ) -> None: """Handle for state changes for dependent sensors.""" - new_state = event.data.get("new_state") - old_state = event.data.get("old_state") - entity = event.data.get("entity_id") + new_state = event.data["new_state"] + old_state = event.data["old_state"] + entity = event.data["entity_id"] _LOGGER.debug( "Sensor state change for %s that had old state %s and new state %s", entity, @@ -173,7 +178,9 @@ class MoldIndicator(SensorEntity): EVENT_HOMEASSISTANT_START, mold_indicator_startup ) - def _update_sensor(self, entity, old_state, new_state): + def _update_sensor( + self, entity: str, old_state: State | None, new_state: State | None + ) -> bool: """Update information based on new sensor states.""" _LOGGER.debug("Sensor update for %s", entity) if new_state is None: @@ -194,7 +201,7 @@ class MoldIndicator(SensorEntity): return True @staticmethod - def _update_temp_sensor(state): + def _update_temp_sensor(state: State) -> float | None: """Parse temperature sensor value.""" _LOGGER.debug("Updating temp sensor with value %s", state.state) @@ -235,7 +242,7 @@ class MoldIndicator(SensorEntity): return None @staticmethod - def _update_hum_sensor(state): + def _update_hum_sensor(state: State) -> float | None: """Parse humidity sensor value.""" _LOGGER.debug("Updating humidity sensor with value %s", state.state) diff --git a/homeassistant/components/plant/__init__.py b/homeassistant/components/plant/__init__.py index e385156c6d1..ed88e50b932 100644 --- a/homeassistant/components/plant/__init__.py +++ b/homeassistant/components/plant/__init__.py @@ -19,13 +19,16 @@ from homeassistant.const import ( STATE_UNKNOWN, UnitOfTemperature, ) -from homeassistant.core import HomeAssistant, callback +from homeassistant.core import HomeAssistant, State, callback from homeassistant.exceptions import HomeAssistantError import homeassistant.helpers.config_validation as cv from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity_component import EntityComponent -from homeassistant.helpers.event import async_track_state_change_event -from homeassistant.helpers.typing import ConfigType +from homeassistant.helpers.event import ( + EventStateChangedData, + async_track_state_change_event, +) +from homeassistant.helpers.typing import ConfigType, EventType from homeassistant.util import dt as dt_util from .const import ( @@ -176,15 +179,16 @@ class Plant(Entity): self._brightness_history = DailyHistory(self._conf_check_days) @callback - def _state_changed_event(self, event): + def _state_changed_event(self, event: EventType[EventStateChangedData]): """Sensor state change event.""" - self.state_changed(event.data.get("entity_id"), event.data.get("new_state")) + self.state_changed(event.data["entity_id"], event.data["new_state"]) @callback - def state_changed(self, entity_id, new_state): + def state_changed(self, entity_id: str, new_state: State | None) -> None: """Update the sensor status.""" if new_state is None: return + value: str | float value = new_state.state _LOGGER.debug("Received callback from %s with value %s", entity_id, value) if value == STATE_UNKNOWN: diff --git a/homeassistant/components/statistics/sensor.py b/homeassistant/components/statistics/sensor.py index 078eb59fe72..e86a4741080 100644 --- a/homeassistant/components/statistics/sensor.py +++ b/homeassistant/components/statistics/sensor.py @@ -32,7 +32,6 @@ from homeassistant.const import ( ) from homeassistant.core import ( CALLBACK_TYPE, - Event, HomeAssistant, State, callback, @@ -41,12 +40,18 @@ from homeassistant.core import ( from homeassistant.helpers import config_validation as cv from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.event import ( + EventStateChangedData, async_track_point_in_utc_time, async_track_state_change_event, ) from homeassistant.helpers.reload import async_setup_reload_service from homeassistant.helpers.start import async_at_start -from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType, StateType +from homeassistant.helpers.typing import ( + ConfigType, + DiscoveryInfoType, + EventType, + StateType, +) from homeassistant.util import dt as dt_util from homeassistant.util.enum import try_parse_enum @@ -308,9 +313,11 @@ class StatisticsSensor(SensorEntity): """Register callbacks.""" @callback - def async_stats_sensor_state_listener(event: Event) -> None: + def async_stats_sensor_state_listener( + event: EventType[EventStateChangedData], + ) -> None: """Handle the sensor state changes.""" - if (new_state := event.data.get("new_state")) is None: + if (new_state := event.data["new_state"]) is None: return self._add_state_to_queue(new_state) self.async_schedule_update_ha_state(True) diff --git a/homeassistant/components/switch_as_x/entity.py b/homeassistant/components/switch_as_x/entity.py index a73271bdc83..36f8a651f06 100644 --- a/homeassistant/components/switch_as_x/entity.py +++ b/homeassistant/components/switch_as_x/entity.py @@ -15,7 +15,11 @@ from homeassistant.const import ( from homeassistant.core import Event, HomeAssistant, callback from homeassistant.helpers import device_registry as dr, entity_registry as er from homeassistant.helpers.entity import DeviceInfo, Entity, ToggleEntity -from homeassistant.helpers.event import async_track_state_change_event +from homeassistant.helpers.event import ( + EventStateChangedData, + async_track_state_change_event, +) +from homeassistant.helpers.typing import EventType from .const import DOMAIN as SWITCH_AS_X_DOMAIN @@ -77,7 +81,9 @@ class BaseEntity(Entity): """Register callbacks and copy the wrapped entity's custom name if set.""" @callback - def _async_state_changed_listener(event: Event | None = None) -> None: + def _async_state_changed_listener( + event: EventType[EventStateChangedData] | None = None, + ) -> None: """Handle child updates.""" self.async_state_changed_listener(event) self.async_write_ha_state() diff --git a/homeassistant/components/threshold/binary_sensor.py b/homeassistant/components/threshold/binary_sensor.py index 09f928303bf..a6621c096c3 100644 --- a/homeassistant/components/threshold/binary_sensor.py +++ b/homeassistant/components/threshold/binary_sensor.py @@ -21,7 +21,7 @@ from homeassistant.const import ( STATE_UNAVAILABLE, STATE_UNKNOWN, ) -from homeassistant.core import Event, HomeAssistant, callback +from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import ( config_validation as cv, device_registry as dr, @@ -29,8 +29,11 @@ from homeassistant.helpers import ( ) from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.helpers.event import async_track_state_change_event -from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType +from homeassistant.helpers.event import ( + EventStateChangedData, + async_track_state_change_event, +) +from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType, EventType from .const import CONF_HYSTERESIS, CONF_LOWER, CONF_UPPER @@ -210,7 +213,9 @@ class ThresholdSensor(BinarySensorEntity): self._update_state() @callback - def async_threshold_sensor_state_listener(event: Event) -> None: + def async_threshold_sensor_state_listener( + event: EventType[EventStateChangedData], + ) -> None: """Handle sensor state changes.""" _update_sensor_state() self.async_write_ha_state() diff --git a/homeassistant/components/trend/binary_sensor.py b/homeassistant/components/trend/binary_sensor.py index e43032a580f..020f7903060 100644 --- a/homeassistant/components/trend/binary_sensor.py +++ b/homeassistant/components/trend/binary_sensor.py @@ -29,9 +29,12 @@ from homeassistant.core import HomeAssistant, callback import homeassistant.helpers.config_validation as cv from homeassistant.helpers.entity import generate_entity_id from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.helpers.event import async_track_state_change_event +from homeassistant.helpers.event import ( + EventStateChangedData, + async_track_state_change_event, +) from homeassistant.helpers.reload import async_setup_reload_service -from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType +from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType, EventType from homeassistant.util.dt import utcnow from . import PLATFORMS @@ -174,9 +177,11 @@ class SensorTrend(BinarySensorEntity): """Complete device setup after being added to hass.""" @callback - def trend_sensor_state_listener(event): + def trend_sensor_state_listener( + event: EventType[EventStateChangedData], + ) -> None: """Handle state changes on the observed device.""" - if (new_state := event.data.get("new_state")) is None: + if (new_state := event.data["new_state"]) is None: return try: if self._attribute: @@ -184,7 +189,7 @@ class SensorTrend(BinarySensorEntity): else: state = new_state.state if state not in (STATE_UNKNOWN, STATE_UNAVAILABLE): - sample = (new_state.last_updated.timestamp(), float(state)) + sample = (new_state.last_updated.timestamp(), float(state)) # type: ignore[arg-type] self.samples.append(sample) self.async_schedule_update_ha_state(True) except (ValueError, TypeError) as ex: diff --git a/homeassistant/components/universal/media_player.py b/homeassistant/components/universal/media_player.py index 68ce8e9b96c..94034cdffe5 100644 --- a/homeassistant/components/universal/media_player.py +++ b/homeassistant/components/universal/media_player.py @@ -85,13 +85,14 @@ from homeassistant.helpers import config_validation as cv from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.event import ( + EventStateChangedData, TrackTemplate, async_track_state_change_event, async_track_template_result, ) from homeassistant.helpers.reload import async_setup_reload_service from homeassistant.helpers.service import async_call_from_config -from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType +from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType, EventType ATTR_ACTIVE_CHILD = "active_child" @@ -183,7 +184,9 @@ class UniversalMediaPlayer(MediaPlayerEntity): """Subscribe to children and template state changes.""" @callback - def _async_on_dependency_update(event): + def _async_on_dependency_update( + event: EventType[EventStateChangedData], + ) -> None: """Update ha state when dependencies update.""" self.async_set_context(event.context) self.async_schedule_update_ha_state(True) diff --git a/homeassistant/components/utility_meter/sensor.py b/homeassistant/components/utility_meter/sensor.py index db03a1ccf2e..7301158d6c6 100644 --- a/homeassistant/components/utility_meter/sensor.py +++ b/homeassistant/components/utility_meter/sensor.py @@ -26,7 +26,7 @@ from homeassistant.const import ( STATE_UNKNOWN, UnitOfEnergy, ) -from homeassistant.core import Event, HomeAssistant, State, callback +from homeassistant.core import HomeAssistant, State, callback from homeassistant.helpers import ( device_registry as dr, entity_platform, @@ -36,12 +36,13 @@ from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.event import ( + EventStateChangedData, async_track_point_in_time, async_track_state_change_event, ) from homeassistant.helpers.start import async_at_started from homeassistant.helpers.template import is_number -from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType +from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType, EventType from homeassistant.util import slugify import homeassistant.util.dt as dt_util @@ -451,7 +452,7 @@ class UtilityMeterSensor(RestoreSensor): return None @callback - def async_reading(self, event: Event): + def async_reading(self, event: EventType[EventStateChangedData]) -> None: """Handle the sensor state changes.""" if ( source_state := self.hass.states.get(self._sensor_source_id) @@ -462,8 +463,10 @@ class UtilityMeterSensor(RestoreSensor): self._attr_available = True - old_state: State | None = event.data.get("old_state") - new_state: State = event.data.get("new_state") # type: ignore[assignment] # a state change event always has a new state + old_state = event.data["old_state"] + new_state = event.data["new_state"] + if new_state is None: + return # First check if the new_state is valid (see discussion in PR #88446) if (new_state_val := self._validate_state(new_state)) is None: @@ -492,14 +495,14 @@ class UtilityMeterSensor(RestoreSensor): self.async_write_ha_state() @callback - def async_tariff_change(self, event): + def async_tariff_change(self, event: EventType[EventStateChangedData]) -> None: """Handle tariff changes.""" - if (new_state := event.data.get("new_state")) is None: + if (new_state := event.data["new_state"]) is None: return self._change_status(new_state.state) - def _change_status(self, tariff): + def _change_status(self, tariff: str) -> None: if self._tariff == tariff: self._collecting = async_track_state_change_event( self.hass, [self._sensor_source_id], self.async_reading diff --git a/homeassistant/components/zha/entity.py b/homeassistant/components/zha/entity.py index 43f487f61d4..7f34629400f 100644 --- a/homeassistant/components/zha/entity.py +++ b/homeassistant/components/zha/entity.py @@ -8,7 +8,7 @@ import logging from typing import TYPE_CHECKING, Any, Self from homeassistant.const import ATTR_NAME -from homeassistant.core import CALLBACK_TYPE, Event, callback +from homeassistant.core import CALLBACK_TYPE, callback from homeassistant.helpers import entity from homeassistant.helpers.debounce import Debouncer from homeassistant.helpers.device_registry import CONNECTION_ZIGBEE @@ -16,8 +16,12 @@ from homeassistant.helpers.dispatcher import ( async_dispatcher_connect, async_dispatcher_send, ) -from homeassistant.helpers.event import async_track_state_change_event +from homeassistant.helpers.event import ( + EventStateChangedData, + async_track_state_change_event, +) from homeassistant.helpers.restore_state import RestoreEntity +from homeassistant.helpers.typing import EventType from .core.const import ( ATTR_MANUFACTURER, @@ -319,7 +323,9 @@ class ZhaGroupEntity(BaseZhaEntity): self.async_on_remove(send_removed_signal) @callback - def async_state_changed_listener(self, event: Event): + def async_state_changed_listener( + self, event: EventType[EventStateChangedData] + ) -> None: """Handle child updates.""" # Delay to ensure that we get updates from all members before updating the group assert self._change_listener_debouncer