mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 20:57:21 +00:00
Require device id for Roku entities (#98734)
This commit is contained in:
parent
0f2b8570d2
commit
2e0038b981
@ -22,7 +22,12 @@ PLATFORMS = [
|
|||||||
|
|
||||||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
"""Set up Roku from a config entry."""
|
"""Set up Roku from a config entry."""
|
||||||
coordinator = RokuDataUpdateCoordinator(hass, host=entry.data[CONF_HOST])
|
if (device_id := entry.unique_id) is None:
|
||||||
|
device_id = entry.entry_id
|
||||||
|
|
||||||
|
coordinator = RokuDataUpdateCoordinator(
|
||||||
|
hass, host=entry.data[CONF_HOST], device_id=device_id
|
||||||
|
)
|
||||||
await coordinator.async_config_entry_first_refresh()
|
await coordinator.async_config_entry_first_refresh()
|
||||||
|
|
||||||
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinator
|
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinator
|
||||||
|
@ -71,10 +71,9 @@ async def async_setup_entry(
|
|||||||
) -> None:
|
) -> None:
|
||||||
"""Set up a Roku binary sensors based on a config entry."""
|
"""Set up a Roku binary sensors based on a config entry."""
|
||||||
coordinator = hass.data[DOMAIN][entry.entry_id]
|
coordinator = hass.data[DOMAIN][entry.entry_id]
|
||||||
unique_id = coordinator.data.info.serial_number
|
|
||||||
async_add_entities(
|
async_add_entities(
|
||||||
RokuBinarySensorEntity(
|
RokuBinarySensorEntity(
|
||||||
device_id=unique_id,
|
|
||||||
coordinator=coordinator,
|
coordinator=coordinator,
|
||||||
description=description,
|
description=description,
|
||||||
)
|
)
|
||||||
|
@ -32,8 +32,10 @@ class RokuDataUpdateCoordinator(DataUpdateCoordinator[Device]):
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
*,
|
*,
|
||||||
host: str,
|
host: str,
|
||||||
|
device_id: str,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize global Roku data updater."""
|
"""Initialize global Roku data updater."""
|
||||||
|
self.device_id = device_id
|
||||||
self.roku = Roku(host=host, session=async_get_clientsession(hass))
|
self.roku = Roku(host=host, session=async_get_clientsession(hass))
|
||||||
|
|
||||||
self.full_update_interval = timedelta(minutes=15)
|
self.full_update_interval = timedelta(minutes=15)
|
||||||
|
@ -12,45 +12,37 @@ from .const import DOMAIN
|
|||||||
class RokuEntity(CoordinatorEntity[RokuDataUpdateCoordinator]):
|
class RokuEntity(CoordinatorEntity[RokuDataUpdateCoordinator]):
|
||||||
"""Defines a base Roku entity."""
|
"""Defines a base Roku entity."""
|
||||||
|
|
||||||
|
_attr_has_entity_name = True
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
device_id: str | None,
|
|
||||||
coordinator: RokuDataUpdateCoordinator,
|
coordinator: RokuDataUpdateCoordinator,
|
||||||
description: EntityDescription | None = None,
|
description: EntityDescription | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize the Roku entity."""
|
"""Initialize the Roku entity."""
|
||||||
super().__init__(coordinator)
|
super().__init__(coordinator)
|
||||||
self._device_id = device_id
|
|
||||||
|
|
||||||
if description is not None:
|
if description is not None:
|
||||||
self.entity_description = description
|
self.entity_description = description
|
||||||
|
self._attr_unique_id = f"{coordinator.device_id}_{description.key}"
|
||||||
|
else:
|
||||||
|
self._attr_unique_id = coordinator.device_id
|
||||||
|
|
||||||
if device_id is None:
|
self._attr_device_info = DeviceInfo(
|
||||||
self._attr_name = f"{coordinator.data.info.name} {description.name}"
|
identifiers={(DOMAIN, coordinator.device_id)},
|
||||||
|
connections={
|
||||||
if device_id is not None:
|
(CONNECTION_NETWORK_MAC, mac_address)
|
||||||
self._attr_has_entity_name = True
|
for mac_address in (
|
||||||
|
self.coordinator.data.info.wifi_mac,
|
||||||
if description is not None:
|
self.coordinator.data.info.ethernet_mac,
|
||||||
self._attr_unique_id = f"{device_id}_{description.key}"
|
)
|
||||||
else:
|
if mac_address is not None
|
||||||
self._attr_unique_id = device_id
|
},
|
||||||
|
name=self.coordinator.data.info.name,
|
||||||
self._attr_device_info = DeviceInfo(
|
manufacturer=self.coordinator.data.info.brand,
|
||||||
identifiers={(DOMAIN, device_id)},
|
model=self.coordinator.data.info.model_name,
|
||||||
connections={
|
hw_version=self.coordinator.data.info.model_number,
|
||||||
(CONNECTION_NETWORK_MAC, mac_address)
|
sw_version=self.coordinator.data.info.version,
|
||||||
for mac_address in (
|
suggested_area=self.coordinator.data.info.device_location,
|
||||||
self.coordinator.data.info.wifi_mac,
|
)
|
||||||
self.coordinator.data.info.ethernet_mac,
|
|
||||||
)
|
|
||||||
if mac_address is not None
|
|
||||||
},
|
|
||||||
name=self.coordinator.data.info.name,
|
|
||||||
manufacturer=self.coordinator.data.info.brand,
|
|
||||||
model=self.coordinator.data.info.model_name,
|
|
||||||
hw_version=self.coordinator.data.info.model_number,
|
|
||||||
sw_version=self.coordinator.data.info.version,
|
|
||||||
suggested_area=self.coordinator.data.info.device_location,
|
|
||||||
)
|
|
||||||
|
@ -85,11 +85,10 @@ async def async_setup_entry(
|
|||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the Roku config entry."""
|
"""Set up the Roku config entry."""
|
||||||
coordinator: RokuDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
|
coordinator: RokuDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
|
||||||
unique_id = coordinator.data.info.serial_number
|
|
||||||
async_add_entities(
|
async_add_entities(
|
||||||
[
|
[
|
||||||
RokuMediaPlayer(
|
RokuMediaPlayer(
|
||||||
device_id=unique_id,
|
|
||||||
coordinator=coordinator,
|
coordinator=coordinator,
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
@ -22,11 +22,10 @@ async def async_setup_entry(
|
|||||||
) -> None:
|
) -> None:
|
||||||
"""Load Roku remote based on a config entry."""
|
"""Load Roku remote based on a config entry."""
|
||||||
coordinator: RokuDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
|
coordinator: RokuDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
|
||||||
unique_id = coordinator.data.info.serial_number
|
|
||||||
async_add_entities(
|
async_add_entities(
|
||||||
[
|
[
|
||||||
RokuRemote(
|
RokuRemote(
|
||||||
device_id=unique_id,
|
|
||||||
coordinator=coordinator,
|
coordinator=coordinator,
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
@ -122,14 +122,12 @@ async def async_setup_entry(
|
|||||||
"""Set up Roku select based on a config entry."""
|
"""Set up Roku select based on a config entry."""
|
||||||
coordinator: RokuDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
|
coordinator: RokuDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
|
||||||
device: RokuDevice = coordinator.data
|
device: RokuDevice = coordinator.data
|
||||||
unique_id = device.info.serial_number
|
|
||||||
|
|
||||||
entities: list[RokuSelectEntity] = []
|
entities: list[RokuSelectEntity] = []
|
||||||
|
|
||||||
for description in ENTITIES:
|
for description in ENTITIES:
|
||||||
entities.append(
|
entities.append(
|
||||||
RokuSelectEntity(
|
RokuSelectEntity(
|
||||||
device_id=unique_id,
|
|
||||||
coordinator=coordinator,
|
coordinator=coordinator,
|
||||||
description=description,
|
description=description,
|
||||||
)
|
)
|
||||||
@ -138,7 +136,6 @@ async def async_setup_entry(
|
|||||||
if len(device.channels) > 0:
|
if len(device.channels) > 0:
|
||||||
entities.append(
|
entities.append(
|
||||||
RokuSelectEntity(
|
RokuSelectEntity(
|
||||||
device_id=unique_id,
|
|
||||||
coordinator=coordinator,
|
coordinator=coordinator,
|
||||||
description=CHANNEL_ENTITY,
|
description=CHANNEL_ENTITY,
|
||||||
)
|
)
|
||||||
|
@ -56,10 +56,9 @@ async def async_setup_entry(
|
|||||||
) -> None:
|
) -> None:
|
||||||
"""Set up Roku sensor based on a config entry."""
|
"""Set up Roku sensor based on a config entry."""
|
||||||
coordinator: RokuDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
|
coordinator: RokuDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
|
||||||
unique_id = coordinator.data.info.serial_number
|
|
||||||
async_add_entities(
|
async_add_entities(
|
||||||
RokuSensorEntity(
|
RokuSensorEntity(
|
||||||
device_id=unique_id,
|
|
||||||
coordinator=coordinator,
|
coordinator=coordinator,
|
||||||
description=description,
|
description=description,
|
||||||
)
|
)
|
||||||
|
@ -81,9 +81,13 @@ def mock_roku(
|
|||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
async def init_integration(
|
async def init_integration(
|
||||||
hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_roku: MagicMock
|
hass: HomeAssistant,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
mock_device: RokuDevice,
|
||||||
|
mock_roku: MagicMock,
|
||||||
) -> MockConfigEntry:
|
) -> MockConfigEntry:
|
||||||
"""Set up the Roku integration for testing."""
|
"""Set up the Roku integration for testing."""
|
||||||
|
mock_config_entry.unique_id = mock_device.info.serial_number
|
||||||
mock_config_entry.add_to_hass(hass)
|
mock_config_entry.add_to_hass(hass)
|
||||||
|
|
||||||
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||||
|
@ -26,6 +26,25 @@ async def test_config_entry_not_ready(
|
|||||||
assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY
|
assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY
|
||||||
|
|
||||||
|
|
||||||
|
async def test_config_entry_no_unique_id(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
mock_roku: AsyncMock,
|
||||||
|
) -> None:
|
||||||
|
"""Test the Roku configuration entry with missing unique id."""
|
||||||
|
mock_config_entry.unique_id = None
|
||||||
|
mock_config_entry.add_to_hass(hass)
|
||||||
|
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert mock_config_entry.entry_id in hass.data[DOMAIN]
|
||||||
|
assert mock_config_entry.state is ConfigEntryState.LOADED
|
||||||
|
assert (
|
||||||
|
hass.data[DOMAIN][mock_config_entry.entry_id].device_id
|
||||||
|
== mock_config_entry.entry_id
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def test_load_unload_config_entry(
|
async def test_load_unload_config_entry(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
mock_config_entry: MockConfigEntry,
|
mock_config_entry: MockConfigEntry,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user