Add media position & seek to Russound RIO (#134372)

pull/135846/head
Noah Husby 2025-01-17 06:03:52 -05:00 committed by GitHub
parent 99d250f222
commit 13a7ad759c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 44 additions and 0 deletions

View File

@ -2,6 +2,7 @@
from __future__ import annotations
import datetime as dt
import logging
from typing import TYPE_CHECKING
@ -57,6 +58,7 @@ class RussoundZoneDevice(RussoundBaseEntity, MediaPlayerEntity):
| MediaPlayerEntityFeature.TURN_ON
| MediaPlayerEntityFeature.TURN_OFF
| MediaPlayerEntityFeature.SELECT_SOURCE
| MediaPlayerEntityFeature.SEEK
)
def __init__(
@ -138,6 +140,21 @@ class RussoundZoneDevice(RussoundBaseEntity, MediaPlayerEntity):
"""Image url of current playing media."""
return self._source.cover_art_url
@property
def media_duration(self) -> int | None:
"""Duration of the current media."""
return self._source.track_time
@property
def media_position(self) -> int | None:
"""Position of the current media."""
return self._source.play_time
@property
def media_position_updated_at(self) -> dt.datetime:
"""Last time the media position was updated."""
return self._source.position_last_updated
@property
def volume_level(self) -> float:
"""Volume level of the media player (0..1).
@ -199,3 +216,8 @@ class RussoundZoneDevice(RussoundBaseEntity, MediaPlayerEntity):
if mute != self.is_volume_muted:
await self._zone.toggle_mute()
@command
async def async_media_seek(self, position: float) -> None:
"""Seek to a position in the current media."""
await self._zone.set_seek_time(int(position))

View File

@ -78,6 +78,7 @@ def mock_russound_client() -> Generator[AsyncMock]:
zone.mute = AsyncMock()
zone.unmute = AsyncMock()
zone.toggle_mute = AsyncMock()
zone.set_seek_time = AsyncMock()
client.controllers = {
1: Controller(

View File

@ -9,6 +9,7 @@ import pytest
from homeassistant.components.media_player import (
ATTR_INPUT_SOURCE,
ATTR_MEDIA_SEEK_POSITION,
ATTR_MEDIA_VOLUME_LEVEL,
ATTR_MEDIA_VOLUME_MUTED,
DOMAIN as MP_DOMAIN,
@ -16,6 +17,7 @@ from homeassistant.components.media_player import (
)
from homeassistant.const import (
ATTR_ENTITY_ID,
SERVICE_MEDIA_SEEK,
SERVICE_TURN_OFF,
SERVICE_TURN_ON,
SERVICE_VOLUME_DOWN,
@ -232,3 +234,22 @@ async def test_power_service(
await hass.services.async_call(MP_DOMAIN, SERVICE_TURN_OFF, data, blocking=True)
mock_russound_client.controllers[1].zones[1].zone_off.assert_called_once()
async def test_media_seek(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_russound_client: AsyncMock,
) -> None:
"""Test media seek service."""
await setup_integration(hass, mock_config_entry)
await hass.services.async_call(
MP_DOMAIN,
SERVICE_MEDIA_SEEK,
{ATTR_ENTITY_ID: ENTITY_ID_ZONE_1, ATTR_MEDIA_SEEK_POSITION: 100},
)
mock_russound_client.controllers[1].zones[1].set_seek_time.assert_called_once_with(
100
)