Skip to content

Commit

Permalink
Implement improved set_volume_level method (#150)
Browse files Browse the repository at this point in the history
* Implement revised 'set_volume_level' method

* Update 'set_volume_level' method

* Python 2 fix
  • Loading branch information
JeffLIrion committed Jan 23, 2020
1 parent 55010d0 commit 1e66a94
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 44 deletions.
41 changes: 8 additions & 33 deletions androidtv/basetv.py
Expand Up @@ -1090,54 +1090,29 @@ def key_z(self):
# volume methods #
# #
# ======================================================================= #
def set_volume_level(self, volume_level, current_volume_level=None):
def set_volume_level(self, volume_level):
"""Set the volume to the desired level.
.. note::
This method works by sending volume up/down commands with a 1 second pause in between. Without this pause,
the device will do a quick power cycle. This is the most robust solution I've found so far.
Parameters
----------
volume_level : float
The new volume level (between 0 and 1)
current_volume_level : float, None
The current volume level (between 0 and 1); if it is not provided, it will be determined
Returns
-------
float, None
The new volume level (between 0 and 1), or ``None`` if ``self.max_volume`` could not be determined
"""
# if necessary, determine the current volume and/or the max volume
if current_volume_level is None or not self.max_volume:
current_volume = self.volume
else:
current_volume = min(max(round(self.max_volume * current_volume_level), 0.), self.max_volume)

# if `self.max_volume` or `current_volume` could not be determined, do not proceed
if not self.max_volume or current_volume is None:
return None

new_volume = min(max(round(self.max_volume * volume_level), 0.), self.max_volume)

# Case 1: the new volume is the same as the current volume
if new_volume == current_volume:
return new_volume / self.max_volume

# Case 2: the new volume is less than the current volume
if new_volume < current_volume:
cmd = "(" + " && sleep 1 && ".join(["input keyevent {0}".format(constants.KEY_VOLUME_DOWN)] * int(current_volume - new_volume)) + ") &"
# if necessary, determine the max volume
if not self.max_volume:
_ = self.volume
if not self.max_volume:
return None

# Case 3: the new volume is greater than the current volume
else:
cmd = "(" + " && sleep 1 && ".join(["input keyevent {0}".format(constants.KEY_VOLUME_UP)] * int(new_volume - current_volume)) + ") &"
new_volume = int(min(max(round(self.max_volume * volume_level), 0.), self.max_volume))

# send the volume down/up commands
self._adb.shell(cmd)
self._adb.shell("media volume --show --stream 3 --set {}".format(new_volume))

# return the new volume level
return new_volume / self.max_volume
Expand Down
16 changes: 5 additions & 11 deletions tests/test_androidtv.py
Expand Up @@ -712,23 +712,17 @@ def test_set_volume_level(self):
with patchers.patch_shell(STREAM_MUSIC_ON)[self.PATCH_KEY]:
new_volume_level = self.atv.set_volume_level(0.5)
self.assertEqual(new_volume_level, 0.5)
self.assertEqual(getattr(self.atv._adb, self.ADB_ATTR).shell_cmd, "(input keyevent 24 && sleep 1 && input keyevent 24 && sleep 1 && input keyevent 24 && sleep 1 && input keyevent 24 && sleep 1 && input keyevent 24 && sleep 1 && input keyevent 24 && sleep 1 && input keyevent 24 && sleep 1 && input keyevent 24) &")
self.assertEqual(getattr(self.atv._adb, self.ADB_ATTR).shell_cmd, "media volume --show --stream 3 --set 30")

with patchers.patch_shell('')[self.PATCH_KEY]:
new_volume_level = self.atv.set_volume_level(0.5, 22./60)
new_volume_level = self.atv.set_volume_level(30./60)
self.assertEqual(new_volume_level, 0.5)
self.assertEqual(getattr(self.atv._adb, self.ADB_ATTR).shell_cmd, "(input keyevent 24 && sleep 1 && input keyevent 24 && sleep 1 && input keyevent 24 && sleep 1 && input keyevent 24 && sleep 1 && input keyevent 24 && sleep 1 && input keyevent 24 && sleep 1 && input keyevent 24 && sleep 1 && input keyevent 24) &")
self.assertEqual(getattr(self.atv._adb, self.ADB_ATTR).shell_cmd, "media volume --show --stream 3 --set 30")

with patchers.patch_shell('')[self.PATCH_KEY]:
new_volume_level = self.atv.set_volume_level(22./60, 0.5)
new_volume_level = self.atv.set_volume_level(22./60)
self.assertEqual(new_volume_level, 22./60)
self.assertEqual(getattr(self.atv._adb, self.ADB_ATTR).shell_cmd, "(input keyevent 25 && sleep 1 && input keyevent 25 && sleep 1 && input keyevent 25 && sleep 1 && input keyevent 25 && sleep 1 && input keyevent 25 && sleep 1 && input keyevent 25 && sleep 1 && input keyevent 25 && sleep 1 && input keyevent 25) &")

with patchers.patch_shell('')[self.PATCH_KEY]:
self.atv.adb_shell('')
new_volume_level = self.atv.set_volume_level(22./60, 22./60)
self.assertEqual(new_volume_level, 22./60)
self.assertEqual(getattr(self.atv._adb, self.ADB_ATTR).shell_cmd, "")
self.assertEqual(getattr(self.atv._adb, self.ADB_ATTR).shell_cmd, "media volume --show --stream 3 --set 22")

def test_volume_up(self):
"""Check that the ``volume_up`` method works correctly.
Expand Down

0 comments on commit 1e66a94

Please sign in to comment.