Skip to content

Commit

Permalink
Add support for preset/mem commands
Browse files Browse the repository at this point in the history
  • Loading branch information
mvdwetering committed Mar 1, 2024
1 parent 87c137c commit 9839339
Show file tree
Hide file tree
Showing 12 changed files with 137 additions and 7 deletions.
1 change: 1 addition & 0 deletions docs/all_commands_ever_seen.txt
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,7 @@
@PC:METAINFO=?
@PC:PLAYBACK=?
@PC:PLAYBACKINFO=?
@PC:PRESET=?
@PC:REPEAT=?
@PC:SHUFFLE=?
@PC:STATION=?
Expand Down
36 changes: 36 additions & 0 deletions tests/test_tun.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@
(SUBUNIT, "FMFREQ", "101.60"),
],
),
(
(SUBUNIT, "PRESET"),
[
(SUBUNIT, "PRESET", "12"),
],
),
(
(SUBUNIT, "RDSINFO"),
[
Expand Down Expand Up @@ -70,6 +76,7 @@ def test_initialize(connection, update_callback):
assert tun.band is BandTun.FM
assert tun.amfreq == 1080
assert tun.fmfreq == 101.60
assert tun.preset == 12


def test_am(connection, initialized_tun: Tun):
Expand Down Expand Up @@ -106,3 +113,32 @@ def test_rds(connection, initialized_tun: Tun):

connection.send_protocol_message(SUBUNIT, "RDSTXTB", "radiotext b")
assert initialized_tun.rdstxtb == "radiotext b"

def test_preset(connection, initialized_tun: Tun):

# Updates from device
connection.send_protocol_message(SUBUNIT, "PRESET", "11")
assert initialized_tun.preset == 11

connection.send_protocol_message(SUBUNIT, "PRESET", "No Preset")
assert initialized_tun.preset == None

# Set preset
initialized_tun.preset = 10
connection.put.assert_called_with(SUBUNIT, "PRESET", "10")

# Preset Up Down
initialized_tun.preset_up()
connection.put.assert_called_with(SUBUNIT, "PRESET", "Up")

initialized_tun.preset_down()
connection.put.assert_called_with(SUBUNIT, "PRESET", "Down")

def test_mem(connection, initialized_tun: Tun):

# Store
initialized_tun.mem(10)
connection.put.assert_called_with(SUBUNIT, "MEM", "10")

initialized_tun.mem()
connection.put.assert_called_with(SUBUNIT, "MEM", "Auto")
17 changes: 17 additions & 0 deletions ynca/converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,23 @@ def to_str(self, value: int) -> str:
return self._to_str(value)


class IntOrNoneConverter(ConverterBase):

def __init__(self, to_str: Callable[[int], str] | None = None) -> None:
self._to_str = to_str or str

def to_value(self, value_string: str) -> int | None:
try:
return int(value_string)
except ValueError:
return None

def to_str(self, value: int) -> str:
# Make sure it is an int compatible types to be usable with MultiConverter
int(value)
return self._to_str(value)


class FloatConverter(ConverterBase):
def __init__(self, to_str: Callable[[float], str] | None = None) -> None:
self._to_str = to_str or str
Expand Down
31 changes: 29 additions & 2 deletions ynca/subunits/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
from __future__ import annotations

from ..converters import FloatConverter
from ..function import Cmd, EnumFunctionMixin, FloatFunctionMixin, StrFunctionMixin
from ..converters import FloatConverter, IntOrNoneConverter
from ..function import (
Cmd,
EnumFunctionMixin,
FloatFunctionMixin,
IntFunctionMixin,
StrFunctionMixin,
)
from ..enums import Playback, PlaybackInfo, Repeat, Shuffle
from ..helpers import number_to_string_with_stepsize

Expand All @@ -27,6 +33,12 @@ class FmFreqFunctionMixin:
"""Read/write FM frequency. Values will be aligned to a valid stepsize."""


class MemFunctionMixin:
def mem(self, parameter: int | None = None):
"""Store preset in memory slot, parameter is a slot number 1-40 or None to select a slot automatically."""
self._put("MEM", "Auto" if parameter is None else str(parameter)) # type: ignore


class PlaybackFunctionMixin:
def playback(self, parameter: Playback):
"""Change playback state"""
Expand All @@ -37,6 +49,21 @@ class PlaybackInfoFunctionMixin:
playbackinfo = EnumFunctionMixin[PlaybackInfo](PlaybackInfo, Cmd.GET)


class PresetFunctionMixin:
preset = IntFunctionMixin(converter=IntOrNoneConverter())
"""Activate or read preset. Note that only TUN and SIRIUS seem to support GET."""


class PresetUpDownFunctionMixin:
def preset_up(self):
"""Select next available preset"""
self._put("PRESET", "Up") # type: ignore

def preset_down(self):
"""Select previous available preset"""
self._put("PRESET", "Down") # type: ignore


class RepeatFunctionMixin:
repeat = EnumFunctionMixin[Repeat](Repeat)

Expand Down
4 changes: 4 additions & 0 deletions ynca/subunits/napster.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
from . import (
AlbumFunctionMixin,
ArtistFunctionMixin,
MemFunctionMixin,
PlaybackFunctionMixin,
PlaybackInfoFunctionMixin,
PresetFunctionMixin,
RepeatFunctionMixin,
ShuffleFunctionMixin,
SongFunctionMixin,
Expand All @@ -16,8 +18,10 @@
class Napster(
AlbumFunctionMixin,
ArtistFunctionMixin,
MemFunctionMixin,
PlaybackFunctionMixin,
PlaybackInfoFunctionMixin,
PresetFunctionMixin,
RepeatFunctionMixin,
ShuffleFunctionMixin,
SongFunctionMixin,
Expand Down
12 changes: 11 additions & 1 deletion ynca/subunits/netradio.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,23 @@

from ..constants import Subunit
from ..subunit import SubunitBase
from . import AlbumFunctionMixin, PlaybackFunctionMixin, PlaybackInfoFunctionMixin, SongFunctionMixin, StationFunctionMixin
from . import (
AlbumFunctionMixin,
MemFunctionMixin,
PlaybackFunctionMixin,
PlaybackInfoFunctionMixin,
PresetFunctionMixin,
SongFunctionMixin,
StationFunctionMixin,
)


class NetRadio(
AlbumFunctionMixin,
MemFunctionMixin,
PlaybackFunctionMixin,
PlaybackInfoFunctionMixin,
PresetFunctionMixin,
SongFunctionMixin,
StationFunctionMixin,
SubunitBase,
Expand Down
4 changes: 4 additions & 0 deletions ynca/subunits/pandora.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
from . import (
AlbumFunctionMixin,
ArtistFunctionMixin,
MemFunctionMixin,
PlaybackFunctionMixin,
PlaybackInfoFunctionMixin,
PresetFunctionMixin,
SongFunctionMixin,
StationFunctionMixin,
TrackFunctionMixin,
Expand All @@ -16,8 +18,10 @@
class Pandora(
AlbumFunctionMixin,
ArtistFunctionMixin,
MemFunctionMixin,
PlaybackFunctionMixin,
PlaybackInfoFunctionMixin,
PresetFunctionMixin,
SongFunctionMixin,
StationFunctionMixin,
TrackFunctionMixin, # Pandora seems to use TRACK or SONG for title based on logs. Maybe depends on firmware version?
Expand Down
4 changes: 4 additions & 0 deletions ynca/subunits/pc.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
from . import (
AlbumFunctionMixin,
ArtistFunctionMixin,
MemFunctionMixin,
PlaybackFunctionMixin,
PlaybackInfoFunctionMixin,
PresetFunctionMixin,
RepeatFunctionMixin,
ShuffleFunctionMixin,
SongFunctionMixin,
Expand All @@ -16,8 +18,10 @@
class Pc(
AlbumFunctionMixin,
ArtistFunctionMixin,
MemFunctionMixin,
PlaybackFunctionMixin,
PlaybackInfoFunctionMixin,
PresetFunctionMixin,
RepeatFunctionMixin,
ShuffleFunctionMixin,
SongFunctionMixin,
Expand Down
4 changes: 4 additions & 0 deletions ynca/subunits/rhap.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
from . import (
AlbumFunctionMixin,
ArtistFunctionMixin,
MemFunctionMixin,
PlaybackFunctionMixin,
PlaybackInfoFunctionMixin,
PresetFunctionMixin,
RepeatFunctionMixin,
ShuffleFunctionMixin,
SongFunctionMixin,
Expand All @@ -16,8 +18,10 @@
class Rhap(
AlbumFunctionMixin,
ArtistFunctionMixin,
MemFunctionMixin,
PlaybackFunctionMixin,
PlaybackInfoFunctionMixin,
PresetFunctionMixin,
RepeatFunctionMixin,
ShuffleFunctionMixin,
SongFunctionMixin,
Expand Down
8 changes: 8 additions & 0 deletions ynca/subunits/sirius.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,21 @@
from . import (
ArtistFunctionMixin,
ChNameFunctionMixin,
MemFunctionMixin,
PlaybackFunctionMixin,
PlaybackInfoFunctionMixin,
PresetFunctionMixin,
PresetUpDownFunctionMixin,
SongFunctionMixin,
)


class Sirius(
ArtistFunctionMixin,
ChNameFunctionMixin,
MemFunctionMixin,
PresetFunctionMixin,
PresetUpDownFunctionMixin,
SongFunctionMixin,
SubunitBase,
):
Expand All @@ -23,8 +29,10 @@ class Sirius(
class SiriusIr(
ArtistFunctionMixin,
ChNameFunctionMixin,
MemFunctionMixin,
PlaybackFunctionMixin,
PlaybackInfoFunctionMixin,
PresetFunctionMixin,
SongFunctionMixin,
SubunitBase,
):
Expand Down
19 changes: 15 additions & 4 deletions ynca/subunits/tun.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,32 @@
from ..enums import BandTun
from ..helpers import number_to_string_with_stepsize
from ..subunit import SubunitBase
from . import FmFreqFunctionMixin
from . import (
FmFreqFunctionMixin,
MemFunctionMixin,
PresetFunctionMixin,
PresetUpDownFunctionMixin,
)


class Tun(FmFreqFunctionMixin, SubunitBase):
class Tun(
FmFreqFunctionMixin,
MemFunctionMixin,
PresetFunctionMixin,
PresetUpDownFunctionMixin,
SubunitBase,
):
id = Subunit.TUN

band = EnumFunctionMixin[BandTun](BandTun)

amfreq = IntFunctionMixin(
converter=IntConverter(
to_str=lambda v: number_to_string_with_stepsize(v, 0, 10)
),
)
"""Read/write AM frequency. Values will be aligned to a valid stepsize."""

band = EnumFunctionMixin[BandTun](BandTun)

rdsprgservice = StrFunctionMixin(Cmd.GET, init="RDSINFO")
rdsprgtype = StrFunctionMixin(Cmd.GET, init="RDSINFO")
rdstxta = StrFunctionMixin(Cmd.GET, init="RDSINFO")
Expand Down
4 changes: 4 additions & 0 deletions ynca/subunits/usb.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
from . import (
AlbumFunctionMixin,
ArtistFunctionMixin,
MemFunctionMixin,
PlaybackFunctionMixin,
PlaybackInfoFunctionMixin,
PresetFunctionMixin,
RepeatFunctionMixin,
ShuffleFunctionMixin,
SongFunctionMixin,
Expand All @@ -16,8 +18,10 @@
class Usb(
AlbumFunctionMixin,
ArtistFunctionMixin,
MemFunctionMixin,
PlaybackFunctionMixin,
PlaybackInfoFunctionMixin,
PresetFunctionMixin,
RepeatFunctionMixin,
ShuffleFunctionMixin,
SongFunctionMixin,
Expand Down

0 comments on commit 9839339

Please sign in to comment.