From e96751aa4688464be2d63e97323b6d57dfbedfc0 Mon Sep 17 00:00:00 2001 From: Kristian Date: Wed, 10 Mar 2010 12:43:11 +0100 Subject: [PATCH] Added Denon mixer support --- mopidy/mixers/denon.py | 27 +++++++++++++++++++++++++++ mopidy/settings/default.py | 16 ++++++++++++++++ tests/__main__.py | 1 + tests/mixers/denontest.py | 31 +++++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+) create mode 100644 mopidy/mixers/denon.py create mode 100644 tests/mixers/denontest.py diff --git a/mopidy/mixers/denon.py b/mopidy/mixers/denon.py new file mode 100644 index 00000000..2acfa619 --- /dev/null +++ b/mopidy/mixers/denon.py @@ -0,0 +1,27 @@ +from serial import Serial + +from mopidy.mixers import BaseMixer +from mopidy.settings import MIXER_PORT + + +class DenonMixer(BaseMixer): + def __init__(self): + self._device = Serial(port=MIXER_PORT) + self._levels = ['99']+["%(#)02d"% {'#': v} for v in range(0,99)] + self._volume = None + + def _get_volume(self): + # The Denon spec doesnt seem to document + # how to query the volume, so we keep the + # state internally + return self._volume + + def _set_volume(self, volume): + # Clamp according to Denon-spec + if not volume: + volume = 0 + elif volume > 99: + volume = 99 + + self._volume = volume + self._device.write('MV%s\r'% self._levels[volume]) diff --git a/mopidy/settings/default.py b/mopidy/settings/default.py index 96d5cd23..d6e18503 100644 --- a/mopidy/settings/default.py +++ b/mopidy/settings/default.py @@ -38,12 +38,28 @@ CONSOLE_LOG_FORMAT = u'%(levelname)-8s %(asctime)s [%(threadName)s] %(name)s\n #: Default on other operating systems:: #: #: MIXER = u'mopidy.mixers.dummy.DummyMixer' +#: +#: *Using external mixers* +#: +#: Using external mixers depends on the pyserial-library, +#: so make sure you have it installed. It also adds one +#: more setting, MIXER_PORT. This must point to the device +#: port like /dev/tty1 or similar. +#: +#: Available external Mixers:: +#: +#: +#: MIXER = u'mopidy.mixers.denon.DenonMixer' +#: MIXER_PORT = u'/dev/tty0' # Verify this manually +#: MIXER = u'mopidy.mixers.dummy.DummyMixer' if sys.platform == 'linux2': MIXER = u'mopidy.mixers.alsa.AlsaMixer' elif sys.platform == 'darwin': MIXER = u'mopidy.mixers.osa.OsaMixer' +MIXER_PORT=None + #: Which address Mopidy should bind to. Examples: #: #: ``localhost`` diff --git a/tests/__main__.py b/tests/__main__.py index 11677b0e..d3adfca0 100644 --- a/tests/__main__.py +++ b/tests/__main__.py @@ -10,6 +10,7 @@ def main(): os.path.abspath(os.path.join(os.path.dirname(__file__), '../'))) r = CoverageTestRunner() r.add_pair('mopidy/mixers/dummy.py', 'tests/mixers/dummytest.py') + r.add_pair('mopidy/mixers/denon.py', 'tests/mixers/denontest.py') r.add_pair('mopidy/models.py', 'tests/modelstest.py') r.add_pair('mopidy/mpd/handler.py', 'tests/mpd/handlertest.py') r.run() diff --git a/tests/mixers/denontest.py b/tests/mixers/denontest.py new file mode 100644 index 00000000..a862e402 --- /dev/null +++ b/tests/mixers/denontest.py @@ -0,0 +1,31 @@ +import unittest +import os + +from mopidy.mixers.denon import DenonMixer + +class DenonMixerTest(unittest.TestCase): + def setUp(self): + self.m = DenonMixer() + self.m._device = os.tmpfile() # "Mock" :-) + + def tearDown(self): + self.m._device.close() + + def test_volume_is_None_initially(self): + self.assertEqual(self.m.volume, None) + + def test_volume_set_to_min(self): + self.m.volume = 0 + self.assertEqual(self.m.volume, 0) + + def test_volume_set_to_max(self): + self.m.volume = 100 + self.assertEqual(self.m.volume, 99) + + def test_volume_set_to_below_min_results_in_min(self): + self.m.volume = -10 + self.assertEqual(self.m.volume, 0) + + def test_volume_set_to_above_max_results_in_max(self): + self.m.volume = 110 + self.assertEqual(self.m.volume, 99)