denonavr 1.2.0__py3-none-any.whl → 1.3.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- denonavr/__init__.py +1 -1
- denonavr/api.py +7 -5
- denonavr/appcommand.py +48 -12
- denonavr/audyssey.py +26 -23
- denonavr/const.py +426 -141
- denonavr/decorators.py +2 -3
- denonavr/denonavr.py +140 -101
- denonavr/dirac.py +5 -5
- denonavr/foundation.py +382 -294
- denonavr/input.py +57 -24
- denonavr/soundmode.py +46 -32
- denonavr/volume.py +33 -36
- {denonavr-1.2.0.dist-info → denonavr-1.3.1.dist-info}/METADATA +1 -1
- denonavr-1.3.1.dist-info/RECORD +20 -0
- {denonavr-1.2.0.dist-info → denonavr-1.3.1.dist-info}/WHEEL +1 -1
- denonavr-1.2.0.dist-info/RECORD +0 -20
- {denonavr-1.2.0.dist-info → denonavr-1.3.1.dist-info}/licenses/LICENSE +0 -0
- {denonavr-1.2.0.dist-info → denonavr-1.3.1.dist-info}/top_level.txt +0 -0
denonavr/input.py
CHANGED
|
@@ -28,6 +28,7 @@ from .const import (
|
|
|
28
28
|
DENON_ATTR_SETATTR,
|
|
29
29
|
HDTUNER_SOURCES,
|
|
30
30
|
MAIN_ZONE,
|
|
31
|
+
NETAUDIO_PLAYING,
|
|
31
32
|
NETAUDIO_SOURCES,
|
|
32
33
|
PLAYING_SOURCES,
|
|
33
34
|
POWER_ON,
|
|
@@ -36,6 +37,7 @@ from .const import (
|
|
|
36
37
|
STATE_ON,
|
|
37
38
|
STATE_PAUSED,
|
|
38
39
|
STATE_PLAYING,
|
|
40
|
+
STATE_STOPPED,
|
|
39
41
|
STATIC_ALBUM_URL,
|
|
40
42
|
TELNET_MAPPING,
|
|
41
43
|
TUNER_SOURCES,
|
|
@@ -73,14 +75,16 @@ def set_input_func(
|
|
|
73
75
|
if value is None:
|
|
74
76
|
return value
|
|
75
77
|
# Map from input_func_map
|
|
76
|
-
#
|
|
77
|
-
if
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
78
|
+
# Some inputs are not always listed in available sources
|
|
79
|
+
if (
|
|
80
|
+
value in {"AirPlay", "Internet Radio", "Media Server", "NET"}
|
|
81
|
+
and value not in instance._input_func_map
|
|
82
|
+
):
|
|
83
|
+
instance._additional_input_funcs.add(value)
|
|
84
|
+
instance._input_func_map[value] = value
|
|
85
|
+
instance._input_func_map_rev[value] = value
|
|
86
|
+
instance._netaudio_func_list.append(value)
|
|
87
|
+
instance._playing_func_list.append(value)
|
|
84
88
|
try:
|
|
85
89
|
input_func = instance._input_func_map_rev[value]
|
|
86
90
|
except KeyError:
|
|
@@ -174,7 +178,8 @@ class DenonAVRInput(DenonAVRFoundation):
|
|
|
174
178
|
),
|
|
175
179
|
default=attr.Factory(set),
|
|
176
180
|
)
|
|
177
|
-
_callback_tasks: Set[asyncio.Task] = attr.ib(attr.Factory(set))
|
|
181
|
+
_callback_tasks: Set[asyncio.Task] = attr.ib(default=attr.Factory(set))
|
|
182
|
+
_netaudio_state: str = attr.ib(converter=fix_string, default="")
|
|
178
183
|
|
|
179
184
|
# Update tags for attributes
|
|
180
185
|
# AppCommand.xml interface
|
|
@@ -235,7 +240,7 @@ class DenonAVRInput(DenonAVRFoundation):
|
|
|
235
240
|
self._unset_media_state()
|
|
236
241
|
self._state = STATE_OFF
|
|
237
242
|
elif self._schedule_media_updates():
|
|
238
|
-
self._state =
|
|
243
|
+
self._state = STATE_ON
|
|
239
244
|
else:
|
|
240
245
|
self._unset_media_state()
|
|
241
246
|
self._state = STATE_ON
|
|
@@ -287,7 +292,18 @@ class DenonAVRInput(DenonAVRFoundation):
|
|
|
287
292
|
if self._input_func not in self._netaudio_func_list:
|
|
288
293
|
return
|
|
289
294
|
|
|
290
|
-
if parameter.startswith("
|
|
295
|
+
if parameter.startswith("0"):
|
|
296
|
+
if parameter[1:].startswith(NETAUDIO_PLAYING):
|
|
297
|
+
# It is not possible to see if the device is playing or paused.
|
|
298
|
+
# We assume it is playing first.
|
|
299
|
+
# Then, the state might be changed by async_play, async_pause
|
|
300
|
+
# and async_stop.
|
|
301
|
+
if self._state not in {STATE_PLAYING, STATE_PAUSED, STATE_STOPPED}:
|
|
302
|
+
self._state = STATE_PLAYING
|
|
303
|
+
else:
|
|
304
|
+
self._state = STATE_STOPPED
|
|
305
|
+
self._netaudio_state = parameter[1:]
|
|
306
|
+
elif parameter.startswith("1"):
|
|
291
307
|
self._title = parameter[1:]
|
|
292
308
|
elif parameter.startswith("2"):
|
|
293
309
|
self._artist = parameter[1:]
|
|
@@ -532,7 +548,7 @@ class DenonAVRInput(DenonAVRFoundation):
|
|
|
532
548
|
|
|
533
549
|
self._replace_duplicate_sources(renamed_sources)
|
|
534
550
|
|
|
535
|
-
return
|
|
551
|
+
return renamed_sources, deleted_sources
|
|
536
552
|
|
|
537
553
|
async def async_get_changed_sources_status_xml(
|
|
538
554
|
self, cache_id: Optional[Hashable] = None
|
|
@@ -622,7 +638,7 @@ class DenonAVRInput(DenonAVRFoundation):
|
|
|
622
638
|
|
|
623
639
|
self._replace_duplicate_sources(renamed_sources)
|
|
624
640
|
|
|
625
|
-
return
|
|
641
|
+
return renamed_sources, deleted_sources
|
|
626
642
|
|
|
627
643
|
async def async_update_inputfuncs(
|
|
628
644
|
self, global_update: bool = False, cache_id: Optional[Hashable] = None
|
|
@@ -821,6 +837,7 @@ class DenonAVRInput(DenonAVRFoundation):
|
|
|
821
837
|
"_title": "./szLine/value[2]",
|
|
822
838
|
"_artist": "./szLine/value[3]",
|
|
823
839
|
"_album": "./szLine/value[5]",
|
|
840
|
+
"_netaudio_state": "./szLine/value[1]",
|
|
824
841
|
}
|
|
825
842
|
self._band = None
|
|
826
843
|
self._frequency = None
|
|
@@ -870,8 +887,16 @@ class DenonAVRInput(DenonAVRFoundation):
|
|
|
870
887
|
port=self._device.api.port,
|
|
871
888
|
hash=hash((self._title, self._artist, self._album)),
|
|
872
889
|
)
|
|
873
|
-
|
|
874
|
-
|
|
890
|
+
|
|
891
|
+
if self._netaudio_state.startswith(NETAUDIO_PLAYING):
|
|
892
|
+
# It is not possible to see if the device is playing or paused.
|
|
893
|
+
# We assume it is playing first.
|
|
894
|
+
# Then, the state might be changed by async_play, async_pause
|
|
895
|
+
# and async_stop.
|
|
896
|
+
if self._state not in {STATE_PLAYING, STATE_PAUSED, STATE_STOPPED}:
|
|
897
|
+
self._state = STATE_PLAYING
|
|
898
|
+
else:
|
|
899
|
+
self._state = STATE_STOPPED
|
|
875
900
|
|
|
876
901
|
await self._async_test_image_accessible()
|
|
877
902
|
|
|
@@ -1078,13 +1103,9 @@ class DenonAVRInput(DenonAVRFoundation):
|
|
|
1078
1103
|
await self.async_play()
|
|
1079
1104
|
|
|
1080
1105
|
async def async_play(self) -> None:
|
|
1081
|
-
"""Send play command to receiver command
|
|
1106
|
+
"""Send play command to receiver command."""
|
|
1082
1107
|
# Use pause command only for sources which support NETAUDIO
|
|
1083
1108
|
if self._input_func in self._netaudio_func_list:
|
|
1084
|
-
# In fact play command is a play/pause toggle. Thus checking state
|
|
1085
|
-
if self._state == STATE_PLAYING:
|
|
1086
|
-
_LOGGER.info("Already playing, play command not sent")
|
|
1087
|
-
return
|
|
1088
1109
|
if self._device.telnet_available:
|
|
1089
1110
|
await self._device.telnet_api.async_send_commands(
|
|
1090
1111
|
self._device.telnet_commands.command_play
|
|
@@ -1094,12 +1115,12 @@ class DenonAVRInput(DenonAVRFoundation):
|
|
|
1094
1115
|
self._state = STATE_PLAYING
|
|
1095
1116
|
|
|
1096
1117
|
async def async_pause(self) -> None:
|
|
1097
|
-
"""Send pause command to receiver command
|
|
1118
|
+
"""Send pause command to receiver command."""
|
|
1098
1119
|
# Use pause command only for sources which support NETAUDIO
|
|
1099
1120
|
if self._input_func in self._netaudio_func_list:
|
|
1100
1121
|
if self._device.telnet_available:
|
|
1101
1122
|
await self._device.telnet_api.async_send_commands(
|
|
1102
|
-
self._device.telnet_commands.
|
|
1123
|
+
self._device.telnet_commands.command_pause
|
|
1103
1124
|
)
|
|
1104
1125
|
else:
|
|
1105
1126
|
await self._device.api.async_get_command(
|
|
@@ -1107,8 +1128,20 @@ class DenonAVRInput(DenonAVRFoundation):
|
|
|
1107
1128
|
)
|
|
1108
1129
|
self._state = STATE_PAUSED
|
|
1109
1130
|
|
|
1131
|
+
async def async_stop(self) -> None:
|
|
1132
|
+
"""Send stop command to receiver command."""
|
|
1133
|
+
# Use stop command only for sources which support NETAUDIO
|
|
1134
|
+
if self._input_func in self._netaudio_func_list:
|
|
1135
|
+
if self._device.telnet_available:
|
|
1136
|
+
await self._device.telnet_api.async_send_commands(
|
|
1137
|
+
self._device.telnet_commands.command_stop
|
|
1138
|
+
)
|
|
1139
|
+
else:
|
|
1140
|
+
await self._device.api.async_get_command(self._device.urls.command_stop)
|
|
1141
|
+
self._state = STATE_STOPPED
|
|
1142
|
+
|
|
1110
1143
|
async def async_previous_track(self) -> None:
|
|
1111
|
-
"""Send previous track command to receiver command
|
|
1144
|
+
"""Send previous track command to receiver command."""
|
|
1112
1145
|
# Use previous track button only for sources which support NETAUDIO
|
|
1113
1146
|
if self._input_func in self._netaudio_func_list:
|
|
1114
1147
|
body = {
|
|
@@ -1121,7 +1154,7 @@ class DenonAVRInput(DenonAVRFoundation):
|
|
|
1121
1154
|
)
|
|
1122
1155
|
|
|
1123
1156
|
async def async_next_track(self) -> None:
|
|
1124
|
-
"""Send next track command to receiver command
|
|
1157
|
+
"""Send next track command to receiver command."""
|
|
1125
1158
|
# Use next track button only for sources which support NETAUDIO
|
|
1126
1159
|
if self._input_func in self._netaudio_func_list:
|
|
1127
1160
|
body = {
|
denonavr/soundmode.py
CHANGED
|
@@ -19,18 +19,18 @@ from .appcommand import AppCommands
|
|
|
19
19
|
from .const import (
|
|
20
20
|
ALL_ZONE_STEREO,
|
|
21
21
|
AURO_3D_MODE_MAP,
|
|
22
|
-
|
|
22
|
+
AURO_3D_MODE_MAP_REVERSE,
|
|
23
23
|
AURO_MATIC_3D_PRESET_MAP,
|
|
24
|
-
|
|
24
|
+
AURO_MATIC_3D_PRESET_MAP_REVERSE,
|
|
25
25
|
DAC_FILTERS_MAP,
|
|
26
|
-
|
|
26
|
+
DAC_FILTERS_MAP_REVERSE,
|
|
27
27
|
DENON_ATTR_SETATTR,
|
|
28
28
|
DIALOG_ENHANCER_LEVEL_MAP,
|
|
29
|
-
|
|
29
|
+
DIALOG_ENHANCER_LEVEL_MAP_REVERSE,
|
|
30
30
|
EFFECT_SPEAKER_SELECTION_MAP,
|
|
31
|
-
|
|
31
|
+
EFFECT_SPEAKER_SELECTION_MAP_REVERSE,
|
|
32
32
|
MDAX_MAP,
|
|
33
|
-
|
|
33
|
+
MDAX_MAP_REVERSE,
|
|
34
34
|
SOUND_MODE_MAPPING,
|
|
35
35
|
Auro3DModes,
|
|
36
36
|
AuroMatic3DPresets,
|
|
@@ -125,18 +125,18 @@ class DenonAVRSoundMode(DenonAVRFoundation):
|
|
|
125
125
|
converter=attr.converters.optional(convert_on_off_bool), default=None
|
|
126
126
|
)
|
|
127
127
|
_dialog_enhancer_level: Optional[str] = attr.ib(
|
|
128
|
-
converter=attr.converters.optional(
|
|
128
|
+
converter=attr.converters.optional(DIALOG_ENHANCER_LEVEL_MAP.get), default=None
|
|
129
129
|
)
|
|
130
130
|
_dialog_enhancer_levels = get_args(DialogEnhancerLevels)
|
|
131
131
|
_auromatic_3d_preset: Optional[str] = attr.ib(
|
|
132
|
-
converter=attr.converters.optional(
|
|
132
|
+
converter=attr.converters.optional(AURO_MATIC_3D_PRESET_MAP.get), default=None
|
|
133
133
|
)
|
|
134
134
|
_auromatic_3d_presets = get_args(AuroMatic3DPresets)
|
|
135
135
|
_auromatic_3d_strength: Optional[int] = attr.ib(
|
|
136
136
|
converter=attr.converters.optional(int), default=None
|
|
137
137
|
)
|
|
138
138
|
_auro_3d_mode: Optional[str] = attr.ib(
|
|
139
|
-
converter=attr.converters.optional(
|
|
139
|
+
converter=attr.converters.optional(AURO_3D_MODE_MAP.get), default=None
|
|
140
140
|
)
|
|
141
141
|
_auro_3d_modes = get_args(Auro3DModes)
|
|
142
142
|
_dialog_control: Optional[int] = attr.ib(
|
|
@@ -146,17 +146,18 @@ class DenonAVRSoundMode(DenonAVRFoundation):
|
|
|
146
146
|
converter=attr.converters.optional(convert_on_off_bool), default=None
|
|
147
147
|
)
|
|
148
148
|
_effect_speaker_selection: Optional[str] = attr.ib(
|
|
149
|
-
converter=attr.converters.optional(
|
|
149
|
+
converter=attr.converters.optional(EFFECT_SPEAKER_SELECTION_MAP.get),
|
|
150
|
+
default=None,
|
|
150
151
|
)
|
|
151
152
|
_effect_speakers = get_args(EffectSpeakers)
|
|
152
153
|
_drc: Optional[str] = attr.ib(converter=attr.converters.optional(str), default=None)
|
|
153
154
|
_drcs = get_args(DRCs)
|
|
154
155
|
_mdax: Optional[str] = attr.ib(
|
|
155
|
-
converter=attr.converters.optional(
|
|
156
|
+
converter=attr.converters.optional(MDAX_MAP.get), default=None
|
|
156
157
|
)
|
|
157
158
|
_mdaxs = get_args(MDAXs)
|
|
158
159
|
_dac_filter: Optional[str] = attr.ib(
|
|
159
|
-
converter=attr.converters.optional(
|
|
160
|
+
converter=attr.converters.optional(DAC_FILTERS_MAP.get), default=None
|
|
160
161
|
)
|
|
161
162
|
_dac_filters = get_args(DACFilters)
|
|
162
163
|
_sound_mode_map: Dict[str, list] = attr.ib(
|
|
@@ -264,9 +265,9 @@ class DenonAVRSoundMode(DenonAVRFoundation):
|
|
|
264
265
|
elif key_value[0] == "IMAXAUD":
|
|
265
266
|
self._imax_audio_settings = parameter[8:]
|
|
266
267
|
elif key_value[0] == "IMAXHPF":
|
|
267
|
-
self._imax_hpf =
|
|
268
|
+
self._imax_hpf = parameter[8:]
|
|
268
269
|
elif key_value[0] == "IMAXLPF":
|
|
269
|
-
self._imax_lpf =
|
|
270
|
+
self._imax_lpf = parameter[8:]
|
|
270
271
|
elif key_value[0] == "IMAXSWM":
|
|
271
272
|
self._imax_subwoofer_mode = parameter[8:]
|
|
272
273
|
elif key_value[0] == "IMAXSWO":
|
|
@@ -292,9 +293,7 @@ class DenonAVRSoundMode(DenonAVRFoundation):
|
|
|
292
293
|
def _dialog_enhancer_callback(self, zone: str, event: str, parameter: str) -> None:
|
|
293
294
|
"""Handle a Dialog Enhancer change event."""
|
|
294
295
|
if parameter[:3] == "DEH":
|
|
295
|
-
self._dialog_enhancer_level =
|
|
296
|
-
parameter[4:]
|
|
297
|
-
]
|
|
296
|
+
self._dialog_enhancer_level = parameter[4:]
|
|
298
297
|
|
|
299
298
|
def _auro_callback(self, zone: str, event: str, parameter: str) -> None:
|
|
300
299
|
"""Handle a Auro change event."""
|
|
@@ -303,11 +302,11 @@ class DenonAVRSoundMode(DenonAVRFoundation):
|
|
|
303
302
|
return
|
|
304
303
|
|
|
305
304
|
if key_value[0] == "AUROPR":
|
|
306
|
-
self._auromatic_3d_preset =
|
|
305
|
+
self._auromatic_3d_preset = parameter[7:]
|
|
307
306
|
elif key_value[0] == "AUROST":
|
|
308
|
-
self._auromatic_3d_strength =
|
|
307
|
+
self._auromatic_3d_strength = parameter[7:]
|
|
309
308
|
elif key_value[0] == "AUROMODE":
|
|
310
|
-
self._auro_3d_mode =
|
|
309
|
+
self._auro_3d_mode = parameter[9:]
|
|
311
310
|
|
|
312
311
|
def _dialog_control_callback(self, zone: str, event: str, parameter: str) -> None:
|
|
313
312
|
"""Handle a Dialog Control change event."""
|
|
@@ -315,7 +314,7 @@ class DenonAVRSoundMode(DenonAVRFoundation):
|
|
|
315
314
|
if len(key_value) != 2 or key_value[0] != "DIC":
|
|
316
315
|
return
|
|
317
316
|
|
|
318
|
-
self._dialog_control =
|
|
317
|
+
self._dialog_control = key_value[1]
|
|
319
318
|
|
|
320
319
|
def _speaker_virtualizer_callback(
|
|
321
320
|
self, zone: str, event: str, parameter: str
|
|
@@ -335,9 +334,7 @@ class DenonAVRSoundMode(DenonAVRFoundation):
|
|
|
335
334
|
if len(key_value) != 2 or key_value[0] != "SP":
|
|
336
335
|
return
|
|
337
336
|
|
|
338
|
-
self._effect_speaker_selection =
|
|
339
|
-
key_value[1]
|
|
340
|
-
]
|
|
337
|
+
self._effect_speaker_selection = key_value[1]
|
|
341
338
|
|
|
342
339
|
def _drc_callback(self, zone: str, event: str, parameter: str) -> None:
|
|
343
340
|
"""Handle a DRC change event."""
|
|
@@ -353,7 +350,7 @@ class DenonAVRSoundMode(DenonAVRFoundation):
|
|
|
353
350
|
if len(key_value) != 2 or key_value[0] != "MDAX":
|
|
354
351
|
return
|
|
355
352
|
|
|
356
|
-
self._mdax =
|
|
353
|
+
self._mdax = key_value[1]
|
|
357
354
|
|
|
358
355
|
def _dac_filter_callback(self, zone: str, event: str, parameter: str) -> None:
|
|
359
356
|
"""Handle a DAC Filter change event."""
|
|
@@ -361,7 +358,7 @@ class DenonAVRSoundMode(DenonAVRFoundation):
|
|
|
361
358
|
if len(key_value) != 2 or key_value[0] != "DACFIL":
|
|
362
359
|
return
|
|
363
360
|
|
|
364
|
-
self._dac_filter =
|
|
361
|
+
self._dac_filter = key_value[1]
|
|
365
362
|
|
|
366
363
|
async def async_update(
|
|
367
364
|
self, global_update: bool = False, cache_id: Optional[Hashable] = None
|
|
@@ -1057,7 +1054,7 @@ class DenonAVRSoundMode(DenonAVRFoundation):
|
|
|
1057
1054
|
if level not in self._dialog_enhancer_levels:
|
|
1058
1055
|
raise AvrCommandError(f"{level} is not a valid dialog enhancer level")
|
|
1059
1056
|
|
|
1060
|
-
level_mapped =
|
|
1057
|
+
level_mapped = DIALOG_ENHANCER_LEVEL_MAP_REVERSE[level]
|
|
1061
1058
|
if self._device.telnet_available:
|
|
1062
1059
|
await self._device.telnet_api.async_send_commands(
|
|
1063
1060
|
self._device.telnet_commands.command_dialog_enhancer.format(
|
|
@@ -1074,7 +1071,7 @@ class DenonAVRSoundMode(DenonAVRFoundation):
|
|
|
1074
1071
|
if preset not in self._auromatic_3d_presets:
|
|
1075
1072
|
raise AvrCommandError(f"{preset} is not a valid Auro-Matic 3D Preset")
|
|
1076
1073
|
|
|
1077
|
-
local_preset =
|
|
1074
|
+
local_preset = AURO_MATIC_3D_PRESET_MAP_REVERSE[preset]
|
|
1078
1075
|
if self._device.telnet_available:
|
|
1079
1076
|
await self._device.telnet_api.async_send_commands(
|
|
1080
1077
|
self._device.telnet_commands.command_auromatic_3d_preset.format(
|
|
@@ -1142,7 +1139,7 @@ class DenonAVRSoundMode(DenonAVRFoundation):
|
|
|
1142
1139
|
if mode not in self._auro_3d_modes:
|
|
1143
1140
|
raise AvrCommandError(f"{mode} is not a valid Auro 3D Mode")
|
|
1144
1141
|
|
|
1145
|
-
local_mode =
|
|
1142
|
+
local_mode = AURO_3D_MODE_MAP_REVERSE[mode]
|
|
1146
1143
|
if self._device.telnet_available:
|
|
1147
1144
|
await self._device.telnet_api.async_send_commands(
|
|
1148
1145
|
self._device.telnet_commands.command_auro_3d_mode.format(
|
|
@@ -1239,7 +1236,7 @@ class DenonAVRSoundMode(DenonAVRFoundation):
|
|
|
1239
1236
|
if mode not in self._effect_speakers:
|
|
1240
1237
|
raise AvrCommandError(f"{mode} is not a valid effect speaker selection")
|
|
1241
1238
|
|
|
1242
|
-
local_mode =
|
|
1239
|
+
local_mode = EFFECT_SPEAKER_SELECTION_MAP_REVERSE[mode]
|
|
1243
1240
|
if self._device.telnet_available:
|
|
1244
1241
|
await self._device.telnet_api.async_send_commands(
|
|
1245
1242
|
self._device.telnet_commands.command_effect_speaker_selection.format(
|
|
@@ -1279,7 +1276,7 @@ class DenonAVRSoundMode(DenonAVRFoundation):
|
|
|
1279
1276
|
if mode not in self._mdaxs:
|
|
1280
1277
|
raise AvrCommandError(f"{mode} is not a valid M-DAX mode")
|
|
1281
1278
|
|
|
1282
|
-
local_mode =
|
|
1279
|
+
local_mode = MDAX_MAP_REVERSE[mode]
|
|
1283
1280
|
if self._device.telnet_available:
|
|
1284
1281
|
await self._device.telnet_api.async_send_commands(
|
|
1285
1282
|
self._device.telnet_commands.command_mdax.format(mode=local_mode)
|
|
@@ -1301,7 +1298,7 @@ class DenonAVRSoundMode(DenonAVRFoundation):
|
|
|
1301
1298
|
if mode not in self._dac_filters:
|
|
1302
1299
|
raise AvrCommandError(f"{mode} is not a valid DAC Filter mode")
|
|
1303
1300
|
|
|
1304
|
-
local_mode =
|
|
1301
|
+
local_mode = DAC_FILTERS_MAP_REVERSE[mode]
|
|
1305
1302
|
if self._device.telnet_available:
|
|
1306
1303
|
await self._device.telnet_api.async_send_commands(
|
|
1307
1304
|
self._device.telnet_commands.command_dac_filter.format(mode=local_mode)
|
|
@@ -1311,6 +1308,23 @@ class DenonAVRSoundMode(DenonAVRFoundation):
|
|
|
1311
1308
|
self._device.urls.command_dac_filter.format(mode=local_mode)
|
|
1312
1309
|
)
|
|
1313
1310
|
|
|
1311
|
+
async def async_dolby_atmos_toggle(self):
|
|
1312
|
+
"""Toggle Dolby Atmos sound mode."""
|
|
1313
|
+
if self._device.telnet_available:
|
|
1314
|
+
command = (
|
|
1315
|
+
self._device.telnet_commands.command_dolby_atmos_toggle_denon
|
|
1316
|
+
if self._device.is_denon
|
|
1317
|
+
else self._device.telnet_commands.command_dolby_atmos_toggle_marantz
|
|
1318
|
+
)
|
|
1319
|
+
await self._device.telnet_api.async_send_commands(command)
|
|
1320
|
+
else:
|
|
1321
|
+
command = (
|
|
1322
|
+
self._device.urls.command_dolby_atmos_toggle_denon
|
|
1323
|
+
if self._device.is_denon
|
|
1324
|
+
else self._device.urls.command_dolby_atmos_toggle_marantz
|
|
1325
|
+
)
|
|
1326
|
+
await self._device.api.async_get_command(command)
|
|
1327
|
+
|
|
1314
1328
|
|
|
1315
1329
|
def sound_mode_factory(instance: DenonAVRFoundation) -> DenonAVRSoundMode:
|
|
1316
1330
|
"""Create DenonAVRSoundMode at receiver instances."""
|
denonavr/volume.py
CHANGED
|
@@ -16,14 +16,14 @@ import attr
|
|
|
16
16
|
from .appcommand import AppCommands
|
|
17
17
|
from .const import (
|
|
18
18
|
CHANNEL_MAP,
|
|
19
|
-
|
|
19
|
+
CHANNEL_MAP_REVERSE,
|
|
20
20
|
CHANNEL_VOLUME_MAP,
|
|
21
|
-
|
|
21
|
+
CHANNEL_VOLUME_MAP_REVERSE,
|
|
22
22
|
DENON_ATTR_SETATTR,
|
|
23
23
|
MAIN_ZONE,
|
|
24
24
|
STATE_ON,
|
|
25
25
|
SUBWOOFERS_MAP,
|
|
26
|
-
|
|
26
|
+
SUBWOOFERS_MAP_REVERSE,
|
|
27
27
|
Channels,
|
|
28
28
|
Subwoofers,
|
|
29
29
|
)
|
|
@@ -119,7 +119,7 @@ class DenonAVRVolume(DenonAVRFoundation):
|
|
|
119
119
|
channel_volume = parameter.split()
|
|
120
120
|
if (
|
|
121
121
|
len(channel_volume) != 2
|
|
122
|
-
or channel_volume[0] not in
|
|
122
|
+
or channel_volume[0] not in CHANNEL_MAP
|
|
123
123
|
or channel_volume[1] not in CHANNEL_VOLUME_MAP
|
|
124
124
|
):
|
|
125
125
|
return
|
|
@@ -127,7 +127,7 @@ class DenonAVRVolume(DenonAVRFoundation):
|
|
|
127
127
|
if self._channel_volumes is None:
|
|
128
128
|
self._channel_volumes = {}
|
|
129
129
|
|
|
130
|
-
channel =
|
|
130
|
+
channel = CHANNEL_MAP[channel_volume[0]]
|
|
131
131
|
volume = channel_volume[1]
|
|
132
132
|
self._channel_volumes[channel] = CHANNEL_VOLUME_MAP[volume]
|
|
133
133
|
|
|
@@ -142,16 +142,13 @@ class DenonAVRVolume(DenonAVRFoundation):
|
|
|
142
142
|
return
|
|
143
143
|
|
|
144
144
|
subwoofer_volume = parameter.split()
|
|
145
|
-
if (
|
|
146
|
-
len(subwoofer_volume) != 2
|
|
147
|
-
or subwoofer_volume[0] not in SUBWOOFERS_MAP_LABELS
|
|
148
|
-
):
|
|
145
|
+
if len(subwoofer_volume) != 2 or subwoofer_volume[0] not in SUBWOOFERS_MAP:
|
|
149
146
|
return
|
|
150
147
|
|
|
151
148
|
if self._subwoofer_levels is None:
|
|
152
149
|
self._subwoofer_levels = {}
|
|
153
150
|
|
|
154
|
-
subwoofer =
|
|
151
|
+
subwoofer = SUBWOOFERS_MAP[subwoofer_volume[0]]
|
|
155
152
|
level = subwoofer_volume[1]
|
|
156
153
|
val = convert_on_off_bool(level)
|
|
157
154
|
if val is not None:
|
|
@@ -306,7 +303,7 @@ class DenonAVRVolume(DenonAVRFoundation):
|
|
|
306
303
|
# Setter #
|
|
307
304
|
##########
|
|
308
305
|
async def async_volume_up(self) -> None:
|
|
309
|
-
"""Volume up receiver
|
|
306
|
+
"""Volume up receiver."""
|
|
310
307
|
if self._device.telnet_available:
|
|
311
308
|
await self._device.telnet_api.async_send_commands(
|
|
312
309
|
self._device.telnet_commands.command_volume_up, skip_confirmation=True
|
|
@@ -317,7 +314,7 @@ class DenonAVRVolume(DenonAVRFoundation):
|
|
|
317
314
|
)
|
|
318
315
|
|
|
319
316
|
async def async_volume_down(self) -> None:
|
|
320
|
-
"""Volume down receiver
|
|
317
|
+
"""Volume down receiver."""
|
|
321
318
|
if self._device.telnet_available:
|
|
322
319
|
await self._device.telnet_api.async_send_commands(
|
|
323
320
|
self._device.telnet_commands.command_volume_down, skip_confirmation=True
|
|
@@ -329,7 +326,7 @@ class DenonAVRVolume(DenonAVRFoundation):
|
|
|
329
326
|
|
|
330
327
|
async def async_set_volume(self, volume: float) -> None:
|
|
331
328
|
"""
|
|
332
|
-
Set receiver volume
|
|
329
|
+
Set receiver volume.
|
|
333
330
|
|
|
334
331
|
Volume is send in a format like -50.0.
|
|
335
332
|
Minimum is -80.0, maximum at 18.0
|
|
@@ -351,7 +348,7 @@ class DenonAVRVolume(DenonAVRFoundation):
|
|
|
351
348
|
)
|
|
352
349
|
|
|
353
350
|
async def async_mute(self, mute: bool) -> None:
|
|
354
|
-
"""Mute receiver
|
|
351
|
+
"""Mute receiver."""
|
|
355
352
|
if mute:
|
|
356
353
|
if self._device.telnet_available:
|
|
357
354
|
await self._device.telnet_api.async_send_commands(
|
|
@@ -372,10 +369,10 @@ class DenonAVRVolume(DenonAVRFoundation):
|
|
|
372
369
|
)
|
|
373
370
|
|
|
374
371
|
async def async_channel_volume_up(self, channel: Channels) -> None:
|
|
375
|
-
"""Increase Channel volume on receiver
|
|
372
|
+
"""Increase Channel volume on receiver."""
|
|
376
373
|
self._is_valid_channel(channel)
|
|
377
374
|
|
|
378
|
-
mapped_channel =
|
|
375
|
+
mapped_channel = CHANNEL_MAP_REVERSE[channel]
|
|
379
376
|
if self._device.telnet_available:
|
|
380
377
|
await self._device.telnet_api.async_send_commands(
|
|
381
378
|
self._device.telnet_commands.command_channel_volume.format(
|
|
@@ -390,10 +387,10 @@ class DenonAVRVolume(DenonAVRFoundation):
|
|
|
390
387
|
)
|
|
391
388
|
|
|
392
389
|
async def async_channel_volume_down(self, channel: Channels) -> None:
|
|
393
|
-
"""Decrease Channel volume on receiver
|
|
390
|
+
"""Decrease Channel volume on receiver."""
|
|
394
391
|
self._is_valid_channel(channel)
|
|
395
392
|
|
|
396
|
-
mapped_channel =
|
|
393
|
+
mapped_channel = CHANNEL_MAP_REVERSE[channel]
|
|
397
394
|
if self._device.telnet_available:
|
|
398
395
|
await self._device.telnet_api.async_send_commands(
|
|
399
396
|
self._device.telnet_commands.command_channel_volume.format(
|
|
@@ -409,17 +406,17 @@ class DenonAVRVolume(DenonAVRFoundation):
|
|
|
409
406
|
|
|
410
407
|
async def async_channel_volume(self, channel: Channels, volume: float) -> None:
|
|
411
408
|
"""
|
|
412
|
-
Set Channel volume on receiver
|
|
409
|
+
Set Channel volume on receiver.
|
|
413
410
|
|
|
414
411
|
:param channel: Channel to set.
|
|
415
412
|
:param volume: Volume to set. Valid values are -12 to 12 with 0.5 steps.
|
|
416
413
|
"""
|
|
417
414
|
self._is_valid_channel(channel)
|
|
418
|
-
if volume not in
|
|
415
|
+
if volume not in CHANNEL_VOLUME_MAP_REVERSE:
|
|
419
416
|
raise AvrCommandError(f"Invalid channel volume: {volume}")
|
|
420
417
|
|
|
421
|
-
mapped_channel =
|
|
422
|
-
mapped_volume =
|
|
418
|
+
mapped_channel = CHANNEL_MAP_REVERSE[channel]
|
|
419
|
+
mapped_volume = CHANNEL_VOLUME_MAP_REVERSE[volume]
|
|
423
420
|
if self._device.telnet_available:
|
|
424
421
|
await self._device.telnet_api.async_send_commands(
|
|
425
422
|
self._device.telnet_commands.command_channel_volume.format(
|
|
@@ -434,7 +431,7 @@ class DenonAVRVolume(DenonAVRFoundation):
|
|
|
434
431
|
)
|
|
435
432
|
|
|
436
433
|
async def async_channel_volumes_reset(self) -> None:
|
|
437
|
-
"""Reset all channel volumes on receiver
|
|
434
|
+
"""Reset all channel volumes on receiver."""
|
|
438
435
|
if self._device.telnet_available:
|
|
439
436
|
await self._device.telnet_api.async_send_commands(
|
|
440
437
|
self._device.telnet_commands.command_channel_volumes_reset
|
|
@@ -445,7 +442,7 @@ class DenonAVRVolume(DenonAVRFoundation):
|
|
|
445
442
|
)
|
|
446
443
|
|
|
447
444
|
async def async_subwoofer_on(self) -> None:
|
|
448
|
-
"""Turn on Subwoofer on receiver
|
|
445
|
+
"""Turn on Subwoofer on receiver."""
|
|
449
446
|
if self._device.telnet_available:
|
|
450
447
|
await self._device.telnet_api.async_send_commands(
|
|
451
448
|
self._device.telnet_commands.command_subwoofer_on_off.format(mode="ON")
|
|
@@ -456,7 +453,7 @@ class DenonAVRVolume(DenonAVRFoundation):
|
|
|
456
453
|
)
|
|
457
454
|
|
|
458
455
|
async def async_subwoofer_off(self) -> None:
|
|
459
|
-
"""Turn off Subwoofer on receiver
|
|
456
|
+
"""Turn off Subwoofer on receiver."""
|
|
460
457
|
if self._device.telnet_available:
|
|
461
458
|
await self._device.telnet_api.async_send_commands(
|
|
462
459
|
self._device.telnet_commands.command_subwoofer_on_off.format(mode="OFF")
|
|
@@ -468,7 +465,7 @@ class DenonAVRVolume(DenonAVRFoundation):
|
|
|
468
465
|
|
|
469
466
|
async def async_subwoofer_toggle(self) -> None:
|
|
470
467
|
"""
|
|
471
|
-
Toggle Subwoofer on receiver
|
|
468
|
+
Toggle Subwoofer on receiver.
|
|
472
469
|
|
|
473
470
|
Only available if using Telnet.
|
|
474
471
|
"""
|
|
@@ -478,9 +475,9 @@ class DenonAVRVolume(DenonAVRFoundation):
|
|
|
478
475
|
await self.async_subwoofer_on()
|
|
479
476
|
|
|
480
477
|
async def async_subwoofer_level_up(self, subwoofer: Subwoofers) -> None:
|
|
481
|
-
"""Increase Subwoofer level on receiver
|
|
478
|
+
"""Increase Subwoofer level on receiver."""
|
|
482
479
|
self._is_valid_subwoofer(subwoofer)
|
|
483
|
-
mapped_subwoofer =
|
|
480
|
+
mapped_subwoofer = SUBWOOFERS_MAP_REVERSE[subwoofer]
|
|
484
481
|
if self._device.telnet_available:
|
|
485
482
|
await self._device.telnet_api.async_send_commands(
|
|
486
483
|
self._device.telnet_commands.command_subwoofer_level.format(
|
|
@@ -495,9 +492,9 @@ class DenonAVRVolume(DenonAVRFoundation):
|
|
|
495
492
|
)
|
|
496
493
|
|
|
497
494
|
async def async_subwoofer_level_down(self, subwoofer: Subwoofers) -> None:
|
|
498
|
-
"""Decrease Subwoofer level on receiver
|
|
495
|
+
"""Decrease Subwoofer level on receiver."""
|
|
499
496
|
self._is_valid_subwoofer(subwoofer)
|
|
500
|
-
mapped_subwoofer =
|
|
497
|
+
mapped_subwoofer = SUBWOOFERS_MAP_REVERSE[subwoofer]
|
|
501
498
|
if self._device.telnet_available:
|
|
502
499
|
await self._device.telnet_api.async_send_commands(
|
|
503
500
|
self._device.telnet_commands.command_subwoofer_level.format(
|
|
@@ -512,7 +509,7 @@ class DenonAVRVolume(DenonAVRFoundation):
|
|
|
512
509
|
)
|
|
513
510
|
|
|
514
511
|
async def async_lfe_up(self) -> None:
|
|
515
|
-
"""Increase LFE on receiver
|
|
512
|
+
"""Increase LFE on receiver."""
|
|
516
513
|
if self._device.telnet_available:
|
|
517
514
|
await self._device.telnet_api.async_send_commands(
|
|
518
515
|
self._device.telnet_commands.command_lfe.format(mode="UP")
|
|
@@ -523,7 +520,7 @@ class DenonAVRVolume(DenonAVRFoundation):
|
|
|
523
520
|
)
|
|
524
521
|
|
|
525
522
|
async def async_lfe_down(self) -> None:
|
|
526
|
-
"""Decrease LFE on receiver
|
|
523
|
+
"""Decrease LFE on receiver."""
|
|
527
524
|
if self._device.telnet_available:
|
|
528
525
|
await self._device.telnet_api.async_send_commands(
|
|
529
526
|
self._device.telnet_commands.command_lfe.format(mode="DOWN")
|
|
@@ -535,7 +532,7 @@ class DenonAVRVolume(DenonAVRFoundation):
|
|
|
535
532
|
|
|
536
533
|
async def async_lfe(self, lfe: int) -> None:
|
|
537
534
|
"""
|
|
538
|
-
Set LFE level on receiver
|
|
535
|
+
Set LFE level on receiver.
|
|
539
536
|
|
|
540
537
|
:param lfe: LFE level to set. Valid values are -10 to 0.
|
|
541
538
|
"""
|
|
@@ -553,7 +550,7 @@ class DenonAVRVolume(DenonAVRFoundation):
|
|
|
553
550
|
)
|
|
554
551
|
|
|
555
552
|
async def async_bass_sync_up(self) -> None:
|
|
556
|
-
"""Increase Bass Sync on receiver
|
|
553
|
+
"""Increase Bass Sync on receiver."""
|
|
557
554
|
if self._device.telnet_available:
|
|
558
555
|
await self._device.telnet_api.async_send_commands(
|
|
559
556
|
self._device.telnet_commands.command_bass_sync.format(mode="UP")
|
|
@@ -564,7 +561,7 @@ class DenonAVRVolume(DenonAVRFoundation):
|
|
|
564
561
|
)
|
|
565
562
|
|
|
566
563
|
async def async_bass_sync_down(self) -> None:
|
|
567
|
-
"""Decrease Bass Sync on receiver
|
|
564
|
+
"""Decrease Bass Sync on receiver."""
|
|
568
565
|
if self._device.telnet_available:
|
|
569
566
|
await self._device.telnet_api.async_send_commands(
|
|
570
567
|
self._device.telnet_commands.command_bass_sync.format(mode="DOWN")
|
|
@@ -576,7 +573,7 @@ class DenonAVRVolume(DenonAVRFoundation):
|
|
|
576
573
|
|
|
577
574
|
async def async_bass_sync(self, lfe: int) -> None:
|
|
578
575
|
"""
|
|
579
|
-
Set Bass Sync level on receiver
|
|
576
|
+
Set Bass Sync level on receiver.
|
|
580
577
|
|
|
581
578
|
:param lfe: Bass Sync level to set. Valid values are -10 to 0.
|
|
582
579
|
"""
|