Add media position & seek to Russound RIO (#134372)
parent
99d250f222
commit
13a7ad759c
|
@ -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))
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue