mirror of
https://github.com/home-assistant/core.git
synced 2025-07-18 18:57:06 +00:00
Add sub-device support to Russound RIO (#146763)
This commit is contained in:
parent
e28965770e
commit
1b73acc025
@ -9,6 +9,8 @@ from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_HOST, CONF_PORT, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import ConfigEntryNotReady
|
||||
from homeassistant.helpers import device_registry as dr
|
||||
from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC
|
||||
|
||||
from .const import DOMAIN, RUSSOUND_RIO_EXCEPTIONS
|
||||
|
||||
@ -52,6 +54,39 @@ async def async_setup_entry(hass: HomeAssistant, entry: RussoundConfigEntry) ->
|
||||
) from err
|
||||
entry.runtime_data = client
|
||||
|
||||
device_registry = dr.async_get(hass)
|
||||
|
||||
for controller_id, controller in client.controllers.items():
|
||||
_device_identifier = (
|
||||
controller.mac_address
|
||||
or f"{client.controllers[1].mac_address}-{controller_id}"
|
||||
)
|
||||
connections = None
|
||||
via_device = None
|
||||
configuration_url = None
|
||||
if controller_id != 1:
|
||||
assert client.controllers[1].mac_address
|
||||
via_device = (
|
||||
DOMAIN,
|
||||
client.controllers[1].mac_address,
|
||||
)
|
||||
else:
|
||||
assert controller.mac_address
|
||||
connections = {(CONNECTION_NETWORK_MAC, controller.mac_address)}
|
||||
if isinstance(client.connection_handler, RussoundTcpConnectionHandler):
|
||||
configuration_url = f"http://{client.connection_handler.host}"
|
||||
device_registry.async_get_or_create(
|
||||
config_entry_id=entry.entry_id,
|
||||
identifiers={(DOMAIN, _device_identifier)},
|
||||
manufacturer="Russound",
|
||||
name=controller.controller_type,
|
||||
model=controller.controller_type,
|
||||
sw_version=controller.firmware_version,
|
||||
connections=connections,
|
||||
via_device=via_device,
|
||||
configuration_url=configuration_url,
|
||||
)
|
||||
|
||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||
|
||||
return True
|
||||
|
@ -4,11 +4,11 @@ from collections.abc import Awaitable, Callable, Coroutine
|
||||
from functools import wraps
|
||||
from typing import Any, Concatenate
|
||||
|
||||
from aiorussound import Controller, RussoundClient, RussoundTcpConnectionHandler
|
||||
from aiorussound import Controller, RussoundClient
|
||||
from aiorussound.models import CallbackType
|
||||
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC, DeviceInfo
|
||||
from homeassistant.helpers.device_registry import DeviceInfo
|
||||
from homeassistant.helpers.entity import Entity
|
||||
|
||||
from .const import DOMAIN, RUSSOUND_RIO_EXCEPTIONS
|
||||
@ -46,6 +46,7 @@ class RussoundBaseEntity(Entity):
|
||||
def __init__(
|
||||
self,
|
||||
controller: Controller,
|
||||
zone_id: int | None = None,
|
||||
) -> None:
|
||||
"""Initialize the entity."""
|
||||
self._client = controller.client
|
||||
@ -57,29 +58,21 @@ class RussoundBaseEntity(Entity):
|
||||
self._controller.mac_address
|
||||
or f"{self._primary_mac_address}-{self._controller.controller_id}"
|
||||
)
|
||||
if not zone_id:
|
||||
self._attr_device_info = DeviceInfo(
|
||||
identifiers={(DOMAIN, self._device_identifier)},
|
||||
)
|
||||
return
|
||||
zone = controller.zones[zone_id]
|
||||
self._attr_device_info = DeviceInfo(
|
||||
# Use MAC address of Russound device as identifier
|
||||
identifiers={(DOMAIN, self._device_identifier)},
|
||||
identifiers={(DOMAIN, f"{self._device_identifier}-{zone_id}")},
|
||||
name=zone.name,
|
||||
manufacturer="Russound",
|
||||
name=controller.controller_type,
|
||||
model=controller.controller_type,
|
||||
sw_version=controller.firmware_version,
|
||||
suggested_area=zone.name,
|
||||
via_device=(DOMAIN, self._device_identifier),
|
||||
)
|
||||
if isinstance(self._client.connection_handler, RussoundTcpConnectionHandler):
|
||||
self._attr_device_info["configuration_url"] = (
|
||||
f"http://{self._client.connection_handler.host}"
|
||||
)
|
||||
if controller.controller_id != 1:
|
||||
assert self._client.controllers[1].mac_address
|
||||
self._attr_device_info["via_device"] = (
|
||||
DOMAIN,
|
||||
self._client.controllers[1].mac_address,
|
||||
)
|
||||
else:
|
||||
assert controller.mac_address
|
||||
self._attr_device_info["connections"] = {
|
||||
(CONNECTION_NETWORK_MAC, controller.mac_address)
|
||||
}
|
||||
|
||||
async def _state_update_callback(
|
||||
self, _client: RussoundClient, _callback_type: CallbackType
|
||||
|
@ -60,16 +60,16 @@ class RussoundZoneDevice(RussoundBaseEntity, MediaPlayerEntity):
|
||||
| MediaPlayerEntityFeature.SELECT_SOURCE
|
||||
| MediaPlayerEntityFeature.SEEK
|
||||
)
|
||||
_attr_name = None
|
||||
|
||||
def __init__(
|
||||
self, controller: Controller, zone_id: int, sources: dict[int, Source]
|
||||
) -> None:
|
||||
"""Initialize the zone device."""
|
||||
super().__init__(controller)
|
||||
super().__init__(controller, zone_id)
|
||||
self._zone_id = zone_id
|
||||
_zone = self._zone
|
||||
self._sources = sources
|
||||
self._attr_name = _zone.name
|
||||
self._attr_unique_id = f"{self._primary_mac_address}-{_zone.device_str}"
|
||||
|
||||
@property
|
||||
|
@ -17,6 +17,5 @@ MOCK_RECONFIGURATION_CONFIG = {
|
||||
CONF_PORT: 9622,
|
||||
}
|
||||
|
||||
DEVICE_NAME = "mca_c5"
|
||||
NAME_ZONE_1 = "backyard"
|
||||
ENTITY_ID_ZONE_1 = f"{MP_DOMAIN}.{DEVICE_NAME}_{NAME_ZONE_1}"
|
||||
ENTITY_ID_ZONE_1 = f"{MP_DOMAIN}.{NAME_ZONE_1}"
|
||||
|
@ -207,7 +207,7 @@ async def test_invalid_source_service(
|
||||
|
||||
with pytest.raises(
|
||||
HomeAssistantError,
|
||||
match="Error executing async_select_source on entity media_player.mca_c5_backyard",
|
||||
match="Error executing async_select_source on entity media_player.backyard",
|
||||
):
|
||||
await hass.services.async_call(
|
||||
MP_DOMAIN,
|
||||
|
Loading…
x
Reference in New Issue
Block a user