diff --git a/homeassistant/components/ipp/__init__.py b/homeassistant/components/ipp/__init__.py index 5979caa37db..1258e1031b4 100644 --- a/homeassistant/components/ipp/__init__.py +++ b/homeassistant/components/ipp/__init__.py @@ -128,24 +128,20 @@ class IPPEntity(Entity): self, *, entry_id: str, + device_id: str, coordinator: IPPDataUpdateCoordinator, name: str, icon: str, enabled_default: bool = True, ) -> None: """Initialize the IPP entity.""" - self._device_id = None + self._device_id = device_id self._enabled_default = enabled_default self._entry_id = entry_id self._icon = icon self._name = name self.coordinator = coordinator - if coordinator.data.info.uuid is not None: - self._device_id = coordinator.data.info.uuid - elif coordinator.data.info.serial is not None: - self._device_id = coordinator.data.info.serial - @property def name(self) -> str: """Return the name of the entity.""" diff --git a/homeassistant/components/ipp/sensor.py b/homeassistant/components/ipp/sensor.py index 5c29be09d94..bbb051d3158 100644 --- a/homeassistant/components/ipp/sensor.py +++ b/homeassistant/components/ipp/sensor.py @@ -32,13 +32,21 @@ async def async_setup_entry( """Set up IPP sensor based on a config entry.""" coordinator: IPPDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] + # config flow sets this to either UUID, serial number or None + unique_id = entry.unique_id + + if unique_id is None: + unique_id = entry.entry_id + sensors = [] - sensors.append(IPPPrinterSensor(entry.entry_id, coordinator)) - sensors.append(IPPUptimeSensor(entry.entry_id, coordinator)) + sensors.append(IPPPrinterSensor(entry.entry_id, unique_id, coordinator)) + sensors.append(IPPUptimeSensor(entry.entry_id, unique_id, coordinator)) for marker_index in range(len(coordinator.data.markers)): - sensors.append(IPPMarkerSensor(entry.entry_id, coordinator, marker_index)) + sensors.append( + IPPMarkerSensor(entry.entry_id, unique_id, coordinator, marker_index) + ) async_add_entities(sensors, True) @@ -52,6 +60,7 @@ class IPPSensor(IPPEntity): coordinator: IPPDataUpdateCoordinator, enabled_default: bool = True, entry_id: str, + unique_id: str, icon: str, key: str, name: str, @@ -62,13 +71,12 @@ class IPPSensor(IPPEntity): self._key = key self._unique_id = None - if coordinator.data.info.uuid is not None: - self._unique_id = f"{coordinator.data.info.uuid}_{key}" - elif coordinator.data.info.serial is not None: - self._unique_id = f"{coordinator.data.info.serial}_{key}" + if unique_id is not None: + self._unique_id = f"{unique_id}_{key}" super().__init__( entry_id=entry_id, + device_id=unique_id, coordinator=coordinator, name=name, icon=icon, @@ -90,7 +98,11 @@ class IPPMarkerSensor(IPPSensor): """Defines an IPP marker sensor.""" def __init__( - self, entry_id: str, coordinator: IPPDataUpdateCoordinator, marker_index: int + self, + entry_id: str, + unique_id: str, + coordinator: IPPDataUpdateCoordinator, + marker_index: int, ) -> None: """Initialize IPP marker sensor.""" self.marker_index = marker_index @@ -98,6 +110,7 @@ class IPPMarkerSensor(IPPSensor): super().__init__( coordinator=coordinator, entry_id=entry_id, + unique_id=unique_id, icon="mdi:water", key=f"marker_{marker_index}", name=f"{coordinator.data.info.name} {coordinator.data.markers[marker_index].name}", @@ -133,11 +146,14 @@ class IPPMarkerSensor(IPPSensor): class IPPPrinterSensor(IPPSensor): """Defines an IPP printer sensor.""" - def __init__(self, entry_id: str, coordinator: IPPDataUpdateCoordinator) -> None: + def __init__( + self, entry_id: str, unique_id: str, coordinator: IPPDataUpdateCoordinator + ) -> None: """Initialize IPP printer sensor.""" super().__init__( coordinator=coordinator, entry_id=entry_id, + unique_id=unique_id, icon="mdi:printer", key="printer", name=coordinator.data.info.name, @@ -166,12 +182,15 @@ class IPPPrinterSensor(IPPSensor): class IPPUptimeSensor(IPPSensor): """Defines a IPP uptime sensor.""" - def __init__(self, entry_id: str, coordinator: IPPDataUpdateCoordinator) -> None: + def __init__( + self, entry_id: str, unique_id: str, coordinator: IPPDataUpdateCoordinator + ) -> None: """Initialize IPP uptime sensor.""" super().__init__( coordinator=coordinator, enabled_default=False, entry_id=entry_id, + unique_id=unique_id, icon="mdi:clock-outline", key="uptime", name=f"{coordinator.data.info.name} Uptime", diff --git a/tests/components/ipp/__init__.py b/tests/components/ipp/__init__.py index a8c79324494..f0dc45417e1 100644 --- a/tests/components/ipp/__init__.py +++ b/tests/components/ipp/__init__.py @@ -62,7 +62,11 @@ def load_fixture_binary(filename): async def init_integration( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, skip_setup: bool = False, + hass: HomeAssistant, + aioclient_mock: AiohttpClientMocker, + skip_setup: bool = False, + uuid: str = "cfe92100-67c4-11d4-a45f-f8d027761251", + unique_id: str = "cfe92100-67c4-11d4-a45f-f8d027761251", ) -> MockConfigEntry: """Set up the IPP integration in Home Assistant.""" fixture = "ipp/get-printer-attributes.bin" @@ -74,14 +78,14 @@ async def init_integration( entry = MockConfigEntry( domain=DOMAIN, - unique_id="cfe92100-67c4-11d4-a45f-f8d027761251", + unique_id=unique_id, data={ CONF_HOST: "192.168.1.31", CONF_PORT: 631, CONF_SSL: False, CONF_VERIFY_SSL: True, CONF_BASE_PATH: "/ipp/print", - CONF_UUID: "cfe92100-67c4-11d4-a45f-f8d027761251", + CONF_UUID: uuid, }, ) diff --git a/tests/components/ipp/test_sensor.py b/tests/components/ipp/test_sensor.py index b7db606d870..e6830f559c6 100644 --- a/tests/components/ipp/test_sensor.py +++ b/tests/components/ipp/test_sensor.py @@ -94,3 +94,15 @@ async def test_disabled_by_default_sensors( assert entry assert entry.disabled assert entry.disabled_by == "integration" + + +async def test_missing_entry_unique_id( + hass: HomeAssistant, aioclient_mock: AiohttpClientMocker +) -> None: + """Test the unique_id of IPP sensor when printer is missing identifiers.""" + entry = await init_integration(hass, aioclient_mock, uuid=None, unique_id=None) + registry = await hass.helpers.entity_registry.async_get_registry() + + entity = registry.async_get("sensor.epson_xp_6000_series") + assert entity + assert entity.unique_id == f"{entry.entry_id}_printer"