diff --git a/homeassistant/components/alexa_devices/coordinator.py b/homeassistant/components/alexa_devices/coordinator.py index e7fe1cddb216a..738ba2efb05e6 100644 --- a/homeassistant/components/alexa_devices/coordinator.py +++ b/homeassistant/components/alexa_devices/coordinator.py @@ -132,8 +132,8 @@ def __init__( device_registry = dr.async_get(hass) self.previous_devices: set[str] = { identifier - for device in device_registry.devices.get_devices_for_config_entry_id( - entry.entry_id + for device in dr.async_entries_for_config_entry( + device_registry, entry.entry_id ) if device.entry_type != dr.DeviceEntryType.SERVICE for identifier_domain, identifier in device.identifiers diff --git a/homeassistant/components/assist_satellite/__init__.py b/homeassistant/components/assist_satellite/__init__.py index abc435f4a22e6..a1fd10f07ab6c 100644 --- a/homeassistant/components/assist_satellite/__init__.py +++ b/homeassistant/components/assist_satellite/__init__.py @@ -131,6 +131,8 @@ async def handle_ask_question(call: ServiceCall) -> dict[str, Any]: f"Invalid Assist satellite entity id: {satellite_entity_id}" ) + satellite_entity.async_set_context(call.context) + ask_question_args = { "question": call.data.get("question"), "question_media_id": call.data.get("question_media_id"), diff --git a/homeassistant/components/bang_olufsen/event.py b/homeassistant/components/bang_olufsen/event.py index 625b742164ad7..d7a6fe6456e79 100644 --- a/homeassistant/components/bang_olufsen/event.py +++ b/homeassistant/components/bang_olufsen/event.py @@ -55,9 +55,7 @@ async def async_setup_entry( # As it has to be removed from the device on the app. device_registry = dr.async_get(hass) - devices = device_registry.devices.get_devices_for_config_entry_id( - config_entry.entry_id - ) + devices = dr.async_entries_for_config_entry(device_registry, config_entry.entry_id) for device in devices: if device.model == BeoModel.BEOREMOTE_ONE and device.serial_number not in { remote.serial_number for remote in remotes diff --git a/homeassistant/components/bang_olufsen/websocket.py b/homeassistant/components/bang_olufsen/websocket.py index 0ed29ed916f64..321d1d19e851a 100644 --- a/homeassistant/components/bang_olufsen/websocket.py +++ b/homeassistant/components/bang_olufsen/websocket.py @@ -185,8 +185,8 @@ async def on_notification_notification( # Get remote devices connected to the device from Home Assistant device_serial_numbers = [ device.serial_number - for device in device_registry.devices.get_devices_for_config_entry_id( - self.entry.entry_id + for device in dr.async_entries_for_config_entry( + device_registry, self.entry.entry_id ) if device.serial_number is not None and device.model == BeoModel.BEOREMOTE_ONE diff --git a/homeassistant/components/buienradar/const.py b/homeassistant/components/buienradar/const.py index fd92afd59b0cf..c8e460a636ee8 100644 --- a/homeassistant/components/buienradar/const.py +++ b/homeassistant/components/buienradar/const.py @@ -14,6 +14,9 @@ SUPPORTED_COUNTRY_CODES = ["NL", "BE"] DEFAULT_COUNTRY = "NL" +SERVICE_TIME_ZONE = "Europe/Amsterdam" +"""Time zone of the buienradar.nl service, which updates around local midnight.""" + SCHEDULE_OK = 10 """Schedule next call after (minutes).""" SCHEDULE_NOK = 2 diff --git a/homeassistant/components/buienradar/util.py b/homeassistant/components/buienradar/util.py index 7ffa6c744ece9..b399a5d82b8aa 100644 --- a/homeassistant/components/buienradar/util.py +++ b/homeassistant/components/buienradar/util.py @@ -1,6 +1,6 @@ """Shared utilities for different supported platforms.""" -from datetime import datetime, timedelta +from datetime import timedelta from http import HTTPStatus import logging from typing import Any @@ -34,7 +34,7 @@ from homeassistant.helpers.event import async_track_point_in_utc_time from homeassistant.util import dt as dt_util -from .const import DEFAULT_TIMEOUT, SCHEDULE_NOK, SCHEDULE_OK +from .const import DEFAULT_TIMEOUT, SCHEDULE_NOK, SCHEDULE_OK, SERVICE_TIME_ZONE __all__ = ["BrData"] _LOGGER = logging.getLogger(__name__) @@ -158,7 +158,12 @@ async def _async_update(self): _LOGGER.debug("Buienradar parsed data: %s", result) if result.get(SUCCESS) is not True: - if int(datetime.now().strftime("%H")) > 0: # pylint: disable=home-assistant-enforce-naive-now + # buienradar.nl updates its forecast for the next day between 00:00 + # and 01:00 CE(S)T and often serves nothing during that hour, so the + # warning is only meaningful outside it. The hour that decides this + # is the one at the service, not in the user's configured time zone. + service_tz = await dt_util.async_get_time_zone(SERVICE_TIME_ZONE) + if service_tz is None or dt_util.utcnow().astimezone(service_tz).hour > 0: _LOGGER.warning( "Unable to parse data from Buienradar. (Msg: %s)", result.get(MESSAGE), diff --git a/homeassistant/components/deconz/services.py b/homeassistant/components/deconz/services.py index 2b87d97416d77..51375b82617e6 100644 --- a/homeassistant/components/deconz/services.py +++ b/homeassistant/components/deconz/services.py @@ -181,8 +181,8 @@ async def async_remove_orphaned_entries_service(hub: DeconzHub) -> None: entities_to_be_removed = [] devices_to_be_removed = [ entry.id - for entry in device_registry.devices.get_devices_for_config_entry_id( - hub.config_entry.entry_id + for entry in dr.async_entries_for_config_entry( + device_registry, hub.config_entry.entry_id ) ] diff --git a/homeassistant/components/geofency/device_tracker.py b/homeassistant/components/geofency/device_tracker.py index 8d7c3b24cc42f..7cc32c8431033 100644 --- a/homeassistant/components/geofency/device_tracker.py +++ b/homeassistant/components/geofency/device_tracker.py @@ -42,9 +42,7 @@ def _receive_data(device, gps, location_name, attributes): dev_reg = dr.async_get(hass) dev_ids = { identifier[1] - for device in dev_reg.devices.get_devices_for_config_entry_id( - config_entry.entry_id - ) + for device in dr.async_entries_for_config_entry(dev_reg, config_entry.entry_id) for identifier in device.identifiers } diff --git a/homeassistant/components/gpslogger/device_tracker.py b/homeassistant/components/gpslogger/device_tracker.py index 32e591e099cd3..d09d4dde7ef87 100644 --- a/homeassistant/components/gpslogger/device_tracker.py +++ b/homeassistant/components/gpslogger/device_tracker.py @@ -48,7 +48,7 @@ def _receive_data(device, gps, battery, accuracy, attrs): dev_reg = dr.async_get(hass) dev_ids = { identifier[1] - for device in dev_reg.devices.get_devices_for_config_entry_id(entry.entry_id) + for device in dr.async_entries_for_config_entry(dev_reg, entry.entry_id) for identifier in device.identifiers } if not dev_ids: diff --git a/homeassistant/components/group/__init__.py b/homeassistant/components/group/__init__.py index 2fafaa1928063..7cb68028d6432 100644 --- a/homeassistant/components/group/__init__.py +++ b/homeassistant/components/group/__init__.py @@ -265,6 +265,7 @@ async def groups_service_handler(service: ServiceCall) -> None: mode=service.data.get(ATTR_ALL), object_id=object_id, order=None, + context=service.context, ) return @@ -272,6 +273,8 @@ async def groups_service_handler(service: ServiceCall) -> None: _LOGGER.warning("%s:Group '%s' doesn't exist!", service.service, object_id) return + group.async_set_context(service.context) + # update group if service.service == SERVICE_SET: need_update = False diff --git a/homeassistant/components/group/cover.py b/homeassistant/components/group/cover.py index 67e32f6f2e775..3800589fbfe37 100644 --- a/homeassistant/components/group/cover.py +++ b/homeassistant/components/group/cover.py @@ -5,20 +5,18 @@ import voluptuous as vol from homeassistant.components.cover import ( - ATTR_CURRENT_POSITION, - ATTR_CURRENT_TILT_POSITION, ATTR_POSITION, ATTR_TILT_POSITION, DOMAIN as COVER_DOMAIN, PLATFORM_SCHEMA as COVER_PLATFORM_SCHEMA, CoverEntity, CoverEntityFeature, + CoverEntityStateAttribute, CoverState, ) from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( ATTR_ENTITY_ID, - ATTR_SUPPORTED_FEATURES, CONF_ENTITIES, CONF_NAME, CONF_UNIQUE_ID, @@ -32,6 +30,7 @@ SERVICE_STOP_COVER_TILT, STATE_UNAVAILABLE, STATE_UNKNOWN, + EntityStateAttribute, ) from homeassistant.core import HomeAssistant, State, callback from homeassistant.helpers import config_validation as cv, entity_registry as er @@ -148,7 +147,7 @@ def async_update_supported_features( values.discard(entity_id) return - features = new_state.attributes.get(ATTR_SUPPORTED_FEATURES, 0) + features = new_state.attributes.get(EntityStateAttribute.SUPPORTED_FEATURES, 0) if features & (CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE): self._covers[KEY_OPEN_CLOSE].add(entity_id) @@ -313,14 +312,14 @@ def async_update_group_state(self) -> None: all_position_states = [self.hass.states.get(x) for x in position_covers] position_states: list[State] = list(filter(None, all_position_states)) self._attr_current_cover_position = reduce_attribute( - position_states, ATTR_CURRENT_POSITION + position_states, CoverEntityStateAttribute.CURRENT_POSITION ) tilt_covers = self._tilts[KEY_POSITION] all_tilt_states = [self.hass.states.get(x) for x in tilt_covers] tilt_states: list[State] = list(filter(None, all_tilt_states)) self._attr_current_cover_tilt_position = reduce_attribute( - tilt_states, ATTR_CURRENT_TILT_POSITION + tilt_states, CoverEntityStateAttribute.CURRENT_TILT_POSITION ) supported_features = CoverEntityFeature(0) diff --git a/homeassistant/components/group/entity.py b/homeassistant/components/group/entity.py index 83874d1f143f8..f08438894a8ae 100644 --- a/homeassistant/components/group/entity.py +++ b/homeassistant/components/group/entity.py @@ -6,14 +6,15 @@ from typing import Any, override from homeassistant.const import ( - ATTR_ASSUMED_STATE, ATTR_ENTITY_ID, - ATTR_GROUP_ENTITIES, STATE_OFF, STATE_ON, + EntityCapabilityAttribute, + EntityStateAttribute, ) from homeassistant.core import ( CALLBACK_TYPE, + Context, Event, EventStateChangedData, HomeAssistant, @@ -39,7 +40,9 @@ class GroupEntity(Entity): """Representation of a Group of entities.""" - _unrecorded_attributes = frozenset({ATTR_ENTITY_ID, ATTR_GROUP_ENTITIES}) + _unrecorded_attributes = frozenset( + {ATTR_ENTITY_ID, EntityCapabilityAttribute.GROUP_ENTITIES} + ) _attr_should_poll = False _entity_ids: list[str] @@ -127,7 +130,7 @@ def _update_assumed_state_from_members(self) -> None: for entity_id in self._entity_ids: if (state := self.hass.states.get(entity_id)) is None: continue - if state.attributes.get(ATTR_ASSUMED_STATE): + if state.attributes.get(EntityStateAttribute.ASSUMED_STATE): self._attr_assumed_state = True return @@ -231,6 +234,7 @@ async def async_create_group( mode: bool | None, object_id: str | None, order: int | None, + context: Context | None, ) -> Group: """Initialize a group. @@ -247,6 +251,9 @@ async def async_create_group( order=order, ) + if context is not None: + group.async_set_context(context) + # If called before the platform async_setup is called (test cases) await async_get_component(hass).async_add_entities([group]) return group @@ -430,7 +437,9 @@ def _see_state(self, new_state: State) -> None: domain = new_state.domain state = new_state.state registry = self._registry - self._assumed[entity_id] = bool(new_state.attributes.get(ATTR_ASSUMED_STATE)) + self._assumed[entity_id] = bool( + new_state.attributes.get(EntityStateAttribute.ASSUMED_STATE) + ) if domain not in registry.on_states_by_domain: # Handle the group of a group case @@ -462,11 +471,12 @@ def _async_update_group_state(self, tr_state: State | None = None) -> None: return if tr_state is None or ( - self._assumed_state and not tr_state.attributes.get(ATTR_ASSUMED_STATE) + self._assumed_state + and not tr_state.attributes.get(EntityStateAttribute.ASSUMED_STATE) ): self._assumed_state = self.mode(self._assumed.values()) - elif tr_state.attributes.get(ATTR_ASSUMED_STATE): + elif tr_state.attributes.get(EntityStateAttribute.ASSUMED_STATE): self._assumed_state = True num_on_states = len(self._on_states) diff --git a/homeassistant/components/group/event.py b/homeassistant/components/group/event.py index 668715ba5e865..2303242dab4d0 100644 --- a/homeassistant/components/group/event.py +++ b/homeassistant/components/group/event.py @@ -6,22 +6,21 @@ import voluptuous as vol from homeassistant.components.event import ( - ATTR_EVENT_TYPE, - ATTR_EVENT_TYPES, DOMAIN as EVENT_DOMAIN, PLATFORM_SCHEMA as EVENT_PLATFORM_SCHEMA, EventEntity, + EventEntityCapabilityAttribute, + EventEntityStateAttribute, ) from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( - ATTR_DEVICE_CLASS, ATTR_ENTITY_ID, - ATTR_FRIENDLY_NAME, CONF_ENTITIES, CONF_NAME, CONF_UNIQUE_ID, STATE_UNAVAILABLE, STATE_UNKNOWN, + EntityStateAttribute, ) from homeassistant.core import Event, EventStateChangedData, HomeAssistant, callback from homeassistant.helpers import config_validation as cv, entity_registry as er @@ -142,16 +141,20 @@ def async_state_changed_listener( and old_state.state not in (STATE_UNAVAILABLE, STATE_UNKNOWN) and (new_state := event.data["new_state"]) and new_state.state not in (STATE_UNAVAILABLE, STATE_UNKNOWN) - and (event_type := new_state.attributes.get(ATTR_EVENT_TYPE)) + and ( + event_type := new_state.attributes.get( + EventEntityStateAttribute.EVENT_TYPE + ) + ) ): event_attributes = new_state.attributes.copy() # We should not propagate the event properties as # fired event attributes. - del event_attributes[ATTR_EVENT_TYPE] - del event_attributes[ATTR_EVENT_TYPES] - event_attributes.pop(ATTR_DEVICE_CLASS, None) - event_attributes.pop(ATTR_FRIENDLY_NAME, None) + del event_attributes[EventEntityStateAttribute.EVENT_TYPE] + del event_attributes[EventEntityCapabilityAttribute.EVENT_TYPES] + event_attributes.pop(EntityStateAttribute.DEVICE_CLASS, None) + event_attributes.pop(EntityStateAttribute.FRIENDLY_NAME, None) # Fire the group event self._trigger_event(event_type, event_attributes) @@ -185,7 +188,8 @@ def async_update_group_state(self) -> None: self._attr_event_types = list( set( itertools.chain.from_iterable( - state.attributes.get(ATTR_EVENT_TYPES, []) for state in states + state.attributes.get(EventEntityCapabilityAttribute.EVENT_TYPES, []) + for state in states ) ) ) diff --git a/homeassistant/components/group/fan.py b/homeassistant/components/group/fan.py index 7c3d64879a0f6..14f1ad6ac3475 100644 --- a/homeassistant/components/group/fan.py +++ b/homeassistant/components/group/fan.py @@ -11,7 +11,6 @@ ATTR_DIRECTION, ATTR_OSCILLATING, ATTR_PERCENTAGE, - ATTR_PERCENTAGE_STEP, DOMAIN as FAN_DOMAIN, PLATFORM_SCHEMA as FAN_PLATFORM_SCHEMA, SERVICE_OSCILLATE, @@ -21,17 +20,18 @@ SERVICE_TURN_ON, FanEntity, FanEntityFeature, + FanEntityStateAttribute, ) from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( ATTR_ENTITY_ID, - ATTR_SUPPORTED_FEATURES, CONF_ENTITIES, CONF_NAME, CONF_UNIQUE_ID, STATE_ON, STATE_UNAVAILABLE, STATE_UNKNOWN, + EntityStateAttribute, ) from homeassistant.core import HomeAssistant, State, callback from homeassistant.helpers import config_validation as cv, entity_registry as er @@ -166,7 +166,9 @@ def async_update_supported_features( for values in self._fans.values(): values.discard(entity_id) else: - features = new_state.attributes.get(ATTR_SUPPORTED_FEATURES, 0) + features = new_state.attributes.get( + EntityStateAttribute.SUPPORTED_FEATURES, 0 + ) for feature in SUPPORTED_FLAGS: if features & feature: self._fans[feature].add(entity_id) @@ -286,14 +288,25 @@ def async_update_group_state(self) -> None: percentage_states = self._async_states_by_support_flag( FanEntityFeature.SET_SPEED ) - self._percentage = reduce_attribute(percentage_states, ATTR_PERCENTAGE) + self._percentage = reduce_attribute( + percentage_states, FanEntityStateAttribute.PERCENTAGE + ) if ( percentage_states - and percentage_states[0].attributes.get(ATTR_PERCENTAGE_STEP) - and attribute_equal(percentage_states, ATTR_PERCENTAGE_STEP) + and percentage_states[0].attributes.get( + FanEntityStateAttribute.PERCENTAGE_STEP + ) + and attribute_equal( + percentage_states, FanEntityStateAttribute.PERCENTAGE_STEP + ) ): self._speed_count = ( - round(100 / percentage_states[0].attributes[ATTR_PERCENTAGE_STEP]) + round( + 100 + / percentage_states[0].attributes[ + FanEntityStateAttribute.PERCENTAGE_STEP + ] + ) or 100 ) else: diff --git a/homeassistant/components/group/light.py b/homeassistant/components/group/light.py index 68f922272b4cd..2877d60d8a096 100644 --- a/homeassistant/components/group/light.py +++ b/homeassistant/components/group/light.py @@ -10,31 +10,27 @@ from homeassistant.components import light from homeassistant.components.light import ( ATTR_BRIGHTNESS, - ATTR_COLOR_MODE, ATTR_COLOR_TEMP_KELVIN, ATTR_EFFECT, - ATTR_EFFECT_LIST, ATTR_FLASH, ATTR_HS_COLOR, - ATTR_MAX_COLOR_TEMP_KELVIN, - ATTR_MIN_COLOR_TEMP_KELVIN, ATTR_RGB_COLOR, ATTR_RGBW_COLOR, ATTR_RGBWW_COLOR, - ATTR_SUPPORTED_COLOR_MODES, ATTR_TRANSITION, ATTR_WHITE, ATTR_XY_COLOR, PLATFORM_SCHEMA as LIGHT_PLATFORM_SCHEMA, ColorMode, LightEntity, + LightEntityCapabilityAttribute, LightEntityFeature, + LightEntityStateAttribute, filter_supported_color_modes, ) from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( ATTR_ENTITY_ID, - ATTR_SUPPORTED_FEATURES, CONF_ENTITIES, CONF_NAME, CONF_UNIQUE_ID, @@ -43,6 +39,7 @@ STATE_ON, STATE_UNAVAILABLE, STATE_UNKNOWN, + EntityStateAttribute, ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv, entity_registry as er @@ -227,36 +224,46 @@ def async_update_group_state(self) -> None: self._attr_is_on = self.mode(state.state == STATE_ON for state in states) self._attr_available = any(state.state != STATE_UNAVAILABLE for state in states) - self._attr_brightness = reduce_attribute(on_states, ATTR_BRIGHTNESS) + self._attr_brightness = reduce_attribute( + on_states, LightEntityStateAttribute.BRIGHTNESS + ) self._attr_hs_color = reduce_attribute( - on_states, ATTR_HS_COLOR, reduce=mean_circle + on_states, LightEntityStateAttribute.HS_COLOR, reduce=mean_circle ) self._attr_rgb_color = reduce_attribute( - on_states, ATTR_RGB_COLOR, reduce=mean_tuple + on_states, LightEntityStateAttribute.RGB_COLOR, reduce=mean_tuple ) self._attr_rgbw_color = reduce_attribute( - on_states, ATTR_RGBW_COLOR, reduce=mean_tuple + on_states, LightEntityStateAttribute.RGBW_COLOR, reduce=mean_tuple ) self._attr_rgbww_color = reduce_attribute( - on_states, ATTR_RGBWW_COLOR, reduce=mean_tuple + on_states, LightEntityStateAttribute.RGBWW_COLOR, reduce=mean_tuple ) self._attr_xy_color = reduce_attribute( - on_states, ATTR_XY_COLOR, reduce=mean_tuple + on_states, LightEntityStateAttribute.XY_COLOR, reduce=mean_tuple ) self._attr_color_temp_kelvin = reduce_attribute( - on_states, ATTR_COLOR_TEMP_KELVIN + on_states, LightEntityStateAttribute.COLOR_TEMP_KELVIN ) self._attr_min_color_temp_kelvin = reduce_attribute( - states, ATTR_MIN_COLOR_TEMP_KELVIN, default=2000, reduce=min + states, + LightEntityCapabilityAttribute.MIN_COLOR_TEMP_KELVIN, + default=2000, + reduce=min, ) self._attr_max_color_temp_kelvin = reduce_attribute( - states, ATTR_MAX_COLOR_TEMP_KELVIN, default=6500, reduce=max + states, + LightEntityCapabilityAttribute.MAX_COLOR_TEMP_KELVIN, + default=6500, + reduce=max, ) self._attr_effect_list = None - all_effect_lists = list(find_state_attributes(states, ATTR_EFFECT_LIST)) + all_effect_lists = list( + find_state_attributes(states, LightEntityCapabilityAttribute.EFFECT_LIST) + ) if all_effect_lists: # Merge all effects from all effect_lists with a union merge. self._attr_effect_list = list(set().union(*all_effect_lists)) @@ -266,7 +273,9 @@ def async_update_group_state(self) -> None: self._attr_effect_list.insert(0, "None") self._attr_effect = None - all_effects = list(find_state_attributes(on_states, ATTR_EFFECT)) + all_effects = list( + find_state_attributes(on_states, LightEntityStateAttribute.EFFECT) + ) if all_effects: # Report the most common effect. effects_count = Counter(itertools.chain(all_effects)) @@ -274,7 +283,9 @@ def async_update_group_state(self) -> None: supported_color_modes = {ColorMode.ONOFF} all_supported_color_modes = list( - find_state_attributes(states, ATTR_SUPPORTED_COLOR_MODES) + find_state_attributes( + states, LightEntityCapabilityAttribute.SUPPORTED_COLOR_MODES + ) ) if all_supported_color_modes: # Merge all color modes. @@ -284,7 +295,9 @@ def async_update_group_state(self) -> None: self._attr_supported_color_modes = supported_color_modes self._attr_color_mode = ColorMode.UNKNOWN - all_color_modes = list(find_state_attributes(on_states, ATTR_COLOR_MODE)) + all_color_modes = list( + find_state_attributes(on_states, LightEntityStateAttribute.COLOR_MODE) + ) if all_color_modes: # Report the most common color mode, select brightness and onoff last color_mode_count = Counter(itertools.chain(all_color_modes)) @@ -304,7 +317,9 @@ def async_update_group_state(self) -> None: self._attr_color_mode = next(iter(supported_color_modes)) self._attr_supported_features = LightEntityFeature(0) - for support in find_state_attributes(states, ATTR_SUPPORTED_FEATURES): + for support in find_state_attributes( + states, EntityStateAttribute.SUPPORTED_FEATURES + ): # Merge supported features by emulating support for every feature # we find. self._attr_supported_features |= support diff --git a/homeassistant/components/group/media_player.py b/homeassistant/components/group/media_player.py index 82d8d1533c0e7..e554fc4c2d990 100644 --- a/homeassistant/components/group/media_player.py +++ b/homeassistant/components/group/media_player.py @@ -19,13 +19,13 @@ SERVICE_PLAY_MEDIA, MediaPlayerEntity, MediaPlayerEntityFeature, + MediaPlayerEntityStateAttribute, MediaPlayerState, MediaType, ) from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( ATTR_ENTITY_ID, - ATTR_SUPPORTED_FEATURES, CONF_ENTITIES, CONF_NAME, CONF_UNIQUE_ID, @@ -42,6 +42,7 @@ SERVICE_VOLUME_SET, STATE_UNAVAILABLE, STATE_UNKNOWN, + EntityStateAttribute, ) from homeassistant.core import ( CALLBACK_TYPE, @@ -174,7 +175,9 @@ def async_update_supported_features( players.discard(entity_id) return - new_features = new_state.attributes.get(ATTR_SUPPORTED_FEATURES, 0) + new_features = new_state.attributes.get( + EntityStateAttribute.SUPPORTED_FEATURES, 0 + ) if new_features & MediaPlayerEntityFeature.CLEAR_PLAYLIST: self._features[KEY_CLEAR_PLAYLIST].add(entity_id) else: @@ -441,7 +444,9 @@ async def async_turn_off(self) -> None: async def async_volume_up(self) -> None: """Turn volume up for media player(s).""" for entity in self._features[KEY_VOLUME]: - volume_level = self.hass.states.get(entity).attributes["volume_level"] # type: ignore[union-attr] + volume_level = self.hass.states.get(entity).attributes[ # type: ignore[union-attr] + MediaPlayerEntityStateAttribute.MEDIA_VOLUME_LEVEL + ] if volume_level < 1: await self.async_set_volume_level(min(1, volume_level + 0.1)) @@ -449,7 +454,9 @@ async def async_volume_up(self) -> None: async def async_volume_down(self) -> None: """Turn volume down for media player(s).""" for entity in self._features[KEY_VOLUME]: - volume_level = self.hass.states.get(entity).attributes["volume_level"] # type: ignore[union-attr] + volume_level = self.hass.states.get(entity).attributes[ # type: ignore[union-attr] + MediaPlayerEntityStateAttribute.MEDIA_VOLUME_LEVEL + ] if volume_level > 0: await self.async_set_volume_level(max(0, volume_level - 0.1)) diff --git a/homeassistant/components/group/notify.py b/homeassistant/components/group/notify.py index 3e61157ab8b52..f0fab28356c38 100644 --- a/homeassistant/components/group/notify.py +++ b/homeassistant/components/group/notify.py @@ -21,11 +21,11 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( ATTR_ENTITY_ID, - ATTR_SUPPORTED_FEATURES, CONF_ACTION, CONF_ENTITIES, CONF_SERVICE, STATE_UNAVAILABLE, + EntityStateAttribute, ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv, entity_registry as er @@ -213,7 +213,7 @@ def async_update_group_state(self) -> None: state = self.hass.states.get(entity_id) if ( state is None - or not state.attributes.get(ATTR_SUPPORTED_FEATURES, 0) + or not state.attributes.get(EntityStateAttribute.SUPPORTED_FEATURES, 0) & NotifyEntityFeature.TITLE ): self._attr_supported_features &= ~NotifyEntityFeature.TITLE diff --git a/homeassistant/components/group/sensor.py b/homeassistant/components/group/sensor.py index 24628ad255999..134af6b9953bf 100644 --- a/homeassistant/components/group/sensor.py +++ b/homeassistant/components/group/sensor.py @@ -36,6 +36,7 @@ CONF_UNIT_OF_MEASUREMENT, STATE_UNAVAILABLE, STATE_UNKNOWN, + EntityStateAttribute, ) from homeassistant.core import HomeAssistant, State, callback from homeassistant.exceptions import HomeAssistantError @@ -401,7 +402,7 @@ def async_update_group_state(self) -> None: states.append(state.state) try: numeric_state = float(state.state) - uom = state.attributes.get("unit_of_measurement") + uom = state.attributes.get(EntityStateAttribute.UNIT_OF_MEASUREMENT) # Convert the state to the native unit of # measurement when we have valid units @@ -455,7 +456,9 @@ def async_update_group_state(self) -> None: entity_id, state.state, self.device_class, - state.attributes.get("unit_of_measurement"), + state.attributes.get( + EntityStateAttribute.UNIT_OF_MEASUREMENT + ), self.entity_id, ) else: diff --git a/homeassistant/components/group/valve.py b/homeassistant/components/group/valve.py index 2ed81dfa4fc71..d9524fb46c74c 100644 --- a/homeassistant/components/group/valve.py +++ b/homeassistant/components/group/valve.py @@ -5,18 +5,17 @@ import voluptuous as vol from homeassistant.components.valve import ( - ATTR_CURRENT_POSITION, ATTR_POSITION, DOMAIN as VALVE_DOMAIN, PLATFORM_SCHEMA as VALVE_PLATFORM_SCHEMA, ValveEntity, ValveEntityFeature, + ValveEntityStateAttribute, ValveState, ) from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( ATTR_ENTITY_ID, - ATTR_SUPPORTED_FEATURES, CONF_ENTITIES, CONF_NAME, CONF_UNIQUE_ID, @@ -26,6 +25,7 @@ SERVICE_STOP_VALVE, STATE_UNAVAILABLE, STATE_UNKNOWN, + EntityStateAttribute, ) from homeassistant.core import HomeAssistant, State, callback from homeassistant.helpers import config_validation as cv, entity_registry as er @@ -136,7 +136,7 @@ def async_update_supported_features( values.discard(entity_id) return - features = new_state.attributes.get(ATTR_SUPPORTED_FEATURES, 0) + features = new_state.attributes.get(EntityStateAttribute.SUPPORTED_FEATURES, 0) if features & (ValveEntityFeature.OPEN | ValveEntityFeature.CLOSE): self._valves[KEY_OPEN_CLOSE].add(entity_id) @@ -233,7 +233,10 @@ def async_update_group_state(self) -> None: self._attr_reports_position = False self._update_assumed_state_from_members() for state in states: - if state.attributes.get(ATTR_CURRENT_POSITION) is not None: + if ( + state.attributes.get(ValveEntityStateAttribute.CURRENT_POSITION) + is not None + ): self._attr_reports_position = True if state.state == ValveState.OPEN: self._attr_is_closed = False @@ -255,7 +258,7 @@ def async_update_group_state(self) -> None: self._attr_is_closed = None self._attr_current_valve_position = reduce_attribute( - states, ATTR_CURRENT_POSITION + states, ValveEntityStateAttribute.CURRENT_POSITION ) supported_features = ValveEntityFeature(0) diff --git a/homeassistant/components/hassio/coordinator.py b/homeassistant/components/hassio/coordinator.py index 985df7331956f..f5115c7f7e3ae 100644 --- a/homeassistant/components/hassio/coordinator.py +++ b/homeassistant/components/hassio/coordinator.py @@ -1347,9 +1347,7 @@ async def _async_update_data(self) -> HassioAddonData: # Remove add-ons that are no longer installed from device registry supervisor_addon_devices = { list(device.identifiers)[0][1] - for device in self.dev_reg.devices.get_devices_for_config_entry_id( - self.entry_id - ) + for device in dr.async_entries_for_config_entry(self.dev_reg, self.entry_id) if device.model == SupervisorEntityModel.ADDON } if stale_addons := supervisor_addon_devices - set(new_data.addons): @@ -1569,9 +1567,7 @@ async def _async_update_data(self) -> HassioMainData: # Remove mounts that no longer exists from device registry supervisor_mount_devices = { device.name - for device in self.dev_reg.devices.get_devices_for_config_entry_id( - self.entry_id - ) + for device in dr.async_entries_for_config_entry(self.dev_reg, self.entry_id) if device.model == SupervisorEntityModel.MOUNT } if stale_mounts := supervisor_mount_devices - set(new_data.mounts): diff --git a/homeassistant/components/heos/__init__.py b/homeassistant/components/heos/__init__.py index c2d24e79968df..ac39f180cc0df 100644 --- a/homeassistant/components/heos/__init__.py +++ b/homeassistant/components/heos/__init__.py @@ -32,9 +32,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: HeosConfigEntry) -> bool # Migrate non-string device identifiers. device_registry = dr.async_get(hass) - for device in device_registry.devices.get_devices_for_config_entry_id( - entry.entry_id - ): + for device in dr.async_entries_for_config_entry(device_registry, entry.entry_id): for ident in device.identifiers: if ident[0] != DOMAIN or isinstance(ident[1], str): continue diff --git a/homeassistant/components/home_connect/config_flow.py b/homeassistant/components/home_connect/config_flow.py index 897416b156b6a..4c852654ebf2c 100644 --- a/homeassistant/components/home_connect/config_flow.py +++ b/homeassistant/components/home_connect/config_flow.py @@ -2,7 +2,7 @@ from collections.abc import Mapping import logging -from typing import Any, override +from typing import Any, Final, override import jwt import voluptuous as vol @@ -13,6 +13,8 @@ from .const import DOMAIN +INPUT_IMAGES_SCOPE: Final = "images_scope" + class OAuth2FlowHandler( config_entry_oauth2_flow.AbstractOAuth2FlowHandler, domain=DOMAIN @@ -23,12 +25,49 @@ class OAuth2FlowHandler( MINOR_VERSION = 3 + images_scope: bool | None = None + @property @override def logger(self) -> logging.Logger: """Return logger.""" return logging.getLogger(__name__) + @property + @override + def extra_authorize_data(self) -> dict[str, str]: + return { + "scope": ( + "Control Monitor Settings" + f" IdentifyAppliance{' Images' if self.images_scope else ''}" + ), + } + + @override + async def async_step_user( + self, user_input: dict[str, Any] | None = None + ) -> ConfigFlowResult: + """Handle a flow start.""" + return await self.async_step_scopes(user_input) + + async def async_step_scopes( + self, user_input: dict[str, Any] | None = None + ) -> ConfigFlowResult: + """Ask for the scopes to use.""" + if user_input is not None: + self.images_scope = user_input[INPUT_IMAGES_SCOPE] + if self.images_scope is not None: + return await self.async_step_pick_implementation(None) + + return self.async_show_form( + step_id="scopes", + data_schema=vol.Schema( + { + vol.Required(INPUT_IMAGES_SCOPE): bool, + } + ), + ) + async def async_step_reauth( self, entry_data: Mapping[str, Any] ) -> ConfigFlowResult: diff --git a/homeassistant/components/home_connect/strings.json b/homeassistant/components/home_connect/strings.json index 2a3e42c602bca..2ff4b99a17122 100644 --- a/homeassistant/components/home_connect/strings.json +++ b/homeassistant/components/home_connect/strings.json @@ -17,6 +17,7 @@ "oauth_timeout": "[%key:common::config_flow::abort::oauth2_timeout%]", "oauth_unauthorized": "[%key:common::config_flow::abort::oauth2_unauthorized%]", "reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]", + "user_rejected_authorize": "[%key:common::config_flow::abort::oauth2_user_rejected_authorize%]", "wrong_account": "Please ensure you reconfigure against the same account." }, "create_entry": { @@ -38,6 +39,16 @@ "reauth_confirm": { "description": "The Home Connect integration needs to re-authenticate your account", "title": "[%key:common::config_flow::title::reauth%]" + }, + "scopes": { + "data": { + "images_scope": "Images scope" + }, + "data_description": { + "images_scope": "Allows Home Assistant to access images from your Home Connect devices." + }, + "description": "Select the optional scopes you want to enable for Home Connect authentication.", + "title": "Scopes" } } }, diff --git a/homeassistant/components/homekit/__init__.py b/homeassistant/components/homekit/__init__.py index 017e9c721fca7..cbf0fb0e9a515 100644 --- a/homeassistant/components/homekit/__init__.py +++ b/homeassistant/components/homekit/__init__.py @@ -1008,7 +1008,7 @@ def _async_purge_old_bridges( """Purge bridges that exist from failed pairing or manual resets.""" devices_to_purge = [ entry.id - for entry in dev_reg.devices.get_devices_for_config_entry_id(self._entry_id) + for entry in dr.async_entries_for_config_entry(dev_reg, self._entry_id) if ( identifier not in entry.identifiers # type: ignore[comparison-overlap] or connection not in entry.connections # type: ignore[unreachable] diff --git a/homeassistant/components/husqvarna_automower/coordinator.py b/homeassistant/components/husqvarna_automower/coordinator.py index e5cddbff7e311..85724a618396f 100644 --- a/homeassistant/components/husqvarna_automower/coordinator.py +++ b/homeassistant/components/husqvarna_automower/coordinator.py @@ -218,8 +218,8 @@ def _async_add_remove_devices(self) -> None: registered_devices: set[str] = { str(mower_id) - for device in device_registry.devices.get_devices_for_config_entry_id( - self.config_entry.entry_id + for device in dr.async_entries_for_config_entry( + device_registry, self.config_entry.entry_id ) for domain, mower_id in device.identifiers if domain == DOMAIN diff --git a/homeassistant/components/ibeacon/coordinator.py b/homeassistant/components/ibeacon/coordinator.py index 826d34a526d3f..4477dd3179af6 100644 --- a/homeassistant/components/ibeacon/coordinator.py +++ b/homeassistant/components/ibeacon/coordinator.py @@ -16,7 +16,7 @@ from homeassistant.components.bluetooth.match import BluetoothCallbackMatcher from homeassistant.config_entries import ConfigEntry from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback -from homeassistant.helpers.device_registry import DeviceRegistry +from homeassistant.helpers import device_registry as dr from homeassistant.helpers.dispatcher import async_dispatcher_send from homeassistant.helpers.event import async_track_time_interval @@ -112,7 +112,7 @@ class IBeaconCoordinator: """Set up the iBeacon Coordinator.""" def __init__( - self, hass: HomeAssistant, entry: ConfigEntry, registry: DeviceRegistry + self, hass: HomeAssistant, entry: ConfigEntry, registry: dr.DeviceRegistry ) -> None: """Initialize the Coordinator.""" self.hass = hass @@ -508,8 +508,8 @@ def _async_update(self, _now: datetime) -> None: @callback def _async_restore_from_registry(self) -> None: """Restore the state of the Coordinator from the device registry.""" - for device in self._dev_reg.devices.get_devices_for_config_entry_id( - self._entry.entry_id + for device in dr.async_entries_for_config_entry( + self._dev_reg, self._entry.entry_id ): if not (identifier := next(iter(device.identifiers), None)): continue diff --git a/homeassistant/components/incomfort/coordinator.py b/homeassistant/components/incomfort/coordinator.py index 12f1255bb0513..9901cb74a9bd8 100644 --- a/homeassistant/components/incomfort/coordinator.py +++ b/homeassistant/components/incomfort/coordinator.py @@ -47,9 +47,7 @@ def async_cleanup_stale_devices( """Cleanup stale heater devices and climates.""" heater_serial_numbers = {heater.serial_no for heater in data.heaters} device_registry = dr.async_get(hass) - device_entries = device_registry.devices.get_devices_for_config_entry_id( - entry.entry_id - ) + device_entries = dr.async_entries_for_config_entry(device_registry, entry.entry_id) stale_heater_serial_numbers: list[str] = [ device_entry.serial_number for device_entry in device_entries diff --git a/homeassistant/components/kulersky/__init__.py b/homeassistant/components/kulersky/__init__.py index b123a4cc035e7..1dc137d27d900 100644 --- a/homeassistant/components/kulersky/__init__.py +++ b/homeassistant/components/kulersky/__init__.py @@ -45,7 +45,7 @@ async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> # supports core bluetooth discovery if config_entry.version == 1: dev_reg = dr.async_get(hass) - devices = dev_reg.devices.get_devices_for_config_entry_id(config_entry.entry_id) + devices = dr.async_entries_for_config_entry(dev_reg, config_entry.entry_id) if len(devices) == 0: _LOGGER.error("Unable to migrate; No devices registered") diff --git a/homeassistant/components/lyngdorf/manifest.json b/homeassistant/components/lyngdorf/manifest.json index 6d69099b5e8ad..2f5242de5b430 100644 --- a/homeassistant/components/lyngdorf/manifest.json +++ b/homeassistant/components/lyngdorf/manifest.json @@ -9,7 +9,7 @@ "iot_class": "local_push", "loggers": ["lyngdorf", "async_upnp_client"], "quality_scale": "silver", - "requirements": ["lyngdorf==1.8.0"], + "requirements": ["lyngdorf==1.9.0"], "ssdp": [ { "deviceType": "urn:schemas-upnp-org:device:MediaRenderer:2", diff --git a/homeassistant/components/mvglive/manifest.json b/homeassistant/components/mvglive/manifest.json index 0229ef35b9c30..da726616f54d4 100644 --- a/homeassistant/components/mvglive/manifest.json +++ b/homeassistant/components/mvglive/manifest.json @@ -6,5 +6,5 @@ "iot_class": "cloud_polling", "loggers": ["MVG"], "quality_scale": "legacy", - "requirements": ["mvg==1.4.0"] + "requirements": ["mvg==1.6.0"] } diff --git a/homeassistant/components/owntracks/device_tracker.py b/homeassistant/components/owntracks/device_tracker.py index 477bf74c4cfa8..e7de158669193 100644 --- a/homeassistant/components/owntracks/device_tracker.py +++ b/homeassistant/components/owntracks/device_tracker.py @@ -49,7 +49,7 @@ async def async_setup_entry( dev_reg = dr.async_get(hass) dev_ids = { identifier[1] - for device in dev_reg.devices.get_devices_for_config_entry_id(entry.entry_id) + for device in dr.async_entries_for_config_entry(dev_reg, entry.entry_id) for identifier in device.identifiers } diff --git a/homeassistant/components/ps4/media_player.py b/homeassistant/components/ps4/media_player.py index 732e31a7011ee..cd5dd5de3e3f7 100644 --- a/homeassistant/components/ps4/media_player.py +++ b/homeassistant/components/ps4/media_player.py @@ -350,9 +350,7 @@ async def async_get_device_info(self, status: dict[str, Any] | None) -> None: self._attr_unique_id = entry.unique_id self.entity_id = entry.entity_id break - for device in d_registry.devices.get_devices_for_config_entry_id( - self._entry_id - ): + for device in dr.async_entries_for_config_entry(d_registry, self._entry_id): # Rebuilt from the existing device entry, which already carries # the network MAC connection added by the live-status branch. self._attr_device_info = DeviceInfo( diff --git a/homeassistant/components/purpleair/config_flow.py b/homeassistant/components/purpleair/config_flow.py index 84742a2b188b1..518ab03a541b3 100644 --- a/homeassistant/components/purpleair/config_flow.py +++ b/homeassistant/components/purpleair/config_flow.py @@ -110,8 +110,8 @@ def async_get_remove_sensor_options( device_registry = dr.async_get(hass) return [ SelectOptionDict(value=device_entry.id, label=cast(str, device_entry.name)) - for device_entry in device_registry.devices.get_devices_for_config_entry_id( - config_entry.entry_id + for device_entry in dr.async_entries_for_config_entry( + device_registry, config_entry.entry_id ) ] diff --git a/homeassistant/components/scrape/manifest.json b/homeassistant/components/scrape/manifest.json index 8140d9608100d..ad1d61d67a37f 100644 --- a/homeassistant/components/scrape/manifest.json +++ b/homeassistant/components/scrape/manifest.json @@ -6,5 +6,5 @@ "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/scrape", "iot_class": "cloud_polling", - "requirements": ["beautifulsoup4==4.13.3", "lxml==6.1.1"] + "requirements": ["beautifulsoup4==4.13.3", "lxml==6.1.2"] } diff --git a/homeassistant/components/shelly/utils.py b/homeassistant/components/shelly/utils.py index d5515e33fdfa4..98908bd938962 100644 --- a/homeassistant/components/shelly/utils.py +++ b/homeassistant/components/shelly/utils.py @@ -917,7 +917,7 @@ def remove_stale_blu_trv_devices( return dev_reg = dr.async_get(hass) - devices = dev_reg.devices.get_devices_for_config_entry_id(entry.entry_id) + devices = dr.async_entries_for_config_entry(dev_reg, entry.entry_id) config = rpc_device.config blutrv_keys = get_rpc_key_ids(config, BLU_TRV_IDENTIFIER) trv_addrs = [config[f"{BLU_TRV_IDENTIFIER}:{key}"]["addr"] for key in blutrv_keys] @@ -943,7 +943,7 @@ def remove_empty_sub_devices(hass: HomeAssistant, entry: ConfigEntry) -> None: dev_reg = dr.async_get(hass) entity_reg = er.async_get(hass) - devices = dev_reg.devices.get_devices_for_config_entry_id(entry.entry_id) + devices = dr.async_entries_for_config_entry(dev_reg, entry.entry_id) for device in devices: if not device.via_device_id: diff --git a/homeassistant/components/tplink_omada/__init__.py b/homeassistant/components/tplink_omada/__init__.py index a782ae0045385..02bd9b5253451 100644 --- a/homeassistant/components/tplink_omada/__init__.py +++ b/homeassistant/components/tplink_omada/__init__.py @@ -91,8 +91,8 @@ def _remove_old_devices( ) -> None: device_registry = dr.async_get(hass) - for registered_device in device_registry.devices.get_devices_for_config_entry_id( - entry.entry_id + for registered_device in dr.async_entries_for_config_entry( + device_registry, entry.entry_id ): mac = next( (i[1] for i in registered_device.identifiers if i[0] == DOMAIN), None diff --git a/homeassistant/components/traccar/device_tracker.py b/homeassistant/components/traccar/device_tracker.py index d260410f43383..cb9d674969044 100644 --- a/homeassistant/components/traccar/device_tracker.py +++ b/homeassistant/components/traccar/device_tracker.py @@ -95,7 +95,7 @@ def _receive_data(device, latitude, longitude, battery, accuracy, attrs): dev_reg = dr.async_get(hass) dev_ids = { identifier[1] - for device in dev_reg.devices.get_devices_for_config_entry_id(entry.entry_id) + for device in dr.async_entries_for_config_entry(dev_reg, entry.entry_id) for identifier in device.identifiers } if not dev_ids: diff --git a/homeassistant/components/withings/sensor.py b/homeassistant/components/withings/sensor.py index 43ae2a4e7dafb..fb1def96c4f16 100644 --- a/homeassistant/components/withings/sensor.py +++ b/homeassistant/components/withings/sensor.py @@ -866,7 +866,7 @@ def _async_device_listener() -> None: ) ) and config_entry.state is ConfigEntryState.LOADED - for device in device_registry.devices.get_entries( + for device in device_registry.async_get_devices( identifiers={(DOMAIN, device_id)} ) ): diff --git a/homeassistant/components/zha/logbook.py b/homeassistant/components/zha/logbook.py index 8dd7bd1d740f0..2d88d60324a6c 100644 --- a/homeassistant/components/zha/logbook.py +++ b/homeassistant/components/zha/logbook.py @@ -36,7 +36,9 @@ def async_describe_zha_event(event: Event) -> dict[str, str]: event_subtype: str | None = None try: - device = device_registry.devices[event.data[ATTR_DEVICE_ID]] + device = device_registry.async_get( + event.data[ATTR_DEVICE_ID], include_child_devices=False + ) if device: device_name = device.name_by_user or device.name or "Unknown device" zha_device = async_get_zha_device_proxy( diff --git a/homeassistant/components/zwave_js/__init__.py b/homeassistant/components/zwave_js/__init__.py index bd6930be8c215..fc62275f4286b 100644 --- a/homeassistant/components/zwave_js/__init__.py +++ b/homeassistant/components/zwave_js/__init__.py @@ -94,7 +94,6 @@ CONF_ADDON_SOCKET, CONF_DATA_COLLECTION_OPTED_IN, CONF_INTEGRATION_CREATED_ADDON, - CONF_KEEP_OLD_DEVICES, CONF_LR_S2_ACCESS_CONTROL_KEY, CONF_LR_S2_AUTHENTICATED_KEY, CONF_NETWORK_KEY, @@ -391,11 +390,12 @@ async def handle_logging_changed(_: Event | None = None) -> None: controller.on("identify", self.controller_events.async_on_identify) ) - if ( + unknown_controller = ( old_unique_id := self.config_entry.unique_id ) is not None and old_unique_id != ( new_unique_id := str(driver.controller.home_id) - ): + ) + if unknown_controller: device_registry = dr.async_get(self.hass) controller_model = "Unknown model" if ( @@ -411,9 +411,6 @@ async def handle_logging_changed(_: Event | None = None) -> None: ): controller_model = model - # Do not clean up old stale devices if an unknown controller is connected. - data = {**self.config_entry.data, CONF_KEEP_OLD_DEVICES: True} - self.hass.config_entries.async_update_entry(self.config_entry, data=data) async_create_issue( self.hass, DOMAIN, @@ -430,9 +427,6 @@ async def handle_logging_changed(_: Event | None = None) -> None: translation_key="migrate_unique_id", ) else: - data = self.config_entry.data.copy() - data.pop(CONF_KEEP_OLD_DEVICES, None) - self.hass.config_entries.async_update_entry(self.config_entry, data=data) async_delete_issue( self.hass, DOMAIN, f"migrate_unique_id.{self.config_entry.entry_id}" ) @@ -455,8 +449,8 @@ async def handle_logging_changed(_: Event | None = None) -> None: ] # Devices that are in the device registry that are not known by the controller - # can be removed - if not self.config_entry.data.get(CONF_KEEP_OLD_DEVICES): + # can be removed, but not while an unknown controller is connected. + if not unknown_controller: for device in stored_devices: if device not in known_devices and device not in provisioned_devices: self.dev_reg.async_remove_device(device.id) diff --git a/homeassistant/components/zwave_js/api.py b/homeassistant/components/zwave_js/api.py index d2c57ccbab6ea..5b98bdfd69e9a 100644 --- a/homeassistant/components/zwave_js/api.py +++ b/homeassistant/components/zwave_js/api.py @@ -51,6 +51,7 @@ NodeFirmwareUpdateProgress, NodeFirmwareUpdateResult, ) +from zwave_js_server.model.statistics import RouteStatistics from zwave_js_server.model.utils import ( async_parse_qr_code_string, async_try_parse_dsk_from_qr_code_string, @@ -2835,10 +2836,30 @@ def _convert_node_to_device_id(node: Node) -> str: device = dev_reg.async_get_device_by_identifier( get_device_id(driver, node), entry.entry_id ) - assert device + if device is None: + raise ValueError(f"Device for node {node.node_id} not found") return device.id - data: dict = { + def _get_route_statistics_dict( + route_statistics: RouteStatistics | None, + ) -> dict[str, Any] | None: + """Get dictionary of route statistics.""" + if route_statistics is None: + return None + try: + data: dict[str, Any] = dict(route_statistics.as_dict()) + for key in ("repeaters", "route_failed_between"): + if data[key]: + data[key] = [_convert_node_to_device_id(node) for node in data[key]] + except KeyError, StopIteration, ValueError: + # The route may reference nodes that have been removed from the + # network (KeyError) or that don't have a device entry (ValueError), + # and async_get_config_entry_from_node raises StopIteration when + # the config entry is no longer loaded + return None + return data + + return { "commands_tx": statistics.commands_tx, "commands_rx": statistics.commands_rx, "commands_dropped_tx": statistics.commands_dropped_tx, @@ -2846,20 +2867,9 @@ def _convert_node_to_device_id(node: Node) -> str: "timeout_response": statistics.timeout_response, "rtt": statistics.rtt, "rssi": statistics.rssi, - "lwr": statistics.lwr.as_dict() if statistics.lwr else None, - "nlwr": statistics.nlwr.as_dict() if statistics.nlwr else None, + "lwr": _get_route_statistics_dict(statistics.lwr), + "nlwr": _get_route_statistics_dict(statistics.nlwr), } - for key in ("lwr", "nlwr"): - if not data[key]: - continue - for key_2 in ("repeaters", "route_failed_between"): - if not data[key][key_2]: - continue - data[key][key_2] = [ - _convert_node_to_device_id(node) for node in data[key][key_2] - ] - - return data @websocket_api.require_admin diff --git a/homeassistant/components/zwave_js/config_flow.py b/homeassistant/components/zwave_js/config_flow.py index 773b322f3bfec..457be46b9a151 100644 --- a/homeassistant/components/zwave_js/config_flow.py +++ b/homeassistant/components/zwave_js/config_flow.py @@ -2,6 +2,7 @@ import asyncio import base64 +from collections.abc import Callable from contextlib import suppress import logging from pathlib import Path @@ -10,7 +11,7 @@ from awesomeversion import AwesomeVersion import voluptuous as vol from zwave_js_server.client import Client -from zwave_js_server.exceptions import FailedCommand +from zwave_js_server.exceptions import BaseZwaveJSServerError, FailedCommand from zwave_js_server.model.driver import Driver from zwave_js_server.version import VersionInfo @@ -34,7 +35,8 @@ from homeassistant.core import HomeAssistant, callback from homeassistant.data_entry_flow import AbortFlow from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers import selector +from homeassistant.helpers import device_registry as dr, selector +from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.hassio import is_hassio from homeassistant.helpers.service_info.esphome import ESPHomeServiceInfo from homeassistant.helpers.service_info.hassio import HassioServiceInfo @@ -42,6 +44,7 @@ from homeassistant.helpers.service_info.zeroconf import ZeroconfServiceInfo from homeassistant.util import dt as dt_util +from . import helpers from .addon import get_addon_manager from .const import ( ADDON_SLUG, @@ -55,7 +58,6 @@ CONF_ADDON_S2_UNAUTHENTICATED_KEY, CONF_ADDON_SOCKET, CONF_INTEGRATION_CREATED_ADDON, - CONF_KEEP_OLD_DEVICES, CONF_LR_S2_ACCESS_CONTROL_KEY, CONF_LR_S2_AUTHENTICATED_KEY, CONF_S0_LEGACY_KEY, @@ -70,8 +72,9 @@ from .helpers import ( CannotConnect, async_get_version_info, - async_wait_for_driver_ready_event, format_home_id_for_display, + get_device_id, + get_device_id_ext, ) from .models import ZwaveJSConfigEntry @@ -82,6 +85,7 @@ ADDON_SETUP_TIMEOUT = 5 ADDON_SETUP_TIMEOUT_ROUNDS = 40 +SERVER_CONNECT_TIMEOUT = 60 ADDON_USER_INPUT_MAP = { CONF_ADDON_DEVICE: CONF_USB_PATH, @@ -1563,15 +1567,9 @@ async def async_step_finish_addon_setup_migrate( """Prepare info needed to complete the config entry update.""" ws_address = self.ws_address assert ws_address is not None - version_info = self.version_info - assert version_info is not None config_entry = self._reconfigure_config_entry assert config_entry is not None - # We need to wait for the config entry to be reloaded, - # before restoring the backup. - # We will do this in the restore nvm progress task, - # to get a nicer user experience. self.hass.config_entries.async_update_entry( config_entry, data={ @@ -1588,7 +1586,6 @@ async def async_step_finish_addon_setup_migrate( CONF_USE_ADDON: True, CONF_INTEGRATION_CREATED_ADDON: self.integration_created_addon, }, - unique_id=str(version_info.home_id), ) return await self.async_step_restore_nvm() @@ -1775,23 +1772,10 @@ def forward_progress(event: dict) -> None: async def _async_restore_network_backup(self) -> None: """Restore the backup.""" assert self.backup_data is not None + assert self.ws_address is not None config_entry = self._reconfigure_config_entry assert config_entry is not None - # Make sure we keep the old devices - # so that user customizations are not lost, - # when loading the config entry. - self.hass.config_entries.async_update_entry( - config_entry, data=config_entry.data | {CONF_KEEP_OLD_DEVICES: True} - ) - - # Reload the config entry to reconnect the client after the addon restart - await self.hass.config_entries.async_reload(config_entry.entry_id) - - data = config_entry.data.copy() - data.pop(CONF_KEEP_OLD_DEVICES, None) - self.hass.config_entries.async_update_entry(config_entry, data=data) - @callback def forward_progress(event: dict) -> None: """Forward progress events to frontend.""" @@ -1804,53 +1788,73 @@ def forward_progress(event: dict) -> None: event["bytesWritten"] / event["total"] * 0.5 + 0.5 ) - driver = self._get_driver() - controller = driver.controller - unsubs = [ - controller.on("nvm convert progress", forward_progress), - controller.on("nvm restore progress", forward_progress), - ] + client = Client(self.ws_address, async_get_clientsession(self.hass)) + driver_ready = asyncio.Event() + listen_task: asyncio.Task[None] | None = None + unsubs: list[Callable[[], None]] = [] + try: + try: + async with asyncio.timeout(SERVER_CONNECT_TIMEOUT): + await client.connect() + listen_task = self.hass.async_create_task( + client.listen(driver_ready), + f"{DOMAIN}_migration_listen", + ) + await driver_ready.wait() + except (TimeoutError, BaseZwaveJSServerError) as err: + raise AbortFlow(f"Failed to restore network: {err}") from err - wait_for_driver_ready = async_wait_for_driver_ready_event(config_entry, driver) + driver = client.driver + assert driver is not None + controller = driver.controller - try: - await controller.async_restore_nvm( - self.backup_data, {"preserveRoutes": False} - ) - except FailedCommand as err: - raise AbortFlow(f"Failed to restore network: {err}") from err - else: - with suppress(TimeoutError): - await wait_for_driver_ready() + controller_reset = asyncio.Event() + + @callback + def set_controller_reset(event: dict) -> None: + controller_reset.set() + + unsubs = [ + controller.on("nvm convert progress", forward_progress), + controller.on("nvm restore progress", forward_progress), + driver.once("driver ready", set_controller_reset), + ] try: - version_info = await async_get_version_info( - self.hass, config_entry.data[CONF_URL] - ) - except CannotConnect: - # Just log this error, as there's nothing to do about it here. - # The stale unique id needs to be handled by a repair flow, - # after the config entry has been reloaded. - _LOGGER.error( - "Failed to get server version, cannot update config entry " - "unique id with new home id, after controller reset" - ) - else: - self.hass.config_entries.async_update_entry( - config_entry, unique_id=str(version_info.home_id) + await controller.async_restore_nvm( + self.backup_data, {"preserveRoutes": False} ) + except FailedCommand as err: + raise AbortFlow(f"Failed to restore network: {err}") from err + with suppress(TimeoutError): + async with asyncio.timeout(helpers.DRIVER_READY_EVENT_TIMEOUT): + await controller_reset.wait() - # The config entry will be also be reloaded when the driver is ready, - # by the listener in the package module, - # and two reloads are needed to clean up the stale controller device entry. - # Since both the old and the new controller have the same node id, - # but different hardware identifiers, the integration - # will create a new device for the new controller, on the first reload, - # but not immediately remove the old device. - await self.hass.config_entries.async_reload(config_entry.entry_id) - + if own_node := controller.own_node: + device_registry = dr.async_get(self.hass) + if ( + (device_id_ext := get_device_id_ext(driver, own_node)) + and ( + old_device := device_registry.async_get_device_by_identifier( + get_device_id(driver, own_node), config_entry.entry_id + ) + ) + and device_id_ext not in old_device.identifiers + ): + # The old controller device is stale, and unlike the + # integration, the flow knows the controller was replaced. + device_registry.async_remove_device(old_device.id) finally: for unsub in unsubs: unsub() + # Disconnect before awaiting the listen task, + # since disconnect waits for the listen loop to finish. + await client.disconnect() + if listen_task is not None: + listen_task.cancel() + with suppress(asyncio.CancelledError, BaseZwaveJSServerError): + await listen_task + + await self.hass.config_entries.async_reload(config_entry.entry_id) def _get_driver(self) -> Driver: """Get the driver from the config entry.""" diff --git a/homeassistant/components/zwave_js/const.py b/homeassistant/components/zwave_js/const.py index ac0463a9411b3..d8b721aa8a95c 100644 --- a/homeassistant/components/zwave_js/const.py +++ b/homeassistant/components/zwave_js/const.py @@ -24,7 +24,6 @@ CONF_ADDON_LR_S2_AUTHENTICATED_KEY = "lr_s2_authenticated_key" CONF_ADDON_SOCKET = "socket" CONF_INTEGRATION_CREATED_ADDON = "integration_created_addon" -CONF_KEEP_OLD_DEVICES = "keep_old_devices" CONF_NETWORK_KEY = "network_key" CONF_S0_LEGACY_KEY = "s0_legacy_key" CONF_S2_ACCESS_CONTROL_KEY = "s2_access_control_key" diff --git a/homeassistant/helpers/device_registry.py b/homeassistant/helpers/device_registry.py index 73917c3a624bb..53f07eefd82a2 100644 --- a/homeassistant/helpers/device_registry.py +++ b/homeassistant/helpers/device_registry.py @@ -131,9 +131,6 @@ class DeviceInfo(TypedDict, total=False): configuration_url: str | URL | None connections: set[tuple[str, str]] created_at: str - default_manufacturer: str - default_model: str - default_name: str entry_type: DeviceEntryType | None identifiers: set[tuple[str, str]] manufacturer: str | None @@ -168,42 +165,6 @@ class ChildDeviceInfo(TypedDict, total=False): translation_placeholders: Mapping[str, str] | None -DEVICE_INFO_TYPES = { - # Device info is categorized by finding the first device info type which has all - # the keys of the device info. The link device info type must be kept first - # to make it preferred over primary. - "link": { - "connections", - "identifiers", - }, - "primary": { - "configuration_url", - "connections", - "entry_type", - "hw_version", - "identifiers", - "manufacturer", - "model", - "model_id", - "name", - "serial_number", - "suggested_area", - "sw_version", - "via_device", - "via_device_id", - }, - "secondary": { - "connections", - "default_manufacturer", - "default_model", - "default_name", - # Used by Fritz - "via_device", - "via_device_id", - }, -} - - class _EventDeviceRegistryUpdatedData_Create(TypedDict): """EventDeviceRegistryUpdated data for action type 'create'.""" @@ -281,40 +242,34 @@ def __init__( ) -def _determine_device_info_type( +def _validate_device_info( config_entry: ConfigEntry, device_info: DeviceInfo, -) -> str: - """Determine the type of a device info.""" - keys = set(device_info) - - # If no keys or not enough info to match up, abort +) -> None: + """Validate that a device info has enough information to match up a device.""" if not device_info.get("connections") and not device_info.get("identifiers"): raise DeviceInfoError( config_entry.domain, device_info, "device info must include at least one of identifiers or connections", ) + for field in ("manufacturer", "model", "name"): + if field in device_info and f"default_{field}" in device_info: + raise DeviceInfoError( + config_entry.domain, + device_info, + f"passing both `{field}` and `default_{field}` is not allowed", + ) - device_info_type: str | None = None - - # Find the first device info type which has all keys in the device info - for possible_type, allowed_keys in DEVICE_INFO_TYPES.items(): - if keys <= allowed_keys: - device_info_type = possible_type - break - - if device_info_type is None: - raise DeviceInfoError( - config_entry.domain, - device_info, - ( - "device info needs to either describe a device, " - "link to existing device or provide extra information." - ), - ) - return device_info_type +# Deprecated `async_get_or_create` parameters, mapped to the HA Core version they are +# removed in. +_DEPRECATED_DEVICE_INFO_PARAMETERS = { + "default_manufacturer": ("2027.9.0", "manufacturer"), + "default_model": ("2027.9.0", "model"), + "default_name": ("2027.9.0", "name"), + "via_device": ("2027.8.0", "via_device_id"), +} class _ValidatedDeviceInfoFields(TypedDict): @@ -2145,9 +2100,6 @@ def async_get_or_create( # noqa: C901 configuration_url: str | URL | UndefinedType | None = UNDEFINED, connections: set[tuple[str, str]] | UndefinedType | None = UNDEFINED, created_at: str | datetime | UndefinedType = UNDEFINED, # will be ignored - default_manufacturer: str | UndefinedType | None = UNDEFINED, - default_model: str | UndefinedType | None = UNDEFINED, - default_name: str | UndefinedType | None = UNDEFINED, # To disable a device if it gets created, does not affect existing devices disabled_by: DeviceEntryDisabler | UndefinedType | None = UNDEFINED, entry_type: DeviceEntryType | UndefinedType | None = UNDEFINED, @@ -2163,10 +2115,8 @@ def async_get_or_create( # noqa: C901 sw_version: str | UndefinedType | None = UNDEFINED, translation_key: str | None = None, translation_placeholders: Mapping[str, str] | None = None, - # via_device is deprecated and will be removed in HA Core 2027.8, use - # via_device_id instead - via_device: tuple[str, str] | UndefinedType | None = UNDEFINED, via_device_id: str | UndefinedType | None = UNDEFINED, + **kwargs: Any, ) -> DeviceEntry: """Get device. Create if it doesn't exist. @@ -2174,6 +2124,18 @@ def async_get_or_create( # noqa: C901 If identifiers overlap with a child device, the method raises. """ + # Extract deprecated parameters, and reject any other unexpected keyword + # argument. + default_manufacturer = kwargs.pop("default_manufacturer", UNDEFINED) + default_model = kwargs.pop("default_model", UNDEFINED) + default_name = kwargs.pop("default_name", UNDEFINED) + via_device = kwargs.pop("via_device", UNDEFINED) + if kwargs: + raise TypeError( + "async_get_or_create() got unexpected keyword arguments " + f"{', '.join(map(repr, kwargs))}" + ) + default_manufacturer = _validate_str( "default_manufacturer", default_manufacturer ) @@ -2207,15 +2169,23 @@ def async_get_or_create( # noqa: C901 "Passing both `via_device` and `via_device_id` is not allowed; " "`via_device` is deprecated, pass `via_device_id` only" ) - # Report the deprecated `via_device` here, before any registry mutation. - if via_device is not UNDEFINED: + # Report the deprecated parameters here, before any registry mutation. + deprecated_values = { + "default_manufacturer": default_manufacturer, + "default_model": default_model, + "default_name": default_name, + "via_device": via_device, + } + for parameter, deprecation in _DEPRECATED_DEVICE_INFO_PARAMETERS.items(): + if deprecated_values[parameter] is UNDEFINED: + continue + version, replacement = deprecation report_usage( - "calls `device_registry.async_get_or_create` with a `via_device`, " - "which is deprecated because device identifiers are no longer unique; " - "pass `via_device_id` instead", + "calls `device_registry.async_get_or_create` with a deprecated " + f"`{parameter}` parameter; use `{replacement}` instead", core_behavior=ReportBehavior.ERROR, core_integration_behavior=ReportBehavior.ERROR, - breaks_in_ha_version="2027.8.0", + breaks_in_ha_version=version, ) if ( config_subentry_id is not UNDEFINED @@ -2252,7 +2222,7 @@ def async_get_or_create( # noqa: C901 if val is not UNDEFINED } - device_info_type = _determine_device_info_type(config_entry, device_info) + _validate_device_info(config_entry, device_info) if identifiers is None or identifiers is UNDEFINED: identifiers = set() @@ -2372,7 +2342,7 @@ def async_get_or_create( # noqa: C901 self.devices[device.id] = device # If creating a new device, default to the config entry name - if device_info_type == "primary" and (not name or name is UNDEFINED): + if not name or name is UNDEFINED: name = config_entry.title elif ( diff --git a/homeassistant/helpers/entity.py b/homeassistant/helpers/entity.py index 292d37ebcbc43..f33f26679a4d4 100644 --- a/homeassistant/helpers/entity.py +++ b/homeassistant/helpers/entity.py @@ -1497,7 +1497,8 @@ async def __async_remove_impl(self, force_remove: bool) -> None: # and not self._removed_from_registry ): - # Set the entity's state will to unavailable + ATTR_RESTORED: True + # Set the entity's state will to unavailable and + # EntityStateAttribute.RESTORED: True self.registry_entry.write_unavailable_state(self.hass) else: self.hass.states.async_remove(self.entity_id, context=self._context) diff --git a/homeassistant/helpers/entity_platform.py b/homeassistant/helpers/entity_platform.py index 50700eecb0615..1920e11e9b806 100644 --- a/homeassistant/helpers/entity_platform.py +++ b/homeassistant/helpers/entity_platform.py @@ -9,9 +9,9 @@ from homeassistant import config_entries from homeassistant.const import ( - ATTR_RESTORED, DEVICE_DEFAULT_NAME, EVENT_HOMEASSISTANT_STARTED, + EntityStateAttribute, ) from homeassistant.core import ( CALLBACK_TYPE, @@ -827,7 +827,10 @@ def _entity_id_already_exists(self, entity_id: str) -> tuple[bool, bool]: if not already_exists and not self.hass.states.async_available(entity_id): existing = self.hass.states.get(entity_id) - if existing is not None and ATTR_RESTORED in existing.attributes: + if ( + existing is not None + and EntityStateAttribute.RESTORED in existing.attributes + ): restored = True else: already_exists = True diff --git a/homeassistant/helpers/restore_state.py b/homeassistant/helpers/restore_state.py index b1c2b9ffde35c..814b3328975aa 100644 --- a/homeassistant/helpers/restore_state.py +++ b/homeassistant/helpers/restore_state.py @@ -5,7 +5,7 @@ import logging from typing import Any, Self, cast, override -from homeassistant.const import ATTR_RESTORED, EVENT_HOMEASSISTANT_STOP +from homeassistant.const import EVENT_HOMEASSISTANT_STOP, EntityStateAttribute from homeassistant.core import HomeAssistant, State, callback, valid_entity_id from homeassistant.exceptions import HomeAssistantError, UnsupportedStorageVersionError from homeassistant.util import dt as dt_util @@ -176,7 +176,7 @@ def async_get_stored_states(self) -> list[StoredState]: current_states_by_entity_id = { state.entity_id: state for state in all_states - if not state.attributes.get(ATTR_RESTORED) + if not state.attributes.get(EntityStateAttribute.RESTORED) } # Start with the currently registered states diff --git a/requirements_all.txt b/requirements_all.txt index 5b5d06d20dea6..a0494898fd8e4 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1534,10 +1534,10 @@ lupupy==0.3.2 lw12==0.9.2 # homeassistant.components.scrape -lxml==6.1.1 +lxml==6.1.2 # homeassistant.components.lyngdorf -lyngdorf==1.8.0 +lyngdorf==1.9.0 # homeassistant.components.matrix matrix-nio==0.26.0 @@ -1649,7 +1649,7 @@ mutagen==1.48.1 mutesync==0.0.1 # homeassistant.components.mvglive -mvg==1.4.0 +mvg==1.6.0 # homeassistant.components.myuplink myuplink==0.7.0 diff --git a/tests/components/alarm_control_panel/test_device_action.py b/tests/components/alarm_control_panel/test_device_action.py index 0774353f5f36e..d6cc460777435 100644 --- a/tests/components/alarm_control_panel/test_device_action.py +++ b/tests/components/alarm_control_panel/test_device_action.py @@ -101,7 +101,9 @@ async def test_get_actions( ) if set_state: hass.states.async_set( - f"{DOMAIN}.test_5678", "attributes", {"supported_features": features_state} + entity_entry.entity_id, + "attributes", + {"supported_features": features_state}, ) expected_actions = [ { @@ -184,7 +186,7 @@ async def test_get_actions_arm_night_only( DOMAIN, "test", "5678", device_id=device_entry.id ) hass.states.async_set( - "alarm_control_panel.test_5678", "attributes", {"supported_features": 4} + entity_entry.entity_id, "attributes", {"supported_features": 4} ) expected_actions = [ { diff --git a/tests/components/alarm_control_panel/test_device_condition.py b/tests/components/alarm_control_panel/test_device_condition.py index 9d098a9b30b8f..00f29bf014d52 100644 --- a/tests/components/alarm_control_panel/test_device_condition.py +++ b/tests/components/alarm_control_panel/test_device_condition.py @@ -80,7 +80,7 @@ async def test_get_conditions( ) if set_state: hass.states.async_set( - "alarm_control_panel.test_5678", + entity_entry.entity_id, "attributes", {"supported_features": features_state}, ) diff --git a/tests/components/alarm_control_panel/test_device_trigger.py b/tests/components/alarm_control_panel/test_device_trigger.py index f7c9e2a8a5f76..89ac6db9022e9 100644 --- a/tests/components/alarm_control_panel/test_device_trigger.py +++ b/tests/components/alarm_control_panel/test_device_trigger.py @@ -169,11 +169,11 @@ async def test_get_trigger_capabilities( config_entry_id=config_entry.entry_id, connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, ) - entity_registry.async_get_or_create( + entity_entry = entity_registry.async_get_or_create( DOMAIN, "test", "5678", device_id=device_entry.id ) hass.states.async_set( - "alarm_control_panel.test_5678", "attributes", {"supported_features": 15} + entity_entry.entity_id, "attributes", {"supported_features": 15} ) triggers = await async_get_device_automations( @@ -208,11 +208,11 @@ async def test_get_trigger_capabilities_legacy( config_entry_id=config_entry.entry_id, connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, ) - entity_registry.async_get_or_create( + entity_entry = entity_registry.async_get_or_create( DOMAIN, "test", "5678", device_id=device_entry.id ) hass.states.async_set( - "alarm_control_panel.test_5678", "attributes", {"supported_features": 15} + entity_entry.entity_id, "attributes", {"supported_features": 15} ) triggers = await async_get_device_automations( diff --git a/tests/components/assist_pipeline/test_pipeline.py b/tests/components/assist_pipeline/test_pipeline.py index d6d03c5bfa9b8..4d231d1c292f5 100644 --- a/tests/components/assist_pipeline/test_pipeline.py +++ b/tests/components/assist_pipeline/test_pipeline.py @@ -1991,7 +1991,7 @@ def _reset() -> None: device_registry.async_update_device(light_device.id, area_id=area_2.id) _reset() - await _run("turn on light 2") + await _run("turn on Mock Title light 2") # Acknowledgment sound should be not played (different device area) text_to_speech.assert_called_once() diff --git a/tests/components/assist_pipeline/test_select.py b/tests/components/assist_pipeline/test_select.py index a15ec167d67d3..6d7df5a3d39ba 100644 --- a/tests/components/assist_pipeline/test_select.py +++ b/tests/components/assist_pipeline/test_select.py @@ -16,7 +16,7 @@ from homeassistant.config_entries import ConfigEntry, ConfigEntryState from homeassistant.const import Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers import device_registry as dr +from homeassistant.helpers import device_registry as dr, entity_registry as er from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback @@ -126,6 +126,7 @@ async def test_select_entity_registering_device( async def test_select_entity_changing_pipelines( hass: HomeAssistant, + entity_registry: er.EntityRegistry, init_select: MockConfigEntry, pipeline_1: Pipeline, pipeline_2: Pipeline, @@ -135,7 +136,12 @@ async def test_select_entity_changing_pipelines( config_entry = init_select # nicer naming config_entry.mock_state(hass, ConfigEntryState.LOADED) - state = hass.states.get("select.assist_pipeline_test_prefix_pipeline") + pipeline_entity_id = entity_registry.async_get_entity_id( + Platform.SELECT, DOMAIN, "test-prefix-pipeline" + ) + assert pipeline_entity_id is not None + + state = hass.states.get(pipeline_entity_id) assert state is not None assert state.state == "preferred" assert state.attributes["options"] == [ @@ -150,13 +156,13 @@ async def test_select_entity_changing_pipelines( "select", "select_option", { - "entity_id": "select.assist_pipeline_test_prefix_pipeline", + "entity_id": pipeline_entity_id, "option": pipeline_2.name, }, blocking=True, ) - state = hass.states.get("select.assist_pipeline_test_prefix_pipeline") + state = hass.states.get(pipeline_entity_id) assert state is not None assert state.state == pipeline_2.name @@ -168,14 +174,14 @@ async def test_select_entity_changing_pipelines( config_entry, [Platform.SELECT] ) - state = hass.states.get("select.assist_pipeline_test_prefix_pipeline") + state = hass.states.get(pipeline_entity_id) assert state is not None assert state.state == pipeline_2.name # Remove selected pipeline await pipeline_storage.async_delete_item(pipeline_2.id) - state = hass.states.get("select.assist_pipeline_test_prefix_pipeline") + state = hass.states.get(pipeline_entity_id) assert state is not None assert state.state == "preferred" assert state.attributes["options"] == [ @@ -187,13 +193,19 @@ async def test_select_entity_changing_pipelines( async def test_select_entity_changing_vad_sensitivity( hass: HomeAssistant, + entity_registry: er.EntityRegistry, init_select: MockConfigEntry, ) -> None: """Test entity tracking vad sensitivity changes.""" config_entry = init_select # nicer naming config_entry.mock_state(hass, ConfigEntryState.LOADED) - state = hass.states.get("select.assist_pipeline_test_vad_sensitivity") + vad_entity_id = entity_registry.async_get_entity_id( + Platform.SELECT, DOMAIN, "test-vad_sensitivity" + ) + assert vad_entity_id is not None + + state = hass.states.get(vad_entity_id) assert state is not None assert state.state == VadSensitivity.DEFAULT.value @@ -202,13 +214,13 @@ async def test_select_entity_changing_vad_sensitivity( "select", "select_option", { - "entity_id": "select.assist_pipeline_test_vad_sensitivity", + "entity_id": vad_entity_id, "option": VadSensitivity.AGGRESSIVE.value, }, blocking=True, ) - state = hass.states.get("select.assist_pipeline_test_vad_sensitivity") + state = hass.states.get(vad_entity_id) assert state is not None assert state.state == VadSensitivity.AGGRESSIVE.value @@ -220,6 +232,6 @@ async def test_select_entity_changing_vad_sensitivity( config_entry, [Platform.SELECT] ) - state = hass.states.get("select.assist_pipeline_test_vad_sensitivity") + state = hass.states.get(vad_entity_id) assert state is not None assert state.state == VadSensitivity.AGGRESSIVE.value diff --git a/tests/components/assist_satellite/test_entity.py b/tests/components/assist_satellite/test_entity.py index 59a7a9fb50984..b8049b8ac96b2 100644 --- a/tests/components/assist_satellite/test_entity.py +++ b/tests/components/assist_satellite/test_entity.py @@ -916,6 +916,7 @@ async def test_ask_question( """Test asking a question on a device and matching an answer.""" entity_id = "assist_satellite.test_entity" question_text = "What kind of music would you like to listen to?" + context = Context() await async_update_pipeline( hass, async_get_pipeline(hass), stt_engine="test-stt-engine", stt_language="en" @@ -982,9 +983,11 @@ async def async_start_conversation(start_announcement): {"entity_id": entity_id, "question": question_text, **service_data}, blocking=True, return_response=True, + context=context, ) assert entity.state == AssistSatelliteState.IDLE assert response == asdict(expected_answer) + assert hass.states.get(entity_id).context is context async def test_ask_question_requires_entity_permission( diff --git a/tests/components/buienradar/test_util.py b/tests/components/buienradar/test_util.py new file mode 100644 index 0000000000000..9997173310f43 --- /dev/null +++ b/tests/components/buienradar/test_util.py @@ -0,0 +1,95 @@ +"""Tests for the Buienradar utilities.""" + +import datetime +from http import HTTPStatus +from unittest.mock import patch + +from buienradar.constants import MESSAGE, SUCCESS +from freezegun.api import FrozenDateTimeFactory +import pytest + +from homeassistant.components.buienradar.const import DOMAIN +from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE +from homeassistant.core import HomeAssistant +from homeassistant.util import dt as dt_util + +from tests.common import MockConfigEntry, async_fire_time_changed +from tests.test_util.aiohttp import AiohttpClientMocker + +TEST_LATITUDE = 51.5 +TEST_LONGITUDE = 5.5 +TEST_CFG_DATA = {CONF_LATITUDE: TEST_LATITUDE, CONF_LONGITUDE: TEST_LONGITUDE} + +WARNING = "Unable to parse data from Buienradar" + + +@pytest.mark.parametrize( + ("update_at", "expect_warning"), + [ + ("2026-01-14T23:00:00+00:00", False), + ("2026-01-14T23:59:59+00:00", False), + ("2026-01-15T00:00:00+00:00", True), + ("2026-07-14T22:30:00+00:00", False), + ("2026-01-15T06:30:00+00:00", True), + ], + ids=[ + "cet_0000_start_of_quiet_hour", + "cet_0059_end_of_quiet_hour", + "cet_0100_just_after", + "cest_0030_quiet_hour_in_dst", + "cet_0730_quiet_only_where_user_lives", + ], +) +async def test_unparsable_data_is_quiet_during_the_midnight_hour( + hass: HomeAssistant, + aioclient_mock: AiohttpClientMocker, + freezer: FrozenDateTimeFactory, + caplog: pytest.LogCaptureFixture, + update_at: str, + expect_warning: bool, +) -> None: + """Test the parse failure warning is suppressed in the midnight hour. + + buienradar.nl serves no data while it updates its forecast between 00:00 and + 01:00 CE(S)T, so the warning is only interesting outside that hour. The hour + that decides this belongs to the service, so the configured time zone here is + deliberately somewhere else: America/Regina is UTC-6 with no DST, which puts + every case below in a different hour locally than in Amsterdam. + + The times are UTC. The first three pin the edges of the quiet hour in CET, + the fourth repeats it in CEST so the offset is not assumed, and the last one + is the quiet hour in America/Regina rather than in Amsterdam, so it must + still warn. + """ + await hass.config.async_set_time_zone("America/Regina") + aioclient_mock.get( + "https://data.buienradar.nl/2.0/feed/json", status=HTTPStatus.OK, text="{}" + ) + aioclient_mock.get( + f"https://gps.buienradar.nl/getrr.php?lat={TEST_LATITUDE}&lon={TEST_LONGITUDE}", + status=HTTPStatus.OK, + text="", + ) + + update = dt_util.parse_datetime(update_at) + assert update is not None + # A failed update reschedules itself two minutes later, which is the update + # the assertion below is about. + freezer.move_to(update - datetime.timedelta(minutes=2)) + + entry = MockConfigEntry(domain=DOMAIN, unique_id="TEST_ID", data=TEST_CFG_DATA) + entry.add_to_hass(hass) + + with patch( + "homeassistant.components.buienradar.util.parse_data", + return_value={SUCCESS: False, MESSAGE: "no data"}, + ): + await hass.config_entries.async_setup(entry.entry_id) + await hass.async_block_till_done() + + caplog.clear() + freezer.move_to(update) + async_fire_time_changed(hass, dt_util.utcnow()) + await hass.async_block_till_done() + + assert (WARNING in caplog.text) is expect_warning diff --git a/tests/components/climate/test_device_action.py b/tests/components/climate/test_device_action.py index 131fcb2681257..1be391d76cb7a 100644 --- a/tests/components/climate/test_device_action.py +++ b/tests/components/climate/test_device_action.py @@ -68,7 +68,9 @@ async def test_get_actions( ) if set_state: hass.states.async_set( - f"{DOMAIN}.test_5678", "attributes", {"supported_features": features_state} + entity_entry.entity_id, + "attributes", + {"supported_features": features_state}, ) expected_actions = [] @@ -380,7 +382,7 @@ async def test_capabilities( ) if set_state: hass.states.async_set( - f"{DOMAIN}.test_5678", + entity_entry.entity_id, HVACMode.COOL, capabilities_state, ) @@ -498,7 +500,7 @@ async def test_capabilities_legacy( ) if set_state: hass.states.async_set( - f"{DOMAIN}.test_5678", + entity_entry.entity_id, HVACMode.COOL, capabilities_state, ) diff --git a/tests/components/climate/test_device_condition.py b/tests/components/climate/test_device_condition.py index 19c8addb5a8dc..47cf81a099ac3 100644 --- a/tests/components/climate/test_device_condition.py +++ b/tests/components/climate/test_device_condition.py @@ -64,7 +64,9 @@ async def test_get_conditions( ) if set_state: hass.states.async_set( - f"{DOMAIN}.test_5678", "attributes", {"supported_features": features_state} + entity_entry.entity_id, + "attributes", + {"supported_features": features_state}, ) expected_conditions = [] expected_conditions += [ diff --git a/tests/components/cover/test_device_condition.py b/tests/components/cover/test_device_condition.py index ebb893835e896..96d101bae9de7 100644 --- a/tests/components/cover/test_device_condition.py +++ b/tests/components/cover/test_device_condition.py @@ -82,7 +82,7 @@ async def test_get_conditions( ) if set_state: hass.states.async_set( - f"{DOMAIN}.test_5678", "attributes", {"supported_features": features_state} + entity_entry.entity_id, "attributes", {"supported_features": features_state} ) await hass.async_block_till_done() diff --git a/tests/components/derivative/test_diagnostics.py b/tests/components/derivative/test_diagnostics.py index 98ceaba1c55d5..258affe487111 100644 --- a/tests/components/derivative/test_diagnostics.py +++ b/tests/components/derivative/test_diagnostics.py @@ -21,4 +21,4 @@ async def test_diagnostics( assert isinstance(result, dict) assert result["config_entry"]["domain"] == "derivative" assert result["config_entry"]["options"]["name"] == "My derivative" - assert result["entity"][0]["entity_id"] == "sensor.my_derivative" + assert result["entity"][0]["entity_id"] == "sensor.mock_title_my_derivative" diff --git a/tests/components/derivative/test_init.py b/tests/components/derivative/test_init.py index b852340f48c49..3161e612382b2 100644 --- a/tests/components/derivative/test_init.py +++ b/tests/components/derivative/test_init.py @@ -97,7 +97,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed( assert await hass.config_entries.async_setup(derivative_config_entry.entry_id) await hass.async_block_till_done() - derivative_entity_entry = entity_registry.async_get("sensor.my_derivative") + derivative_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_derivative" + ) assert derivative_entity_entry.device_id == sensor_entity_entry.device_id sensor_device = device_registry.async_get(sensor_device.id) @@ -116,7 +118,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed( mock_unload_entry.assert_not_called() # Check that the entity is no longer linked to the source device - derivative_entity_entry = entity_registry.async_get("sensor.my_derivative") + derivative_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_derivative" + ) assert derivative_entity_entry.device_id is None # Check that the device is removed @@ -141,7 +145,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed_shared_d assert await hass.config_entries.async_setup(derivative_config_entry.entry_id) await hass.async_block_till_done() - derivative_entity_entry = entity_registry.async_get("sensor.my_derivative") + derivative_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_derivative" + ) assert derivative_entity_entry.device_id == sensor_entity_entry.device_id sensor_device = device_registry.async_get(sensor_device.id) @@ -160,7 +166,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed_shared_d mock_unload_entry.assert_not_called() # Check that the entity is no longer linked to the source device - derivative_entity_entry = entity_registry.async_get("sensor.my_derivative") + derivative_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_derivative" + ) assert derivative_entity_entry.device_id is None # Check that the source device is not removed @@ -187,7 +195,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed_from_dev assert await hass.config_entries.async_setup(derivative_config_entry.entry_id) await hass.async_block_till_done() - derivative_entity_entry = entity_registry.async_get("sensor.my_derivative") + derivative_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_derivative" + ) assert derivative_entity_entry.device_id == sensor_entity_entry.device_id sensor_device = device_registry.async_get(sensor_device.id) @@ -207,7 +217,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed_from_dev mock_unload_entry.assert_called_once() # Check that the entity is no longer linked to the source device - derivative_entity_entry = entity_registry.async_get("sensor.my_derivative") + derivative_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_derivative" + ) assert derivative_entity_entry.device_id is None # Check that the derivative config entry is not in the device @@ -239,7 +251,9 @@ async def test_async_handle_source_entity_changes_source_entity_moved_other_devi assert await hass.config_entries.async_setup(derivative_config_entry.entry_id) await hass.async_block_till_done() - derivative_entity_entry = entity_registry.async_get("sensor.my_derivative") + derivative_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_derivative" + ) assert derivative_entity_entry.device_id == sensor_entity_entry.device_id sensor_device = device_registry.async_get(sensor_device.id) @@ -261,7 +275,9 @@ async def test_async_handle_source_entity_changes_source_entity_moved_other_devi mock_unload_entry.assert_called_once() # Check that the entity is linked to the other device - derivative_entity_entry = entity_registry.async_get("sensor.my_derivative") + derivative_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_derivative" + ) assert derivative_entity_entry.device_id == sensor_device_2.id # Check that the derivative config entry is not in any of the devices @@ -289,7 +305,9 @@ async def test_async_handle_source_entity_new_entity_id( assert await hass.config_entries.async_setup(derivative_config_entry.entry_id) await hass.async_block_till_done() - derivative_entity_entry = entity_registry.async_get("sensor.my_derivative") + derivative_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_derivative" + ) assert derivative_entity_entry.device_id == sensor_entity_entry.device_id sensor_device = device_registry.async_get(sensor_device.id) @@ -375,7 +393,7 @@ async def test_migration_1_2( options={ "name": "My derivative", "round": 1.0, - "source": "sensor.test_unique", + "source": sensor_entity_entry.entity_id, "time_window": {"seconds": 0.0}, "unit_prefix": "k", "unit_time": "min", @@ -395,7 +413,9 @@ async def test_migration_1_2( # derivative entity is linked to the source device sensor_device = device_registry.async_get(sensor_device.id) assert derivative_config_entry.entry_id not in sensor_device.config_entries - derivative_entity_entry = entity_registry.async_get("sensor.my_derivative") + derivative_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_derivative" + ) assert derivative_entity_entry.device_id == sensor_entity_entry.device_id assert derivative_config_entry.version == 1 diff --git a/tests/components/derivative/test_sensor.py b/tests/components/derivative/test_sensor.py index dc816bc881f02..f147139553631 100644 --- a/tests/components/derivative/test_sensor.py +++ b/tests/components/derivative/test_sensor.py @@ -915,7 +915,7 @@ async def test_device_id( device_id=source_device_entry.id, ) await hass.async_block_till_done() - assert entity_registry.async_get("sensor.test_source") is not None + assert entity_registry.async_get(source_entity.entity_id) is not None derivative_config_entry = MockConfigEntry( data={}, @@ -923,7 +923,7 @@ async def test_device_id( options={ "name": "Derivative", "round": 1.0, - "source": "sensor.test_source", + "source": source_entity.entity_id, "time_window": {"seconds": 0.0}, "unit_prefix": "k", "unit_time": "min", @@ -936,7 +936,7 @@ async def test_device_id( assert await hass.config_entries.async_setup(derivative_config_entry.entry_id) await hass.async_block_till_done() - derivative_entity = entity_registry.async_get("sensor.derivative") + derivative_entity = entity_registry.async_get("sensor.mock_title_derivative") assert derivative_entity is not None assert derivative_entity.device_id == source_entity.device_id diff --git a/tests/components/device_sun_light_trigger/test_init.py b/tests/components/device_sun_light_trigger/test_init.py index 2499648291603..62492a1b19e09 100644 --- a/tests/components/device_sun_light_trigger/test_init.py +++ b/tests/components/device_sun_light_trigger/test_init.py @@ -216,6 +216,7 @@ async def test_lights_turn_on_when_coming_home_after_sun_set_person( mode=None, object_id=None, order=None, + context=None, ) assert await async_setup_component( diff --git a/tests/components/dlna_dmr/test_media_player.py b/tests/components/dlna_dmr/test_media_player.py index bef58fb753efe..ac5334e8e5b64 100644 --- a/tests/components/dlna_dmr/test_media_player.py +++ b/tests/components/dlna_dmr/test_media_player.py @@ -1359,12 +1359,13 @@ async def test_unavailable_device( blocking=True, ) - # Check hass device information has not been filled in yet + # The device is named after the config entry until it can be connected to; + # detailed information such as manufacturer is filled in once connected. device = device_registry.async_get_device_by_connection( (dr.CONNECTION_UPNP, MOCK_DEVICE_UDN), config_entry_mock.entry_id ) assert device is not None - assert device.name is None + assert device.name == MOCK_DEVICE_NAME assert device.manufacturer is None # Unload config entry to clean up diff --git a/tests/components/generic_hygrostat/test_humidifier.py b/tests/components/generic_hygrostat/test_humidifier.py index c088a3fbefb0f..d268b14a155ec 100644 --- a/tests/components/generic_hygrostat/test_humidifier.py +++ b/tests/components/generic_hygrostat/test_humidifier.py @@ -1856,7 +1856,7 @@ async def test_device_id( device_id=source_device_entry.id, ) await hass.async_block_till_done() - assert entity_registry.async_get("switch.test_source") is not None + assert entity_registry.async_get(source_entity.entity_id) is not None helper_config_entry = MockConfigEntry( data={}, @@ -1864,7 +1864,7 @@ async def test_device_id( options={ "device_class": "humidifier", "dry_tolerance": 2.0, - "humidifier": "switch.test_source", + "humidifier": source_entity.entity_id, "name": "Test", "target_sensor": ENT_SENSOR, "wet_tolerance": 4.0, @@ -1876,7 +1876,7 @@ async def test_device_id( assert await hass.config_entries.async_setup(helper_config_entry.entry_id) await hass.async_block_till_done() - helper_entity = entity_registry.async_get("humidifier.test") + helper_entity = entity_registry.async_get("humidifier.mock_title_test") assert helper_entity is not None assert helper_entity.device_id == source_entity.device_id @@ -1895,7 +1895,7 @@ async def test_device_id_yaml( identifiers={("switch", "identifier_test")}, connections={("mac", "30:31:32:33:34:35")}, ) - entity_registry.async_get_or_create( + source_entity = entity_registry.async_get_or_create( "switch", "test", "source", @@ -1911,7 +1911,7 @@ async def test_device_id_yaml( "humidifier": { "platform": "generic_hygrostat", "name": "test", - "humidifier": "switch.test_source", + "humidifier": source_entity.entity_id, "target_sensor": ENT_SENSOR, "unique_id": "generic_hygrostat_yaml", } diff --git a/tests/components/generic_hygrostat/test_init.py b/tests/components/generic_hygrostat/test_init.py index 1562f3be6c1a5..2631be29d5eb1 100644 --- a/tests/components/generic_hygrostat/test_init.py +++ b/tests/components/generic_hygrostat/test_init.py @@ -148,8 +148,8 @@ def add_event(event: Event[er.EventEntityRegistryUpdatedData]) -> None: @pytest.mark.parametrize( ("source_entity_id", "expected_helper_device_id", "expected_events"), [ - ("switch.test_unique", None, ["update"]), - ("sensor.test_unique", "switch_device_id", []), + ("switch.mock_title", None, ["update"]), + ("sensor.mock_title", "switch_device_id", []), ], indirect=["expected_helper_device_id"], ) @@ -172,7 +172,7 @@ async def test_async_handle_source_entity_changes_source_entity_removed( await hass.async_block_till_done() generic_hygrostat_entity_entry = entity_registry.async_get( - "humidifier.my_generic_hygrostat" + "humidifier.mock_title_my_generic_hygrostat" ) assert generic_hygrostat_entity_entry.device_id == switch_entity_entry.device_id @@ -195,7 +195,7 @@ async def test_async_handle_source_entity_changes_source_entity_removed( # Check that the helper entity is linked to the expected source device generic_hygrostat_entity_entry = entity_registry.async_get( - "humidifier.my_generic_hygrostat" + "humidifier.mock_title_my_generic_hygrostat" ) assert generic_hygrostat_entity_entry.device_id == expected_helper_device_id @@ -221,8 +221,8 @@ async def test_async_handle_source_entity_changes_source_entity_removed( @pytest.mark.parametrize( ("source_entity_id", "expected_helper_device_id", "expected_events"), [ - ("switch.test_unique", None, ["update"]), - ("sensor.test_unique", "switch_device_id", []), + ("switch.mock_title", None, ["update"]), + ("sensor.mock_title", "switch_device_id", []), ], indirect=["expected_helper_device_id"], ) @@ -245,7 +245,7 @@ async def test_async_handle_source_entity_changes_source_entity_removed_shared_d await hass.async_block_till_done() generic_hygrostat_entity_entry = entity_registry.async_get( - "humidifier.my_generic_hygrostat" + "humidifier.mock_title_my_generic_hygrostat" ) assert generic_hygrostat_entity_entry.device_id == switch_entity_entry.device_id @@ -268,7 +268,7 @@ async def test_async_handle_source_entity_changes_source_entity_removed_shared_d # Check that the helper entity is linked to the expected source device generic_hygrostat_entity_entry = entity_registry.async_get( - "humidifier.my_generic_hygrostat" + "humidifier.mock_title_my_generic_hygrostat" ) assert generic_hygrostat_entity_entry.device_id == expected_helper_device_id @@ -302,8 +302,8 @@ async def test_async_handle_source_entity_changes_source_entity_removed_shared_d "expected_events", ), [ - ("switch.test_unique", 1, None, ["update"]), - ("sensor.test_unique", 0, "switch_device_id", []), + ("switch.mock_title", 1, None, ["update"]), + ("sensor.mock_title", 0, "switch_device_id", []), ], indirect=["expected_helper_device_id"], ) @@ -327,7 +327,7 @@ async def test_async_handle_source_entity_changes_source_entity_removed_from_dev await hass.async_block_till_done() generic_hygrostat_entity_entry = entity_registry.async_get( - "humidifier.my_generic_hygrostat" + "humidifier.mock_title_my_generic_hygrostat" ) assert generic_hygrostat_entity_entry.device_id == switch_entity_entry.device_id @@ -351,7 +351,7 @@ async def test_async_handle_source_entity_changes_source_entity_removed_from_dev # Check that the helper entity is linked to the expected source device generic_hygrostat_entity_entry = entity_registry.async_get( - "humidifier.my_generic_hygrostat" + "humidifier.mock_title_my_generic_hygrostat" ) assert generic_hygrostat_entity_entry.device_id == expected_helper_device_id @@ -377,7 +377,7 @@ async def test_async_handle_source_entity_changes_source_entity_removed_from_dev ) @pytest.mark.parametrize( ("source_entity_id", "unload_entry_calls", "expected_events"), - [("switch.test_unique", 1, ["update"]), ("sensor.test_unique", 0, [])], + [("switch.mock_title", 1, ["update"]), ("sensor.mock_title", 0, [])], ) async def test_async_handle_source_entity_changes_source_entity_moved_other_device( hass: HomeAssistant, @@ -403,7 +403,7 @@ async def test_async_handle_source_entity_changes_source_entity_moved_other_devi await hass.async_block_till_done() generic_hygrostat_entity_entry = entity_registry.async_get( - "humidifier.my_generic_hygrostat" + "humidifier.mock_title_my_generic_hygrostat" ) assert generic_hygrostat_entity_entry.device_id == switch_entity_entry.device_id @@ -430,7 +430,7 @@ async def test_async_handle_source_entity_changes_source_entity_moved_other_devi # Check that the helper entity is linked to the expected source device switch_entity_entry = entity_registry.async_get(switch_entity_entry.entity_id) generic_hygrostat_entity_entry = entity_registry.async_get( - "humidifier.my_generic_hygrostat" + "humidifier.mock_title_my_generic_hygrostat" ) assert generic_hygrostat_entity_entry.device_id == switch_entity_entry.device_id @@ -459,8 +459,8 @@ async def test_async_handle_source_entity_changes_source_entity_moved_other_devi @pytest.mark.parametrize( ("source_entity_id", "new_entity_id", "config_key"), [ - ("switch.test_unique", "switch.new_entity_id", "humidifier"), - ("sensor.test_unique", "sensor.new_entity_id", "target_sensor"), + ("switch.mock_title", "switch.new_entity_id", "humidifier"), + ("sensor.mock_title", "sensor.new_entity_id", "target_sensor"), ], ) async def test_async_handle_source_entity_new_entity_id( @@ -482,7 +482,7 @@ async def test_async_handle_source_entity_new_entity_id( await hass.async_block_till_done() generic_hygrostat_entity_entry = entity_registry.async_get( - "humidifier.my_generic_hygrostat" + "humidifier.mock_title_my_generic_hygrostat" ) assert generic_hygrostat_entity_entry.device_id == switch_entity_entry.device_id @@ -558,7 +558,7 @@ async def test_migration_1_1( switch_device = device_registry.async_get(switch_device.id) assert generic_hygrostat_config_entry.entry_id not in switch_device.config_entries generic_hygrostat_entity_entry = entity_registry.async_get( - "humidifier.my_generic_hygrostat" + "humidifier.mock_title_my_generic_hygrostat" ) assert generic_hygrostat_entity_entry.device_id == switch_entity_entry.device_id diff --git a/tests/components/generic_thermostat/test_climate.py b/tests/components/generic_thermostat/test_climate.py index 8b5072931bca4..8f5c9fa580e03 100644 --- a/tests/components/generic_thermostat/test_climate.py +++ b/tests/components/generic_thermostat/test_climate.py @@ -1848,14 +1848,14 @@ async def test_device_id( device_id=source_device_entry.id, ) await hass.async_block_till_done() - assert entity_registry.async_get("switch.test_source") is not None + assert entity_registry.async_get(source_entity.entity_id) is not None helper_config_entry = MockConfigEntry( data={}, domain=DOMAIN, options={ "name": "Test", - "heater": "switch.test_source", + "heater": source_entity.entity_id, "target_sensor": ENT_SENSOR, "ac_mode": False, "cold_tolerance": 0.3, @@ -1868,7 +1868,7 @@ async def test_device_id( assert await hass.config_entries.async_setup(helper_config_entry.entry_id) await hass.async_block_till_done() - helper_entity = entity_registry.async_get("climate.test") + helper_entity = entity_registry.async_get("climate.mock_title_test") assert helper_entity is not None assert helper_entity.device_id == source_entity.device_id diff --git a/tests/components/generic_thermostat/test_init.py b/tests/components/generic_thermostat/test_init.py index 240a82199094d..c0d5f359caa86 100644 --- a/tests/components/generic_thermostat/test_init.py +++ b/tests/components/generic_thermostat/test_init.py @@ -152,8 +152,8 @@ def add_event(event: Event[er.EventEntityRegistryUpdatedData]) -> None: @pytest.mark.parametrize( ("source_entity_id", "expected_helper_device_id", "expected_events"), [ - ("switch.test_unique", None, ["update"]), - ("sensor.test_unique", "switch_device_id", []), + ("switch.mock_title", None, ["update"]), + ("sensor.mock_title", "switch_device_id", []), ], indirect=["expected_helper_device_id"], ) @@ -176,7 +176,7 @@ async def test_async_handle_source_entity_changes_source_entity_removed( await hass.async_block_till_done() generic_thermostat_entity_entry = entity_registry.async_get( - "climate.my_generic_thermostat" + "climate.mock_title_my_generic_thermostat" ) assert generic_thermostat_entity_entry.device_id == switch_entity_entry.device_id @@ -199,7 +199,7 @@ async def test_async_handle_source_entity_changes_source_entity_removed( # Check that the helper entity is linked to the expected source device generic_thermostat_entity_entry = entity_registry.async_get( - "climate.my_generic_thermostat" + "climate.mock_title_my_generic_thermostat" ) assert generic_thermostat_entity_entry.device_id == expected_helper_device_id @@ -226,8 +226,8 @@ async def test_async_handle_source_entity_changes_source_entity_removed( @pytest.mark.parametrize( ("source_entity_id", "expected_helper_device_id", "expected_events"), [ - ("switch.test_unique", None, ["update"]), - ("sensor.test_unique", "switch_device_id", []), + ("switch.mock_title", None, ["update"]), + ("sensor.mock_title", "switch_device_id", []), ], indirect=["expected_helper_device_id"], ) @@ -250,7 +250,7 @@ async def test_async_handle_source_entity_changes_source_entity_removed_shared_d await hass.async_block_till_done() generic_thermostat_entity_entry = entity_registry.async_get( - "climate.my_generic_thermostat" + "climate.mock_title_my_generic_thermostat" ) assert generic_thermostat_entity_entry.device_id == switch_entity_entry.device_id @@ -273,7 +273,7 @@ async def test_async_handle_source_entity_changes_source_entity_removed_shared_d # Check that the helper entity is linked to the expected source device generic_thermostat_entity_entry = entity_registry.async_get( - "climate.my_generic_thermostat" + "climate.mock_title_my_generic_thermostat" ) assert generic_thermostat_entity_entry.device_id == expected_helper_device_id @@ -308,8 +308,8 @@ async def test_async_handle_source_entity_changes_source_entity_removed_shared_d "expected_events", ), [ - ("switch.test_unique", 1, None, ["update"]), - ("sensor.test_unique", 0, "switch_device_id", []), + ("switch.mock_title", 1, None, ["update"]), + ("sensor.mock_title", 0, "switch_device_id", []), ], indirect=["expected_helper_device_id"], ) @@ -333,7 +333,7 @@ async def test_async_handle_source_entity_changes_source_entity_removed_from_dev await hass.async_block_till_done() generic_thermostat_entity_entry = entity_registry.async_get( - "climate.my_generic_thermostat" + "climate.mock_title_my_generic_thermostat" ) assert generic_thermostat_entity_entry.device_id == switch_entity_entry.device_id @@ -357,7 +357,7 @@ async def test_async_handle_source_entity_changes_source_entity_removed_from_dev # Check that the helper entity is linked to the expected source device generic_thermostat_entity_entry = entity_registry.async_get( - "climate.my_generic_thermostat" + "climate.mock_title_my_generic_thermostat" ) assert generic_thermostat_entity_entry.device_id == expected_helper_device_id @@ -384,7 +384,7 @@ async def test_async_handle_source_entity_changes_source_entity_removed_from_dev ) @pytest.mark.parametrize( ("source_entity_id", "unload_entry_calls", "expected_events"), - [("switch.test_unique", 1, ["update"]), ("sensor.test_unique", 0, [])], + [("switch.mock_title", 1, ["update"]), ("sensor.mock_title", 0, [])], ) async def test_async_handle_source_entity_changes_source_entity_moved_other_device( hass: HomeAssistant, @@ -410,7 +410,7 @@ async def test_async_handle_source_entity_changes_source_entity_moved_other_devi await hass.async_block_till_done() generic_thermostat_entity_entry = entity_registry.async_get( - "climate.my_generic_thermostat" + "climate.mock_title_my_generic_thermostat" ) assert generic_thermostat_entity_entry.device_id == switch_entity_entry.device_id @@ -439,7 +439,7 @@ async def test_async_handle_source_entity_changes_source_entity_moved_other_devi # Check that the helper entity is linked to the expected source device switch_entity_entry = entity_registry.async_get(switch_entity_entry.entity_id) generic_thermostat_entity_entry = entity_registry.async_get( - "climate.my_generic_thermostat" + "climate.mock_title_my_generic_thermostat" ) assert generic_thermostat_entity_entry.device_id == switch_entity_entry.device_id @@ -471,8 +471,8 @@ async def test_async_handle_source_entity_changes_source_entity_moved_other_devi @pytest.mark.parametrize( ("source_entity_id", "new_entity_id", "config_key"), [ - ("switch.test_unique", "switch.new_entity_id", "heater"), - ("sensor.test_unique", "sensor.new_entity_id", "target_sensor"), + ("switch.mock_title", "switch.new_entity_id", "heater"), + ("sensor.mock_title", "sensor.new_entity_id", "target_sensor"), ], ) async def test_async_handle_source_entity_new_entity_id( @@ -494,7 +494,7 @@ async def test_async_handle_source_entity_new_entity_id( await hass.async_block_till_done() generic_thermostat_entity_entry = entity_registry.async_get( - "climate.my_generic_thermostat" + "climate.mock_title_my_generic_thermostat" ) assert generic_thermostat_entity_entry.device_id == switch_entity_entry.device_id @@ -571,7 +571,7 @@ async def test_migration_1_1( switch_device = device_registry.async_get(switch_device.id) assert generic_thermostat_config_entry.entry_id not in switch_device.config_entries generic_thermostat_entity_entry = entity_registry.async_get( - "climate.my_generic_thermostat" + "climate.mock_title_my_generic_thermostat" ) assert generic_thermostat_entity_entry.device_id == switch_entity_entry.device_id diff --git a/tests/components/group/test_init.py b/tests/components/group/test_init.py index a04e2ddc55f6f..22b590e9477fb 100644 --- a/tests/components/group/test_init.py +++ b/tests/components/group/test_init.py @@ -16,6 +16,7 @@ ATTR_FRIENDLY_NAME, ATTR_ICON, EVENT_HOMEASSISTANT_START, + EVENT_STATE_CHANGED, SERVICE_RELOAD, STATE_CLOSED, STATE_HOME, @@ -24,7 +25,7 @@ STATE_ON, STATE_UNKNOWN, ) -from homeassistant.core import CoreState, HomeAssistant +from homeassistant.core import Context, CoreState, HomeAssistant from homeassistant.helpers import entity_registry as er from homeassistant.setup import async_setup_component @@ -35,6 +36,7 @@ MockModule, MockPlatform, assert_setup_component, + async_capture_events, mock_integration, mock_platform, ) @@ -159,6 +161,7 @@ async def test_setup_group_with_mixed_groupable_states(hass: HomeAssistant) -> N mode=None, object_id=None, order=None, + context=None, ) await hass.async_block_till_done() @@ -181,6 +184,7 @@ async def test_setup_group_with_a_non_existing_state(hass: HomeAssistant) -> Non mode=None, object_id=None, order=None, + context=None, ) assert grp.state == STATE_ON @@ -202,6 +206,7 @@ async def test_setup_group_with_non_groupable_states(hass: HomeAssistant) -> Non mode=None, object_id=None, order=None, + context=None, ) assert grp.state is None @@ -218,6 +223,7 @@ async def test_setup_empty_group(hass: HomeAssistant) -> None: mode=None, object_id=None, order=None, + context=None, ) assert grp.state is None @@ -239,6 +245,7 @@ async def test_monitor_group(hass: HomeAssistant) -> None: mode=None, object_id=None, order=None, + context=None, ) # Test if group setup in our init mode is ok @@ -265,6 +272,7 @@ async def test_group_turns_off_if_all_off(hass: HomeAssistant) -> None: mode=None, object_id=None, order=None, + context=None, ) await hass.async_block_till_done() @@ -291,6 +299,7 @@ async def test_group_turns_on_if_all_are_off_and_one_turns_on( mode=None, object_id=None, order=None, + context=None, ) # Turn one on @@ -319,6 +328,7 @@ async def test_allgroup_stays_off_if_all_are_off_and_one_turns_on( mode=True, object_id=None, order=None, + context=None, ) # Turn one on @@ -345,6 +355,7 @@ async def test_allgroup_turn_on_if_last_turns_on(hass: HomeAssistant) -> None: mode=True, object_id=None, order=None, + context=None, ) # Turn one on @@ -371,6 +382,7 @@ async def test_expand_entity_ids(hass: HomeAssistant) -> None: mode=None, object_id=None, order=None, + context=None, ) assert sorted(["light.ceiling", "light.bowl"]) == sorted( @@ -396,6 +408,7 @@ async def test_expand_entity_ids_does_not_return_duplicates( mode=None, object_id=None, order=None, + context=None, ) assert sorted( @@ -423,6 +436,7 @@ async def test_expand_entity_ids_recursive(hass: HomeAssistant) -> None: mode=None, object_id=None, order=None, + context=None, ) assert sorted(["light.ceiling", "light.bowl"]) == sorted( @@ -451,6 +465,7 @@ async def test_get_entity_ids(hass: HomeAssistant) -> None: mode=None, object_id=None, order=None, + context=None, ) assert sorted(group.get_entity_ids(hass, test_group.entity_id)) == [ @@ -474,6 +489,7 @@ async def test_get_entity_ids_with_domain_filter(hass: HomeAssistant) -> None: mode=None, object_id=None, order=None, + context=None, ) assert group.get_entity_ids( @@ -511,6 +527,7 @@ async def test_group_being_init_before_first_tracked_state_is_set_to_on( mode=None, object_id=None, order=None, + context=None, ) hass.states.async_set("light.not_there_1", STATE_ON) @@ -539,6 +556,7 @@ async def test_group_being_init_before_first_tracked_state_is_set_to_off( mode=None, object_id=None, order=None, + context=None, ) hass.states.async_set("light.not_there_1", STATE_OFF) @@ -563,6 +581,7 @@ async def test_groups_get_unique_names(hass: HomeAssistant) -> None: mode=None, object_id=None, order=None, + context=None, ) grp2 = await group.Group.async_create_group( hass, @@ -573,6 +592,7 @@ async def test_groups_get_unique_names(hass: HomeAssistant) -> None: mode=None, object_id=None, order=None, + context=None, ) assert grp1.entity_id != grp2.entity_id @@ -592,6 +612,7 @@ async def test_expand_entity_ids_expands_nested_groups(hass: HomeAssistant) -> N mode=None, object_id=None, order=None, + context=None, ) await group.Group.async_create_group( hass, @@ -602,6 +623,7 @@ async def test_expand_entity_ids_expands_nested_groups(hass: HomeAssistant) -> N mode=None, object_id=None, order=None, + context=None, ) await group.Group.async_create_group( hass, @@ -612,6 +634,7 @@ async def test_expand_entity_ids_expands_nested_groups(hass: HomeAssistant) -> N mode=None, object_id=None, order=None, + context=None, ) assert sorted(group.expand_entity_ids(hass, ["group.group_of_groups"])) == [ @@ -638,6 +661,7 @@ async def test_set_assumed_state_based_on_tracked(hass: HomeAssistant) -> None: mode=None, object_id=None, order=None, + context=None, ) state = hass.states.get(test_group.entity_id) @@ -677,6 +701,7 @@ async def test_group_updated_after_device_tracker_zone_change( mode=None, object_id=None, order=None, + context=None, ) hass.states.async_set("device_tracker.Adam", "cool_state_not_home") @@ -703,6 +728,7 @@ async def test_is_on(hass: HomeAssistant) -> None: mode=None, object_id=None, order=None, + context=None, ) await hass.async_block_till_done() @@ -840,6 +866,7 @@ async def test_is_on_and_state_mixed_domains( mode=None, object_id=None, order=None, + context=None, ) await hass.async_block_till_done() @@ -883,6 +910,7 @@ async def test_reloading_groups(hass: HomeAssistant) -> None: mode=None, object_id=None, order=None, + context=None, ) await hass.async_block_till_done() @@ -960,6 +988,7 @@ async def test_setup(hass: HomeAssistant) -> None: mode=None, object_id=None, order=None, + context=None, ) await group.Group.async_create_group( hass, @@ -970,6 +999,7 @@ async def test_setup(hass: HomeAssistant) -> None: mode=None, object_id=None, order=None, + context=None, ) await hass.async_block_till_done() @@ -1013,6 +1043,8 @@ async def test_service_group_services_add_remove_entities(hass: HomeAssistant) - assert hass.services.has_service("group", group.SERVICE_SET) + create_context = Context() + created_events = async_capture_events(hass, EVENT_STATE_CHANGED) await hass.services.async_call( group.DOMAIN, group.SERVICE_SET, @@ -1021,6 +1053,7 @@ async def test_service_group_services_add_remove_entities(hass: HomeAssistant) - "name": "New Group", "entities": ["person.one", "person.two"], }, + context=create_context, ) await hass.async_block_till_done() @@ -1029,6 +1062,17 @@ async def test_service_group_services_add_remove_entities(hass: HomeAssistant) - assert group_state.attributes["friendly_name"] == "New Group" assert list(group_state.attributes["entity_id"]) == ["person.one", "person.two"] + # The group recomputes from its members right after, so assert on the state + # written when the entity was added rather than on the current state + created_event = next( + event + for event in created_events + if event.data["entity_id"] == "group.new_group" + and event.data["old_state"] is None + ) + assert created_event.context is create_context + + context = Context() await hass.services.async_call( group.DOMAIN, group.SERVICE_SET, @@ -1036,11 +1080,13 @@ async def test_service_group_services_add_remove_entities(hass: HomeAssistant) - "object_id": "new_group", "add_entities": "person.three", }, + context=context, ) await hass.async_block_till_done() group_state = hass.states.get("group.new_group") assert group_state.state == "home" assert "person.three" in list(group_state.attributes["entity_id"]) + assert group_state.context is context await hass.services.async_call( group.DOMAIN, @@ -1096,11 +1142,22 @@ async def test_service_group_set_group_remove_group(hass: HomeAssistant) -> None ["test.entity_bla1", "test.entity_id2"] ) - common.async_remove(hass, "user_test_group") + removed_events = async_capture_events(hass, EVENT_STATE_CHANGED) + context = Context() + await hass.services.async_call( + group.DOMAIN, + group.SERVICE_REMOVE, + {"object_id": "user_test_group"}, + blocking=True, + context=context, + ) await hass.async_block_till_done() group_state = hass.states.get("group.user_test_group") assert group_state is None + assert removed_events[-1].data["entity_id"] == "group.user_test_group" + assert removed_events[-1].data["new_state"] is None + assert removed_events[-1].context is context async def test_group_order(hass: HomeAssistant) -> None: diff --git a/tests/components/history_stats/test_init.py b/tests/components/history_stats/test_init.py index 49550428d9242..b7e0655669fc0 100644 --- a/tests/components/history_stats/test_init.py +++ b/tests/components/history_stats/test_init.py @@ -127,7 +127,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed( assert await hass.config_entries.async_setup(history_stats_config_entry.entry_id) await hass.async_block_till_done() - history_stats_entity_entry = entity_registry.async_get("sensor.my_history_stats") + history_stats_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_history_stats" + ) assert history_stats_entity_entry.device_id == sensor_entity_entry.device_id sensor_device = device_registry.async_get(sensor_device.id) @@ -146,7 +148,7 @@ async def test_async_handle_source_entity_changes_source_entity_removed( mock_unload_entry.assert_called_once() # Check that the helper entity is removed - assert not entity_registry.async_get("sensor.my_history_stats") + assert not entity_registry.async_get(history_stats_entity_entry.entity_id) # Check that the device is removed assert not device_registry.async_get(sensor_device.id) @@ -177,7 +179,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed_shared_d assert await hass.config_entries.async_setup(history_stats_config_entry.entry_id) await hass.async_block_till_done() - history_stats_entity_entry = entity_registry.async_get("sensor.my_history_stats") + history_stats_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_history_stats" + ) assert history_stats_entity_entry.device_id == sensor_entity_entry.device_id sensor_device = device_registry.async_get(sensor_device.id) @@ -196,7 +200,7 @@ async def test_async_handle_source_entity_changes_source_entity_removed_shared_d mock_unload_entry.assert_called_once() # Check that the helper entity is removed - assert not entity_registry.async_get("sensor.my_history_stats") + assert not entity_registry.async_get(history_stats_entity_entry.entity_id) # Check that the source device is not removed sensor_device = device_registry.async_get(sensor_device.id) @@ -225,7 +229,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed_from_dev assert await hass.config_entries.async_setup(history_stats_config_entry.entry_id) await hass.async_block_till_done() - history_stats_entity_entry = entity_registry.async_get("sensor.my_history_stats") + history_stats_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_history_stats" + ) assert history_stats_entity_entry.device_id == sensor_entity_entry.device_id sensor_device = device_registry.async_get(sensor_device.id) @@ -245,7 +251,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed_from_dev mock_unload_entry.assert_called_once() # Check that the entity is no longer linked to the source device - history_stats_entity_entry = entity_registry.async_get("sensor.my_history_stats") + history_stats_entity_entry = entity_registry.async_get( + history_stats_entity_entry.entity_id + ) assert history_stats_entity_entry.device_id is None # Check that the history_stats config entry is not in the device @@ -278,7 +286,9 @@ async def test_async_handle_source_entity_changes_source_entity_moved_other_devi assert await hass.config_entries.async_setup(history_stats_config_entry.entry_id) await hass.async_block_till_done() - history_stats_entity_entry = entity_registry.async_get("sensor.my_history_stats") + history_stats_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_history_stats" + ) assert history_stats_entity_entry.device_id == sensor_entity_entry.device_id sensor_device = device_registry.async_get(sensor_device.id) @@ -300,7 +310,9 @@ async def test_async_handle_source_entity_changes_source_entity_moved_other_devi mock_unload_entry.assert_called_once() # Check that the entity is linked to the other device - history_stats_entity_entry = entity_registry.async_get("sensor.my_history_stats") + history_stats_entity_entry = entity_registry.async_get( + history_stats_entity_entry.entity_id + ) assert history_stats_entity_entry.device_id == sensor_device_2.id # Check that the history_stats config entry is not in any of the devices @@ -329,7 +341,9 @@ async def test_async_handle_source_entity_new_entity_id( assert await hass.config_entries.async_setup(history_stats_config_entry.entry_id) await hass.async_block_till_done() - history_stats_entity_entry = entity_registry.async_get("sensor.my_history_stats") + history_stats_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_history_stats" + ) assert history_stats_entity_entry.device_id == sensor_entity_entry.device_id sensor_device = device_registry.async_get(sensor_device.id) @@ -398,7 +412,9 @@ async def test_migration_1_1( # entity is linked to the source device sensor_device = device_registry.async_get(sensor_device.id) assert history_stats_config_entry.entry_id not in sensor_device.config_entries - history_stats_entity_entry = entity_registry.async_get("sensor.my_history_stats") + history_stats_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_history_stats" + ) assert history_stats_entity_entry.device_id == sensor_entity_entry.device_id assert history_stats_config_entry.version == 2 @@ -449,9 +465,11 @@ async def test_migration_1_2( == HistoryStatsConfigFlowHandler.MINOR_VERSION ) - assert hass.states.get("sensor.my_history_stats") is not None + assert hass.states.get("sensor.mock_title_my_history_stats") is not None assert ( - hass.states.get("sensor.my_history_stats").attributes.get(CONF_STATE_CLASS) + hass.states.get("sensor.mock_title_my_history_stats").attributes.get( + CONF_STATE_CLASS + ) == SensorStateClass.MEASUREMENT ) diff --git a/tests/components/history_stats/test_sensor.py b/tests/components/history_stats/test_sensor.py index 608b9da923e81..f5144ee86e57b 100644 --- a/tests/components/history_stats/test_sensor.py +++ b/tests/components/history_stats/test_sensor.py @@ -2162,14 +2162,14 @@ async def test_device_id( device_id=source_device_entry.id, ) await hass.async_block_till_done() - assert entity_registry.async_get("binary_sensor.test_source") is not None + assert entity_registry.async_get(source_entity.entity_id) is not None history_stats_config_entry = MockConfigEntry( data={}, domain=DOMAIN, options={ CONF_NAME: DEFAULT_NAME, - CONF_ENTITY_ID: "binary_sensor.test_source", + CONF_ENTITY_ID: source_entity.entity_id, CONF_STATE: ["on"], CONF_TYPE: "count", CONF_START: "{{ as_timestamp(utcnow()) - 3600 }}", @@ -2182,7 +2182,7 @@ async def test_device_id( assert await hass.config_entries.async_setup(history_stats_config_entry.entry_id) await hass.async_block_till_done() - history_stats_entity = entity_registry.async_get("sensor.history_stats") + history_stats_entity = entity_registry.async_get("sensor.mock_title_history_stats") assert history_stats_entity is not None assert history_stats_entity.device_id == source_entity.device_id diff --git a/tests/components/home_connect/test_config_flow.py b/tests/components/home_connect/test_config_flow.py index 29afa27bea06c..1464be1b580c4 100644 --- a/tests/components/home_connect/test_config_flow.py +++ b/tests/components/home_connect/test_config_flow.py @@ -3,6 +3,7 @@ from collections.abc import Awaitable, Callable from http import HTTPStatus from unittest.mock import MagicMock, patch +from urllib.parse import parse_qsl, urlsplit from aiohomeconnect.const import OAUTH2_AUTHORIZE, OAUTH2_TOKEN from aiohomeconnect.model import HomeAppliance @@ -25,6 +26,23 @@ CLIENT_ID = "1234" CLIENT_SECRET = "5678" + +def assert_authorize_url(url: str, state: str, images_scope: bool | None) -> None: + """Assert the generated OAuth authorize URL.""" + split_url = urlsplit(url) + + assert ( + f"{split_url.scheme}://{split_url.netloc}{split_url.path}" == OAUTH2_AUTHORIZE + ) + assert dict(parse_qsl(split_url.query)) == { + "response_type": "code", + "client_id": CLIENT_ID, + "redirect_uri": "https://example.com/auth/external/callback", + "state": state, + "scope": f"Control Monitor Settings IdentifyAppliance{' Images' if images_scope else ''}", + } + + DHCP_DISCOVERY = ( DhcpServiceInfo( ip="1.1.1.1", @@ -95,10 +113,14 @@ @pytest.mark.usefixtures("current_request_with_host") +@pytest.mark.parametrize( + "images_scope", [True, False], ids=["images_scope", "no_images_scope"] +) async def test_full_flow( hass: HomeAssistant, hass_client_no_auth: ClientSessionGenerator, aioclient_mock: AiohttpClientMocker, + images_scope: bool, ) -> None: """Check full flow.""" assert await setup.async_setup_component(hass, "home_connect", {}) @@ -106,6 +128,13 @@ async def test_full_flow( result = await hass.config_entries.flow.async_init( DOMAIN, context=ConfigFlowContext(source=config_entries.SOURCE_USER) ) + + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "scopes" + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], user_input={"images_scope": images_scope} + ) state = config_entry_oauth2_flow._encode_jwt( hass, { @@ -115,11 +144,7 @@ async def test_full_flow( ) assert result["type"] is FlowResultType.EXTERNAL_STEP - assert result["url"] == ( - f"{OAUTH2_AUTHORIZE}?response_type=code&client_id={CLIENT_ID}" - "&redirect_uri=https://example.com/auth/external/callback" - f"&state={state}" - ) + assert_authorize_url(result["url"], state, images_scope) client = await hass_client_no_auth() resp = await client.get(f"/auth/external/callback?code=abcd&state={state}") @@ -161,6 +186,13 @@ async def test_prevent_reconfiguring_same_account( result = await hass.config_entries.flow.async_init( DOMAIN, context=ConfigFlowContext(source=config_entries.SOURCE_USER) ) + + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "scopes" + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], user_input={"images_scope": True} + ) state = config_entry_oauth2_flow._encode_jwt( hass, { @@ -170,11 +202,7 @@ async def test_prevent_reconfiguring_same_account( ) assert result["type"] is FlowResultType.EXTERNAL_STEP - assert result["url"] == ( - f"{OAUTH2_AUTHORIZE}?response_type=code&client_id={CLIENT_ID}" - "&redirect_uri=https://example.com/auth/external/callback" - f"&state={state}" - ) + assert_authorize_url(result["url"], state, True) client = await hass_client_no_auth() resp = await client.get(f"/auth/external/callback?code=abcd&state={state}") @@ -214,6 +242,13 @@ async def test_reauth_flow( assert result["step_id"] == "reauth_confirm" result = await hass.config_entries.flow.async_configure(result["flow_id"], {}) + + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "scopes" + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], user_input={"images_scope": False} + ) state = config_entry_oauth2_flow._encode_jwt( hass, { @@ -268,6 +303,13 @@ async def test_reauth_flow_with_different_account( assert result["step_id"] == "reauth_confirm" result = await hass.config_entries.flow.async_configure(result["flow_id"], {}) + + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "scopes" + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], user_input={"images_scope": True} + ) state = config_entry_oauth2_flow._encode_jwt( hass, { @@ -323,6 +365,13 @@ async def test_zeroconf_flow( result["flow_id"], {}, ) + + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "scopes" + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], user_input={"images_scope": True} + ) state = config_entry_oauth2_flow._encode_jwt( hass, { @@ -332,11 +381,7 @@ async def test_zeroconf_flow( ) assert result["type"] is FlowResultType.EXTERNAL_STEP - assert result["url"] == ( - f"{OAUTH2_AUTHORIZE}?response_type=code&client_id={CLIENT_ID}" - "&redirect_uri=https://example.com/auth/external/callback" - f"&state={state}" - ) + assert_authorize_url(result["url"], state, True) client = await hass_client_no_auth() resp = await client.get(f"/auth/external/callback?code=abcd&state={state}") @@ -406,6 +451,13 @@ async def test_dhcp_flow( result["flow_id"], {}, ) + + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "scopes" + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], user_input={"images_scope": True} + ) state = config_entry_oauth2_flow._encode_jwt( hass, { @@ -414,11 +466,7 @@ async def test_dhcp_flow( }, ) assert result["type"] is FlowResultType.EXTERNAL_STEP - assert result["url"] == ( - f"{OAUTH2_AUTHORIZE}?response_type=code&client_id={CLIENT_ID}" - "&redirect_uri=https://example.com/auth/external/callback" - f"&state={state}" - ) + assert_authorize_url(result["url"], state, True) client = await hass_client_no_auth() resp = await client.get(f"/auth/external/callback?code=abcd&state={state}") diff --git a/tests/components/humidifier/test_device_action.py b/tests/components/humidifier/test_device_action.py index 2f02f03658b38..55524143adf11 100644 --- a/tests/components/humidifier/test_device_action.py +++ b/tests/components/humidifier/test_device_action.py @@ -58,7 +58,9 @@ async def test_get_actions( ) if set_state: hass.states.async_set( - f"{DOMAIN}.test_5678", "attributes", {"supported_features": features_state} + entity_entry.entity_id, + "attributes", + {"supported_features": features_state}, ) expected_actions = [] basic_action_types = ["set_humidity", "turn_on", "turn_off", "toggle"] @@ -471,7 +473,7 @@ async def test_capabilities( ) if set_state: hass.states.async_set( - f"{DOMAIN}.test_5678", + entity_entry.entity_id, STATE_ON, capabilities_state, ) @@ -615,7 +617,7 @@ async def test_capabilities_legacy( ) if set_state: hass.states.async_set( - f"{DOMAIN}.test_5678", + entity_entry.entity_id, STATE_ON, capabilities_state, ) diff --git a/tests/components/humidifier/test_device_condition.py b/tests/components/humidifier/test_device_condition.py index 1f362b9b0109d..5e7c41dca7a65 100644 --- a/tests/components/humidifier/test_device_condition.py +++ b/tests/components/humidifier/test_device_condition.py @@ -54,7 +54,9 @@ async def test_get_conditions( ) if set_state: hass.states.async_set( - f"{DOMAIN}.test_5678", "attributes", {"supported_features": features_state} + entity_entry.entity_id, + "attributes", + {"supported_features": features_state}, ) expected_conditions = [] basic_condition_types = ["is_on", "is_off"] diff --git a/tests/components/humidifier/test_device_trigger.py b/tests/components/humidifier/test_device_trigger.py index dfd6fc0bd1010..2fb67579d9ef1 100644 --- a/tests/components/humidifier/test_device_trigger.py +++ b/tests/components/humidifier/test_device_trigger.py @@ -395,8 +395,8 @@ async def test_if_fires_on_state_change( await hass.async_block_till_done() assert len(service_calls) == 8 assert {service_calls[6].data["some"], service_calls[7].data["some"]} == { - "turn_off device - humidifier.test_5678 - on - off - None", - "turn_on_or_off device - humidifier.test_5678 - on - off - None", + f"turn_off device - {entry.entity_id} - on - off - None", + f"turn_on_or_off device - {entry.entity_id} - on - off - None", } # Fake turn on @@ -408,8 +408,8 @@ async def test_if_fires_on_state_change( await hass.async_block_till_done() assert len(service_calls) == 10 assert {service_calls[8].data["some"], service_calls[9].data["some"]} == { - "turn_on device - humidifier.test_5678 - off - on - None", - "turn_on_or_off device - humidifier.test_5678 - off - on - None", + f"turn_on device - {entry.entity_id} - off - on - None", + f"turn_on_or_off device - {entry.entity_id} - off - on - None", } diff --git a/tests/components/incomfort/test_config_flow.py b/tests/components/incomfort/test_config_flow.py index ce74b966fca65..e413087dd3f38 100644 --- a/tests/components/incomfort/test_config_flow.py +++ b/tests/components/incomfort/test_config_flow.py @@ -164,7 +164,7 @@ async def test_dhcp_flow_simple( assert gateway_device.manufacturer == "Intergas" assert gateway_device.connections == {("mac", "00:04:a3:de:ad:ff")} - devices = device_registry.devices.get_devices_for_config_entry_id(entry_id) + devices = dr.async_entries_for_config_entry(device_registry, entry_id) assert len(devices) == 3 boiler_device = device_registry.async_get_device_by_identifier( (DOMAIN, "c0ffeec0ffee"), entry_id @@ -212,8 +212,8 @@ async def test_dhcp_flow_migrates_existing_entry_without_unique_id( assert gateway_device.manufacturer == "Intergas" assert gateway_device.connections == {("mac", "00:04:a3:de:ad:ff")} - devices = device_registry.devices.get_devices_for_config_entry_id( - mock_config_entry.entry_id + devices = dr.async_entries_for_config_entry( + device_registry, mock_config_entry.entry_id ) assert len(devices) == 3 boiler_device = device_registry.async_get_device_by_identifier( diff --git a/tests/components/incomfort/test_init.py b/tests/components/incomfort/test_init.py index f619219d2f0e2..c6d478674c820 100644 --- a/tests/components/incomfort/test_init.py +++ b/tests/components/incomfort/test_init.py @@ -14,7 +14,7 @@ from homeassistant.config_entries import ConfigEntry, ConfigEntryState from homeassistant.const import STATE_UNAVAILABLE from homeassistant.core import HomeAssistant -from homeassistant.helpers import entity_registry as er +from homeassistant.helpers import device_registry as dr, entity_registry as er from homeassistant.helpers.device_registry import DeviceRegistry from .conftest import MOCK_HEATER_STATUS @@ -81,8 +81,8 @@ async def test_stale_devices_cleanup( await hass.config_entries.async_setup(mock_config_entry.entry_id) assert mock_config_entry.state is ConfigEntryState.LOADED await hass.config_entries.async_unload(mock_config_entry.entry_id) - old_entries = device_registry.devices.get_devices_for_config_entry_id( - mock_config_entry.entry_id + old_entries = dr.async_entries_for_config_entry( + device_registry, mock_config_entry.entry_id ) assert len(old_entries) == 3 old_heater = device_registry.async_get_device_by_identifier( @@ -103,8 +103,8 @@ async def test_stale_devices_cleanup( await hass.config_entries.async_setup(mock_config_entry.entry_id) assert mock_config_entry.state is ConfigEntryState.LOADED - new_entries = device_registry.devices.get_devices_for_config_entry_id( - mock_config_entry.entry_id + new_entries = dr.async_entries_for_config_entry( + device_registry, mock_config_entry.entry_id ) assert len(new_entries) == 3 new_heater = device_registry.async_get_device_by_identifier( diff --git a/tests/components/integration/test_init.py b/tests/components/integration/test_init.py index d422ac541860a..8328c82bf4a88 100644 --- a/tests/components/integration/test_init.py +++ b/tests/components/integration/test_init.py @@ -197,7 +197,7 @@ def _get_device_config_entries(entry: er.RegistryEntry) -> set[str]: assert config_entry.entry_id not in _get_device_config_entries(input_entry) assert config_entry.entry_id not in _get_device_config_entries(valid_entry) - integration_entity_entry = entity_registry.async_get("sensor.my_integration") + integration_entity_entry = entity_registry.async_get("sensor.input_my_integration") assert integration_entity_entry.device_id == input_entry.device_id hass.config_entries.async_update_entry( @@ -209,7 +209,7 @@ def _get_device_config_entries(entry: er.RegistryEntry) -> set[str]: # Check that the device association has updated assert config_entry.entry_id not in _get_device_config_entries(input_entry) assert config_entry.entry_id not in _get_device_config_entries(valid_entry) - integration_entity_entry = entity_registry.async_get("sensor.my_integration") + integration_entity_entry = entity_registry.async_get("sensor.input_my_integration") assert integration_entity_entry.device_id == valid_entry.device_id @@ -226,7 +226,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed( assert await hass.config_entries.async_setup(integration_config_entry.entry_id) await hass.async_block_till_done() - integration_entity_entry = entity_registry.async_get("sensor.my_integration") + integration_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_integration" + ) assert integration_entity_entry.device_id == sensor_entity_entry.device_id sensor_device = device_registry.async_get(sensor_device.id) @@ -245,7 +247,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed( mock_unload_entry.assert_not_called() # Check that the entity is no longer linked to the source device - integration_entity_entry = entity_registry.async_get("sensor.my_integration") + integration_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_integration" + ) assert integration_entity_entry.device_id is None # Check that the device is removed @@ -270,7 +274,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed_shared_d assert await hass.config_entries.async_setup(integration_config_entry.entry_id) await hass.async_block_till_done() - integration_entity_entry = entity_registry.async_get("sensor.my_integration") + integration_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_integration" + ) assert integration_entity_entry.device_id == sensor_entity_entry.device_id sensor_device = device_registry.async_get(sensor_device.id) @@ -289,7 +295,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed_shared_d mock_unload_entry.assert_not_called() # Check that the entity is no longer linked to the source device - integration_entity_entry = entity_registry.async_get("sensor.my_integration") + integration_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_integration" + ) assert integration_entity_entry.device_id is None # Check that the source device is not removed @@ -318,7 +326,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed_from_dev assert await hass.config_entries.async_setup(integration_config_entry.entry_id) await hass.async_block_till_done() - integration_entity_entry = entity_registry.async_get("sensor.my_integration") + integration_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_integration" + ) assert integration_entity_entry.device_id == sensor_entity_entry.device_id sensor_device = device_registry.async_get(sensor_device.id) @@ -338,7 +348,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed_from_dev mock_unload_entry.assert_called_once() # Check that the entity is no longer linked to the source device - integration_entity_entry = entity_registry.async_get("sensor.my_integration") + integration_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_integration" + ) assert integration_entity_entry.device_id is None # Check that the integration config entry is not in the device @@ -370,7 +382,9 @@ async def test_async_handle_source_entity_changes_source_entity_moved_other_devi assert await hass.config_entries.async_setup(integration_config_entry.entry_id) await hass.async_block_till_done() - integration_entity_entry = entity_registry.async_get("sensor.my_integration") + integration_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_integration" + ) assert integration_entity_entry.device_id == sensor_entity_entry.device_id sensor_device = device_registry.async_get(sensor_device.id) @@ -392,7 +406,9 @@ async def test_async_handle_source_entity_changes_source_entity_moved_other_devi mock_unload_entry.assert_called_once() # Check that the entity is linked to the other device - integration_entity_entry = entity_registry.async_get("sensor.my_integration") + integration_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_integration" + ) assert integration_entity_entry.device_id == sensor_device_2.id # Check that the derivative config entry is not in any of the devices @@ -420,7 +436,9 @@ async def test_async_handle_source_entity_new_entity_id( assert await hass.config_entries.async_setup(integration_config_entry.entry_id) await hass.async_block_till_done() - integration_entity_entry = entity_registry.async_get("sensor.my_integration") + integration_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_integration" + ) assert integration_entity_entry.device_id == sensor_entity_entry.device_id sensor_device = device_registry.async_get(sensor_device.id) @@ -489,7 +507,9 @@ async def test_migration_1_1( # is linked to the source device sensor_device = device_registry.async_get(sensor_device.id) assert integration_config_entry.entry_id not in sensor_device.config_entries - integration_entity_entry = entity_registry.async_get("sensor.my_integration") + integration_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_integration" + ) assert integration_entity_entry.device_id == sensor_entity_entry.device_id assert integration_config_entry.version == 1 diff --git a/tests/components/integration/test_sensor.py b/tests/components/integration/test_sensor.py index b8c8b0270abda..fdd3a50cefedf 100644 --- a/tests/components/integration/test_sensor.py +++ b/tests/components/integration/test_sensor.py @@ -892,7 +892,7 @@ async def test_device_id( device_id=source_device_entry.id, ) await hass.async_block_till_done() - assert entity_registry.async_get("sensor.test_source") is not None + assert entity_registry.async_get("sensor.mock_title") is not None integration_config_entry = MockConfigEntry( data={}, @@ -901,7 +901,7 @@ async def test_device_id( "method": "trapezoidal", "name": "integration", "round": 1.0, - "source": "sensor.test_source", + "source": "sensor.mock_title", "unit_prefix": "k", "unit_time": "min", }, @@ -913,7 +913,7 @@ async def test_device_id( assert await hass.config_entries.async_setup(integration_config_entry.entry_id) await hass.async_block_till_done() - integration_entity = entity_registry.async_get("sensor.integration") + integration_entity = entity_registry.async_get("sensor.mock_title_integration") assert integration_entity is not None assert integration_entity.device_id == source_entity.device_id diff --git a/tests/components/knx/test_interface_device.py b/tests/components/knx/test_interface_device.py index 2c74d00fb395c..851a57c11f81c 100644 --- a/tests/components/knx/test_interface_device.py +++ b/tests/components/knx/test_interface_device.py @@ -124,8 +124,8 @@ async def test_remove_interface_device( assert await async_setup_component(hass, "config", {}) await knx.setup_integration() client = await hass_ws_client(hass) - knx_devices = device_registry.devices.get_devices_for_config_entry_id( - knx.mock_config_entry.entry_id + knx_devices = dr.async_entries_for_config_entry( + device_registry, knx.mock_config_entry.entry_id ) assert len(knx_devices) == 1 assert knx_devices[0].name == "KNX Interface" diff --git a/tests/components/knx/test_switch.py b/tests/components/knx/test_switch.py index b214efea0d52d..69961da5b4e77 100644 --- a/tests/components/knx/test_switch.py +++ b/tests/components/knx/test_switch.py @@ -238,6 +238,6 @@ async def test_switch_ui_load(knx: KNXTestKit) -> None: # unrelated light in config store await knx.assert_read("1/0/21", response=True, ignore_order=True) knx.assert_state( - "switch.test", # has_entity_name with unregistered device + "switch.knx_test", # has_entity_name with device named after config entry STATE_ON, ) diff --git a/tests/components/lock/test_device_action.py b/tests/components/lock/test_device_action.py index 24053bdce46ba..eec5a023e9dc1 100644 --- a/tests/components/lock/test_device_action.py +++ b/tests/components/lock/test_device_action.py @@ -53,7 +53,7 @@ async def test_get_actions( ) if set_state: hass.states.async_set( - f"{DOMAIN}.test_5678", "attributes", {"supported_features": features_state} + entity_entry.entity_id, "attributes", {"supported_features": features_state} ) expected_actions = [] basic_action_types = ["lock", "unlock"] diff --git a/tests/components/media_player/test_device_trigger.py b/tests/components/media_player/test_device_trigger.py index 7618d0a474b16..7488dad82a62f 100644 --- a/tests/components/media_player/test_device_trigger.py +++ b/tests/components/media_player/test_device_trigger.py @@ -265,8 +265,8 @@ async def test_if_fires_on_state_change( await hass.async_block_till_done() assert len(service_calls) == 2 assert {service_calls[0].data["some"], service_calls[1].data["some"]} == { - "turned_on - device - media_player.test_5678 - off - on - None", - "changed_states - device - media_player.test_5678 - off - on - None", + f"turned_on - device - {entry.entity_id} - off - on - None", + f"changed_states - device - {entry.entity_id} - off - on - None", } # Fake that the entity is turning off. @@ -274,8 +274,8 @@ async def test_if_fires_on_state_change( await hass.async_block_till_done() assert len(service_calls) == 4 assert {service_calls[2].data["some"], service_calls[3].data["some"]} == { - "turned_off - device - media_player.test_5678 - on - off - None", - "changed_states - device - media_player.test_5678 - on - off - None", + f"turned_off - device - {entry.entity_id} - on - off - None", + f"changed_states - device - {entry.entity_id} - on - off - None", } # Fake that the entity becomes idle. @@ -283,8 +283,8 @@ async def test_if_fires_on_state_change( await hass.async_block_till_done() assert len(service_calls) == 6 assert {service_calls[4].data["some"], service_calls[5].data["some"]} == { - "idle - device - media_player.test_5678 - off - idle - None", - "changed_states - device - media_player.test_5678 - off - idle - None", + f"idle - device - {entry.entity_id} - off - idle - None", + f"changed_states - device - {entry.entity_id} - off - idle - None", } # Fake that the entity starts playing. @@ -292,8 +292,8 @@ async def test_if_fires_on_state_change( await hass.async_block_till_done() assert len(service_calls) == 8 assert {service_calls[6].data["some"], service_calls[7].data["some"]} == { - "playing - device - media_player.test_5678 - idle - playing - None", - "changed_states - device - media_player.test_5678 - idle - playing - None", + f"playing - device - {entry.entity_id} - idle - playing - None", + f"changed_states - device - {entry.entity_id} - idle - playing - None", } # Fake that the entity is paused. @@ -301,8 +301,8 @@ async def test_if_fires_on_state_change( await hass.async_block_till_done() assert len(service_calls) == 10 assert {service_calls[8].data["some"], service_calls[9].data["some"]} == { - "paused - device - media_player.test_5678 - playing - paused - None", - "changed_states - device - media_player.test_5678 - playing - paused - None", + f"paused - device - {entry.entity_id} - playing - paused - None", + f"changed_states - device - {entry.entity_id} - playing - paused - None", } # Fake that the entity is buffering. @@ -310,8 +310,8 @@ async def test_if_fires_on_state_change( await hass.async_block_till_done() assert len(service_calls) == 12 assert {service_calls[10].data["some"], service_calls[11].data["some"]} == { - "buffering - device - media_player.test_5678 - paused - buffering - None", - "changed_states - device - media_player.test_5678 - paused - buffering - None", + f"buffering - device - {entry.entity_id} - paused - buffering - None", + f"changed_states - device - {entry.entity_id} - paused - buffering - None", } @@ -370,7 +370,7 @@ async def test_if_fires_on_state_change_legacy( assert len(service_calls) == 1 assert ( service_calls[0].data["some"] - == "turned_on - device - media_player.test_5678 - off - on - None" + == f"turned_on - device - {entry.entity_id} - off - on - None" ) diff --git a/tests/components/miele/snapshots/test_sensor.ambr b/tests/components/miele/snapshots/test_sensor.ambr index 960b9af0121d4..a80757fa90e6e 100644 --- a/tests/components/miele/snapshots/test_sensor.ambr +++ b/tests/components/miele/snapshots/test_sensor.ambr @@ -520,7 +520,7 @@ 'state': 'own_program', }) # --- -# name: test_coffee_system_sensor_states[platforms0-coffee_system.json][sensor.powerdisk_level-entry] +# name: test_coffee_system_sensor_states[platforms0-coffee_system.json][sensor.miele_test_powerdisk_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -534,7 +534,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.powerdisk_level', + 'entity_id': 'sensor.miele_test_powerdisk_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -557,21 +557,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_coffee_system_sensor_states[platforms0-coffee_system.json][sensor.powerdisk_level-state] +# name: test_coffee_system_sensor_states[platforms0-coffee_system.json][sensor.miele_test_powerdisk_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'PowerDisk level', + : 'Miele test PowerDisk level', : '%', }), 'context': , - 'entity_id': 'sensor.powerdisk_level', + 'entity_id': 'sensor.miele_test_powerdisk_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '80.5', }) # --- -# name: test_coffee_system_sensor_states[platforms0-coffee_system.json][sensor.rinse_aid_level-entry] +# name: test_coffee_system_sensor_states[platforms0-coffee_system.json][sensor.miele_test_rinse_aid_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -585,7 +585,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.rinse_aid_level', + 'entity_id': 'sensor.miele_test_rinse_aid_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -608,21 +608,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_coffee_system_sensor_states[platforms0-coffee_system.json][sensor.rinse_aid_level-state] +# name: test_coffee_system_sensor_states[platforms0-coffee_system.json][sensor.miele_test_rinse_aid_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Rinse aid level', + : 'Miele test Rinse aid level', : '%', }), 'context': , - 'entity_id': 'sensor.rinse_aid_level', + 'entity_id': 'sensor.miele_test_rinse_aid_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '25', }) # --- -# name: test_coffee_system_sensor_states[platforms0-coffee_system.json][sensor.salt_level-entry] +# name: test_coffee_system_sensor_states[platforms0-coffee_system.json][sensor.miele_test_salt_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -636,7 +636,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.salt_level', + 'entity_id': 'sensor.miele_test_salt_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -659,21 +659,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_coffee_system_sensor_states[platforms0-coffee_system.json][sensor.salt_level-state] +# name: test_coffee_system_sensor_states[platforms0-coffee_system.json][sensor.miele_test_salt_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Salt level', + : 'Miele test Salt level', : '%', }), 'context': , - 'entity_id': 'sensor.salt_level', + 'entity_id': 'sensor.miele_test_salt_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '75', }) # --- -# name: test_coffee_system_sensor_states[platforms0-coffee_system.json][sensor.twindos_1_level-entry] +# name: test_coffee_system_sensor_states[platforms0-coffee_system.json][sensor.miele_test_twindos_1_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -687,7 +687,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.twindos_1_level', + 'entity_id': 'sensor.miele_test_twindos_1_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -710,21 +710,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_coffee_system_sensor_states[platforms0-coffee_system.json][sensor.twindos_1_level-state] +# name: test_coffee_system_sensor_states[platforms0-coffee_system.json][sensor.miele_test_twindos_1_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'TwinDos 1 level', + : 'Miele test TwinDos 1 level', : '%', }), 'context': , - 'entity_id': 'sensor.twindos_1_level', + 'entity_id': 'sensor.miele_test_twindos_1_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '63', }) # --- -# name: test_coffee_system_sensor_states[platforms0-coffee_system.json][sensor.twindos_1_level_2-entry] +# name: test_coffee_system_sensor_states[platforms0-coffee_system.json][sensor.miele_test_twindos_1_level_2-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -738,7 +738,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.twindos_1_level_2', + 'entity_id': 'sensor.miele_test_twindos_1_level_2', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -761,21 +761,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_coffee_system_sensor_states[platforms0-coffee_system.json][sensor.twindos_1_level_2-state] +# name: test_coffee_system_sensor_states[platforms0-coffee_system.json][sensor.miele_test_twindos_1_level_2-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'TwinDos 1 level', + : 'Miele test TwinDos 1 level', : '%', }), 'context': , - 'entity_id': 'sensor.twindos_1_level_2', + 'entity_id': 'sensor.miele_test_twindos_1_level_2', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '63', }) # --- -# name: test_coffee_system_sensor_states[platforms0-coffee_system.json][sensor.twindos_2_level-entry] +# name: test_coffee_system_sensor_states[platforms0-coffee_system.json][sensor.miele_test_twindos_2_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -789,7 +789,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.twindos_2_level', + 'entity_id': 'sensor.miele_test_twindos_2_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -812,21 +812,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_coffee_system_sensor_states[platforms0-coffee_system.json][sensor.twindos_2_level-state] +# name: test_coffee_system_sensor_states[platforms0-coffee_system.json][sensor.miele_test_twindos_2_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'TwinDos 2 level', + : 'Miele test TwinDos 2 level', : '%', }), 'context': , - 'entity_id': 'sensor.twindos_2_level', + 'entity_id': 'sensor.miele_test_twindos_2_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '20', }) # --- -# name: test_coffee_system_sensor_states[platforms0-coffee_system.json][sensor.twindos_2_level_2-entry] +# name: test_coffee_system_sensor_states[platforms0-coffee_system.json][sensor.miele_test_twindos_2_level_2-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -840,7 +840,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.twindos_2_level_2', + 'entity_id': 'sensor.miele_test_twindos_2_level_2', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -863,21 +863,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_coffee_system_sensor_states[platforms0-coffee_system.json][sensor.twindos_2_level_2-state] +# name: test_coffee_system_sensor_states[platforms0-coffee_system.json][sensor.miele_test_twindos_2_level_2-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'TwinDos 2 level', + : 'Miele test TwinDos 2 level', : '%', }), 'context': , - 'entity_id': 'sensor.twindos_2_level_2', + 'entity_id': 'sensor.miele_test_twindos_2_level_2', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '20', }) # --- -# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.degreasing_cycles-entry] +# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.miele_test_degreasing_cycles-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -893,7 +893,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.degreasing_cycles', + 'entity_id': 'sensor.miele_test_degreasing_cycles', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -916,21 +916,21 @@ 'unit_of_measurement': None, }) # --- -# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.degreasing_cycles-state] +# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.miele_test_degreasing_cycles-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Degreasing cycles', + : 'Miele test Degreasing cycles', : , }), 'context': , - 'entity_id': 'sensor.degreasing_cycles', + 'entity_id': 'sensor.miele_test_degreasing_cycles', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '2', }) # --- -# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.descaling_cycles-entry] +# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.miele_test_descaling_cycles-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -946,7 +946,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.descaling_cycles', + 'entity_id': 'sensor.miele_test_descaling_cycles', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -969,14 +969,14 @@ 'unit_of_measurement': None, }) # --- -# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.descaling_cycles-state] +# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.miele_test_descaling_cycles-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Descaling cycles', + : 'Miele test Descaling cycles', : , }), 'context': , - 'entity_id': 'sensor.descaling_cycles', + 'entity_id': 'sensor.miele_test_descaling_cycles', 'last_changed': , 'last_reported': , 'last_updated': , @@ -2168,7 +2168,7 @@ 'state': 'off', }) # --- -# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.milk_pipework_cleaning_cycles-entry] +# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.miele_test_milk_pipework_cleaning_cycles-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -2184,7 +2184,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.milk_pipework_cleaning_cycles', + 'entity_id': 'sensor.miele_test_milk_pipework_cleaning_cycles', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -2207,21 +2207,21 @@ 'unit_of_measurement': None, }) # --- -# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.milk_pipework_cleaning_cycles-state] +# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.miele_test_milk_pipework_cleaning_cycles-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Milk pipework cleaning cycles', + : 'Miele test Milk pipework cleaning cycles', : , }), 'context': , - 'entity_id': 'sensor.milk_pipework_cleaning_cycles', + 'entity_id': 'sensor.miele_test_milk_pipework_cleaning_cycles', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '3', }) # --- -# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.powerdisk_level-entry] +# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.miele_test_powerdisk_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -2235,7 +2235,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.powerdisk_level', + 'entity_id': 'sensor.miele_test_powerdisk_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -2258,21 +2258,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.powerdisk_level-state] +# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.miele_test_powerdisk_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'PowerDisk level', + : 'Miele test PowerDisk level', : '%', }), 'context': , - 'entity_id': 'sensor.powerdisk_level', + 'entity_id': 'sensor.miele_test_powerdisk_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '80.5', }) # --- -# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.rinse_aid_level-entry] +# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.miele_test_rinse_aid_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -2286,7 +2286,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.rinse_aid_level', + 'entity_id': 'sensor.miele_test_rinse_aid_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -2309,21 +2309,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.rinse_aid_level-state] +# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.miele_test_rinse_aid_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Rinse aid level', + : 'Miele test Rinse aid level', : '%', }), 'context': , - 'entity_id': 'sensor.rinse_aid_level', + 'entity_id': 'sensor.miele_test_rinse_aid_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '25', }) # --- -# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.salt_level-entry] +# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.miele_test_salt_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -2337,7 +2337,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.salt_level', + 'entity_id': 'sensor.miele_test_salt_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -2360,21 +2360,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.salt_level-state] +# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.miele_test_salt_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Salt level', + : 'Miele test Salt level', : '%', }), 'context': , - 'entity_id': 'sensor.salt_level', + 'entity_id': 'sensor.miele_test_salt_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '75', }) # --- -# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.twindos_1_level-entry] +# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.miele_test_twindos_1_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -2388,7 +2388,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.twindos_1_level', + 'entity_id': 'sensor.miele_test_twindos_1_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -2411,21 +2411,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.twindos_1_level-state] +# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.miele_test_twindos_1_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'TwinDos 1 level', + : 'Miele test TwinDos 1 level', : '%', }), 'context': , - 'entity_id': 'sensor.twindos_1_level', + 'entity_id': 'sensor.miele_test_twindos_1_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '63', }) # --- -# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.twindos_1_level_2-entry] +# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.miele_test_twindos_1_level_2-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -2439,7 +2439,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.twindos_1_level_2', + 'entity_id': 'sensor.miele_test_twindos_1_level_2', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -2462,21 +2462,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.twindos_1_level_2-state] +# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.miele_test_twindos_1_level_2-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'TwinDos 1 level', + : 'Miele test TwinDos 1 level', : '%', }), 'context': , - 'entity_id': 'sensor.twindos_1_level_2', + 'entity_id': 'sensor.miele_test_twindos_1_level_2', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '63', }) # --- -# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.twindos_2_level-entry] +# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.miele_test_twindos_2_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -2490,7 +2490,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.twindos_2_level', + 'entity_id': 'sensor.miele_test_twindos_2_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -2513,21 +2513,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.twindos_2_level-state] +# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.miele_test_twindos_2_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'TwinDos 2 level', + : 'Miele test TwinDos 2 level', : '%', }), 'context': , - 'entity_id': 'sensor.twindos_2_level', + 'entity_id': 'sensor.miele_test_twindos_2_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '20', }) # --- -# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.twindos_2_level_2-entry] +# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.miele_test_twindos_2_level_2-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -2541,7 +2541,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.twindos_2_level_2', + 'entity_id': 'sensor.miele_test_twindos_2_level_2', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -2564,21 +2564,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.twindos_2_level_2-state] +# name: test_fan_hob_sensor_states[platforms0-fan_devices.json][sensor.miele_test_twindos_2_level_2-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'TwinDos 2 level', + : 'Miele test TwinDos 2 level', : '%', }), 'context': , - 'entity_id': 'sensor.twindos_2_level_2', + 'entity_id': 'sensor.miele_test_twindos_2_level_2', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '20', }) # --- -# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.degreasing_cycles-entry] +# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.miele_test_degreasing_cycles-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -2594,7 +2594,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.degreasing_cycles', + 'entity_id': 'sensor.miele_test_degreasing_cycles', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -2617,21 +2617,21 @@ 'unit_of_measurement': None, }) # --- -# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.degreasing_cycles-state] +# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.miele_test_degreasing_cycles-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Degreasing cycles', + : 'Miele test Degreasing cycles', : , }), 'context': , - 'entity_id': 'sensor.degreasing_cycles', + 'entity_id': 'sensor.miele_test_degreasing_cycles', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '2', }) # --- -# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.descaling_cycles-entry] +# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.miele_test_descaling_cycles-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -2647,7 +2647,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.descaling_cycles', + 'entity_id': 'sensor.miele_test_descaling_cycles', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -2670,14 +2670,14 @@ 'unit_of_measurement': None, }) # --- -# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.descaling_cycles-state] +# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.miele_test_descaling_cycles-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Descaling cycles', + : 'Miele test Descaling cycles', : , }), 'context': , - 'entity_id': 'sensor.descaling_cycles', + 'entity_id': 'sensor.miele_test_descaling_cycles', 'last_changed': , 'last_reported': , 'last_updated': , @@ -3048,7 +3048,7 @@ 'state': '-18.0', }) # --- -# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.milk_pipework_cleaning_cycles-entry] +# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.miele_test_milk_pipework_cleaning_cycles-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -3064,7 +3064,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.milk_pipework_cleaning_cycles', + 'entity_id': 'sensor.miele_test_milk_pipework_cleaning_cycles', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -3087,21 +3087,21 @@ 'unit_of_measurement': None, }) # --- -# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.milk_pipework_cleaning_cycles-state] +# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.miele_test_milk_pipework_cleaning_cycles-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Milk pipework cleaning cycles', + : 'Miele test Milk pipework cleaning cycles', : , }), 'context': , - 'entity_id': 'sensor.milk_pipework_cleaning_cycles', + 'entity_id': 'sensor.miele_test_milk_pipework_cleaning_cycles', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '3', }) # --- -# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.powerdisk_level-entry] +# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.miele_test_powerdisk_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -3115,7 +3115,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.powerdisk_level', + 'entity_id': 'sensor.miele_test_powerdisk_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -3138,21 +3138,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.powerdisk_level-state] +# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.miele_test_powerdisk_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'PowerDisk level', + : 'Miele test PowerDisk level', : '%', }), 'context': , - 'entity_id': 'sensor.powerdisk_level', + 'entity_id': 'sensor.miele_test_powerdisk_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '80.5', }) # --- -# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.rinse_aid_level-entry] +# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.miele_test_rinse_aid_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -3166,7 +3166,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.rinse_aid_level', + 'entity_id': 'sensor.miele_test_rinse_aid_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -3189,21 +3189,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.rinse_aid_level-state] +# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.miele_test_rinse_aid_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Rinse aid level', + : 'Miele test Rinse aid level', : '%', }), 'context': , - 'entity_id': 'sensor.rinse_aid_level', + 'entity_id': 'sensor.miele_test_rinse_aid_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '25', }) # --- -# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.salt_level-entry] +# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.miele_test_salt_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -3217,7 +3217,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.salt_level', + 'entity_id': 'sensor.miele_test_salt_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -3240,21 +3240,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.salt_level-state] +# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.miele_test_salt_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Salt level', + : 'Miele test Salt level', : '%', }), 'context': , - 'entity_id': 'sensor.salt_level', + 'entity_id': 'sensor.miele_test_salt_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '75', }) # --- -# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.twindos_1_level-entry] +# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.miele_test_twindos_1_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -3268,7 +3268,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.twindos_1_level', + 'entity_id': 'sensor.miele_test_twindos_1_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -3291,21 +3291,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.twindos_1_level-state] +# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.miele_test_twindos_1_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'TwinDos 1 level', + : 'Miele test TwinDos 1 level', : '%', }), 'context': , - 'entity_id': 'sensor.twindos_1_level', + 'entity_id': 'sensor.miele_test_twindos_1_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '63', }) # --- -# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.twindos_1_level_2-entry] +# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.miele_test_twindos_1_level_2-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -3319,7 +3319,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.twindos_1_level_2', + 'entity_id': 'sensor.miele_test_twindos_1_level_2', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -3342,21 +3342,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.twindos_1_level_2-state] +# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.miele_test_twindos_1_level_2-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'TwinDos 1 level', + : 'Miele test TwinDos 1 level', : '%', }), 'context': , - 'entity_id': 'sensor.twindos_1_level_2', + 'entity_id': 'sensor.miele_test_twindos_1_level_2', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '63', }) # --- -# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.twindos_2_level-entry] +# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.miele_test_twindos_2_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -3370,7 +3370,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.twindos_2_level', + 'entity_id': 'sensor.miele_test_twindos_2_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -3393,21 +3393,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.twindos_2_level-state] +# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.miele_test_twindos_2_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'TwinDos 2 level', + : 'Miele test TwinDos 2 level', : '%', }), 'context': , - 'entity_id': 'sensor.twindos_2_level', + 'entity_id': 'sensor.miele_test_twindos_2_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '20', }) # --- -# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.twindos_2_level_2-entry] +# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.miele_test_twindos_2_level_2-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -3421,7 +3421,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.twindos_2_level_2', + 'entity_id': 'sensor.miele_test_twindos_2_level_2', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -3444,21 +3444,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.twindos_2_level_2-state] +# name: test_fridge_freezer_sensor_states[platforms0-fridge_freezer.json][sensor.miele_test_twindos_2_level_2-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'TwinDos 2 level', + : 'Miele test TwinDos 2 level', : '%', }), 'context': , - 'entity_id': 'sensor.twindos_2_level_2', + 'entity_id': 'sensor.miele_test_twindos_2_level_2', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '20', }) # --- -# name: test_hob_sensor_states[platforms0-hob.json][sensor.degreasing_cycles-entry] +# name: test_hob_sensor_states[platforms0-hob.json][sensor.miele_test_degreasing_cycles-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -3474,7 +3474,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.degreasing_cycles', + 'entity_id': 'sensor.miele_test_degreasing_cycles', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -3497,21 +3497,21 @@ 'unit_of_measurement': None, }) # --- -# name: test_hob_sensor_states[platforms0-hob.json][sensor.degreasing_cycles-state] +# name: test_hob_sensor_states[platforms0-hob.json][sensor.miele_test_degreasing_cycles-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Degreasing cycles', + : 'Miele test Degreasing cycles', : , }), 'context': , - 'entity_id': 'sensor.degreasing_cycles', + 'entity_id': 'sensor.miele_test_degreasing_cycles', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '2', }) # --- -# name: test_hob_sensor_states[platforms0-hob.json][sensor.descaling_cycles-entry] +# name: test_hob_sensor_states[platforms0-hob.json][sensor.miele_test_descaling_cycles-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -3527,7 +3527,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.descaling_cycles', + 'entity_id': 'sensor.miele_test_descaling_cycles', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -3550,14 +3550,14 @@ 'unit_of_measurement': None, }) # --- -# name: test_hob_sensor_states[platforms0-hob.json][sensor.descaling_cycles-state] +# name: test_hob_sensor_states[platforms0-hob.json][sensor.miele_test_descaling_cycles-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Descaling cycles', + : 'Miele test Descaling cycles', : , }), 'context': , - 'entity_id': 'sensor.descaling_cycles', + 'entity_id': 'sensor.miele_test_descaling_cycles', 'last_changed': , 'last_reported': , 'last_updated': , @@ -4159,7 +4159,7 @@ 'state': 'plate_step_boost', }) # --- -# name: test_hob_sensor_states[platforms0-hob.json][sensor.milk_pipework_cleaning_cycles-entry] +# name: test_hob_sensor_states[platforms0-hob.json][sensor.miele_test_milk_pipework_cleaning_cycles-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -4175,7 +4175,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.milk_pipework_cleaning_cycles', + 'entity_id': 'sensor.miele_test_milk_pipework_cleaning_cycles', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -4198,21 +4198,21 @@ 'unit_of_measurement': None, }) # --- -# name: test_hob_sensor_states[platforms0-hob.json][sensor.milk_pipework_cleaning_cycles-state] +# name: test_hob_sensor_states[platforms0-hob.json][sensor.miele_test_milk_pipework_cleaning_cycles-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Milk pipework cleaning cycles', + : 'Miele test Milk pipework cleaning cycles', : , }), 'context': , - 'entity_id': 'sensor.milk_pipework_cleaning_cycles', + 'entity_id': 'sensor.miele_test_milk_pipework_cleaning_cycles', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '3', }) # --- -# name: test_hob_sensor_states[platforms0-hob.json][sensor.powerdisk_level-entry] +# name: test_hob_sensor_states[platforms0-hob.json][sensor.miele_test_powerdisk_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -4226,7 +4226,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.powerdisk_level', + 'entity_id': 'sensor.miele_test_powerdisk_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -4249,21 +4249,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_hob_sensor_states[platforms0-hob.json][sensor.powerdisk_level-state] +# name: test_hob_sensor_states[platforms0-hob.json][sensor.miele_test_powerdisk_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'PowerDisk level', + : 'Miele test PowerDisk level', : '%', }), 'context': , - 'entity_id': 'sensor.powerdisk_level', + 'entity_id': 'sensor.miele_test_powerdisk_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '80.5', }) # --- -# name: test_hob_sensor_states[platforms0-hob.json][sensor.rinse_aid_level-entry] +# name: test_hob_sensor_states[platforms0-hob.json][sensor.miele_test_rinse_aid_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -4277,7 +4277,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.rinse_aid_level', + 'entity_id': 'sensor.miele_test_rinse_aid_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -4300,21 +4300,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_hob_sensor_states[platforms0-hob.json][sensor.rinse_aid_level-state] +# name: test_hob_sensor_states[platforms0-hob.json][sensor.miele_test_rinse_aid_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Rinse aid level', + : 'Miele test Rinse aid level', : '%', }), 'context': , - 'entity_id': 'sensor.rinse_aid_level', + 'entity_id': 'sensor.miele_test_rinse_aid_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '25', }) # --- -# name: test_hob_sensor_states[platforms0-hob.json][sensor.salt_level-entry] +# name: test_hob_sensor_states[platforms0-hob.json][sensor.miele_test_salt_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -4328,7 +4328,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.salt_level', + 'entity_id': 'sensor.miele_test_salt_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -4351,21 +4351,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_hob_sensor_states[platforms0-hob.json][sensor.salt_level-state] +# name: test_hob_sensor_states[platforms0-hob.json][sensor.miele_test_salt_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Salt level', + : 'Miele test Salt level', : '%', }), 'context': , - 'entity_id': 'sensor.salt_level', + 'entity_id': 'sensor.miele_test_salt_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '75', }) # --- -# name: test_hob_sensor_states[platforms0-hob.json][sensor.twindos_1_level-entry] +# name: test_hob_sensor_states[platforms0-hob.json][sensor.miele_test_twindos_1_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -4379,7 +4379,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.twindos_1_level', + 'entity_id': 'sensor.miele_test_twindos_1_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -4402,21 +4402,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_hob_sensor_states[platforms0-hob.json][sensor.twindos_1_level-state] +# name: test_hob_sensor_states[platforms0-hob.json][sensor.miele_test_twindos_1_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'TwinDos 1 level', + : 'Miele test TwinDos 1 level', : '%', }), 'context': , - 'entity_id': 'sensor.twindos_1_level', + 'entity_id': 'sensor.miele_test_twindos_1_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '63', }) # --- -# name: test_hob_sensor_states[platforms0-hob.json][sensor.twindos_1_level_2-entry] +# name: test_hob_sensor_states[platforms0-hob.json][sensor.miele_test_twindos_1_level_2-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -4430,7 +4430,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.twindos_1_level_2', + 'entity_id': 'sensor.miele_test_twindos_1_level_2', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -4453,21 +4453,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_hob_sensor_states[platforms0-hob.json][sensor.twindos_1_level_2-state] +# name: test_hob_sensor_states[platforms0-hob.json][sensor.miele_test_twindos_1_level_2-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'TwinDos 1 level', + : 'Miele test TwinDos 1 level', : '%', }), 'context': , - 'entity_id': 'sensor.twindos_1_level_2', + 'entity_id': 'sensor.miele_test_twindos_1_level_2', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '63', }) # --- -# name: test_hob_sensor_states[platforms0-hob.json][sensor.twindos_2_level-entry] +# name: test_hob_sensor_states[platforms0-hob.json][sensor.miele_test_twindos_2_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -4481,7 +4481,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.twindos_2_level', + 'entity_id': 'sensor.miele_test_twindos_2_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -4504,21 +4504,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_hob_sensor_states[platforms0-hob.json][sensor.twindos_2_level-state] +# name: test_hob_sensor_states[platforms0-hob.json][sensor.miele_test_twindos_2_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'TwinDos 2 level', + : 'Miele test TwinDos 2 level', : '%', }), 'context': , - 'entity_id': 'sensor.twindos_2_level', + 'entity_id': 'sensor.miele_test_twindos_2_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '20', }) # --- -# name: test_hob_sensor_states[platforms0-hob.json][sensor.twindos_2_level_2-entry] +# name: test_hob_sensor_states[platforms0-hob.json][sensor.miele_test_twindos_2_level_2-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -4532,7 +4532,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.twindos_2_level_2', + 'entity_id': 'sensor.miele_test_twindos_2_level_2', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -4555,21 +4555,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_hob_sensor_states[platforms0-hob.json][sensor.twindos_2_level_2-state] +# name: test_hob_sensor_states[platforms0-hob.json][sensor.miele_test_twindos_2_level_2-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'TwinDos 2 level', + : 'Miele test TwinDos 2 level', : '%', }), 'context': , - 'entity_id': 'sensor.twindos_2_level_2', + 'entity_id': 'sensor.miele_test_twindos_2_level_2', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '20', }) # --- -# name: test_sensor_states[platforms0][sensor.degreasing_cycles-entry] +# name: test_sensor_states[platforms0][sensor.miele_test_degreasing_cycles-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -4585,7 +4585,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.degreasing_cycles', + 'entity_id': 'sensor.miele_test_degreasing_cycles', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -4608,21 +4608,21 @@ 'unit_of_measurement': None, }) # --- -# name: test_sensor_states[platforms0][sensor.degreasing_cycles-state] +# name: test_sensor_states[platforms0][sensor.miele_test_degreasing_cycles-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Degreasing cycles', + : 'Miele test Degreasing cycles', : , }), 'context': , - 'entity_id': 'sensor.degreasing_cycles', + 'entity_id': 'sensor.miele_test_degreasing_cycles', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '2', }) # --- -# name: test_sensor_states[platforms0][sensor.descaling_cycles-entry] +# name: test_sensor_states[platforms0][sensor.miele_test_descaling_cycles-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -4638,7 +4638,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.descaling_cycles', + 'entity_id': 'sensor.miele_test_descaling_cycles', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -4661,14 +4661,14 @@ 'unit_of_measurement': None, }) # --- -# name: test_sensor_states[platforms0][sensor.descaling_cycles-state] +# name: test_sensor_states[platforms0][sensor.miele_test_descaling_cycles-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Descaling cycles', + : 'Miele test Descaling cycles', : , }), 'context': , - 'entity_id': 'sensor.descaling_cycles', + 'entity_id': 'sensor.miele_test_descaling_cycles', 'last_changed': , 'last_reported': , 'last_updated': , @@ -4923,7 +4923,7 @@ 'state': 'off', }) # --- -# name: test_sensor_states[platforms0][sensor.milk_pipework_cleaning_cycles-entry] +# name: test_sensor_states[platforms0][sensor.miele_test_milk_pipework_cleaning_cycles-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -4939,7 +4939,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.milk_pipework_cleaning_cycles', + 'entity_id': 'sensor.miele_test_milk_pipework_cleaning_cycles', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -4962,14 +4962,14 @@ 'unit_of_measurement': None, }) # --- -# name: test_sensor_states[platforms0][sensor.milk_pipework_cleaning_cycles-state] +# name: test_sensor_states[platforms0][sensor.miele_test_milk_pipework_cleaning_cycles-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Milk pipework cleaning cycles', + : 'Miele test Milk pipework cleaning cycles', : , }), 'context': , - 'entity_id': 'sensor.milk_pipework_cleaning_cycles', + 'entity_id': 'sensor.miele_test_milk_pipework_cleaning_cycles', 'last_changed': , 'last_reported': , 'last_updated': , @@ -6863,7 +6863,7 @@ 'state': '19.54', }) # --- -# name: test_sensor_states[platforms0][sensor.powerdisk_level-entry] +# name: test_sensor_states[platforms0][sensor.miele_test_powerdisk_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -6877,7 +6877,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.powerdisk_level', + 'entity_id': 'sensor.miele_test_powerdisk_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -6900,14 +6900,14 @@ 'unit_of_measurement': '%', }) # --- -# name: test_sensor_states[platforms0][sensor.powerdisk_level-state] +# name: test_sensor_states[platforms0][sensor.miele_test_powerdisk_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'PowerDisk level', + : 'Miele test PowerDisk level', : '%', }), 'context': , - 'entity_id': 'sensor.powerdisk_level', + 'entity_id': 'sensor.miele_test_powerdisk_level', 'last_changed': , 'last_reported': , 'last_updated': , @@ -7067,7 +7067,7 @@ 'state': '4.0', }) # --- -# name: test_sensor_states[platforms0][sensor.rinse_aid_level-entry] +# name: test_sensor_states[platforms0][sensor.miele_test_rinse_aid_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -7081,7 +7081,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.rinse_aid_level', + 'entity_id': 'sensor.miele_test_rinse_aid_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -7104,21 +7104,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_sensor_states[platforms0][sensor.rinse_aid_level-state] +# name: test_sensor_states[platforms0][sensor.miele_test_rinse_aid_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Rinse aid level', + : 'Miele test Rinse aid level', : '%', }), 'context': , - 'entity_id': 'sensor.rinse_aid_level', + 'entity_id': 'sensor.miele_test_rinse_aid_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '25', }) # --- -# name: test_sensor_states[platforms0][sensor.salt_level-entry] +# name: test_sensor_states[platforms0][sensor.miele_test_salt_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -7132,7 +7132,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.salt_level', + 'entity_id': 'sensor.miele_test_salt_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -7155,21 +7155,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_sensor_states[platforms0][sensor.salt_level-state] +# name: test_sensor_states[platforms0][sensor.miele_test_salt_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Salt level', + : 'Miele test Salt level', : '%', }), 'context': , - 'entity_id': 'sensor.salt_level', + 'entity_id': 'sensor.miele_test_salt_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '75', }) # --- -# name: test_sensor_states[platforms0][sensor.twindos_1_level-entry] +# name: test_sensor_states[platforms0][sensor.miele_test_twindos_1_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -7183,7 +7183,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.twindos_1_level', + 'entity_id': 'sensor.miele_test_twindos_1_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -7206,21 +7206,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_sensor_states[platforms0][sensor.twindos_1_level-state] +# name: test_sensor_states[platforms0][sensor.miele_test_twindos_1_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'TwinDos 1 level', + : 'Miele test TwinDos 1 level', : '%', }), 'context': , - 'entity_id': 'sensor.twindos_1_level', + 'entity_id': 'sensor.miele_test_twindos_1_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '63', }) # --- -# name: test_sensor_states[platforms0][sensor.twindos_2_level-entry] +# name: test_sensor_states[platforms0][sensor.miele_test_twindos_2_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -7234,7 +7234,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.twindos_2_level', + 'entity_id': 'sensor.miele_test_twindos_2_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -7257,14 +7257,14 @@ 'unit_of_measurement': '%', }) # --- -# name: test_sensor_states[platforms0][sensor.twindos_2_level-state] +# name: test_sensor_states[platforms0][sensor.miele_test_twindos_2_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'TwinDos 2 level', + : 'Miele test TwinDos 2 level', : '%', }), 'context': , - 'entity_id': 'sensor.twindos_2_level', + 'entity_id': 'sensor.miele_test_twindos_2_level', 'last_changed': , 'last_reported': , 'last_updated': , @@ -8383,7 +8383,7 @@ 'state': '0.0', }) # --- -# name: test_sensor_states_api_push[platforms0][sensor.degreasing_cycles-entry] +# name: test_sensor_states_api_push[platforms0][sensor.miele_test_degreasing_cycles-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -8399,7 +8399,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.degreasing_cycles', + 'entity_id': 'sensor.miele_test_degreasing_cycles', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -8422,21 +8422,21 @@ 'unit_of_measurement': None, }) # --- -# name: test_sensor_states_api_push[platforms0][sensor.degreasing_cycles-state] +# name: test_sensor_states_api_push[platforms0][sensor.miele_test_degreasing_cycles-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Degreasing cycles', + : 'Miele test Degreasing cycles', : , }), 'context': , - 'entity_id': 'sensor.degreasing_cycles', + 'entity_id': 'sensor.miele_test_degreasing_cycles', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '2', }) # --- -# name: test_sensor_states_api_push[platforms0][sensor.descaling_cycles-entry] +# name: test_sensor_states_api_push[platforms0][sensor.miele_test_descaling_cycles-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -8452,7 +8452,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.descaling_cycles', + 'entity_id': 'sensor.miele_test_descaling_cycles', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -8475,14 +8475,14 @@ 'unit_of_measurement': None, }) # --- -# name: test_sensor_states_api_push[platforms0][sensor.descaling_cycles-state] +# name: test_sensor_states_api_push[platforms0][sensor.miele_test_descaling_cycles-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Descaling cycles', + : 'Miele test Descaling cycles', : , }), 'context': , - 'entity_id': 'sensor.descaling_cycles', + 'entity_id': 'sensor.miele_test_descaling_cycles', 'last_changed': , 'last_reported': , 'last_updated': , @@ -8737,7 +8737,7 @@ 'state': 'off', }) # --- -# name: test_sensor_states_api_push[platforms0][sensor.milk_pipework_cleaning_cycles-entry] +# name: test_sensor_states_api_push[platforms0][sensor.miele_test_milk_pipework_cleaning_cycles-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -8753,7 +8753,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.milk_pipework_cleaning_cycles', + 'entity_id': 'sensor.miele_test_milk_pipework_cleaning_cycles', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -8776,14 +8776,14 @@ 'unit_of_measurement': None, }) # --- -# name: test_sensor_states_api_push[platforms0][sensor.milk_pipework_cleaning_cycles-state] +# name: test_sensor_states_api_push[platforms0][sensor.miele_test_milk_pipework_cleaning_cycles-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Milk pipework cleaning cycles', + : 'Miele test Milk pipework cleaning cycles', : , }), 'context': , - 'entity_id': 'sensor.milk_pipework_cleaning_cycles', + 'entity_id': 'sensor.miele_test_milk_pipework_cleaning_cycles', 'last_changed': , 'last_reported': , 'last_updated': , @@ -10677,7 +10677,7 @@ 'state': '19.54', }) # --- -# name: test_sensor_states_api_push[platforms0][sensor.powerdisk_level-entry] +# name: test_sensor_states_api_push[platforms0][sensor.miele_test_powerdisk_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -10691,7 +10691,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.powerdisk_level', + 'entity_id': 'sensor.miele_test_powerdisk_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -10714,14 +10714,14 @@ 'unit_of_measurement': '%', }) # --- -# name: test_sensor_states_api_push[platforms0][sensor.powerdisk_level-state] +# name: test_sensor_states_api_push[platforms0][sensor.miele_test_powerdisk_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'PowerDisk level', + : 'Miele test PowerDisk level', : '%', }), 'context': , - 'entity_id': 'sensor.powerdisk_level', + 'entity_id': 'sensor.miele_test_powerdisk_level', 'last_changed': , 'last_reported': , 'last_updated': , @@ -10881,7 +10881,7 @@ 'state': '4.0', }) # --- -# name: test_sensor_states_api_push[platforms0][sensor.rinse_aid_level-entry] +# name: test_sensor_states_api_push[platforms0][sensor.miele_test_rinse_aid_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -10895,7 +10895,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.rinse_aid_level', + 'entity_id': 'sensor.miele_test_rinse_aid_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -10918,21 +10918,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_sensor_states_api_push[platforms0][sensor.rinse_aid_level-state] +# name: test_sensor_states_api_push[platforms0][sensor.miele_test_rinse_aid_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Rinse aid level', + : 'Miele test Rinse aid level', : '%', }), 'context': , - 'entity_id': 'sensor.rinse_aid_level', + 'entity_id': 'sensor.miele_test_rinse_aid_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '25', }) # --- -# name: test_sensor_states_api_push[platforms0][sensor.salt_level-entry] +# name: test_sensor_states_api_push[platforms0][sensor.miele_test_salt_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -10946,7 +10946,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.salt_level', + 'entity_id': 'sensor.miele_test_salt_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -10969,21 +10969,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_sensor_states_api_push[platforms0][sensor.salt_level-state] +# name: test_sensor_states_api_push[platforms0][sensor.miele_test_salt_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Salt level', + : 'Miele test Salt level', : '%', }), 'context': , - 'entity_id': 'sensor.salt_level', + 'entity_id': 'sensor.miele_test_salt_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '75', }) # --- -# name: test_sensor_states_api_push[platforms0][sensor.twindos_1_level-entry] +# name: test_sensor_states_api_push[platforms0][sensor.miele_test_twindos_1_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -10997,7 +10997,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.twindos_1_level', + 'entity_id': 'sensor.miele_test_twindos_1_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -11020,21 +11020,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_sensor_states_api_push[platforms0][sensor.twindos_1_level-state] +# name: test_sensor_states_api_push[platforms0][sensor.miele_test_twindos_1_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'TwinDos 1 level', + : 'Miele test TwinDos 1 level', : '%', }), 'context': , - 'entity_id': 'sensor.twindos_1_level', + 'entity_id': 'sensor.miele_test_twindos_1_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '63', }) # --- -# name: test_sensor_states_api_push[platforms0][sensor.twindos_2_level-entry] +# name: test_sensor_states_api_push[platforms0][sensor.miele_test_twindos_2_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -11048,7 +11048,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.twindos_2_level', + 'entity_id': 'sensor.miele_test_twindos_2_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -11071,14 +11071,14 @@ 'unit_of_measurement': '%', }) # --- -# name: test_sensor_states_api_push[platforms0][sensor.twindos_2_level-state] +# name: test_sensor_states_api_push[platforms0][sensor.miele_test_twindos_2_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'TwinDos 2 level', + : 'Miele test TwinDos 2 level', : '%', }), 'context': , - 'entity_id': 'sensor.twindos_2_level', + 'entity_id': 'sensor.miele_test_twindos_2_level', 'last_changed': , 'last_reported': , 'last_updated': , @@ -12197,7 +12197,7 @@ 'state': '0.0', }) # --- -# name: test_sensor_states_api_push_one_device[platforms0][sensor.degreasing_cycles-entry] +# name: test_sensor_states_api_push_one_device[platforms0][sensor.miele_test_degreasing_cycles-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -12213,7 +12213,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.degreasing_cycles', + 'entity_id': 'sensor.miele_test_degreasing_cycles', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -12236,21 +12236,21 @@ 'unit_of_measurement': None, }) # --- -# name: test_sensor_states_api_push_one_device[platforms0][sensor.degreasing_cycles-state] +# name: test_sensor_states_api_push_one_device[platforms0][sensor.miele_test_degreasing_cycles-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Degreasing cycles', + : 'Miele test Degreasing cycles', : , }), 'context': , - 'entity_id': 'sensor.degreasing_cycles', + 'entity_id': 'sensor.miele_test_degreasing_cycles', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '2', }) # --- -# name: test_sensor_states_api_push_one_device[platforms0][sensor.descaling_cycles-entry] +# name: test_sensor_states_api_push_one_device[platforms0][sensor.miele_test_descaling_cycles-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -12266,7 +12266,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.descaling_cycles', + 'entity_id': 'sensor.miele_test_descaling_cycles', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -12289,14 +12289,14 @@ 'unit_of_measurement': None, }) # --- -# name: test_sensor_states_api_push_one_device[platforms0][sensor.descaling_cycles-state] +# name: test_sensor_states_api_push_one_device[platforms0][sensor.miele_test_descaling_cycles-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Descaling cycles', + : 'Miele test Descaling cycles', : , }), 'context': , - 'entity_id': 'sensor.descaling_cycles', + 'entity_id': 'sensor.miele_test_descaling_cycles', 'last_changed': , 'last_reported': , 'last_updated': , @@ -12551,7 +12551,7 @@ 'state': 'off', }) # --- -# name: test_sensor_states_api_push_one_device[platforms0][sensor.milk_pipework_cleaning_cycles-entry] +# name: test_sensor_states_api_push_one_device[platforms0][sensor.miele_test_milk_pipework_cleaning_cycles-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -12567,7 +12567,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.milk_pipework_cleaning_cycles', + 'entity_id': 'sensor.miele_test_milk_pipework_cleaning_cycles', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -12590,14 +12590,14 @@ 'unit_of_measurement': None, }) # --- -# name: test_sensor_states_api_push_one_device[platforms0][sensor.milk_pipework_cleaning_cycles-state] +# name: test_sensor_states_api_push_one_device[platforms0][sensor.miele_test_milk_pipework_cleaning_cycles-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Milk pipework cleaning cycles', + : 'Miele test Milk pipework cleaning cycles', : , }), 'context': , - 'entity_id': 'sensor.milk_pipework_cleaning_cycles', + 'entity_id': 'sensor.miele_test_milk_pipework_cleaning_cycles', 'last_changed': , 'last_reported': , 'last_updated': , @@ -14491,7 +14491,7 @@ 'state': '19.54', }) # --- -# name: test_sensor_states_api_push_one_device[platforms0][sensor.powerdisk_level-entry] +# name: test_sensor_states_api_push_one_device[platforms0][sensor.miele_test_powerdisk_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -14505,7 +14505,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.powerdisk_level', + 'entity_id': 'sensor.miele_test_powerdisk_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -14528,14 +14528,14 @@ 'unit_of_measurement': '%', }) # --- -# name: test_sensor_states_api_push_one_device[platforms0][sensor.powerdisk_level-state] +# name: test_sensor_states_api_push_one_device[platforms0][sensor.miele_test_powerdisk_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'PowerDisk level', + : 'Miele test PowerDisk level', : '%', }), 'context': , - 'entity_id': 'sensor.powerdisk_level', + 'entity_id': 'sensor.miele_test_powerdisk_level', 'last_changed': , 'last_reported': , 'last_updated': , @@ -14695,7 +14695,7 @@ 'state': '4.0', }) # --- -# name: test_sensor_states_api_push_one_device[platforms0][sensor.rinse_aid_level-entry] +# name: test_sensor_states_api_push_one_device[platforms0][sensor.miele_test_rinse_aid_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -14709,7 +14709,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.rinse_aid_level', + 'entity_id': 'sensor.miele_test_rinse_aid_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -14732,21 +14732,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_sensor_states_api_push_one_device[platforms0][sensor.rinse_aid_level-state] +# name: test_sensor_states_api_push_one_device[platforms0][sensor.miele_test_rinse_aid_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Rinse aid level', + : 'Miele test Rinse aid level', : '%', }), 'context': , - 'entity_id': 'sensor.rinse_aid_level', + 'entity_id': 'sensor.miele_test_rinse_aid_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '25', }) # --- -# name: test_sensor_states_api_push_one_device[platforms0][sensor.salt_level-entry] +# name: test_sensor_states_api_push_one_device[platforms0][sensor.miele_test_salt_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -14760,7 +14760,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.salt_level', + 'entity_id': 'sensor.miele_test_salt_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -14783,21 +14783,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_sensor_states_api_push_one_device[platforms0][sensor.salt_level-state] +# name: test_sensor_states_api_push_one_device[platforms0][sensor.miele_test_salt_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Salt level', + : 'Miele test Salt level', : '%', }), 'context': , - 'entity_id': 'sensor.salt_level', + 'entity_id': 'sensor.miele_test_salt_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '75', }) # --- -# name: test_sensor_states_api_push_one_device[platforms0][sensor.twindos_1_level-entry] +# name: test_sensor_states_api_push_one_device[platforms0][sensor.miele_test_twindos_1_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -14811,7 +14811,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.twindos_1_level', + 'entity_id': 'sensor.miele_test_twindos_1_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -14834,21 +14834,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_sensor_states_api_push_one_device[platforms0][sensor.twindos_1_level-state] +# name: test_sensor_states_api_push_one_device[platforms0][sensor.miele_test_twindos_1_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'TwinDos 1 level', + : 'Miele test TwinDos 1 level', : '%', }), 'context': , - 'entity_id': 'sensor.twindos_1_level', + 'entity_id': 'sensor.miele_test_twindos_1_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '63', }) # --- -# name: test_sensor_states_api_push_one_device[platforms0][sensor.twindos_2_level-entry] +# name: test_sensor_states_api_push_one_device[platforms0][sensor.miele_test_twindos_2_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -14862,7 +14862,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.twindos_2_level', + 'entity_id': 'sensor.miele_test_twindos_2_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -14885,14 +14885,14 @@ 'unit_of_measurement': '%', }) # --- -# name: test_sensor_states_api_push_one_device[platforms0][sensor.twindos_2_level-state] +# name: test_sensor_states_api_push_one_device[platforms0][sensor.miele_test_twindos_2_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'TwinDos 2 level', + : 'Miele test TwinDos 2 level', : '%', }), 'context': , - 'entity_id': 'sensor.twindos_2_level', + 'entity_id': 'sensor.miele_test_twindos_2_level', 'last_changed': , 'last_reported': , 'last_updated': , @@ -16011,7 +16011,7 @@ 'state': '0.0', }) # --- -# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.degreasing_cycles-entry] +# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.miele_test_degreasing_cycles-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -16027,7 +16027,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.degreasing_cycles', + 'entity_id': 'sensor.miele_test_degreasing_cycles', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -16050,21 +16050,21 @@ 'unit_of_measurement': None, }) # --- -# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.degreasing_cycles-state] +# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.miele_test_degreasing_cycles-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Degreasing cycles', + : 'Miele test Degreasing cycles', : , }), 'context': , - 'entity_id': 'sensor.degreasing_cycles', + 'entity_id': 'sensor.miele_test_degreasing_cycles', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '2', }) # --- -# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.descaling_cycles-entry] +# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.miele_test_descaling_cycles-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -16080,7 +16080,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.descaling_cycles', + 'entity_id': 'sensor.miele_test_descaling_cycles', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -16103,21 +16103,21 @@ 'unit_of_measurement': None, }) # --- -# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.descaling_cycles-state] +# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.miele_test_descaling_cycles-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Descaling cycles', + : 'Miele test Descaling cycles', : , }), 'context': , - 'entity_id': 'sensor.descaling_cycles', + 'entity_id': 'sensor.miele_test_descaling_cycles', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '1', }) # --- -# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.milk_pipework_cleaning_cycles-entry] +# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.miele_test_milk_pipework_cleaning_cycles-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -16133,7 +16133,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.milk_pipework_cleaning_cycles', + 'entity_id': 'sensor.miele_test_milk_pipework_cleaning_cycles', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -16156,21 +16156,21 @@ 'unit_of_measurement': None, }) # --- -# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.milk_pipework_cleaning_cycles-state] +# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.miele_test_milk_pipework_cleaning_cycles-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Milk pipework cleaning cycles', + : 'Miele test Milk pipework cleaning cycles', : , }), 'context': , - 'entity_id': 'sensor.milk_pipework_cleaning_cycles', + 'entity_id': 'sensor.miele_test_milk_pipework_cleaning_cycles', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '3', }) # --- -# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.powerdisk_level-entry] +# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.miele_test_powerdisk_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -16184,7 +16184,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.powerdisk_level', + 'entity_id': 'sensor.miele_test_powerdisk_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -16207,21 +16207,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.powerdisk_level-state] +# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.miele_test_powerdisk_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'PowerDisk level', + : 'Miele test PowerDisk level', : '%', }), 'context': , - 'entity_id': 'sensor.powerdisk_level', + 'entity_id': 'sensor.miele_test_powerdisk_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '80.5', }) # --- -# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.rinse_aid_level-entry] +# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.miele_test_rinse_aid_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -16235,7 +16235,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.rinse_aid_level', + 'entity_id': 'sensor.miele_test_rinse_aid_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -16258,14 +16258,14 @@ 'unit_of_measurement': '%', }) # --- -# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.rinse_aid_level-state] +# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.miele_test_rinse_aid_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Rinse aid level', + : 'Miele test Rinse aid level', : '%', }), 'context': , - 'entity_id': 'sensor.rinse_aid_level', + 'entity_id': 'sensor.miele_test_rinse_aid_level', 'last_changed': , 'last_reported': , 'last_updated': , @@ -16761,7 +16761,7 @@ 'state': 'unknown', }) # --- -# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.salt_level-entry] +# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.miele_test_salt_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -16775,7 +16775,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.salt_level', + 'entity_id': 'sensor.miele_test_salt_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -16798,21 +16798,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.salt_level-state] +# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.miele_test_salt_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Salt level', + : 'Miele test Salt level', : '%', }), 'context': , - 'entity_id': 'sensor.salt_level', + 'entity_id': 'sensor.miele_test_salt_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '75', }) # --- -# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.twindos_1_level-entry] +# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.miele_test_twindos_1_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -16826,7 +16826,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.twindos_1_level', + 'entity_id': 'sensor.miele_test_twindos_1_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -16849,21 +16849,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.twindos_1_level-state] +# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.miele_test_twindos_1_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'TwinDos 1 level', + : 'Miele test TwinDos 1 level', : '%', }), 'context': , - 'entity_id': 'sensor.twindos_1_level', + 'entity_id': 'sensor.miele_test_twindos_1_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '63', }) # --- -# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.twindos_1_level_2-entry] +# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.miele_test_twindos_1_level_2-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -16877,7 +16877,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.twindos_1_level_2', + 'entity_id': 'sensor.miele_test_twindos_1_level_2', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -16900,21 +16900,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.twindos_1_level_2-state] +# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.miele_test_twindos_1_level_2-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'TwinDos 1 level', + : 'Miele test TwinDos 1 level', : '%', }), 'context': , - 'entity_id': 'sensor.twindos_1_level_2', + 'entity_id': 'sensor.miele_test_twindos_1_level_2', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '63', }) # --- -# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.twindos_2_level-entry] +# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.miele_test_twindos_2_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -16928,7 +16928,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.twindos_2_level', + 'entity_id': 'sensor.miele_test_twindos_2_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -16951,21 +16951,21 @@ 'unit_of_measurement': '%', }) # --- -# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.twindos_2_level-state] +# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.miele_test_twindos_2_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'TwinDos 2 level', + : 'Miele test TwinDos 2 level', : '%', }), 'context': , - 'entity_id': 'sensor.twindos_2_level', + 'entity_id': 'sensor.miele_test_twindos_2_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '20', }) # --- -# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.twindos_2_level_2-entry] +# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.miele_test_twindos_2_level_2-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -16979,7 +16979,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.twindos_2_level_2', + 'entity_id': 'sensor.miele_test_twindos_2_level_2', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -17002,14 +17002,14 @@ 'unit_of_measurement': '%', }) # --- -# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.twindos_2_level_2-state] +# name: test_vacuum_sensor_states[platforms0-vacuum_device.json][sensor.miele_test_twindos_2_level_2-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'TwinDos 2 level', + : 'Miele test TwinDos 2 level', : '%', }), 'context': , - 'entity_id': 'sensor.twindos_2_level_2', + 'entity_id': 'sensor.miele_test_twindos_2_level_2', 'last_changed': , 'last_reported': , 'last_updated': , diff --git a/tests/components/mold_indicator/test_init.py b/tests/components/mold_indicator/test_init.py index e87fc42145b3f..8d77547e7f26c 100644 --- a/tests/components/mold_indicator/test_init.py +++ b/tests/components/mold_indicator/test_init.py @@ -196,9 +196,9 @@ async def test_unload_entry(hass: HomeAssistant, loaded_entry: MockConfigEntry) @pytest.mark.parametrize( ("source_entity_id", "expected_helper_device_id", "expected_events"), [ - ("sensor.test_unique_indoor_humidity", None, ["update"]), - ("sensor.test_unique_indoor_temperature", "humidity_device_id", []), - ("sensor.test_unique_outdoor_temperature", "humidity_device_id", []), + ("sensor.mock_title", None, ["update"]), + ("sensor.mock_title_2", "humidity_device_id", []), + ("sensor.mock_title_3", "humidity_device_id", []), ], indirect=["expected_helper_device_id"], ) @@ -218,7 +218,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed( assert await hass.config_entries.async_setup(mold_indicator_config_entry.entry_id) await hass.async_block_till_done() - mold_indicator_entity_entry = entity_registry.async_get("sensor.my_mold_indicator") + mold_indicator_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_mold_indicator" + ) assert ( mold_indicator_entity_entry.device_id == indoor_humidity_entity_entry.device_id ) @@ -239,7 +241,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed( mock_unload_entry.assert_not_called() # Check that the helper entity is linked to the expected source device - mold_indicator_entity_entry = entity_registry.async_get("sensor.my_mold_indicator") + mold_indicator_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_mold_indicator" + ) assert mold_indicator_entity_entry.device_id == expected_helper_device_id # Check that the device is removed @@ -255,9 +259,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed( @pytest.mark.parametrize( ("source_entity_id", "expected_helper_device_id", "expected_events"), [ - ("sensor.test_unique_indoor_humidity", None, ["update"]), - ("sensor.test_unique_indoor_temperature", "humidity_device_id", []), - ("sensor.test_unique_outdoor_temperature", "humidity_device_id", []), + ("sensor.mock_title", None, ["update"]), + ("sensor.mock_title_2", "humidity_device_id", []), + ("sensor.mock_title_3", "humidity_device_id", []), ], indirect=["expected_helper_device_id"], ) @@ -277,7 +281,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed_shared_d assert await hass.config_entries.async_setup(mold_indicator_config_entry.entry_id) await hass.async_block_till_done() - mold_indicator_entity_entry = entity_registry.async_get("sensor.my_mold_indicator") + mold_indicator_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_mold_indicator" + ) assert ( mold_indicator_entity_entry.device_id == indoor_humidity_entity_entry.device_id ) @@ -298,7 +304,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed_shared_d mock_unload_entry.assert_not_called() # Check that the helper entity is linked to the expected source device - mold_indicator_entity_entry = entity_registry.async_get("sensor.my_mold_indicator") + mold_indicator_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_mold_indicator" + ) assert mold_indicator_entity_entry.device_id == expected_helper_device_id # Check that the source device is not removed @@ -323,9 +331,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed_shared_d "expected_events", ), [ - ("sensor.test_unique_indoor_humidity", 1, None, ["update"]), - ("sensor.test_unique_indoor_temperature", 0, "humidity_device_id", []), - ("sensor.test_unique_outdoor_temperature", 0, "humidity_device_id", []), + ("sensor.mock_title", 1, None, ["update"]), + ("sensor.mock_title_2", 0, "humidity_device_id", []), + ("sensor.mock_title_3", 0, "humidity_device_id", []), ], indirect=["expected_helper_device_id"], ) @@ -346,7 +354,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed_from_dev assert await hass.config_entries.async_setup(mold_indicator_config_entry.entry_id) await hass.async_block_till_done() - mold_indicator_entity_entry = entity_registry.async_get("sensor.my_mold_indicator") + mold_indicator_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_mold_indicator" + ) assert ( mold_indicator_entity_entry.device_id == indoor_humidity_entity_entry.device_id ) @@ -368,7 +378,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed_from_dev assert len(mock_unload_entry.mock_calls) == unload_entry_calls # Check that the helper entity is linked to the expected source device - mold_indicator_entity_entry = entity_registry.async_get("sensor.my_mold_indicator") + mold_indicator_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_mold_indicator" + ) assert mold_indicator_entity_entry.device_id == expected_helper_device_id # Check that the mold_indicator config entry is not in the device @@ -385,9 +397,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed_from_dev @pytest.mark.parametrize( ("source_entity_id", "unload_entry_calls", "expected_events"), [ - ("sensor.test_unique_indoor_humidity", 1, ["update"]), - ("sensor.test_unique_indoor_temperature", 0, []), - ("sensor.test_unique_outdoor_temperature", 0, []), + ("sensor.mock_title", 1, ["update"]), + ("sensor.mock_title_2", 0, []), + ("sensor.mock_title_3", 0, []), ], ) async def test_async_handle_source_entity_changes_source_entity_moved_other_device( @@ -411,7 +423,9 @@ async def test_async_handle_source_entity_changes_source_entity_moved_other_devi assert await hass.config_entries.async_setup(mold_indicator_config_entry.entry_id) await hass.async_block_till_done() - mold_indicator_entity_entry = entity_registry.async_get("sensor.my_mold_indicator") + mold_indicator_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_mold_indicator" + ) assert ( mold_indicator_entity_entry.device_id == indoor_humidity_entity_entry.device_id ) @@ -438,7 +452,9 @@ async def test_async_handle_source_entity_changes_source_entity_moved_other_devi indoor_humidity_entity_entry = entity_registry.async_get( indoor_humidity_entity_entry.entity_id ) - mold_indicator_entity_entry = entity_registry.async_get("sensor.my_mold_indicator") + mold_indicator_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_mold_indicator" + ) assert ( mold_indicator_entity_entry.device_id == indoor_humidity_entity_entry.device_id ) @@ -459,9 +475,9 @@ async def test_async_handle_source_entity_changes_source_entity_moved_other_devi @pytest.mark.parametrize( ("source_entity_id", "config_key"), [ - ("sensor.test_unique_indoor_humidity", CONF_INDOOR_HUMIDITY), - ("sensor.test_unique_indoor_temperature", CONF_INDOOR_TEMP), - ("sensor.test_unique_outdoor_temperature", CONF_OUTDOOR_TEMP), + ("sensor.mock_title", CONF_INDOOR_HUMIDITY), + ("sensor.mock_title_2", CONF_INDOOR_TEMP), + ("sensor.mock_title_3", CONF_OUTDOOR_TEMP), ], ) async def test_async_handle_source_entity_new_entity_id( @@ -479,7 +495,9 @@ async def test_async_handle_source_entity_new_entity_id( assert await hass.config_entries.async_setup(mold_indicator_config_entry.entry_id) await hass.async_block_till_done() - mold_indicator_entity_entry = entity_registry.async_get("sensor.my_mold_indicator") + mold_indicator_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_mold_indicator" + ) assert ( mold_indicator_entity_entry.device_id == indoor_humidity_entity_entry.device_id ) @@ -550,7 +568,9 @@ async def test_migration_1_1( # is linked to the source device source_device = device_registry.async_get(indoor_humidity_device.id) assert mold_indicator_config_entry.entry_id not in source_device.config_entries - mold_indicator_entity_entry = entity_registry.async_get("sensor.my_mold_indicator") + mold_indicator_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_mold_indicator" + ) assert ( mold_indicator_entity_entry.device_id == indoor_humidity_entity_entry.device_id ) diff --git a/tests/components/mqtt/test_device_tracker.py b/tests/components/mqtt/test_device_tracker.py index 82afd5411bb6b..b07d86eaeae95 100644 --- a/tests/components/mqtt/test_device_tracker.py +++ b/tests/components/mqtt/test_device_tracker.py @@ -272,10 +272,10 @@ async def test_cleanup_device_tracker( ("mqtt", "0AFFD2"), mqtt_config_entry.entry_id ) assert device_entry is not None - entity_entry = entity_registry.async_get("device_tracker.mqtt_unique") + entity_entry = entity_registry.async_get("device_tracker.mqtt") assert entity_entry is not None - state = hass.states.get("device_tracker.mqtt_unique") + state = hass.states.get("device_tracker.mqtt") assert state is not None # Remove MQTT from the device @@ -289,11 +289,11 @@ async def test_cleanup_device_tracker( ("mqtt", "0AFFD2"), mqtt_config_entry.entry_id ) assert device_entry is None - entity_entry = entity_registry.async_get("device_tracker.mqtt_unique") + entity_entry = entity_registry.async_get("device_tracker.mqtt") assert entity_entry is None # Verify state is removed - state = hass.states.get("device_tracker.mqtt_unique") + state = hass.states.get("device_tracker.mqtt") assert state is None await hass.async_block_till_done() diff --git a/tests/components/mqtt/test_diagnostics.py b/tests/components/mqtt/test_diagnostics.py index bb6319b27a63c..5bc5048cf6fa3 100644 --- a/tests/components/mqtt/test_diagnostics.py +++ b/tests/components/mqtt/test_diagnostics.py @@ -72,7 +72,7 @@ async def test_entry_diagnostics( expected_debug_info = { "entities": [ { - "entity_id": "sensor.mqtt_sensor", + "entity_id": "sensor.mqtt_mqtt_sensor", "subscriptions": [{"topic": "foobar/sensor", "messages": []}], "discovery_data": { "payload": config_sensor, @@ -101,13 +101,13 @@ async def test_entry_diagnostics( "disabled": False, "disabled_by": None, "entity_category": None, - "entity_id": "sensor.mqtt_sensor", + "entity_id": "sensor.mqtt_mqtt_sensor", "icon": None, "original_device_class": None, "original_icon": None, "state": { - "attributes": {"friendly_name": "MQTT Sensor"}, - "entity_id": "sensor.mqtt_sensor", + "attributes": {"friendly_name": "MQTT MQTT Sensor"}, + "entity_id": "sensor.mqtt_mqtt_sensor", "last_changed": ANY, "last_reported": ANY, "last_updated": ANY, @@ -117,7 +117,7 @@ async def test_entry_diagnostics( } ], "id": device_entry.id, - "name": None, + "name": "MQTT", "name_by_user": None, } @@ -199,7 +199,7 @@ async def test_redact_diagnostics( expected_debug_info = { "entities": [ { - "entity_id": "device_tracker.mqtt_unique", + "entity_id": "device_tracker.mqtt", "subscriptions": [ { "topic": "attributes-topic", @@ -234,12 +234,13 @@ async def test_redact_diagnostics( "disabled": False, "disabled_by": None, "entity_category": None, - "entity_id": "device_tracker.mqtt_unique", + "entity_id": "device_tracker.mqtt", "icon": None, "original_device_class": None, "original_icon": None, "state": { "attributes": { + "friendly_name": "MQTT", "gps_accuracy": 1.5, "in_zones": ["zone.home"], "latitude": "**REDACTED**", @@ -247,7 +248,7 @@ async def test_redact_diagnostics( "source_type": "gps", "tracking_type": "position", }, - "entity_id": "device_tracker.mqtt_unique", + "entity_id": "device_tracker.mqtt", "last_changed": ANY, "last_reported": ANY, "last_updated": ANY, @@ -257,7 +258,7 @@ async def test_redact_diagnostics( } ], "id": device_entry.id, - "name": None, + "name": "MQTT", "name_by_user": None, } @@ -294,7 +295,7 @@ async def test_redact_diagnostics( "connected": True, "device": { "id": device_entry.id, - "name": None, + "name": "MQTT", "name_by_user": None, "disabled": False, "disabled_by": None, diff --git a/tests/components/mqtt/test_discovery.py b/tests/components/mqtt/test_discovery.py index b4ab259d58c4f..e7611edde6021 100644 --- a/tests/components/mqtt/test_discovery.py +++ b/tests/components/mqtt/test_discovery.py @@ -84,7 +84,9 @@ def _get_device_for_config_entry( connections: set[tuple[str, str]] | None = None, ) -> dr.DeviceEntry | None: """Return the device for a config entry matching identifiers or connections.""" - for device in device_registry.devices.get_entries(identifiers, connections): + for device in device_registry.async_get_devices( + identifiers=identifiers, connections=connections + ): if device.config_entry_id == config_entry_id: return device return None @@ -1198,9 +1200,9 @@ async def test_discovery_component_availability_overridden( payload, ) await hass.async_block_till_done() - state = hass.states.get("binary_sensor.beer") + state = hass.states.get("binary_sensor.mqtt_beer") assert state is not None - assert state.name == "Beer" + assert state.name == "MQTT Beer" assert state.state == STATE_UNAVAILABLE async_fire_mqtt_message( @@ -1209,7 +1211,7 @@ async def test_discovery_component_availability_overridden( "online", ) await hass.async_block_till_done() - state = hass.states.get("binary_sensor.beer") + state = hass.states.get("binary_sensor.mqtt_beer") assert state is not None assert state.state == STATE_UNAVAILABLE @@ -1219,7 +1221,7 @@ async def test_discovery_component_availability_overridden( "online", ) await hass.async_block_till_done() - state = hass.states.get("binary_sensor.beer") + state = hass.states.get("binary_sensor.mqtt_beer") assert state is not None assert state.state == STATE_UNKNOWN @@ -1229,7 +1231,7 @@ async def test_discovery_component_availability_overridden( "ON", ) await hass.async_block_till_done() - state = hass.states.get("binary_sensor.beer") + state = hass.states.get("binary_sensor.mqtt_beer") assert state is not None assert state.state == STATE_ON @@ -1741,7 +1743,7 @@ async def test_duplicate_removal( '"name": "sensor2"' "}", }, - ["sensor.sensor1", "sensor.sensor2"], + ["sensor.mqtt_sensor1", "sensor.mqtt_sensor2"], ), ( { @@ -1760,7 +1762,7 @@ async def test_duplicate_removal( '"unique_id": "unique2"' "}}}" }, - ["sensor.sensor1", "sensor.sensor2"], + ["sensor.mqtt_sensor1", "sensor.mqtt_sensor2"], ), ], ) @@ -1836,7 +1838,7 @@ async def test_cleanup_device_manual( '{ "device":{"identifiers":["0AFFD2"]},' ' "state_topic": "foobar/sensor",' ' "unique_id": "unique" }', - ["sensor.mqtt_sensor"], + ["sensor.mqtt_mqtt_sensor"], ), ( "homeassistant/device/bla/config", @@ -1853,7 +1855,7 @@ async def test_cleanup_device_manual( ' "state_topic": "foobar/sensor2",' ' "unique_id": "unique2"' "}}}", - ["sensor.sensor1", "sensor.sensor2"], + ["sensor.mqtt_sensor1", "sensor.mqtt_sensor2"], ), ], ) @@ -1877,7 +1879,7 @@ async def test_cleanup_device_mqtt( ' "unique_id": "unique_base" }' ) base_discovery_topic = "homeassistant/sensor/bla_base/config" - base_entity_id = "sensor.sensor_base" + base_entity_id = "sensor.mqtt_sensor_base" async_fire_mqtt_message(hass, base_discovery_topic, data) await hass.async_block_till_done() @@ -1965,7 +1967,7 @@ async def test_cleanup_device_mqtt_device_discovery( ' "unique_id": "unique2"' "}}}" ) - entity_ids = ["sensor.sensor1", "sensor.sensor2"] + entity_ids = ["sensor.mqtt_sensor1", "sensor.mqtt_sensor2"] async_fire_mqtt_message(hass, discovery_topic, discovery_payload) await hass.async_block_till_done() @@ -2116,10 +2118,10 @@ async def test_cleanup_device_multiple_config_entries( ) is not None ) - entity_entry = entity_registry.async_get("sensor.mqtt_sensor") + entity_entry = entity_registry.async_get("sensor.mqtt_mqtt_sensor") assert entity_entry is not None - state = hass.states.get("sensor.mqtt_sensor") + state = hass.states.get("sensor.mqtt_mqtt_sensor") assert state is not None # Remove MQTT from the device @@ -2135,12 +2137,12 @@ async def test_cleanup_device_multiple_config_entries( ("mac", "12:34:56:AB:CD:EF"), config_entry.entry_id ) assert device_entry is not None - entity_entry = entity_registry.async_get("sensor.mqtt_sensor") + entity_entry = entity_registry.async_get("sensor.mqtt_mqtt_sensor") assert device_entry.config_entries == {config_entry.entry_id} assert entity_entry is None # Verify state is removed - state = hass.states.get("sensor.mqtt_sensor") + state = hass.states.get("sensor.mqtt_mqtt_sensor") assert state is None await hass.async_block_till_done() @@ -2241,10 +2243,10 @@ async def test_cleanup_device_multiple_config_entries_mqtt( ) is not None ) - entity_entry = entity_registry.async_get("sensor.mqtt_sensor") + entity_entry = entity_registry.async_get("sensor.mqtt_mqtt_sensor") assert entity_entry is not None - state = hass.states.get("sensor.mqtt_sensor") + state = hass.states.get("sensor.mqtt_mqtt_sensor") assert state is not None # Send MQTT messages to remove @@ -2260,12 +2262,12 @@ async def test_cleanup_device_multiple_config_entries_mqtt( ("mac", "12:34:56:AB:CD:EF"), config_entry.entry_id ) assert device_entry is not None - entity_entry = entity_registry.async_get("sensor.mqtt_sensor") + entity_entry = entity_registry.async_get("sensor.mqtt_mqtt_sensor") assert device_entry.config_entries == {config_entry.entry_id} assert entity_entry is None # Verify state is removed - state = hass.states.get("sensor.mqtt_sensor") + state = hass.states.get("sensor.mqtt_mqtt_sensor") assert state is None await hass.async_block_till_done() @@ -3194,7 +3196,7 @@ def _callback(*args) -> None: ' "state_topic": "foobar/sensor3",' ' "unique_id": "unique3"' "}}}", - ["sensor.sensor1", "sensor.sensor2", "sensor.sensor3"], + ["sensor.mqtt_sensor1", "sensor.mqtt_sensor2", "sensor.mqtt_sensor3"], ), ], ) @@ -3281,7 +3283,7 @@ async def test_discovery_with_late_via_device_discovery( hass.config_entries.async_entries("mqtt")[0].entry_id, ) assert via_device_entry is not None - assert via_device_entry.name is None + assert via_device_entry.name == "MQTT" await hass.async_block_till_done() @@ -3376,7 +3378,7 @@ async def test_discovery_with_late_via_device_update( hass.config_entries.async_entries("mqtt")[0].entry_id, ) assert via_device_entry is not None - assert via_device_entry.name is None + assert via_device_entry.name == "MQTT" await hass.async_block_till_done() await hass.async_block_till_done() diff --git a/tests/components/mqtt/test_init.py b/tests/components/mqtt/test_init.py index 0862c9f5ee139..7296fa1ad73ba 100644 --- a/tests/components/mqtt/test_init.py +++ b/tests/components/mqtt/test_init.py @@ -1200,7 +1200,7 @@ async def test_mqtt_ws_get_device_debug_info( expected_result = { "entities": [ { - "entity_id": "sensor.mqtt_sensor", + "entity_id": "sensor.mqtt_mqtt_sensor", "subscriptions": [{"topic": "foobar/sensor", "messages": []}], "discovery_data": { "payload": config_sensor, @@ -1263,7 +1263,7 @@ async def test_mqtt_ws_get_device_debug_info_binary( expected_result = { "entities": [ { - "entity_id": "camera.mqtt_camera", + "entity_id": "camera.mqtt_mqtt_camera", "subscriptions": [ { "topic": "foobar/image", diff --git a/tests/components/mqtt/test_mixins.py b/tests/components/mqtt/test_mixins.py index 93bb1017f7859..360837a69e589 100644 --- a/tests/components/mqtt/test_mixins.py +++ b/tests/components/mqtt/test_mixins.py @@ -113,9 +113,9 @@ def test_callback(event) -> None: } } }, - "sensor.mqtt_sensor", - DEFAULT_SENSOR_NAME, - None, + "sensor.mock_title_mqtt_sensor", + f"Mock Title {DEFAULT_SENSOR_NAME}", + "Mock Title", True, ), ( # default_entity_name_with_device_name @@ -160,9 +160,9 @@ def test_callback(event) -> None: } } }, - "sensor.humidity", - "Humidity", - None, + "sensor.mock_title_humidity", + "Mock Title Humidity", + "Mock Title", True, ), ( # name_overrides_device_class @@ -194,9 +194,9 @@ def test_callback(event) -> None: } } }, - "sensor.mysensor", - "MySensor", - None, + "sensor.mock_title_mysensor", + "Mock Title MySensor", + "Mock Title", True, ), ( # none_entity_name_with_device_name @@ -228,9 +228,9 @@ def test_callback(event) -> None: } } }, - "sensor.mqtt_veryunique", - "mqtt veryunique", - None, + "sensor.mock_title", + "Mock Title", + "Mock Title", True, ), ( # entity_name_and_device_name_the_same diff --git a/tests/components/mqtt/test_tag.py b/tests/components/mqtt/test_tag.py index e1ef04a409daf..7446e759ea4db 100644 --- a/tests/components/mqtt/test_tag.py +++ b/tests/components/mqtt/test_tag.py @@ -54,7 +54,9 @@ def _get_device_for_config_entry( connections: set[tuple[str, str]] | None = None, ) -> dr.DeviceEntry | None: """Return the device for a config entry matching identifiers or connections.""" - for device in device_registry.devices.get_entries(identifiers, connections): + for device in device_registry.async_get_devices( + identifiers=identifiers, connections=connections + ): if device.config_entry_id == config_entry_id: return device return None diff --git a/tests/components/overkiz/snapshots/test_sensor.ambr b/tests/components/overkiz/snapshots/test_sensor.ambr index 49d9b0f58ddce..c7e7f66f57d28 100644 --- a/tests/components/overkiz/snapshots/test_sensor.ambr +++ b/tests/components/overkiz/snapshots/test_sensor.ambr @@ -1,5 +1,5 @@ # serializer version: 1 -# name: test_sensor_entities_snapshot[cloud_atlantic_cozytouch.json][sensor.living_room_temperature_temperature-entry] +# name: test_sensor_entities_snapshot[cloud_atlantic_cozytouch.json][sensor.somfy_tahoma_switch_living_room_temperature_temperature-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -15,7 +15,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': None, - 'entity_id': 'sensor.living_room_temperature_temperature', + 'entity_id': 'sensor.somfy_tahoma_switch_living_room_temperature_temperature', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -41,16 +41,16 @@ 'unit_of_measurement': , }) # --- -# name: test_sensor_entities_snapshot[cloud_atlantic_cozytouch.json][sensor.living_room_temperature_temperature-state] +# name: test_sensor_entities_snapshot[cloud_atlantic_cozytouch.json][sensor.somfy_tahoma_switch_living_room_temperature_temperature-state] StateSnapshot({ 'attributes': ReadOnlyDict({ : 'temperature', - : 'Living room temperature Temperature', + : 'Somfy TaHoma Switch Living room temperature Temperature', : , : , }), 'context': , - 'entity_id': 'sensor.living_room_temperature_temperature', + 'entity_id': 'sensor.somfy_tahoma_switch_living_room_temperature_temperature', 'last_changed': , 'last_reported': , 'last_updated': , @@ -9296,7 +9296,7 @@ 'state': 'unknown', }) # --- -# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.garden_temp_probe_discrete_rssi_level-entry] +# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.somfy_tahoma_switch_garden_temp_probe_discrete_rssi_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -9317,7 +9317,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.garden_temp_probe_discrete_rssi_level', + 'entity_id': 'sensor.somfy_tahoma_switch_garden_temp_probe_discrete_rssi_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -9340,7 +9340,7 @@ 'unit_of_measurement': None, }) # --- -# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.garden_temp_probe_discrete_rssi_level-state] +# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.somfy_tahoma_switch_garden_temp_probe_discrete_rssi_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ : 'enum', @@ -9354,14 +9354,14 @@ ]), }), 'context': , - 'entity_id': 'sensor.garden_temp_probe_discrete_rssi_level', + 'entity_id': 'sensor.somfy_tahoma_switch_garden_temp_probe_discrete_rssi_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': 'normal', }) # --- -# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.garden_temp_probe_rssi_level-entry] +# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.somfy_tahoma_switch_garden_temp_probe_rssi_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -9377,7 +9377,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.garden_temp_probe_rssi_level', + 'entity_id': 'sensor.somfy_tahoma_switch_garden_temp_probe_rssi_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -9400,7 +9400,7 @@ 'unit_of_measurement': 'dB', }) # --- -# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.garden_temp_probe_rssi_level-state] +# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.somfy_tahoma_switch_garden_temp_probe_rssi_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ : 'signal_strength', @@ -9409,14 +9409,14 @@ : 'dB', }), 'context': , - 'entity_id': 'sensor.garden_temp_probe_rssi_level', + 'entity_id': 'sensor.somfy_tahoma_switch_garden_temp_probe_rssi_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '54', }) # --- -# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.garden_temp_probe_sensor_defect-entry] +# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.somfy_tahoma_switch_garden_temp_probe_sensor_defect-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -9437,7 +9437,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.garden_temp_probe_sensor_defect', + 'entity_id': 'sensor.somfy_tahoma_switch_garden_temp_probe_sensor_defect', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -9460,7 +9460,7 @@ 'unit_of_measurement': None, }) # --- -# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.garden_temp_probe_sensor_defect-state] +# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.somfy_tahoma_switch_garden_temp_probe_sensor_defect-state] StateSnapshot({ 'attributes': ReadOnlyDict({ : 'enum', @@ -9473,14 +9473,14 @@ ]), }), 'context': , - 'entity_id': 'sensor.garden_temp_probe_sensor_defect', + 'entity_id': 'sensor.somfy_tahoma_switch_garden_temp_probe_sensor_defect', 'last_changed': , 'last_reported': , 'last_updated': , 'state': 'unknown', }) # --- -# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.garden_temp_probe_temperature-entry] +# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.somfy_tahoma_switch_garden_temp_probe_temperature-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -9496,7 +9496,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': None, - 'entity_id': 'sensor.garden_temp_probe_temperature', + 'entity_id': 'sensor.somfy_tahoma_switch_garden_temp_probe_temperature', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -9522,7 +9522,7 @@ 'unit_of_measurement': , }) # --- -# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.garden_temp_probe_temperature-state] +# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.somfy_tahoma_switch_garden_temp_probe_temperature-state] StateSnapshot({ 'attributes': ReadOnlyDict({ : 'temperature', @@ -9531,14 +9531,14 @@ : , }), 'context': , - 'entity_id': 'sensor.garden_temp_probe_temperature', + 'entity_id': 'sensor.somfy_tahoma_switch_garden_temp_probe_temperature', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '24.2', }) # --- -# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.garden_temperature_sensor_discrete_rssi_level-entry] +# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.somfy_tahoma_switch_garden_temperature_sensor_discrete_rssi_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -9559,7 +9559,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.garden_temperature_sensor_discrete_rssi_level', + 'entity_id': 'sensor.somfy_tahoma_switch_garden_temperature_sensor_discrete_rssi_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -9582,7 +9582,7 @@ 'unit_of_measurement': None, }) # --- -# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.garden_temperature_sensor_discrete_rssi_level-state] +# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.somfy_tahoma_switch_garden_temperature_sensor_discrete_rssi_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ : 'enum', @@ -9596,14 +9596,14 @@ ]), }), 'context': , - 'entity_id': 'sensor.garden_temperature_sensor_discrete_rssi_level', + 'entity_id': 'sensor.somfy_tahoma_switch_garden_temperature_sensor_discrete_rssi_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': 'good', }) # --- -# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.garden_temperature_sensor_rssi_level-entry] +# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.somfy_tahoma_switch_garden_temperature_sensor_rssi_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -9619,7 +9619,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.garden_temperature_sensor_rssi_level', + 'entity_id': 'sensor.somfy_tahoma_switch_garden_temperature_sensor_rssi_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -9642,7 +9642,7 @@ 'unit_of_measurement': 'dB', }) # --- -# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.garden_temperature_sensor_rssi_level-state] +# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.somfy_tahoma_switch_garden_temperature_sensor_rssi_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ : 'signal_strength', @@ -9651,14 +9651,14 @@ : 'dB', }), 'context': , - 'entity_id': 'sensor.garden_temperature_sensor_rssi_level', + 'entity_id': 'sensor.somfy_tahoma_switch_garden_temperature_sensor_rssi_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '98', }) # --- -# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.garden_temperature_sensor_sensor_defect-entry] +# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.somfy_tahoma_switch_garden_temperature_sensor_sensor_defect-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -9679,7 +9679,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.garden_temperature_sensor_sensor_defect', + 'entity_id': 'sensor.somfy_tahoma_switch_garden_temperature_sensor_sensor_defect', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -9702,7 +9702,7 @@ 'unit_of_measurement': None, }) # --- -# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.garden_temperature_sensor_sensor_defect-state] +# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.somfy_tahoma_switch_garden_temperature_sensor_sensor_defect-state] StateSnapshot({ 'attributes': ReadOnlyDict({ : 'enum', @@ -9715,14 +9715,14 @@ ]), }), 'context': , - 'entity_id': 'sensor.garden_temperature_sensor_sensor_defect', + 'entity_id': 'sensor.somfy_tahoma_switch_garden_temperature_sensor_sensor_defect', 'last_changed': , 'last_reported': , 'last_updated': , 'state': 'unknown', }) # --- -# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.garden_temperature_sensor_temperature-entry] +# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.somfy_tahoma_switch_garden_temperature_sensor_temperature-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -9738,7 +9738,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': None, - 'entity_id': 'sensor.garden_temperature_sensor_temperature', + 'entity_id': 'sensor.somfy_tahoma_switch_garden_temperature_sensor_temperature', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -9764,7 +9764,7 @@ 'unit_of_measurement': , }) # --- -# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.garden_temperature_sensor_temperature-state] +# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.somfy_tahoma_switch_garden_temperature_sensor_temperature-state] StateSnapshot({ 'attributes': ReadOnlyDict({ : 'temperature', @@ -9773,7 +9773,7 @@ : , }), 'context': , - 'entity_id': 'sensor.garden_temperature_sensor_temperature', + 'entity_id': 'sensor.somfy_tahoma_switch_garden_temperature_sensor_temperature', 'last_changed': , 'last_reported': , 'last_updated': , @@ -10501,7 +10501,7 @@ 'state': '96', }) # --- -# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.kitchen_temp_probe_discrete_rssi_level-entry] +# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.somfy_tahoma_switch_kitchen_temp_probe_discrete_rssi_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -10522,7 +10522,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.kitchen_temp_probe_discrete_rssi_level', + 'entity_id': 'sensor.somfy_tahoma_switch_kitchen_temp_probe_discrete_rssi_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -10545,7 +10545,7 @@ 'unit_of_measurement': None, }) # --- -# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.kitchen_temp_probe_discrete_rssi_level-state] +# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.somfy_tahoma_switch_kitchen_temp_probe_discrete_rssi_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ : 'enum', @@ -10559,14 +10559,14 @@ ]), }), 'context': , - 'entity_id': 'sensor.kitchen_temp_probe_discrete_rssi_level', + 'entity_id': 'sensor.somfy_tahoma_switch_kitchen_temp_probe_discrete_rssi_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': 'good', }) # --- -# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.kitchen_temp_probe_rssi_level-entry] +# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.somfy_tahoma_switch_kitchen_temp_probe_rssi_level-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -10582,7 +10582,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.kitchen_temp_probe_rssi_level', + 'entity_id': 'sensor.somfy_tahoma_switch_kitchen_temp_probe_rssi_level', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -10605,7 +10605,7 @@ 'unit_of_measurement': 'dB', }) # --- -# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.kitchen_temp_probe_rssi_level-state] +# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.somfy_tahoma_switch_kitchen_temp_probe_rssi_level-state] StateSnapshot({ 'attributes': ReadOnlyDict({ : 'signal_strength', @@ -10614,14 +10614,14 @@ : 'dB', }), 'context': , - 'entity_id': 'sensor.kitchen_temp_probe_rssi_level', + 'entity_id': 'sensor.somfy_tahoma_switch_kitchen_temp_probe_rssi_level', 'last_changed': , 'last_reported': , 'last_updated': , 'state': '82', }) # --- -# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.kitchen_temp_probe_sensor_defect-entry] +# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.somfy_tahoma_switch_kitchen_temp_probe_sensor_defect-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -10642,7 +10642,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': , - 'entity_id': 'sensor.kitchen_temp_probe_sensor_defect', + 'entity_id': 'sensor.somfy_tahoma_switch_kitchen_temp_probe_sensor_defect', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -10665,7 +10665,7 @@ 'unit_of_measurement': None, }) # --- -# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.kitchen_temp_probe_sensor_defect-state] +# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.somfy_tahoma_switch_kitchen_temp_probe_sensor_defect-state] StateSnapshot({ 'attributes': ReadOnlyDict({ : 'enum', @@ -10678,14 +10678,14 @@ ]), }), 'context': , - 'entity_id': 'sensor.kitchen_temp_probe_sensor_defect', + 'entity_id': 'sensor.somfy_tahoma_switch_kitchen_temp_probe_sensor_defect', 'last_changed': , 'last_reported': , 'last_updated': , 'state': 'unknown', }) # --- -# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.kitchen_temp_probe_temperature-entry] +# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.somfy_tahoma_switch_kitchen_temp_probe_temperature-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -10701,7 +10701,7 @@ 'disabled_by': None, 'domain': 'sensor', 'entity_category': None, - 'entity_id': 'sensor.kitchen_temp_probe_temperature', + 'entity_id': 'sensor.somfy_tahoma_switch_kitchen_temp_probe_temperature', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -10727,7 +10727,7 @@ 'unit_of_measurement': , }) # --- -# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.kitchen_temp_probe_temperature-state] +# name: test_sensor_entities_snapshot[local_somfy_tahoma_switch_europe_3.json][sensor.somfy_tahoma_switch_kitchen_temp_probe_temperature-state] StateSnapshot({ 'attributes': ReadOnlyDict({ : 'temperature', @@ -10736,7 +10736,7 @@ : , }), 'context': , - 'entity_id': 'sensor.kitchen_temp_probe_temperature', + 'entity_id': 'sensor.somfy_tahoma_switch_kitchen_temp_probe_temperature', 'last_changed': , 'last_reported': , 'last_updated': , diff --git a/tests/components/overkiz/snapshots/test_switch.ambr b/tests/components/overkiz/snapshots/test_switch.ambr index 1fe6d83d8d1ae..26dd2743df09e 100644 --- a/tests/components/overkiz/snapshots/test_switch.ambr +++ b/tests/components/overkiz/snapshots/test_switch.ambr @@ -1,5 +1,5 @@ # serializer version: 1 -# name: test_switch_entities_snapshot[cloud_somfy_myfox_europe.json][switch.hot_water_tank-entry] +# name: test_switch_entities_snapshot[cloud_somfy_myfox_europe.json][switch.somfy_tahoma_switch_hot_water_tank-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -13,7 +13,7 @@ 'disabled_by': None, 'domain': 'switch', 'entity_category': None, - 'entity_id': 'switch.hot_water_tank', + 'entity_id': 'switch.somfy_tahoma_switch_hot_water_tank', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -36,14 +36,14 @@ 'unit_of_measurement': None, }) # --- -# name: test_switch_entities_snapshot[cloud_somfy_myfox_europe.json][switch.hot_water_tank-state] +# name: test_switch_entities_snapshot[cloud_somfy_myfox_europe.json][switch.somfy_tahoma_switch_hot_water_tank-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Hot Water Tank', + : 'Somfy TaHoma Switch Hot Water Tank', : 'mdi:water-boiler', }), 'context': , - 'entity_id': 'switch.hot_water_tank', + 'entity_id': 'switch.somfy_tahoma_switch_hot_water_tank', 'last_changed': , 'last_reported': , 'last_updated': , diff --git a/tests/components/overkiz/snapshots/test_water_heater.ambr b/tests/components/overkiz/snapshots/test_water_heater.ambr index e83aa39bb407f..e6ffaf03aeefd 100644 --- a/tests/components/overkiz/snapshots/test_water_heater.ambr +++ b/tests/components/overkiz/snapshots/test_water_heater.ambr @@ -147,7 +147,7 @@ 'state': 'auto', }) # --- -# name: test_water_heater_entities_snapshot[cloud_atlantic_cozytouch.json][water_heater.yutaki_dhw-entry] +# name: test_water_heater_entities_snapshot[cloud_atlantic_cozytouch.json][water_heater.somfy_tahoma_switch_yutaki_dhw-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -169,7 +169,7 @@ 'disabled_by': None, 'domain': 'water_heater', 'entity_category': None, - 'entity_id': 'water_heater.yutaki_dhw', + 'entity_id': 'water_heater.somfy_tahoma_switch_yutaki_dhw', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -192,11 +192,11 @@ 'unit_of_measurement': None, }) # --- -# name: test_water_heater_entities_snapshot[cloud_atlantic_cozytouch.json][water_heater.yutaki_dhw-state] +# name: test_water_heater_entities_snapshot[cloud_atlantic_cozytouch.json][water_heater.somfy_tahoma_switch_yutaki_dhw-state] StateSnapshot({ 'attributes': ReadOnlyDict({ : 46, - : 'Yutaki DHW', + : 'Somfy TaHoma Switch Yutaki DHW', : 70, : 30, : list([ @@ -211,7 +211,7 @@ : 54, }), 'context': , - 'entity_id': 'water_heater.yutaki_dhw', + 'entity_id': 'water_heater.somfy_tahoma_switch_yutaki_dhw', 'last_changed': , 'last_reported': , 'last_updated': , diff --git a/tests/components/overkiz/test_switch.py b/tests/components/overkiz/test_switch.py index 96d73a950f38c..97995cbe5c315 100644 --- a/tests/components/overkiz/test_switch.py +++ b/tests/components/overkiz/test_switch.py @@ -52,12 +52,12 @@ "myfox://SOMFY_PROTECT-1234567890ABCDEF/jQ5ul40RVLnipT6JB8b3JK96tUsf14mR", "switch.outdoor_camera_camera_shutter", ) -# Sub-device (#7 suffix) whose DomesticHotWaterTank description has no name set, -# so the entity name falls back to the device label alone. +# Sub-device (#7 suffix) whose device has no name set, so it takes the config +# entry title, and the entity id becomes device name + entity name. DOMESTIC_HOT_WATER_TANK = FixtureDevice( "setup/cloud_somfy_myfox_europe.json", "io://1234-5678-1202/6019143#7", - "switch.hot_water_tank", + "switch.somfy_tahoma_switch_hot_water_tank", ) diff --git a/tests/components/overkiz/test_water_heater.py b/tests/components/overkiz/test_water_heater.py index a9ed2fa265904..40301f405d51f 100644 --- a/tests/components/overkiz/test_water_heater.py +++ b/tests/components/overkiz/test_water_heater.py @@ -42,7 +42,7 @@ DHW_HITACHI_YUTAKI = FixtureDevice( "setup/cloud_atlantic_cozytouch.json", "modbus://1234-5678-5643/6381497/1#4", - "water_heater.yutaki_dhw", + "water_heater.somfy_tahoma_switch_yutaki_dhw", ) # Thermor Aéromax 4 (io:AtlanticDomesticHotWaterProductionIOComponent) diff --git a/tests/components/roborock/test_init.py b/tests/components/roborock/test_init.py index b35d8e9be0cd2..6b5b9bbc47c02 100644 --- a/tests/components/roborock/test_init.py +++ b/tests/components/roborock/test_init.py @@ -73,8 +73,8 @@ async def test_stale_device( await hass.async_block_till_done() if mock_roborock_entry._background_tasks: await asyncio.gather(*mock_roborock_entry._background_tasks) - existing_devices = device_registry.devices.get_devices_for_config_entry_id( - mock_roborock_entry.entry_id + existing_devices = dr.async_entries_for_config_entry( + device_registry, mock_roborock_entry.entry_id ) assert {device.name for device in existing_devices} == { "Roborock S7 MaxV", @@ -95,8 +95,8 @@ async def test_stale_device( await hass.async_block_till_done() if mock_roborock_entry._background_tasks: await asyncio.gather(*mock_roborock_entry._background_tasks) - new_devices = device_registry.devices.get_devices_for_config_entry_id( - mock_roborock_entry.entry_id + new_devices = dr.async_entries_for_config_entry( + device_registry, mock_roborock_entry.entry_id ) assert {device.name for device in new_devices} == { "Roborock S7 2", @@ -120,8 +120,8 @@ async def test_no_stale_device( await hass.async_block_till_done() if mock_roborock_entry._background_tasks: await asyncio.gather(*mock_roborock_entry._background_tasks) - existing_devices = device_registry.devices.get_devices_for_config_entry_id( - mock_roborock_entry.entry_id + existing_devices = dr.async_entries_for_config_entry( + device_registry, mock_roborock_entry.entry_id ) assert {device.name for device in existing_devices} == { "Roborock S7 MaxV", @@ -138,8 +138,8 @@ async def test_no_stale_device( await hass.async_block_till_done() if mock_roborock_entry._background_tasks: await asyncio.gather(*mock_roborock_entry._background_tasks) - new_devices = device_registry.devices.get_devices_for_config_entry_id( - mock_roborock_entry.entry_id + new_devices = dr.async_entries_for_config_entry( + device_registry, mock_roborock_entry.entry_id ) assert {device.name for device in new_devices} == { "Roborock S7 MaxV", @@ -700,8 +700,8 @@ async def test_disabled_device_no_coordinator( assert all(coord.duid != first_device.duid for coord in coordinators.v1) # Other devices should still be set up - found_devices = device_registry.devices.get_devices_for_config_entry_id( - mock_roborock_entry.entry_id + found_devices = dr.async_entries_for_config_entry( + device_registry, mock_roborock_entry.entry_id ) enabled_device_names = { device.name for device in found_devices if not device.disabled diff --git a/tests/components/snooz/snapshots/test_init.ambr b/tests/components/snooz/snapshots/test_init.ambr index 2428bdd78c126..06f53bc4eaa1a 100644 --- a/tests/components/snooz/snapshots/test_init.ambr +++ b/tests/components/snooz/snapshots/test_init.ambr @@ -26,7 +26,7 @@ 'manufacturer': None, 'model': None, 'model_id': None, - 'name': None, + 'name': 'Mock Title', 'name_by_user': None, 'serial_number': None, 'sw_version': None, diff --git a/tests/components/squeezebox/snapshots/test_switch.ambr b/tests/components/squeezebox/snapshots/test_switch.ambr index 6a78d35e83e55..2454256db9f3e 100644 --- a/tests/components/squeezebox/snapshots/test_switch.ambr +++ b/tests/components/squeezebox/snapshots/test_switch.ambr @@ -1,5 +1,5 @@ # serializer version: 1 -# name: test_entity_registry[switch.alarm_1-entry] +# name: test_entity_registry[switch.mock_title_alarm_1-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -13,7 +13,7 @@ 'disabled_by': None, 'domain': 'switch', 'entity_category': , - 'entity_id': 'switch.alarm_1', + 'entity_id': 'switch.mock_title_alarm_1', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -36,21 +36,21 @@ 'unit_of_measurement': None, }) # --- -# name: test_entity_registry[switch.alarm_1-state] +# name: test_entity_registry[switch.mock_title_alarm_1-state] StateSnapshot({ 'attributes': ReadOnlyDict({ 'alarm_id': '1', - : 'Alarm (1)', + : 'Mock Title Alarm (1)', }), 'context': , - 'entity_id': 'switch.alarm_1', + 'entity_id': 'switch.mock_title_alarm_1', 'last_changed': , 'last_reported': , 'last_updated': , 'state': 'on', }) # --- -# name: test_entity_registry[switch.alarms_enabled-entry] +# name: test_entity_registry[switch.mock_title_alarms_enabled-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -64,7 +64,7 @@ 'disabled_by': None, 'domain': 'switch', 'entity_category': , - 'entity_id': 'switch.alarms_enabled', + 'entity_id': 'switch.mock_title_alarms_enabled', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -87,13 +87,13 @@ 'unit_of_measurement': None, }) # --- -# name: test_entity_registry[switch.alarms_enabled-state] +# name: test_entity_registry[switch.mock_title_alarms_enabled-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - : 'Alarms enabled', + : 'Mock Title Alarms enabled', }), 'context': , - 'entity_id': 'switch.alarms_enabled', + 'entity_id': 'switch.mock_title_alarms_enabled', 'last_changed': , 'last_reported': , 'last_updated': , diff --git a/tests/components/squeezebox/test_binary_sensor.py b/tests/components/squeezebox/test_binary_sensor.py index 5966142a2771a..46098af5c4aa3 100644 --- a/tests/components/squeezebox/test_binary_sensor.py +++ b/tests/components/squeezebox/test_binary_sensor.py @@ -8,11 +8,18 @@ import pytest from homeassistant.components.binary_sensor import BinarySensorDeviceClass -from homeassistant.components.squeezebox.const import PLAYER_UPDATE_INTERVAL +from homeassistant.components.squeezebox.const import ( + DOMAIN, + PLAYER_SENSOR_ALARM_ACTIVE, + PLAYER_SENSOR_ALARM_SNOOZE, + PLAYER_SENSOR_ALARM_UPCOMING, + PLAYER_UPDATE_INTERVAL, +) from homeassistant.const import STATE_OFF, STATE_ON, Platform from homeassistant.core import HomeAssistant +from homeassistant.helpers import entity_registry as er -from .conftest import FAKE_QUERY_RESPONSE +from .conftest import FAKE_QUERY_RESPONSE, TEST_MAC from tests.common import MockConfigEntry, async_fire_time_changed @@ -67,24 +74,35 @@ async def mock_player( async def test_player_alarm_sensors_device_class( hass: HomeAssistant, + entity_registry: er.EntityRegistry, mock_player: MagicMock, ) -> None: """Test player alarm binary sensors have correct device class.""" + upcoming_id = entity_registry.async_get_entity_id( + Platform.BINARY_SENSOR, DOMAIN, f"{TEST_MAC[0]}_{PLAYER_SENSOR_ALARM_UPCOMING}" + ) + active_id = entity_registry.async_get_entity_id( + Platform.BINARY_SENSOR, DOMAIN, f"{TEST_MAC[0]}_{PLAYER_SENSOR_ALARM_ACTIVE}" + ) + snooze_id = entity_registry.async_get_entity_id( + Platform.BINARY_SENSOR, DOMAIN, f"{TEST_MAC[0]}_{PLAYER_SENSOR_ALARM_SNOOZE}" + ) + # Test alarm upcoming sensor device class - upcoming_state = hass.states.get("binary_sensor.alarm_upcoming") + upcoming_state = hass.states.get(upcoming_id) assert upcoming_state is not None assert upcoming_state.attributes.get("device_class") is None # Test alarm active sensor device class - active_state = hass.states.get("binary_sensor.alarm_active") + active_state = hass.states.get(active_id) assert active_state is not None assert ( active_state.attributes.get("device_class") == BinarySensorDeviceClass.RUNNING ) # Test alarm snooze sensor device class - snooze_state = hass.states.get("binary_sensor.alarm_snoozed") + snooze_state = hass.states.get(snooze_id) assert snooze_state is not None assert ( snooze_state.attributes.get("device_class") == BinarySensorDeviceClass.RUNNING @@ -93,6 +111,7 @@ async def test_player_alarm_sensors_device_class( async def test_player_alarm_sensors_state( hass: HomeAssistant, + entity_registry: er.EntityRegistry, mock_player: MagicMock, freezer: FrozenDateTimeFactory, ) -> None: @@ -100,18 +119,28 @@ async def test_player_alarm_sensors_state( player = mock_player + upcoming_id = entity_registry.async_get_entity_id( + Platform.BINARY_SENSOR, DOMAIN, f"{TEST_MAC[0]}_{PLAYER_SENSOR_ALARM_UPCOMING}" + ) + active_id = entity_registry.async_get_entity_id( + Platform.BINARY_SENSOR, DOMAIN, f"{TEST_MAC[0]}_{PLAYER_SENSOR_ALARM_ACTIVE}" + ) + snooze_id = entity_registry.async_get_entity_id( + Platform.BINARY_SENSOR, DOMAIN, f"{TEST_MAC[0]}_{PLAYER_SENSOR_ALARM_SNOOZE}" + ) + # Test alarm upcoming sensor - upcoming_state = hass.states.get("binary_sensor.alarm_upcoming") + upcoming_state = hass.states.get(upcoming_id) assert upcoming_state is not None assert upcoming_state.state == STATE_ON # Test alarm active sensor - active_state = hass.states.get("binary_sensor.alarm_active") + active_state = hass.states.get(active_id) assert active_state is not None assert active_state.state == STATE_OFF # Test alarm snooze sensor - snooze_state = hass.states.get("binary_sensor.alarm_snoozed") + snooze_state = hass.states.get(snooze_id) assert snooze_state is not None assert snooze_state.state == STATE_OFF @@ -123,10 +152,10 @@ async def test_player_alarm_sensors_state( async_fire_time_changed(hass) await hass.async_block_till_done() - upcoming_state = hass.states.get("binary_sensor.alarm_upcoming") + upcoming_state = hass.states.get(upcoming_id) assert upcoming_state is not None assert upcoming_state.state == STATE_OFF - active_state = hass.states.get("binary_sensor.alarm_active") + active_state = hass.states.get(active_id) assert active_state is not None assert active_state.state == STATE_ON diff --git a/tests/components/squeezebox/test_button.py b/tests/components/squeezebox/test_button.py index 1ff623687edef..53015b3c769af 100644 --- a/tests/components/squeezebox/test_button.py +++ b/tests/components/squeezebox/test_button.py @@ -5,8 +5,12 @@ import pytest from homeassistant.components.button import DOMAIN as BUTTON_DOMAIN, SERVICE_PRESS +from homeassistant.components.squeezebox.const import DOMAIN from homeassistant.const import ATTR_ENTITY_ID, Platform from homeassistant.core import HomeAssistant +from homeassistant.helpers import entity_registry as er + +from .conftest import TEST_MAC @pytest.fixture(autouse=True) @@ -17,13 +21,18 @@ def squeezebox_button_platform(): async def test_squeezebox_press( - hass: HomeAssistant, configured_player: MagicMock + hass: HomeAssistant, + entity_registry: er.EntityRegistry, + configured_player: MagicMock, ) -> None: """Test press service call.""" + entity_id = entity_registry.async_get_entity_id( + Platform.BUTTON, DOMAIN, f"{TEST_MAC[0]}_preset_1" + ) await hass.services.async_call( BUTTON_DOMAIN, SERVICE_PRESS, - {ATTR_ENTITY_ID: "button.preset_1"}, + {ATTR_ENTITY_ID: entity_id}, blocking=True, ) diff --git a/tests/components/squeezebox/test_sensor.py b/tests/components/squeezebox/test_sensor.py index 2f66cbd0e39c8..c75d8ee58c959 100644 --- a/tests/components/squeezebox/test_sensor.py +++ b/tests/components/squeezebox/test_sensor.py @@ -7,11 +7,16 @@ from freezegun.api import FrozenDateTimeFactory import pytest -from homeassistant.components.squeezebox.const import PLAYER_UPDATE_INTERVAL +from homeassistant.components.squeezebox.const import ( + DOMAIN, + PLAYER_SENSOR_NEXT_ALARM, + PLAYER_UPDATE_INTERVAL, +) from homeassistant.const import STATE_UNKNOWN, Platform from homeassistant.core import HomeAssistant +from homeassistant.helpers import entity_registry as er -from .conftest import FAKE_QUERY_RESPONSE, TEST_ALARM_NEXT_TIME +from .conftest import FAKE_QUERY_RESPONSE, TEST_ALARM_NEXT_TIME, TEST_MAC from tests.common import MockConfigEntry, async_fire_time_changed @@ -44,6 +49,7 @@ async def test_server_sensor( async def test_player_sensor_next_alarm( hass: HomeAssistant, + entity_registry: er.EntityRegistry, config_entry: MockConfigEntry, lms: MagicMock, freezer: FrozenDateTimeFactory, @@ -59,8 +65,12 @@ async def test_player_sensor_next_alarm( await hass.async_block_till_done(wait_background_tasks=True) player = (await lms.async_get_players())[0] + entity_id = entity_registry.async_get_entity_id( + Platform.SENSOR, DOMAIN, f"{TEST_MAC[0]}_{PLAYER_SENSOR_NEXT_ALARM}" + ) + # test alarm time is set from player - state = hass.states.get("sensor.next_alarm") + state = hass.states.get(entity_id) assert state is not None assert state.state == TEST_ALARM_NEXT_TIME.isoformat() @@ -70,6 +80,6 @@ async def test_player_sensor_next_alarm( async_fire_time_changed(hass) await hass.async_block_till_done() - state = hass.states.get("sensor.next_alarm") + state = hass.states.get(entity_id) assert state is not None assert state.state == STATE_UNKNOWN diff --git a/tests/components/squeezebox/test_switch.py b/tests/components/squeezebox/test_switch.py index 93eef1ab13d2d..f457f49530a39 100644 --- a/tests/components/squeezebox/test_switch.py +++ b/tests/components/squeezebox/test_switch.py @@ -7,7 +7,7 @@ import pytest from syrupy.assertion import SnapshotAssertion -from homeassistant.components.squeezebox.const import PLAYER_UPDATE_INTERVAL +from homeassistant.components.squeezebox.const import DOMAIN, PLAYER_UPDATE_INTERVAL from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN from homeassistant.const import ( CONF_ENTITY_ID, @@ -18,7 +18,7 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_registry import EntityRegistry -from .conftest import TEST_ALARM_ID +from .conftest import TEST_ALARM_ID, TEST_MAC from tests.common import MockConfigEntry, async_fire_time_changed, snapshot_platform @@ -70,43 +70,55 @@ async def test_entity_registry( async def test_switch_state( hass: HomeAssistant, + entity_registry: EntityRegistry, mock_alarms_player: MagicMock, freezer: FrozenDateTimeFactory, ) -> None: """Test the state of the switch.""" - assert hass.states.get(f"switch.alarm_{TEST_ALARM_ID}").state == "on" + entity_id = entity_registry.async_get_entity_id( + SWITCH_DOMAIN, DOMAIN, f"{TEST_MAC[0]}_alarm_{TEST_ALARM_ID}" + ) + assert hass.states.get(entity_id).state == "on" mock_alarms_player.alarms[0]["enabled"] = False freezer.tick(timedelta(seconds=PLAYER_UPDATE_INTERVAL)) async_fire_time_changed(hass) await hass.async_block_till_done() - assert hass.states.get(f"switch.alarm_{TEST_ALARM_ID}").state == "off" + assert hass.states.get(entity_id).state == "off" async def test_switch_deleted( hass: HomeAssistant, + entity_registry: EntityRegistry, mock_alarms_player: MagicMock, freezer: FrozenDateTimeFactory, ) -> None: """Test detecting switch deleted.""" - assert hass.states.get(f"switch.alarm_{TEST_ALARM_ID}").state == "on" + entity_id = entity_registry.async_get_entity_id( + SWITCH_DOMAIN, DOMAIN, f"{TEST_MAC[0]}_alarm_{TEST_ALARM_ID}" + ) + assert hass.states.get(entity_id).state == "on" mock_alarms_player.alarms = [] freezer.tick(timedelta(seconds=PLAYER_UPDATE_INTERVAL)) async_fire_time_changed(hass) await hass.async_block_till_done() - assert hass.states.get(f"switch.alarm_{TEST_ALARM_ID}") is None + assert hass.states.get(entity_id) is None async def test_turn_on( hass: HomeAssistant, + entity_registry: EntityRegistry, mock_alarms_player: MagicMock, ) -> None: """Test turning on the switch.""" + entity_id = entity_registry.async_get_entity_id( + SWITCH_DOMAIN, DOMAIN, f"{TEST_MAC[0]}_alarm_{TEST_ALARM_ID}" + ) await hass.services.async_call( SWITCH_DOMAIN, SERVICE_TURN_ON, - {CONF_ENTITY_ID: f"switch.alarm_{TEST_ALARM_ID}"}, + {CONF_ENTITY_ID: entity_id}, blocking=True, ) mock_alarms_player.async_update_alarm.assert_called_once_with( @@ -116,13 +128,17 @@ async def test_turn_on( async def test_turn_off( hass: HomeAssistant, + entity_registry: EntityRegistry, mock_alarms_player: MagicMock, ) -> None: """Test turning on the switch.""" + entity_id = entity_registry.async_get_entity_id( + SWITCH_DOMAIN, DOMAIN, f"{TEST_MAC[0]}_alarm_{TEST_ALARM_ID}" + ) await hass.services.async_call( SWITCH_DOMAIN, SERVICE_TURN_OFF, - {CONF_ENTITY_ID: f"switch.alarm_{TEST_ALARM_ID}"}, + {CONF_ENTITY_ID: entity_id}, blocking=True, ) mock_alarms_player.async_update_alarm.assert_called_once_with( @@ -132,30 +148,38 @@ async def test_turn_off( async def test_alarms_enabled_state( hass: HomeAssistant, + entity_registry: EntityRegistry, mock_alarms_player: MagicMock, freezer: FrozenDateTimeFactory, ) -> None: """Test the alarms enabled switch.""" + entity_id = entity_registry.async_get_entity_id( + SWITCH_DOMAIN, DOMAIN, f"{TEST_MAC[0]}_alarms_enabled" + ) - assert hass.states.get("switch.alarms_enabled").state == "on" + assert hass.states.get(entity_id).state == "on" mock_alarms_player.alarms_enabled = False freezer.tick(timedelta(seconds=PLAYER_UPDATE_INTERVAL)) async_fire_time_changed(hass) await hass.async_block_till_done() - assert hass.states.get("switch.alarms_enabled").state == "off" + assert hass.states.get(entity_id).state == "off" async def test_alarms_enabled_turn_on( hass: HomeAssistant, + entity_registry: EntityRegistry, mock_alarms_player: MagicMock, ) -> None: """Test turning on the alarms enabled switch.""" + entity_id = entity_registry.async_get_entity_id( + SWITCH_DOMAIN, DOMAIN, f"{TEST_MAC[0]}_alarms_enabled" + ) await hass.services.async_call( SWITCH_DOMAIN, SERVICE_TURN_ON, - {CONF_ENTITY_ID: "switch.alarms_enabled"}, + {CONF_ENTITY_ID: entity_id}, blocking=True, ) mock_alarms_player.async_set_alarms_enabled.assert_called_once_with(True) @@ -163,13 +187,17 @@ async def test_alarms_enabled_turn_on( async def test_alarms_enabled_turn_off( hass: HomeAssistant, + entity_registry: EntityRegistry, mock_alarms_player: MagicMock, ) -> None: """Test turning off the alarms enabled switch.""" + entity_id = entity_registry.async_get_entity_id( + SWITCH_DOMAIN, DOMAIN, f"{TEST_MAC[0]}_alarms_enabled" + ) await hass.services.async_call( SWITCH_DOMAIN, SERVICE_TURN_OFF, - {CONF_ENTITY_ID: "switch.alarms_enabled"}, + {CONF_ENTITY_ID: entity_id}, blocking=True, ) mock_alarms_player.async_set_alarms_enabled.assert_called_once_with(False) diff --git a/tests/components/statistics/test_init.py b/tests/components/statistics/test_init.py index df37c994d3a68..a65cd31ac5d6d 100644 --- a/tests/components/statistics/test_init.py +++ b/tests/components/statistics/test_init.py @@ -115,7 +115,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed( assert await hass.config_entries.async_setup(statistics_config_entry.entry_id) await hass.async_block_till_done() - statistics_entity_entry = entity_registry.async_get("sensor.my_statistics") + statistics_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_statistics" + ) assert statistics_entity_entry.device_id == sensor_entity_entry.device_id sensor_device = device_registry.async_get(sensor_device.id) @@ -134,7 +136,7 @@ async def test_async_handle_source_entity_changes_source_entity_removed( mock_unload_entry.assert_called_once() # Check that the helper entity is removed - assert not entity_registry.async_get("sensor.my_statistics") + assert not entity_registry.async_get("sensor.mock_title_my_statistics") # Check that the device is removed assert not device_registry.async_get(sensor_device.id) @@ -162,7 +164,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed_shared_d assert await hass.config_entries.async_setup(statistics_config_entry.entry_id) await hass.async_block_till_done() - statistics_entity_entry = entity_registry.async_get("sensor.my_statistics") + statistics_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_statistics" + ) assert statistics_entity_entry.device_id == sensor_entity_entry.device_id sensor_device = device_registry.async_get(sensor_device.id) @@ -181,7 +185,7 @@ async def test_async_handle_source_entity_changes_source_entity_removed_shared_d mock_unload_entry.assert_called_once() # Check that the helper entity is removed - assert not entity_registry.async_get("sensor.my_statistics") + assert not entity_registry.async_get("sensor.mock_title_my_statistics") # Check that the source device is not removed assert device_registry.async_get(sensor_device.id) is not None @@ -209,7 +213,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed_from_dev assert await hass.config_entries.async_setup(statistics_config_entry.entry_id) await hass.async_block_till_done() - statistics_entity_entry = entity_registry.async_get("sensor.my_statistics") + statistics_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_statistics" + ) assert statistics_entity_entry.device_id == sensor_entity_entry.device_id sensor_device = device_registry.async_get(sensor_device.id) @@ -229,7 +235,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed_from_dev mock_unload_entry.assert_called_once() # Check that the entity is no longer linked to the source device - statistics_entity_entry = entity_registry.async_get("sensor.my_statistics") + statistics_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_statistics" + ) assert statistics_entity_entry.device_id is None # Check that the statistics config entry is not in the device @@ -261,7 +269,9 @@ async def test_async_handle_source_entity_changes_source_entity_moved_other_devi assert await hass.config_entries.async_setup(statistics_config_entry.entry_id) await hass.async_block_till_done() - statistics_entity_entry = entity_registry.async_get("sensor.my_statistics") + statistics_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_statistics" + ) assert statistics_entity_entry.device_id == sensor_entity_entry.device_id sensor_device = device_registry.async_get(sensor_device.id) @@ -283,7 +293,9 @@ async def test_async_handle_source_entity_changes_source_entity_moved_other_devi mock_unload_entry.assert_called_once() # Check that the entity is linked to the other device - statistics_entity_entry = entity_registry.async_get("sensor.my_statistics") + statistics_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_statistics" + ) assert statistics_entity_entry.device_id == sensor_device_2.id # Check that the history_stats config entry is not in any of the devices @@ -311,7 +323,9 @@ async def test_async_handle_source_entity_new_entity_id( assert await hass.config_entries.async_setup(statistics_config_entry.entry_id) await hass.async_block_till_done() - statistics_entity_entry = entity_registry.async_get("sensor.my_statistics") + statistics_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_statistics" + ) assert statistics_entity_entry.device_id == sensor_entity_entry.device_id sensor_device = device_registry.async_get(sensor_device.id) @@ -380,7 +394,9 @@ async def test_migration_1_1( # is linked to the source device sensor_device = device_registry.async_get(sensor_device.id) assert statistics_config_entry.entry_id not in sensor_device.config_entries - statistics_entity_entry = entity_registry.async_get("sensor.my_statistics") + statistics_entity_entry = entity_registry.async_get( + "sensor.mock_title_my_statistics" + ) assert statistics_entity_entry.device_id == sensor_entity_entry.device_id assert statistics_config_entry.version == 1 diff --git a/tests/components/statistics/test_sensor.py b/tests/components/statistics/test_sensor.py index 7c10ae30469fc..ad59427dde870 100644 --- a/tests/components/statistics/test_sensor.py +++ b/tests/components/statistics/test_sensor.py @@ -1694,14 +1694,14 @@ async def test_device_id( device_id=source_device_entry.id, ) await hass.async_block_till_done() - assert entity_registry.async_get("sensor.test_source") is not None + assert entity_registry.async_get("sensor.mock_title") is not None statistics_config_entry = MockConfigEntry( data={}, domain=DOMAIN, options={ "name": "Statistics", - "entity_id": "sensor.test_source", + "entity_id": "sensor.mock_title", "state_characteristic": "mean", "keep_last_sample": False, "percentile": 50.0, @@ -1715,7 +1715,7 @@ async def test_device_id( assert await hass.config_entries.async_setup(statistics_config_entry.entry_id) await hass.async_block_till_done() - statistics_entity = entity_registry.async_get("sensor.statistics") + statistics_entity = entity_registry.async_get("sensor.mock_title_statistics") assert statistics_entity is not None assert statistics_entity.device_id == source_entity.device_id diff --git a/tests/components/switch_as_x/test_init.py b/tests/components/switch_as_x/test_init.py index f3cddd346f033..842415fc5c283 100644 --- a/tests/components/switch_as_x/test_init.py +++ b/tests/components/switch_as_x/test_init.py @@ -226,7 +226,10 @@ async def test_device_registry_config_entry_1( assert await hass.config_entries.async_setup(switch_as_x_config_entry.entry_id) await hass.async_block_till_done() - entity_entry = entity_registry.async_get(f"{target_domain}.abc") + entity_id = entity_registry.async_get_entity_id( + target_domain, DOMAIN, switch_as_x_config_entry.entry_id + ) + entity_entry = entity_registry.async_get(entity_id) assert entity_entry.device_id == switch_entity_entry.device_id device_entry = device_registry.async_get(device_entry.id) @@ -305,7 +308,10 @@ async def test_device_registry_config_entry_2( assert await hass.config_entries.async_setup(switch_as_x_config_entry.entry_id) await hass.async_block_till_done() - entity_entry = entity_registry.async_get(f"{target_domain}.abc") + entity_id = entity_registry.async_get_entity_id( + target_domain, DOMAIN, switch_as_x_config_entry.entry_id + ) + entity_entry = entity_registry.async_get(entity_id) assert entity_entry.device_id == switch_entity_entry.device_id device_entry = device_registry.async_get(device_entry.id) @@ -387,7 +393,10 @@ async def test_device_registry_config_entry_3( assert await hass.config_entries.async_setup(switch_as_x_config_entry.entry_id) await hass.async_block_till_done() - entity_entry = entity_registry.async_get(f"{target_domain}.abc") + entity_id = entity_registry.async_get_entity_id( + target_domain, DOMAIN, switch_as_x_config_entry.entry_id + ) + entity_entry = entity_registry.async_get(entity_id) assert entity_entry.device_id == switch_entity_entry.device_id device_entry = device_registry.async_get(device_entry.id) @@ -531,7 +540,10 @@ async def test_device( assert await hass.config_entries.async_setup(switch_as_x_config_entry.entry_id) await hass.async_block_till_done() - entity_entry = entity_registry.async_get(f"{target_domain}.abc") + entity_id = entity_registry.async_get_entity_id( + target_domain, DOMAIN, switch_as_x_config_entry.entry_id + ) + entity_entry = entity_registry.async_get(entity_id) assert entity_entry assert entity_entry.device_id == switch_entity_entry.device_id @@ -1164,8 +1176,8 @@ async def test_migrate( assert config_entry.minor_version == SwitchAsXConfigFlowHandler.MINOR_VERSION # Check the state and entity registry entry are present - assert hass.states.get(f"{target_domain}.abc") is not None - assert entity_registry.async_get(f"{target_domain}.abc") is not None + assert hass.states.get(switch_as_x_entity_entry.entity_id) is not None + assert entity_registry.async_get(switch_as_x_entity_entry.entity_id) is not None # The switch_as_x config entry was never added to the device, so migration does # not change the switch_as_x entity's device link diff --git a/tests/components/tasmota/test_discovery.py b/tests/components/tasmota/test_discovery.py index 0f59b1ce6140d..efb8867d064da 100644 --- a/tests/components/tasmota/test_discovery.py +++ b/tests/components/tasmota/test_discovery.py @@ -31,7 +31,9 @@ def _get_device_for_config_entry( connections: set[tuple[str, str]] | None = None, ) -> dr.DeviceEntry | None: """Return the device for a config entry matching identifiers or connections.""" - for device in device_registry.devices.get_entries(identifiers, connections): + for device in device_registry.async_get_devices( + identifiers=identifiers, connections=connections + ): if device.config_entry_id == config_entry_id: return device return None diff --git a/tests/components/template/test_alarm_control_panel.py b/tests/components/template/test_alarm_control_panel.py index eb3450955efbd..856e2fff5b5c3 100644 --- a/tests/components/template/test_alarm_control_panel.py +++ b/tests/components/template/test_alarm_control_panel.py @@ -642,7 +642,9 @@ async def test_device_id( assert await hass.config_entries.async_setup(template_config_entry.entry_id) await hass.async_block_till_done() - template_entity = entity_registry.async_get("alarm_control_panel.my_template") + template_entity = entity_registry.async_get( + "alarm_control_panel.mock_title_my_template" + ) assert template_entity is not None assert template_entity.device_id == device_entry.id diff --git a/tests/components/template/test_binary_sensor.py b/tests/components/template/test_binary_sensor.py index e90df7d64ff81..22b8ef25f3ebc 100644 --- a/tests/components/template/test_binary_sensor.py +++ b/tests/components/template/test_binary_sensor.py @@ -1536,7 +1536,7 @@ async def test_device_id( assert await hass.config_entries.async_setup(template_config_entry.entry_id) await hass.async_block_till_done() - template_entity = entity_registry.async_get("binary_sensor.my_template") + template_entity = entity_registry.async_get("binary_sensor.mock_title_my_template") assert template_entity is not None assert template_entity.device_id == device_entry.id diff --git a/tests/components/template/test_button.py b/tests/components/template/test_button.py index 8a9e8403e05de..cefbb2c9fc9d6 100644 --- a/tests/components/template/test_button.py +++ b/tests/components/template/test_button.py @@ -341,7 +341,7 @@ async def test_device_id( assert await hass.config_entries.async_setup(template_config_entry.entry_id) await hass.async_block_till_done() - template_entity = entity_registry.async_get("button.my_template") + template_entity = entity_registry.async_get("button.mock_title_my_template") assert template_entity is not None assert template_entity.device_id == device_entry.id diff --git a/tests/components/template/test_device_tracker.py b/tests/components/template/test_device_tracker.py index 624d6208a6ee2..a4192491471dd 100644 --- a/tests/components/template/test_device_tracker.py +++ b/tests/components/template/test_device_tracker.py @@ -207,7 +207,7 @@ async def test_device_id( assert await hass.config_entries.async_setup(template_config_entry.entry_id) await hass.async_block_till_done() - template_entity = entity_registry.async_get("device_tracker.my_template") + template_entity = entity_registry.async_get("device_tracker.mock_title_my_template") assert template_entity is not None assert template_entity.device_id == device_entry.id diff --git a/tests/components/template/test_event.py b/tests/components/template/test_event.py index e3713fdd24b56..46d15f2a0dadd 100644 --- a/tests/components/template/test_event.py +++ b/tests/components/template/test_event.py @@ -194,7 +194,7 @@ async def test_device_id( assert await hass.config_entries.async_setup(template_config_entry.entry_id) await hass.async_block_till_done() - template_entity = entity_registry.async_get("event.my_template") + template_entity = entity_registry.async_get("event.mock_title_my_template") assert template_entity is not None assert template_entity.device_id == device_entry.id diff --git a/tests/components/template/test_image.py b/tests/components/template/test_image.py index 541c9a5f06d3f..02a9b5972dc34 100644 --- a/tests/components/template/test_image.py +++ b/tests/components/template/test_image.py @@ -597,7 +597,7 @@ async def test_device_id( assert await hass.config_entries.async_setup(template_config_entry.entry_id) await hass.async_block_till_done() - template_entity = entity_registry.async_get("image.my_template") + template_entity = entity_registry.async_get("image.mock_title_my_template") assert template_entity is not None assert template_entity.device_id == device_entry.id diff --git a/tests/components/template/test_init.py b/tests/components/template/test_init.py index f1c2233ba4ced..af518f5a7b302 100644 --- a/tests/components/template/test_init.py +++ b/tests/components/template/test_init.py @@ -438,7 +438,9 @@ def check_template_entities( assert await hass.config_entries.async_setup(template_config_entry.entry_id) await hass.async_block_till_done() - template_entity_id = f"{config_entry_options['template_type']}.my_template" + template_entity_id = ( + f"{config_entry_options['template_type']}.mock_title_my_template" + ) # Confirm that the template config entry has not been added to either device # and that the entities are linked to device 1 @@ -676,7 +678,7 @@ async def test_migration_1_1( # entity is linked to the source device device_entry = device_registry.async_get(device_entry.id) assert template_config_entry.entry_id not in device_entry.config_entries - template_entity_entry = entity_registry.async_get("sensor.my_template") + template_entity_entry = entity_registry.async_get("sensor.mock_title_my_template") assert template_entity_entry.device_id == device_entry.id assert template_config_entry.version == 2 diff --git a/tests/components/template/test_number.py b/tests/components/template/test_number.py index 1a8339a932095..bb46638d52ea4 100644 --- a/tests/components/template/test_number.py +++ b/tests/components/template/test_number.py @@ -352,7 +352,7 @@ async def test_device_id( assert await hass.config_entries.async_setup(template_config_entry.entry_id) await hass.async_block_till_done() - template_entity = entity_registry.async_get("number.my_template") + template_entity = entity_registry.async_get("number.mock_title_my_template") assert template_entity is not None assert template_entity.device_id == device_entry.id diff --git a/tests/components/template/test_select.py b/tests/components/template/test_select.py index 9b8f4b322551a..be2045d1ce2e9 100644 --- a/tests/components/template/test_select.py +++ b/tests/components/template/test_select.py @@ -324,7 +324,7 @@ async def test_device_id( assert await hass.config_entries.async_setup(template_config_entry.entry_id) await hass.async_block_till_done() - template_entity = entity_registry.async_get("select.my_template") + template_entity = entity_registry.async_get("select.mock_title_my_template") assert template_entity is not None assert template_entity.device_id == device_entry.id diff --git a/tests/components/template/test_sensor.py b/tests/components/template/test_sensor.py index 4f2e7b33ccea2..480046a4f54ae 100644 --- a/tests/components/template/test_sensor.py +++ b/tests/components/template/test_sensor.py @@ -1836,7 +1836,7 @@ async def test_device_id( assert await hass.config_entries.async_setup(template_config_entry.entry_id) await hass.async_block_till_done() - template_entity = entity_registry.async_get("sensor.my_template") + template_entity = entity_registry.async_get("sensor.mock_title_my_template") assert template_entity is not None assert template_entity.device_id == device_entry.id diff --git a/tests/components/template/test_switch.py b/tests/components/template/test_switch.py index 99d84debb893a..cc1732b499ffe 100644 --- a/tests/components/template/test_switch.py +++ b/tests/components/template/test_switch.py @@ -712,7 +712,7 @@ async def test_device_id( assert await hass.config_entries.async_setup(template_config_entry.entry_id) await hass.async_block_till_done() - template_entity = entity_registry.async_get("switch.my_template") + template_entity = entity_registry.async_get("switch.mock_title_my_template") assert template_entity is not None assert template_entity.device_id == device_entry.id diff --git a/tests/components/template/test_update.py b/tests/components/template/test_update.py index b35f1d026642d..f75c177c5c42e 100644 --- a/tests/components/template/test_update.py +++ b/tests/components/template/test_update.py @@ -186,7 +186,7 @@ async def test_device_id( assert await hass.config_entries.async_setup(template_config_entry.entry_id) await hass.async_block_till_done() - template_entity = entity_registry.async_get(TEST_UPDATE.entity_id) + template_entity = entity_registry.async_get("update.mock_title_template_update") assert template_entity is not None assert template_entity.device_id == device_entry.id diff --git a/tests/components/threshold/test_binary_sensor.py b/tests/components/threshold/test_binary_sensor.py index b227f757b9c5d..10573a71f15cd 100644 --- a/tests/components/threshold/test_binary_sensor.py +++ b/tests/components/threshold/test_binary_sensor.py @@ -563,13 +563,13 @@ async def test_device_id( device_id=source_device_entry.id, ) await hass.async_block_till_done() - assert entity_registry.async_get("sensor.test_source") is not None + assert entity_registry.async_get(source_entity.entity_id) is not None utility_meter_config_entry = MockConfigEntry( data={}, domain=DOMAIN, options={ - CONF_ENTITY_ID: "sensor.test_source", + CONF_ENTITY_ID: source_entity.entity_id, CONF_HYSTERESIS: 0.0, CONF_LOWER: -2.0, CONF_NAME: "Threshold", @@ -583,7 +583,9 @@ async def test_device_id( assert await hass.config_entries.async_setup(utility_meter_config_entry.entry_id) await hass.async_block_till_done() - utility_meter_entity = entity_registry.async_get("binary_sensor.threshold") + utility_meter_entity = entity_registry.async_get( + "binary_sensor.mock_title_threshold" + ) assert utility_meter_entity is not None assert utility_meter_entity.device_id == source_entity.device_id diff --git a/tests/components/threshold/test_init.py b/tests/components/threshold/test_init.py index 0f8c1539880f2..ceafee7c78b6a 100644 --- a/tests/components/threshold/test_init.py +++ b/tests/components/threshold/test_init.py @@ -196,7 +196,9 @@ def _get_device_config_entries(entry: er.RegistryEntry) -> set[str]: assert config_entry.entry_id not in _get_device_config_entries(run1_entry) assert config_entry.entry_id not in _get_device_config_entries(run2_entry) - threshold_entity_entry = entity_registry.async_get("binary_sensor.my_threshold") + threshold_entity_entry = entity_registry.async_get( + "binary_sensor.initial_my_threshold" + ) assert threshold_entity_entry.device_id == run1_entry.device_id hass.config_entries.async_update_entry( @@ -208,7 +210,9 @@ def _get_device_config_entries(entry: er.RegistryEntry) -> set[str]: # Check that the device association has updated assert config_entry.entry_id not in _get_device_config_entries(run1_entry) assert config_entry.entry_id not in _get_device_config_entries(run2_entry) - threshold_entity_entry = entity_registry.async_get("binary_sensor.my_threshold") + threshold_entity_entry = entity_registry.async_get( + "binary_sensor.initial_my_threshold" + ) assert threshold_entity_entry.device_id == run2_entry.device_id @@ -225,7 +229,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed( assert await hass.config_entries.async_setup(threshold_config_entry.entry_id) await hass.async_block_till_done() - threshold_entity_entry = entity_registry.async_get("binary_sensor.my_threshold") + threshold_entity_entry = entity_registry.async_get( + "binary_sensor.mock_title_my_threshold" + ) assert threshold_entity_entry.device_id == sensor_entity_entry.device_id sensor_device = device_registry.async_get(sensor_device.id) @@ -244,7 +250,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed( mock_unload_entry.assert_not_called() # Check that the entity is no longer linked to the source device - threshold_entity_entry = entity_registry.async_get("binary_sensor.my_threshold") + threshold_entity_entry = entity_registry.async_get( + "binary_sensor.mock_title_my_threshold" + ) assert threshold_entity_entry.device_id is None # Check that the device is removed @@ -269,7 +277,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed_shared_d assert await hass.config_entries.async_setup(threshold_config_entry.entry_id) await hass.async_block_till_done() - threshold_entity_entry = entity_registry.async_get("binary_sensor.my_threshold") + threshold_entity_entry = entity_registry.async_get( + "binary_sensor.mock_title_my_threshold" + ) assert threshold_entity_entry.device_id == sensor_entity_entry.device_id sensor_device = device_registry.async_get(sensor_device.id) @@ -288,7 +298,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed_shared_d mock_unload_entry.assert_not_called() # Check that the entity is no longer linked to the source device - threshold_entity_entry = entity_registry.async_get("binary_sensor.my_threshold") + threshold_entity_entry = entity_registry.async_get( + "binary_sensor.mock_title_my_threshold" + ) assert threshold_entity_entry.device_id is None # Check that the source device is not removed @@ -317,7 +329,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed_from_dev assert await hass.config_entries.async_setup(threshold_config_entry.entry_id) await hass.async_block_till_done() - threshold_entity_entry = entity_registry.async_get("binary_sensor.my_threshold") + threshold_entity_entry = entity_registry.async_get( + "binary_sensor.mock_title_my_threshold" + ) assert threshold_entity_entry.device_id == sensor_entity_entry.device_id sensor_device = device_registry.async_get(sensor_device.id) @@ -337,7 +351,9 @@ async def test_async_handle_source_entity_changes_source_entity_removed_from_dev mock_unload_entry.assert_called_once() # Check that the entity is no longer linked to the source device - threshold_entity_entry = entity_registry.async_get("binary_sensor.my_threshold") + threshold_entity_entry = entity_registry.async_get( + "binary_sensor.mock_title_my_threshold" + ) assert threshold_entity_entry.device_id is None # Check that the threshold config entry is not in the device @@ -369,7 +385,9 @@ async def test_async_handle_source_entity_changes_source_entity_moved_other_devi assert await hass.config_entries.async_setup(threshold_config_entry.entry_id) await hass.async_block_till_done() - threshold_entity_entry = entity_registry.async_get("binary_sensor.my_threshold") + threshold_entity_entry = entity_registry.async_get( + "binary_sensor.mock_title_my_threshold" + ) assert threshold_entity_entry.device_id == sensor_entity_entry.device_id sensor_device = device_registry.async_get(sensor_device.id) @@ -391,7 +409,9 @@ async def test_async_handle_source_entity_changes_source_entity_moved_other_devi mock_unload_entry.assert_called_once() # Check that the entity is linked to the other device - threshold_entity_entry = entity_registry.async_get("binary_sensor.my_threshold") + threshold_entity_entry = entity_registry.async_get( + "binary_sensor.mock_title_my_threshold" + ) assert threshold_entity_entry.device_id == sensor_device_2.id # Check that the derivative config entry is not in any of the devices @@ -419,7 +439,9 @@ async def test_async_handle_source_entity_new_entity_id( assert await hass.config_entries.async_setup(threshold_config_entry.entry_id) await hass.async_block_till_done() - threshold_entity_entry = entity_registry.async_get("binary_sensor.my_threshold") + threshold_entity_entry = entity_registry.async_get( + "binary_sensor.mock_title_my_threshold" + ) assert threshold_entity_entry.device_id == sensor_entity_entry.device_id sensor_device = device_registry.async_get(sensor_device.id) @@ -486,7 +508,9 @@ async def test_migration_1_1( # is linked to the source device sensor_device = device_registry.async_get(sensor_device.id) assert threshold_config_entry.entry_id not in sensor_device.config_entries - threshold_entity_entry = entity_registry.async_get("binary_sensor.my_threshold") + threshold_entity_entry = entity_registry.async_get( + "binary_sensor.mock_title_my_threshold" + ) assert threshold_entity_entry.device_id == sensor_entity_entry.device_id assert threshold_config_entry.version == 1 diff --git a/tests/components/trend/test_binary_sensor.py b/tests/components/trend/test_binary_sensor.py index 5d366b91564ae..ee61f70c9de7f 100644 --- a/tests/components/trend/test_binary_sensor.py +++ b/tests/components/trend/test_binary_sensor.py @@ -428,14 +428,14 @@ async def test_device_id( device_id=source_device_entry.id, ) await hass.async_block_till_done() - assert entity_registry.async_get("sensor.test_source") is not None + assert entity_registry.async_get(source_entity.entity_id) is not None trend_config_entry = MockConfigEntry( data={}, domain=DOMAIN, options={ "name": "Trend", - "entity_id": "sensor.test_source", + "entity_id": source_entity.entity_id, "invert": False, }, title="Trend", @@ -445,7 +445,7 @@ async def test_device_id( assert await hass.config_entries.async_setup(trend_config_entry.entry_id) await hass.async_block_till_done() - trend_entity = entity_registry.async_get("binary_sensor.trend") + trend_entity = entity_registry.async_get("binary_sensor.mock_title_trend") assert trend_entity is not None assert trend_entity.device_id == source_entity.device_id diff --git a/tests/components/trend/test_init.py b/tests/components/trend/test_init.py index 50533b8f1d646..632a2e09e6ca5 100644 --- a/tests/components/trend/test_init.py +++ b/tests/components/trend/test_init.py @@ -147,7 +147,7 @@ async def test_async_handle_source_entity_changes_source_entity_removed( assert await hass.config_entries.async_setup(trend_config_entry.entry_id) await hass.async_block_till_done() - trend_entity_entry = entity_registry.async_get("binary_sensor.my_trend") + trend_entity_entry = entity_registry.async_get("binary_sensor.mock_title_my_trend") assert trend_entity_entry.device_id == sensor_entity_entry.device_id sensor_device = device_registry.async_get(sensor_device.id) @@ -166,7 +166,7 @@ async def test_async_handle_source_entity_changes_source_entity_removed( mock_unload_entry.assert_called_once() # Check that the helper entity is removed - assert not entity_registry.async_get("binary_sensor.my_trend") + assert not entity_registry.async_get(trend_entity_entry.entity_id) # Check that the device is removed assert not device_registry.async_get(sensor_device.id) @@ -194,7 +194,7 @@ async def test_async_handle_source_entity_changes_source_entity_removed_shared_d assert await hass.config_entries.async_setup(trend_config_entry.entry_id) await hass.async_block_till_done() - trend_entity_entry = entity_registry.async_get("binary_sensor.my_trend") + trend_entity_entry = entity_registry.async_get("binary_sensor.mock_title_my_trend") assert trend_entity_entry.device_id == sensor_entity_entry.device_id sensor_device = device_registry.async_get(sensor_device.id) @@ -213,7 +213,7 @@ async def test_async_handle_source_entity_changes_source_entity_removed_shared_d mock_unload_entry.assert_called_once() # Check that the helper entity is removed - assert not entity_registry.async_get("binary_sensor.my_trend") + assert not entity_registry.async_get(trend_entity_entry.entity_id) # Check that the source device is not removed assert device_registry.async_get(sensor_device.id) is not None @@ -241,7 +241,7 @@ async def test_async_handle_source_entity_changes_source_entity_removed_from_dev assert await hass.config_entries.async_setup(trend_config_entry.entry_id) await hass.async_block_till_done() - trend_entity_entry = entity_registry.async_get("binary_sensor.my_trend") + trend_entity_entry = entity_registry.async_get("binary_sensor.mock_title_my_trend") assert trend_entity_entry.device_id == sensor_entity_entry.device_id sensor_device = device_registry.async_get(sensor_device.id) @@ -261,7 +261,7 @@ async def test_async_handle_source_entity_changes_source_entity_removed_from_dev mock_unload_entry.assert_called_once() # Check that the entity is no longer linked to the source device - trend_entity_entry = entity_registry.async_get("binary_sensor.my_trend") + trend_entity_entry = entity_registry.async_get(trend_entity_entry.entity_id) assert trend_entity_entry.device_id is None # Check that the trend config entry is not in the device @@ -293,7 +293,7 @@ async def test_async_handle_source_entity_changes_source_entity_moved_other_devi assert await hass.config_entries.async_setup(trend_config_entry.entry_id) await hass.async_block_till_done() - trend_entity_entry = entity_registry.async_get("binary_sensor.my_trend") + trend_entity_entry = entity_registry.async_get("binary_sensor.mock_title_my_trend") assert trend_entity_entry.device_id == sensor_entity_entry.device_id sensor_device = device_registry.async_get(sensor_device.id) @@ -315,7 +315,7 @@ async def test_async_handle_source_entity_changes_source_entity_moved_other_devi mock_unload_entry.assert_called_once() # Check that the entity is linked to the other device - trend_entity_entry = entity_registry.async_get("binary_sensor.my_trend") + trend_entity_entry = entity_registry.async_get(trend_entity_entry.entity_id) assert trend_entity_entry.device_id == sensor_device_2.id # Check that the trend config entry is not in any of the devices @@ -343,7 +343,7 @@ async def test_async_handle_source_entity_new_entity_id( assert await hass.config_entries.async_setup(trend_config_entry.entry_id) await hass.async_block_till_done() - trend_entity_entry = entity_registry.async_get("binary_sensor.my_trend") + trend_entity_entry = entity_registry.async_get("binary_sensor.mock_title_my_trend") assert trend_entity_entry.device_id == sensor_entity_entry.device_id sensor_device = device_registry.async_get(sensor_device.id) @@ -408,7 +408,7 @@ async def test_migration_1_1( # is linked to the source device sensor_device = device_registry.async_get(sensor_device.id) assert trend_config_entry.entry_id not in sensor_device.config_entries - trend_entity_entry = entity_registry.async_get("binary_sensor.my_trend") + trend_entity_entry = entity_registry.async_get("binary_sensor.mock_title_my_trend") assert trend_entity_entry.device_id == sensor_entity_entry.device_id assert trend_config_entry.version == 1 diff --git a/tests/components/utility_meter/test_config_flow.py b/tests/components/utility_meter/test_config_flow.py index 9c4c7a40021b4..0959f8b150b49 100644 --- a/tests/components/utility_meter/test_config_flow.py +++ b/tests/components/utility_meter/test_config_flow.py @@ -373,9 +373,9 @@ async def test_change_device_source( await hass.async_block_till_done() - input_sensor_entity_id_1 = "sensor.test_source1" - input_sensor_entity_id_2 = "sensor.test_source2" - input_sensor_entity_id_3 = "sensor.test_source3" + input_sensor_entity_id_1 = source_entity_1.entity_id + input_sensor_entity_id_2 = source_entity_2.entity_id + input_sensor_entity_id_3 = source_entity_3.entity_id # Test the existence of configured source entities assert entity_registry.async_get(input_sensor_entity_id_1) is not None diff --git a/tests/components/utility_meter/test_init.py b/tests/components/utility_meter/test_init.py index 31e3b80c493c9..800692ab9546d 100644 --- a/tests/components/utility_meter/test_init.py +++ b/tests/components/utility_meter/test_init.py @@ -560,13 +560,13 @@ async def test_setup_and_remove_config_entry( @pytest.mark.parametrize( ("tariffs", "expected_entities"), [ - ([], {"sensor.my_utility_meter"}), + ([], {"sensor.mock_title_my_utility_meter"}), ( ["peak", "offpeak"], { "select.my_utility_meter", - "sensor.my_utility_meter_offpeak", - "sensor.my_utility_meter_peak", + "sensor.mock_title_my_utility_meter_offpeak", + "sensor.mock_title_my_utility_meter_peak", }, ), ], @@ -632,13 +632,13 @@ async def test_async_handle_source_entity_changes_source_entity_removed( @pytest.mark.parametrize( ("tariffs", "expected_entities"), [ - ([], {"sensor.my_utility_meter"}), + ([], {"sensor.mock_title_my_utility_meter"}), ( ["peak", "offpeak"], { "select.my_utility_meter", - "sensor.my_utility_meter_offpeak", - "sensor.my_utility_meter_peak", + "sensor.mock_title_my_utility_meter_offpeak", + "sensor.mock_title_my_utility_meter_peak", }, ), ], @@ -706,13 +706,13 @@ async def test_async_handle_source_entity_changes_source_entity_removed_shared_d @pytest.mark.parametrize( ("tariffs", "expected_entities"), [ - ([], {"sensor.my_utility_meter"}), + ([], {"sensor.mock_title_my_utility_meter"}), ( ["peak", "offpeak"], { "select.my_utility_meter", - "sensor.my_utility_meter_offpeak", - "sensor.my_utility_meter_peak", + "sensor.mock_title_my_utility_meter_offpeak", + "sensor.mock_title_my_utility_meter_peak", }, ), ], @@ -779,13 +779,13 @@ async def test_async_handle_source_entity_changes_source_entity_removed_from_dev @pytest.mark.parametrize( ("tariffs", "expected_entities"), [ - ([], {"sensor.my_utility_meter"}), + ([], {"sensor.mock_title_my_utility_meter"}), ( ["peak", "offpeak"], { "select.my_utility_meter", - "sensor.my_utility_meter_offpeak", - "sensor.my_utility_meter_peak", + "sensor.mock_title_my_utility_meter_offpeak", + "sensor.mock_title_my_utility_meter_peak", }, ), ], @@ -862,13 +862,13 @@ async def test_async_handle_source_entity_changes_source_entity_moved_other_devi @pytest.mark.parametrize( ("tariffs", "expected_entities"), [ - ([], {"sensor.my_utility_meter"}), + ([], {"sensor.mock_title_my_utility_meter"}), ( ["peak", "offpeak"], { "select.my_utility_meter", - "sensor.my_utility_meter_offpeak", - "sensor.my_utility_meter_peak", + "sensor.mock_title_my_utility_meter_offpeak", + "sensor.mock_title_my_utility_meter_peak", }, ), ], @@ -930,13 +930,13 @@ async def test_async_handle_source_entity_new_entity_id( @pytest.mark.parametrize( ("tariffs", "expected_entities"), [ - ([], {"sensor.my_utility_meter"}), + ([], {"sensor.mock_title_my_utility_meter"}), ( ["peak", "offpeak"], { "select.my_utility_meter", - "sensor.my_utility_meter_offpeak", - "sensor.my_utility_meter_peak", + "sensor.mock_title_my_utility_meter_offpeak", + "sensor.mock_title_my_utility_meter_peak", }, ), ], diff --git a/tests/components/utility_meter/test_select.py b/tests/components/utility_meter/test_select.py index 1f54f3b500a16..ccd0fc22cc717 100644 --- a/tests/components/utility_meter/test_select.py +++ b/tests/components/utility_meter/test_select.py @@ -90,7 +90,7 @@ async def test_device_id( device_id=source_device_entry.id, ) await hass.async_block_till_done() - assert entity_registry.async_get("sensor.test_source") is not None + assert entity_registry.async_get(source_entity.entity_id) is not None utility_meter_config_entry = MockConfigEntry( data={}, @@ -102,7 +102,7 @@ async def test_device_id( "net_consumption": False, "offset": 0, "periodically_resetting": True, - "source": "sensor.test_source", + "source": source_entity.entity_id, "tariffs": ["peak", "offpeak"], }, title="Energy", diff --git a/tests/components/utility_meter/test_sensor.py b/tests/components/utility_meter/test_sensor.py index c0726cbb736fb..6e1ca07e802be 100644 --- a/tests/components/utility_meter/test_sensor.py +++ b/tests/components/utility_meter/test_sensor.py @@ -2059,7 +2059,7 @@ async def test_device_id( device_id=source_device_entry.id, ) await hass.async_block_till_done() - assert entity_registry.async_get("sensor.test_source") is not None + assert entity_registry.async_get(source_entity.entity_id) is not None utility_meter_config_entry = MockConfigEntry( data={}, @@ -2071,7 +2071,7 @@ async def test_device_id( "net_consumption": False, "offset": 0, "periodically_resetting": True, - "source": "sensor.test_source", + "source": source_entity.entity_id, "tariffs": ["peak", "offpeak"], }, title="Energy", @@ -2082,11 +2082,11 @@ async def test_device_id( assert await hass.config_entries.async_setup(utility_meter_config_entry.entry_id) await hass.async_block_till_done() - utility_meter_entity = entity_registry.async_get("sensor.energy_peak") + utility_meter_entity = entity_registry.async_get("sensor.mock_title_energy_peak") assert utility_meter_entity is not None assert utility_meter_entity.device_id == source_entity.device_id - utility_meter_entity = entity_registry.async_get("sensor.energy_offpeak") + utility_meter_entity = entity_registry.async_get("sensor.mock_title_energy_offpeak") assert utility_meter_entity is not None assert utility_meter_entity.device_id == source_entity.device_id @@ -2100,7 +2100,7 @@ async def test_device_id( "net_consumption": False, "offset": 0, "periodically_resetting": True, - "source": "sensor.test_source", + "source": source_entity.entity_id, "tariffs": [], }, title="Energy", @@ -2113,7 +2113,9 @@ async def test_device_id( ) await hass.async_block_till_done() - utility_meter_no_tariffs_entity = entity_registry.async_get("sensor.energy") + utility_meter_no_tariffs_entity = entity_registry.async_get( + "sensor.mock_title_energy" + ) assert utility_meter_no_tariffs_entity is not None assert utility_meter_no_tariffs_entity.device_id == source_entity.device_id diff --git a/tests/components/withings/test_sensor.py b/tests/components/withings/test_sensor.py index 718ca42b4ca6a..010bf420f2298 100644 --- a/tests/components/withings/test_sensor.py +++ b/tests/components/withings/test_sensor.py @@ -473,9 +473,7 @@ def _device_for_entry(entry: MockConfigEntry) -> dr.DeviceEntry | None: return next( ( device - for device in device_registry.devices.get_entries( - identifiers=identifiers - ) + for device in device_registry.async_get_devices(identifiers=identifiers) if device.config_entry_id == entry.entry_id ), None, diff --git a/tests/components/wmspro/test_init.py b/tests/components/wmspro/test_init.py index 53653415ddf3c..76dcdf75fb052 100644 --- a/tests/components/wmspro/test_init.py +++ b/tests/components/wmspro/test_init.py @@ -91,8 +91,8 @@ async def test_device_setup( assert len(mock_hub_configuration.mock_calls) == 1 assert len(mock_hub_status.mock_calls) == len(mock_hub_configuration.destinations) - device_entries = device_registry.devices.get_devices_for_config_entry_id( - mock_config_entry.entry_id + device_entries = dr.async_entries_for_config_entry( + device_registry, mock_config_entry.entry_id ) assert len(device_entries) > len(mock_hub_configuration.destinations) diff --git a/tests/components/zwave_js/conftest.py b/tests/components/zwave_js/conftest.py index 6a5318897a914..4d4ce3e01b41e 100644 --- a/tests/components/zwave_js/conftest.py +++ b/tests/components/zwave_js/conftest.py @@ -636,9 +636,12 @@ def mock_client_fixture( listen_block: asyncio.Event, ): """Mock a client.""" - with patch( - "homeassistant.components.zwave_js.ZwaveClient", autospec=True - ) as client_class: + with ( + patch( + "homeassistant.components.zwave_js.ZwaveClient", autospec=True + ) as client_class, + patch("homeassistant.components.zwave_js.config_flow.Client", client_class), + ): client = client_class.return_value async def connect(): diff --git a/tests/components/zwave_js/test_api.py b/tests/components/zwave_js/test_api.py index 2d1dc6aef3508..b417c244b39c5 100644 --- a/tests/components/zwave_js/test_api.py +++ b/tests/components/zwave_js/test_api.py @@ -101,7 +101,11 @@ from homeassistant.helpers import device_registry as dr from tests.common import MockConfigEntry, MockUser -from tests.typing import ClientSessionGenerator, WebSocketGenerator +from tests.typing import ( + ClientSessionGenerator, + MockHAClientWebSocket, + WebSocketGenerator, +) CONTROLLER_PATCH_PREFIX = "zwave_js_server.model.controller.Controller" @@ -5264,6 +5268,147 @@ async def test_subscribe_node_statistics( assert msg["error"]["code"] == ERR_NOT_LOADED +def _stats_updated_event(node_id: int, repeater_node_id: int) -> Event: + """Return a statistics updated event with a route through the repeater.""" + return Event( + "statistics updated", + { + "source": "node", + "event": "statistics updated", + "nodeId": node_id, + "statistics": { + "commandsTX": 1, + "commandsRX": 2, + "commandsDroppedTX": 3, + "commandsDroppedRX": 4, + "timeoutResponse": 5, + "lwr": { + "protocolDataRate": 1, + "rssi": 1, + "repeaters": [repeater_node_id], + "repeaterRSSI": [1], + }, + }, + }, + ) + + +async def _subscribe_node_statistics( + ws_client: MockHAClientWebSocket, device_id: str +) -> None: + """Subscribe to node statistics and consume the initial state event.""" + await ws_client.send_json_auto_id( + { + TYPE: "zwave_js/subscribe_node_statistics", + DEVICE_ID: device_id, + } + ) + msg = await ws_client.receive_json() + assert msg["success"] + msg = await ws_client.receive_json() + assert msg["event"]["event"] == "statistics updated" + + +async def test_node_statistics_route_with_removed_node( + hass: HomeAssistant, + multisensor_6: Node, + wallmote_central_scene: Node, + integration: MockConfigEntry, + client: MagicMock, + hass_ws_client: WebSocketGenerator, +) -> None: + """Test a route referencing a node that was removed from the network. + + Resolving the repeater in the controller's node collection raises + KeyError, which must null the route instead of breaking the subscription. + """ + ws_client = await hass_ws_client(hass) + device = get_device(hass, multisensor_6) + wallmote_device = get_device(hass, wallmote_central_scene) + await _subscribe_node_statistics(ws_client, device.id) + + event = _stats_updated_event(multisensor_6.node_id, 999) + event.data["statistics"]["nlwr"] = { + "protocolDataRate": 2, + "rssi": 2, + "repeaters": [wallmote_central_scene.node_id], + "repeaterRSSI": [2], + } + client.driver.controller.receive_event(event) + msg = await ws_client.receive_json() + + assert msg["event"]["commands_tx"] == 1 + assert msg["event"]["lwr"] is None + assert msg["event"]["nlwr"] == { + "protocol_data_rate": 2, + "rssi": 2, + "repeaters": [wallmote_device.id], + "repeater_rssi": [2], + "route_failed_between": None, + } + + +async def test_node_statistics_route_with_removed_device( + hass: HomeAssistant, + device_registry: dr.DeviceRegistry, + multisensor_6: Node, + wallmote_central_scene: Node, + integration: MockConfigEntry, + client: MagicMock, + hass_ws_client: WebSocketGenerator, +) -> None: + """Test a route referencing a node without a device registry entry. + + Converting the repeater to a device ID raises ValueError, which must null + the route instead of breaking the subscription. + """ + ws_client = await hass_ws_client(hass) + device = get_device(hass, multisensor_6) + wallmote_device = get_device(hass, wallmote_central_scene) + await _subscribe_node_statistics(ws_client, device.id) + + device_registry.async_remove_device(wallmote_device.id) + await hass.async_block_till_done() + + client.driver.controller.receive_event( + _stats_updated_event(multisensor_6.node_id, wallmote_central_scene.node_id) + ) + msg = await ws_client.receive_json() + + assert msg["event"]["commands_tx"] == 1 + assert msg["event"]["lwr"] is None + + +async def test_node_statistics_route_with_unloaded_entry( + hass: HomeAssistant, + multisensor_6: Node, + wallmote_central_scene: Node, + integration: MockConfigEntry, + client: MagicMock, + hass_ws_client: WebSocketGenerator, +) -> None: + """Test a route received after the config entry was unloaded. + + async_get_config_entry_from_node raises StopIteration when no loaded + config entry owns the node, which must null the route instead of + breaking the subscription. + """ + ws_client = await hass_ws_client(hass) + device = get_device(hass, multisensor_6) + await _subscribe_node_statistics(ws_client, device.id) + + await hass.config_entries.async_unload(integration.entry_id) + await hass.async_block_till_done() + + client.driver.controller.receive_event( + _stats_updated_event(multisensor_6.node_id, wallmote_central_scene.node_id) + ) + msg = await ws_client.receive_json() + + assert msg["event"]["commands_tx"] == 1 + assert msg["event"]["lwr"] is None + + async def test_hard_reset_controller( hass: HomeAssistant, caplog: pytest.LogCaptureFixture, diff --git a/tests/components/zwave_js/test_config_flow.py b/tests/components/zwave_js/test_config_flow.py index c1f95ba0b200a..ed8ad08afe3d1 100644 --- a/tests/components/zwave_js/test_config_flow.py +++ b/tests/components/zwave_js/test_config_flow.py @@ -14,7 +14,7 @@ import aiohttp import pytest from voluptuous import InInvalid -from zwave_js_server.exceptions import FailedCommand +from zwave_js_server.exceptions import ConnectionFailed, FailedCommand from zwave_js_server.model.node import Node from zwave_js_server.version import VersionInfo @@ -1058,7 +1058,7 @@ async def mock_restart_addon(addon_slug: str) -> None: assert client.connect.call_count == 2 await hass.async_block_till_done() - assert client.connect.call_count == 4 + assert client.connect.call_count == 3 assert entry.state is config_entries.ConfigEntryState.LOADED assert client.driver.controller.async_restore_nvm.call_count == 1 assert len(events) == 2 @@ -1073,7 +1073,126 @@ async def mock_restart_addon(addon_slug: str) -> None: assert entry.data["usb_path"] == USB_DISCOVERY_INFO.device assert entry.data["socket_path"] is None assert entry.data["use_addon"] is True - assert "keep_old_devices" not in entry.data + assert entry.unique_id == "3245146787" + + +@pytest.mark.usefixtures( + "supervisor", + "addon_running", + "backup_nvm", + "climate_radio_thermostat_ct100_plus", + "lock_schlage_be469", +) +async def test_usb_discovery_migration_new_stick( + hass: HomeAssistant, + device_registry: dr.DeviceRegistry, + client: MagicMock, + integration: MockConfigEntry, + restart_addon: AsyncMock, + set_addon_options: AsyncMock, + addon_options: dict[str, Any], + mock_usb_serial_by_id: MagicMock, + get_server_version: AsyncMock, +) -> None: + """Test migration to a factory-new adapter keeps the old node devices.""" + addon_options["device"] = "/dev/ttyUSB0" + entry = integration + assert entry.unique_id == "3245146787" + hass.config_entries.async_update_entry( + entry, + data={ + "url": "ws://localhost:3000", + "use_addon": True, + "usb_path": "/dev/ttyUSB0", + }, + ) + + device_entries = dr.async_entries_for_config_entry(device_registry, entry.entry_id) + assert len(device_entries) == 3 + old_device_ids = {device.id for device in device_entries} + + nodes_snapshot = dict(client.driver.controller.nodes) + own_node_id = client.driver.controller.own_node.node_id + + async def mock_restart_addon(addon_slug: str) -> None: + # A factory-new adapter has its own home id and no nodes. + client.driver.controller.data["homeId"] = 1234 + client.driver.controller.nodes.clear() + client.driver.controller.nodes[own_node_id] = nodes_snapshot[own_node_id] + + restart_addon.side_effect = mock_restart_addon + + async def mock_restore_nvm(data: bytes, options: dict[str, bool] | None = None): + client.driver.controller.emit( + "nvm convert progress", + {"event": "nvm convert progress", "bytesRead": 100, "total": 200}, + ) + await asyncio.sleep(0) + client.driver.controller.emit( + "nvm restore progress", + {"event": "nvm restore progress", "bytesWritten": 100, "total": 200}, + ) + client.driver.controller.data["homeId"] = 3245146787 + client.driver.controller.nodes.update(nodes_snapshot) + client.driver.emit( + "driver ready", {"event": "driver ready", "source": "driver"} + ) + + client.driver.controller.async_restore_nvm = AsyncMock(side_effect=mock_restore_nvm) + + registry_events = async_capture_events(hass, dr.EVENT_DEVICE_REGISTRY_UPDATED) + + result = await hass.config_entries.flow.async_init( + DOMAIN, + context={"source": config_entries.SOURCE_USB}, + data=USB_DISCOVERY_INFO, + ) + + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "confirm_usb_migration" + + result = await hass.config_entries.flow.async_configure(result["flow_id"], {}) + + assert result["type"] is FlowResultType.SHOW_PROGRESS + assert result["step_id"] == "backup_nvm" + + with patch("pathlib.Path.write_bytes"): + await hass.async_block_till_done() + + result = await hass.config_entries.flow.async_configure(result["flow_id"]) + + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "instruct_unplug" + + result = await hass.config_entries.flow.async_configure(result["flow_id"], {}) + + assert result["type"] is FlowResultType.SHOW_PROGRESS + assert result["step_id"] == "start_addon" + + await hass.async_block_till_done() + + # The server, connected to the new adapter, reports the adapter's + # factory home id before the restore. + _set_home_id(get_server_version, 1234) + + result = await hass.config_entries.flow.async_configure(result["flow_id"]) + + assert result["type"] is FlowResultType.SHOW_PROGRESS + assert result["step_id"] == "restore_nvm" + assert entry.unique_id == "3245146787" + + await hass.async_block_till_done() + + result = await hass.config_entries.flow.async_configure(result["flow_id"]) + + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "migration_successful" + await hass.async_block_till_done() + + assert not [event for event in registry_events if event.data["action"] == "remove"] + device_entries = dr.async_entries_for_config_entry(device_registry, entry.entry_id) + assert len(device_entries) == 3 + assert {device.id for device in device_entries} == old_device_ids assert entry.unique_id == "3245146787" @@ -1197,8 +1316,7 @@ async def mock_restore_nvm(data: bytes, options: dict[str, bool] | None = None): assert entry.data["usb_path"] == USB_DISCOVERY_INFO.device assert entry.data["socket_path"] is None assert entry.data["use_addon"] is True - assert entry.unique_id == "1234" - assert "keep_old_devices" in entry.data + assert entry.unique_id == "3245146787" @pytest.mark.usefixtures("supervisor", "addon_info") @@ -4568,7 +4686,6 @@ async def test_reconfigure_migrate_no_addon( assert result["type"] is FlowResultType.ABORT assert result["reason"] == "addon_required" - assert "keep_old_devices" not in entry.data @pytest.mark.usefixtures("mock_sdk_version") @@ -4593,35 +4710,16 @@ async def test_reconfigure_migrate_low_sdk_version( assert result["type"] is FlowResultType.ABORT assert result["reason"] == "migration_low_sdk_version" - assert "keep_old_devices" not in entry.data @pytest.mark.usefixtures("supervisor", "addon_running") @pytest.mark.parametrize( - ( - "form_data", - "new_addon_options", - "restore_server_version_side_effect", - "final_unique_id", - "keep_old_devices", - "device_entry_count", - ), + ("form_data", "new_addon_options"), [ - ( - {CONF_USB_PATH: "/test"}, - {CONF_ADDON_DEVICE: "/test"}, - None, - "3245146787", - False, - 2, - ), + ({CONF_USB_PATH: "/test"}, {CONF_ADDON_DEVICE: "/test"}), ( {CONF_SOCKET_PATH: "esphome://1.2.3.4:1234"}, {CONF_ADDON_SOCKET: "esphome://1.2.3.4:1234"}, - aiohttp.ClientError("Boom"), - "5678", - True, - 4, ), ], ) @@ -4638,10 +4736,6 @@ async def test_reconfigure_migrate_with_addon( get_server_version: AsyncMock, form_data: dict[str, Any], new_addon_options: dict, - restore_server_version_side_effect: Exception | None, - final_unique_id: str, - keep_old_devices: bool, - device_entry_count: int, ) -> None: """Test migration flow with add-on.""" entry = integration @@ -4759,16 +4853,14 @@ async def test_reconfigure_migrate_with_addon( with patch("homeassistant.components.zwave_js.async_ensure_addon_running"): result = await hass.config_entries.flow.async_configure(result["flow_id"]) - assert entry.unique_id == "5678" - get_server_version.side_effect = restore_server_version_side_effect - _set_home_id(get_server_version, 3245146787) + assert entry.unique_id == "3245146787" assert result["type"] is FlowResultType.SHOW_PROGRESS assert result["step_id"] == "restore_nvm" assert client.connect.call_count == 2 await hass.async_block_till_done() - assert client.connect.call_count == 4 + assert client.connect.call_count == 3 assert entry.state is config_entries.ConfigEntryState.LOADED assert client.driver.controller.async_restore_nvm.call_count == 1 assert len(events) == 2 @@ -4783,10 +4875,9 @@ async def test_reconfigure_migrate_with_addon( assert entry.data[CONF_USB_PATH] == new_addon_options.get(CONF_ADDON_DEVICE) assert entry.data[CONF_SOCKET_PATH] == new_addon_options.get(CONF_ADDON_SOCKET) assert entry.data["use_addon"] is True - assert ("keep_old_devices" in entry.data) is keep_old_devices - assert entry.unique_id == final_unique_id + assert entry.unique_id == "3245146787" - assert len(device_registry.devices) == device_entry_count + assert len(device_registry.devices) == 2 controller_device_id_ext = ( f"{controller_device_id}-{controller_node.manufacturer_id}:" f"{controller_node.product_type}:{controller_node.product_id}" @@ -4931,8 +5022,7 @@ async def mock_restore_nvm(data: bytes, options: dict[str, bool] | None = None): assert entry.data["usb_path"] == "/test" assert entry.data["socket_path"] is None assert entry.data["use_addon"] is True - assert "keep_old_devices" in entry.data - assert entry.unique_id == "1234" + assert entry.unique_id == "3245146787" async def test_reconfigure_migrate_backup_failure( @@ -4961,7 +5051,6 @@ async def test_reconfigure_migrate_backup_failure( assert result["type"] is FlowResultType.ABORT assert result["reason"] == "backup_failed" - assert "keep_old_devices" not in entry.data @pytest.mark.usefixtures("backup_nvm") @@ -4996,7 +5085,6 @@ async def test_reconfigure_migrate_backup_file_failure( assert result["type"] is FlowResultType.ABORT assert result["reason"] == "backup_failed" - assert "keep_old_devices" not in entry.data @pytest.mark.usefixtures("supervisor", "addon_running", "backup_nvm") @@ -5062,7 +5150,82 @@ async def test_reconfigure_migrate_start_addon_failure( assert result["type"] is FlowResultType.ABORT assert result["reason"] == "addon_start_failed" - assert "keep_old_devices" not in entry.data + + +@pytest.mark.usefixtures( + "supervisor", "addon_running", "restart_addon", "backup_nvm", "restore_nvm" +) +async def test_reconfigure_migrate_connect_failure( + hass: HomeAssistant, + client: MagicMock, + integration: MockConfigEntry, + set_addon_options: AsyncMock, +) -> None: + """Test the restore step can be retried after a connect failure.""" + entry = integration + hass.config_entries.async_update_entry( + entry, data={**entry.data, "use_addon": True} + ) + + connect_side_effect = client.connect.side_effect + client.connect.side_effect = ConnectionFailed("test_error") + + result = await entry.start_reconfigure_flow(hass) + + assert result["type"] is FlowResultType.MENU + assert result["step_id"] == "reconfigure" + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], {"next_step_id": "intent_migrate"} + ) + + assert result["type"] is FlowResultType.SHOW_PROGRESS + assert result["step_id"] == "backup_nvm" + + with patch("pathlib.Path.write_bytes"): + await hass.async_block_till_done() + + result = await hass.config_entries.flow.async_configure(result["flow_id"]) + + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "instruct_unplug" + + result = await hass.config_entries.flow.async_configure(result["flow_id"], {}) + + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "choose_serial_port" + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + user_input={ + CONF_USB_PATH: "/test", + }, + ) + + assert result["type"] is FlowResultType.SHOW_PROGRESS + assert result["step_id"] == "start_addon" + + await hass.async_block_till_done() + result = await hass.config_entries.flow.async_configure(result["flow_id"]) + + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "restore_failed" + assert client.driver.controller.async_restore_nvm.call_count == 0 + + client.connect.side_effect = connect_side_effect + + result = await hass.config_entries.flow.async_configure(result["flow_id"], {}) + + assert result["type"] is FlowResultType.SHOW_PROGRESS + assert result["step_id"] == "restore_nvm" + + await hass.async_block_till_done() + + result = await hass.config_entries.flow.async_configure(result["flow_id"]) + + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "migration_successful" + assert entry.unique_id == "3245146787" @pytest.mark.usefixtures("supervisor", "addon_running", "restart_addon", "backup_nvm") @@ -5158,7 +5321,6 @@ async def test_reconfigure_migrate_restore_failure( hass.config_entries.flow.async_abort(result["flow_id"]) assert len(hass.config_entries.flow.async_progress()) == 0 - assert "keep_old_devices" not in entry.data async def test_get_driver_failure_intent_migrate( @@ -5182,7 +5344,6 @@ async def test_get_driver_failure_intent_migrate( assert result["type"] is FlowResultType.ABORT assert result["reason"] == "config_entry_not_loaded" - assert "keep_old_devices" not in entry.data @pytest.mark.usefixtures("backup_nvm") @@ -6182,15 +6343,14 @@ async def test_addon_rf_region_migrate_network( result = await hass.config_entries.flow.async_configure(result["flow_id"]) - assert entry.unique_id == "5678" - _set_home_id(get_server_version, 3245146787) + assert entry.unique_id == "3245146787" assert result["type"] is FlowResultType.SHOW_PROGRESS assert result["step_id"] == "restore_nvm" assert client.connect.call_count == 2 await hass.async_block_till_done() - assert client.connect.call_count == 4 + assert client.connect.call_count == 3 assert entry.state is config_entries.ConfigEntryState.LOADED assert client.driver.controller.async_restore_nvm.call_count == 1 assert len(events) == 2 diff --git a/tests/components/zwave_js/test_repairs.py b/tests/components/zwave_js/test_repairs.py index 5dc19cd2f980f..101fbc3436c18 100644 --- a/tests/components/zwave_js/test_repairs.py +++ b/tests/components/zwave_js/test_repairs.py @@ -9,7 +9,6 @@ from zwave_js_server.model.node import Node, NodeDataType from homeassistant.components.zwave_js import DOMAIN -from homeassistant.components.zwave_js.const import CONF_KEEP_OLD_DEVICES from homeassistant.components.zwave_js.helpers import get_device_id from homeassistant.core import HomeAssistant from homeassistant.helpers import device_registry as dr, issue_registry as ir @@ -342,8 +341,6 @@ async def test_migrate_unique_id( await hass.config_entries.async_setup(config_entry.entry_id) - assert CONF_KEEP_OLD_DEVICES in config_entry.data - assert config_entry.data[CONF_KEEP_OLD_DEVICES] is True stored_devices = dr.async_entries_for_config_entry( device_registry, config_entry.entry_id ) diff --git a/tests/components/zwave_js/test_services.py b/tests/components/zwave_js/test_services.py index bfb7dd8bf5b43..f0ffd0bcaa00e 100644 --- a/tests/components/zwave_js/test_services.py +++ b/tests/components/zwave_js/test_services.py @@ -302,6 +302,7 @@ async def test_set_config_parameter( mode=None, object_id=None, order=None, + context=None, ) await hass.services.async_call( DOMAIN, @@ -800,6 +801,7 @@ async def test_bulk_set_config_parameters( mode=None, object_id=None, order=None, + context=None, ) await hass.services.async_call( DOMAIN, @@ -943,6 +945,7 @@ async def test_refresh_value( mode=None, object_id=None, order=None, + context=None, ) client.async_send_command.return_value = {"result": 2} await hass.services.async_call( @@ -1075,6 +1078,7 @@ async def test_set_value( mode=None, object_id=None, order=None, + context=None, ) await hass.services.async_call( DOMAIN, @@ -1385,6 +1389,7 @@ async def test_multicast_set_value( mode=None, object_id=None, order=None, + context=None, ) await hass.services.async_call( DOMAIN, @@ -1760,6 +1765,7 @@ async def test_ping( mode=None, object_id=None, order=None, + context=None, ) await hass.services.async_call( DOMAIN, diff --git a/tests/helpers/template/extensions/test_devices.py b/tests/helpers/template/extensions/test_devices.py index 3c797b5ad1820..c13c93ccb306c 100644 --- a/tests/helpers/template/extensions/test_devices.py +++ b/tests/helpers/template/extensions/test_devices.py @@ -38,7 +38,7 @@ async def test_device_entities( assert info.rate_limit is None # Test device with single entity, which has no state - entity_registry.async_get_or_create( + entity_entry = entity_registry.async_get_or_create( "light", "hue", "5678", @@ -46,7 +46,7 @@ async def test_device_entities( device_id=device_entry.id, ) info = render_to_info(hass, f"{{{{ device_entities('{device_entry.id}') }}}}") - assert_result_info(info, ["light.hue_5678"], []) + assert_result_info(info, [entity_entry.entity_id], []) assert info.rate_limit is None info = render_to_info( hass, @@ -55,11 +55,11 @@ async def test_device_entities( "| sort(attribute='entity_id') | map(attribute='entity_id') | join(', ') }}" ), ) - assert_result_info(info, "", ["light.hue_5678"]) + assert_result_info(info, "", [entity_entry.entity_id]) assert info.rate_limit is None # Test device with single entity, with state - hass.states.async_set("light.hue_5678", "happy") + hass.states.async_set(entity_entry.entity_id, "happy") info = render_to_info( hass, ( @@ -67,20 +67,20 @@ async def test_device_entities( "| sort(attribute='entity_id') | map(attribute='entity_id') | join(', ') }}" ), ) - assert_result_info(info, "light.hue_5678", ["light.hue_5678"]) + assert_result_info(info, entity_entry.entity_id, [entity_entry.entity_id]) assert info.rate_limit is None # Test device with multiple entities, which have a state - entity_registry.async_get_or_create( + entity_entry_2 = entity_registry.async_get_or_create( "light", "hue", "ABCD", config_entry=config_entry, device_id=device_entry.id, ) - hass.states.async_set("light.hue_abcd", "camper") + hass.states.async_set(entity_entry_2.entity_id, "camper") info = render_to_info(hass, f"{{{{ device_entities('{device_entry.id}') }}}}") - assert_result_info(info, ["light.hue_5678", "light.hue_abcd"], []) + assert_result_info(info, [entity_entry.entity_id, entity_entry_2.entity_id], []) assert info.rate_limit is None info = render_to_info( hass, @@ -90,7 +90,9 @@ async def test_device_entities( ), ) assert_result_info( - info, "light.hue_5678, light.hue_abcd", ["light.hue_5678", "light.hue_abcd"] + info, + f"{entity_entry.entity_id}, {entity_entry_2.entity_id}", + [entity_entry.entity_id, entity_entry_2.entity_id], ) assert info.rate_limit is None diff --git a/tests/helpers/template/extensions/test_state.py b/tests/helpers/template/extensions/test_state.py index 7ca099dff527e..1cf6afb684de1 100644 --- a/tests/helpers/template/extensions/test_state.py +++ b/tests/helpers/template/extensions/test_state.py @@ -740,6 +740,7 @@ async def test_expand(hass: HomeAssistant) -> None: mode=None, object_id=None, order=None, + context=None, ) info = render_to_info( @@ -800,6 +801,7 @@ async def test_expand(hass: HomeAssistant) -> None: mode=None, object_id=None, order=None, + context=None, ) info = render_to_info( @@ -1301,6 +1303,7 @@ async def test_closest_function_home_vs_group_entity_id(hass: HomeAssistant) -> mode=None, object_id=None, order=None, + context=None, ) info = render_to_info(hass, '{{ closest("group.location_group").entity_id }}') @@ -1338,6 +1341,7 @@ async def test_closest_function_home_vs_group_state(hass: HomeAssistant) -> None mode=None, object_id=None, order=None, + context=None, ) info = render_to_info(hass, '{{ closest("group.location_group").entity_id }}') diff --git a/tests/helpers/test_device.py b/tests/helpers/test_device.py index 6c8dbd9d3f5c4..c5cc48484b94c 100644 --- a/tests/helpers/test_device.py +++ b/tests/helpers/test_device.py @@ -44,7 +44,7 @@ async def test_entity_id_to_device_device_id( device_id=device.id, ) await hass.async_block_till_done() - assert entity_registry.async_get("sensor.test_source") is not None + assert entity_registry.async_get(entity.entity_id) is not None device_id = async_entity_id_to_device_id( hass, @@ -130,7 +130,7 @@ async def test_device_info_to_link( device_id=device.id, ) await hass.async_block_till_done() - assert entity_registry.async_get("sensor.test_source") is not None + assert entity_registry.async_get(source_entity.entity_id) is not None # No link device_info is returned, even for an existing entity and device with patch("homeassistant.helpers.device.report_usage") as report_usage: diff --git a/tests/helpers/test_device_registry.py b/tests/helpers/test_device_registry.py index e633732f88575..068d98264f958 100644 --- a/tests/helpers/test_device_registry.py +++ b/tests/helpers/test_device_registry.py @@ -4235,9 +4235,13 @@ async def test_async_get_device_deprecated( @pytest.mark.parametrize( - "via_device", - [("some_domain", "via_id"), None], - ids=["value", "none"], + ("parameter", "value", "replacement"), + [ + ("default_manufacturer", "manufacturer", "manufacturer"), + ("default_model", "model", "model"), + ("default_name", "name", "name"), + ("via_device", ("some_domain", "via_id"), "via_device_id"), + ], ) @pytest.mark.parametrize( ("integration_frame_path", "expectation", "expected_log"), @@ -4260,17 +4264,19 @@ async def test_async_get_device_deprecated( ], ) @pytest.mark.usefixtures("mock_integration_frame") -async def test_async_get_or_create_via_device_deprecated( +async def test_async_get_or_create_deprecated_parameters( hass: HomeAssistant, device_registry: dr.DeviceRegistry, caplog: pytest.LogCaptureFixture, - via_device: tuple[str, str] | None, + parameter: str, + value: Any, + replacement: str, expectation: AbstractContextManager, expected_log: int, ) -> None: - """Test passing via_device to async_get_or_create is deprecated. + """Test passing deprecated parameters to async_get_or_create. - It logs for custom integrations and raises for core and core integrations. + They log for custom integrations and raise for core and core integrations. """ config_entry = MockConfigEntry() config_entry.add_to_hass(hass) @@ -4278,23 +4284,37 @@ async def test_async_get_or_create_via_device_deprecated( config_entry_id=config_entry.entry_id, identifiers={("some_domain", "via_id")} ) - what = "calls `device_registry.async_get_or_create` with a `via_device`" + what = ( + "calls `device_registry.async_get_or_create` with a deprecated " + f"`{parameter}` parameter; use `{replacement}` instead" + ) with patch.object(frame, "_REPORTED_INTEGRATIONS", set()), expectation: device_registry.async_get_or_create( config_entry_id=config_entry.entry_id, identifiers={("some_domain", "some_id")}, - via_device=via_device, + **{parameter: value}, ) assert caplog.text.count(what) == expected_log +@pytest.mark.parametrize( + ("parameter", "value"), + [ + ("default_manufacturer", "manufacturer"), + ("default_model", "model"), + ("default_name", "name"), + ("via_device", ("some_domain", "via_id")), + ], +) @pytest.mark.usefixtures("mock_integration_frame") -async def test_async_get_or_create_via_device_reported_before_mutation( +async def test_async_get_or_create_deprecated_parameter_reported_before_mutation( hass: HomeAssistant, device_registry: dr.DeviceRegistry, + parameter: str, + value: Any, ) -> None: - """The via_device deprecation is reported before the registry is mutated. + """A deprecated parameter is reported before the registry is mutated. The default frame is a core integration, so the report raises; the new device must not be left partially created. @@ -4309,7 +4329,7 @@ async def test_async_get_or_create_via_device_reported_before_mutation( device_registry.async_get_or_create( config_entry_id=config_entry.entry_id, identifiers={("some_domain", "new_device")}, - via_device=("some_domain", "via_id"), + **{parameter: value}, ) # The report raised before insertion, so no partial device was left behind. @@ -4321,6 +4341,25 @@ async def test_async_get_or_create_via_device_reported_before_mutation( ) +async def test_async_get_or_create_unexpected_keyword_argument( + hass: HomeAssistant, + device_registry: dr.DeviceRegistry, +) -> None: + """Test passing an unexpected keyword argument to async_get_or_create raises.""" + config_entry = MockConfigEntry() + config_entry.add_to_hass(hass) + + with pytest.raises( + TypeError, + match="got unexpected keyword arguments 'unexpected'", + ): + device_registry.async_get_or_create( + config_entry_id=config_entry.entry_id, + identifiers={("some_domain", "some_id")}, + unexpected="value", + ) + + @pytest.mark.parametrize( ("integration_frame_path", "expectation", "expected_log"), [ @@ -7162,6 +7201,32 @@ async def test_get_or_create_sets_default_values( assert entry.manufacturer == "default manufacturer 1" +@pytest.mark.parametrize( + ("field", "default_field"), + [ + ("name", "default_name"), + ("manufacturer", "default_manufacturer"), + ("model", "default_model"), + ], +) +async def test_get_or_create_rejects_field_and_its_default( + device_registry: dr.DeviceRegistry, + mock_config_entry: MockConfigEntry, + field: str, + default_field: str, +) -> None: + """Test passing both an explicit field and its default_ counterpart is rejected.""" + with pytest.raises( + dr.DeviceInfoError, + match=f"passing both `{field}` and `{default_field}` is not allowed", + ): + device_registry.async_get_or_create( + config_entry_id=mock_config_entry.entry_id, + connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + **{field: "explicit value", default_field: "default value"}, + ) + + async def test_verify_suggested_area_does_not_overwrite_area_id( device_registry: dr.DeviceRegistry, area_registry: ar.AreaRegistry, diff --git a/tests/helpers/test_entity.py b/tests/helpers/test_entity.py index 1406a12206a2b..b88d69ff4963f 100644 --- a/tests/helpers/test_entity.py +++ b/tests/helpers/test_entity.py @@ -1036,7 +1036,7 @@ async def async_setup_entry( (False, None, "Device Bla", "Device Bla"), (True, "Entity Blu", "Device Bla", "Device Bla Entity Blu"), (True, None, "Device Bla", "Device Bla"), - (True, "Entity Blu", UNDEFINED, "Entity Blu"), + (True, "Entity Blu", UNDEFINED, "Mock Title Entity Blu"), (True, "Entity Blu", None, "Mock Title Entity Blu"), ], ) diff --git a/tests/helpers/test_entity_platform.py b/tests/helpers/test_entity_platform.py index e84fb9c69731c..f8f524f52d588 100644 --- a/tests/helpers/test_entity_platform.py +++ b/tests/helpers/test_entity_platform.py @@ -1531,7 +1531,7 @@ async def async_setup_entry( async def test_device_info_not_overrides( hass: HomeAssistant, device_registry: dr.DeviceRegistry ) -> None: - """Test device info is forwarded correctly.""" + """Test re-registering a device does not override existing values.""" config_entry = MockConfigEntry(entry_id="super-mock-id") config_entry.add_to_hass(hass) device = device_registry.async_get_or_create( @@ -1556,9 +1556,6 @@ async def async_setup_entry( unique_id="qwer", device_info={ "connections": {(dr.CONNECTION_NETWORK_MAC, "abcd")}, - "default_name": "default name 1", - "default_model": "default model 1", - "default_manufacturer": "default manufacturer 1", }, ) ] @@ -2734,8 +2731,8 @@ async def test_device_name_defaulting_config_entry( hass: HomeAssistant, device_registry: dr.DeviceRegistry, config_entry_title: str, - entity_device_name: str, - entity_device_default_name: str, + entity_device_name: str | None, + entity_device_default_name: str | None, expected_device_name: str, ) -> None: """Test setting the device name based on input info.""" @@ -2767,8 +2764,11 @@ async def async_setup_entry( hass, platform_name=config_entry.domain, platform=platform ) - assert await entity_platform.async_setup_entry(config_entry) - await hass.async_block_till_done() + # `default_name` is deprecated in the device registry; suppress the deprecation + # report so it does not raise when the entity is added. + with patch.object(dr, "report_usage"): + assert await entity_platform.async_setup_entry(config_entry) + await hass.async_block_till_done() device = device_registry.async_get_device_by_connection( (dr.CONNECTION_NETWORK_MAC, "1234"), config_entry.entry_id @@ -2783,16 +2783,6 @@ async def async_setup_entry( # No identifiers ({}, 1), # Empty device info does not prevent the entity from being created ({"name": "bla"}, 0), - ({"default_name": "bla"}, 0), - # Match multiple types - ( - { - "identifiers": {("hue", "1234")}, - "name": "bla", - "default_name": "yo", - }, - 0, - ), ], ) async def test_device_type_error_checking( diff --git a/tests/helpers/test_entity_registry.py b/tests/helpers/test_entity_registry.py index b75f66280a331..3a469bd160395 100644 --- a/tests/helpers/test_entity_registry.py +++ b/tests/helpers/test_entity_registry.py @@ -210,7 +210,7 @@ def test_get_or_create_updates_data( assert set(entity_registry.async_device_ids()) == {orig_device_entry.id} assert orig_entry == er.RegistryEntry( - entity_id="light.hue_5678", + entity_id=orig_entry.entity_id, unique_id="5678", platform="hue", aliases=[er.COMPUTED_NAME], @@ -271,7 +271,7 @@ def test_get_or_create_updates_data( ) assert new_entry == er.RegistryEntry( - entity_id="light.hue_5678", + entity_id=new_entry.entity_id, unique_id="5678", platform="hue", aliases=[er.COMPUTED_NAME], @@ -327,7 +327,7 @@ def test_get_or_create_updates_data( ) assert new_entry == er.RegistryEntry( - entity_id="light.hue_5678", + entity_id=new_entry.entity_id, unique_id="5678", platform="hue", aliases=[er.COMPUTED_NAME], diff --git a/tests/helpers/test_service.py b/tests/helpers/test_service.py index 7505798e9dc1d..cca0ed954190f 100644 --- a/tests/helpers/test_service.py +++ b/tests/helpers/test_service.py @@ -719,6 +719,7 @@ async def test_extract_entity_ids(hass: HomeAssistant) -> None: mode=None, object_id=None, order=None, + context=None, ) call = ServiceCall(hass, "light", "turn_on", {ATTR_ENTITY_ID: "light.Bowl"}) diff --git a/tests/helpers/test_target.py b/tests/helpers/test_target.py index e42cbc4eb3899..27f57ae1d5f22 100644 --- a/tests/helpers/test_target.py +++ b/tests/helpers/test_target.py @@ -513,6 +513,7 @@ async def test_extract_referenced_entity_ids( mode=None, object_id=None, order=None, + context=None, ) target_selection = selection_class(selector_config)