parent
3a5309e9a0
commit
8d239d368b
|
@ -3,7 +3,7 @@
|
|||
import asyncio
|
||||
import logging
|
||||
|
||||
from aiorussound import Russound
|
||||
from aiorussound import RussoundClient, RussoundTcpConnectionHandler
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_HOST, CONF_PORT, Platform
|
||||
|
@ -16,7 +16,7 @@ PLATFORMS = [Platform.MEDIA_PLAYER]
|
|||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
type RussoundConfigEntry = ConfigEntry[Russound]
|
||||
type RussoundConfigEntry = ConfigEntry[RussoundClient]
|
||||
|
||||
|
||||
async def async_setup_entry(hass: HomeAssistant, entry: RussoundConfigEntry) -> bool:
|
||||
|
@ -24,7 +24,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: RussoundConfigEntry) ->
|
|||
|
||||
host = entry.data[CONF_HOST]
|
||||
port = entry.data[CONF_PORT]
|
||||
russ = Russound(hass.loop, host, port)
|
||||
russ = RussoundClient(RussoundTcpConnectionHandler(hass.loop, host, port))
|
||||
|
||||
@callback
|
||||
def is_connected_updated(connected: bool) -> None:
|
||||
|
@ -37,14 +37,12 @@ async def async_setup_entry(hass: HomeAssistant, entry: RussoundConfigEntry) ->
|
|||
port,
|
||||
)
|
||||
|
||||
russ.add_connection_callback(is_connected_updated)
|
||||
|
||||
russ.connection_handler.add_connection_callback(is_connected_updated)
|
||||
try:
|
||||
async with asyncio.timeout(CONNECT_TIMEOUT):
|
||||
await russ.connect()
|
||||
except RUSSOUND_RIO_EXCEPTIONS as err:
|
||||
raise ConfigEntryNotReady(f"Error while connecting to {host}:{port}") from err
|
||||
|
||||
entry.runtime_data = russ
|
||||
|
||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||
|
|
|
@ -6,7 +6,7 @@ import asyncio
|
|||
import logging
|
||||
from typing import Any
|
||||
|
||||
from aiorussound import Controller, Russound
|
||||
from aiorussound import Controller, RussoundClient, RussoundTcpConnectionHandler
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
|
||||
|
@ -54,8 +54,9 @@ class FlowHandler(ConfigFlow, domain=DOMAIN):
|
|||
host = user_input[CONF_HOST]
|
||||
port = user_input[CONF_PORT]
|
||||
|
||||
controllers = None
|
||||
russ = Russound(self.hass.loop, host, port)
|
||||
russ = RussoundClient(
|
||||
RussoundTcpConnectionHandler(self.hass.loop, host, port)
|
||||
)
|
||||
try:
|
||||
async with asyncio.timeout(CONNECT_TIMEOUT):
|
||||
await russ.connect()
|
||||
|
@ -87,7 +88,7 @@ class FlowHandler(ConfigFlow, domain=DOMAIN):
|
|||
port = import_data.get(CONF_PORT, 9621)
|
||||
|
||||
# Connection logic is repeated here since this method will be removed in future releases
|
||||
russ = Russound(self.hass.loop, host, port)
|
||||
russ = RussoundClient(RussoundTcpConnectionHandler(self.hass.loop, host, port))
|
||||
try:
|
||||
async with asyncio.timeout(CONNECT_TIMEOUT):
|
||||
await russ.connect()
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import asyncio
|
||||
|
||||
from aiorussound import CommandException
|
||||
from aiorussound import CommandError
|
||||
from aiorussound.const import FeatureFlag
|
||||
|
||||
from homeassistant.components.media_player import MediaPlayerEntityFeature
|
||||
|
@ -10,7 +10,7 @@ from homeassistant.components.media_player import MediaPlayerEntityFeature
|
|||
DOMAIN = "russound_rio"
|
||||
|
||||
RUSSOUND_RIO_EXCEPTIONS = (
|
||||
CommandException,
|
||||
CommandError,
|
||||
ConnectionRefusedError,
|
||||
TimeoutError,
|
||||
asyncio.CancelledError,
|
||||
|
|
|
@ -4,7 +4,7 @@ from collections.abc import Awaitable, Callable, Coroutine
|
|||
from functools import wraps
|
||||
from typing import Any, Concatenate
|
||||
|
||||
from aiorussound import Controller
|
||||
from aiorussound import Controller, RussoundTcpConnectionHandler
|
||||
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
|
@ -53,7 +53,6 @@ class RussoundBaseEntity(Entity):
|
|||
or f"{self._primary_mac_address}-{self._controller.controller_id}"
|
||||
)
|
||||
self._attr_device_info = DeviceInfo(
|
||||
configuration_url=f"http://{self._instance.host}",
|
||||
# Use MAC address of Russound device as identifier
|
||||
identifiers={(DOMAIN, self._device_identifier)},
|
||||
manufacturer="Russound",
|
||||
|
@ -61,6 +60,10 @@ class RussoundBaseEntity(Entity):
|
|||
model=controller.controller_type,
|
||||
sw_version=controller.firmware_version,
|
||||
)
|
||||
if isinstance(self._instance.connection_handler, RussoundTcpConnectionHandler):
|
||||
self._attr_device_info["configuration_url"] = (
|
||||
f"http://{self._instance.connection_handler.host}"
|
||||
)
|
||||
if controller.parent_controller:
|
||||
self._attr_device_info["via_device"] = (
|
||||
DOMAIN,
|
||||
|
@ -79,8 +82,12 @@ class RussoundBaseEntity(Entity):
|
|||
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Register callbacks."""
|
||||
self._instance.add_connection_callback(self._is_connected_updated)
|
||||
self._instance.connection_handler.add_connection_callback(
|
||||
self._is_connected_updated
|
||||
)
|
||||
|
||||
async def async_will_remove_from_hass(self) -> None:
|
||||
"""Remove callbacks."""
|
||||
self._instance.remove_connection_callback(self._is_connected_updated)
|
||||
self._instance.connection_handler.remove_connection_callback(
|
||||
self._is_connected_updated
|
||||
)
|
||||
|
|
|
@ -7,5 +7,5 @@
|
|||
"iot_class": "local_push",
|
||||
"loggers": ["aiorussound"],
|
||||
"quality_scale": "silver",
|
||||
"requirements": ["aiorussound==2.3.2"]
|
||||
"requirements": ["aiorussound==3.0.4"]
|
||||
}
|
||||
|
|
|
@ -84,14 +84,16 @@ async def async_setup_entry(
|
|||
"""Set up the Russound RIO platform."""
|
||||
russ = entry.runtime_data
|
||||
|
||||
await russ.init_sources()
|
||||
sources = russ.sources
|
||||
for source in sources.values():
|
||||
await source.watch()
|
||||
|
||||
# Discover controllers
|
||||
controllers = await russ.enumerate_controllers()
|
||||
|
||||
entities = []
|
||||
for controller in controllers.values():
|
||||
sources = controller.sources
|
||||
for source in sources.values():
|
||||
await source.watch()
|
||||
for zone in controller.zones.values():
|
||||
await zone.watch()
|
||||
mp = RussoundZoneDevice(zone, sources)
|
||||
|
@ -154,7 +156,7 @@ class RussoundZoneDevice(RussoundBaseEntity, MediaPlayerEntity):
|
|||
@property
|
||||
def state(self) -> MediaPlayerState | None:
|
||||
"""Return the state of the device."""
|
||||
status = self._zone.status
|
||||
status = self._zone.properties.status
|
||||
if status == "ON":
|
||||
return MediaPlayerState.ON
|
||||
if status == "OFF":
|
||||
|
@ -174,22 +176,22 @@ class RussoundZoneDevice(RussoundBaseEntity, MediaPlayerEntity):
|
|||
@property
|
||||
def media_title(self):
|
||||
"""Title of current playing media."""
|
||||
return self._current_source().song_name
|
||||
return self._current_source().properties.song_name
|
||||
|
||||
@property
|
||||
def media_artist(self):
|
||||
"""Artist of current playing media, music track only."""
|
||||
return self._current_source().artist_name
|
||||
return self._current_source().properties.artist_name
|
||||
|
||||
@property
|
||||
def media_album_name(self):
|
||||
"""Album name of current playing media, music track only."""
|
||||
return self._current_source().album_name
|
||||
return self._current_source().properties.album_name
|
||||
|
||||
@property
|
||||
def media_image_url(self):
|
||||
"""Image url of current playing media."""
|
||||
return self._current_source().cover_art_url
|
||||
return self._current_source().properties.cover_art_url
|
||||
|
||||
@property
|
||||
def volume_level(self):
|
||||
|
@ -198,7 +200,7 @@ class RussoundZoneDevice(RussoundBaseEntity, MediaPlayerEntity):
|
|||
Value is returned based on a range (0..50).
|
||||
Therefore float divide by 50 to get to the required range.
|
||||
"""
|
||||
return float(self._zone.volume or "0") / 50.0
|
||||
return float(self._zone.properties.volume or "0") / 50.0
|
||||
|
||||
@command
|
||||
async def async_turn_off(self) -> None:
|
||||
|
@ -214,7 +216,7 @@ class RussoundZoneDevice(RussoundBaseEntity, MediaPlayerEntity):
|
|||
async def async_set_volume_level(self, volume: float) -> None:
|
||||
"""Set the volume level."""
|
||||
rvol = int(volume * 50.0)
|
||||
await self._zone.set_volume(rvol)
|
||||
await self._zone.set_volume(str(rvol))
|
||||
|
||||
@command
|
||||
async def async_select_source(self, source: str) -> None:
|
||||
|
|
|
@ -350,7 +350,7 @@ aioridwell==2024.01.0
|
|||
aioruckus==0.41
|
||||
|
||||
# homeassistant.components.russound_rio
|
||||
aiorussound==2.3.2
|
||||
aiorussound==3.0.4
|
||||
|
||||
# homeassistant.components.ruuvi_gateway
|
||||
aioruuvigateway==0.1.0
|
||||
|
|
|
@ -332,7 +332,7 @@ aioridwell==2024.01.0
|
|||
aioruckus==0.41
|
||||
|
||||
# homeassistant.components.russound_rio
|
||||
aiorussound==2.3.2
|
||||
aiorussound==3.0.4
|
||||
|
||||
# homeassistant.components.ruuvi_gateway
|
||||
aioruuvigateway==0.1.0
|
||||
|
|
|
@ -37,10 +37,10 @@ def mock_russound() -> Generator[AsyncMock]:
|
|||
"""Mock the Russound RIO client."""
|
||||
with (
|
||||
patch(
|
||||
"homeassistant.components.russound_rio.Russound", autospec=True
|
||||
"homeassistant.components.russound_rio.RussoundClient", autospec=True
|
||||
) as mock_client,
|
||||
patch(
|
||||
"homeassistant.components.russound_rio.config_flow.Russound",
|
||||
"homeassistant.components.russound_rio.config_flow.RussoundClient",
|
||||
return_value=mock_client,
|
||||
),
|
||||
):
|
||||
|
|
Loading…
Reference in New Issue