Skip to content

Commit

Permalink
Merge pull request #40 from noahhusby/feat/output-select
Browse files Browse the repository at this point in the history
Add audio output selection
  • Loading branch information
noahhusby authored Oct 16, 2024
2 parents d0371a2 + bf6cafd commit f3edfc2
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 244 deletions.
1 change: 1 addition & 0 deletions aiostreammagic/endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@
PLAY_CONTROL = "/zone/play_control"
STREAM_RADIO = "/stream/radio"
POWER = "/system/power"
ZONE_AUDIO_OUTPUT = "/zone/audio/output"
18 changes: 18 additions & 0 deletions aiostreammagic/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ class State(DataClassORJSONMixin):
metadata=field_options(alias="volume_percent"), default=None
)
mute: bool = field(metadata=field_options(alias="mute"), default=False)
audio_output: str = field(
metadata=field_options(alias="audio_output"), default=None
)


@dataclass
Expand Down Expand Up @@ -105,6 +108,21 @@ class NowPlaying(DataClassORJSONMixin):
)


@dataclass
class AudioOutput(DataClassORJSONMixin):
"""Data class representing StreamMagic audio output."""

outputs: list[Output] = field(metadata=field_options(alias="outputs"), default=None)


@dataclass
class Output(DataClassORJSONMixin):
"""Data class representing StreamMagic output."""

id: str = field(metadata=field_options(alias="id"))
name: str = field(metadata=field_options(alias="name"))


class TransportControl(StrEnum):
"""Control enum."""

Expand Down
23 changes: 23 additions & 0 deletions aiostreammagic/stream_magic.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
ShuffleMode,
RepeatMode,
CallbackType,
AudioOutput,
)
from . import endpoints as ep
from .const import _LOGGER
Expand All @@ -45,6 +46,7 @@ def __init__(self, host):
self.state: State | None = None
self.play_state: PlayState | None = None
self.now_playing: NowPlaying | None = None
self.audio_output: AudioOutput | None = None
self._attempt_reconnection = False
self._reconnect_task: Optional[Task] = None
self.position_last_updated: datetime = datetime.now()
Expand Down Expand Up @@ -146,12 +148,14 @@ async def _connect_handler(self, res):
self.state,
self.play_state,
self.now_playing,
self.audio_output,
) = await asyncio.gather(
self.get_info(),
self.get_sources(),
self.get_state(),
self.get_play_state(),
self.get_now_playing(),
self.get_audio_output(),
)
subscribe_state_updates = {
self.subscribe(self._async_handle_info, ep.INFO),
Expand All @@ -160,6 +164,7 @@ async def _connect_handler(self, res):
self.subscribe(self._async_handle_play_state, ep.PLAY_STATE),
self.subscribe(self._async_handle_position, ep.POSITION),
self.subscribe(self._async_handle_now_playing, ep.NOW_PLAYING),
self.subscribe(self._async_handle_audio_output, ep.ZONE_AUDIO_OUTPUT),
}
subscribe_tasks = set()
for state_update in subscribe_state_updates:
Expand Down Expand Up @@ -295,6 +300,11 @@ async def get_now_playing(self) -> NowPlaying:
data = await self.request(ep.NOW_PLAYING)
return NowPlaying.from_dict(data["params"]["data"])

async def get_audio_output(self) -> AudioOutput:
"""Get audio output information from device."""
data = await self.request(ep.ZONE_AUDIO_OUTPUT)
return AudioOutput.from_dict(data["params"]["data"])

async def _async_handle_info(self, payload) -> None:
"""Handle async info update."""
params = payload["params"]
Expand Down Expand Up @@ -339,6 +349,13 @@ async def _async_handle_now_playing(self, payload) -> None:
self.now_playing = NowPlaying.from_dict(params["data"])
await self.do_state_update_callbacks()

async def _async_handle_audio_output(self, payload) -> None:
"""Handle async audio output update."""
params = payload["params"]
if "data" in params:
self.audio_output = AudioOutput.from_dict(params["data"])
await self.do_state_update_callbacks()

async def power_on(self) -> None:
"""Set the power of the device to on."""
await self.request(ep.POWER, params={"power": "ON"})
Expand Down Expand Up @@ -454,3 +471,9 @@ async def play_radio_url(self, name: str, url: str) -> None:
await self.request(
ep.STREAM_RADIO, params={"zone": "ZONE1", "url": url, "name": name}
)

async def set_audio_output(self, output_id: str) -> None:
"""Set the audio output of the device."""
await self.request(
ep.ZONE_AUDIO_OUTPUT, params={"zone": "ZONE1", "id": output_id}
)
Loading

0 comments on commit f3edfc2

Please sign in to comment.