diff --git a/homeassistant/components/api/__init__.py b/homeassistant/components/api/__init__.py index 39b74b3fe3b18..06c67d2787cd0 100644 --- a/homeassistant/components/api/__init__.py +++ b/homeassistant/components/api/__init__.py @@ -440,14 +440,18 @@ def _async_save_changed_entities( try: # shield the service call from cancellation on connection drop + # and track the task so it cannot be garbage collected mid-run response = await shield( - hass.services.async_call( - domain, - service, - data, # type: ignore[arg-type] - blocking=True, - context=context, - return_response=response_requested, + hass.async_create_task( + hass.services.async_call( + domain, + service, + data, # type: ignore[arg-type] + blocking=True, + context=context, + return_response=response_requested, + ), + f"api service call {domain}.{service}", ) ) except (vol.Invalid, ServiceNotFound) as ex: diff --git a/homeassistant/components/blebox/diagnostics.py b/homeassistant/components/blebox/diagnostics.py index bb9a0728dab5a..d9fa6d4979311 100644 --- a/homeassistant/components/blebox/diagnostics.py +++ b/homeassistant/components/blebox/diagnostics.py @@ -23,6 +23,7 @@ async def async_get_config_entry_diagnostics( "name": product.name, "type": product.type, "model": product.model, + "product": product.product, "unique_id": product.unique_id, "firmware_version": product.firmware_version, "hardware_version": product.hardware_version, diff --git a/homeassistant/components/blebox/entity.py b/homeassistant/components/blebox/entity.py index ccd5a565986ba..9dfd6543e6ac1 100644 --- a/homeassistant/components/blebox/entity.py +++ b/homeassistant/components/blebox/entity.py @@ -23,8 +23,9 @@ def __init__(self, coordinator: BleBoxCoordinator, feature: _FeatureT) -> None: self._attr_device_info = DeviceInfo( identifiers={(DOMAIN, product.unique_id)}, manufacturer=product.brand, - model=product.model, + model=product.product, name=product.name, sw_version=product.firmware_version, + hw_version=product.hardware_version, configuration_url=f"http://{product.address}", ) diff --git a/homeassistant/components/lyngdorf/manifest.json b/homeassistant/components/lyngdorf/manifest.json index 93a20c4cd5892..88e43b877e93a 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.4.3"], + "requirements": ["lyngdorf==1.4.4"], "ssdp": [ { "deviceType": "urn:schemas-upnp-org:device:MediaRenderer:2", diff --git a/homeassistant/components/mikrotik/strings.json b/homeassistant/components/mikrotik/strings.json index 1cdc058d6f770..43a56dd00b20f 100644 --- a/homeassistant/components/mikrotik/strings.json +++ b/homeassistant/components/mikrotik/strings.json @@ -15,7 +15,7 @@ "password": "[%key:common::config_flow::data::password%]" }, "data_description": { - "password": "[%key:component::vodafone_station::config::step::user::data_description::password%]" + "password": "The password for your Mikrotik device." }, "description": "The password for {username} is invalid.", "title": "[%key:common::config_flow::title::reauth%]" diff --git a/homeassistant/components/picnic/config_flow.py b/homeassistant/components/picnic/config_flow.py index 06befeca3279c..03ee261bcb11c 100644 --- a/homeassistant/components/picnic/config_flow.py +++ b/homeassistant/components/picnic/config_flow.py @@ -192,7 +192,7 @@ async def _async_finish( CONF_ACCESS_TOKEN: auth_token, CONF_COUNTRY_CODE: user_input[CONF_COUNTRY_CODE], } - existing_entry = await self.async_set_unique_id(user_data["user_id"]) + existing_entry = await self.async_set_unique_id(user_data.user_id) # Abort if we're adding a new config and the unique id # is already in use, else create the entry diff --git a/homeassistant/components/picnic/coordinator.py b/homeassistant/components/picnic/coordinator.py index 8cc2b21a5be5d..d7c2f9ba44564 100644 --- a/homeassistant/components/picnic/coordinator.py +++ b/homeassistant/components/picnic/coordinator.py @@ -2,12 +2,13 @@ import asyncio from contextlib import suppress -import copy +from dataclasses import dataclass from datetime import timedelta import logging from typing import override from python_picnic_api2 import PicnicAPI +from python_picnic_api2.models import Cart, DeliverySummary, Slot from python_picnic_api2.session import PicnicAuthError from homeassistant.config_entries import ConfigEntry @@ -32,6 +33,25 @@ type PicnicConfigEntry = ConfigEntry[PicnicUpdateCoordinator] +@dataclass +class NextDeliveryData: + """The next (current, undelivered) delivery, with its live ETA.""" + + delivery: DeliverySummary | None = None + eta_start: str | None = None + eta_end: str | None = None + estimated_arrival: int | None = None + + +@dataclass +class LastOrderData: + """The most recent delivery, with its total price.""" + + delivery: DeliverySummary | None = None + total_price: int = 0 + delivery_time_start: str | None = None + + class PicnicUpdateCoordinator(DataUpdateCoordinator): """The coordinator to fetch data from the Picnic API at a set interval.""" @@ -86,21 +106,20 @@ async def _async_update_data(self) -> dict: return data @staticmethod - def _get_update_interval(next_delivery: dict | None) -> timedelta: + def _get_update_interval(next_delivery: NextDeliveryData | None) -> timedelta: """Poll faster around the delivery so the live ETA is picked up in time.""" - if not next_delivery: + if next_delivery is None or next_delivery.delivery is None: return DEFAULT_UPDATE_INTERVAL - eta = next_delivery.get("eta") - slot = next_delivery.get("slot") + slot = next_delivery.delivery.slot start = end = None - if eta: - start = dt_util.parse_datetime(str(eta.get("start"))) - end = dt_util.parse_datetime(str(eta.get("end"))) + if next_delivery.eta_start and next_delivery.eta_end: + start = dt_util.parse_datetime(next_delivery.eta_start) + end = dt_util.parse_datetime(next_delivery.eta_end) if (start is None or end is None) and slot: - start = dt_util.parse_datetime(str(slot.get("window_start"))) - end = dt_util.parse_datetime(str(slot.get("window_end"))) + start = dt_util.parse_datetime(str(slot.window_start)) + end = dt_util.parse_datetime(str(slot.window_end)) if start is None or end is None: return DEFAULT_UPDATE_INTERVAL @@ -129,12 +148,11 @@ def fetch_data(self): raise UpdateFailed("API response doesn't contain expected data.") next_delivery, last_order = self._get_order_data() - slot_data = self._get_slot_data(cart) return { ADDRESS: self._get_address(), CART_DATA: cart, - SLOT_DATA: slot_data, + SLOT_DATA: self._get_slot_data(cart), NEXT_DELIVERY_DATA: next_delivery, LAST_ORDER_DATA: last_order, } @@ -142,85 +160,85 @@ def fetch_data(self): def _get_address(self): """Get the address that identifies the Picnic service.""" if self._user_address is None: - address = self.picnic_api_client.get_user()["address"] + address = self.picnic_api_client.get_user().address self._user_address = ( - f"{address['street']} " - f"{address['house_number']}{address['house_number_ext']}" + f"{address.street} " + f"{address.house_number}{address.house_number_ext or ''}" ) return self._user_address @staticmethod - def _get_slot_data(cart: dict) -> dict: + def _get_slot_data(cart: Cart) -> Slot | None: """Get the selected slot, if it's explicitly selected.""" - selected_slot = cart.get("selected_slot", {}) - available_slots = cart.get("delivery_slots", []) + selected_slot = cart.selected_slot - if selected_slot.get("state") == "EXPLICIT": - slot_data = filter( - lambda slot: slot.get("slot_id") == selected_slot.get("slot_id"), - available_slots, - ) - if slot_data: - return next(slot_data) + if selected_slot and selected_slot.state == "EXPLICIT": + for slot in cart.delivery_slots: + if slot.slot_id == selected_slot.slot_id: + return slot - return {} + return None - def _get_order_data(self) -> tuple[dict, dict]: + @staticmethod + def _delivery_time(delivery: DeliverySummary) -> dict | None: + """Return the raw delivery-time window; not a field the library models.""" + return delivery.raw.get("delivery_time") if delivery.raw else None + + def _get_order_data(self) -> tuple[NextDeliveryData, LastOrderData]: """Get data of the last order from the list of deliveries.""" # Get the deliveries deliveries = self.picnic_api_client.get_deliveries(summary=True) - # Determine the last order and return an empty dict if there is none + # Determine the last order and return empty data if there is none try: # Filter on status CURRENT and select the last # on the list which is the first one to be delivered - # Make a deepcopy because some references are local - next_deliveries = list( - filter(lambda d: d["status"] == "CURRENT", deliveries) - ) - next_delivery = ( - copy.deepcopy(next_deliveries[-1]) if next_deliveries else {} - ) - last_order = copy.deepcopy(deliveries[0]) if deliveries else {} - except KeyError, TypeError: - # A KeyError or TypeError indicate that the + next_deliveries = [d for d in deliveries if d.status == "CURRENT"] + next_delivery = next_deliveries[-1] if next_deliveries else None + last_order = deliveries[0] if deliveries else None + except AttributeError, TypeError: + # An AttributeError or TypeError indicate that the # response contains unexpected data - return {}, {} + return NextDeliveryData(), LastOrderData() + + if last_order is None: + return NextDeliveryData(), LastOrderData() # Get the next order's position details if there is an undelivered order delivery_position = {} - if next_delivery and not next_delivery.get("delivery_time"): + if next_delivery and not self._delivery_time(next_delivery): # ValueError: If no information yet can mean an empty response with suppress(ValueError): delivery_position = self.picnic_api_client.get_delivery_position( - next_delivery["delivery_id"] + next_delivery.delivery_id ) # Determine the ETA, if available, the one from the # delivery position API is more precise # but, it's only available shortly before the actual delivery. - next_delivery["eta"] = delivery_position.get( - "eta_window", next_delivery.get("eta2", {}) + eta_window = delivery_position.get("eta_window") or {} + eta2 = next_delivery.eta2 if next_delivery else None + next_delivery_data = NextDeliveryData( + delivery=next_delivery, + eta_start=eta_window.get("start") or (eta2.start if eta2 else None), + eta_end=eta_window.get("end") or (eta2.end if eta2 else None), + # The position response's eta (unix timestamp in milliseconds) feeds + # the estimated arrival sensor; the API only serves it shortly before + # the delivery, so that sensor is unknown outside that window + estimated_arrival=delivery_position.get("eta"), ) - if "eta2" in next_delivery: - del next_delivery["eta2"] - - # The position response's eta (unix timestamp in milliseconds) feeds - # the estimated arrival sensor; the API only serves it shortly before - # the delivery, so that sensor is unknown outside that window - next_delivery["estimated_arrival"] = delivery_position.get("eta") # Determine the total price by adding up the total price of all sub-orders - total_price = 0 - for order in last_order.get("orders", []): - total_price += order.get("total_price", 0) - last_order["total_price"] = total_price - - # Make sure delivery_time is a dict - last_order.setdefault("delivery_time", {}) + total_price = sum(order.total_price or 0 for order in last_order.orders) + delivery_time = self._delivery_time(last_order) + last_order_data = LastOrderData( + delivery=last_order, + total_price=total_price, + delivery_time_start=delivery_time.get("start") if delivery_time else None, + ) - return next_delivery, last_order + return next_delivery_data, last_order_data @callback def _update_auth_token(self): diff --git a/homeassistant/components/picnic/manifest.json b/homeassistant/components/picnic/manifest.json index d75b145aecf8a..8f08c7fb0732d 100644 --- a/homeassistant/components/picnic/manifest.json +++ b/homeassistant/components/picnic/manifest.json @@ -7,5 +7,5 @@ "integration_type": "service", "iot_class": "cloud_polling", "loggers": ["python_picnic_api2"], - "requirements": ["python-picnic-api2==1.3.4"] + "requirements": ["python-picnic-api2==2.0.1"] } diff --git a/homeassistant/components/picnic/sensor.py b/homeassistant/components/picnic/sensor.py index 0deb382a31ccb..8f82552dab302 100644 --- a/homeassistant/components/picnic/sensor.py +++ b/homeassistant/components/picnic/sensor.py @@ -39,7 +39,17 @@ SENSOR_SELECTED_SLOT_MIN_ORDER_VALUE, SENSOR_SELECTED_SLOT_START, ) -from .coordinator import PicnicConfigEntry, PicnicUpdateCoordinator +from .coordinator import ( + LastOrderData, + NextDeliveryData, + PicnicConfigEntry, + PicnicUpdateCoordinator, +) + +_EMPTY_DATA_FACTORIES: dict[str, Callable[[], Any]] = { + "next_delivery_data": NextDeliveryData, + "last_order_data": LastOrderData, +} @dataclass(frozen=True, kw_only=True) @@ -59,35 +69,41 @@ class PicnicSensorEntityDescription(SensorEntityDescription): key=SENSOR_CART_ITEMS_COUNT, translation_key=SENSOR_CART_ITEMS_COUNT, data_type="cart_data", - value_fn=lambda cart: cart.get("total_count", 0), + value_fn=lambda cart: (cart.total_count or 0) if cart else 0, ), PicnicSensorEntityDescription( key=SENSOR_CART_TOTAL_PRICE, translation_key=SENSOR_CART_TOTAL_PRICE, native_unit_of_measurement=CURRENCY_EURO, data_type="cart_data", - value_fn=lambda cart: cart.get("total_price", 0) / 100, + value_fn=lambda cart: ((cart.total_price or 0) if cart else 0) / 100, ), PicnicSensorEntityDescription( key=SENSOR_SELECTED_SLOT_START, translation_key=SENSOR_SELECTED_SLOT_START, device_class=SensorDeviceClass.TIMESTAMP, data_type="slot_data", - value_fn=lambda slot: dt_util.parse_datetime(str(slot.get("window_start"))), + value_fn=lambda slot: ( + dt_util.parse_datetime(str(slot.window_start)) if slot else None + ), ), PicnicSensorEntityDescription( key=SENSOR_SELECTED_SLOT_END, translation_key=SENSOR_SELECTED_SLOT_END, device_class=SensorDeviceClass.TIMESTAMP, data_type="slot_data", - value_fn=lambda slot: dt_util.parse_datetime(str(slot.get("window_end"))), + value_fn=lambda slot: ( + dt_util.parse_datetime(str(slot.window_end)) if slot else None + ), ), PicnicSensorEntityDescription( key=SENSOR_SELECTED_SLOT_MAX_ORDER_TIME, translation_key=SENSOR_SELECTED_SLOT_MAX_ORDER_TIME, device_class=SensorDeviceClass.TIMESTAMP, data_type="slot_data", - value_fn=lambda slot: dt_util.parse_datetime(str(slot.get("cut_off_time"))), + value_fn=lambda slot: ( + dt_util.parse_datetime(str(slot.cut_off_time)) if slot else None + ), ), PicnicSensorEntityDescription( key=SENSOR_SELECTED_SLOT_MIN_ORDER_VALUE, @@ -95,8 +111,8 @@ class PicnicSensorEntityDescription(SensorEntityDescription): native_unit_of_measurement=CURRENCY_EURO, data_type="slot_data", value_fn=lambda slot: ( - slot["minimum_order_value"] / 100 - if slot.get("minimum_order_value") + slot.minimum_order_value / 100 + if slot and slot.minimum_order_value else None ), ), @@ -105,8 +121,10 @@ class PicnicSensorEntityDescription(SensorEntityDescription): translation_key=SENSOR_LAST_ORDER_SLOT_START, device_class=SensorDeviceClass.TIMESTAMP, data_type="last_order_data", - value_fn=lambda last_order: dt_util.parse_datetime( - str(last_order.get("slot", {}).get("window_start")) + value_fn=lambda last_order: ( + dt_util.parse_datetime(str(last_order.delivery.slot.window_start)) + if last_order.delivery and last_order.delivery.slot + else None ), ), PicnicSensorEntityDescription( @@ -114,23 +132,29 @@ class PicnicSensorEntityDescription(SensorEntityDescription): translation_key=SENSOR_LAST_ORDER_SLOT_END, device_class=SensorDeviceClass.TIMESTAMP, data_type="last_order_data", - value_fn=lambda last_order: dt_util.parse_datetime( - str(last_order.get("slot", {}).get("window_end")) + value_fn=lambda last_order: ( + dt_util.parse_datetime(str(last_order.delivery.slot.window_end)) + if last_order.delivery and last_order.delivery.slot + else None ), ), PicnicSensorEntityDescription( key=SENSOR_LAST_ORDER_STATUS, translation_key=SENSOR_LAST_ORDER_STATUS, data_type="last_order_data", - value_fn=lambda last_order: last_order.get("status"), + value_fn=lambda last_order: ( + last_order.delivery.status if last_order.delivery else None + ), ), PicnicSensorEntityDescription( key=SENSOR_LAST_ORDER_MAX_ORDER_TIME, translation_key=SENSOR_LAST_ORDER_MAX_ORDER_TIME, device_class=SensorDeviceClass.TIMESTAMP, data_type="last_order_data", - value_fn=lambda last_order: dt_util.parse_datetime( - str(last_order.get("slot", {}).get("cut_off_time")) + value_fn=lambda last_order: ( + dt_util.parse_datetime(str(last_order.delivery.slot.cut_off_time)) + if last_order.delivery and last_order.delivery.slot + else None ), ), PicnicSensorEntityDescription( @@ -139,7 +163,7 @@ class PicnicSensorEntityDescription(SensorEntityDescription): device_class=SensorDeviceClass.TIMESTAMP, data_type="last_order_data", value_fn=lambda last_order: dt_util.parse_datetime( - str(last_order.get("delivery_time", {}).get("start")) + str(last_order.delivery_time_start) ), ), PicnicSensorEntityDescription( @@ -147,7 +171,7 @@ class PicnicSensorEntityDescription(SensorEntityDescription): translation_key=SENSOR_LAST_ORDER_TOTAL_PRICE, native_unit_of_measurement=CURRENCY_EURO, data_type="last_order_data", - value_fn=lambda last_order: last_order.get("total_price", 0) / 100, + value_fn=lambda last_order: last_order.total_price / 100, ), PicnicSensorEntityDescription( key=SENSOR_NEXT_DELIVERY_ETA_START, @@ -155,7 +179,7 @@ class PicnicSensorEntityDescription(SensorEntityDescription): device_class=SensorDeviceClass.TIMESTAMP, data_type="next_delivery_data", value_fn=lambda next_delivery: dt_util.parse_datetime( - str(next_delivery.get("eta", {}).get("start")) + str(next_delivery.eta_start) ), ), PicnicSensorEntityDescription( @@ -164,7 +188,7 @@ class PicnicSensorEntityDescription(SensorEntityDescription): device_class=SensorDeviceClass.TIMESTAMP, data_type="next_delivery_data", value_fn=lambda next_delivery: dt_util.parse_datetime( - str(next_delivery.get("eta", {}).get("end")) + str(next_delivery.eta_end) ), ), PicnicSensorEntityDescription( @@ -173,8 +197,8 @@ class PicnicSensorEntityDescription(SensorEntityDescription): device_class=SensorDeviceClass.TIMESTAMP, data_type="next_delivery_data", value_fn=lambda next_delivery: ( - dt_util.utc_from_timestamp(next_delivery["estimated_arrival"] / 1000) - if next_delivery.get("estimated_arrival") + dt_util.utc_from_timestamp(next_delivery.estimated_arrival / 1000) + if next_delivery.estimated_arrival else None ), ), @@ -183,8 +207,10 @@ class PicnicSensorEntityDescription(SensorEntityDescription): translation_key=SENSOR_NEXT_DELIVERY_SLOT_START, device_class=SensorDeviceClass.TIMESTAMP, data_type="next_delivery_data", - value_fn=lambda next_delivery: dt_util.parse_datetime( - str(next_delivery.get("slot", {}).get("window_start")) + value_fn=lambda next_delivery: ( + dt_util.parse_datetime(str(next_delivery.delivery.slot.window_start)) + if next_delivery.delivery and next_delivery.delivery.slot + else None ), ), PicnicSensorEntityDescription( @@ -192,8 +218,10 @@ class PicnicSensorEntityDescription(SensorEntityDescription): translation_key=SENSOR_NEXT_DELIVERY_SLOT_END, device_class=SensorDeviceClass.TIMESTAMP, data_type="next_delivery_data", - value_fn=lambda next_delivery: dt_util.parse_datetime( - str(next_delivery.get("slot", {}).get("window_end")) + value_fn=lambda next_delivery: ( + dt_util.parse_datetime(str(next_delivery.delivery.slot.window_end)) + if next_delivery.delivery and next_delivery.delivery.slot + else None ), ), ) @@ -243,9 +271,11 @@ def __init__( @override def native_value(self) -> StateType | datetime: """Return the value reported by the sensor.""" - data_set = ( - self.coordinator.data.get(self.entity_description.data_type, {}) - if self.coordinator.data is not None - else {} - ) + data = self.coordinator.data or {} + data_type = self.entity_description.data_type + if data_type in data: + data_set = data[data_type] + else: + factory = _EMPTY_DATA_FACTORIES.get(data_type) + data_set = factory() if factory else None return self.entity_description.value_fn(data_set) diff --git a/homeassistant/components/picnic/services.py b/homeassistant/components/picnic/services.py index e3635264e7e38..630bf23162beb 100644 --- a/homeassistant/components/picnic/services.py +++ b/homeassistant/components/picnic/services.py @@ -80,12 +80,12 @@ def product_search(api_client: PicnicAPI, product_name: str | None) -> str | Non search_result = api_client.search(product_name) - if not search_result or "items" not in search_result[0]: + if not search_result or not search_result.items: return None # Return the first valid result - for item in search_result[0]["items"]: - if "name" in item: - return str(item["id"]) + for item in search_result.items: + if item.name: + return str(item.id) return None diff --git a/homeassistant/components/picnic/todo.py b/homeassistant/components/picnic/todo.py index b1e5c26bea485..82f8dce39a510 100644 --- a/homeassistant/components/picnic/todo.py +++ b/homeassistant/components/picnic/todo.py @@ -15,7 +15,7 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity -from .const import DOMAIN +from .const import CART_DATA, DOMAIN from .coordinator import PicnicConfigEntry, PicnicUpdateCoordinator from .services import product_search @@ -62,17 +62,18 @@ def todo_items(self) -> list[TodoItem] | None: if self.coordinator.data is None: return None - _LOGGER.debug(self.coordinator.data["cart_data"]["items"]) + cart = self.coordinator.data[CART_DATA] + _LOGGER.debug(cart.items) return [ TodoItem( - summary=f"{article['name']} ({article['unit_quantity']})", - uid=f"{item['id']}-{article['id']}", + summary=f"{article.name} ({article.unit_quantity})", + uid=f"{line.id}-{article.id}", # We set 'NEEDS_ACTION' so they count as state status=TodoItemStatus.NEEDS_ACTION, ) - for item in self.coordinator.data["cart_data"]["items"] - for article in item["items"] + for line in cart.items + for article in line.items ] @override diff --git a/homeassistant/components/smartthings/climate.py b/homeassistant/components/smartthings/climate.py index b54e115cb80fe..13130a9858c42 100644 --- a/homeassistant/components/smartthings/climate.py +++ b/homeassistant/components/smartthings/climate.py @@ -582,6 +582,39 @@ def target_temperature(self) -> float: Capability.THERMOSTAT_COOLING_SETPOINT, Attribute.COOLING_SETPOINT ) + def _get_setpoint_range_value(self, key: str) -> float | None: + """Return a value from the cooling setpoint range, if the device reports it.""" + if ( + setpoint_range := self.get_attribute_value( + Capability.THERMOSTAT_COOLING_SETPOINT, + Attribute.COOLING_SETPOINT_RANGE, + ) + ) is None: + return None + return setpoint_range.get(key) + + @property + @override + def target_temperature_step(self) -> float | None: + """Return the supported step of target temperature.""" + return self._get_setpoint_range_value("step") + + @property + @override + def min_temp(self) -> float: + """Return the minimum temperature.""" + if (minimum := self._get_setpoint_range_value("minimum")) is None: + return DEFAULT_MIN_TEMP + return minimum + + @property + @override + def max_temp(self) -> float: + """Return the maximum temperature.""" + if (maximum := self._get_setpoint_range_value("maximum")) is None: + return DEFAULT_MAX_TEMP + return maximum + @property @override def temperature_unit(self) -> str: diff --git a/homeassistant/components/solaredge/manifest.json b/homeassistant/components/solaredge/manifest.json index ab668d398096a..3bb86ac9da1a9 100644 --- a/homeassistant/components/solaredge/manifest.json +++ b/homeassistant/components/solaredge/manifest.json @@ -14,5 +14,5 @@ "integration_type": "device", "iot_class": "cloud_polling", "loggers": ["aiosolaredge", "solaredge_web"], - "requirements": ["aiosolaredge==1.0.2", "solaredge-web==0.3.0"] + "requirements": ["aiosolaredge==1.0.2", "solaredge-web==0.3.1"] } diff --git a/homeassistant/components/switchbot_cloud/const.py b/homeassistant/components/switchbot_cloud/const.py index bb5ea64b137fb..03636f419acb5 100644 --- a/homeassistant/components/switchbot_cloud/const.py +++ b/homeassistant/components/switchbot_cloud/const.py @@ -151,28 +151,31 @@ class SwitchbotCloudDeviceConfig: "Smart Lock Pro Wifi": SwitchbotCloudDeviceConfig( True, entity_config=(Platform.SENSOR, Platform.BINARY_SENSOR, Platform.LOCK) ), - "Strip Light": SwitchbotCloudDeviceConfig(False, entity_config=(Platform.LIGHT,)), - "Strip Light 3": SwitchbotCloudDeviceConfig(False, entity_config=(Platform.LIGHT,)), - "Floor Lamp": SwitchbotCloudDeviceConfig(False, entity_config=(Platform.LIGHT,)), - "Color Bulb": SwitchbotCloudDeviceConfig(False, entity_config=(Platform.LIGHT,)), + "Strip Light": SwitchbotCloudDeviceConfig(True, entity_config=(Platform.LIGHT,)), + "Strip Light 3": SwitchbotCloudDeviceConfig(True, entity_config=(Platform.LIGHT,)), + "Floor Lamp": SwitchbotCloudDeviceConfig(True, entity_config=(Platform.LIGHT,)), + "Color Bulb": SwitchbotCloudDeviceConfig(True, entity_config=(Platform.LIGHT,)), "RGBICWW Floor Lamp": SwitchbotCloudDeviceConfig( - False, entity_config=(Platform.LIGHT,) + True, entity_config=(Platform.LIGHT,) + ), + "Permanent Outdoor Lights": SwitchbotCloudDeviceConfig( + True, entity_config=(Platform.LIGHT,) ), "RGBICWW Strip Light": SwitchbotCloudDeviceConfig( - False, entity_config=(Platform.LIGHT,) + True, entity_config=(Platform.LIGHT,) ), - "Ceiling Light": SwitchbotCloudDeviceConfig(False, entity_config=(Platform.LIGHT,)), + "Ceiling Light": SwitchbotCloudDeviceConfig(True, entity_config=(Platform.LIGHT,)), "Ceiling Light Pro": SwitchbotCloudDeviceConfig( - False, entity_config=(Platform.LIGHT,) + True, entity_config=(Platform.LIGHT,) ), "RGBIC Neon Wire Rope Light": SwitchbotCloudDeviceConfig( - False, entity_config=(Platform.LIGHT,) + True, entity_config=(Platform.LIGHT,) ), "RGBIC Neon Rope Light": SwitchbotCloudDeviceConfig( - False, entity_config=(Platform.LIGHT,) + True, entity_config=(Platform.LIGHT,) ), "Candle Warmer Lamp": SwitchbotCloudDeviceConfig( - False, entity_config=(Platform.LIGHT,) + True, entity_config=(Platform.LIGHT,) ), "MeterPro(CO2)": SwitchbotCloudDeviceConfig(True, entity_config=(Platform.SENSOR,)), "AI Art Frame": SwitchbotCloudDeviceConfig( diff --git a/homeassistant/components/switchbot_cloud/light.py b/homeassistant/components/switchbot_cloud/light.py index 02e6770de0c8c..b1dd9cf026dab 100644 --- a/homeassistant/components/switchbot_cloud/light.py +++ b/homeassistant/components/switchbot_cloud/light.py @@ -70,11 +70,13 @@ def _set_attributes(self) -> None: """Set attributes from coordinator data.""" if self.coordinator.data is None: return - power: str | None = self.coordinator.data.get("power") + power: str | None = self.coordinator.data.get( + "power" + ) or self.coordinator.data.get("powerState") brightness: int | None = self.coordinator.data.get("brightness") color: str | None = self.coordinator.data.get("color") color_temperature: int | None = self.coordinator.data.get("colorTemperature") - self._attr_is_on = power == "on" if power else None + self._attr_is_on = power.lower() == "on" if power else None self._attr_brightness: int | None = ( brightness_map_value(brightness) if brightness else None ) diff --git a/homeassistant/components/v2c/manifest.json b/homeassistant/components/v2c/manifest.json index 903280052d003..91eabb8dc0c69 100644 --- a/homeassistant/components/v2c/manifest.json +++ b/homeassistant/components/v2c/manifest.json @@ -6,5 +6,5 @@ "documentation": "https://www.home-assistant.io/integrations/v2c", "integration_type": "device", "iot_class": "local_polling", - "requirements": ["pytrydan==1.0.4"] + "requirements": ["pytrydan==1.0.5"] } diff --git a/requirements_all.txt b/requirements_all.txt index 9020c77cd6d7a..7da24435f4df1 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1534,7 +1534,7 @@ lw12==0.9.2 lxml==6.1.1 # homeassistant.components.lyngdorf -lyngdorf==1.4.3 +lyngdorf==1.4.4 # homeassistant.components.matrix matrix-nio==0.26.0 @@ -2741,7 +2741,7 @@ python-otbr-api==2.10.0 python-overseerr==0.9.0 # homeassistant.components.picnic -python-picnic-api2==1.3.4 +python-picnic-api2==2.0.1 # homeassistant.components.pooldose python-pooldose==0.9.6 @@ -2817,7 +2817,7 @@ pytradfri[async]==9.0.1 pytrafikverket==1.1.1 # homeassistant.components.v2c -pytrydan==1.0.4 +pytrydan==1.0.5 # homeassistant.components.uptimerobot pyuptimerobot==25.0.0 @@ -3068,7 +3068,7 @@ soco==0.31.2 solaredge-local==0.2.3 # homeassistant.components.solaredge -solaredge-web==0.3.0 +solaredge-web==0.3.1 # homeassistant.components.solarlog solarlog_cli==0.7.1 diff --git a/tests/components/anthropic/test_init.py b/tests/components/anthropic/test_init.py index 0fe41c2ab938b..bf8159eb1be7d 100644 --- a/tests/components/anthropic/test_init.py +++ b/tests/components/anthropic/test_init.py @@ -237,8 +237,8 @@ async def test_migration_from_v1_to_v2( assert migrated_entity.unique_id == subentry.subentry_id # Check device migration - assert not device_registry.async_get_device_by_identifier( - (DOMAIN, mock_config_entry.entry_id), mock_config_entry.entry_id + assert not device_registry.async_get_devices( + identifiers={(DOMAIN, mock_config_entry.entry_id)} ) assert ( migrated_device := device_registry.async_get_device_by_identifier( @@ -436,11 +436,11 @@ async def test_migration_from_v1_disabled( assert subentry.data == options assert "Claude" in subentry.title - assert not device_registry.async_get_device_by_identifier( - (DOMAIN, mock_config_entry.entry_id), mock_config_entry.entry_id + assert not device_registry.async_get_devices( + identifiers={(DOMAIN, mock_config_entry.entry_id)} ) - assert not device_registry.async_get_device_by_identifier( - (DOMAIN, mock_config_entry_2.entry_id), mock_config_entry_2.entry_id + assert not device_registry.async_get_devices( + identifiers={(DOMAIN, mock_config_entry_2.entry_id)} ) for idx, subentry in enumerate(conversation_subentries): @@ -667,12 +667,7 @@ async def test_migration_from_v2_1_to_v2_2( device_registry: dr.DeviceRegistry, entity_registry: er.EntityRegistry, ) -> None: - """Test migration from version 2.1 to version 2.2. - - This tests we clean up the broken migration in Home Assistant Core - 2025.7.0b0-2025.7.0b1: - - Fix device registry (Fixed in Home Assistant Core 2025.7.0b2) - """ + """Test migration from version 2.1 to version 2.2.""" # Create a v2.1 config entry with 2 subentries, devices and entities options = { "recommended": True, @@ -715,10 +710,6 @@ async def test_migration_from_v2_1_to_v2_2( model="Claude", entry_type=dr.DeviceEntryType.SERVICE, ) - device_1 = device_registry.async_update_device( - device_1.id, add_config_entry_id="mock_entry_id", add_config_subentry_id=None - ) - assert device_1.config_entries_subentries == {"mock_entry_id": {"mock_id_1"}} entity_registry.async_get_or_create( "conversation", DOMAIN, @@ -778,8 +769,8 @@ async def test_migration_from_v2_1_to_v2_2( assert entity.config_subentry_id == subentry.subentry_id assert entity.config_entry_id == entry.entry_id - assert not device_registry.async_get_device_by_identifier( - (DOMAIN, mock_config_entry.entry_id), mock_config_entry.entry_id + assert not device_registry.async_get_devices( + identifiers={(DOMAIN, mock_config_entry.entry_id)} ) assert ( device := device_registry.async_get_device_by_identifier( @@ -799,8 +790,8 @@ async def test_migration_from_v2_1_to_v2_2( assert entity.unique_id == subentry.subentry_id assert entity.config_subentry_id == subentry.subentry_id assert entity.config_entry_id == entry.entry_id - assert not device_registry.async_get_device_by_identifier( - (DOMAIN, mock_config_entry.entry_id), mock_config_entry.entry_id + assert not device_registry.async_get_devices( + identifiers={(DOMAIN, mock_config_entry.entry_id)} ) assert ( device := device_registry.async_get_device_by_identifier( diff --git a/tests/components/blebox/conftest.py b/tests/components/blebox/conftest.py index 39e599b95a8c0..15cd93775c2a1 100644 --- a/tests/components/blebox/conftest.py +++ b/tests/components/blebox/conftest.py @@ -53,6 +53,7 @@ def mock_feature(category, spec, set_spec: bool = True, **kwargs): type(feature_mock.product).name = PropertyMock(return_value="Some name") type(feature_mock.product).type = PropertyMock(return_value="some type") type(feature_mock.product).model = PropertyMock(return_value="some model") + type(feature_mock.product).product = PropertyMock(return_value="some product") type(feature_mock.product).brand = PropertyMock(return_value="BleBox") type(feature_mock.product).firmware_version = PropertyMock(return_value="1.23") type(feature_mock.product).hardware_version = PropertyMock(return_value="0.1") diff --git a/tests/components/blebox/snapshots/test_diagnostics.ambr b/tests/components/blebox/snapshots/test_diagnostics.ambr index 326885368ae9e..fa702c9adb6ee 100644 --- a/tests/components/blebox/snapshots/test_diagnostics.ambr +++ b/tests/components/blebox/snapshots/test_diagnostics.ambr @@ -11,6 +11,7 @@ }), 'model': 'some model', 'name': 'Some name', + 'product': 'some product', 'type': 'some type', 'unique_id': 'abcd0123ef5678', }), @@ -49,6 +50,7 @@ }), 'model': 'some model', 'name': 'Some name', + 'product': 'some product', 'type': 'some type', 'unique_id': 'abcd0123ef5678', }), diff --git a/tests/components/blebox/test_binary_sensor.py b/tests/components/blebox/test_binary_sensor.py index 1ba01a7ef02a5..6b7103f0aa7d6 100644 --- a/tests/components/blebox/test_binary_sensor.py +++ b/tests/components/blebox/test_binary_sensor.py @@ -28,6 +28,7 @@ def airsensor_fixture() -> tuple[AsyncMock, str]: product = feature.product type(product).name = PropertyMock(return_value="My rain sensor") type(product).model = PropertyMock(return_value="rainSensor") + type(product).product = PropertyMock(return_value="rainSensor") return feature, "binary_sensor.my_rain_sensor_moisture" @@ -45,6 +46,7 @@ def open_sensor_fixture() -> tuple[AsyncMock, str]: product = feature.product type(product).name = PropertyMock(return_value="My open sensor") type(product).model = PropertyMock(return_value="openSensor") + type(product).product = PropertyMock(return_value="openSensor") return feature, "binary_sensor.my_open_sensor_window" @@ -62,6 +64,7 @@ def inputsensor_fixture() -> tuple[AsyncMock, str]: product = feature.product type(product).name = PropertyMock(return_value="My input sensor") type(product).model = PropertyMock(return_value="inputSensorD") + type(product).product = PropertyMock(return_value="inputSensorD") return feature, "binary_sensor.my_input_sensor_input" @@ -134,6 +137,7 @@ async def test_binary_sensor_with_name(hass: HomeAssistant) -> None: product = feature.product type(product).name = PropertyMock(return_value="My rain sensor") type(product).model = PropertyMock(return_value="rainSensor") + type(product).product = PropertyMock(return_value="rainSensor") await async_setup_entity(hass, "binary_sensor.my_rain_sensor_front_yard") state = hass.states.get("binary_sensor.my_rain_sensor_front_yard") diff --git a/tests/components/blebox/test_button.py b/tests/components/blebox/test_button.py index 1a18de458b167..4e8fff9bb784c 100644 --- a/tests/components/blebox/test_button.py +++ b/tests/components/blebox/test_button.py @@ -36,6 +36,7 @@ def tv_lift_box_fixture(caplog: pytest.LogCaptureFixture): product = feature.product type(product).name = PropertyMock(return_value="My tvLiftBox") type(product).model = PropertyMock(return_value="tvLiftBox") + type(product).product = PropertyMock(return_value="tvLiftBox") type(product)._query_string = PropertyMock(return_value="open_or_stop") return (feature, "button.my_tvliftbox") diff --git a/tests/components/blebox/test_climate.py b/tests/components/blebox/test_climate.py index 7d55d8447b09f..6567abf4ecbf3 100644 --- a/tests/components/blebox/test_climate.py +++ b/tests/components/blebox/test_climate.py @@ -55,6 +55,7 @@ def saunabox_fixture(): product = feature.product type(product).name = PropertyMock(return_value="My sauna") type(product).model = PropertyMock(return_value="saunaBox") + type(product).product = PropertyMock(return_value="saunaBox") return (feature, "climate.my_sauna") @@ -78,6 +79,7 @@ def thermobox_fixture(): product = feature.product type(product).name = PropertyMock(return_value="My thermo") type(product).model = PropertyMock(return_value="thermoBox") + type(product).product = PropertyMock(return_value="thermoBox") return (feature, "climate.my_thermo") diff --git a/tests/components/blebox/test_config_flow.py b/tests/components/blebox/test_config_flow.py index 85afe7b7c6379..1c3e1e4bfc9a2 100644 --- a/tests/components/blebox/test_config_flow.py +++ b/tests/components/blebox/test_config_flow.py @@ -64,6 +64,7 @@ def create_valid_feature_mock(path="homeassistant.components.blebox.Products"): type(product).name = PropertyMock(return_value="My gate controller") type(product).model = PropertyMock(return_value="gateController") + type(product).product = PropertyMock(return_value="gateController") type(product).type = PropertyMock(return_value="gateBox") type(product).brand = PropertyMock(return_value="BleBox") type(product).firmware_version = PropertyMock(return_value="1.23") diff --git a/tests/components/blebox/test_cover.py b/tests/components/blebox/test_cover.py index b057e178d56da..69b6b634c5e10 100644 --- a/tests/components/blebox/test_cover.py +++ b/tests/components/blebox/test_cover.py @@ -63,6 +63,7 @@ def shutterbox_fixture(): product = feature.product type(product).name = PropertyMock(return_value="My shutter") type(product).model = PropertyMock(return_value="shutterBox") + type(product).product = PropertyMock(return_value="shutterBox") return (feature, "cover.my_shutter") @@ -86,6 +87,7 @@ def gatebox_fixture(): product = feature.product type(product).name = PropertyMock(return_value="My gatebox") type(product).model = PropertyMock(return_value="gateBox") + type(product).product = PropertyMock(return_value="gateBox") return (feature, "cover.my_gatebox") @@ -109,6 +111,7 @@ def gate_fixture(): product = feature.product type(product).name = PropertyMock(return_value="My gate controller") type(product).model = PropertyMock(return_value="gateController") + type(product).product = PropertyMock(return_value="gateController") return (feature, "cover.my_gate_controller") @@ -247,6 +250,7 @@ async def test_device_class_from_unified_cover_type( product = feature.product type(product).name = PropertyMock(return_value="My shutter") type(product).model = PropertyMock(return_value="shutterBox") + type(product).product = PropertyMock(return_value="shutterBox") entity_id = "cover.my_shutter" entry = await async_setup_entity(hass, entity_id) diff --git a/tests/components/blebox/test_init.py b/tests/components/blebox/test_init.py index cd8d0e8e4da1d..757ccdd5317d3 100644 --- a/tests/components/blebox/test_init.py +++ b/tests/components/blebox/test_init.py @@ -1,13 +1,19 @@ """BleBox devices setup tests.""" +from unittest.mock import PropertyMock + import blebox_uniapi +import blebox_uniapi.sensor import pytest from homeassistant.config_entries import ConfigEntryState from homeassistant.core import HomeAssistant +from homeassistant.helpers import device_registry as dr from .conftest import ( async_setup_config_entry, + async_setup_entity, + mock_feature, patch_product_identify, setup_product_mock, ) @@ -67,3 +73,32 @@ async def test_unload_config_entry( assert not hasattr(config_entry, "runtime_data") assert config_entry.state is ConfigEntryState.NOT_LOADED + + +async def test_device_registry_model_and_hw_version( + hass: HomeAssistant, device_registry: dr.DeviceRegistry +) -> None: + """Test device registry has correct model and hardware version.""" + feature_mock = mock_feature( + "sensors", + blebox_uniapi.sensor.Temperature, + unique_id="BleBox-multiSensor-1afe34e750b8-0.temperature", + full_name="multiSensor-0.temperature", + device_class="temperature", + unit="celsius", + current=None, + native_value=None, + index=None, + ) + type(feature_mock).name = PropertyMock(return_value=None) + type(feature_mock.product).name = PropertyMock(return_value="My test sensor") + type(feature_mock.product).model = PropertyMock(return_value="multiSensor") + type(feature_mock.product).product = PropertyMock(return_value="rainSensor") + type(feature_mock.product).hardware_version = PropertyMock(return_value="2.1") + + entry = await async_setup_entity(hass, "sensor.my_test_sensor_temperature") + + device = device_registry.async_get(entry.device_id) + + assert device.model == "rainSensor" + assert device.hw_version == "2.1" diff --git a/tests/components/blebox/test_light.py b/tests/components/blebox/test_light.py index 031f4bca861aa..df3112bd1ca83 100644 --- a/tests/components/blebox/test_light.py +++ b/tests/components/blebox/test_light.py @@ -53,6 +53,7 @@ def dimmer_fixture(): product = feature.product type(product).name = PropertyMock(return_value="My dimmer") type(product).model = PropertyMock(return_value="dimmerBox") + type(product).product = PropertyMock(return_value="dimmerBox") return (feature, "light.my_dimmer") @@ -175,6 +176,7 @@ def wlightboxs_fixture(): product = feature.product type(product).name = PropertyMock(return_value="My wLightBoxS") type(product).model = PropertyMock(return_value="wLightBoxS") + type(product).product = PropertyMock(return_value="wLightBoxS") return (feature, "light.my_wlightboxs") @@ -260,6 +262,7 @@ def wlightbox_fixture(): product = feature.product type(product).name = PropertyMock(return_value="My wLightBox") type(product).model = PropertyMock(return_value="wLightBox") + type(product).product = PropertyMock(return_value="wLightBox") return (feature, "light.my_wlightbox") @@ -286,6 +289,7 @@ def wlightbox_ct_fixture() -> tuple[MagicMock, str]: product = feature.product type(product).name = PropertyMock(return_value="My wLightBox") type(product).model = PropertyMock(return_value="wLightBox") + type(product).product = PropertyMock(return_value="wLightBox") return feature, "light.my_wlightbox" @@ -571,6 +575,7 @@ async def test_multichannel_light_name( product = feature.product type(product).name = PropertyMock(return_value="My wLightBox") type(product).model = PropertyMock(return_value="wLightBox") + type(product).product = PropertyMock(return_value="wLightBox") await async_setup_entity(hass, entity_id) state = hass.states.get(entity_id) diff --git a/tests/components/blebox/test_sensor.py b/tests/components/blebox/test_sensor.py index 5a24da079bcf5..9c003d60a7898 100644 --- a/tests/components/blebox/test_sensor.py +++ b/tests/components/blebox/test_sensor.py @@ -48,6 +48,7 @@ def airsensor_fixture(): product = feature.product type(product).name = PropertyMock(return_value="My air sensor") type(product).model = PropertyMock(return_value="airSensor") + type(product).product = PropertyMock(return_value="airSensor") return (feature, "sensor.my_air_sensor_pm1") @@ -69,6 +70,7 @@ def tempsensor_fixture(): product = feature.product type(product).name = PropertyMock(return_value="My temperature sensor") type(product).model = PropertyMock(return_value="tempSensor") + type(product).product = PropertyMock(return_value="tempSensor") return (feature, "sensor.my_temperature_sensor_temperature") @@ -174,6 +176,7 @@ async def test_multi_sensor_single_has_no_channel_suffix( product = feature.product type(product).name = PropertyMock(return_value="My smart meter") type(product).model = PropertyMock(return_value="smartMeter") + type(product).product = PropertyMock(return_value="smartMeter") await async_setup_entity(hass, "sensor.my_smart_meter_voltage") state = hass.states.get("sensor.my_smart_meter_voltage") @@ -201,6 +204,7 @@ async def test_multi_sensor_multiple_have_channel_suffix( product = setup_product_mock("sensors", features) type(product).name = PropertyMock(return_value="My smart meter") type(product).model = PropertyMock(return_value="smartMeter") + type(product).product = PropertyMock(return_value="smartMeter") type(product).brand = PropertyMock(return_value="BleBox") type(product).firmware_version = PropertyMock(return_value="1.23") type(product).unique_id = PropertyMock(return_value="aabbcc112233") @@ -256,6 +260,7 @@ def open_status_sensor_fixture(): product = feature.product type(product).name = PropertyMock(return_value="My open sensor") type(product).model = PropertyMock(return_value="openSensor") + type(product).product = PropertyMock(return_value="openSensor") return (feature, "sensor.my_open_sensor_open_status") @@ -326,6 +331,7 @@ def co2_definition_sensor_fixture(): product = feature.product type(product).name = PropertyMock(return_value="My CO2 sensor") type(product).model = PropertyMock(return_value="co2Sensor") + type(product).product = PropertyMock(return_value="co2Sensor") return (feature, "sensor.my_co2_sensor_carbon_dioxide_level") diff --git a/tests/components/blebox/test_switch.py b/tests/components/blebox/test_switch.py index ccd66fad439e1..503af5b88b4e8 100644 --- a/tests/components/blebox/test_switch.py +++ b/tests/components/blebox/test_switch.py @@ -48,6 +48,7 @@ def switchbox_fixture(): product = feature.product type(product).name = PropertyMock(return_value="My switch box") type(product).model = PropertyMock(return_value="switchBox") + type(product).product = PropertyMock(return_value="switchBox") return (feature, "switch.my_switch_box") @@ -162,6 +163,7 @@ def switchbox_d_fixture(): type(product).name = PropertyMock(return_value="My relays") type(product).model = PropertyMock(return_value="switchBoxD") + type(product).product = PropertyMock(return_value="switchBoxD") type(product).brand = PropertyMock(return_value="BleBox") type(product).firmware_version = PropertyMock(return_value="1.23") type(product).unique_id = PropertyMock(return_value="abcd0123ef5678") @@ -333,6 +335,7 @@ async def test_switchbox_with_name(hass: HomeAssistant) -> None: product = feature.product type(product).name = PropertyMock(return_value="My switch box") type(product).model = PropertyMock(return_value="switchBoxD") + type(product).product = PropertyMock(return_value="switchBoxD") await async_setup_entity(hass, "switch.my_switch_box_garden_lights") state = hass.states.get("switch.my_switch_box_garden_lights") diff --git a/tests/components/blebox/test_update.py b/tests/components/blebox/test_update.py index 9f56b9112fb06..3f1b21aa7e233 100644 --- a/tests/components/blebox/test_update.py +++ b/tests/components/blebox/test_update.py @@ -48,6 +48,7 @@ def firmwareupdate_fixture() -> tuple[blebox_uniapi.update.Update, str]: product = feature.product type(product).name = PropertyMock(return_value="My airSensor") type(product).model = PropertyMock(return_value="airSensor") + type(product).product = PropertyMock(return_value="airSensor") return (feature, "update.my_airsensor_firmware") diff --git a/tests/components/bond/test_init.py b/tests/components/bond/test_init.py index 01e5b57bfbf72..feeaa253b57dd 100644 --- a/tests/components/bond/test_init.py +++ b/tests/components/bond/test_init.py @@ -116,7 +116,9 @@ async def test_async_setup_entry_sets_up_hub_and_supported_domains( assert config_entry.unique_id == "ZXXX12345" # verify hub device is registered correctly - hub = device_registry.async_get_device(identifiers={(DOMAIN, "ZXXX12345")}) + hub = device_registry.async_get_device_by_identifier( + (DOMAIN, "ZXXX12345"), config_entry.entry_id + ) assert hub.name == "bond-name" assert hub.manufacturer == "Olibra" assert hub.model == "test-model" @@ -201,8 +203,15 @@ async def test_old_identifiers_are_removed( assert config_entry.unique_id == "ZXXX12345" # verify the device info is cleaned up - assert device_registry.async_get_device(identifiers={old_identifers}) is None - assert device_registry.async_get_device(identifiers={new_identifiers}) is not None + assert ( + device_registry.async_get_device_by_identifier( + old_identifers, config_entry.entry_id + ) + is None + ) + assert device_registry.async_get_device_by_identifier( + new_identifiers, config_entry.entry_id + ) async def test_device_via_device_links( @@ -270,7 +279,9 @@ async def test_smart_by_bond_device_suggested_area( assert config_entry.state is ConfigEntryState.LOADED assert config_entry.unique_id == "KXXX12345" - device = device_registry.async_get_device(identifiers={(DOMAIN, "KXXX12345")}) + device = device_registry.async_get_device_by_identifier( + (DOMAIN, "KXXX12345"), config_entry.entry_id + ) assert device is not None assert device.area_id == area_registry.async_get_area_by_name("Den").id @@ -320,7 +331,9 @@ async def test_bridge_device_suggested_area( assert config_entry.state is ConfigEntryState.LOADED assert config_entry.unique_id == "ZXXX12345" - device = device_registry.async_get_device(identifiers={(DOMAIN, "ZXXX12345")}) + device = device_registry.async_get_device_by_identifier( + (DOMAIN, "ZXXX12345"), config_entry.entry_id + ) assert device is not None assert device.area_id == area_registry.async_get_area_by_name("Office").id diff --git a/tests/components/duco/test_init.py b/tests/components/duco/test_init.py index fdabfd21de241..69d2b743283bc 100644 --- a/tests/components/duco/test_init.py +++ b/tests/components/duco/test_init.py @@ -37,9 +37,13 @@ from tests.common import MockConfigEntry, async_fire_time_changed -def _get_duco_node_device(device_registry: dr.DeviceRegistry) -> dr.DeviceEntry: +def _get_duco_node_device( + device_registry: dr.DeviceRegistry, config_entry_id: str +) -> dr.DeviceEntry: """Return the primary Duco node device used in setup tests.""" - device = device_registry.async_get_device(identifiers={("duco", f"{TEST_MAC}_1")}) + device = device_registry.async_get_device_by_identifier( + ("duco", f"{TEST_MAC}_1"), config_entry_id + ) assert device is not None return device @@ -243,7 +247,7 @@ async def test_setup_entry_ignores_node_name_config_failures( assert mock_config_entry.state is ConfigEntryState.LOADED - device = _get_duco_node_device(device_registry) + device = _get_duco_node_device(device_registry, mock_config_entry.entry_id) assert device.name == mock_nodes[0].general.name assert mock_duco_client.async_get_node_configs.call_count == 1 @@ -384,7 +388,7 @@ async def test_setup_entry_uses_configured_node_name( await hass.config_entries.async_setup(mock_config_entry.entry_id) await hass.async_block_till_done() - device = _get_duco_node_device(device_registry) + device = _get_duco_node_device(device_registry, mock_config_entry.entry_id) assert device.name == "Kitchen" assert mock_duco_client.async_get_node_configs.call_count == 1 @@ -407,7 +411,7 @@ async def test_node_name_refresh_updates_device_registry_name( await hass.config_entries.async_setup(mock_config_entry.entry_id) await hass.async_block_till_done() - device = _get_duco_node_device(device_registry) + device = _get_duco_node_device(device_registry, mock_config_entry.entry_id) assert device.name == "Kitchen" assert mock_duco_client.async_get_node_configs.call_count == 1 @@ -415,13 +419,13 @@ async def test_node_name_refresh_updates_device_registry_name( async_fire_time_changed(hass) await hass.async_block_till_done(wait_background_tasks=True) - device = _get_duco_node_device(device_registry) + device = _get_duco_node_device(device_registry, mock_config_entry.entry_id) assert device.name == "Kitchen" assert mock_duco_client.async_get_node_configs.call_count == 1 assert await hass.config_entries.async_reload(mock_config_entry.entry_id) await hass.async_block_till_done() - device = _get_duco_node_device(device_registry) + device = _get_duco_node_device(device_registry, mock_config_entry.entry_id) assert device.name == "Living Room" assert mock_duco_client.async_get_node_configs.call_count == 2 diff --git a/tests/components/duco/test_sensor.py b/tests/components/duco/test_sensor.py index f3c978d0822bd..698b1d12d507c 100644 --- a/tests/components/duco/test_sensor.py +++ b/tests/components/duco/test_sensor.py @@ -377,8 +377,8 @@ async def test_deregistered_node_removes_device( ) -> None: """Test a node disappearing from the API removes its device from the registry.""" # Verify node 2 (UCCO2 RF sensor) device exists before deregistration. - device = device_registry.async_get_device( - identifiers={(DOMAIN, f"{mock_config_entry.unique_id}_2")} + device = device_registry.async_get_device_by_identifier( + (DOMAIN, f"{mock_config_entry.unique_id}_2"), mock_config_entry.entry_id ) assert device is not None @@ -392,8 +392,8 @@ async def test_deregistered_node_removes_device( await hass.async_block_till_done(wait_background_tasks=True) # The device should be removed from the device registry. - device = device_registry.async_get_device( - identifiers={(DOMAIN, f"{mock_config_entry.unique_id}_2")} + device = device_registry.async_get_device_by_identifier( + (DOMAIN, f"{mock_config_entry.unique_id}_2"), mock_config_entry.entry_id ) assert device is None @@ -413,8 +413,9 @@ async def test_box_node_not_removed_on_transient_incomplete_node_list( hass, mock_config_entry, [Platform.FAN, Platform.SENSOR] ) - box_device = device_registry.async_get_device( - identifiers={(DOMAIN, f"{mock_config_entry.unique_id}_{BOX_NODE_ID}")} + box_device = device_registry.async_get_device_by_identifier( + (DOMAIN, f"{mock_config_entry.unique_id}_{BOX_NODE_ID}"), + mock_config_entry.entry_id, ) assert box_device is not None assert hass.states.get("fan.living") is not None @@ -428,8 +429,9 @@ async def test_box_node_not_removed_on_transient_incomplete_node_list( await hass.async_block_till_done(wait_background_tasks=True) assert ( - device_registry.async_get_device( - identifiers={(DOMAIN, f"{mock_config_entry.unique_id}_{BOX_NODE_ID}")} + device_registry.async_get_device_by_identifier( + (DOMAIN, f"{mock_config_entry.unique_id}_{BOX_NODE_ID}"), + mock_config_entry.entry_id, ) is not None ) @@ -483,8 +485,8 @@ async def test_unknown_node_type_logs_warning_and_creates_no_entities( assert "unsupported" in caplog.text.lower() assert hass.states.get("sensor.unsupported_device_humidity") is None - device = device_registry.async_get_device( - identifiers={(DOMAIN, f"{mock_config_entry.unique_id}_99")} + device = device_registry.async_get_device_by_identifier( + (DOMAIN, f"{mock_config_entry.unique_id}_99"), mock_config_entry.entry_id ) assert device is None diff --git a/tests/components/google_generative_ai_conversation/test_init.py b/tests/components/google_generative_ai_conversation/test_init.py index 75dd8e112e841..bc139d00c9036 100644 --- a/tests/components/google_generative_ai_conversation/test_init.py +++ b/tests/components/google_generative_ai_conversation/test_init.py @@ -191,12 +191,12 @@ async def test_migration_from_v1( assert entity.config_subentry_id == subentry.subentry_id assert entity.config_entry_id == entry.entry_id - assert not device_registry.async_get_device( + assert not device_registry.async_get_devices( identifiers={(DOMAIN, mock_config_entry.entry_id)} ) assert ( - device := device_registry.async_get_device( - identifiers={(DOMAIN, subentry.subentry_id)} + device := device_registry.async_get_device_by_identifier( + (DOMAIN, subentry.subentry_id), mock_config_entry.entry_id ) ) assert device.identifiers == {(DOMAIN, subentry.subentry_id)} @@ -214,12 +214,12 @@ async def test_migration_from_v1( assert entity.unique_id == subentry.subentry_id assert entity.config_subentry_id == subentry.subentry_id assert entity.config_entry_id == entry.entry_id - assert not device_registry.async_get_device( + assert not device_registry.async_get_devices( identifiers={(DOMAIN, mock_config_entry_2.entry_id)} ) assert ( - device := device_registry.async_get_device( - identifiers={(DOMAIN, subentry.subentry_id)} + device := device_registry.async_get_device_by_identifier( + (DOMAIN, subentry.subentry_id), mock_config_entry.entry_id ) ) assert device.identifiers == {(DOMAIN, subentry.subentry_id)} @@ -448,10 +448,10 @@ async def test_migration_from_v1_disabled( assert stt_subentries[0].data == RECOMMENDED_STT_OPTIONS assert stt_subentries[0].title == DEFAULT_STT_NAME - assert not device_registry.async_get_device( + assert not device_registry.async_get_devices( identifiers={(DOMAIN, mock_config_entry.entry_id)} ) - assert not device_registry.async_get_device( + assert not device_registry.async_get_devices( identifiers={(DOMAIN, mock_config_entry_2.entry_id)} ) @@ -464,8 +464,9 @@ async def test_migration_from_v1_disabled( assert entity.disabled_by is subentry_data["entity_disabled_by"] assert ( - device := device_registry.async_get_device( - identifiers={(DOMAIN, subentry.subentry_id)} + device := device_registry.async_get_device_by_identifier( + (DOMAIN, subentry.subentry_id), + mock_config_entries[main_config_entry].entry_id, ) ) assert device.identifiers == {(DOMAIN, subentry.subentry_id)} @@ -577,8 +578,8 @@ async def test_migration_from_v1_with_multiple_keys( assert subentry.data == RECOMMENDED_STT_OPTIONS assert subentry.title == DEFAULT_STT_NAME - dev = device_registry.async_get_device( - identifiers={(DOMAIN, list(entry.subentries.values())[0].subentry_id)} + dev = device_registry.async_get_device_by_identifier( + (DOMAIN, list(entry.subentries.values())[0].subentry_id), entry.entry_id ) assert dev is not None assert dev.config_entries == {entry.entry_id} @@ -709,12 +710,12 @@ async def test_migration_from_v1_with_same_keys( assert entity.config_subentry_id == subentry.subentry_id assert entity.config_entry_id == entry.entry_id - assert not device_registry.async_get_device( + assert not device_registry.async_get_devices( identifiers={(DOMAIN, mock_config_entry.entry_id)} ) assert ( - device := device_registry.async_get_device( - identifiers={(DOMAIN, subentry.subentry_id)} + device := device_registry.async_get_device_by_identifier( + (DOMAIN, subentry.subentry_id), mock_config_entry.entry_id ) ) assert device.identifiers == {(DOMAIN, subentry.subentry_id)} @@ -732,12 +733,12 @@ async def test_migration_from_v1_with_same_keys( assert entity.unique_id == subentry.subentry_id assert entity.config_subentry_id == subentry.subentry_id assert entity.config_entry_id == entry.entry_id - assert not device_registry.async_get_device( + assert not device_registry.async_get_devices( identifiers={(DOMAIN, mock_config_entry_2.entry_id)} ) assert ( - device := device_registry.async_get_device( - identifiers={(DOMAIN, subentry.subentry_id)} + device := device_registry.async_get_device_by_identifier( + (DOMAIN, subentry.subentry_id), mock_config_entry.entry_id ) ) assert device.identifiers == {(DOMAIN, subentry.subentry_id)} @@ -749,34 +750,14 @@ async def test_migration_from_v1_with_same_keys( @pytest.mark.parametrize( - ("device_changes", "extra_subentries", "expected_device_subentries"), + "extra_subentries", [ # Scenario where we have a v2.1 config entry migrated by HA Core 2025.7.0b0: - # Wrong device registry, no TTS subentry - ( - {"add_config_entry_id": "mock_entry_id", "add_config_subentry_id": None}, - [], - {"mock_entry_id": {"mock_id_1"}}, - ), - # Scenario where we have a v2.1 config entry migrated by HA Core 2025.7.0b1: - # Wrong device registry, TTS subentry created - ( - {"add_config_entry_id": "mock_entry_id", "add_config_subentry_id": None}, - [ - ConfigSubentryData( - data=RECOMMENDED_TTS_OPTIONS, - subentry_id="mock_id_3", - subentry_type="tts", - title=DEFAULT_TTS_NAME, - unique_id=None, - ) - ], - {"mock_entry_id": {"mock_id_1"}}, - ), - # Scenario where we have a v2.1 config entry migrated by HA Core 2025.7.0b2 - # or later: Correct device registry, TTS subentry created - ( - {}, + # no TTS subentry + pytest.param([], id="without_tts_subentry"), + # Scenario where we have a v2.1 config entry migrated by HA Core 2025.7.0b1 + # or later: TTS subentry created + pytest.param( [ ConfigSubentryData( data=RECOMMENDED_TTS_OPTIONS, @@ -786,7 +767,7 @@ async def test_migration_from_v1_with_same_keys( unique_id=None, ) ], - {"mock_entry_id": {"mock_id_1"}}, + id="with_tts_subentry", ), ], ) @@ -794,15 +775,11 @@ async def test_migration_from_v2_1( hass: HomeAssistant, device_registry: dr.DeviceRegistry, entity_registry: er.EntityRegistry, - device_changes: dict[str, str], extra_subentries: list[ConfigSubentryData], - expected_device_subentries: dict[str, set[str | None]], ) -> None: """Test migration from version 2.1. - This tests we clean up the broken migration in Home Assistant Core - 2025.7.0b0-2025.7.0b1 and add AI Task and STT subentries: - - Fix device registry (Fixed in Home Assistant Core 2025.7.0b2) + This tests we add TTS, AI Task and STT subentries: - Add TTS subentry (Added in Home Assistant Core 2025.7.0b1) - Add AI Task subentry (Added in version 2.3) - Add STT subentry (Added in version 2.3) @@ -850,8 +827,6 @@ async def test_migration_from_v2_1( model="Generative AI", entry_type=dr.DeviceEntryType.SERVICE, ) - device_1 = device_registry.async_update_device(device_1.id, **device_changes) - assert device_1.config_entries_subentries == expected_device_subentries entity_registry.async_get_or_create( "conversation", DOMAIN, @@ -939,12 +914,12 @@ async def test_migration_from_v2_1( assert entity.config_subentry_id == subentry.subentry_id assert entity.config_entry_id == entry.entry_id - assert not device_registry.async_get_device( + assert not device_registry.async_get_devices( identifiers={(DOMAIN, mock_config_entry.entry_id)} ) assert ( - device := device_registry.async_get_device( - identifiers={(DOMAIN, subentry.subentry_id)} + device := device_registry.async_get_device_by_identifier( + (DOMAIN, subentry.subentry_id), mock_config_entry.entry_id ) ) assert device.identifiers == {(DOMAIN, subentry.subentry_id)} @@ -962,12 +937,12 @@ async def test_migration_from_v2_1( assert entity.unique_id == subentry.subentry_id assert entity.config_subentry_id == subentry.subentry_id assert entity.config_entry_id == entry.entry_id - assert not device_registry.async_get_device( + assert not device_registry.async_get_devices( identifiers={(DOMAIN, mock_config_entry.entry_id)} ) assert ( - device := device_registry.async_get_device( - identifiers={(DOMAIN, subentry.subentry_id)} + device := device_registry.async_get_device_by_identifier( + (DOMAIN, subentry.subentry_id), mock_config_entry.entry_id ) ) assert device.identifiers == {(DOMAIN, subentry.subentry_id)} diff --git a/tests/components/homekit/test_homekit.py b/tests/components/homekit/test_homekit.py index 4778ba35321f4..5f615833700a0 100644 --- a/tests/components/homekit/test_homekit.py +++ b/tests/components/homekit/test_homekit.py @@ -762,8 +762,8 @@ async def test_homekit_start( assert device_registry.async_get(bridge_with_wrong_mac.id) is None - device = device_registry.async_get_device( - identifiers={(DOMAIN, entry.entry_id, BRIDGE_SERIAL_NUMBER)} + device = device_registry.async_get_device_by_identifier( + (DOMAIN, entry.entry_id, BRIDGE_SERIAL_NUMBER), entry.entry_id ) assert device formatted_mac = dr.format_mac(homekit.driver.state.mac) @@ -784,8 +784,8 @@ async def test_homekit_start( assert load_mock.called assert not persist_mock.called - device = device_registry.async_get_device( - identifiers={(DOMAIN, entry.entry_id, BRIDGE_SERIAL_NUMBER)} + device = device_registry.async_get_device_by_identifier( + (DOMAIN, entry.entry_id, BRIDGE_SERIAL_NUMBER), entry.entry_id ) assert device formatted_mac = dr.format_mac(homekit.driver.state.mac) @@ -1101,8 +1101,8 @@ async def test_homekit_unpair( state.add_paired_client(str(uuid1()).encode("utf-8"), "any", b"0") formatted_mac = dr.format_mac(state.mac) - hk_bridge_dev = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, formatted_mac)} + hk_bridge_dev = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, formatted_mac), entry.entry_id ) await hass.services.async_call( @@ -2402,8 +2402,8 @@ async def test_homekit_start_in_accessory_mode( assert hk_driver_start.called assert homekit.status == STATUS_RUNNING - device = device_registry.async_get_device( - identifiers={(DOMAIN, entry.entry_id, BRIDGE_SERIAL_NUMBER)} + device = device_registry.async_get_device_by_identifier( + (DOMAIN, entry.entry_id, BRIDGE_SERIAL_NUMBER), entry.entry_id ) assert device formatted_mac = dr.format_mac(homekit.driver.state.mac) diff --git a/tests/components/homekit_controller/common.py b/tests/components/homekit_controller/common.py index 0b272ab5b73fe..e5f9e0a58b198 100644 --- a/tests/components/homekit_controller/common.py +++ b/tests/components/homekit_controller/common.py @@ -315,7 +315,7 @@ async def setup_test_component( async def assert_devices_and_entities_created( - hass: HomeAssistant, expected: DeviceTestInfo + hass: HomeAssistant, config_entry_id: str, expected: DeviceTestInfo ): """Check all expected devices and entities are loaded correctly.""" entity_registry = er.async_get(hass) @@ -337,8 +337,8 @@ async def _do_assertions(expected: DeviceTestInfo) -> dr.DeviceEntry: # This is only set when we have detected broken serial numbers # (and serial number is not used as an identifier). - device = device_registry.async_get_device( - identifiers={(IDENTIFIER_ACCESSORY_ID, expected.unique_id)} + device = device_registry.async_get_device_by_identifier( + (IDENTIFIER_ACCESSORY_ID, expected.unique_id), config_entry_id ) logger.debug("Comparing device %r to %r", device, expected) diff --git a/tests/components/homekit_controller/specific_devices/test_anker_eufycam.py b/tests/components/homekit_controller/specific_devices/test_anker_eufycam.py index 43945af2fbff9..13c11bf8b1ee5 100644 --- a/tests/components/homekit_controller/specific_devices/test_anker_eufycam.py +++ b/tests/components/homekit_controller/specific_devices/test_anker_eufycam.py @@ -15,10 +15,11 @@ async def test_eufycam_setup(hass: HomeAssistant) -> None: """Test that a eufycam can be correctly setup in HA.""" accessories = await setup_accessories_from_file(hass, "anker_eufycam.json") - await setup_test_accessories(hass, accessories) + config_entry, _ = await setup_test_accessories(hass, accessories) await assert_devices_and_entities_created( hass, + config_entry.entry_id, DeviceTestInfo( unique_id=HUB_TEST_ACCESSORY_ID, name="eufy HomeBase2-0AAA", diff --git a/tests/components/homekit_controller/specific_devices/test_aqara_switch.py b/tests/components/homekit_controller/specific_devices/test_aqara_switch.py index b684800094349..eba3d40fcf631 100644 --- a/tests/components/homekit_controller/specific_devices/test_aqara_switch.py +++ b/tests/components/homekit_controller/specific_devices/test_aqara_switch.py @@ -24,10 +24,11 @@ async def test_aqara_switch_setup(hass: HomeAssistant) -> None: """Test that a Aqara Switch can be correctly setup in HA.""" accessories = await setup_accessories_from_file(hass, "aqara_switch.json") - await setup_test_accessories(hass, accessories) + config_entry, _ = await setup_test_accessories(hass, accessories) await assert_devices_and_entities_created( hass, + config_entry.entry_id, DeviceTestInfo( unique_id=HUB_TEST_ACCESSORY_ID, name="Programmable Switch", diff --git a/tests/components/homekit_controller/specific_devices/test_connectsense.py b/tests/components/homekit_controller/specific_devices/test_connectsense.py index 82c8a1b810298..125153defd8fd 100644 --- a/tests/components/homekit_controller/specific_devices/test_connectsense.py +++ b/tests/components/homekit_controller/specific_devices/test_connectsense.py @@ -21,6 +21,7 @@ async def test_connectsense_setup(hass: HomeAssistant) -> None: await assert_devices_and_entities_created( hass, + config_entry.entry_id, DeviceTestInfo( unique_id=HUB_TEST_ACCESSORY_ID, name="InWall Outlet-0394DE", @@ -100,6 +101,7 @@ async def test_connectsense_setup(hass: HomeAssistant) -> None: await assert_devices_and_entities_created( hass, + config_entry.entry_id, DeviceTestInfo( unique_id=HUB_TEST_ACCESSORY_ID, name="InWall Outlet-0394DE", diff --git a/tests/components/homekit_controller/specific_devices/test_ecobee3.py b/tests/components/homekit_controller/specific_devices/test_ecobee3.py index e79d3ab3edb49..99df4c8112eec 100644 --- a/tests/components/homekit_controller/specific_devices/test_ecobee3.py +++ b/tests/components/homekit_controller/specific_devices/test_ecobee3.py @@ -31,10 +31,11 @@ async def test_ecobee3_setup(hass: HomeAssistant) -> None: """Test that a Ecbobee 3 can be correctly setup in HA.""" accessories = await setup_accessories_from_file(hass, "ecobee3.json") - await setup_test_accessories(hass, accessories) + config_entry, _ = await setup_test_accessories(hass, accessories) await assert_devices_and_entities_created( hass, + config_entry.entry_id, DeviceTestInfo( unique_id=HUB_TEST_ACCESSORY_ID, name="HomeW", diff --git a/tests/components/homekit_controller/specific_devices/test_hue_bridge.py b/tests/components/homekit_controller/specific_devices/test_hue_bridge.py index 115686b2f809b..d8f240a00b3f4 100644 --- a/tests/components/homekit_controller/specific_devices/test_hue_bridge.py +++ b/tests/components/homekit_controller/specific_devices/test_hue_bridge.py @@ -18,10 +18,11 @@ async def test_hue_bridge_setup(hass: HomeAssistant) -> None: """Test that a Hue hub can be correctly setup in HA via HomeKit.""" accessories = await setup_accessories_from_file(hass, "hue_bridge.json") - await setup_test_accessories(hass, accessories) + config_entry, _ = await setup_test_accessories(hass, accessories) await assert_devices_and_entities_created( hass, + config_entry.entry_id, DeviceTestInfo( unique_id=HUB_TEST_ACCESSORY_ID, name="Philips hue - 482544", diff --git a/tests/components/homekit_controller/specific_devices/test_koogeek_sw2.py b/tests/components/homekit_controller/specific_devices/test_koogeek_sw2.py index 0063bfc7f5bd3..439e4f750289d 100644 --- a/tests/components/homekit_controller/specific_devices/test_koogeek_sw2.py +++ b/tests/components/homekit_controller/specific_devices/test_koogeek_sw2.py @@ -22,10 +22,11 @@ async def test_koogeek_sw2_setup(hass: HomeAssistant) -> None: """Test that a Koogeek LS1 can be correctly setup in HA.""" accessories = await setup_accessories_from_file(hass, "koogeek_sw2.json") - await setup_test_accessories(hass, accessories) + config_entry, _ = await setup_test_accessories(hass, accessories) await assert_devices_and_entities_created( hass, + config_entry.entry_id, DeviceTestInfo( unique_id=HUB_TEST_ACCESSORY_ID, name="Koogeek-SW2-187A91", diff --git a/tests/components/homekit_controller/specific_devices/test_lg_tv.py b/tests/components/homekit_controller/specific_devices/test_lg_tv.py index 48d1fc3ebdc91..6242ee88a8b29 100644 --- a/tests/components/homekit_controller/specific_devices/test_lg_tv.py +++ b/tests/components/homekit_controller/specific_devices/test_lg_tv.py @@ -19,10 +19,11 @@ async def test_lg_tv_setup(hass: HomeAssistant) -> None: """Test that a LG TV can be correctly setup in HA.""" accessories = await setup_accessories_from_file(hass, "lg_tv.json") - await setup_test_accessories(hass, accessories) + config_entry, _ = await setup_test_accessories(hass, accessories) await assert_devices_and_entities_created( hass, + config_entry.entry_id, DeviceTestInfo( unique_id=HUB_TEST_ACCESSORY_ID, name="LG webOS TV AF80", diff --git a/tests/components/homekit_controller/specific_devices/test_netamo_doorbell.py b/tests/components/homekit_controller/specific_devices/test_netamo_doorbell.py index 9b85a111fc7c3..cb03ab4780bd1 100644 --- a/tests/components/homekit_controller/specific_devices/test_netamo_doorbell.py +++ b/tests/components/homekit_controller/specific_devices/test_netamo_doorbell.py @@ -19,10 +19,11 @@ async def test_netamo_doorbell_setup(hass: HomeAssistant) -> None: """Test that a Netamo Doorbell can be correctly setup in HA.""" accessories = await setup_accessories_from_file(hass, "netamo_doorbell.json") - await setup_test_accessories(hass, accessories) + config_entry, _ = await setup_test_accessories(hass, accessories) await assert_devices_and_entities_created( hass, + config_entry.entry_id, DeviceTestInfo( unique_id=HUB_TEST_ACCESSORY_ID, name="Netatmo-Doorbell-g738658", diff --git a/tests/components/homekit_controller/specific_devices/test_vocolinc_vp3.py b/tests/components/homekit_controller/specific_devices/test_vocolinc_vp3.py index 9bb06486e18b5..02530394e3233 100644 --- a/tests/components/homekit_controller/specific_devices/test_vocolinc_vp3.py +++ b/tests/components/homekit_controller/specific_devices/test_vocolinc_vp3.py @@ -35,10 +35,11 @@ async def test_vocolinc_vp3_setup( ) accessories = await setup_accessories_from_file(hass, "vocolinc_vp3.json") - await setup_test_accessories(hass, accessories) + config_entry, _ = await setup_test_accessories(hass, accessories) await assert_devices_and_entities_created( hass, + config_entry.entry_id, DeviceTestInfo( unique_id=HUB_TEST_ACCESSORY_ID, name="VOCOlinc-VP3-123456", diff --git a/tests/components/homekit_controller/test_init.py b/tests/components/homekit_controller/test_init.py index d7c3266f230ee..58153e49c26b2 100644 --- a/tests/components/homekit_controller/test_init.py +++ b/tests/components/homekit_controller/test_init.py @@ -263,8 +263,8 @@ async def test_ble_device_populates_connections( assert config_entry.state is ConfigEntryState.LOADED dev_reg = dr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures assert ( - dev_reg.async_get_device( - identifiers={}, connections={("bluetooth", "AA:BB:CC:DD:EE:FF")} + dev_reg.async_get_device_by_connection( + ("bluetooth", "AA:BB:CC:DD:EE:FF"), config_entry.entry_id ) is not None ) diff --git a/tests/components/honeywell/test_init.py b/tests/components/honeywell/test_init.py index 1d18a527e0c95..13418395e2d46 100644 --- a/tests/components/honeywell/test_init.py +++ b/tests/components/honeywell/test_init.py @@ -162,23 +162,7 @@ async def test_remove_stale_device( """Test that the stale device is removed.""" location.devices_by_id[another_device.deviceid] = another_device - config_entry_other = MockConfigEntry( - domain="OtherDomain", - data={}, - unique_id="unique_id", - ) - config_entry_other.add_to_hass(hass) - device_entry_other = device_registry.async_get_or_create( - config_entry_id=config_entry_other.entry_id, - identifiers={("OtherDomain", 7654321)}, - ) - config_entry.add_to_hass(hass) - device_registry.async_update_device( - device_entry_other.id, - add_config_entry_id=config_entry.entry_id, - merge_identifiers={(DOMAIN, 7654321)}, - ) await hass.config_entries.async_setup(config_entry.entry_id) await hass.async_block_till_done() @@ -188,28 +172,9 @@ async def test_remove_stale_device( device_entries = dr.async_entries_for_config_entry( device_registry, config_entry.entry_id ) - - device_entries_other = dr.async_entries_for_config_entry( - device_registry, config_entry_other.entry_id - ) - assert len(device_entries) == 2 assert any((DOMAIN, 1234567) in device.identifiers for device in device_entries) assert any((DOMAIN, 7654321) in device.identifiers for device in device_entries) - # Identifiers are unique per config entry, so Honeywell and OtherDomain have - # separate devices for 7654321; Honeywell's devices do not carry the OtherDomain - # identifier - assert not any( - ("OtherDomain", 7654321) in device.identifiers for device in device_entries - ) - assert len(device_entries_other) == 1 - assert any( - ("OtherDomain", 7654321) in device.identifiers - for device in device_entries_other - ) - assert any( - (DOMAIN, 7654321) in device.identifiers for device in device_entries_other - ) assert await hass.config_entries.async_unload(config_entry.entry_id) await hass.async_block_till_done() @@ -233,15 +198,3 @@ async def test_remove_stale_device( assert len(device_entries) == 1 assert any((DOMAIN, 1234567) in device.identifiers for device in device_entries) assert not any((DOMAIN, 7654321) in device.identifiers for device in device_entries) - assert not any( - ("OtherDomain", 7654321) in device.identifiers for device in device_entries - ) - - device_entries_other = dr.async_entries_for_config_entry( - device_registry, config_entry_other.entry_id - ) - assert len(device_entries_other) == 1 - assert any( - ("OtherDomain", 7654321) in device.identifiers - for device in device_entries_other - ) diff --git a/tests/components/ollama/test_init.py b/tests/components/ollama/test_init.py index 758d4ae341fc6..460ce25337fee 100644 --- a/tests/components/ollama/test_init.py +++ b/tests/components/ollama/test_init.py @@ -239,8 +239,8 @@ async def test_migration_from_v1( assert migrated_entity.unique_id == subentry.subentry_id # Check device migration - assert not device_registry.async_get_device_by_identifier( - (DOMAIN, mock_config_entry.entry_id), mock_config_entry.entry_id + assert not device_registry.async_get_devices( + identifiers={(DOMAIN, mock_config_entry.entry_id)} ) assert ( migrated_device := device_registry.async_get_device_by_identifier( @@ -652,11 +652,11 @@ async def test_migration_from_v1_disabled( assert ai_task_subentries[0].data == {"model": "llama3.2:latest"} assert ai_task_subentries[0].title == "Ollama AI Task" - assert not device_registry.async_get_device_by_identifier( - (DOMAIN, mock_config_entry.entry_id), mock_config_entry.entry_id + assert not device_registry.async_get_devices( + identifiers={(DOMAIN, mock_config_entry.entry_id)} ) - assert not device_registry.async_get_device_by_identifier( - (DOMAIN, mock_config_entry_2.entry_id), mock_config_entry_2.entry_id + assert not device_registry.async_get_devices( + identifiers={(DOMAIN, mock_config_entry_2.entry_id)} ) for idx, subentry in enumerate(conversation_subentries): @@ -689,12 +689,7 @@ async def test_migration_from_v2_1( device_registry: dr.DeviceRegistry, entity_registry: er.EntityRegistry, ) -> None: - """Test migration from version 2.1. - - This tests we clean up the broken migration in Home Assistant Core - 2025.7.0b0-2025.7.0b1: - - Fix device registry (Fixed in Home Assistant Core 2025.7.0b2) - """ + """Test migration from version 2.1.""" # Create a v2.1 config entry with 2 subentries, devices and entities mock_config_entry = MockConfigEntry( domain=DOMAIN, @@ -731,10 +726,6 @@ async def test_migration_from_v2_1( model="Ollama", entry_type=dr.DeviceEntryType.SERVICE, ) - device_1 = device_registry.async_update_device( - device_1.id, add_config_entry_id="mock_entry_id", add_config_subentry_id=None - ) - assert device_1.config_entries_subentries == {"mock_entry_id": {"mock_id_1"}} entity_registry.async_get_or_create( "conversation", DOMAIN, @@ -800,8 +791,8 @@ async def test_migration_from_v2_1( assert entity.config_subentry_id == subentry.subentry_id assert entity.config_entry_id == entry.entry_id - assert not device_registry.async_get_device_by_identifier( - (DOMAIN, mock_config_entry.entry_id), mock_config_entry.entry_id + assert not device_registry.async_get_devices( + identifiers={(DOMAIN, mock_config_entry.entry_id)} ) assert ( device := device_registry.async_get_device_by_identifier( @@ -821,8 +812,8 @@ async def test_migration_from_v2_1( assert entity.unique_id == subentry.subentry_id assert entity.config_subentry_id == subentry.subentry_id assert entity.config_entry_id == entry.entry_id - assert not device_registry.async_get_device_by_identifier( - (DOMAIN, mock_config_entry.entry_id), mock_config_entry.entry_id + assert not device_registry.async_get_devices( + identifiers={(DOMAIN, mock_config_entry.entry_id)} ) assert ( device := device_registry.async_get_device_by_identifier( diff --git a/tests/components/openai_conversation/test_init.py b/tests/components/openai_conversation/test_init.py index 8970d0b9d9a99..dcd6d492ddc8a 100644 --- a/tests/components/openai_conversation/test_init.py +++ b/tests/components/openai_conversation/test_init.py @@ -736,8 +736,8 @@ async def test_migration_from_v1( assert migrated_entity.unique_id == subentry.subentry_id # Check device migration - assert not device_registry.async_get_device_by_identifier( - (DOMAIN, mock_config_entry.entry_id), mock_config_entry.entry_id + assert not device_registry.async_get_devices( + identifiers={(DOMAIN, mock_config_entry.entry_id)} ) assert ( migrated_device := device_registry.async_get_device_by_identifier( @@ -1192,11 +1192,11 @@ async def test_migration_from_v1_disabled( assert tts_subentries[0].data == RECOMMENDED_TTS_OPTIONS assert tts_subentries[0].title == DEFAULT_TTS_NAME - assert not device_registry.async_get_device_by_identifier( - (DOMAIN, mock_config_entry.entry_id), mock_config_entry.entry_id + assert not device_registry.async_get_devices( + identifiers={(DOMAIN, mock_config_entry.entry_id)} ) - assert not device_registry.async_get_device_by_identifier( - (DOMAIN, mock_config_entry_2.entry_id), mock_config_entry_2.entry_id + assert not device_registry.async_get_devices( + identifiers={(DOMAIN, mock_config_entry_2.entry_id)} ) for idx, subentry in enumerate(conversation_subentries): @@ -1229,12 +1229,7 @@ async def test_migration_from_v2_1( device_registry: dr.DeviceRegistry, entity_registry: er.EntityRegistry, ) -> None: - """Test migration from version 2.1. - - This tests we clean up the broken migration in Home Assistant Core - 2025.7.0b0-2025.7.0b1: - - Fix device registry (Fixed in Home Assistant Core 2025.7.0b2) - """ + """Test migration from version 2.1.""" # Create a v2.1 config entry with 2 subentries, devices and entities options = { "recommended": True, @@ -1277,10 +1272,6 @@ async def test_migration_from_v2_1( model="ChatGPT", entry_type=dr.DeviceEntryType.SERVICE, ) - device_1 = device_registry.async_update_device( - device_1.id, add_config_entry_id="mock_entry_id", add_config_subentry_id=None - ) - assert device_1.config_entries_subentries == {"mock_entry_id": {"mock_id_1"}} entity_registry.async_get_or_create( "conversation", DOMAIN, @@ -1362,8 +1353,8 @@ async def test_migration_from_v2_1( assert entity.config_subentry_id == subentry.subentry_id assert entity.config_entry_id == entry.entry_id - assert not device_registry.async_get_device_by_identifier( - (DOMAIN, mock_config_entry.entry_id), mock_config_entry.entry_id + assert not device_registry.async_get_devices( + identifiers={(DOMAIN, mock_config_entry.entry_id)} ) assert ( device := device_registry.async_get_device_by_identifier( @@ -1383,8 +1374,8 @@ async def test_migration_from_v2_1( assert entity.unique_id == subentry.subentry_id assert entity.config_subentry_id == subentry.subentry_id assert entity.config_entry_id == entry.entry_id - assert not device_registry.async_get_device_by_identifier( - (DOMAIN, mock_config_entry.entry_id), mock_config_entry.entry_id + assert not device_registry.async_get_devices( + identifiers={(DOMAIN, mock_config_entry.entry_id)} ) assert ( device := device_registry.async_get_device_by_identifier( diff --git a/tests/components/picnic/conftest.py b/tests/components/picnic/conftest.py index fac10ec491bf5..daba33bd3dfbb 100644 --- a/tests/components/picnic/conftest.py +++ b/tests/components/picnic/conftest.py @@ -6,6 +6,7 @@ from unittest.mock import MagicMock, patch import pytest +from python_picnic_api2.models import Cart, DeliverySummary, Eta, User from homeassistant.components.picnic import CONF_COUNTRY_CODE, DOMAIN from homeassistant.const import CONF_ACCESS_TOKEN @@ -19,7 +20,7 @@ SetupDeliveryFixture = Callable[ [str, tuple[timedelta, timedelta] | None, tuple[timedelta, timedelta]], - Awaitable[dict], + Awaitable[DeliverySummary], ] @@ -42,10 +43,14 @@ def mock_picnic_api(): with patch("homeassistant.components.picnic.PicnicAPI") as mock: client = mock.return_value client.session.auth_token = "3q29fpwhulzes" - client.get_cart.return_value = json.loads(load_fixture("picnic/cart.json")) - client.get_user.return_value = json.loads(load_fixture("picnic/user.json")) + client.get_cart.return_value = Cart.from_api( + json.loads(load_fixture("picnic/cart.json")) + ) + client.get_user.return_value = User.from_api( + json.loads(load_fixture("picnic/user.json")) + ) client.get_deliveries.return_value = [ - json.loads(load_fixture("picnic/delivery.json")) + DeliverySummary.from_api(json.loads(load_fixture("picnic/delivery.json"))) ] client.get_delivery_position.return_value = {} yield client @@ -63,19 +68,18 @@ async def _setup( status: str, eta2: tuple[timedelta, timedelta] | None, slot_window: tuple[timedelta, timedelta], - ) -> dict: + ) -> DeliverySummary: delivery = mock_picnic_api.get_deliveries.return_value[0] - delivery["status"] = status - delivery["delivery_time"] = None + delivery.status = status + # delivery_time isn't a modelled field; it lives on the raw payload + delivery.raw["delivery_time"] = None # eta2 is the API's field name for the route-planning ETA - delivery["eta2"] = eta2 and { - "start": (dt_util.utcnow() + eta2[0]).isoformat(), - "end": (dt_util.utcnow() + eta2[1]).isoformat(), - } - delivery["slot"]["window_start"] = ( - dt_util.utcnow() + slot_window[0] - ).isoformat() - delivery["slot"]["window_end"] = (dt_util.utcnow() + slot_window[1]).isoformat() + delivery.eta2 = eta2 and Eta( + start=(dt_util.utcnow() + eta2[0]).isoformat(), + end=(dt_util.utcnow() + eta2[1]).isoformat(), + ) + delivery.slot.window_start = (dt_util.utcnow() + slot_window[0]).isoformat() + delivery.slot.window_end = (dt_util.utcnow() + slot_window[1]).isoformat() mock_config_entry.add_to_hass(hass) await hass.config_entries.async_setup(mock_config_entry.entry_id) diff --git a/tests/components/picnic/test_config_flow.py b/tests/components/picnic/test_config_flow.py index c5e221cb3996e..150a4231aac4b 100644 --- a/tests/components/picnic/test_config_flow.py +++ b/tests/components/picnic/test_config_flow.py @@ -3,6 +3,7 @@ from unittest.mock import patch import pytest +from python_picnic_api2.models import User from python_picnic_api2.session import ( Picnic2FAError, Picnic2FARequired, @@ -36,7 +37,7 @@ def picnic_api(): ) as picnic_mock: instance = picnic_mock.return_value instance.session.auth_token = auth_token - instance.get_user.return_value = auth_data + instance.get_user.return_value = User.from_api(auth_data) instance.login.return_value = None # no 2FA by default instance.generate_2fa_code.return_value = None instance.verify_2fa_code.return_value = None @@ -389,7 +390,7 @@ async def test_form_already_configured(hass: HomeAssistant, picnic_api) -> None: # user_id as set for the picnic_api mock response. MockConfigEntry( domain=DOMAIN, - unique_id=picnic_api().get_user()["user_id"], + unique_id=picnic_api().get_user().user_id, data={CONF_ACCESS_TOKEN: "a3p98fsen.a39p3fap", CONF_COUNTRY_CODE: "NL"}, ).add_to_hass(hass) @@ -418,7 +419,7 @@ async def test_step_reauth(hass: HomeAssistant, picnic_api) -> None: entry = MockConfigEntry( domain=DOMAIN, - unique_id=picnic_api().get_user()["user_id"], + unique_id=picnic_api().get_user().user_id, data=conf, ) entry.add_to_hass(hass) diff --git a/tests/components/picnic/test_coordinator.py b/tests/components/picnic/test_coordinator.py index 209fcedd29f87..5816566b2e6fb 100644 --- a/tests/components/picnic/test_coordinator.py +++ b/tests/components/picnic/test_coordinator.py @@ -5,6 +5,7 @@ from freezegun.api import FrozenDateTimeFactory import pytest +from python_picnic_api2.models import Eta from homeassistant.components.picnic.const import ( DEFAULT_UPDATE_INTERVAL, @@ -112,15 +113,11 @@ async def test_update_interval_with_malformed_eta( ) -> None: """Test that a malformed ETA falls back to the slot window.""" delivery = mock_picnic_api.get_deliveries.return_value[0] - delivery["status"] = "CURRENT" - delivery["delivery_time"] = None - delivery["eta2"] = {"start": "malformed", "end": "malformed"} - delivery["slot"]["window_start"] = ( - dt_util.utcnow() + timedelta(minutes=10) - ).isoformat() - delivery["slot"]["window_end"] = ( - dt_util.utcnow() + timedelta(minutes=70) - ).isoformat() + delivery.status = "CURRENT" + delivery.raw["delivery_time"] = None + delivery.eta2 = Eta(start="malformed", end="malformed") + delivery.slot.window_start = (dt_util.utcnow() + timedelta(minutes=10)).isoformat() + delivery.slot.window_end = (dt_util.utcnow() + timedelta(minutes=70)).isoformat() mock_config_entry.add_to_hass(hass) await hass.config_entries.async_setup(mock_config_entry.entry_id) @@ -146,7 +143,7 @@ async def test_update_interval_relaxes_after_delivery( coordinator = mock_config_entry.runtime_data assert coordinator.update_interval == DELIVERY_UPDATE_INTERVAL - delivery["status"] = "COMPLETED" + delivery.status = "COMPLETED" freezer.tick(DELIVERY_UPDATE_INTERVAL + timedelta(seconds=30)) async_fire_time_changed(hass) await hass.async_block_till_done(wait_background_tasks=True) diff --git a/tests/components/picnic/test_sensor.py b/tests/components/picnic/test_sensor.py index 68f96f23361c6..0dbbc2a6a4011 100644 --- a/tests/components/picnic/test_sensor.py +++ b/tests/components/picnic/test_sensor.py @@ -6,6 +6,7 @@ from unittest.mock import patch import pytest +from python_picnic_api2.models import Cart, DeliverySummary, User import requests from homeassistant import config_entries @@ -150,14 +151,14 @@ async def _setup_platform( ): """Set up the Picnic sensor platform.""" if use_default_responses: - self.picnic_mock().get_user.return_value = copy.deepcopy( - DEFAULT_USER_RESPONSE + self.picnic_mock().get_user.return_value = User.from_api( + copy.deepcopy(DEFAULT_USER_RESPONSE) ) - self.picnic_mock().get_cart.return_value = copy.deepcopy( - DEFAULT_CART_RESPONSE + self.picnic_mock().get_cart.return_value = Cart.from_api( + copy.deepcopy(DEFAULT_CART_RESPONSE) ) self.picnic_mock().get_deliveries.return_value = [ - copy.deepcopy(DEFAULT_DELIVERY_RESPONSE) + DeliverySummary.from_api(copy.deepcopy(DEFAULT_DELIVERY_RESPONSE)) ] self.picnic_mock().get_delivery_position.return_value = {} @@ -315,10 +316,12 @@ async def test_sensors_no_selected_time_slot(self): cart_response["selected_slot"]["state"] = "IMPLICIT" # Set mock responses - self.picnic_mock().get_user.return_value = copy.deepcopy(DEFAULT_USER_RESPONSE) - self.picnic_mock().get_cart.return_value = cart_response + self.picnic_mock().get_user.return_value = User.from_api( + copy.deepcopy(DEFAULT_USER_RESPONSE) + ) + self.picnic_mock().get_cart.return_value = Cart.from_api(cart_response) self.picnic_mock().get_deliveries.return_value = [ - copy.deepcopy(DEFAULT_DELIVERY_RESPONSE) + DeliverySummary.from_api(copy.deepcopy(DEFAULT_DELIVERY_RESPONSE)) ] self.picnic_mock().get_delivery_position.return_value = {} await self._setup_platform() @@ -343,9 +346,15 @@ async def test_next_delivery_sensors(self): delivery_response["status"] = "CURRENT" # Set mock responses - self.picnic_mock().get_user.return_value = copy.deepcopy(DEFAULT_USER_RESPONSE) - self.picnic_mock().get_cart.return_value = copy.deepcopy(DEFAULT_CART_RESPONSE) - self.picnic_mock().get_deliveries.return_value = [delivery_response] + self.picnic_mock().get_user.return_value = User.from_api( + copy.deepcopy(DEFAULT_USER_RESPONSE) + ) + self.picnic_mock().get_cart.return_value = Cart.from_api( + copy.deepcopy(DEFAULT_CART_RESPONSE) + ) + self.picnic_mock().get_deliveries.return_value = [ + DeliverySummary.from_api(delivery_response) + ] self.picnic_mock().get_delivery_position.return_value = {} await self._setup_platform() @@ -381,7 +390,9 @@ async def test_sensors_eta_date_malformed(self): delivery_response = copy.deepcopy(DEFAULT_DELIVERY_RESPONSE) delivery_response["eta2"] = eta_dates delivery_response["status"] = "CURRENT" - self.picnic_mock().get_deliveries.return_value = [delivery_response] + self.picnic_mock().get_deliveries.return_value = [ + DeliverySummary.from_api(delivery_response) + ] await self._coordinator.async_refresh() # Assert eta times are not available due to malformed date strings @@ -404,7 +415,9 @@ async def test_sensors_use_detailed_eta_if_available(self): delivery_response = copy.deepcopy(DEFAULT_DELIVERY_RESPONSE) del delivery_response["delivery_time"] delivery_response["status"] = "CURRENT" - self.picnic_mock().get_deliveries.return_value = [delivery_response] + self.picnic_mock().get_deliveries.return_value = [ + DeliverySummary.from_api(delivery_response) + ] self.picnic_mock().get_delivery_position.return_value = { "eta_window": { "start": "2021-03-05T10:19:20.452+00:00", @@ -543,14 +556,18 @@ async def test_multiple_active_orders(self): undelivered_order_2["eta2"]["end"] = "2022-03-08T13:45:00.000+01:00" deliveries_response = [ - undelivered_order_2, - undelivered_order, - copy.deepcopy(DEFAULT_DELIVERY_RESPONSE), + DeliverySummary.from_api(undelivered_order_2), + DeliverySummary.from_api(undelivered_order), + DeliverySummary.from_api(copy.deepcopy(DEFAULT_DELIVERY_RESPONSE)), ] # Set mock responses - self.picnic_mock().get_user.return_value = copy.deepcopy(DEFAULT_USER_RESPONSE) - self.picnic_mock().get_cart.return_value = copy.deepcopy(DEFAULT_CART_RESPONSE) + self.picnic_mock().get_user.return_value = User.from_api( + copy.deepcopy(DEFAULT_USER_RESPONSE) + ) + self.picnic_mock().get_cart.return_value = Cart.from_api( + copy.deepcopy(DEFAULT_CART_RESPONSE) + ) self.picnic_mock().get_deliveries.return_value = deliveries_response self.picnic_mock().get_delivery_position.return_value = {} await self._setup_platform() diff --git a/tests/components/picnic/test_services.py b/tests/components/picnic/test_services.py index d46c0832b1a34..c5f60d1acd74f 100644 --- a/tests/components/picnic/test_services.py +++ b/tests/components/picnic/test_services.py @@ -3,6 +3,7 @@ from unittest.mock import MagicMock, patch import pytest +from python_picnic_api2.models import SearchResult, SearchResultItem, User from homeassistant.components.picnic import CONF_COUNTRY_CODE, DOMAIN from homeassistant.components.picnic.const import SERVICE_ADD_PRODUCT_TO_CART @@ -29,7 +30,7 @@ def create_picnic_api_client(unique_id): } picnic_mock = MagicMock() picnic_mock.session.auth_token = auth_token - picnic_mock.get_user.return_value = auth_data + picnic_mock.get_user.return_value = User.from_api(auth_data) return picnic_mock @@ -98,24 +99,22 @@ async def test_add_product_using_name( """Test adding a product by name.""" # Set the return value of the search api endpoint - picnic_api_client.search.return_value = [ - { - "items": [ - { - "id": "2525404", - "name": "Best tea", - "display_price": 321, - "unit_quantity": "big bags", - }, - { - "id": "2525500", - "name": "Cheap tea", - "display_price": 100, - "unit_quantity": "small bags", - }, - ] - } - ] + picnic_api_client.search.return_value = SearchResult( + items=[ + SearchResultItem( + id="2525404", + name="Best tea", + display_price=321, + unit_quantity="big bags", + ), + SearchResultItem( + id="2525500", + name="Cheap tea", + display_price=100, + unit_quantity="small bags", + ), + ] + ) await hass.services.async_call( DOMAIN, @@ -137,7 +136,7 @@ async def test_add_product_using_name_no_results( # Set the search return value and check that the right exception # is raised during the service call - picnic_api_client.search.return_value = [] + picnic_api_client.search.return_value = SearchResult(items=[]) with pytest.raises(PicnicServiceException): await hass.services.async_call( DOMAIN, @@ -159,7 +158,9 @@ async def test_add_product_using_name_no_named_results( # Set the search return value and check that the right exception # is raised during the service call - picnic_api_client.search.return_value = [{"items": [{"attr": "test"}]}] + picnic_api_client.search.return_value = SearchResult( + items=[SearchResultItem(id="999")] + ) with pytest.raises(PicnicServiceException): await hass.services.async_call( DOMAIN, diff --git a/tests/components/picnic/test_todo.py b/tests/components/picnic/test_todo.py index 3a6e09f7ac0df..45ab02a304d29 100644 --- a/tests/components/picnic/test_todo.py +++ b/tests/components/picnic/test_todo.py @@ -3,6 +3,7 @@ from unittest.mock import MagicMock, Mock import pytest +from python_picnic_api2.models import Cart, SearchResult, SearchResultItem from syrupy.assertion import SnapshotAssertion from homeassistant.components.todo import ATTR_ITEM, DOMAIN as TODO_DOMAIN, TodoServices @@ -33,7 +34,7 @@ async def test_cart_list_empty_items( hass: HomeAssistant, mock_picnic_api: MagicMock, mock_config_entry: MockConfigEntry ) -> None: """Test loading of shopping cart without items.""" - mock_picnic_api.get_cart.return_value = {"items": []} + mock_picnic_api.get_cart.return_value = Cart(items=[]) mock_config_entry.add_to_hass(hass) await hass.config_entries.async_setup(mock_config_entry.entry_id) await hass.async_block_till_done() @@ -76,17 +77,9 @@ async def test_create_todo_list_item( assert len(mock_picnic_api.get_cart.mock_calls) == 1 mock_picnic_api.search = Mock() - mock_picnic_api.search.return_value = [ - { - "items": [ - { - "id": 321, - "name": "Picnic Melk", - "unit_quantity": "2 liter", - } - ] - } - ] + mock_picnic_api.search.return_value = SearchResult( + items=[SearchResultItem(id="321", name="Picnic Melk", unit_quantity="2 liter")] + ) mock_picnic_api.add_product = Mock() @@ -115,7 +108,7 @@ async def test_create_todo_list_item_not_found( ) -> None: """Test for creating a picnic cart item when ID is not found.""" mock_picnic_api.search = Mock() - mock_picnic_api.search.return_value = [{"items": []}] + mock_picnic_api.search.return_value = SearchResult(items=[]) with pytest.raises(ServiceValidationError): await hass.services.async_call( diff --git a/tests/components/ruckus_unleashed/test_init.py b/tests/components/ruckus_unleashed/test_init.py index c77dff769255e..4f5d7eaa5e445 100644 --- a/tests/components/ruckus_unleashed/test_init.py +++ b/tests/components/ruckus_unleashed/test_init.py @@ -60,13 +60,12 @@ async def test_router_device_setup( hass: HomeAssistant, device_registry: dr.DeviceRegistry ) -> None: """Test a router device is created.""" - await init_integration(hass) + entry = await init_integration(hass) device_info = DEFAULT_AP_INFO[0] - device = device_registry.async_get_device( - identifiers={(CONNECTION_NETWORK_MAC, device_info[API_AP_MAC])}, - connections={(CONNECTION_NETWORK_MAC, device_info[API_AP_MAC])}, + device = device_registry.async_get_device_by_connection( + (CONNECTION_NETWORK_MAC, device_info[API_AP_MAC]), entry.entry_id ) assert device diff --git a/tests/components/russound_rio/test_init.py b/tests/components/russound_rio/test_init.py index de6340d2a2d78..7fbe5326b36ba 100644 --- a/tests/components/russound_rio/test_init.py +++ b/tests/components/russound_rio/test_init.py @@ -43,8 +43,8 @@ async def test_device_info( ) -> None: """Test device registry integration.""" await setup_integration(hass, mock_config_entry) - device_entry = device_registry.async_get_device( - identifiers={(DOMAIN, mock_config_entry.unique_id)} + device_entry = device_registry.async_get_device_by_identifier( + (DOMAIN, mock_config_entry.unique_id), mock_config_entry.entry_id ) assert device_entry is not None assert device_entry == snapshot diff --git a/tests/components/sensibo/test_init.py b/tests/components/sensibo/test_init.py index 0de04c798539a..442af4b54ef16 100644 --- a/tests/components/sensibo/test_init.py +++ b/tests/components/sensibo/test_init.py @@ -140,7 +140,9 @@ async def test_automatic_device_addition_and_removal( assert state assert entity_registry.async_get(entity_id) for device_id in device_ids: - assert device_registry.async_get_device(identifiers={(DOMAIN, device_id)}) + assert device_registry.async_get_device_by_identifier( + (DOMAIN, device_id), load_int.entry_id + ) # Remove one of the devices new_device_list = [ @@ -162,7 +164,9 @@ async def test_automatic_device_addition_and_removal( assert not state assert not entity_registry.async_get(entity_id) for device_id in device_ids: - assert not device_registry.async_get_device(identifiers={(DOMAIN, device_id)}) + assert not device_registry.async_get_device_by_identifier( + (DOMAIN, device_id), load_int.entry_id + ) # Add the device back mock_client.async_get_devices.return_value = get_data[2] @@ -176,4 +180,6 @@ async def test_automatic_device_addition_and_removal( assert state assert entity_registry.async_get(entity_id) for device_id in device_ids: - assert device_registry.async_get_device(identifiers={(DOMAIN, device_id)}) + assert device_registry.async_get_device_by_identifier( + (DOMAIN, device_id), load_int.entry_id + ) diff --git a/tests/components/shelly/test_coordinator.py b/tests/components/shelly/test_coordinator.py index 87c40b7be3f4a..ded9f296460ed 100644 --- a/tests/components/shelly/test_coordinator.py +++ b/tests/components/shelly/test_coordinator.py @@ -892,9 +892,8 @@ async def test_rpc_update_entry_fw_ver( await hass.async_block_till_done(wait_background_tasks=True) assert entry.unique_id - device = device_registry.async_get_device( - identifiers={(DOMAIN, entry.entry_id)}, - connections={(dr.CONNECTION_NETWORK_MAC, dr.format_mac(entry.unique_id))}, + device = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, dr.format_mac(entry.unique_id)), entry.entry_id ) assert device assert device.sw_version == "some fw string" @@ -904,9 +903,8 @@ async def test_rpc_update_entry_fw_ver( mock_rpc_device.mock_update() await hass.async_block_till_done() - device = device_registry.async_get_device( - identifiers={(DOMAIN, entry.entry_id)}, - connections={(dr.CONNECTION_NETWORK_MAC, dr.format_mac(entry.unique_id))}, + device = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, dr.format_mac(entry.unique_id)), entry.entry_id ) assert device assert device.sw_version == "99.0.0" @@ -1145,9 +1143,8 @@ async def test_xmod_model_lookup( monkeypatch.setattr(mock_rpc_device, "xmod_info", {"n": xmod_model}) entry = await init_integration(hass, 2) - device = device_registry.async_get_device( - identifiers={(DOMAIN, entry.entry_id)}, - connections={(dr.CONNECTION_NETWORK_MAC, dr.format_mac(entry.unique_id))}, + device = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, dr.format_mac(entry.unique_id)), entry.entry_id ) assert device assert device.model == xmod_model diff --git a/tests/components/smartthings/snapshots/test_climate.ambr b/tests/components/smartthings/snapshots/test_climate.ambr index 8c29788fe901c..fc8330524d3f4 100644 --- a/tests/components/smartthings/snapshots/test_climate.ambr +++ b/tests/components/smartthings/snapshots/test_climate.ambr @@ -155,8 +155,8 @@ , , ]), - : 35, - : 7, + : 30, + : 18, : list([ 'none', 'wind_free', @@ -171,6 +171,7 @@ 'horizontal', 'both', ]), + : 0.5, }), 'config_entry_id': , 'config_subentry_id': , @@ -226,8 +227,8 @@ , , ]), - : 35, - : 7, + : 30, + : 18, : 'none', : list([ 'none', @@ -245,6 +246,7 @@ 'horizontal', 'both', ]), + : 0.5, : 20, }), 'context': , @@ -581,8 +583,8 @@ , , ]), - : 35, - : 7, + : 30, + : 16, : list([ 'none', 'sleep', @@ -598,6 +600,7 @@ 'horizontal', 'both', ]), + : 1, }), 'config_entry_id': , 'config_subentry_id': , @@ -654,8 +657,8 @@ , , ]), - : 35, - : 7, + : 30, + : 16, : 'none', : list([ 'none', @@ -674,6 +677,7 @@ 'horizontal', 'both', ]), + : 1, : 23, }), 'context': , diff --git a/tests/components/smartthings/test_climate.py b/tests/components/smartthings/test_climate.py index 0b1d91a806122..208345390a434 100644 --- a/tests/components/smartthings/test_climate.py +++ b/tests/components/smartthings/test_climate.py @@ -22,6 +22,9 @@ ATTR_SWING_MODE, ATTR_TARGET_TEMP_HIGH, ATTR_TARGET_TEMP_LOW, + ATTR_TARGET_TEMP_STEP, + DEFAULT_MAX_TEMP, + DEFAULT_MIN_TEMP, DOMAIN as CLIMATE_DOMAIN, PRESET_BOOST, PRESET_NONE, @@ -616,6 +619,35 @@ async def test_ac_state_attributes_update( ) +@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"]) +async def test_ac_setpoint_range_update( + hass: HomeAssistant, + devices: AsyncMock, + mock_config_entry: MockConfigEntry, +) -> None: + """Test the setpoint range is used when the device reports one.""" + await setup_integration(hass, mock_config_entry) + + state = hass.states.get("climate.theater_ac_office_granit") + assert state.attributes[ATTR_MIN_TEMP] == DEFAULT_MIN_TEMP + assert state.attributes[ATTR_MAX_TEMP] == DEFAULT_MAX_TEMP + assert ATTR_TARGET_TEMP_STEP not in state.attributes + + await trigger_update( + hass, + devices, + "96a5ef74-5832-a84b-f1f7-ca799957065d", + Capability.THERMOSTAT_COOLING_SETPOINT, + Attribute.COOLING_SETPOINT_RANGE, + {"minimum": 16, "maximum": 30, "step": 1}, + ) + + state = hass.states.get("climate.theater_ac_office_granit") + assert state.attributes[ATTR_MIN_TEMP] == 16 + assert state.attributes[ATTR_MAX_TEMP] == 30 + assert state.attributes[ATTR_TARGET_TEMP_STEP] == 1 + + @pytest.mark.parametrize("device_fixture", ["virtual_thermostat"]) async def test_thermostat_set_fan_mode( hass: HomeAssistant, diff --git a/tests/components/tasmota/test_common.py b/tests/components/tasmota/test_common.py index d23c031b9aa1d..8b24e5bccc1e4 100644 --- a/tests/components/tasmota/test_common.py +++ b/tests/components/tasmota/test_common.py @@ -540,8 +540,9 @@ async def help_test_discovery_removal( await hass.async_block_till_done() # Verify device and entity registry entries are created - device_entry = device_reg.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, config1[CONF_MAC])} + device_entry = device_reg.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, config1[CONF_MAC]), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert device_entry is not None entity_entry = entity_reg.async_get(f"{domain}.{object_id}") @@ -563,8 +564,9 @@ async def help_test_discovery_removal( await hass.async_block_till_done() # Verify entity registry entries are cleared - device_entry = device_reg.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, config2[CONF_MAC])} + device_entry = device_reg.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, config2[CONF_MAC]), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert device_entry is not None entity_entry = entity_reg.async_get(f"{domain}.{object_id}") @@ -654,8 +656,9 @@ async def help_test_discovery_device_remove( ) await hass.async_block_till_done() - device = device_reg.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, config[CONF_MAC])} + device = device_reg.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, config[CONF_MAC]), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert device is not None assert entity_reg.async_get_entity_id(domain, "tasmota", unique_id) @@ -663,8 +666,9 @@ async def help_test_discovery_device_remove( async_fire_mqtt_message(hass, f"{DEFAULT_PREFIX}/{config[CONF_MAC]}/config", "") await hass.async_block_till_done() - device = device_reg.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, config[CONF_MAC])} + device = device_reg.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, config[CONF_MAC]), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert device is None assert not entity_reg.async_get_entity_id(domain, "tasmota", unique_id) diff --git a/tests/components/tasmota/test_device_trigger.py b/tests/components/tasmota/test_device_trigger.py index 80138da69e81b..5cee64875106a 100644 --- a/tests/components/tasmota/test_device_trigger.py +++ b/tests/components/tasmota/test_device_trigger.py @@ -40,8 +40,9 @@ async def test_get_triggers_btn( async_fire_mqtt_message(hass, f"{DEFAULT_PREFIX}/{mac}/config", json.dumps(config)) await hass.async_block_till_done() - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) expected_triggers = [ { @@ -83,8 +84,9 @@ async def test_get_triggers_swc( async_fire_mqtt_message(hass, f"{DEFAULT_PREFIX}/{mac}/config", json.dumps(config)) await hass.async_block_till_done() - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) expected_triggers = [ { @@ -118,8 +120,9 @@ async def test_get_unknown_triggers( async_fire_mqtt_message(hass, f"{DEFAULT_PREFIX}/{mac}/config", json.dumps(config)) await hass.async_block_till_done() - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert await async_setup_component( @@ -166,8 +169,9 @@ async def test_get_non_existing_triggers( async_fire_mqtt_message(hass, f"{DEFAULT_PREFIX}/{mac}/config", json.dumps(config1)) await hass.async_block_till_done() - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) triggers = await async_get_device_automations( hass, DeviceAutomationType.TRIGGER, device_entry.id @@ -197,8 +201,9 @@ async def test_discover_bad_triggers( ) await hass.async_block_till_done() - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) triggers = await async_get_device_automations( hass, DeviceAutomationType.TRIGGER, device_entry.id @@ -233,8 +238,9 @@ def is_active(self): ) await hass.async_block_till_done() - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) triggers = await async_get_device_automations( hass, DeviceAutomationType.TRIGGER, device_entry.id @@ -285,8 +291,9 @@ async def test_update_remove_triggers( async_fire_mqtt_message(hass, f"{DEFAULT_PREFIX}/{mac}/config", json.dumps(config1)) await hass.async_block_till_done() - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) expected_triggers1 = [ @@ -355,8 +362,9 @@ async def test_if_fires_on_mqtt_message_btn( async_fire_mqtt_message(hass, f"{DEFAULT_PREFIX}/{mac}/config", json.dumps(config)) await hass.async_block_till_done() - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert await async_setup_component( @@ -431,8 +439,9 @@ async def test_if_fires_on_mqtt_message_swc( async_fire_mqtt_message(hass, f"{DEFAULT_PREFIX}/{mac}/config", json.dumps(config)) await hass.async_block_till_done() - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert await async_setup_component( @@ -533,8 +542,9 @@ async def test_if_fires_on_mqtt_message_late_discover( async_fire_mqtt_message(hass, f"{DEFAULT_PREFIX}/{mac}/config", json.dumps(config1)) await hass.async_block_till_done() - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert await async_setup_component( @@ -613,8 +623,9 @@ async def test_if_fires_on_mqtt_message_after_update( async_fire_mqtt_message(hass, f"{DEFAULT_PREFIX}/{mac}/config", json.dumps(config1)) await hass.async_block_till_done() - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert await async_setup_component( @@ -697,8 +708,9 @@ async def test_no_resubscribe_same_topic( async_fire_mqtt_message(hass, f"{DEFAULT_PREFIX}/{mac}/config", json.dumps(config)) await hass.async_block_till_done() - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert await async_setup_component( @@ -749,8 +761,9 @@ async def test_not_fires_on_mqtt_message_after_remove_by_mqtt( async_fire_mqtt_message(hass, f"{DEFAULT_PREFIX}/{mac}/config", json.dumps(config)) await hass.async_block_till_done() - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert await async_setup_component( @@ -826,8 +839,9 @@ async def test_not_fires_on_mqtt_message_after_remove_from_registry( async_fire_mqtt_message(hass, f"{DEFAULT_PREFIX}/{mac}/config", json.dumps(config)) await hass.async_block_till_done() - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert await async_setup_component( @@ -888,8 +902,9 @@ async def test_attach_remove( async_fire_mqtt_message(hass, f"{DEFAULT_PREFIX}/{mac}/config", json.dumps(config)) await hass.async_block_till_done() - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) service_calls = [] @@ -954,8 +969,9 @@ async def test_attach_remove_late( async_fire_mqtt_message(hass, f"{DEFAULT_PREFIX}/{mac}/config", json.dumps(config1)) await hass.async_block_till_done() - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) service_calls = [] @@ -1030,8 +1046,9 @@ async def test_attach_remove_late2( async_fire_mqtt_message(hass, f"{DEFAULT_PREFIX}/{mac}/config", json.dumps(config1)) await hass.async_block_till_done() - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) service_calls = [] @@ -1087,8 +1104,9 @@ async def test_attach_remove_unknown1( async_fire_mqtt_message(hass, f"{DEFAULT_PREFIX}/{mac}/config", json.dumps(config1)) await hass.async_block_till_done() - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) remove = await async_initialize_triggers( @@ -1140,8 +1158,9 @@ async def test_attach_unknown_remove_device_from_registry( async_fire_mqtt_message(hass, f"{DEFAULT_PREFIX}/{mac}/config", json.dumps(config1)) await hass.async_block_till_done() - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) await async_initialize_triggers( @@ -1184,8 +1203,9 @@ async def test_attach_remove_config_entry( async_fire_mqtt_message(hass, f"{DEFAULT_PREFIX}/{mac}/config", json.dumps(config)) await hass.async_block_till_done() - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) service_calls = [] diff --git a/tests/components/tasmota/test_discovery.py b/tests/components/tasmota/test_discovery.py index fdfa04eadc8c7..0f59b1ce6140d 100644 --- a/tests/components/tasmota/test_discovery.py +++ b/tests/components/tasmota/test_discovery.py @@ -155,8 +155,9 @@ async def test_correct_config_discovery( await hass.async_block_till_done() # Verify device and registry entries are created - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert device_entry is not None entity_entry = entity_registry.async_get("switch.tasmota_test") @@ -187,8 +188,9 @@ async def test_device_discover( await hass.async_block_till_done() # Verify device and registry entries are created - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert device_entry is not None assert device_entry.configuration_url == f"http://{config['ip']}/" @@ -216,8 +218,9 @@ async def test_device_discover_deprecated( await hass.async_block_till_done() # Verify device and registry entries are created - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert device_entry is not None assert device_entry.manufacturer == "Tasmota" @@ -247,8 +250,9 @@ async def test_device_update( await hass.async_block_till_done() # Verify device entry is created - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert device_entry is not None @@ -265,8 +269,9 @@ async def test_device_update( await hass.async_block_till_done() # Verify device entry is updated - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert device_entry is not None assert device_entry.model == "Another model" @@ -292,8 +297,9 @@ async def test_device_remove( await hass.async_block_till_done() # Verify device entry is created - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert device_entry is not None @@ -305,8 +311,9 @@ async def test_device_remove( await hass.async_block_till_done() # Verify device entry is removed - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert device_entry is None @@ -432,8 +439,9 @@ async def test_device_remove_multiple_config_entries_2( await hass.async_block_till_done() # Verify the Tasmota device entry is not removed - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert device_entry is not None assert device_entry.config_entries == {tasmota_entry.entry_id} @@ -466,8 +474,9 @@ async def test_device_remove_stale( ) # Verify device entry was created - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert device_entry is not None @@ -475,8 +484,9 @@ async def test_device_remove_stale( await remove_device(hass, hass_ws_client, device_entry.id) # Verify device entry is removed - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert device_entry is None @@ -499,8 +509,9 @@ async def test_device_rediscover( await hass.async_block_till_done() # Verify device entry is created - device_entry1 = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry1 = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert device_entry1 is not None @@ -512,8 +523,9 @@ async def test_device_rediscover( await hass.async_block_till_done() # Verify device entry is removed - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert device_entry is None @@ -525,8 +537,9 @@ async def test_device_rediscover( await hass.async_block_till_done() # Verify device entry is created, and id is reused - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert device_entry is not None assert device_entry1.id == device_entry.id @@ -626,8 +639,9 @@ async def test_same_topic( # Verify device registry entries are created for both devices for config in configs[0:2]: - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, config["mac"])} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, config["mac"]), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert device_entry is not None assert device_entry.configuration_url == f"http://{config['ip']}/" @@ -637,12 +651,14 @@ async def test_same_topic( assert device_entry.sw_version == config["sw"] # Verify entities are created only for the first device - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, configs[0]["mac"])} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, configs[0]["mac"]), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert len(er.async_entries_for_device(entity_registry, device_entry.id, True)) == 1 - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, configs[1]["mac"])} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, configs[1]["mac"]), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert len(er.async_entries_for_device(entity_registry, device_entry.id, True)) == 0 @@ -660,8 +676,9 @@ async def test_same_topic( await hass.async_block_till_done() # Verify device registry entries was created - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, configs[2]["mac"])} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, configs[2]["mac"]), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert device_entry is not None assert device_entry.configuration_url == f"http://{configs[2]['ip']}/" @@ -671,8 +688,9 @@ async def test_same_topic( assert device_entry.sw_version == configs[2]["sw"] # Verify no entities were created - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, configs[2]["mac"])} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, configs[2]["mac"]), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert len(er.async_entries_for_device(entity_registry, device_entry.id, True)) == 0 @@ -690,8 +708,9 @@ async def test_same_topic( await hass.async_block_till_done() # Verify entities are created also for the third device - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, configs[2]["mac"])} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, configs[2]["mac"]), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert len(er.async_entries_for_device(entity_registry, device_entry.id, True)) == 1 @@ -709,8 +728,9 @@ async def test_same_topic( await hass.async_block_till_done() # Verify entities are created also for the second device - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, configs[1]["mac"])} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, configs[1]["mac"]), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert len(er.async_entries_for_device(entity_registry, device_entry.id, True)) == 1 @@ -739,8 +759,9 @@ async def test_topic_no_prefix( await hass.async_block_till_done() # Verify device registry entry is created - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, config["mac"])} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, config["mac"]), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert device_entry is not None assert device_entry.configuration_url == f"http://{config['ip']}/" @@ -750,8 +771,9 @@ async def test_topic_no_prefix( assert device_entry.sw_version == config["sw"] # Verify entities are not created - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, config["mac"])} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, config["mac"]), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert len(er.async_entries_for_device(entity_registry, device_entry.id, True)) == 0 @@ -769,8 +791,9 @@ async def test_topic_no_prefix( await hass.async_block_till_done() # Verify entities are created - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, config["mac"])} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, config["mac"]), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert len(er.async_entries_for_device(entity_registry, device_entry.id, True)) == 1 diff --git a/tests/components/tasmota/test_init.py b/tests/components/tasmota/test_init.py index 5eb3872c8df41..d0b02cf810a97 100644 --- a/tests/components/tasmota/test_init.py +++ b/tests/components/tasmota/test_init.py @@ -41,8 +41,9 @@ async def test_device_remove( await hass.async_block_till_done() # Verify device entry is created - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert device_entry is not None @@ -50,10 +51,13 @@ async def test_device_remove( await hass.async_block_till_done() # Verify device entry is removed - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + assert ( + device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, + ) + is None ) - assert device_entry is None # Verify retained discovery topic has been cleared mqtt_mock.async_publish.assert_has_calls( @@ -113,10 +117,12 @@ async def async_remove_config_entry_device( await hass.async_block_till_done() # Verify device entry is removed - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + assert ( + device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), config_entry.entry_id + ) + is None ) - assert device_entry is None # Verify no Tasmota discovery message was sent mqtt_mock.async_publish.assert_not_called() @@ -144,10 +150,12 @@ async def test_device_remove_stale_tasmota_device( await hass.async_block_till_done() # Verify device entry is removed - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + assert ( + device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), config_entry.entry_id + ) + is None ) - assert device_entry is None # Verify retained discovery topic has not been cleared mqtt_mock.async_publish.assert_not_called() @@ -169,8 +177,9 @@ async def test_tasmota_ws_remove_discovered_device( await hass.async_block_till_done() # Verify device entry is created - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + device_entry = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), + hass.config_entries.async_entries("tasmota")[0].entry_id, ) assert device_entry is not None @@ -180,7 +189,9 @@ async def test_tasmota_ws_remove_discovered_device( ) # Verify device entry is cleared - device_entry = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, mac)} + assert ( + device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, mac), tasmota_config_entry.entry_id + ) + is None ) - assert device_entry is None diff --git a/tests/components/unifi_access/test_services.py b/tests/components/unifi_access/test_services.py index b08dad8e898a9..c9aadea44d668 100644 --- a/tests/components/unifi_access/test_services.py +++ b/tests/components/unifi_access/test_services.py @@ -28,9 +28,13 @@ FRONT_DOOR_LOCK_RULE_ENTITY = "sensor.front_door_lock_rule" -def _device_id(device_registry: dr.DeviceRegistry, identifier: str) -> str: +def _device_id( + device_registry: dr.DeviceRegistry, identifier: str, config_entry_id: str +) -> str: """Return the device ID for a UniFi Access identifier.""" - device = device_registry.async_get_device(identifiers={(DOMAIN, identifier)}) + device = device_registry.async_get_device_by_identifier( + (DOMAIN, identifier), config_entry_id + ) assert device is not None return device.id @@ -48,7 +52,9 @@ async def test_set_lock_rule_service_calls_api( DOMAIN, SERVICE_SET_LOCK_RULE, { - ATTR_DEVICE_ID: _device_id(device_registry, "door-001"), + ATTR_DEVICE_ID: _device_id( + device_registry, "door-001", mock_config_entry.entry_id + ), ATTR_RULE: "keep_lock", ATTR_INTERVAL: {"minutes": 30}, }, @@ -73,7 +79,9 @@ async def test_set_lock_rule_service_defaults_interval( DOMAIN, SERVICE_SET_LOCK_RULE, { - ATTR_DEVICE_ID: _device_id(device_registry, "door-001"), + ATTR_DEVICE_ID: _device_id( + device_registry, "door-001", mock_config_entry.entry_id + ), ATTR_RULE: "keep_unlock", }, blocking=True, @@ -98,7 +106,9 @@ async def test_set_lock_rule_service_updates_sensor_state( DOMAIN, SERVICE_SET_LOCK_RULE, { - ATTR_DEVICE_ID: _device_id(device_registry, "door-001"), + ATTR_DEVICE_ID: _device_id( + device_registry, "door-001", mock_config_entry.entry_id + ), ATTR_RULE: "keep_lock", }, blocking=True, @@ -126,7 +136,9 @@ async def test_set_lock_rule_service_raises_on_api_error( DOMAIN, SERVICE_SET_LOCK_RULE, { - ATTR_DEVICE_ID: _device_id(device_registry, "door-001"), + ATTR_DEVICE_ID: _device_id( + device_registry, "door-001", mock_config_entry.entry_id + ), ATTR_RULE: "keep_lock", }, blocking=True, @@ -150,7 +162,11 @@ async def test_set_lock_rule_service_rejects_hub_device( DOMAIN, SERVICE_SET_LOCK_RULE, { - ATTR_DEVICE_ID: _device_id(device_registry, mock_config_entry.entry_id), + ATTR_DEVICE_ID: _device_id( + device_registry, + mock_config_entry.entry_id, + mock_config_entry.entry_id, + ), ATTR_RULE: "keep_lock", }, blocking=True, diff --git a/tests/components/velbus/test_init.py b/tests/components/velbus/test_init.py index 9af5ec773be05..bad3ac73ad52d 100644 --- a/tests/components/velbus/test_init.py +++ b/tests/components/velbus/test_init.py @@ -74,29 +74,38 @@ async def test_device_identifier_migration( device_registry: dr.DeviceRegistry, ) -> None: """Test being able to unload an entry.""" - original_identifiers = {(DOMAIN, "module_address", "module_serial")} - target_identifiers = {(DOMAIN, "module_address")} + original_identifier = (DOMAIN, "module_address", "module_serial") + target_identifier = (DOMAIN, "module_address") device_registry.async_get_or_create( config_entry_id=config_entry.entry_id, - identifiers=original_identifiers, # type: ignore[arg-type] + identifiers={original_identifier}, # type: ignore[arg-type] name="channel_name", manufacturer="Velleman", model="module_type_name", sw_version="module_sw_version", ) - assert device_registry.async_get_device( - identifiers=original_identifiers # type: ignore[arg-type] + assert device_registry.async_get_device_by_identifier( + original_identifier, # type: ignore[arg-type] + config_entry.entry_id, + ) + assert ( + device_registry.async_get_device_by_identifier( + target_identifier, config_entry.entry_id + ) + is None ) - assert not device_registry.async_get_device(identifiers=target_identifiers) await hass.config_entries.async_setup(config_entry.entry_id) await hass.async_block_till_done() - assert not device_registry.async_get_device( - identifiers=original_identifiers # type: ignore[arg-type] + assert not device_registry.async_get_device_by_identifier( + original_identifier, # type: ignore[arg-type] + config_entry.entry_id, + ) + device_entry = device_registry.async_get_device_by_identifier( + target_identifier, config_entry.entry_id ) - device_entry = device_registry.async_get_device(identifiers=target_identifiers) assert device_entry assert device_entry.name == "channel_name" assert device_entry.manufacturer == "Velleman" @@ -216,13 +225,19 @@ async def test_device_registry( # Sort by identifier to ensure consistent order in snapshot assert sorted(device_entries, key=lambda x: list(x.identifiers)[0][1]) == snapshot - device_parent = device_registry.async_get_device(identifiers={(DOMAIN, "88")}) + device_parent = device_registry.async_get_device_by_identifier( + (DOMAIN, "88"), config_entry.entry_id + ) assert device_parent.via_device_id is None - device = device_registry.async_get_device(identifiers={(DOMAIN, "88-9")}) + device = device_registry.async_get_device_by_identifier( + (DOMAIN, "88-9"), config_entry.entry_id + ) assert device.via_device_id == device_parent.id - device_no_sub = device_registry.async_get_device(identifiers={(DOMAIN, "2")}) + device_no_sub = device_registry.async_get_device_by_identifier( + (DOMAIN, "2"), config_entry.entry_id + ) assert device_no_sub.via_device_id is None @@ -235,7 +250,9 @@ async def test_remove_config_entry_device( await init_integration(hass, config_entry) # Active device (found on bus) can be removed; scan will recreate it - active_device = device_registry.async_get_device(identifiers={(DOMAIN, "1")}) + active_device = device_registry.async_get_device_by_identifier( + (DOMAIN, "1"), config_entry.entry_id + ) assert active_device is not None result = await async_remove_config_entry_device(hass, config_entry, active_device) assert result is True diff --git a/tests/components/vilfo/test_init.py b/tests/components/vilfo/test_init.py index 51a019e76a3e8..66849e5d888c0 100644 --- a/tests/components/vilfo/test_init.py +++ b/tests/components/vilfo/test_init.py @@ -13,16 +13,16 @@ @pytest.mark.parametrize( - ("mac", "identifiers"), + ("mac", "identifier"), [ pytest.param( "FF-00-00-00-00-00", - {(DOMAIN, "testadmin.vilfo.com", "FF-00-00-00-00-00")}, + (DOMAIN, "testadmin.vilfo.com", "FF-00-00-00-00-00"), id="with_mac", ), pytest.param( None, - {(DOMAIN, "testadmin.vilfo.com", None)}, + (DOMAIN, "testadmin.vilfo.com", None), id="without_mac", ), ], @@ -33,7 +33,7 @@ async def test_device_registry( device_registry: dr.DeviceRegistry, snapshot: SnapshotAssertion, mac: str | None, - identifiers: set[tuple[str, str | None]], + identifier: tuple[str, str, str | None], ) -> None: """Test the device registry entry. @@ -55,5 +55,7 @@ async def test_device_registry( assert await hass.config_entries.async_setup(mock_config_entry.entry_id) await hass.async_block_till_done() - device_entry = device_registry.async_get_device(identifiers=identifiers) + device_entry = device_registry.async_get_device_by_identifier( + identifier, mock_config_entry.entry_id + ) assert device_entry == snapshot diff --git a/tests/components/vodafone_station/test_coordinator.py b/tests/components/vodafone_station/test_coordinator.py index c119184d3cc1e..f235f747fe65a 100644 --- a/tests/components/vodafone_station/test_coordinator.py +++ b/tests/components/vodafone_station/test_coordinator.py @@ -66,7 +66,10 @@ async def test_coordinator_device_cleanup( assert f"Skipping entity {DEVICE_2_HOST}" in caplog.text assert ( - device_registry.async_get_device(identifiers={(DOMAIN, DEVICE_1_MAC)}) is None + device_registry.async_get_device_by_identifier( + (DOMAIN, DEVICE_1_MAC), mock_config_entry.entry_id + ) + is None ) assert f"Removing device: {DEVICE_1_HOST}" in caplog.text diff --git a/tests/components/voip/test_devices.py b/tests/components/voip/test_devices.py index 2771ab7d66c31..bf1b2a38ed480 100644 --- a/tests/components/voip/test_devices.py +++ b/tests/components/voip/test_devices.py @@ -20,13 +20,14 @@ async def test_device_registry_info( voip_devices: VoIPDevices, call_info: CallInfo, device_registry: dr.DeviceRegistry, + config_entry: MockConfigEntry, ) -> None: """Test info in device registry.""" voip_device = voip_devices.async_get_or_create(call_info) assert not voip_device.async_allow_call(hass) - device = device_registry.async_get_device( - identifiers={(DOMAIN, call_info.caller_endpoint.uri)} + device = device_registry.async_get_device_by_identifier( + (DOMAIN, call_info.caller_endpoint.uri), config_entry.entry_id ) assert device is not None assert device.name == call_info.caller_endpoint.host @@ -40,8 +41,8 @@ async def test_device_registry_info( assert not voip_device.async_allow_call(hass) - device = device_registry.async_get_device( - identifiers={(DOMAIN, call_info.caller_endpoint.uri)} + device = device_registry.async_get_device_by_identifier( + (DOMAIN, call_info.caller_endpoint.uri), config_entry.entry_id ) assert device.sw_version == "2.0.0.0" @@ -51,14 +52,15 @@ async def test_device_registry_info_from_unknown_phone( voip_devices: VoIPDevices, call_info: CallInfo, device_registry: dr.DeviceRegistry, + config_entry: MockConfigEntry, ) -> None: """Test info in device registry from unknown phone.""" call_info.headers["user-agent"] = "Unknown" voip_device = voip_devices.async_get_or_create(call_info) assert not voip_device.async_allow_call(hass) - device = device_registry.async_get_device( - identifiers={(DOMAIN, call_info.caller_endpoint.uri)} + device = device_registry.async_get_device_by_identifier( + (DOMAIN, call_info.caller_endpoint.uri), config_entry.entry_id ) assert device.manufacturer is None assert device.model == "Unknown" @@ -70,13 +72,14 @@ async def test_device_registry_info_update_contact( voip_devices: VoIPDevices, call_info: CallInfo, device_registry: dr.DeviceRegistry, + config_entry: MockConfigEntry, ) -> None: """Test info in device registry.""" voip_device = voip_devices.async_get_or_create(call_info) assert not voip_device.async_allow_call(hass) - device = device_registry.async_get_device( - identifiers={(DOMAIN, call_info.caller_endpoint.uri)} + device = device_registry.async_get_device_by_identifier( + (DOMAIN, call_info.caller_endpoint.uri), config_entry.entry_id ) assert device is not None assert device.name == call_info.caller_endpoint.host @@ -92,8 +95,8 @@ async def test_device_registry_info_update_contact( assert voip_device.contact == SipEndpoint("Test ") assert not voip_device.async_allow_call(hass) - device = device_registry.async_get_device( - identifiers={(DOMAIN, call_info.caller_endpoint.uri)} + device = device_registry.async_get_device_by_identifier( + (DOMAIN, call_info.caller_endpoint.uri), config_entry.entry_id ) assert device.sw_version == "2.0.0.0" @@ -179,13 +182,16 @@ async def test_device_registry_migration( call_info: CallInfo, entity_registry: er.EntityRegistry, device_registry: dr.DeviceRegistry, + config_entry: MockConfigEntry, ) -> None: """Test info in device registry migrates old devices.""" voip_device = voip_devices.async_get_or_create(call_info) new_id = call_info.caller_endpoint.uri assert voip_device.voip_id == new_id - device = device_registry.async_get_device(identifiers={(DOMAIN, new_id)}) + device = device_registry.async_get_device_by_identifier( + (DOMAIN, new_id), config_entry.entry_id + ) assert device is not None assert device.id == legacy_dev_reg_entry.id assert device.identifiers == {(DOMAIN, new_id)} diff --git a/tests/components/waqi/test_init.py b/tests/components/waqi/test_init.py index fd35031fc0c1d..92adbf32b6fac 100644 --- a/tests/components/waqi/test_init.py +++ b/tests/components/waqi/test_init.py @@ -111,7 +111,11 @@ async def test_migration_from_v1( assert entity.config_subentry_id == subentry.subentry_id assert entity.config_entry_id == entry.entry_id - assert (device := device_registry.async_get_device(identifiers={(DOMAIN, "4584")})) + assert ( + device := device_registry.async_get_device_by_identifier( + (DOMAIN, "4584"), mock_config_entry.entry_id + ) + ) assert device.identifiers == {(DOMAIN, "4584")} assert device.id == device_1.id assert device.config_entries == {mock_config_entry.entry_id} @@ -129,7 +133,11 @@ async def test_migration_from_v1( assert entity.unique_id == "4585_air_quality" assert entity.config_subentry_id == subentry.subentry_id assert entity.config_entry_id == entry.entry_id - assert (device := device_registry.async_get_device(identifiers={(DOMAIN, "4585")})) + assert ( + device := device_registry.async_get_device_by_identifier( + (DOMAIN, "4585"), mock_config_entry.entry_id + ) + ) assert device.identifiers == {(DOMAIN, "4585")} assert device.id == device_2.id assert device.config_entries == {mock_config_entry.entry_id} @@ -315,11 +323,11 @@ async def test_migration_from_v1_disabled( assert subentry.data == {CONF_STATION_NUMBER: int(subentry.unique_id)} assert "de Jongweg" in subentry.title - assert not device_registry.async_get_device( - identifiers={(DOMAIN, mock_config_entry.entry_id)} + assert not device_registry.async_get_device_by_identifier( + (DOMAIN, mock_config_entry.entry_id), mock_config_entry.entry_id ) - assert not device_registry.async_get_device( - identifiers={(DOMAIN, mock_config_entry_2.entry_id)} + assert not device_registry.async_get_device_by_identifier( + (DOMAIN, mock_config_entry_2.entry_id), mock_config_entry_2.entry_id ) for idx, subentry in enumerate(station_subentries): @@ -331,8 +339,9 @@ async def test_migration_from_v1_disabled( assert entity.disabled_by is subentry_data["entity_disabled_by"] assert ( - device := device_registry.async_get_device( - identifiers={(DOMAIN, subentry.unique_id)} + device := device_registry.async_get_device_by_identifier( + (DOMAIN, subentry.unique_id), + mock_config_entries[main_config_entry].entry_id, ) ) assert device.identifiers == {(DOMAIN, subentry.unique_id)} diff --git a/tests/components/watts/test_init.py b/tests/components/watts/test_init.py index 2044e5cedd23c..41fa0aa1cdb02 100644 --- a/tests/components/watts/test_init.py +++ b/tests/components/watts/test_init.py @@ -203,10 +203,16 @@ async def test_dynamic_device_creation( """Test new devices are created dynamically.""" await setup_integration(hass, mock_config_entry) - assert device_registry.async_get_device(identifiers={(DOMAIN, "thermostat_123")}) - assert device_registry.async_get_device(identifiers={(DOMAIN, "thermostat_456")}) + assert device_registry.async_get_device_by_identifier( + (DOMAIN, "thermostat_123"), mock_config_entry.entry_id + ) + assert device_registry.async_get_device_by_identifier( + (DOMAIN, "thermostat_456"), mock_config_entry.entry_id + ) assert ( - device_registry.async_get_device(identifiers={(DOMAIN, "thermostat_789")}) + device_registry.async_get_device_by_identifier( + (DOMAIN, "thermostat_789"), mock_config_entry.entry_id + ) is None ) @@ -234,8 +240,8 @@ async def test_dynamic_device_creation( async_fire_time_changed(hass) await hass.async_block_till_done() - new_device_entry = device_registry.async_get_device( - identifiers={(DOMAIN, "thermostat_789")} + new_device_entry = device_registry.async_get_device_by_identifier( + (DOMAIN, "thermostat_789"), mock_config_entry.entry_id ) assert new_device_entry is not None assert new_device_entry.name == "Kitchen Thermostat" @@ -254,11 +260,11 @@ async def test_stale_device_removal( """Test stale devices are removed dynamically.""" await setup_integration(hass, mock_config_entry) - device_123 = device_registry.async_get_device( - identifiers={(DOMAIN, "thermostat_123")} + device_123 = device_registry.async_get_device_by_identifier( + (DOMAIN, "thermostat_123"), mock_config_entry.entry_id ) - device_456 = device_registry.async_get_device( - identifiers={(DOMAIN, "thermostat_456")} + device_456 = device_registry.async_get_device_by_identifier( + (DOMAIN, "thermostat_456"), mock_config_entry.entry_id ) assert device_123 is not None assert device_456 is not None @@ -275,8 +281,8 @@ async def test_stale_device_removal( await hass.async_block_till_done() # Verify thermostat_456 has been removed - device_456_after_removal = device_registry.async_get_device( - identifiers={(DOMAIN, "thermostat_456")} + device_456_after_removal = device_registry.async_get_device_by_identifier( + (DOMAIN, "thermostat_456"), mock_config_entry.entry_id ) assert device_456_after_removal is None diff --git a/tests/components/webostv/test_device_trigger.py b/tests/components/webostv/test_device_trigger.py index 75ba4b0d47883..4c96c77b2be64 100644 --- a/tests/components/webostv/test_device_trigger.py +++ b/tests/components/webostv/test_device_trigger.py @@ -24,9 +24,11 @@ async def test_get_triggers( hass: HomeAssistant, device_registry: dr.DeviceRegistry, client ) -> None: """Test we get the expected triggers.""" - await setup_webostv(hass) + entry = await setup_webostv(hass) - device = device_registry.async_get_device(identifiers={(DOMAIN, FAKE_UUID)}) + device = device_registry.async_get_device_by_identifier( + (DOMAIN, FAKE_UUID), entry.entry_id + ) turn_on_trigger = { "platform": "device", @@ -49,9 +51,11 @@ async def test_if_fires_on_turn_on_request( client, ) -> None: """Test for turn_on and turn_off triggers firing.""" - await setup_webostv(hass) + entry = await setup_webostv(hass) - device = device_registry.async_get_device(identifiers={(DOMAIN, FAKE_UUID)}) + device = device_registry.async_get_device_by_identifier( + (DOMAIN, FAKE_UUID), entry.entry_id + ) assert await async_setup_component( hass, diff --git a/tests/components/webostv/test_media_player.py b/tests/components/webostv/test_media_player.py index 9217b7e6f00b9..5e541e5b3205b 100644 --- a/tests/components/webostv/test_media_player.py +++ b/tests/components/webostv/test_media_player.py @@ -324,7 +324,9 @@ async def test_device_info_startup_off( assert hass.states.get(ENTITY_ID).state == STATE_OFF - device = device_registry.async_get_device(identifiers={(DOMAIN, entry.unique_id)}) + device = device_registry.async_get_device_by_identifier( + (DOMAIN, entry.unique_id), entry.entry_id + ) assert device assert device.identifiers == {(DOMAIN, entry.unique_id)} @@ -363,7 +365,9 @@ async def test_entity_attributes( assert attrs[ATTR_MEDIA_TITLE] == "Channel Name 2" # Device Info - device = device_registry.async_get_device(identifiers={(DOMAIN, entry.unique_id)}) + device = device_registry.async_get_device_by_identifier( + (DOMAIN, entry.unique_id), entry.entry_id + ) assert device == snapshot # Sound output when off diff --git a/tests/components/webostv/test_trigger.py b/tests/components/webostv/test_trigger.py index 646b8f8034aec..b3d759e7ee41d 100644 --- a/tests/components/webostv/test_trigger.py +++ b/tests/components/webostv/test_trigger.py @@ -25,9 +25,11 @@ async def test_webostv_turn_on_trigger_device_id( client, ) -> None: """Test for turn_on triggers by device_id firing.""" - await setup_webostv(hass) + entry = await setup_webostv(hass) - device = device_registry.async_get_device(identifiers={(DOMAIN, FAKE_UUID)}) + device = device_registry.async_get_device_by_identifier( + (DOMAIN, FAKE_UUID), entry.entry_id + ) assert await async_setup_component( hass, diff --git a/tests/components/wiim/test_entity.py b/tests/components/wiim/test_entity.py index f7bf17d085dcb..79110c607232c 100644 --- a/tests/components/wiim/test_entity.py +++ b/tests/components/wiim/test_entity.py @@ -25,8 +25,8 @@ async def test_device_info_uses_http_api_url( await setup_integration(hass, mock_config_entry) - device_entry = device_registry.async_get_device( - identifiers={(DOMAIN, mock_wiim_device.udn)} + device_entry = device_registry.async_get_device_by_identifier( + (DOMAIN, mock_wiim_device.udn), mock_config_entry.entry_id ) assert device_entry is not None assert device_entry.configuration_url == mock_wiim_device.http_api_url diff --git a/tests/components/withings/test_init.py b/tests/components/withings/test_init.py index 63c50983ae9b1..1a69cc74786d3 100644 --- a/tests/components/withings/test_init.py +++ b/tests/components/withings/test_init.py @@ -710,7 +710,9 @@ async def test_devices( await hass.async_block_till_done() for device_id in ("12345", "f998be4b9ccc9e136fd8cd8e8e344c31ec3b271d"): - device = device_registry.async_get_device({(DOMAIN, device_id)}) + device = device_registry.async_get_device_by_identifier( + (DOMAIN, device_id), webhook_config_entry.entry_id + ) assert device is not None assert device == snapshot(name=device_id) diff --git a/tests/components/withings/test_sensor.py b/tests/components/withings/test_sensor.py index 0a44756f8f4a9..718ca42b4ca6a 100644 --- a/tests/components/withings/test_sensor.py +++ b/tests/components/withings/test_sensor.py @@ -397,8 +397,9 @@ async def test_device_sensors_created_when_device_data_received( await hass.async_block_till_done() assert hass.states.get("sensor.body_battery") - assert device_registry.async_get_device( - {(DOMAIN, "f998be4b9ccc9e136fd8cd8e8e344c31ec3b271d")} + assert device_registry.async_get_device_by_identifier( + (DOMAIN, "f998be4b9ccc9e136fd8cd8e8e344c31ec3b271d"), + polling_config_entry.entry_id, ) withings.get_devices.return_value = [] @@ -408,8 +409,9 @@ async def test_device_sensors_created_when_device_data_received( await hass.async_block_till_done() assert hass.states.get("sensor.body_battery") is None - assert not device_registry.async_get_device( - {(DOMAIN, "f998be4b9ccc9e136fd8cd8e8e344c31ec3b271d")} + assert not device_registry.async_get_device_by_identifier( + (DOMAIN, "f998be4b9ccc9e136fd8cd8e8e344c31ec3b271d"), + polling_config_entry.entry_id, ) diff --git a/tests/components/wmspro/test_cover.py b/tests/components/wmspro/test_cover.py index c47c6eef7c325..22bc1f045dccc 100644 --- a/tests/components/wmspro/test_cover.py +++ b/tests/components/wmspro/test_cover.py @@ -56,7 +56,9 @@ async def test_cover_device( assert len(mock_hub_configuration.mock_calls) == 1 assert len(mock_hub_status.mock_calls) == len(mock_hub_configuration.destinations) - device_entry = device_registry.async_get_device(identifiers={(DOMAIN, "58717")}) + device_entry = device_registry.async_get_device_by_identifier( + (DOMAIN, "58717"), mock_config_entry.entry_id + ) assert device_entry is not None assert device_entry == snapshot diff --git a/tests/components/wmspro/test_light.py b/tests/components/wmspro/test_light.py index cc91385e96649..aaf8ea1f05495 100644 --- a/tests/components/wmspro/test_light.py +++ b/tests/components/wmspro/test_light.py @@ -44,7 +44,9 @@ async def test_light_device( assert len(mock_hub_configuration.mock_calls) == 1 assert len(mock_hub_status.mock_calls) == len(mock_hub_configuration.destinations) - device_entry = device_registry.async_get_device(identifiers={(DOMAIN, "97358")}) + device_entry = device_registry.async_get_device_by_identifier( + (DOMAIN, "97358"), mock_config_entry.entry_id + ) assert device_entry is not None assert device_entry == snapshot diff --git a/tests/components/wmspro/test_scene.py b/tests/components/wmspro/test_scene.py index 7a65e39f19463..a28ea911c4995 100644 --- a/tests/components/wmspro/test_scene.py +++ b/tests/components/wmspro/test_scene.py @@ -36,7 +36,9 @@ async def test_scene_room_device( assert len(mock_hub_configuration.mock_calls) == 1 assert len(mock_dest_refresh.mock_calls) == 2 - device_entry = device_registry.async_get_device(identifiers={(DOMAIN, "42581")}) + device_entry = device_registry.async_get_device_by_identifier( + (DOMAIN, "42581"), mock_config_entry.entry_id + ) assert device_entry is not None assert device_entry == snapshot diff --git a/tests/components/wmspro/test_switch.py b/tests/components/wmspro/test_switch.py index 818c74818910f..af4d7b5748cf6 100644 --- a/tests/components/wmspro/test_switch.py +++ b/tests/components/wmspro/test_switch.py @@ -44,7 +44,9 @@ async def test_switch_device( assert len(mock_hub_configuration.mock_calls) == 1 assert len(mock_hub_status.mock_calls) == len(mock_hub_configuration.destinations) - device_entry = device_registry.async_get_device(identifiers={(DOMAIN, "499120")}) + device_entry = device_registry.async_get_device_by_identifier( + (DOMAIN, "499120"), mock_config_entry.entry_id + ) assert device_entry is not None assert device_entry == snapshot diff --git a/tests/components/wolflink/test_init.py b/tests/components/wolflink/test_init.py index b8632bc5c33e5..a01af2871b305 100644 --- a/tests/components/wolflink/test_init.py +++ b/tests/components/wolflink/test_init.py @@ -393,8 +393,12 @@ async def test_setup_multiple_devices( await setup_integration(hass, mock_config_entry) # Both devices must appear in the device registry. - first = device_registry.async_get_device({(DOMAIN, "1234")}) - second = device_registry.async_get_device({(DOMAIN, "9999")}) + first = device_registry.async_get_device_by_identifier( + (DOMAIN, "1234"), mock_config_entry.entry_id + ) + second = device_registry.async_get_device_by_identifier( + (DOMAIN, "9999"), mock_config_entry.entry_id + ) assert first is not None assert second is not None assert first.name == "first-device" diff --git a/tests/components/wolflink/test_sensor.py b/tests/components/wolflink/test_sensor.py index 06c50fc3c5980..5459f87178b81 100644 --- a/tests/components/wolflink/test_sensor.py +++ b/tests/components/wolflink/test_sensor.py @@ -24,7 +24,9 @@ async def test_device_entry( await hass.config_entries.async_setup(mock_config_entry.entry_id) await hass.async_block_till_done() - device = device_registry.async_get_device({(mock_config_entry.domain, "1234")}) + device = device_registry.async_get_device_by_identifier( + (mock_config_entry.domain, "1234"), mock_config_entry.entry_id + ) assert device == snapshot diff --git a/tests/components/wyoming/test_devices.py b/tests/components/wyoming/test_devices.py index d7cba133c2cb3..24c6480a12310 100644 --- a/tests/components/wyoming/test_devices.py +++ b/tests/components/wyoming/test_devices.py @@ -20,8 +20,8 @@ async def test_device_registry_info( # Satellite uses config entry id since only one satellite per entry is # supported. - device = device_registry.async_get_device( - identifiers={(DOMAIN, satellite_config_entry.entry_id)} + device = device_registry.async_get_device_by_identifier( + (DOMAIN, satellite_config_entry.entry_id), satellite_config_entry.entry_id ) assert device is not None assert device.name == "Test Satellite" diff --git a/tests/components/xbox/test_init.py b/tests/components/xbox/test_init.py index e0cee16cb8dc8..469a96b6f2b6f 100644 --- a/tests/components/xbox/test_init.py +++ b/tests/components/xbox/test_init.py @@ -219,8 +219,18 @@ async def test_dynamic_devices( assert config_entry.state is ConfigEntryState.LOADED - assert device_registry.async_get_device({(DOMAIN, "ABCDEFG")}) is None - assert device_registry.async_get_device({(DOMAIN, "HIJKLMN")}) is None + assert ( + device_registry.async_get_device_by_identifier( + (DOMAIN, "ABCDEFG"), config_entry.entry_id + ) + is None + ) + assert ( + device_registry.async_get_device_by_identifier( + (DOMAIN, "HIJKLMN"), config_entry.entry_id + ) + is None + ) xbox_live_client.smartglass.get_console_list.return_value = SmartglassConsoleList( **await async_load_json_object_fixture( @@ -232,8 +242,12 @@ async def test_dynamic_devices( async_fire_time_changed(hass) await hass.async_block_till_done() - assert device_registry.async_get_device({(DOMAIN, "ABCDEFG")}) - assert device_registry.async_get_device({(DOMAIN, "HIJKLMN")}) + assert device_registry.async_get_device_by_identifier( + (DOMAIN, "ABCDEFG"), config_entry.entry_id + ) + assert device_registry.async_get_device_by_identifier( + (DOMAIN, "HIJKLMN"), config_entry.entry_id + ) xbox_live_client.smartglass.get_console_list.return_value = SmartglassConsoleList( **await async_load_json_object_fixture( @@ -245,5 +259,15 @@ async def test_dynamic_devices( async_fire_time_changed(hass) await hass.async_block_till_done() - assert device_registry.async_get_device({(DOMAIN, "ABCDEFG")}) is None - assert device_registry.async_get_device({(DOMAIN, "HIJKLMN")}) is None + assert ( + device_registry.async_get_device_by_identifier( + (DOMAIN, "ABCDEFG"), config_entry.entry_id + ) + is None + ) + assert ( + device_registry.async_get_device_by_identifier( + (DOMAIN, "HIJKLMN"), config_entry.entry_id + ) + is None + ) diff --git a/tests/components/xiaomi_ble/test_device_trigger.py b/tests/components/xiaomi_ble/test_device_trigger.py index 2c0751bf56c6b..19d45bac02a79 100644 --- a/tests/components/xiaomi_ble/test_device_trigger.py +++ b/tests/components/xiaomi_ble/test_device_trigger.py @@ -190,7 +190,9 @@ async def test_get_triggers_button( await hass.async_block_till_done() assert len(events) == 1 - device = device_registry.async_get_device(identifiers={get_device_id(mac)}) + device = device_registry.async_get_device_by_identifier( + get_device_id(mac), entry.entry_id + ) assert device expected_trigger = { CONF_PLATFORM: "device", @@ -231,7 +233,9 @@ async def test_get_triggers_double_button( await hass.async_block_till_done() assert len(events) == 1 - device = device_registry.async_get_device(identifiers={get_device_id(mac)}) + device = device_registry.async_get_device_by_identifier( + get_device_id(mac), entry.entry_id + ) assert device expected_trigger = { CONF_PLATFORM: "device", @@ -273,7 +277,9 @@ async def test_get_triggers_lock( await hass.async_block_till_done() assert len(events) == 1 - device = device_registry.async_get_device(identifiers={get_device_id(mac)}) + device = device_registry.async_get_device_by_identifier( + get_device_id(mac), entry.entry_id + ) assert device expected_trigger = { CONF_PLATFORM: "device", @@ -310,7 +316,9 @@ async def test_get_triggers_motion( await hass.async_block_till_done() assert len(events) == 1 - device = device_registry.async_get_device(identifiers={get_device_id(mac)}) + device = device_registry.async_get_device_by_identifier( + get_device_id(mac), entry.entry_id + ) assert device expected_trigger = { CONF_PLATFORM: "device", @@ -413,7 +421,9 @@ async def test_if_fires_on_button_press( # wait for the device being created await hass.async_block_till_done() - device = device_registry.async_get_device(identifiers={get_device_id(mac)}) + device = device_registry.async_get_device_by_identifier( + get_device_id(mac), entry.entry_id + ) device_id = device.id assert await async_setup_component( @@ -476,7 +486,9 @@ async def test_if_fires_on_double_button_long_press( # wait for the device being created await hass.async_block_till_done() - device = device_registry.async_get_device(identifiers={get_device_id(mac)}) + device = device_registry.async_get_device_by_identifier( + get_device_id(mac), entry.entry_id + ) device_id = device.id assert await async_setup_component( @@ -535,7 +547,9 @@ async def test_if_fires_on_motion_detected( # wait for the device being created await hass.async_block_till_done() - device = device_registry.async_get_device(identifiers={get_device_id(mac)}) + device = device_registry.async_get_device_by_identifier( + get_device_id(mac), entry.entry_id + ) device_id = device.id assert await async_setup_component( @@ -591,7 +605,9 @@ async def test_automation_with_invalid_trigger_type( # wait for the event await hass.async_block_till_done() - device = device_registry.async_get_device(identifiers={get_device_id(mac)}) + device = device_registry.async_get_device_by_identifier( + get_device_id(mac), entry.entry_id + ) device_id = device.id assert await async_setup_component( @@ -640,7 +656,9 @@ async def test_automation_with_invalid_trigger_event_property( # wait for the event await hass.async_block_till_done() - device = device_registry.async_get_device(identifiers={get_device_id(mac)}) + device = device_registry.async_get_device_by_identifier( + get_device_id(mac), entry.entry_id + ) device_id = device.id assert await async_setup_component( diff --git a/tests/components/xthings_cloud/test_init.py b/tests/components/xthings_cloud/test_init.py index 9210a062c0859..f7dfbe22adf2d 100644 --- a/tests/components/xthings_cloud/test_init.py +++ b/tests/components/xthings_cloud/test_init.py @@ -24,7 +24,9 @@ async def test_devices( await setup_integration(hass, mock_config_entry) for device in mock_api_client.async_get_devices.return_value: - device_entry = device_registry.async_get_device({(DOMAIN, device["id"])}) + device_entry = device_registry.async_get_device_by_identifier( + (DOMAIN, device["id"]), mock_config_entry.entry_id + ) assert device_entry is not None assert device_entry == snapshot(name=device["model"]) diff --git a/tests/components/yale/test_binary_sensor.py b/tests/components/yale/test_binary_sensor.py index 61416f44cac3e..4bf76dd06ef50 100644 --- a/tests/components/yale/test_binary_sensor.py +++ b/tests/components/yale/test_binary_sensor.py @@ -309,9 +309,11 @@ async def test_doorbell_device_registry( ) -> None: """Test creation of a lock with doorsense and bridge ands up in the registry.""" doorbell_one = await _mock_doorbell_from_fixture(hass, "get_doorbell.offline.json") - await _create_yale_with_devices(hass, [doorbell_one]) + config_entry, _ = await _create_yale_with_devices(hass, [doorbell_one]) - reg_device = device_registry.async_get_device(identifiers={("yale", "tmt100")}) + reg_device = device_registry.async_get_device_by_identifier( + ("yale", "tmt100"), config_entry.entry_id + ) assert reg_device == snapshot diff --git a/tests/components/yale/test_lock.py b/tests/components/yale/test_lock.py index ad5c5cd66732d..684fae8588365 100644 --- a/tests/components/yale/test_lock.py +++ b/tests/components/yale/test_lock.py @@ -40,10 +40,10 @@ async def test_lock_device_registry( ) -> None: """Test creation of a lock with doorsense and bridge ands up in the registry.""" lock_one = await _mock_doorsense_enabled_yale_lock_detail(hass) - await _create_yale_with_devices(hass, [lock_one]) + entry, _ = await _create_yale_with_devices(hass, [lock_one]) - reg_device = device_registry.async_get_device( - identifiers={("yale", "online_with_doorsense")} + reg_device = device_registry.async_get_device_by_identifier( + ("yale", "online_with_doorsense"), entry.entry_id ) assert reg_device == snapshot diff --git a/tests/components/yolink/test_device_trigger.py b/tests/components/yolink/test_device_trigger.py index c82c507940c81..2c526dd28c912 100644 --- a/tests/components/yolink/test_device_trigger.py +++ b/tests/components/yolink/test_device_trigger.py @@ -150,7 +150,9 @@ async def test_if_fires_on_event( }, ) - device = device_registry.async_get_device(connections={connection}) + device = device_registry.async_get_device_by_connection( + connection, config_entry.entry_id + ) assert device is not None # Fake remote button long press. hass.bus.async_fire( diff --git a/tests/components/yoto/test_init.py b/tests/components/yoto/test_init.py index 8fc92e4b7c4fc..3f5ca9ba284e8 100644 --- a/tests/components/yoto/test_init.py +++ b/tests/components/yoto/test_init.py @@ -397,7 +397,10 @@ async def test_stale_device_removed( """A player removed from the account has its device dropped.""" await setup_integration(hass, mock_config_entry) assert ( - device_registry.async_get_device(identifiers={(DOMAIN, PLAYER_ID)}) is not None + device_registry.async_get_device_by_identifier( + (DOMAIN, PLAYER_ID), mock_config_entry.entry_id + ) + is not None ) mock_yoto_client.players.clear() @@ -405,5 +408,10 @@ async def test_stale_device_removed( async_fire_time_changed(hass) await hass.async_block_till_done() - assert device_registry.async_get_device(identifiers={(DOMAIN, PLAYER_ID)}) is None + assert ( + device_registry.async_get_device_by_identifier( + (DOMAIN, PLAYER_ID), mock_config_entry.entry_id + ) + is None + ) mock_yoto_client.unsubscribe_player_events.assert_called_once_with(PLAYER_ID) diff --git a/tests/components/youtube/test_init.py b/tests/components/youtube/test_init.py index a7d2639902c52..bbcb86fc424ef 100644 --- a/tests/components/youtube/test_init.py +++ b/tests/components/youtube/test_init.py @@ -130,8 +130,8 @@ async def test_device_info( entry = hass.config_entries.async_entries(DOMAIN)[0] channel_id = entry.options[CONF_CHANNELS][0] - device = device_registry.async_get_device( - identifiers={(DOMAIN, f"{entry.entry_id}_{channel_id}")} + device = device_registry.async_get_device_by_identifier( + (DOMAIN, f"{entry.entry_id}_{channel_id}"), entry.entry_id ) assert device.entry_type is dr.DeviceEntryType.SERVICE diff --git a/tests/components/zeversolar/test_diagnostics.py b/tests/components/zeversolar/test_diagnostics.py index 384a8f7a42dc2..6b12fe709dcc1 100644 --- a/tests/components/zeversolar/test_diagnostics.py +++ b/tests/components/zeversolar/test_diagnostics.py @@ -37,8 +37,8 @@ async def test_device_diagnostics( init_integration: MockConfigEntry, ) -> None: """Test device diagnostics.""" - device = device_registry.async_get_device( - identifiers={(DOMAIN, MOCK_SERIAL_NUMBER)} + device = device_registry.async_get_device_by_identifier( + (DOMAIN, MOCK_SERIAL_NUMBER), init_integration.entry_id ) assert ( diff --git a/tests/components/zha/test_device_action.py b/tests/components/zha/test_device_action.py index 05211ce4ceee7..3309292f42802 100644 --- a/tests/components/zha/test_device_action.py +++ b/tests/components/zha/test_device_action.py @@ -21,7 +21,11 @@ from .conftest import SIG_EP_INPUT, SIG_EP_OUTPUT, SIG_EP_PROFILE, SIG_EP_TYPE -from tests.common import async_get_device_automations, async_mock_service +from tests.common import ( + MockConfigEntry, + async_get_device_automations, + async_mock_service, +) SHORT_PRESS = "remote_button_short_press" COMMAND = "command" @@ -52,6 +56,7 @@ async def test_get_actions( hass: HomeAssistant, device_registry: dr.DeviceRegistry, entity_registry: er.EntityRegistry, + config_entry: MockConfigEntry, setup_zha: Callable[..., Coroutine[None]], zigpy_device_mock: Callable[..., Device], ) -> None: @@ -80,7 +85,9 @@ async def test_get_actions( await hass.async_block_till_done(wait_background_tasks=True) ieee_address = str(zigpy_device.ieee) - reg_device = device_registry.async_get_device(identifiers={(DOMAIN, ieee_address)}) + reg_device = device_registry.async_get_device_by_identifier( + (DOMAIN, ieee_address), config_entry.entry_id + ) siren_level_select = entity_registry.async_get( "select.fakemanufacturer_fakemodel_default_siren_level" ) @@ -138,6 +145,7 @@ async def test_get_actions( async def test_action( hass: HomeAssistant, device_registry: dr.DeviceRegistry, + config_entry: MockConfigEntry, setup_zha: Callable[..., Coroutine[None]], zigpy_device_mock: Callable[..., Device], ) -> None: @@ -168,7 +176,9 @@ async def test_action( await hass.async_block_till_done(wait_background_tasks=True) ieee_address = str(zigpy_device.ieee) - reg_device = device_registry.async_get_device(identifiers={(DOMAIN, ieee_address)}) + reg_device = device_registry.async_get_device_by_identifier( + (DOMAIN, ieee_address), config_entry.entry_id + ) with patch( "zigpy.zcl.Cluster.request", diff --git a/tests/components/zha/test_device_trigger.py b/tests/components/zha/test_device_trigger.py index 6afe6d063931c..36934ff5d6567 100644 --- a/tests/components/zha/test_device_trigger.py +++ b/tests/components/zha/test_device_trigger.py @@ -79,8 +79,9 @@ async def test_triggers( await gateway.async_device_initialized(zha_device.device) await hass.async_block_till_done(wait_background_tasks=True) - reg_device = device_registry.async_get_device( - identifiers={("zha", str(zha_device.ieee))} + reg_device = device_registry.async_get_device_by_identifier( + ("zha", str(zha_device.ieee)), + hass.config_entries.async_entries("zha")[0].entry_id, ) triggers = await async_get_device_automations( @@ -160,8 +161,9 @@ async def test_no_triggers( await gateway.async_device_initialized(zha_device.device) await hass.async_block_till_done(wait_background_tasks=True) - reg_device = device_registry.async_get_device( - identifiers={("zha", str(zha_device.ieee))} + reg_device = device_registry.async_get_device_by_identifier( + ("zha", str(zha_device.ieee)), + hass.config_entries.async_entries("zha")[0].entry_id, ) triggers = await async_get_device_automations( @@ -211,8 +213,9 @@ async def test_if_fires_on_event( await gateway.async_device_initialized(zha_device.device) await hass.async_block_till_done(wait_background_tasks=True) - reg_device = device_registry.async_get_device( - identifiers={("zha", str(zha_device.ieee))} + reg_device = device_registry.async_get_device_by_identifier( + ("zha", str(zha_device.ieee)), + hass.config_entries.async_entries("zha")[0].entry_id, ) assert await async_setup_component( @@ -276,8 +279,9 @@ async def test_device_offline_fires( await gateway.async_device_initialized(zha_device.device) await hass.async_block_till_done(wait_background_tasks=True) - reg_device = device_registry.async_get_device( - identifiers={("zha", str(zha_device.ieee))} + reg_device = device_registry.async_get_device_by_identifier( + ("zha", str(zha_device.ieee)), + hass.config_entries.async_entries("zha")[0].entry_id, ) assert await async_setup_component( @@ -332,8 +336,9 @@ async def test_exception_no_triggers( await gateway.async_device_initialized(zha_device.device) await hass.async_block_till_done(wait_background_tasks=True) - reg_device = device_registry.async_get_device( - identifiers={("zha", str(zha_device.ieee))} + reg_device = device_registry.async_get_device_by_identifier( + ("zha", str(zha_device.ieee)), + hass.config_entries.async_entries("zha")[0].entry_id, ) await async_setup_component( @@ -392,8 +397,9 @@ async def test_exception_bad_trigger( await gateway.async_device_initialized(zha_device.device) await hass.async_block_till_done(wait_background_tasks=True) - reg_device = device_registry.async_get_device( - identifiers={("zha", str(zha_device.ieee))} + reg_device = device_registry.async_get_device_by_identifier( + ("zha", str(zha_device.ieee)), + hass.config_entries.async_entries("zha")[0].entry_id, ) await async_setup_component( @@ -457,8 +463,8 @@ async def test_validate_trigger_config_missing_info( # it be pulled from the current device, making it impossible to validate triggers await hass.config_entries.async_unload(config_entry.entry_id) - reg_device = device_registry.async_get_device( - identifiers={("zha", str(zha_device.ieee))} + reg_device = device_registry.async_get_device_by_identifier( + ("zha", str(zha_device.ieee)), config_entry.entry_id ) assert await async_setup_component( @@ -532,8 +538,8 @@ async def test_validate_trigger_config_unloaded_bad_info( await hass.config_entries.async_unload(config_entry.entry_id) - reg_device = device_registry.async_get_device( - identifiers={("zha", str(zha_device.ieee))} + reg_device = device_registry.async_get_device_by_identifier( + ("zha", str(zha_device.ieee)), config_entry.entry_id ) assert await async_setup_component( diff --git a/tests/components/zha/test_diagnostics.py b/tests/components/zha/test_diagnostics.py index 55828532384e3..72bdaec483676 100644 --- a/tests/components/zha/test_diagnostics.py +++ b/tests/components/zha/test_diagnostics.py @@ -129,8 +129,8 @@ async def test_diagnostics_for_device( security.IasZone.AttributeDefs.current_zone_sensitivity_level ) - device = device_registry.async_get_device( - identifiers={("zha", str(zha_device_proxy.device.ieee))} + device = device_registry.async_get_device_by_identifier( + ("zha", str(zha_device_proxy.device.ieee)), config_entry.entry_id ) assert device diagnostics_data = await get_diagnostics_for_device( diff --git a/tests/components/zha/test_logbook.py b/tests/components/zha/test_logbook.py index 4a4fc5caf545d..a1d8953f3c27b 100644 --- a/tests/components/zha/test_logbook.py +++ b/tests/components/zha/test_logbook.py @@ -98,7 +98,9 @@ async def test_zha_logbook_event_device_with_triggers( ieee_address = str(zha_device.device.ieee) - reg_device = device_registry.async_get_device(identifiers={("zha", ieee_address)}) + reg_device = device_registry.async_get_device_by_identifier( + ("zha", ieee_address), hass.config_entries.async_entries("zha")[0].entry_id + ) hass.config.components.add("recorder") assert await async_setup_component(hass, "logbook", {}) @@ -174,7 +176,9 @@ async def test_zha_logbook_event_device_no_triggers( _zigpy_device, zha_device = mock_devices ieee_address = str(zha_device.device.ieee) - reg_device = device_registry.async_get_device(identifiers={("zha", ieee_address)}) + reg_device = device_registry.async_get_device_by_identifier( + ("zha", ieee_address), hass.config_entries.async_entries("zha")[0].entry_id + ) hass.config.components.add("recorder") assert await async_setup_component(hass, "logbook", {}) diff --git a/tests/components/zha/test_update.py b/tests/components/zha/test_update.py index f5e30e84072d9..d55bd8bd7f9d9 100644 --- a/tests/components/zha/test_update.py +++ b/tests/components/zha/test_update.py @@ -715,13 +715,15 @@ async def test_update_version_sync_device_registry( zha_device, _, _, _ = await setup_test_data(hass, zigpy_device_mock) zha_device.device.async_update_firmware_version("0x12345678") - reg_device = device_registry.async_get_device( - identifiers={("zha", str(zha_device.device.ieee))} + reg_device = device_registry.async_get_device_by_identifier( + ("zha", str(zha_device.device.ieee)), + hass.config_entries.async_entries("zha")[0].entry_id, ) assert reg_device.sw_version == "0x12345678" zha_device.device.async_update_firmware_version("0xabcd1234") - reg_device = device_registry.async_get_device( - identifiers={("zha", str(zha_device.device.ieee))} + reg_device = device_registry.async_get_device_by_identifier( + ("zha", str(zha_device.device.ieee)), + hass.config_entries.async_entries("zha")[0].entry_id, ) assert reg_device.sw_version == "0xabcd1234" diff --git a/tests/components/zwave_js/test_api.py b/tests/components/zwave_js/test_api.py index d073c37fc6de9..d85ba7ab0b007 100644 --- a/tests/components/zwave_js/test_api.py +++ b/tests/components/zwave_js/test_api.py @@ -116,7 +116,9 @@ def get_device(hass: HomeAssistant, node): """Get device ID for a node.""" dev_reg = dr.async_get(hass) device_id = get_device_id(node.client.driver, node) - return dev_reg.async_get_device(identifiers={device_id}) + return dev_reg.async_get_device_by_identifier( + device_id, hass.config_entries.async_entries(DOMAIN)[0].entry_id + ) async def test_no_driver( @@ -180,8 +182,8 @@ async def test_network_status( assert result["controller"]["supports_long_range"] # Try API call with device ID - device = device_registry.async_get_device( - identifiers={(DOMAIN, "3245146787-52")}, + device = device_registry.async_get_device_by_identifier( + (DOMAIN, "3245146787-52"), entry.entry_id ) assert device with patch( @@ -491,7 +493,9 @@ async def test_node_alerts( entry = integration ws_client = await hass_ws_client(hass) - device = device_registry.async_get_device(identifiers={(DOMAIN, "3245146787-35")}) + device = device_registry.async_get_device_by_identifier( + (DOMAIN, "3245146787-35"), entry.entry_id + ) assert device await ws_client.send_json_auto_id( @@ -1284,8 +1288,8 @@ async def test_provision_smart_start_node( assert msg["success"] # verify a device was created - device = device_registry.async_get_device( - identifiers={(DOMAIN, "provision_test")}, + device = device_registry.async_get_device_by_identifier( + (DOMAIN, "provision_test"), entry.entry_id ) assert device is not None assert device.name == "test_name" @@ -1945,8 +1949,8 @@ async def test_remove_node( assert msg["event"]["event"] == "node removed" # Verify device was removed from device registry - device = device_registry.async_get_device( - identifiers={(DOMAIN, "3245146787-67")}, + device = device_registry.async_get_device_by_identifier( + (DOMAIN, "3245146787-67"), entry.entry_id ) assert device is None @@ -2133,8 +2137,8 @@ async def test_replace_failed_node( # Verify device was removed from device registry assert ( - device_registry.async_get_device( - identifiers={(DOMAIN, "3245146787-67")}, + device_registry.async_get_device_by_identifier( + (DOMAIN, "3245146787-67"), entry.entry_id ) is None ) @@ -2449,8 +2453,8 @@ async def test_remove_failed_node( # Verify device was removed from device registry assert ( - device_registry.async_get_device( - identifiers={(DOMAIN, "3245146787-67")}, + device_registry.async_get_device_by_identifier( + (DOMAIN, "3245146787-67"), entry.entry_id ) is None ) @@ -5290,8 +5294,8 @@ async def mock_driver_hard_reset() -> None: msg = await ws_client.receive_json() await hass.async_block_till_done() - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, client.driver.controller.nodes[1])} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, client.driver.controller.nodes[1]), entry.entry_id ) assert device is not None assert msg["result"] == device.id @@ -5315,8 +5319,8 @@ async def mock_driver_hard_reset() -> None: msg = await ws_client.receive_json() await hass.async_block_till_done() - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, client.driver.controller.nodes[1])} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, client.driver.controller.nodes[1]), entry.entry_id ) assert device is not None assert msg["result"] == device.id @@ -5350,8 +5354,8 @@ async def mock_driver_hard_reset_no_driver_ready() -> None: msg = await ws_client.receive_json() await hass.async_block_till_done() - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, client.driver.controller.nodes[1])} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, client.driver.controller.nodes[1]), entry.entry_id ) assert device is not None assert msg["result"] == device.id diff --git a/tests/components/zwave_js/test_config_flow.py b/tests/components/zwave_js/test_config_flow.py index c5ec67b69af2f..a6478cb7ef16f 100644 --- a/tests/components/zwave_js/test_config_flow.py +++ b/tests/components/zwave_js/test_config_flow.py @@ -4271,19 +4271,21 @@ async def test_reconfigure_migrate_with_addon( assert len(device_registry.devices) == 2 # Verify there's a device entry for the controller. - device = device_registry.async_get_device( - identifiers={(DOMAIN, controller_device_id)} + device = device_registry.async_get_device_by_identifier( + (DOMAIN, controller_device_id), entry.entry_id ) assert device - assert device == device_registry.async_get_device( - identifiers={(DOMAIN, controller_device_id_ext)} + assert device == device_registry.async_get_device_by_identifier( + (DOMAIN, controller_device_id_ext), entry.entry_id ) assert device.manufacturer == "AEON Labs" assert device.model == "ZW090" assert device.name == "Z‐Stick Gen5 USB Controller" # Verify there's a device entry for the multisensor. sensor_device_id = f"{client.driver.controller.home_id}-{multisensor_6.node_id}" - device = device_registry.async_get_device(identifiers={(DOMAIN, sensor_device_id)}) + device = device_registry.async_get_device_by_identifier( + (DOMAIN, sensor_device_id), entry.entry_id + ) assert device assert device.manufacturer == "AEON Labs" assert device.model == "ZW100" @@ -4419,14 +4421,16 @@ async def mock_restore_nvm(data: bytes, options: dict[str, bool] | None = None): f"{controller_device_id}-{controller_node.manufacturer_id}:" f"{controller_node.product_type}:{controller_node.product_id}" ) - device = device_registry.async_get_device( - identifiers={(DOMAIN, controller_device_id_ext)} + device = device_registry.async_get_device_by_identifier( + (DOMAIN, controller_device_id_ext), entry.entry_id ) assert device assert device.manufacturer == "New Device Manufacturer" assert device.model == "New Device Model" assert device.name == "New Device Name" - device = device_registry.async_get_device(identifiers={(DOMAIN, sensor_device_id)}) + device = device_registry.async_get_device_by_identifier( + (DOMAIN, sensor_device_id), entry.entry_id + ) assert device assert device.manufacturer == "AEON Labs" assert device.model == "ZW100" diff --git a/tests/components/zwave_js/test_credential_services.py b/tests/components/zwave_js/test_credential_services.py index 1efc844085570..dd6e22f1492ad 100644 --- a/tests/components/zwave_js/test_credential_services.py +++ b/tests/components/zwave_js/test_credential_services.py @@ -88,11 +88,14 @@ def _mock_access_control( def _device_id( - device_registry: dr.DeviceRegistry, client: MagicMock, node: Node + device_registry: dr.DeviceRegistry, + client: MagicMock, + node: Node, + config_entry_id: str, ) -> str: """Resolve the HA device_id for a mocked Z-Wave node.""" - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, node)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, node), config_entry_id ) assert device is not None return device.id @@ -103,9 +106,10 @@ def _lock_entity_id( device_registry: dr.DeviceRegistry, client: MagicMock, node: Node, + config_entry_id: str, ) -> str: """Resolve the HA lock entity_id for a mocked Z-Wave node.""" - device_id = _device_id(device_registry, client, node) + device_id = _device_id(device_registry, client, node, config_entry_id) for entry in entity_registry.entities.values(): if entry.device_id == device_id and entry.entity_id.startswith("lock."): return entry.entity_id @@ -124,7 +128,11 @@ async def test_set_user_new_user_auto_find( api = _mock_access_control(lock_schlage_be469) api.add_user.return_value = AddUserResult(user=SetUserResult.OK) entity_id = _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ) result = await hass.services.async_call( @@ -166,7 +174,11 @@ async def test_set_user_existing_user( """With a user_id, set_user updates the existing user via setUser.""" api = _mock_access_control(lock_schlage_be469) entity_id = _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ) result = await hass.services.async_call( @@ -220,7 +232,11 @@ async def test_set_user_no_slots( "set_user", { ATTR_ENTITY_ID: _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ), "user_name": "Charlie", }, @@ -245,7 +261,11 @@ async def test_set_user_new_user_with_credential( """A new user and its credential are written in one addUser call.""" api = _mock_access_control(lock_schlage_be469) entity_id = _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ) result = await hass.services.async_call( @@ -305,7 +325,11 @@ async def test_set_user_rolls_back_on_credential_failure( "set_user", { ATTR_ENTITY_ID: _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ), "user_name": "Alice", "credential_type": "pin_code", @@ -343,7 +367,11 @@ async def test_set_user_rollback_failure_still_raises_credential_error( "set_user", { ATTR_ENTITY_ID: _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ), "user_name": "Alice", "credential_type": "pin_code", @@ -392,7 +420,11 @@ async def test_set_user_new_user_credential_slot_allocation( user2.user_id = 2 api.get_users_cached.return_value = [user1, user2] entity_id = _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ) result = await hass.services.async_call( @@ -454,7 +486,11 @@ async def test_set_user_existing_user_with_credential( supports_users_without_credentials=supports_users_without_credentials, ) entity_id = _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ) result = await hass.services.async_call( @@ -504,7 +540,11 @@ async def test_set_user_existing_user_explicit_credential_slot( """An explicit credential_slot is honored on the existing-user path.""" api = _mock_access_control(lock_schlage_be469) entity_id = _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ) result = await hass.services.async_call( @@ -554,7 +594,11 @@ async def test_set_user_invalid_pin( "set_user", { ATTR_ENTITY_ID: _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ), "credential_type": "pin_code", "credential_data": "abcd", @@ -586,7 +630,11 @@ async def test_set_user_requires_credential_on_user_code_cc( "set_user", { ATTR_ENTITY_ID: _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ), "user_name": "Alice", }, @@ -616,7 +664,11 @@ async def test_delete_user( "delete_user", { ATTR_ENTITY_ID: _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ), "user_id": 3, }, @@ -642,7 +694,11 @@ async def test_delete_all_users( "delete_all_users", { ATTR_ENTITY_ID: _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ), }, blocking=True, @@ -662,7 +718,11 @@ async def test_get_credential_capabilities( """Test get_credential_capabilities returns capability data.""" _mock_access_control(lock_schlage_be469) entity_id = _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ) result = await hass.services.async_call( @@ -716,7 +776,11 @@ async def test_get_credential_capabilities_not_supported( "get_credential_capabilities", { ATTR_ENTITY_ID: _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ) }, blocking=True, @@ -758,7 +822,11 @@ async def test_get_users( api.get_all_credentials_cached.return_value = [credential] entity_id = _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ) result = await hass.services.async_call( @@ -800,7 +868,11 @@ async def test_set_credential_auto_slot( api = _mock_access_control(lock_schlage_be469) entity_id = _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ) result = await hass.services.async_call( DOMAIN, @@ -833,7 +905,11 @@ async def test_set_credential_explicit_slot( """Test set_credential with explicit user_id and slot.""" api = _mock_access_control(lock_schlage_be469) entity_id = _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ) result = await hass.services.async_call( @@ -871,10 +947,14 @@ async def test_set_credential_multi_target( api2 = _mock_access_control(lock_august_pro) entity_1 = _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ) entity_2 = _lock_entity_id( - entity_registry, device_registry, client, lock_august_pro + entity_registry, device_registry, client, lock_august_pro, integration.entry_id ) result = await hass.services.async_call( DOMAIN, @@ -935,7 +1015,11 @@ async def test_set_user_rejection_raises( "set_user", { ATTR_ENTITY_ID: _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ), "user_id": 1, "user_name": "Guest", @@ -1008,7 +1092,11 @@ async def test_set_credential_rejection_raises( "set_credential", { ATTR_ENTITY_ID: _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ), "user_id": 1, "credential_type": "pin_code", @@ -1042,7 +1130,11 @@ async def test_set_credential_requires_user_id( "set_credential", { ATTR_ENTITY_ID: _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ), "credential_type": "pin_code", "credential_data": "1234", @@ -1076,7 +1168,11 @@ async def test_set_credential_type_not_supported( "set_credential", { ATTR_ENTITY_ID: _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ), "user_id": 1, "credential_type": "pin_code", @@ -1124,7 +1220,11 @@ async def test_set_credential_no_available_slots( "set_credential", { ATTR_ENTITY_ID: _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ), "user_id": 1, "credential_type": "pin_code", @@ -1167,7 +1267,11 @@ async def test_set_credential_pin_not_digits( "set_credential", { ATTR_ENTITY_ID: _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ), "user_id": 1, "credential_type": "pin_code", @@ -1195,7 +1299,11 @@ async def test_set_credential_password_allows_non_digits( """Password credentials must not be subject to the PIN-only digit check.""" api = _mock_access_control(lock_schlage_be469) entity_id = _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ) result = await hass.services.async_call( @@ -1237,7 +1345,11 @@ async def test_set_credential_length_validation( "set_credential", { ATTR_ENTITY_ID: _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ), "user_id": 1, "credential_type": "pin_code", @@ -1276,7 +1388,11 @@ async def test_delete_credential( "delete_credential", { ATTR_ENTITY_ID: _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ), "user_id": 1, "credential_type": "pin_code", @@ -1312,7 +1428,11 @@ async def test_delete_all_credentials( "delete_all_credentials", { ATTR_ENTITY_ID: _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ), "user_id": 1, }, @@ -1341,7 +1461,11 @@ async def test_set_credential_id_range_validation( payload: dict = { ATTR_ENTITY_ID: _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ), "user_id": 1, "credential_type": "pin_code", @@ -1380,7 +1504,11 @@ async def test_delete_user_rejects_oversize_user_id( "delete_user", { ATTR_ENTITY_ID: _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ), "user_id": 70000, }, @@ -1411,10 +1539,18 @@ async def test_mutation_supports_multi_target( { ATTR_ENTITY_ID: [ _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ), _lock_entity_id( - entity_registry, device_registry, client, lock_august_pro + entity_registry, + device_registry, + client, + lock_august_pro, + integration.entry_id, ), ], "user_id": 3, @@ -1456,10 +1592,14 @@ async def test_get_users_supports_multi_target( api2.get_users_cached.return_value = [user_2] entity_1 = _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ) entity_2 = _lock_entity_id( - entity_registry, device_registry, client, lock_august_pro + entity_registry, device_registry, client, lock_august_pro, integration.entry_id ) result = await hass.services.async_call( @@ -1592,7 +1732,11 @@ async def test_server_error_wrapped_with_translation_key( getattr(api, failing_attr).side_effect = FailedZWaveCommand("boom", 1, "boom") entity_id = _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ) with pytest.raises(HomeAssistantError) as exc: @@ -1636,7 +1780,11 @@ async def test_delete_all_credentials_failure_wrapped( "delete_all_credentials", { ATTR_ENTITY_ID: _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ), "user_id": 7, }, @@ -1684,7 +1832,11 @@ async def test_delete_all_credentials_partial_failure( "delete_all_credentials", { ATTR_ENTITY_ID: _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ), "user_id": 7, }, @@ -1729,7 +1881,11 @@ async def test_delete_all_credentials_single_failure_unwrapped( "delete_all_credentials", { ATTR_ENTITY_ID: _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ), "user_id": 7, }, @@ -1778,7 +1934,11 @@ async def test_service_access_control_not_supported( api = _mock_access_control(lock_schlage_be469) api.is_supported.return_value = False entity_id = _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ) with pytest.raises(HomeAssistantError) as exc: @@ -1836,7 +1996,11 @@ async def test_service_requires_admin( hass_read_only_user.mock_policy({"entities": {"all": {"control": True}}}) api = _mock_access_control(lock_schlage_be469) entity_id = _lock_entity_id( - entity_registry, device_registry, client, lock_schlage_be469 + entity_registry, + device_registry, + client, + lock_schlage_be469, + integration.entry_id, ) with pytest.raises(Unauthorized): diff --git a/tests/components/zwave_js/test_device_action.py b/tests/components/zwave_js/test_device_action.py index 66fda41220260..06a606e459e90 100644 --- a/tests/components/zwave_js/test_device_action.py +++ b/tests/components/zwave_js/test_device_action.py @@ -38,7 +38,9 @@ async def test_get_actions( node = lock_schlage_be469 driver = client.driver assert driver - device = device_registry.async_get_device(identifiers={get_device_id(driver, node)}) + device = device_registry.async_get_device_by_identifier( + get_device_id(driver, node), integration.entry_id + ) assert device binary_sensor = entity_registry.async_get( "binary_sensor.touchscreen_deadbolt_low_battery_level" @@ -105,8 +107,8 @@ async def test_get_actions( assert action in actions # Test that we don't return actions for a controller node - device = device_registry.async_get_device( - identifiers={get_device_id(driver, client.driver.controller.nodes[1])} + device = device_registry.async_get_device_by_identifier( + get_device_id(driver, client.driver.controller.nodes[1]), integration.entry_id ) assert device assert ( @@ -126,7 +128,9 @@ async def test_get_actions_meter( node = aeon_smart_switch_6 driver = client.driver assert driver - device = device_registry.async_get_device(identifiers={get_device_id(driver, node)}) + device = device_registry.async_get_device_by_identifier( + get_device_id(driver, node), integration.entry_id + ) assert device actions = await async_get_device_automations( hass, DeviceAutomationType.ACTION, device.id @@ -148,7 +152,9 @@ async def test_actions( driver = client.driver assert driver device_id = get_device_id(driver, node) - device = device_registry.async_get_device(identifiers={device_id}) + device = device_registry.async_get_device_by_identifier( + device_id, integration.entry_id + ) assert device climate = entity_registry.async_get("climate.z_wave_thermostat") @@ -302,7 +308,9 @@ async def test_actions_legacy( driver = client.driver assert driver device_id = get_device_id(driver, node) - device = device_registry.async_get_device(identifiers={device_id}) + device = device_registry.async_get_device_by_identifier( + device_id, integration.entry_id + ) assert device climate = entity_registry.async_get("climate.z_wave_thermostat") @@ -360,7 +368,9 @@ async def test_actions_multiple_calls( driver = client.driver assert driver device_id = get_device_id(driver, node) - device = device_registry.async_get_device({device_id}) + device = device_registry.async_get_device_by_identifier( + device_id, integration.entry_id + ) assert device climate = entity_registry.async_get("climate.z_wave_thermostat") assert climate @@ -410,7 +420,9 @@ async def test_lock_actions( driver = client.driver assert driver device_id = get_device_id(driver, node) - device = device_registry.async_get_device(identifiers={device_id}) + device = device_registry.async_get_device_by_identifier( + device_id, integration.entry_id + ) assert device lock = entity_registry.async_get("lock.touchscreen_deadbolt") assert lock @@ -484,7 +496,9 @@ async def test_reset_meter_action( driver = client.driver assert driver device_id = get_device_id(driver, node) - device = device_registry.async_get_device(identifiers={device_id}) + device = device_registry.async_get_device_by_identifier( + device_id, integration.entry_id + ) assert device sensor = entity_registry.async_get("sensor.smart_switch_6_electric_consumed_kwh") assert sensor @@ -530,8 +544,9 @@ async def test_get_action_capabilities( device_registry: dr.DeviceRegistry, ) -> None: """Test we get the expected action capabilities.""" - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, climate_radio_thermostat_ct100_plus)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, climate_radio_thermostat_ct100_plus), + integration.entry_id, ) assert device @@ -767,7 +782,9 @@ async def test_get_action_capabilities_meter_triggers( node = aeon_smart_switch_6 driver = client.driver assert driver - device = device_registry.async_get_device(identifiers={get_device_id(driver, node)}) + device = device_registry.async_get_device_by_identifier( + get_device_id(driver, node), integration.entry_id + ) assert device capabilities = await device_action.async_get_action_capabilities( hass, @@ -824,7 +841,9 @@ async def test_unavailable_entity_actions( node = lock_schlage_be469 driver = client.driver assert driver - device = device_registry.async_get_device(identifiers={get_device_id(driver, node)}) + device = device_registry.async_get_device_by_identifier( + get_device_id(driver, node), integration.entry_id + ) assert device binary_sensor = entity_registry.async_get(entity_id_unavailable) assert binary_sensor diff --git a/tests/components/zwave_js/test_device_condition.py b/tests/components/zwave_js/test_device_condition.py index 3ecd1722dea86..b273d56ee0926 100644 --- a/tests/components/zwave_js/test_device_condition.py +++ b/tests/components/zwave_js/test_device_condition.py @@ -34,8 +34,8 @@ async def test_get_conditions( device_registry: dr.DeviceRegistry, ) -> None: """Test we get the expected onditions from a zwave_js.""" - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, lock_schlage_be469)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, lock_schlage_be469), integration.entry_id ) assert device config_value = list(lock_schlage_be469.get_configuration_values().values())[0] @@ -74,8 +74,9 @@ async def test_get_conditions( assert condition in conditions # Test that we don't return actions for a controller node - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, client.driver.controller.nodes[1])} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, client.driver.controller.nodes[1]), + integration.entry_id, ) assert device assert ( @@ -95,8 +96,8 @@ async def test_node_status_state( device_registry: dr.DeviceRegistry, ) -> None: """Test for node_status conditions.""" - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, lock_schlage_be469)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, lock_schlage_be469), integration.entry_id ) assert device @@ -260,8 +261,8 @@ async def test_config_parameter_state( device_registry: dr.DeviceRegistry, ) -> None: """Test for config_parameter conditions.""" - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, lock_schlage_be469)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, lock_schlage_be469), integration.entry_id ) assert device @@ -380,8 +381,8 @@ async def test_value_state( device_registry: dr.DeviceRegistry, ) -> None: """Test for value conditions.""" - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, lock_schlage_be469)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, lock_schlage_be469), integration.entry_id ) assert device @@ -431,8 +432,8 @@ async def test_get_condition_capabilities_node_status( device_registry: dr.DeviceRegistry, ) -> None: """Test we don't get capabilities from a node_status condition.""" - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, lock_schlage_be469)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, lock_schlage_be469), integration.entry_id ) assert device @@ -471,8 +472,8 @@ async def test_get_condition_capabilities_value( device_registry: dr.DeviceRegistry, ) -> None: """Test we get the expected capabilities from a value condition.""" - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, lock_schlage_be469)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, lock_schlage_be469), integration.entry_id ) assert device @@ -524,8 +525,9 @@ async def test_get_condition_capabilities_config_parameter( ) -> None: """Test we get the expected capabilities from a config_parameter condition.""" node = climate_radio_thermostat_ct100_plus - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, climate_radio_thermostat_ct100_plus)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, climate_radio_thermostat_ct100_plus), + integration.entry_id, ) assert device @@ -609,8 +611,8 @@ async def test_failure_scenarios( device_registry: dr.DeviceRegistry, ) -> None: """Test failure scenarios.""" - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, hank_binary_switch)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, hank_binary_switch), integration.entry_id ) assert device diff --git a/tests/components/zwave_js/test_device_trigger.py b/tests/components/zwave_js/test_device_trigger.py index 92dc404087b2e..3777fcf5909f9 100644 --- a/tests/components/zwave_js/test_device_trigger.py +++ b/tests/components/zwave_js/test_device_trigger.py @@ -35,8 +35,9 @@ async def test_no_controller_triggers( hass: HomeAssistant, device_registry: dr.DeviceRegistry, client, integration ) -> None: """Test that we do not get triggers for the controller.""" - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, client.driver.controller.nodes[1])} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, client.driver.controller.nodes[1]), + integration.entry_id, ) assert device assert ( @@ -55,8 +56,8 @@ async def test_get_notification_notification_triggers( integration, ) -> None: """Test expected triggers from a device with Notification CC.""" - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, lock_schlage_be469)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, lock_schlage_be469), integration.entry_id ) assert device expected_trigger = { @@ -83,8 +84,8 @@ async def test_if_notification_notification_fires( ) -> None: """Test for event.notification.notification trigger firing.""" node: Node = lock_schlage_be469 - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, lock_schlage_be469)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, lock_schlage_be469), integration.entry_id ) assert device @@ -181,8 +182,8 @@ async def test_get_trigger_capabilities_notification_notification( integration, ) -> None: """Test capabilities from a notification.notification trigger.""" - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, lock_schlage_be469)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, lock_schlage_be469), integration.entry_id ) assert device capabilities = await device_trigger.async_get_trigger_capabilities( @@ -224,8 +225,8 @@ async def test_if_entry_control_notification_fires( ) -> None: """Test for notification.entry_control trigger firing.""" node: Node = lock_schlage_be469 - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, lock_schlage_be469)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, lock_schlage_be469), integration.entry_id ) assert device @@ -321,8 +322,8 @@ async def test_get_trigger_capabilities_entry_control_notification( integration, ) -> None: """Test capabilities from a notification.entry_control trigger.""" - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, lock_schlage_be469)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, lock_schlage_be469), integration.entry_id ) assert device capabilities = await device_trigger.async_get_trigger_capabilities( @@ -366,8 +367,8 @@ async def test_get_node_status_triggers( integration, ) -> None: """Test expected triggers from device with node status enabled.""" - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, lock_schlage_be469)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, lock_schlage_be469), integration.entry_id ) assert device entity_id = async_get_node_status_sensor_entity_id( @@ -402,8 +403,8 @@ async def test_if_node_status_change_fires( ) -> None: """Test for node_status trigger firing.""" node: Node = lock_schlage_be469 - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, lock_schlage_be469)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, lock_schlage_be469), integration.entry_id ) assert device entity_id = async_get_node_status_sensor_entity_id( @@ -485,8 +486,8 @@ async def test_if_node_status_change_fires_legacy( ) -> None: """Test for node_status trigger firing.""" node: Node = lock_schlage_be469 - device = device_registry.async_get_device( - {get_device_id(client.driver, lock_schlage_be469)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, lock_schlage_be469), integration.entry_id ) assert device entity_id = async_get_node_status_sensor_entity_id( @@ -566,8 +567,8 @@ async def test_get_trigger_capabilities_node_status( integration, ) -> None: """Test we get the expected capabilities from a node_status trigger.""" - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, lock_schlage_be469)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, lock_schlage_be469), integration.entry_id ) assert device entity_id = async_get_node_status_sensor_entity_id( @@ -633,8 +634,8 @@ async def test_get_basic_value_notification_triggers( integration, ) -> None: """Test we get the expected triggers from a zwave_js device with the Basic CC.""" - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, ge_in_wall_dimmer_switch)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, ge_in_wall_dimmer_switch), integration.entry_id ) assert device expected_trigger = { @@ -665,8 +666,8 @@ async def test_if_basic_value_notification_fires( ) -> None: """Test for event.value_notification.basic trigger firing.""" node: Node = ge_in_wall_dimmer_switch - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, ge_in_wall_dimmer_switch)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, ge_in_wall_dimmer_switch), integration.entry_id ) assert device @@ -777,8 +778,8 @@ async def test_get_trigger_capabilities_basic_value_notification( integration, ) -> None: """Test we get the expected capabilities from a value_notification.basic trigger.""" - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, ge_in_wall_dimmer_switch)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, ge_in_wall_dimmer_switch), integration.entry_id ) assert device capabilities = await device_trigger.async_get_trigger_capabilities( @@ -819,8 +820,8 @@ async def test_get_central_scene_value_notification_triggers( integration, ) -> None: """Test expected triggers from a device with Central Scene CC.""" - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, wallmote_central_scene)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, wallmote_central_scene), integration.entry_id ) assert device expected_trigger = { @@ -851,8 +852,8 @@ async def test_if_central_scene_value_notification_fires( ) -> None: """Test for event.value_notification.central_scene trigger firing.""" node: Node = wallmote_central_scene - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, wallmote_central_scene)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, wallmote_central_scene), integration.entry_id ) assert device @@ -973,8 +974,8 @@ async def test_get_trigger_capabilities_central_scene_value_notification( integration, ) -> None: """Test capabilities from value_notification.central_scene.""" - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, wallmote_central_scene)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, wallmote_central_scene), integration.entry_id ) assert device capabilities = await device_trigger.async_get_trigger_capabilities( @@ -1018,8 +1019,8 @@ async def test_get_scene_activation_value_notification_triggers( integration, ) -> None: """Test expected triggers from device with SceneActivation CC.""" - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, hank_binary_switch)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, hank_binary_switch), integration.entry_id ) assert device expected_trigger = { @@ -1050,8 +1051,8 @@ async def test_if_scene_activation_value_notification_fires( ) -> None: """Test for event.value_notification.scene_activation trigger firing.""" node: Node = hank_binary_switch - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, hank_binary_switch)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, hank_binary_switch), integration.entry_id ) assert device @@ -1166,8 +1167,8 @@ async def test_get_trigger_capabilities_scene_activation_value_notification( integration, ) -> None: """Test capabilities from value_notification.scene_activation.""" - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, hank_binary_switch)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, hank_binary_switch), integration.entry_id ) assert device capabilities = await device_trigger.async_get_trigger_capabilities( @@ -1208,8 +1209,8 @@ async def test_get_value_updated_value_triggers( integration, ) -> None: """Test we get the zwave_js.value_updated.value trigger from a zwave_js device.""" - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, lock_schlage_be469)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, lock_schlage_be469), integration.entry_id ) assert device expected_trigger = { @@ -1235,8 +1236,8 @@ async def test_if_value_updated_value_fires( ) -> None: """Test for zwave_js.value_updated.value trigger firing.""" node: Node = lock_schlage_be469 - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, lock_schlage_be469)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, lock_schlage_be469), integration.entry_id ) assert device @@ -1331,8 +1332,8 @@ async def test_value_updated_value_no_driver( ) -> None: """Test zwave_js.value_updated.value trigger with missing driver.""" node: Node = lock_schlage_be469 - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, lock_schlage_be469)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, lock_schlage_be469), integration.entry_id ) assert device driver = client.driver @@ -1404,8 +1405,8 @@ async def test_get_trigger_capabilities_value_updated_value( integration, ) -> None: """Test capabilities from zwave_js.value_updated.value trigger.""" - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, lock_schlage_be469)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, lock_schlage_be469), integration.entry_id ) assert device capabilities = await device_trigger.async_get_trigger_capabilities( @@ -1458,8 +1459,8 @@ async def test_get_value_updated_config_parameter_triggers( integration, ) -> None: """Test value_updated.config_parameter trigger from a device.""" - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, lock_schlage_be469)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, lock_schlage_be469), integration.entry_id ) assert device expected_trigger = { @@ -1490,8 +1491,8 @@ async def test_if_value_updated_config_parameter_fires( ) -> None: """Test for zwave_js.value_updated.config_parameter trigger firing.""" node: Node = lock_schlage_be469 - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, lock_schlage_be469)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, lock_schlage_be469), integration.entry_id ) assert device @@ -1563,8 +1564,8 @@ async def test_get_trigger_capabilities_value_updated_config_parameter_range( integration, ) -> None: """Test capabilities from a range config_parameter trigger.""" - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, lock_schlage_be469)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, lock_schlage_be469), integration.entry_id ) assert device capabilities = await device_trigger.async_get_trigger_capabilities( @@ -1613,8 +1614,8 @@ async def test_get_trigger_capabilities_value_updated_config_parameter_enumerate integration, ) -> None: """Test capabilities from an enumerated config_parameter trigger.""" - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, lock_schlage_be469)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, lock_schlage_be469), integration.entry_id ) assert device capabilities = await device_trigger.async_get_trigger_capabilities( @@ -1674,8 +1675,8 @@ async def test_failure_scenarios( {}, ) - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, hank_binary_switch)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, hank_binary_switch), integration.entry_id ) assert device diff --git a/tests/components/zwave_js/test_diagnostics.py b/tests/components/zwave_js/test_diagnostics.py index 835b85177fe14..65e7ff22260ee 100644 --- a/tests/components/zwave_js/test_diagnostics.py +++ b/tests/components/zwave_js/test_diagnostics.py @@ -62,8 +62,8 @@ async def test_device_diagnostics( snapshot: SnapshotAssertion, ) -> None: """Test the device level diagnostics data dump.""" - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, multisensor_6)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, multisensor_6), integration.entry_id ) assert device @@ -166,8 +166,8 @@ async def test_device_diagnostics_missing_primary_value( hass_client: ClientSessionGenerator, ) -> None: """Test that device diagnostics handles an entity with a missing primary value.""" - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, multisensor_6)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, multisensor_6), integration.entry_id ) assert device @@ -259,8 +259,8 @@ def _find_ultraviolet_val(data: dict) -> dict: client.driver.controller.nodes[node.node_id] = node client.driver.controller.emit("node added", {"node": node}) await hass.async_block_till_done() - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, node)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, node), integration.entry_id ) assert device diff --git a/tests/components/zwave_js/test_discovery.py b/tests/components/zwave_js/test_discovery.py index dd62350608d70..8763a8a49f6fc 100644 --- a/tests/components/zwave_js/test_discovery.py +++ b/tests/components/zwave_js/test_discovery.py @@ -683,8 +683,9 @@ async def test_fibaro_fgms001_unknown_firmware_setup( """ assert integration.state is ConfigEntryState.LOADED - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, fibaro_fgms001_unknown_firmware)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, fibaro_fgms001_unknown_firmware), + integration.entry_id, ) assert device is not None @@ -717,8 +718,8 @@ async def test_fibaro_fgms001_v2_8_motion_discovery( or be misclassified, so we assert that exactly one binary_sensor entity with device_class=motion is created and no light entity exists. """ - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, fibaro_fgms001_v2_8)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, fibaro_fgms001_v2_8), integration.entry_id ) assert device is not None diff --git a/tests/components/zwave_js/test_init.py b/tests/components/zwave_js/test_init.py index d5a3b49965759..90703a9f4d019 100644 --- a/tests/components/zwave_js/test_init.py +++ b/tests/components/zwave_js/test_init.py @@ -482,8 +482,8 @@ async def test_on_node_added_ready( state = hass.states.get(AIR_TEMPERATURE_SENSOR) assert not state # entity and device not yet added - assert not device_registry.async_get_device( - identifiers={(DOMAIN, air_temperature_device_id)} + assert not device_registry.async_get_device_by_identifier( + (DOMAIN, air_temperature_device_id), integration.entry_id ) client.driver.controller.emit("node added", event) @@ -625,7 +625,9 @@ async def test_on_node_added_not_ready( client.driver.receive_event(event) await hass.async_block_till_done() - device = device_registry.async_get_device(identifiers={(DOMAIN, device_id)}) + device = device_registry.async_get_device_by_identifier( + (DOMAIN, device_id), hass.config_entries.async_entries(DOMAIN)[0].entry_id + ) assert device # no extended device identifier yet assert len(device.identifiers) == 1 @@ -655,12 +657,12 @@ async def test_existing_node_ready( assert state # entity and device added assert state.state != STATE_UNAVAILABLE - device = device_registry.async_get_device( - identifiers={(DOMAIN, air_temperature_device_id)} + device = device_registry.async_get_device_by_identifier( + (DOMAIN, air_temperature_device_id), integration.entry_id ) assert device - assert device == device_registry.async_get_device( - identifiers={(DOMAIN, air_temperature_device_id_ext)} + assert device == device_registry.async_get_device_by_identifier( + (DOMAIN, air_temperature_device_id_ext), integration.entry_id ) @@ -686,12 +688,12 @@ async def test_existing_node_reinterview( assert state # entity and device added assert state.state != STATE_UNAVAILABLE - device = device_registry.async_get_device( - identifiers={(DOMAIN, air_temperature_device_id)} + device = device_registry.async_get_device_by_identifier( + (DOMAIN, air_temperature_device_id), integration.entry_id ) assert device - assert device == device_registry.async_get_device( - identifiers={(DOMAIN, air_temperature_device_id_ext)} + assert device == device_registry.async_get_device_by_identifier( + (DOMAIN, air_temperature_device_id_ext), integration.entry_id ) assert device.sw_version == "1.12" @@ -713,12 +715,12 @@ async def test_existing_node_reinterview( assert state assert state.state != STATE_UNAVAILABLE - device = device_registry.async_get_device( - identifiers={(DOMAIN, air_temperature_device_id)} + device = device_registry.async_get_device_by_identifier( + (DOMAIN, air_temperature_device_id), integration.entry_id ) assert device - assert device == device_registry.async_get_device( - identifiers={(DOMAIN, air_temperature_device_id_ext)} + assert device == device_registry.async_get_device_by_identifier( + (DOMAIN, air_temperature_device_id_ext), integration.entry_id ) assert device.sw_version == "1.13" @@ -735,14 +737,18 @@ async def test_existing_node_not_ready( node = zp3111_not_ready device_id = f"{client.driver.controller.home_id}-{node.node_id}" - device = device_registry.async_get_device(identifiers={(DOMAIN, device_id)}) + device = device_registry.async_get_device_by_identifier( + (DOMAIN, device_id), integration.entry_id + ) assert device assert device.name == f"Node {node.node_id}" assert not device.manufacturer assert not device.model assert not device.sw_version - device = device_registry.async_get_device(identifiers={(DOMAIN, device_id)}) + device = device_registry.async_get_device_by_identifier( + (DOMAIN, device_id), integration.entry_id + ) assert device # no extended device identifier yet assert len(device.identifiers) == 1 @@ -775,7 +781,9 @@ async def test_existing_node_not_replaced_when_not_ready( f"{zp3111.product_type}:{zp3111.product_id}" ) - device = device_registry.async_get_device(identifiers={(DOMAIN, device_id)}) + device = device_registry.async_get_device_by_identifier( + (DOMAIN, device_id), integration.entry_id + ) assert device assert device.name == "4-in-1 Sensor" assert not device.name_by_user @@ -783,8 +791,8 @@ async def test_existing_node_not_replaced_when_not_ready( assert device.model == "ZP3111-5" assert device.sw_version == "5.1" assert not device.area_id - assert device == device_registry.async_get_device( - identifiers={(DOMAIN, device_id_ext)} + assert device == device_registry.async_get_device_by_identifier( + (DOMAIN, device_id_ext), integration.entry_id ) motion_entity = "binary_sensor.4_in_1_sensor_motion_detection" @@ -796,7 +804,9 @@ async def test_existing_node_not_replaced_when_not_ready( device.id, name_by_user="Custom Device Name", area_id=kitchen_area.id ) - custom_device = device_registry.async_get_device(identifiers={(DOMAIN, device_id)}) + custom_device = device_registry.async_get_device_by_identifier( + (DOMAIN, device_id), integration.entry_id + ) assert custom_device assert custom_device.name == "4-in-1 Sensor" assert custom_device.name_by_user == "Custom Device Name" @@ -804,8 +814,8 @@ async def test_existing_node_not_replaced_when_not_ready( assert custom_device.model == "ZP3111-5" assert device.sw_version == "5.1" assert custom_device.area_id == kitchen_area.id - assert custom_device == device_registry.async_get_device( - identifiers={(DOMAIN, device_id_ext)} + assert custom_device == device_registry.async_get_device_by_identifier( + (DOMAIN, device_id_ext), integration.entry_id ) custom_entity = "binary_sensor.custom_motion_sensor" @@ -833,10 +843,12 @@ async def test_existing_node_not_replaced_when_not_ready( client.driver.receive_event(event) await hass.async_block_till_done() - device = device_registry.async_get_device(identifiers={(DOMAIN, device_id)}) + device = device_registry.async_get_device_by_identifier( + (DOMAIN, device_id), integration.entry_id + ) assert device - assert device == device_registry.async_get_device( - identifiers={(DOMAIN, device_id_ext)} + assert device == device_registry.async_get_device_by_identifier( + (DOMAIN, device_id_ext), integration.entry_id ) assert device.id == custom_device.id assert device.identifiers == custom_device.identifiers @@ -863,10 +875,12 @@ async def test_existing_node_not_replaced_when_not_ready( client.driver.receive_event(event) await hass.async_block_till_done() - device = device_registry.async_get_device(identifiers={(DOMAIN, device_id)}) + device = device_registry.async_get_device_by_identifier( + (DOMAIN, device_id), integration.entry_id + ) assert device - assert device == device_registry.async_get_device( - identifiers={(DOMAIN, device_id_ext)} + assert device == device_registry.async_get_device_by_identifier( + (DOMAIN, device_id_ext), integration.entry_id ) assert device.id == custom_device.id assert device.identifiers == custom_device.identifiers @@ -1452,7 +1466,9 @@ async def test_removed_device( ) assert len(device_entries) == 2 assert ( - device_registry.async_get_device(identifiers={get_device_id(driver, old_node)}) + device_registry.async_get_device_by_identifier( + get_device_id(driver, old_node), integration.entry_id + ) is None ) @@ -1496,7 +1512,9 @@ async def test_node_removed( client.driver.controller.receive_event(Event("node added", event)) await hass.async_block_till_done() - old_device = device_registry.async_get_device(identifiers={(DOMAIN, device_id)}) + old_device = device_registry.async_get_device_by_identifier( + (DOMAIN, device_id), integration.entry_id + ) assert old_device assert old_device.id @@ -1531,10 +1549,12 @@ async def test_replace_same_node( f"{multisensor_6.product_type}:{multisensor_6.product_id}" ) - device = device_registry.async_get_device(identifiers={(DOMAIN, device_id)}) + device = device_registry.async_get_device_by_identifier( + (DOMAIN, device_id), integration.entry_id + ) assert device - assert device == device_registry.async_get_device( - identifiers={(DOMAIN, multisensor_6_device_id)} + assert device == device_registry.async_get_device_by_identifier( + (DOMAIN, multisensor_6_device_id), integration.entry_id ) assert device.manufacturer == "AEON Labs" assert device.model == "ZW100" @@ -1613,9 +1633,11 @@ async def test_replace_same_node( # Device is the same device = device_registry.async_get(dev_id) assert device - assert device == device_registry.async_get_device(identifiers={(DOMAIN, device_id)}) - assert device == device_registry.async_get_device( - identifiers={(DOMAIN, multisensor_6_device_id)} + assert device == device_registry.async_get_device_by_identifier( + (DOMAIN, device_id), integration.entry_id + ) + assert device == device_registry.async_get_device_by_identifier( + (DOMAIN, multisensor_6_device_id), integration.entry_id ) assert device.manufacturer == "AEON Labs" assert device.model == "ZW100" @@ -1649,10 +1671,12 @@ async def test_replace_different_node( f"{state['productId']}" ) - device = device_registry.async_get_device(identifiers={(DOMAIN, device_id)}) + device = device_registry.async_get_device_by_identifier( + (DOMAIN, device_id), integration.entry_id + ) assert device - assert device == device_registry.async_get_device( - identifiers={(DOMAIN, multisensor_6_device_id_ext)} + assert device == device_registry.async_get_device_by_identifier( + (DOMAIN, multisensor_6_device_id_ext), integration.entry_id ) assert device.manufacturer == "AEON Labs" assert device.model == "ZW100" @@ -1674,8 +1698,8 @@ async def test_replace_different_node( await hass.async_block_till_done() # Device should still be there after the node was removed - device = device_registry.async_get_device( - identifiers={(DOMAIN, multisensor_6_device_id_ext)} + device = device_registry.async_get_device_by_identifier( + (DOMAIN, multisensor_6_device_id_ext), integration.entry_id ) assert device assert len(device.identifiers) == 2 @@ -1734,10 +1758,12 @@ async def test_replace_different_node( # node ID based device identifier should be moved from the old multisensor device # to the new hank device and both the old and new devices should exist. - new_device = device_registry.async_get_device(identifiers={(DOMAIN, device_id)}) + new_device = device_registry.async_get_device_by_identifier( + (DOMAIN, device_id), integration.entry_id + ) assert new_device - hank_device = device_registry.async_get_device( - identifiers={(DOMAIN, hank_device_id_ext)} + hank_device = device_registry.async_get_device_by_identifier( + (DOMAIN, hank_device_id_ext), integration.entry_id ) assert hank_device assert hank_device == new_device @@ -1745,8 +1771,8 @@ async def test_replace_different_node( (DOMAIN, device_id), (DOMAIN, hank_device_id_ext), } - multisensor_6_device = device_registry.async_get_device( - identifiers={(DOMAIN, multisensor_6_device_id_ext)} + multisensor_6_device = device_registry.async_get_device_by_identifier( + (DOMAIN, multisensor_6_device_id_ext), integration.entry_id ) assert multisensor_6_device assert multisensor_6_device != new_device @@ -1776,8 +1802,8 @@ async def test_replace_different_node( await hass.async_block_till_done() # Device should still be there after the node was removed - device = device_registry.async_get_device( - identifiers={(DOMAIN, hank_device_id_ext)} + device = device_registry.async_get_device_by_identifier( + (DOMAIN, hank_device_id_ext), integration.entry_id ) assert device assert len(device.identifiers) == 2 @@ -1835,16 +1861,18 @@ async def test_replace_different_node( # node ID based device identifier should be moved from the new hank device # to the old multisensor device and both the old and new devices should exist. - old_device = device_registry.async_get_device(identifiers={(DOMAIN, device_id)}) + old_device = device_registry.async_get_device_by_identifier( + (DOMAIN, device_id), integration.entry_id + ) assert old_device - hank_device = device_registry.async_get_device( - identifiers={(DOMAIN, hank_device_id_ext)} + hank_device = device_registry.async_get_device_by_identifier( + (DOMAIN, hank_device_id_ext), integration.entry_id ) assert hank_device assert hank_device != old_device assert hank_device.identifiers == {(DOMAIN, hank_device_id_ext)} - multisensor_6_device = device_registry.async_get_device( - identifiers={(DOMAIN, multisensor_6_device_id_ext)} + multisensor_6_device = device_registry.async_get_device_by_identifier( + (DOMAIN, multisensor_6_device_id_ext), integration.entry_id ) assert multisensor_6_device assert multisensor_6_device == old_device @@ -1873,10 +1901,12 @@ async def test_node_model_change( ) # Verify device and entities have default names/ids - device = device_registry.async_get_device(identifiers={(DOMAIN, device_id)}) + device = device_registry.async_get_device_by_identifier( + (DOMAIN, device_id), integration.entry_id + ) assert device - assert device == device_registry.async_get_device( - identifiers={(DOMAIN, device_id_ext)} + assert device == device_registry.async_get_device_by_identifier( + (DOMAIN, device_id_ext), integration.entry_id ) assert device.manufacturer == "Vision Security" assert device.model == "ZP3111-5" @@ -1892,11 +1922,13 @@ async def test_node_model_change( # Customize device and entity names/ids device_registry.async_update_device(device.id, name_by_user="Custom Device Name") - device = device_registry.async_get_device(identifiers={(DOMAIN, device_id)}) + device = device_registry.async_get_device_by_identifier( + (DOMAIN, device_id), integration.entry_id + ) assert device assert device.id == dev_id - assert device == device_registry.async_get_device( - identifiers={(DOMAIN, device_id_ext)} + assert device == device_registry.async_get_device_by_identifier( + (DOMAIN, device_id_ext), integration.entry_id ) assert device.manufacturer == "Vision Security" assert device.model == "ZP3111-5" @@ -2425,7 +2457,9 @@ async def test_factory_reset_node( assert "with the home ID" not in notifications[msg_id]["message"] async_dismiss(hass, msg_id) await hass.async_block_till_done() - assert not device_registry.async_get_device(identifiers={dev_id}) + assert not device_registry.async_get_device_by_identifier( + dev_id, integration.entry_id + ) # Add mock config entry to simulate having multiple entries new_entry = MockConfigEntry(domain=DOMAIN) diff --git a/tests/components/zwave_js/test_logbook.py b/tests/components/zwave_js/test_logbook.py index 362daecdb4706..e56be4e8ea0b0 100644 --- a/tests/components/zwave_js/test_logbook.py +++ b/tests/components/zwave_js/test_logbook.py @@ -22,8 +22,8 @@ async def test_humanifying_zwave_js_notification_event( integration, ) -> None: """Test humanifying Z-Wave JS notification events.""" - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, lock_schlage_be469)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, lock_schlage_be469), integration.entry_id ) assert device @@ -123,8 +123,8 @@ async def test_humanifying_zwave_js_value_notification_event( integration, ) -> None: """Test humanifying Z-Wave JS value notification events.""" - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, lock_schlage_be469)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, lock_schlage_be469), integration.entry_id ) assert device diff --git a/tests/components/zwave_js/test_repairs.py b/tests/components/zwave_js/test_repairs.py index 226173dc0129f..5dc19cd2f980f 100644 --- a/tests/components/zwave_js/test_repairs.py +++ b/tests/components/zwave_js/test_repairs.py @@ -64,8 +64,8 @@ async def test_device_config_file_changed_confirm_step( client.async_send_command_no_wait.reset_mock() - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, node)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, node), integration.entry_id ) assert device issue_id = f"device_config_file_changed.{device.id}" @@ -126,8 +126,8 @@ async def test_device_config_file_changed_cleared( """Test the device_config_file_changed issue is cleared when no longer true.""" node = await _trigger_repair_issue(hass, client, multisensor_6_state) - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, node)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, node), integration.entry_id ) assert device issue_id = f"device_config_file_changed.{device.id}" @@ -168,8 +168,8 @@ async def test_device_config_file_changed_ignore_step( client.async_send_command_no_wait.reset_mock() - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, node)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, node), integration.entry_id ) assert device issue_id = f"device_config_file_changed.{device.id}" @@ -280,8 +280,8 @@ async def test_abort_confirm( """Test aborting device_config_file_changed issue in confirm step.""" node = await _trigger_repair_issue(hass, client, multisensor_6_state) - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, node)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, node), integration.entry_id ) assert device issue_id = f"device_config_file_changed.{device.id}" diff --git a/tests/components/zwave_js/test_services.py b/tests/components/zwave_js/test_services.py index c2ae3bb9c6611..bfb7dd8bf5b43 100644 --- a/tests/components/zwave_js/test_services.py +++ b/tests/components/zwave_js/test_services.py @@ -608,8 +608,8 @@ async def test_bulk_set_config_parameters( integration, ) -> None: """Test the bulk_set_partial_config_parameters service.""" - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, multisensor_6)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, multisensor_6), integration.entry_id ) assert device @@ -978,8 +978,8 @@ async def test_set_value( integration, ) -> None: """Test set_value service.""" - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, climate_danfoss_lc_13)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, climate_danfoss_lc_13), integration.entry_id ) assert device @@ -1334,12 +1334,12 @@ async def test_multicast_set_value( client.async_send_command.reset_mock() # Test using area ID - device_eurotronic = device_registry.async_get_device( - identifiers={get_device_id(client.driver, climate_eurotronic_spirit_z)} + device_eurotronic = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, climate_eurotronic_spirit_z), integration.entry_id ) assert device_eurotronic - device_danfoss = device_registry.async_get_device( - identifiers={get_device_id(client.driver, climate_danfoss_lc_13)} + device_danfoss = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, climate_danfoss_lc_13), integration.entry_id ) assert device_danfoss area = area_registry.async_get_or_create("test") @@ -1659,16 +1659,15 @@ async def test_ping( integration, ) -> None: """Test ping service.""" - device_radio_thermostat = device_registry.async_get_device( - identifiers={ - get_device_id( - client.driver, climate_radio_thermostat_ct100_plus_different_endpoints - ) - } + device_radio_thermostat = device_registry.async_get_device_by_identifier( + get_device_id( + client.driver, climate_radio_thermostat_ct100_plus_different_endpoints + ), + integration.entry_id, ) assert device_radio_thermostat - device_danfoss = device_registry.async_get_device( - identifiers={get_device_id(client.driver, climate_danfoss_lc_13)} + device_danfoss = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, climate_danfoss_lc_13), integration.entry_id ) assert device_danfoss @@ -1816,16 +1815,15 @@ async def test_invoke_cc_api( integration, ) -> None: """Test invoke_cc_api service.""" - device_radio_thermostat = device_registry.async_get_device( - identifiers={ - get_device_id( - client.driver, climate_radio_thermostat_ct100_plus_different_endpoints - ) - } + device_radio_thermostat = device_registry.async_get_device_by_identifier( + get_device_id( + client.driver, climate_radio_thermostat_ct100_plus_different_endpoints + ), + integration.entry_id, ) assert device_radio_thermostat - device_danfoss = device_registry.async_get_device( - identifiers={get_device_id(client.driver, climate_danfoss_lc_13)} + device_danfoss = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, climate_danfoss_lc_13), integration.entry_id ) assert device_danfoss @@ -1983,12 +1981,12 @@ async def test_refresh_notifications( integration, ) -> None: """Test refresh_notifications service.""" - zen_31_device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, zen_31)} + zen_31_device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, zen_31), integration.entry_id ) assert zen_31_device - multisensor_6_device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, multisensor_6)} + multisensor_6_device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, multisensor_6), integration.entry_id ) assert multisensor_6_device diff --git a/tests/components/zwave_js/test_trigger.py b/tests/components/zwave_js/test_trigger.py index 17e48ab6572ad..06b699e883941 100644 --- a/tests/components/zwave_js/test_trigger.py +++ b/tests/components/zwave_js/test_trigger.py @@ -35,8 +35,8 @@ async def test_zwave_js_value_updated( """Test for zwave_js.value_updated automation trigger.""" trigger_type = f"{DOMAIN}.value_updated" node: Node = lock_schlage_be469 - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, lock_schlage_be469)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, lock_schlage_be469), integration.entry_id ) assert device @@ -478,8 +478,8 @@ async def test_zwave_js_event( """Test for zwave_js.event automation trigger.""" trigger_type = f"{DOMAIN}.event" node: Node = lock_schlage_be469 - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, lock_schlage_be469)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, lock_schlage_be469), integration.entry_id ) assert device @@ -1049,8 +1049,8 @@ async def test_zwave_js_trigger_config_entry_unloaded( integration, ) -> None: """Test zwave_js triggers bypass dynamic validation when needed.""" - device = device_registry.async_get_device( - identifiers={get_device_id(client.driver, lock_schlage_be469)} + device = device_registry.async_get_device_by_identifier( + get_device_id(client.driver, lock_schlage_be469), integration.entry_id ) assert device diff --git a/tests/components/zwave_me/test_remove_stale_devices.py b/tests/components/zwave_me/test_remove_stale_devices.py index 9f8607cf91e93..ae6c5dfff4845 100644 --- a/tests/components/zwave_me/test_remove_stale_devices.py +++ b/tests/components/zwave_me/test_remove_stale_devices.py @@ -63,13 +63,12 @@ async def test_remove_stale_devices( await hass.config_entries.async_setup(config_entry.entry_id) assert ( bool( - device_registry.async_get_device( - identifiers={ - ( - "zwave_me", - f"{config_entry.unique_id}-{identifier}", - ) - } + device_registry.async_get_device_by_identifier( + ( + "zwave_me", + f"{config_entry.unique_id}-{identifier}", + ), + config_entry.entry_id, ) ) == should_exist diff --git a/tests/helpers/test_entity.py b/tests/helpers/test_entity.py index bf562c8c12be7..1406a12206a2b 100644 --- a/tests/helpers/test_entity.py +++ b/tests/helpers/test_entity.py @@ -1630,7 +1630,9 @@ async def async_setup_entry( state = hass.states.async_all()[0] assert state.attributes.get(ATTR_FRIENDLY_NAME) == expected_friendly_name1 - device = device_registry.async_get_device(identifiers={("hue", "1234")}) + device = device_registry.async_get_device_by_identifier( + ("hue", "1234"), config_entry.entry_id + ) device_registry.async_update_device(device.id, name_by_user="Device Bla2") await hass.async_block_till_done() diff --git a/tests/helpers/test_entity_platform.py b/tests/helpers/test_entity_platform.py index acdb456872591..9d20a8770a42f 100644 --- a/tests/helpers/test_entity_platform.py +++ b/tests/helpers/test_entity_platform.py @@ -1508,13 +1508,17 @@ async def async_setup_entry( assert len(hass.states.async_entity_ids()) == 3 - device = device_registry.async_get_device(identifiers={("hue", "1234")}) + device = device_registry.async_get_device_by_identifier( + ("hue", "1234"), config_entry.entry_id + ) assert device == snapshot assert device.config_entries == {config_entry.entry_id} assert device.config_entries_subentries == {config_entry.entry_id: {None}} assert device.primary_config_entry == config_entry.entry_id assert device.via_device_id == via.id - device = device_registry.async_get_device(identifiers={("hue", "efgh")}) + device = device_registry.async_get_device_by_identifier( + ("hue", "efgh"), config_entry.entry_id + ) assert device == snapshot assert device.config_entries == {config_entry.entry_id} assert device.config_entries_subentries == { @@ -1568,8 +1572,8 @@ async def async_setup_entry( assert await entity_platform.async_setup_entry(config_entry) await hass.async_block_till_done() - device2 = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, "abcd")} + device2 = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, "abcd"), config_entry.entry_id ) assert device2 is not None assert device.id == device2.id @@ -1622,7 +1626,9 @@ async def async_setup_entry( assert len(hass.states.async_entity_ids()) == 1 - device = device_registry.async_get_device(identifiers={("mqtt", "1234")}) + device = device_registry.async_get_device_by_identifier( + ("mqtt", "1234"), config_entry.entry_id + ) assert device is not None assert device.identifiers == {("mqtt", "1234")} assert device.configuration_url == "homeassistant://config/mqtt" @@ -1674,7 +1680,9 @@ async def async_setup_entry( assert len(hass.states.async_entity_ids()) == 1 - device = device_registry.async_get_device(identifiers={("mqtt", "1234")}) + device = device_registry.async_get_device_by_identifier( + ("mqtt", "1234"), config_entry.entry_id + ) assert device is not None assert device.identifiers == {("mqtt", "1234")} assert device.configuration_url is None @@ -2762,8 +2770,8 @@ async def async_setup_entry( assert await entity_platform.async_setup_entry(config_entry) await hass.async_block_till_done() - device = device_registry.async_get_device( - connections={(dr.CONNECTION_NETWORK_MAC, "1234")} + device = device_registry.async_get_device_by_connection( + (dr.CONNECTION_NETWORK_MAC, "1234"), config_entry.entry_id ) assert device is not None assert device.name == expected_device_name diff --git a/tests/helpers/test_entity_registry.py b/tests/helpers/test_entity_registry.py index 63e569aa4643d..52b5a09ff7388 100644 --- a/tests/helpers/test_entity_registry.py +++ b/tests/helpers/test_entity_registry.py @@ -3239,12 +3239,12 @@ async def test_remove_device_removes_entities( assert not entity_registry.async_is_registered(entry.entity_id) -async def test_remove_config_entry_from_device_removes_entities( +async def test_remove_device_with_shared_connection_removes_entities( hass: HomeAssistant, device_registry: dr.DeviceRegistry, entity_registry: er.EntityRegistry, ) -> None: - """Test that we remove entities tied to a device when its config entry is removed.""" + """Test removing a device with a shared connection removes only its entities.""" config_entry_1 = MockConfigEntry(domain="hue") config_entry_1.add_to_hass(hass) config_entry_2 = MockConfigEntry(domain="device_tracker") @@ -3279,10 +3279,8 @@ async def test_remove_config_entry_from_device_removes_entities( assert entity_registry.async_is_registered(entry_1.entity_id) assert entity_registry.async_is_registered(entry_2.entity_id) - # Removing the first config entry removes its device and the tied entity - device_registry.async_update_device( - device_entry_1.id, remove_config_entry_id=config_entry_1.entry_id - ) + # Removing the first device removes it along with its tied entity + device_registry.async_remove_device(device_entry_1.id) await hass.async_block_till_done() assert not device_registry.async_get(device_entry_1.id) @@ -3290,22 +3288,20 @@ async def test_remove_config_entry_from_device_removes_entities( assert device_registry.async_get(device_entry_2.id) assert entity_registry.async_is_registered(entry_2.entity_id) - # Removing the second config entry removes its device and entity too - device_registry.async_update_device( - device_entry_2.id, remove_config_entry_id=config_entry_2.entry_id - ) + # Removing the second device removes it along with its entity too + device_registry.async_remove_device(device_entry_2.id) await hass.async_block_till_done() assert not device_registry.async_get(device_entry_2.id) assert not entity_registry.async_is_registered(entry_2.entity_id) -async def test_remove_config_entry_from_device_removes_entities_2( +async def test_remove_device_keeps_other_config_entry_entities( hass: HomeAssistant, device_registry: dr.DeviceRegistry, entity_registry: er.EntityRegistry, ) -> None: - """Test we don't remove entities not tied to the removed config entry.""" + """Test removing a device keeps entities not owned by its config entry.""" config_entry_1 = MockConfigEntry(domain="hue") config_entry_1.add_to_hass(hass) config_entry_2 = MockConfigEntry(domain="some_helper") @@ -3335,14 +3331,12 @@ async def test_remove_config_entry_from_device_removes_entities_2( assert entity_registry.async_is_registered(entry_1.entity_id) assert entity_registry.async_is_registered(entry_2.entity_id) - # Removing the device's config entry removes the device - device_registry.async_update_device( - device_entry.id, remove_config_entry_id=config_entry_1.entry_id - ) + # Removing the device + device_registry.async_remove_device(device_entry.id) await hass.async_block_till_done() assert not device_registry.async_get(device_entry.id) - # Entities not tied to the removed config entry are kept, but detached + # Entities not owned by the removed device's config entry are kept, but detached assert entity_registry.async_is_registered(entry_1.entity_id) assert entity_registry.async_is_registered(entry_2.entity_id) assert entity_registry.async_get(entry_1.entity_id).device_id is None @@ -3449,12 +3443,12 @@ async def test_move_device_config_subentry_removes_old_subentry_entities( assert entity_registry.async_is_registered(sub2_entity.entity_id) -async def test_remove_config_subentry_from_device_removes_entities( +async def test_remove_device_removes_config_subentry_entities( hass: HomeAssistant, device_registry: dr.DeviceRegistry, entity_registry: er.EntityRegistry, ) -> None: - """Test that we remove entities tied to a device when its config subentry is removed.""" + """Test removing a device removes the entities tied to its config subentry.""" config_entry_1 = MockConfigEntry( domain="hue", subentries_data=[ @@ -3505,13 +3499,9 @@ async def test_remove_config_subentry_from_device_removes_entities( assert entity_registry.async_is_registered(entry_1.entity_id) assert entity_registry.async_is_registered(entry_2.entity_id) - # Removing the device's config subentry deletes the device; the entity tied to that - # subentry is removed, the entity tied to another subentry is detached - device_registry.async_update_device( - device_entry.id, - remove_config_entry_id=config_entry_1.entry_id, - remove_config_subentry_id="mock-subentry-id-1", - ) + # Removing the device removes the entity tied to the device's subentry, and detaches + # the entity tied to another subentry of the same config entry + device_registry.async_remove_device(device_entry.id) await hass.async_block_till_done() assert not device_registry.async_get(device_entry.id) @@ -3520,12 +3510,12 @@ async def test_remove_config_subentry_from_device_removes_entities( assert entity_registry.async_get(entry_2.entity_id).device_id is None -async def test_remove_config_subentry_from_device_removes_entities_2( +async def test_remove_device_keeps_other_config_subentry_entities( hass: HomeAssistant, device_registry: dr.DeviceRegistry, entity_registry: er.EntityRegistry, ) -> None: - """Test we don't remove entities not tied to the removed config subentry.""" + """Test removing a device keeps entities not tied to its config subentry.""" config_entry_1 = MockConfigEntry( domain="hue", subentries_data=[ @@ -3572,13 +3562,9 @@ async def test_remove_config_subentry_from_device_removes_entities_2( assert entity_registry.async_is_registered(entry_1.entity_id) assert entity_registry.async_is_registered(entry_2.entity_id) - # Removing the device's config subentry deletes the device; entities not tied to - # that subentry are kept but detached - device_registry.async_update_device( - device_entry.id, - remove_config_entry_id=config_entry_1.entry_id, - remove_config_subentry_id="mock-subentry-id-1", - ) + # Removing the device keeps entities not owned by its config subentry (one with no + # config entry, one in another subentry) but detaches them + device_registry.async_remove_device(device_entry.id) await hass.async_block_till_done() assert not device_registry.async_get(device_entry.id)