-
-
Notifications
You must be signed in to change notification settings - Fork 30.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sound mode support media_player general and denonavr #13706
Changes from 8 commits
062db8a
69440e2
8dab888
142a71a
c7df1bb
a5ae281
90924ac
e4da0d4
29659cb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,27 +12,32 @@ | |
from homeassistant.components.media_player import ( | ||
SUPPORT_PAUSE, SUPPORT_NEXT_TRACK, SUPPORT_PREVIOUS_TRACK, | ||
SUPPORT_TURN_OFF, SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_STEP, | ||
SUPPORT_SELECT_SOURCE, SUPPORT_PLAY_MEDIA, MEDIA_TYPE_CHANNEL, | ||
MediaPlayerDevice, PLATFORM_SCHEMA, SUPPORT_TURN_ON, | ||
MEDIA_TYPE_MUSIC, SUPPORT_VOLUME_SET, SUPPORT_PLAY) | ||
SUPPORT_SELECT_SOURCE, SUPPORT_SELECT_SOUND_MODE, | ||
SUPPORT_PLAY_MEDIA, MEDIA_TYPE_CHANNEL, MediaPlayerDevice, | ||
PLATFORM_SCHEMA, SUPPORT_TURN_ON, MEDIA_TYPE_MUSIC, | ||
SUPPORT_VOLUME_SET, SUPPORT_PLAY) | ||
from homeassistant.const import ( | ||
CONF_HOST, STATE_OFF, STATE_PLAYING, STATE_PAUSED, | ||
CONF_NAME, STATE_ON, CONF_ZONE, CONF_TIMEOUT) | ||
import homeassistant.helpers.config_validation as cv | ||
|
||
REQUIREMENTS = ['denonavr==0.6.1'] | ||
REQUIREMENTS = ['denonavr==0.7.0'] | ||
|
||
_LOGGER = logging.getLogger(__name__) | ||
|
||
DEFAULT_NAME = None | ||
DEFAULT_SHOW_SOURCES = False | ||
DEFAULT_TIMEOUT = 2 | ||
DEFAULT_SOUND_MODE = True | ||
CONF_SHOW_ALL_SOURCES = 'show_all_sources' | ||
CONF_ZONES = 'zones' | ||
CONF_SOUND_MODE = 'sound_mode' | ||
CONF_SOUND_MODE_DICT = 'sound_mode_dict' | ||
CONF_VALID_ZONES = ['Zone2', 'Zone3'] | ||
CONF_INVALID_ZONES_ERR = 'Invalid Zone (expected Zone2 or Zone3)' | ||
KEY_DENON_CACHE = 'denonavr_hosts' | ||
|
||
ATTR_SOUND_MODE_RAW = 'sound_mode_raw' | ||
|
||
SUPPORT_DENON = SUPPORT_VOLUME_STEP | SUPPORT_VOLUME_MUTE | \ | ||
SUPPORT_TURN_ON | SUPPORT_TURN_OFF | \ | ||
SUPPORT_SELECT_SOURCE | SUPPORT_VOLUME_SET | ||
|
@@ -49,6 +54,8 @@ | |
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ | ||
vol.Optional(CONF_HOST): cv.string, | ||
vol.Optional(CONF_NAME): cv.string, | ||
vol.Optional(CONF_SOUND_MODE, default=DEFAULT_SOUND_MODE): cv.boolean, | ||
vol.Optional(CONF_SOUND_MODE_DICT): vol.Schema({str: list}), | ||
vol.Optional(CONF_SHOW_ALL_SOURCES, default=DEFAULT_SHOW_SOURCES): | ||
cv.boolean, | ||
vol.Optional(CONF_ZONES): | ||
|
@@ -84,6 +91,10 @@ def setup_platform(hass, config, add_devices, discovery_info=None): | |
else: | ||
add_zones = None | ||
|
||
# Get config option for sound mode | ||
sound_mode_support = config.get(CONF_SOUND_MODE) | ||
sound_mode_dict = config.get(CONF_SOUND_MODE_DICT) | ||
|
||
# Start assignment of host and name | ||
new_hosts = [] | ||
# 1. option: manual setting | ||
|
@@ -117,7 +128,9 @@ def setup_platform(hass, config, add_devices, discovery_info=None): | |
show_all_inputs=show_all_sources, timeout=timeout, | ||
add_zones=add_zones) | ||
for new_zone in new_device.zones.values(): | ||
receivers.append(DenonDevice(new_zone)) | ||
receivers.append(DenonDevice(new_zone, | ||
sound_mode_support, | ||
sound_mode_dict)) | ||
cache.add(host) | ||
_LOGGER.info("Denon receiver at host %s initialized", host) | ||
|
||
|
@@ -129,7 +142,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): | |
class DenonDevice(MediaPlayerDevice): | ||
"""Representation of a Denon Media Player Device.""" | ||
|
||
def __init__(self, receiver): | ||
def __init__(self, receiver, sound_mode_support, sound_mode_dict): | ||
"""Initialize the device.""" | ||
self._receiver = receiver | ||
self._name = self._receiver.name | ||
|
@@ -147,6 +160,24 @@ def __init__(self, receiver): | |
self._frequency = self._receiver.frequency | ||
self._station = self._receiver.station | ||
|
||
self._sound_mode_support = sound_mode_support | ||
if sound_mode_support: | ||
self._sound_mode = self._receiver.sound_mode | ||
self._sound_mode_raw = self._receiver.sound_mode_raw | ||
if sound_mode_dict is None: | ||
self._sound_mode_list = self._receiver.sound_mode_list | ||
else: | ||
self._receiver.set_sound_mode_dict(sound_mode_dict) | ||
self._sound_mode_list = list(sound_mode_dict) | ||
else: | ||
self._sound_mode = None | ||
self._sound_mode_raw = None | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. self._sound_mode_raw attribute does not seem to be used at all and could be removed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just made a commit where I implemented it as a state property. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did not test this change yet, will test it tonight. |
||
self._sound_mode_list = None | ||
|
||
self._supported_features_base = SUPPORT_DENON | ||
self._supported_features_base |= (sound_mode_support and | ||
SUPPORT_SELECT_SOUND_MODE) | ||
|
||
def update(self): | ||
"""Get the latest status information from device.""" | ||
self._receiver.update() | ||
|
@@ -164,6 +195,9 @@ def update(self): | |
self._band = self._receiver.band | ||
self._frequency = self._receiver.frequency | ||
self._station = self._receiver.station | ||
if self._sound_mode_support: | ||
self._sound_mode = self._receiver.sound_mode | ||
self._sound_mode_raw = self._receiver.sound_mode_raw | ||
|
||
@property | ||
def name(self): | ||
|
@@ -197,12 +231,27 @@ def source_list(self): | |
"""Return a list of available input sources.""" | ||
return self._source_list | ||
|
||
@property | ||
def sound_mode(self): | ||
"""Return the current matched sound mode.""" | ||
return self._sound_mode | ||
|
||
@property | ||
def sound_mode_raw(self): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as for self._sound_mode_raw. There is no equivalent property in constructor of parent media_player class, thus I assume it is not used. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above |
||
"""Return the current raw sound mode.""" | ||
return self._sound_mode_raw | ||
|
||
@property | ||
def sound_mode_list(self): | ||
"""Return a list of available sound modes.""" | ||
return self._sound_mode_list | ||
|
||
@property | ||
def supported_features(self): | ||
"""Flag media player features that are supported.""" | ||
if self._current_source in self._receiver.netaudio_func_list: | ||
return SUPPORT_DENON | SUPPORT_MEDIA_MODES | ||
return SUPPORT_DENON | ||
return self._supported_features_base | SUPPORT_MEDIA_MODES | ||
return self._supported_features_base | ||
|
||
@property | ||
def media_content_id(self): | ||
|
@@ -276,6 +325,15 @@ def media_episode(self): | |
"""Episode of current playing media, TV show only.""" | ||
return None | ||
|
||
@property | ||
def device_state_attributes(self): | ||
"""Return device specific state attributes.""" | ||
attributes = {} | ||
if self._sound_mode_raw is not None and self._sound_mode_support\ | ||
and self._power == 'ON': | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. continuation line missing indentation or outdented |
||
attributes[ATTR_SOUND_MODE_RAW] = self._sound_mode_raw | ||
return attributes | ||
|
||
def media_play_pause(self): | ||
"""Simulate play pause media player.""" | ||
return self._receiver.toggle_play_pause() | ||
|
@@ -292,6 +350,10 @@ def select_source(self, source): | |
"""Select input source.""" | ||
return self._receiver.set_input_func(source) | ||
|
||
def select_sound_mode(self, sound_mode): | ||
"""Select sound mode.""" | ||
return self._receiver.set_sound_mode(sound_mode) | ||
|
||
def turn_on(self): | ||
"""Turn on media player.""" | ||
if self._receiver.power_on(): | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should not add this as a new supported feature for media players. We should only add things that exist among many media players.
Revert all changes to this file and add a new service to the denonavr platform called
media_player.denonavr_set_sound_mode
to allow changing thet mode.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was planning to add support for sound modes in a form or another to songpal, so that'd be two platforms for using such a feature. I haven't checked out yet how to do that, but will try to find some time during the upcoming weekend for it, if that's fine?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@balloob I asked about this on the form when I first started with this code, and at that time there was also someone who was intrested in implementing sound mode support for the sonos platform based on my code (but he wanted to wait until I finished and it has been quite a long time).
But that would already make 3 platforms that would uses this.
Besides almost all sound systems have some kind of sound mode feature, therefore it could be implemented in most of the platforms if someone is willing to make the code (and has that device).
Therfore I made this a general support feature in the media_player/init.py file, and I think this is a good thing. Do you agree @balloob?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See https://developers.home-assistant.io/docs/en/entity_index.html#changing-the-entity-model
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So let me close this PR and the frontend PR, and you can open an issue on the architecture repo to propose the new feature.