Get A/V info for Onkyo receivers (#34477)

* Get A/V info for Onkyo receivers

* Fix lint errors

* Remove blank line

* Trigger CI
This commit is contained in:
On Freund 2021-01-14 10:39:11 +02:00 committed by GitHub
parent e0c8b1aab6
commit 2ac658d257
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -93,6 +93,9 @@ TIMEOUT_MESSAGE = "Timeout waiting for response."
ATTR_HDMI_OUTPUT = "hdmi_output"
ATTR_PRESET = "preset"
ATTR_AUDIO_INFORMATION = "audio_information"
ATTR_VIDEO_INFORMATION = "video_information"
ATTR_VIDEO_OUT = "video_out"
ACCEPTED_VALUES = [
"no",
@ -115,6 +118,22 @@ ONKYO_SELECT_OUTPUT_SCHEMA = vol.Schema(
SERVICE_SELECT_HDMI_OUTPUT = "onkyo_select_hdmi_output"
def _parse_onkyo_tuple(tup):
"""Parse a tuple returned from the eiscp library."""
if len(tup) < 2:
return None
if isinstance(tup[1], str):
return tup[1].split(",")
return tup[1]
def _tuple_get(tup, index, default=None):
"""Return a tuple item at index or a default value if it doesn't exist."""
return (tup[index : index + 1] or [default])[0]
def determine_zones(receiver):
"""Determine what zones are available for the receiver."""
out = {"zone2": False, "zone3": False}
@ -229,9 +248,17 @@ class OnkyoDevice(MediaPlayerEntity):
self._muted = False
self._volume = 0
self._pwstate = STATE_OFF
self._name = (
name or f"{receiver.info['model_name']}_{receiver.info['identifier']}"
)
if name:
# not discovered
self._name = name
self._unique_id = None
else:
# discovered
self._unique_id = (
f"{receiver.info['model_name']}_{receiver.info['identifier']}"
)
self._name = self._unique_id
self._max_volume = max_volume
self._receiver_max_volume = receiver_max_volume
self._current_source = None
@ -265,6 +292,10 @@ class OnkyoDevice(MediaPlayerEntity):
self._pwstate = STATE_ON
else:
self._pwstate = STATE_OFF
self._attributes.pop(ATTR_AUDIO_INFORMATION, None)
self._attributes.pop(ATTR_VIDEO_INFORMATION, None)
self._attributes.pop(ATTR_PRESET, None)
self._attributes.pop(ATTR_VIDEO_OUT, None)
return
volume_raw = self.command("volume query")
@ -278,20 +309,19 @@ class OnkyoDevice(MediaPlayerEntity):
else:
hdmi_out_raw = []
preset_raw = self.command("preset query")
audio_information_raw = self.command("audio-information query")
video_information_raw = self.command("video-information query")
if not (volume_raw and mute_raw and current_source_raw):
return
# eiscp can return string or tuple. Make everything tuples.
if isinstance(current_source_raw[1], str):
current_source_tuples = (current_source_raw[0], (current_source_raw[1],))
else:
current_source_tuples = current_source_raw
sources = _parse_onkyo_tuple(current_source_raw)
for source in current_source_tuples[1]:
for source in sources:
if source in self._source_mapping:
self._current_source = self._source_mapping[source]
break
self._current_source = "_".join(current_source_tuples[1])
self._current_source = "_".join(sources)
if preset_raw and self._current_source.lower() == "radio":
self._attributes[ATTR_PRESET] = preset_raw[1]
elif ATTR_PRESET in self._attributes:
@ -303,12 +333,20 @@ class OnkyoDevice(MediaPlayerEntity):
self._receiver_max_volume * self._max_volume / 100
)
self._parse_audio_inforamtion(audio_information_raw)
self._parse_video_inforamtion(video_information_raw)
if not hdmi_out_raw:
return
self._attributes["video_out"] = ",".join(hdmi_out_raw[1])
self._attributes[ATTR_VIDEO_OUT] = ",".join(hdmi_out_raw[1])
if hdmi_out_raw[1] == "N/A":
self._hdmi_out_supported = False
@property
def unique_id(self):
"""Return unique ID for this device."""
return self._unique_id
@property
def name(self):
"""Return the name of the device."""
@ -402,6 +440,37 @@ class OnkyoDevice(MediaPlayerEntity):
"""Set hdmi-out."""
self.command(f"hdmi-output-selector={output}")
def _parse_audio_inforamtion(self, audio_information_raw):
values = _parse_onkyo_tuple(audio_information_raw)
if values:
info = {
"format": _tuple_get(values, 1),
"input_frequency": _tuple_get(values, 2),
"input_channels": _tuple_get(values, 3),
"listening_mode": _tuple_get(values, 4),
"output_channels": _tuple_get(values, 5),
"output_frequency": _tuple_get(values, 6),
}
self._attributes[ATTR_AUDIO_INFORMATION] = info
else:
self._attributes.pop(ATTR_AUDIO_INFORMATION, None)
def _parse_video_inforamtion(self, video_information_raw):
values = _parse_onkyo_tuple(video_information_raw)
if values:
info = {
"input_resolution": _tuple_get(values, 1),
"input_color_schema": _tuple_get(values, 2),
"input_color_depth": _tuple_get(values, 3),
"output_resolution": _tuple_get(values, 5),
"output_color_schema": _tuple_get(values, 6),
"output_color_depth": _tuple_get(values, 7),
"picture_mode": _tuple_get(values, 8),
}
self._attributes[ATTR_VIDEO_INFORMATION] = info
else:
self._attributes.pop(ATTR_VIDEO_INFORMATION, None)
class OnkyoDeviceZone(OnkyoDevice):
"""Representation of an Onkyo device's extra zone."""