Skip to content
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

Added AVR 2016 Sound Mode, All Zone Stereo, and Marantz SR6011-6013 support #65

Merged
merged 5 commits into from
Dec 2, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 71 additions & 7 deletions denonavr/denonavr.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
_LOGGER = logging.getLogger("DenonAVR")

DEVICEINFO_AVR_X_PATTERN = re.compile(
r"(.*AVR-X.*|.*SR500[6-9]|.*SR60(07|08|09|10)|.*NR1604)")
r"(.*AVR-X.*|.*SR500[6-9]|.*SR60(07|08|09|10|11|12|13)|.*NR1604)")
DEVICEINFO_COMMAPI_PATTERN = re.compile(r"(0210|0300)")

ReceiverType = namedtuple('ReceiverType', ["type", "port"])
Expand All @@ -35,6 +35,8 @@
"Media Server": "SERVER", "Spotify": "SPOTIFY",
"Flickr": "FLICKR", "Favorites": "FAVORITES"}

ALL_ZONE_STEREO = "ALL ZONE STEREO"

SOUND_MODE_MAPPING = OrderedDict(
[('MUSIC', ['PLII MUSIC', 'DTS NEO:6 MUSIC', 'DOLBY D +NEO:X M',
'ROCK ARENA', 'JAZZ CLUB', 'MATRIX']),
Expand All @@ -51,7 +53,8 @@
('DTS SURROUND', ['DTS SURROUND', 'DTS NEURAL:X', 'STANDARD(DTS)',
'DTS + NEURAL:X']),
('MCH STEREO', ['MULTI CH STEREO', 'MULTI CH IN', 'MULTI_CH_STEREO']),
('STEREO', ['STEREO'])])
('STEREO', ['STEREO']),
(ALL_ZONE_STEREO, [ALL_ZONE_STEREO])])

PLAYING_SOURCES = ("Online Music", "Media Server", "iPod/USB", "Bluetooth",
"Internet Radio", "Favorites", "SpotifyConnect", "Flickr",
Expand Down Expand Up @@ -87,6 +90,7 @@
COMMAND_MUTE_ON_URL = "/goform/formiPhoneAppMute.xml?1+MuteOn"
COMMAND_MUTE_OFF_URL = "/goform/formiPhoneAppMute.xml?1+MuteOff"
COMMAND_SEL_SM_URL = "/goform/formiPhoneAppDirect.xml?MS"
COMMAND_SET_ZST_URL = "/goform/formiPhoneAppDirect.xml?MN"

# Zone 2 URLs
STATUS_Z2_URL = "/goform/formZone2_Zone2XmlStatus.xml"
Expand Down Expand Up @@ -122,7 +126,8 @@
"command_power_standby", "command_volume_up",
"command_volume_down", "command_set_volume",
"command_mute_on", "command_mute_off",
"command_sel_sound_mode", "command_netaudio_post"])
"command_sel_sound_mode", "command_netaudio_post",
"command_set_all_zone_stereo"])

DENONAVR_URLS = ReceiverURLs(appcommand=APPCOMMAND_URL,
status=STATUS_URL,
Expand All @@ -141,7 +146,8 @@
command_mute_on=COMMAND_MUTE_ON_URL,
command_mute_off=COMMAND_MUTE_OFF_URL,
command_sel_sound_mode=COMMAND_SEL_SM_URL,
command_netaudio_post=COMMAND_NETAUDIO_POST_URL)
command_netaudio_post=COMMAND_NETAUDIO_POST_URL,
command_set_all_zone_stereo=COMMAND_SET_ZST_URL)

ZONE2_URLS = ReceiverURLs(appcommand=APPCOMMAND_URL,
status=STATUS_Z2_URL,
Expand All @@ -160,7 +166,8 @@
command_mute_on=COMMAND_MUTE_ON_Z2_URL,
command_mute_off=COMMAND_MUTE_OFF_Z2_URL,
command_sel_sound_mode=COMMAND_SEL_SM_URL,
command_netaudio_post=COMMAND_NETAUDIO_POST_URL)
command_netaudio_post=COMMAND_NETAUDIO_POST_URL,
command_set_all_zone_stereo=COMMAND_SET_ZST_URL)

ZONE3_URLS = ReceiverURLs(appcommand=APPCOMMAND_URL,
status=STATUS_Z3_URL,
Expand All @@ -179,7 +186,8 @@
command_mute_on=COMMAND_MUTE_ON_Z3_URL,
command_mute_off=COMMAND_MUTE_OFF_Z3_URL,
command_sel_sound_mode=COMMAND_SEL_SM_URL,
command_netaudio_post=COMMAND_NETAUDIO_POST_URL)
command_netaudio_post=COMMAND_NETAUDIO_POST_URL,
command_set_all_zone_stereo=COMMAND_SET_ZST_URL)

POWER_ON = "ON"
POWER_OFF = "OFF"
Expand Down Expand Up @@ -497,7 +505,8 @@ def _update_avr_2016(self):
"""
# Collect tags for AppCommand.xml call
tags = ["GetAllZonePowerStatus", "GetAllZoneSource",
"GetAllZoneVolume", "GetAllZoneMuteStatus"]
"GetAllZoneVolume", "GetAllZoneMuteStatus",
"GetSurroundModeStatus"]
# Execute call
root = self.exec_appcommand_post(tags)
# Check result
Expand Down Expand Up @@ -547,6 +556,10 @@ def _update_avr_2016(self):
_LOGGER.error((
"Input function list for Denon receiver at host %s "
"could not be updated."), self._host)
try:
self._sound_mode_raw = root[4][0].text.rstrip()
except (AttributeError, IndexError):
_LOGGER.error("No SoundMode found for the main zone %s", self.zone)

# Now playing information is not implemented for 2016+ models, because
# a HEOS API query needed. So only sync the power state for now.
Expand Down Expand Up @@ -694,6 +707,17 @@ def _get_support_sound_mode(self):
"""
Get if sound mode is supported from device.

Method executes the method for the current receiver type.
"""
if self._receiver_type == AVR_X_2016.type:
return self._get_support_sound_mode_avr_2016()
else:
return self._get_support_sound_mode_avr()

def _get_support_sound_mode_avr(self):
"""
Get if sound mode is supported from device.

Method queries device via HTTP.
Returns "True" if sound mode supported and "False" if not.
This method is for pre 2016 AVR(-X) devices
Expand Down Expand Up @@ -730,6 +754,16 @@ def _get_support_sound_mode(self):
self._support_sound_mode = True
return True

def _get_support_sound_mode_avr_2016(self):
"""
Get if sound mode is supported from device.

Method enables sound mode.
Returns "True" in all cases for 2016 AVR(-X) devices
"""
self._support_sound_mode = True
return True

def _get_renamed_deleted_sources(self):
"""
Get renamed and deleted sources lists from receiver .
Expand Down Expand Up @@ -1376,6 +1410,27 @@ def sound_mode(self, sound_mode):
"""Setter function for sound_mode to switch sound_mode of device."""
self.set_sound_mode(sound_mode)

def _set_all_zone_stereo(self, zst_on):
"""
Set All Zone Stereo option on the device.

Calls command to activate/deactivate the mode
Return "True" when successfully sent.
"""
command_url = self._urls.command_set_all_zone_stereo
if zst_on:
command_url += "ZST ON"
else:
command_url += "ZST OFF"

try:
return self.send_get_command(command_url)
except requests.exceptions.RequestException:
_LOGGER.error(
"Connection error: unable to set All Zone Stereo to %s",
zst_on)
return False

def set_sound_mode(self, sound_mode):
"""
Set sound_mode of device.
Expand All @@ -1384,6 +1439,15 @@ def set_sound_mode(self, sound_mode):
"sound_mode_list".
Return "True" on success and "False" on fail.
"""
if sound_mode == ALL_ZONE_STEREO:
if self._set_all_zone_stereo(True):
self._sound_mode_raw = ALL_ZONE_STEREO
return True
else:
return False
if self._sound_mode_raw == ALL_ZONE_STEREO:
if not self._set_all_zone_stereo(False):
return False
# For selection of sound mode other names then at receiving sound modes
# have to be used
# Therefore source mapping is needed to get sound_mode
Expand Down