mirror of
https://github.com/home-assistant/core.git
synced 2025-04-26 10:17:51 +00:00
Fix HEOS device information (#135940)
This commit is contained in:
parent
b17c36eeff
commit
439f22f584
@ -81,6 +81,18 @@ async def async_setup_entry(hass: HomeAssistant, entry: HeosConfigEntry) -> bool
|
|||||||
if entry.unique_id is None:
|
if entry.unique_id is None:
|
||||||
hass.config_entries.async_update_entry(entry, unique_id=DOMAIN)
|
hass.config_entries.async_update_entry(entry, unique_id=DOMAIN)
|
||||||
|
|
||||||
|
# Migrate non-string device identifiers.
|
||||||
|
device_registry = dr.async_get(hass)
|
||||||
|
for device in device_registry.devices.get_devices_for_config_entry_id(
|
||||||
|
entry.entry_id
|
||||||
|
):
|
||||||
|
for domain, player_id in device.identifiers:
|
||||||
|
if domain == DOMAIN and not isinstance(player_id, str):
|
||||||
|
device_registry.async_update_device(
|
||||||
|
device.id, new_identifiers={(DOMAIN, str(player_id))}
|
||||||
|
)
|
||||||
|
break
|
||||||
|
|
||||||
host = entry.data[CONF_HOST]
|
host = entry.data[CONF_HOST]
|
||||||
credentials: Credentials | None = None
|
credentials: Credentials | None = None
|
||||||
if entry.options:
|
if entry.options:
|
||||||
@ -221,13 +233,13 @@ class ControllerManager:
|
|||||||
# update device registry
|
# update device registry
|
||||||
assert self._device_registry is not None
|
assert self._device_registry is not None
|
||||||
entry = self._device_registry.async_get_device(
|
entry = self._device_registry.async_get_device(
|
||||||
identifiers={(DOMAIN, old_id)} # type: ignore[arg-type] # Fix in the future
|
identifiers={(DOMAIN, str(old_id))}
|
||||||
)
|
)
|
||||||
new_identifiers = {(DOMAIN, new_id)}
|
new_identifiers = {(DOMAIN, str(new_id))}
|
||||||
if entry:
|
if entry:
|
||||||
self._device_registry.async_update_device(
|
self._device_registry.async_update_device(
|
||||||
entry.id,
|
entry.id,
|
||||||
new_identifiers=new_identifiers, # type: ignore[arg-type] # Fix in the future
|
new_identifiers=new_identifiers,
|
||||||
)
|
)
|
||||||
_LOGGER.debug(
|
_LOGGER.debug(
|
||||||
"Updated device %s identifiers to %s", entry.id, new_identifiers
|
"Updated device %s identifiers to %s", entry.id, new_identifiers
|
||||||
|
@ -136,11 +136,15 @@ class HeosMediaPlayer(MediaPlayerEntity):
|
|||||||
self._source_manager = source_manager
|
self._source_manager = source_manager
|
||||||
self._group_manager = group_manager
|
self._group_manager = group_manager
|
||||||
self._attr_unique_id = str(player.player_id)
|
self._attr_unique_id = str(player.player_id)
|
||||||
|
model_parts = player.model.split(maxsplit=1)
|
||||||
|
manufacturer = model_parts[0] if len(model_parts) == 2 else "HEOS"
|
||||||
|
model = model_parts[1] if len(model_parts) == 2 else player.model
|
||||||
self._attr_device_info = DeviceInfo(
|
self._attr_device_info = DeviceInfo(
|
||||||
identifiers={(HEOS_DOMAIN, player.player_id)},
|
identifiers={(HEOS_DOMAIN, str(player.player_id))},
|
||||||
manufacturer="HEOS",
|
manufacturer=manufacturer,
|
||||||
model=player.model,
|
model=model,
|
||||||
name=player.name,
|
name=player.name,
|
||||||
|
serial_number=player.serial, # Only available for some models
|
||||||
sw_version=player.version,
|
sw_version=player.version,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -50,11 +50,7 @@ rules:
|
|||||||
4. Recommend using snapshot in test_state_attributes.
|
4. Recommend using snapshot in test_state_attributes.
|
||||||
5. Find a way to avoid using internal dispatcher in test_updates_from_connection_event.
|
5. Find a way to avoid using internal dispatcher in test_updates_from_connection_event.
|
||||||
# Gold
|
# Gold
|
||||||
devices:
|
devices: done
|
||||||
status: todo
|
|
||||||
comment: |
|
|
||||||
The integraiton creates devices, but needs to stringify the id for the device identifier and
|
|
||||||
also migrate the device.
|
|
||||||
diagnostics: todo
|
diagnostics: todo
|
||||||
discovery-update-info:
|
discovery-update-info:
|
||||||
status: todo
|
status: todo
|
||||||
|
@ -125,8 +125,8 @@ def player_fixture(quick_selects):
|
|||||||
player = HeosPlayer(
|
player = HeosPlayer(
|
||||||
player_id=i,
|
player_id=i,
|
||||||
name="Test Player" if i == 1 else f"Test Player {i}",
|
name="Test Player" if i == 1 else f"Test Player {i}",
|
||||||
model="Test Model",
|
model="HEOS Drive HS2" if i == 1 else "Speaker",
|
||||||
serial="",
|
serial="123456",
|
||||||
version="1.0.0",
|
version="1.0.0",
|
||||||
line_out=LineOutLevelType.VARIABLE,
|
line_out=LineOutLevelType.VARIABLE,
|
||||||
is_muted=False,
|
is_muted=False,
|
||||||
|
@ -19,6 +19,7 @@ from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntryState
|
|||||||
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME
|
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.exceptions import ConfigEntryNotReady
|
from homeassistant.exceptions import ConfigEntryNotReady
|
||||||
|
from homeassistant.helpers import device_registry as dr
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
from tests.common import MockConfigEntry
|
||||||
@ -217,3 +218,42 @@ async def test_update_sources_retry(
|
|||||||
while "Unable to update sources" not in caplog.text:
|
while "Unable to update sources" not in caplog.text:
|
||||||
await asyncio.sleep(0.1)
|
await asyncio.sleep(0.1)
|
||||||
assert controller.get_favorites.call_count == 2
|
assert controller.get_favorites.call_count == 2
|
||||||
|
|
||||||
|
|
||||||
|
async def test_device_info(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
device_registry: dr.DeviceRegistry,
|
||||||
|
config_entry: MockConfigEntry,
|
||||||
|
) -> None:
|
||||||
|
"""Test device information populates correctly."""
|
||||||
|
config_entry.add_to_hass(hass)
|
||||||
|
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||||
|
device = device_registry.async_get_device({(DOMAIN, "1")})
|
||||||
|
assert device.manufacturer == "HEOS"
|
||||||
|
assert device.model == "Drive HS2"
|
||||||
|
assert device.name == "Test Player"
|
||||||
|
assert device.serial_number == "123456"
|
||||||
|
assert device.sw_version == "1.0.0"
|
||||||
|
device = device_registry.async_get_device({(DOMAIN, "2")})
|
||||||
|
assert device.manufacturer == "HEOS"
|
||||||
|
assert device.model == "Speaker"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_device_id_migration(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
device_registry: dr.DeviceRegistry,
|
||||||
|
config_entry: MockConfigEntry,
|
||||||
|
) -> None:
|
||||||
|
"""Test that legacy non-string device identifiers are migrated to strings."""
|
||||||
|
config_entry.add_to_hass(hass)
|
||||||
|
# Create a device with a legacy identifier
|
||||||
|
device_registry.async_get_or_create(
|
||||||
|
config_entry_id=config_entry.entry_id, identifiers={(DOMAIN, 1)}
|
||||||
|
)
|
||||||
|
device_registry.async_get_or_create(
|
||||||
|
config_entry_id=config_entry.entry_id, identifiers={("Other", 1)}
|
||||||
|
)
|
||||||
|
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||||
|
assert device_registry.async_get_device({("Other", 1)}) is not None
|
||||||
|
assert device_registry.async_get_device({(DOMAIN, 1)}) is None
|
||||||
|
assert device_registry.async_get_device({(DOMAIN, "1")}) is not None
|
||||||
|
@ -271,7 +271,7 @@ async def test_updates_from_players_changed_new_ids(
|
|||||||
event = asyncio.Event()
|
event = asyncio.Event()
|
||||||
|
|
||||||
# Assert device registry matches current id
|
# Assert device registry matches current id
|
||||||
assert device_registry.async_get_device(identifiers={(DOMAIN, 1)})
|
assert device_registry.async_get_device(identifiers={(DOMAIN, "1")})
|
||||||
# Assert entity registry matches current id
|
# Assert entity registry matches current id
|
||||||
assert (
|
assert (
|
||||||
entity_registry.async_get_entity_id(MEDIA_PLAYER_DOMAIN, DOMAIN, "1")
|
entity_registry.async_get_entity_id(MEDIA_PLAYER_DOMAIN, DOMAIN, "1")
|
||||||
@ -292,7 +292,7 @@ async def test_updates_from_players_changed_new_ids(
|
|||||||
|
|
||||||
# Assert device registry identifiers were updated
|
# Assert device registry identifiers were updated
|
||||||
assert len(device_registry.devices) == 2
|
assert len(device_registry.devices) == 2
|
||||||
assert device_registry.async_get_device(identifiers={(DOMAIN, 101)})
|
assert device_registry.async_get_device(identifiers={(DOMAIN, "101")})
|
||||||
# Assert entity registry unique id was updated
|
# Assert entity registry unique id was updated
|
||||||
assert len(entity_registry.entities) == 2
|
assert len(entity_registry.entities) == 2
|
||||||
assert (
|
assert (
|
||||||
|
Loading…
x
Reference in New Issue
Block a user