Skip to content

Commit

Permalink
Merge pull request #41 from noahhusby/feat/output-select
Browse files Browse the repository at this point in the history
Add update & display models
  • Loading branch information
noahhusby authored Oct 16, 2024
2 parents 9935f25 + d1f54fd commit e1c31c5
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 1 deletion.
1 change: 1 addition & 0 deletions aiostreammagic/endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@
STREAM_RADIO = "/stream/radio"
POWER = "/system/power"
ZONE_AUDIO_OUTPUT = "/zone/audio/output"
DISPLAY = "/system/display"
35 changes: 35 additions & 0 deletions aiostreammagic/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ class State(DataClassORJSONMixin):
audio_output: str = field(
metadata=field_options(alias="audio_output"), default=None
)
control_bus: ControlBusMode = field(
metadata=field_options(alias="cbus"), default="off"
)


@dataclass
Expand Down Expand Up @@ -123,6 +126,22 @@ class Output(DataClassORJSONMixin):
name: str = field(metadata=field_options(alias="name"))


@dataclass
class Display(DataClassORJSONMixin):
brightness: DisplayBrightness = field(metadata=field_options(alias="brightness"))


@dataclass
class Update(DataClassORJSONMixin):
early_update: bool = field(
metadata=field_options(alias="early_update"), default=False
)
update_available: bool = field(
metadata=field_options(alias="update_available"), default=False
)
updating: bool = field(metadata=field_options(alias="updating"), default=False)


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

Expand Down Expand Up @@ -158,3 +177,19 @@ class CallbackType(StrEnum):

STATE = "state"
CONNECTION = "connection"


class DisplayBrightness(StrEnum):
"""Display brightness."""

BRIGHT = "bright"
DIM = "dim"
OFF = "off"


class ControlBusMode(StrEnum):
"""Control bus mode."""

AMPLIFIER = "amplifier"
RECEIVER = "receiver"
OFF = "off"
63 changes: 63 additions & 0 deletions aiostreammagic/stream_magic.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
RepeatMode,
CallbackType,
AudioOutput,
Display,
DisplayBrightness,
Update,
)
from . import endpoints as ep
from .const import _LOGGER
Expand All @@ -47,6 +50,8 @@ def __init__(self, host):
self.play_state: PlayState | None = None
self.now_playing: NowPlaying | None = None
self.audio_output: AudioOutput | None = None
self.display: Display | None = None
self.update: Update | None = None
self._attempt_reconnection = False
self._reconnect_task: Optional[Task] = None
self.position_last_updated: datetime = datetime.now()
Expand Down Expand Up @@ -149,13 +154,17 @@ async def _connect_handler(self, res):
self.play_state,
self.now_playing,
self.audio_output,
self.display,
self.update,
) = await asyncio.gather(
self.get_info(),
self.get_sources(),
self.get_state(),
self.get_play_state(),
self.get_now_playing(),
self.get_audio_output(),
self.get_display(),
self.get_update(),
)
subscribe_state_updates = {
self.subscribe(self._async_handle_info, ep.INFO),
Expand All @@ -165,6 +174,8 @@ async def _connect_handler(self, res):
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),
self.subscribe(self._async_handle_display, ep.DISPLAY),
self.subscribe(self._async_handle_update, ep.UPDATE),
}
subscribe_tasks = set()
for state_update in subscribe_state_updates:
Expand Down Expand Up @@ -305,6 +316,16 @@ async def get_audio_output(self) -> AudioOutput:
data = await self.request(ep.ZONE_AUDIO_OUTPUT)
return AudioOutput.from_dict(data["params"]["data"])

async def get_display(self) -> Display:
"""Get display information from device."""
data = await self.request(ep.DISPLAY)
return Display.from_dict(data["params"]["data"])

async def get_update(self) -> Update:
"""Get display information from device."""
data = await self.request(ep.UPDATE)
return Update.from_dict(data["params"]["data"])

async def _async_handle_info(self, payload) -> None:
"""Handle async info update."""
params = payload["params"]
Expand Down Expand Up @@ -356,6 +377,20 @@ async def _async_handle_audio_output(self, payload) -> None:
self.audio_output = AudioOutput.from_dict(params["data"])
await self.do_state_update_callbacks()

async def _async_handle_display(self, payload) -> None:
"""Handle async display update."""
params = payload["params"]
if "data" in params:
self.display = Display.from_dict(params["data"])
await self.do_state_update_callbacks()

async def _async_handle_update(self, payload) -> None:
"""Handle async display update."""
params = payload["params"]
if "data" in params:
self.update = Update.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 @@ -477,3 +512,31 @@ async def set_audio_output(self, output_id: str) -> None:
await self.request(
ep.ZONE_AUDIO_OUTPUT, params={"zone": "ZONE1", "id": output_id}
)

async def set_pre_amp_mode(self, enabled: bool) -> None:
"""Sets whether the internal pre-amp is enabled."""
await self.request(ep.ZONE_STATE, params={"pre_amp_mode": enabled})

async def set_volume_limit(self, volume_limit_percent: int) -> None:
"""Sets the volume limit for the internal pre-amp. Value must be between 0 and 100."""
if not 0 <= volume_limit_percent <= 100:
raise StreamMagicError("Volume limit must be between 0 and 100")
await self.request(
ep.ZONE_STATE, params={"volume_limit_percent": volume_limit_percent}
)

async def set_device_name(self, device_name: str) -> None:
"""Set the device name."""
await self.request(ep.INFO, params={"name": device_name})

async def set_display_brightness(
self, display_brightness: DisplayBrightness
) -> None:
"""Set the display brightness of the device."""
await self.request(ep.DISPLAY, params={"brightness": display_brightness})

async def set_early_update(self, early_update: bool) -> None:
"""Set whether the device should be on the early update channel."""
await self.request(
ep.UPDATE, params={"early_update": early_update, "action": "CHECK"}
)
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "aiostreammagic"
version = "2.6.0"
version = "2.7.0"
description = "An async python package for interfacing with Cambridge Audio / Stream Magic compatible streamers."
authors = ["Noah Husby <[email protected]>"]
maintainers = ["Noah Husby <[email protected]>"]
Expand Down

0 comments on commit e1c31c5

Please sign in to comment.