denonavr 1.0.1__py3-none-any.whl → 1.1.0__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 +45 -0
- denonavr/audyssey.py +105 -0
- denonavr/const.py +879 -1
- denonavr/denonavr.py +499 -2
- denonavr/dirac.py +89 -0
- denonavr/foundation.py +1190 -19
- denonavr/soundmode.py +912 -3
- denonavr/volume.py +415 -4
- {denonavr-1.0.1.dist-info → denonavr-1.1.0.dist-info}/METADATA +5 -21
- denonavr-1.1.0.dist-info/RECORD +20 -0
- {denonavr-1.0.1.dist-info → denonavr-1.1.0.dist-info}/WHEEL +1 -1
- denonavr-1.0.1.dist-info/RECORD +0 -19
- {denonavr-1.0.1.dist-info → denonavr-1.1.0.dist-info/licenses}/LICENSE +0 -0
- {denonavr-1.0.1.dist-info → denonavr-1.1.0.dist-info}/top_level.txt +0 -0
denonavr/volume.py
CHANGED
|
@@ -9,14 +9,26 @@ This module implements the handler for volume of Denon AVR receivers.
|
|
|
9
9
|
|
|
10
10
|
import logging
|
|
11
11
|
from collections.abc import Hashable
|
|
12
|
-
from typing import Optional, Union
|
|
12
|
+
from typing import Dict, Optional, Union, get_args
|
|
13
13
|
|
|
14
14
|
import attr
|
|
15
15
|
|
|
16
16
|
from .appcommand import AppCommands
|
|
17
|
-
from .const import
|
|
17
|
+
from .const import (
|
|
18
|
+
CHANNEL_MAP,
|
|
19
|
+
CHANNEL_MAP_LABELS,
|
|
20
|
+
CHANNEL_VOLUME_MAP,
|
|
21
|
+
CHANNEL_VOLUME_MAP_LABELS,
|
|
22
|
+
DENON_ATTR_SETATTR,
|
|
23
|
+
MAIN_ZONE,
|
|
24
|
+
STATE_ON,
|
|
25
|
+
SUBWOOFERS_MAP,
|
|
26
|
+
SUBWOOFERS_MAP_LABELS,
|
|
27
|
+
Channels,
|
|
28
|
+
Subwoofers,
|
|
29
|
+
)
|
|
18
30
|
from .exceptions import AvrCommandError, AvrProcessingError
|
|
19
|
-
from .foundation import DenonAVRFoundation
|
|
31
|
+
from .foundation import DenonAVRFoundation, convert_on_off_bool
|
|
20
32
|
|
|
21
33
|
_LOGGER = logging.getLogger(__name__)
|
|
22
34
|
|
|
@@ -43,7 +55,18 @@ class DenonAVRVolume(DenonAVRFoundation):
|
|
|
43
55
|
_muted: Optional[bool] = attr.ib(
|
|
44
56
|
converter=attr.converters.optional(convert_muted), default=None
|
|
45
57
|
)
|
|
46
|
-
|
|
58
|
+
_channel_volumes: Optional[Dict[Channels, float]] = attr.ib(default=None)
|
|
59
|
+
_valid_channels = get_args(Channels)
|
|
60
|
+
_subwoofer: Optional[bool] = attr.ib(
|
|
61
|
+
converter=attr.converters.optional(convert_on_off_bool), default=None
|
|
62
|
+
)
|
|
63
|
+
_subwoofer_levels_adjustment: bool = attr.ib(default=True)
|
|
64
|
+
_subwoofer_levels: Optional[Dict[Subwoofers, float]] = attr.ib(default=None)
|
|
65
|
+
_valid_subwoofers = get_args(Subwoofers)
|
|
66
|
+
_lfe: Optional[int] = attr.ib(converter=attr.converters.optional(int), default=None)
|
|
67
|
+
_bass_sync: Optional[int] = attr.ib(
|
|
68
|
+
converter=attr.converters.optional(int), default=None
|
|
69
|
+
)
|
|
47
70
|
# Update tags for attributes
|
|
48
71
|
# AppCommand.xml interface
|
|
49
72
|
appcommand_attrs = {
|
|
@@ -61,6 +84,17 @@ class DenonAVRVolume(DenonAVRFoundation):
|
|
|
61
84
|
|
|
62
85
|
self._device.telnet_api.register_callback("MV", self._async_volume_callback)
|
|
63
86
|
self._device.telnet_api.register_callback("MU", self._async_mute_callback)
|
|
87
|
+
self._device.telnet_api.register_callback(
|
|
88
|
+
"CV", self._async_channel_volume_callback
|
|
89
|
+
)
|
|
90
|
+
self._device.telnet_api.register_callback(
|
|
91
|
+
"PS", self._async_subwoofer_state_callback
|
|
92
|
+
)
|
|
93
|
+
self._device.telnet_api.register_callback(
|
|
94
|
+
"PS", self._async_subwoofer_levels_callback
|
|
95
|
+
)
|
|
96
|
+
self._device.telnet_api.register_callback("PS", self._async_lfe_callback)
|
|
97
|
+
self._device.telnet_api.register_callback("PS", self._async_bass_sync_callback)
|
|
64
98
|
|
|
65
99
|
self._is_setup = True
|
|
66
100
|
|
|
@@ -85,6 +119,76 @@ class DenonAVRVolume(DenonAVRFoundation):
|
|
|
85
119
|
|
|
86
120
|
self._muted = parameter
|
|
87
121
|
|
|
122
|
+
async def _async_channel_volume_callback(
|
|
123
|
+
self, zone: str, event: str, parameter: str
|
|
124
|
+
) -> None:
|
|
125
|
+
"""Handle a channel volume change event."""
|
|
126
|
+
if event != "CV":
|
|
127
|
+
return
|
|
128
|
+
|
|
129
|
+
channel_volume = parameter.split()
|
|
130
|
+
if (
|
|
131
|
+
len(channel_volume) != 2
|
|
132
|
+
or channel_volume[0] not in CHANNEL_MAP_LABELS
|
|
133
|
+
or channel_volume[1] not in CHANNEL_VOLUME_MAP
|
|
134
|
+
):
|
|
135
|
+
return
|
|
136
|
+
|
|
137
|
+
if self._channel_volumes is None:
|
|
138
|
+
self._channel_volumes = {}
|
|
139
|
+
|
|
140
|
+
channel = CHANNEL_MAP_LABELS[channel_volume[0]]
|
|
141
|
+
volume = channel_volume[1]
|
|
142
|
+
self._channel_volumes[channel] = CHANNEL_VOLUME_MAP[volume]
|
|
143
|
+
|
|
144
|
+
async def _async_subwoofer_state_callback(
|
|
145
|
+
self, zone: str, event: str, parameter: str
|
|
146
|
+
) -> None:
|
|
147
|
+
"""Handle a subwoofer state change event."""
|
|
148
|
+
if parameter[:3] == "SWR":
|
|
149
|
+
self._subwoofer = parameter[4:]
|
|
150
|
+
|
|
151
|
+
async def _async_subwoofer_levels_callback(
|
|
152
|
+
self, zone: str, event: str, parameter: str
|
|
153
|
+
) -> None:
|
|
154
|
+
"""Handle a subwoofer levels change event."""
|
|
155
|
+
if parameter[:3] != "SWL":
|
|
156
|
+
return
|
|
157
|
+
|
|
158
|
+
subwoofer_volume = parameter.split()
|
|
159
|
+
if (
|
|
160
|
+
len(subwoofer_volume) != 2
|
|
161
|
+
or subwoofer_volume[0] not in SUBWOOFERS_MAP_LABELS
|
|
162
|
+
):
|
|
163
|
+
return
|
|
164
|
+
|
|
165
|
+
if self._subwoofer_levels is None:
|
|
166
|
+
self._subwoofer_levels = {}
|
|
167
|
+
|
|
168
|
+
subwoofer = SUBWOOFERS_MAP_LABELS[subwoofer_volume[0]]
|
|
169
|
+
level = subwoofer_volume[1]
|
|
170
|
+
val = convert_on_off_bool(level)
|
|
171
|
+
if val is not None:
|
|
172
|
+
self._subwoofer_levels_adjustment = val
|
|
173
|
+
elif level in CHANNEL_VOLUME_MAP:
|
|
174
|
+
self._subwoofer_levels[subwoofer] = CHANNEL_VOLUME_MAP[level]
|
|
175
|
+
|
|
176
|
+
async def _async_lfe_callback(self, zone: str, event: str, parameter: str) -> None:
|
|
177
|
+
"""Handle a LFE change event."""
|
|
178
|
+
if parameter[:3] != "LFE":
|
|
179
|
+
return
|
|
180
|
+
|
|
181
|
+
self._lfe = int(parameter[4:]) * -1
|
|
182
|
+
|
|
183
|
+
async def _async_bass_sync_callback(
|
|
184
|
+
self, zone: str, event: str, parameter: str
|
|
185
|
+
) -> None:
|
|
186
|
+
"""Handle a LFE change event."""
|
|
187
|
+
if parameter[:3] != "BSC":
|
|
188
|
+
return
|
|
189
|
+
|
|
190
|
+
self._bass_sync = int(parameter[4:]) * -1
|
|
191
|
+
|
|
88
192
|
async def async_update(
|
|
89
193
|
self, global_update: bool = False, cache_id: Optional[Hashable] = None
|
|
90
194
|
) -> None:
|
|
@@ -141,6 +245,79 @@ class DenonAVRVolume(DenonAVRFoundation):
|
|
|
141
245
|
"""
|
|
142
246
|
return self._volume
|
|
143
247
|
|
|
248
|
+
@property
|
|
249
|
+
def channel_volumes(self) -> Optional[Dict[Channels, float]]:
|
|
250
|
+
"""
|
|
251
|
+
Return the channel levels of the device in dB.
|
|
252
|
+
|
|
253
|
+
Only available if using Telnet.
|
|
254
|
+
"""
|
|
255
|
+
return self._channel_volumes
|
|
256
|
+
|
|
257
|
+
@property
|
|
258
|
+
def subwoofer(self) -> Optional[bool]:
|
|
259
|
+
"""
|
|
260
|
+
Return the state of the subwoofer.
|
|
261
|
+
|
|
262
|
+
Only available if using Telnet.
|
|
263
|
+
"""
|
|
264
|
+
return self._subwoofer
|
|
265
|
+
|
|
266
|
+
@property
|
|
267
|
+
def subwoofer_levels(self) -> Optional[Dict[Subwoofers, Union[bool, float]]]:
|
|
268
|
+
"""
|
|
269
|
+
Return the subwoofer levels of the device in dB when enabled.
|
|
270
|
+
|
|
271
|
+
Only available if using Telnet.
|
|
272
|
+
"""
|
|
273
|
+
if self._subwoofer_levels_adjustment:
|
|
274
|
+
return self._subwoofer_levels
|
|
275
|
+
|
|
276
|
+
return None
|
|
277
|
+
|
|
278
|
+
@property
|
|
279
|
+
def lfe(self) -> Optional[int]:
|
|
280
|
+
"""
|
|
281
|
+
Return LFE level in dB.
|
|
282
|
+
|
|
283
|
+
Only available if using Telnet.
|
|
284
|
+
"""
|
|
285
|
+
return self._lfe
|
|
286
|
+
|
|
287
|
+
@property
|
|
288
|
+
def bass_sync(self) -> Optional[int]:
|
|
289
|
+
"""
|
|
290
|
+
Return Bass Sync level in dB.
|
|
291
|
+
|
|
292
|
+
Only available if using Telnet.
|
|
293
|
+
"""
|
|
294
|
+
return self._bass_sync
|
|
295
|
+
|
|
296
|
+
##########
|
|
297
|
+
# Getter #
|
|
298
|
+
##########
|
|
299
|
+
def channel_volume(self, channel: Channels) -> Optional[float]:
|
|
300
|
+
"""
|
|
301
|
+
Return the volume of a channel in dB.
|
|
302
|
+
|
|
303
|
+
Only available if using Telnet.
|
|
304
|
+
"""
|
|
305
|
+
self._is_valid_channel(channel)
|
|
306
|
+
if self._channel_volumes is None:
|
|
307
|
+
return None
|
|
308
|
+
return self._channel_volumes[channel]
|
|
309
|
+
|
|
310
|
+
def subwoofer_level(self, subwoofer: Subwoofers) -> Optional[float]:
|
|
311
|
+
"""
|
|
312
|
+
Return the volume of a subwoofer in dB.
|
|
313
|
+
|
|
314
|
+
Only available if using Telnet.
|
|
315
|
+
"""
|
|
316
|
+
self._is_valid_subwoofer(subwoofer)
|
|
317
|
+
if self._subwoofer_levels is None:
|
|
318
|
+
return None
|
|
319
|
+
return self._subwoofer_levels[subwoofer]
|
|
320
|
+
|
|
144
321
|
##########
|
|
145
322
|
# Setter #
|
|
146
323
|
##########
|
|
@@ -210,6 +387,240 @@ class DenonAVRVolume(DenonAVRFoundation):
|
|
|
210
387
|
self._device.urls.command_mute_off
|
|
211
388
|
)
|
|
212
389
|
|
|
390
|
+
async def async_channel_volume_up(self, channel: Channels) -> None:
|
|
391
|
+
"""Increase Channel volume on receiver via HTTP get command."""
|
|
392
|
+
self._is_valid_channel(channel)
|
|
393
|
+
|
|
394
|
+
mapped_channel = CHANNEL_MAP[channel]
|
|
395
|
+
if self._device.telnet_available:
|
|
396
|
+
await self._device.telnet_api.async_send_commands(
|
|
397
|
+
self._device.telnet_commands.command_channel_volume.format(
|
|
398
|
+
channel=mapped_channel, value="UP"
|
|
399
|
+
)
|
|
400
|
+
)
|
|
401
|
+
else:
|
|
402
|
+
await self._device.api.async_get_command(
|
|
403
|
+
self._device.urls.command_channel_volume.format(
|
|
404
|
+
channel=mapped_channel, value="UP"
|
|
405
|
+
)
|
|
406
|
+
)
|
|
407
|
+
|
|
408
|
+
async def async_channel_volume_down(self, channel: Channels) -> None:
|
|
409
|
+
"""Decrease Channel volume on receiver via HTTP get command."""
|
|
410
|
+
self._is_valid_channel(channel)
|
|
411
|
+
|
|
412
|
+
mapped_channel = CHANNEL_MAP[channel]
|
|
413
|
+
if self._device.telnet_available:
|
|
414
|
+
await self._device.telnet_api.async_send_commands(
|
|
415
|
+
self._device.telnet_commands.command_channel_volume.format(
|
|
416
|
+
channel=mapped_channel, value="DOWN"
|
|
417
|
+
)
|
|
418
|
+
)
|
|
419
|
+
else:
|
|
420
|
+
await self._device.api.async_get_command(
|
|
421
|
+
self._device.urls.command_channel_volume.format(
|
|
422
|
+
channel=mapped_channel, value="DOWN"
|
|
423
|
+
)
|
|
424
|
+
)
|
|
425
|
+
|
|
426
|
+
async def async_channel_volume(self, channel: Channels, volume: float) -> None:
|
|
427
|
+
"""
|
|
428
|
+
Set Channel volume on receiver via HTTP get command.
|
|
429
|
+
|
|
430
|
+
:param channel: Channel to set.
|
|
431
|
+
:param volume: Volume to set. Valid values are -12 to 12 with 0.5 steps.
|
|
432
|
+
"""
|
|
433
|
+
self._is_valid_channel(channel)
|
|
434
|
+
if volume not in CHANNEL_VOLUME_MAP_LABELS:
|
|
435
|
+
raise AvrCommandError(f"Invalid channel volume: {volume}")
|
|
436
|
+
|
|
437
|
+
mapped_channel = CHANNEL_MAP[channel]
|
|
438
|
+
mapped_volume = CHANNEL_VOLUME_MAP_LABELS[volume]
|
|
439
|
+
if self._device.telnet_available:
|
|
440
|
+
await self._device.telnet_api.async_send_commands(
|
|
441
|
+
self._device.telnet_commands.command_channel_volume.format(
|
|
442
|
+
channel=mapped_channel, value=mapped_volume
|
|
443
|
+
)
|
|
444
|
+
)
|
|
445
|
+
else:
|
|
446
|
+
await self._device.api.async_get_command(
|
|
447
|
+
self._device.urls.command_channel_volume.format(
|
|
448
|
+
channel=mapped_channel, value=mapped_volume
|
|
449
|
+
)
|
|
450
|
+
)
|
|
451
|
+
|
|
452
|
+
async def async_channel_volumes_reset(self) -> None:
|
|
453
|
+
"""Reset all channel volumes on receiver via HTTP get command."""
|
|
454
|
+
if self._device.telnet_available:
|
|
455
|
+
await self._device.telnet_api.async_send_commands(
|
|
456
|
+
self._device.telnet_commands.command_channel_volumes_reset
|
|
457
|
+
)
|
|
458
|
+
else:
|
|
459
|
+
await self._device.api.async_get_command(
|
|
460
|
+
self._device.urls.command_channel_volumes_reset
|
|
461
|
+
)
|
|
462
|
+
|
|
463
|
+
async def async_subwoofer_on(self) -> None:
|
|
464
|
+
"""Turn on Subwoofer on receiver via HTTP get command."""
|
|
465
|
+
if self._device.telnet_available:
|
|
466
|
+
await self._device.telnet_api.async_send_commands(
|
|
467
|
+
self._device.telnet_commands.command_subwoofer_on_off.format(mode="ON")
|
|
468
|
+
)
|
|
469
|
+
else:
|
|
470
|
+
await self._device.api.async_get_command(
|
|
471
|
+
self._device.urls.command_subwoofer_on_off.format(mode="ON")
|
|
472
|
+
)
|
|
473
|
+
|
|
474
|
+
async def async_subwoofer_off(self) -> None:
|
|
475
|
+
"""Turn off Subwoofer on receiver via HTTP get command."""
|
|
476
|
+
if self._device.telnet_available:
|
|
477
|
+
await self._device.telnet_api.async_send_commands(
|
|
478
|
+
self._device.telnet_commands.command_subwoofer_on_off.format(mode="OFF")
|
|
479
|
+
)
|
|
480
|
+
else:
|
|
481
|
+
await self._device.api.async_get_command(
|
|
482
|
+
self._device.urls.command_subwoofer_on_off.format(mode="OFF")
|
|
483
|
+
)
|
|
484
|
+
|
|
485
|
+
async def async_subwoofer_toggle(self) -> None:
|
|
486
|
+
"""
|
|
487
|
+
Toggle Subwoofer on receiver via HTTP get command.
|
|
488
|
+
|
|
489
|
+
Only available if using Telnet.
|
|
490
|
+
"""
|
|
491
|
+
if self._subwoofer:
|
|
492
|
+
await self.async_subwoofer_off()
|
|
493
|
+
else:
|
|
494
|
+
await self.async_subwoofer_on()
|
|
495
|
+
|
|
496
|
+
async def async_subwoofer_level_up(self, subwoofer: Subwoofers) -> None:
|
|
497
|
+
"""Increase Subwoofer level on receiver via HTTP get command."""
|
|
498
|
+
self._is_valid_subwoofer(subwoofer)
|
|
499
|
+
mapped_subwoofer = SUBWOOFERS_MAP[subwoofer]
|
|
500
|
+
if self._device.telnet_available:
|
|
501
|
+
await self._device.telnet_api.async_send_commands(
|
|
502
|
+
self._device.telnet_commands.command_subwoofer_level.format(
|
|
503
|
+
number=mapped_subwoofer, mode="UP"
|
|
504
|
+
)
|
|
505
|
+
)
|
|
506
|
+
else:
|
|
507
|
+
await self._device.api.async_get_command(
|
|
508
|
+
self._device.urls.command_subwoofer_level.format(
|
|
509
|
+
number=mapped_subwoofer, mode="UP"
|
|
510
|
+
)
|
|
511
|
+
)
|
|
512
|
+
|
|
513
|
+
async def async_subwoofer_level_down(self, subwoofer: Subwoofers) -> None:
|
|
514
|
+
"""Decrease Subwoofer level on receiver via HTTP get command."""
|
|
515
|
+
self._is_valid_subwoofer(subwoofer)
|
|
516
|
+
mapped_subwoofer = SUBWOOFERS_MAP[subwoofer]
|
|
517
|
+
if self._device.telnet_available:
|
|
518
|
+
await self._device.telnet_api.async_send_commands(
|
|
519
|
+
self._device.telnet_commands.command_subwoofer_level.format(
|
|
520
|
+
number=mapped_subwoofer, mode="DOWN"
|
|
521
|
+
)
|
|
522
|
+
)
|
|
523
|
+
else:
|
|
524
|
+
await self._device.api.async_get_command(
|
|
525
|
+
self._device.urls.command_subwoofer_level.format(
|
|
526
|
+
number=mapped_subwoofer, mode="DOWN"
|
|
527
|
+
)
|
|
528
|
+
)
|
|
529
|
+
|
|
530
|
+
async def async_lfe_up(self) -> None:
|
|
531
|
+
"""Increase LFE on receiver via HTTP get command."""
|
|
532
|
+
if self._device.telnet_available:
|
|
533
|
+
await self._device.telnet_api.async_send_commands(
|
|
534
|
+
self._device.telnet_commands.command_lfe.format(mode="UP")
|
|
535
|
+
)
|
|
536
|
+
else:
|
|
537
|
+
await self._device.api.async_get_command(
|
|
538
|
+
self._device.urls.command_lfe.format(mode="UP")
|
|
539
|
+
)
|
|
540
|
+
|
|
541
|
+
async def async_lfe_down(self) -> None:
|
|
542
|
+
"""Decrease LFE on receiver via HTTP get command."""
|
|
543
|
+
if self._device.telnet_available:
|
|
544
|
+
await self._device.telnet_api.async_send_commands(
|
|
545
|
+
self._device.telnet_commands.command_lfe.format(mode="DOWN")
|
|
546
|
+
)
|
|
547
|
+
else:
|
|
548
|
+
await self._device.api.async_get_command(
|
|
549
|
+
self._device.urls.command_lfe.format(mode="DOWN")
|
|
550
|
+
)
|
|
551
|
+
|
|
552
|
+
async def async_lfe(self, lfe: int) -> None:
|
|
553
|
+
"""
|
|
554
|
+
Set LFE level on receiver via HTTP get command.
|
|
555
|
+
|
|
556
|
+
:param lfe: LFE level to set. Valid values are -10 to 0.
|
|
557
|
+
"""
|
|
558
|
+
if lfe < -10 or lfe > 0:
|
|
559
|
+
raise AvrCommandError(f"Invalid LFE: {lfe}")
|
|
560
|
+
|
|
561
|
+
lfe_local = str(lfe).replace("-", "").zfill(2)
|
|
562
|
+
if self._device.telnet_available:
|
|
563
|
+
await self._device.telnet_api.async_send_commands(
|
|
564
|
+
self._device.telnet_commands.command_lfe.format(mode=lfe_local)
|
|
565
|
+
)
|
|
566
|
+
else:
|
|
567
|
+
await self._device.api.async_get_command(
|
|
568
|
+
self._device.urls.command_lfe.format(mode=lfe_local)
|
|
569
|
+
)
|
|
570
|
+
|
|
571
|
+
async def async_bass_sync_up(self) -> None:
|
|
572
|
+
"""Increase Bass Sync on receiver via HTTP get command."""
|
|
573
|
+
if self._device.telnet_available:
|
|
574
|
+
await self._device.telnet_api.async_send_commands(
|
|
575
|
+
self._device.telnet_commands.command_bass_sync.format(mode="UP")
|
|
576
|
+
)
|
|
577
|
+
else:
|
|
578
|
+
await self._device.api.async_get_command(
|
|
579
|
+
self._device.urls.command_bass_sync.format(mode="UP")
|
|
580
|
+
)
|
|
581
|
+
|
|
582
|
+
async def async_bass_sync_down(self) -> None:
|
|
583
|
+
"""Decrease Bass Sync on receiver via HTTP get command."""
|
|
584
|
+
if self._device.telnet_available:
|
|
585
|
+
await self._device.telnet_api.async_send_commands(
|
|
586
|
+
self._device.telnet_commands.command_bass_sync.format(mode="DOWN")
|
|
587
|
+
)
|
|
588
|
+
else:
|
|
589
|
+
await self._device.api.async_get_command(
|
|
590
|
+
self._device.urls.command_bass_sync.format(mode="DOWN")
|
|
591
|
+
)
|
|
592
|
+
|
|
593
|
+
async def async_bass_sync(self, lfe: int) -> None:
|
|
594
|
+
"""
|
|
595
|
+
Set Bass Sync level on receiver via HTTP get command.
|
|
596
|
+
|
|
597
|
+
:param lfe: Bass Sync level to set. Valid values are -10 to 0.
|
|
598
|
+
"""
|
|
599
|
+
if lfe < -10 or lfe > 0:
|
|
600
|
+
raise AvrCommandError(f"Invalid Bass Sync: {lfe}")
|
|
601
|
+
|
|
602
|
+
bass_sync_local = str(lfe).replace("-", "").zfill(2)
|
|
603
|
+
if self._device.telnet_available:
|
|
604
|
+
await self._device.telnet_api.async_send_commands(
|
|
605
|
+
self._device.telnet_commands.command_bass_sync.format(
|
|
606
|
+
mode=bass_sync_local
|
|
607
|
+
)
|
|
608
|
+
)
|
|
609
|
+
else:
|
|
610
|
+
await self._device.api.async_get_command(
|
|
611
|
+
self._device.urls.command_bass_sync.format(mode=bass_sync_local)
|
|
612
|
+
)
|
|
613
|
+
|
|
614
|
+
@staticmethod
|
|
615
|
+
def _is_valid_channel(channel: Channels):
|
|
616
|
+
if channel not in DenonAVRVolume._valid_channels:
|
|
617
|
+
raise AvrCommandError("Invalid channel")
|
|
618
|
+
|
|
619
|
+
@staticmethod
|
|
620
|
+
def _is_valid_subwoofer(subwoofer: Subwoofers):
|
|
621
|
+
if subwoofer not in DenonAVRVolume._valid_subwoofers:
|
|
622
|
+
raise AvrCommandError("Invalid subwoofer")
|
|
623
|
+
|
|
213
624
|
|
|
214
625
|
def volume_factory(instance: DenonAVRFoundation) -> DenonAVRVolume:
|
|
215
626
|
"""Create DenonAVRVolume at receiver instances."""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: denonavr
|
|
3
|
-
Version: 1.0
|
|
3
|
+
Version: 1.1.0
|
|
4
4
|
Summary: Automation Library for Denon AVR receivers
|
|
5
5
|
Author-email: Oliver Goetz <scarface@mywoh.de>
|
|
6
6
|
License: MIT
|
|
@@ -14,14 +14,13 @@ Classifier: License :: OSI Approved :: MIT License
|
|
|
14
14
|
Classifier: Operating System :: OS Independent
|
|
15
15
|
Classifier: Topic :: Software Development :: Libraries
|
|
16
16
|
Classifier: Topic :: Home Automation
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.8
|
|
19
18
|
Classifier: Programming Language :: Python :: 3.9
|
|
20
19
|
Classifier: Programming Language :: Python :: 3.10
|
|
21
20
|
Classifier: Programming Language :: Python :: 3.11
|
|
22
21
|
Classifier: Programming Language :: Python :: 3.12
|
|
23
22
|
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
-
Requires-Python: >=3.
|
|
23
|
+
Requires-Python: >=3.8
|
|
25
24
|
Description-Content-Type: text/markdown; charset=UTF-8
|
|
26
25
|
License-File: LICENSE
|
|
27
26
|
Requires-Dist: asyncstdlib>=3.10.2
|
|
@@ -41,6 +40,7 @@ Requires-Dist: pytest-asyncio; extra == "testing"
|
|
|
41
40
|
Requires-Dist: pytest-httpx; extra == "testing"
|
|
42
41
|
Requires-Dist: flake8-docstrings; extra == "testing"
|
|
43
42
|
Requires-Dist: flake8; extra == "testing"
|
|
43
|
+
Dynamic: license-file
|
|
44
44
|
|
|
45
45
|
# denonavr
|
|
46
46
|
[](https://github.com/ol-iver/denonavr/releases/latest)
|
|
@@ -132,27 +132,11 @@ Other `async` methods available include:
|
|
|
132
132
|
* `d.async_set_volume(50)`
|
|
133
133
|
|
|
134
134
|
## Collection of HTTP calls
|
|
135
|
-
For a collection of HTTP calls for Denon receivers please have a look at the
|
|
135
|
+
For a collection of HTTP calls for Denon receivers please have a look at the [doc folder](doc/XML_data_dump.txt).
|
|
136
136
|
|
|
137
137
|
## License
|
|
138
138
|
MIT
|
|
139
139
|
|
|
140
|
-
## Author
|
|
141
|
-
@ol-iver: https://github.com/ol-iver
|
|
142
|
-
|
|
143
|
-
## Contributors
|
|
144
|
-
@soldag: https://github.com/soldag
|
|
145
|
-
@shapiromatron: https://github.com/shapiromatron
|
|
146
|
-
@glance-: https://github.com/glance-
|
|
147
|
-
@p3dda: https://github.com/p3dda
|
|
148
|
-
@russel: https://github.com/russell
|
|
149
|
-
@starkillerOG: https://github.com/starkillerOG
|
|
150
|
-
@andrewsayre: https://github.com/andrewsayre
|
|
151
|
-
@JPHutchins: https://github.com/JPHutchins
|
|
152
|
-
@MarBra: https://github.com/MarBra
|
|
153
|
-
@dcmeglio: https://github.com/dcmeglio
|
|
154
|
-
@bdraco: https://github.com/bdraco
|
|
155
|
-
|
|
156
140
|
## Users
|
|
157
141
|
Home Assistant: https://github.com/home-assistant/home-assistant/
|
|
158
142
|
denonavr-cli: https://pypi.org/project/denonavr-cli/
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
denonavr/__init__.py,sha256=LfB6oTshGAwfau1j3RXNNPFt3NTQeKbsZFVovFBhWWk,1325
|
|
2
|
+
denonavr/api.py,sha256=SaJls_9yQ8TyklzWwflubwy6oJki1NYIQGeeHNf-3ss,32530
|
|
3
|
+
denonavr/appcommand.py,sha256=H37VK4n-yW0ISvR1hfX8G4udQtGASoY44QNaXtLSidE,7784
|
|
4
|
+
denonavr/audyssey.py,sha256=d7mSkRiMvrZMtCzQdixfJuLmkuZeSi1w1GgQ_1fm-j8,14655
|
|
5
|
+
denonavr/const.py,sha256=HwdM3x-Fa3DxOs1-Tpg28Z9LSCRpMoI8-pSOhdmhx64,54261
|
|
6
|
+
denonavr/decorators.py,sha256=tLoVjGtDmN75fhwCgNREMGjbB6varDERnYlrhC6yIZ8,2733
|
|
7
|
+
denonavr/denonavr.py,sha256=lN_xwG9sa1TYCZQi24FRq4p4jV6GaOuDefYGuLvvXGI,39823
|
|
8
|
+
denonavr/dirac.py,sha256=my8E9r-t8u579chnyIhJb1afNme73bQGCxj3D3TQX8g,2534
|
|
9
|
+
denonavr/exceptions.py,sha256=naP7MCuNH98rv7y_lDdO7ayyvQGywnsfpHhW-o9tKeo,1725
|
|
10
|
+
denonavr/foundation.py,sha256=1_fpV9pA0Jz36Rnieowz4myqpAdaCaNwP74QTdMpSgk,72785
|
|
11
|
+
denonavr/input.py,sha256=kbKPePkdFHQSHKzOvAYudeSyJiRrUh0PxIOkG38kDUo,43050
|
|
12
|
+
denonavr/soundmode.py,sha256=kO2lxaj_i8G31fmwH9tu66YIZ6XaYA-kuFBKxYJhsdE,44632
|
|
13
|
+
denonavr/ssdp.py,sha256=4gyvN0yo9qSnJ7l6iJmSC_5qW45Fq2Tt2RACpxFMSqg,7839
|
|
14
|
+
denonavr/tonecontrol.py,sha256=DfHzziEeLdYiyTbJKcGk5cCPTvKBgjMqQReYp0qoF0U,12474
|
|
15
|
+
denonavr/volume.py,sha256=qnsYr4AWfCu8MQH9mdw1qsaLo3-Sq1mdzreYQDhaTXQ,22260
|
|
16
|
+
denonavr-1.1.0.dist-info/licenses/LICENSE,sha256=hcKXAoZnRee1NRWnxTpKyjKCz4aHhw76sZUZoB3qPTw,1068
|
|
17
|
+
denonavr-1.1.0.dist-info/METADATA,sha256=5fhJJuUm42gutbrRH-VRDqkmp7wXnUQnfuDK7G-xaOk,4707
|
|
18
|
+
denonavr-1.1.0.dist-info/WHEEL,sha256=GHB6lJx2juba1wDgXDNlMTyM13ckjBMKf-OnwgKOCtA,91
|
|
19
|
+
denonavr-1.1.0.dist-info/top_level.txt,sha256=GKwe6bOaw_R68BR7x-C7VD3bDFKKNBf0pRkWywUZWIs,9
|
|
20
|
+
denonavr-1.1.0.dist-info/RECORD,,
|
denonavr-1.0.1.dist-info/RECORD
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
denonavr/__init__.py,sha256=2EHaA5L852gUHTxouwZk4aLyww3HNlkgTPS5CzYkn4w,1325
|
|
2
|
-
denonavr/api.py,sha256=0i68EOx6hhSqGeQaIVw9bpbK7fxLKB_ynR_FtStA2J0,31462
|
|
3
|
-
denonavr/appcommand.py,sha256=H37VK4n-yW0ISvR1hfX8G4udQtGASoY44QNaXtLSidE,7784
|
|
4
|
-
denonavr/audyssey.py,sha256=bHzgFRdUwLQozP2Or59jn6qfYU4WSQxiGKixBx7xxQo,11085
|
|
5
|
-
denonavr/const.py,sha256=HoF8Zn03rC5oiAzl_y4YbYeft6tCKUU95z_GG-sPTMY,21464
|
|
6
|
-
denonavr/decorators.py,sha256=tLoVjGtDmN75fhwCgNREMGjbB6varDERnYlrhC6yIZ8,2733
|
|
7
|
-
denonavr/denonavr.py,sha256=twI100XNXvR6cfqtYKiegjhapOlKBUUSeZFdNBgjUew,24013
|
|
8
|
-
denonavr/exceptions.py,sha256=naP7MCuNH98rv7y_lDdO7ayyvQGywnsfpHhW-o9tKeo,1725
|
|
9
|
-
denonavr/foundation.py,sha256=c8drYLPThQS2cXs6RJbhLMpcb097AA2rC4ofd9fJobA,31432
|
|
10
|
-
denonavr/input.py,sha256=kbKPePkdFHQSHKzOvAYudeSyJiRrUh0PxIOkG38kDUo,43050
|
|
11
|
-
denonavr/soundmode.py,sha256=MKyBtSQ-1gtnNyT_qQhbGDlPQuNS3QzBurjUUWNPKeo,12464
|
|
12
|
-
denonavr/ssdp.py,sha256=4gyvN0yo9qSnJ7l6iJmSC_5qW45Fq2Tt2RACpxFMSqg,7839
|
|
13
|
-
denonavr/tonecontrol.py,sha256=DfHzziEeLdYiyTbJKcGk5cCPTvKBgjMqQReYp0qoF0U,12474
|
|
14
|
-
denonavr/volume.py,sha256=S3UeyassnErOSqiaS48Q4Vo9QHJTyG1jnyEDSRFOfdw,7341
|
|
15
|
-
denonavr-1.0.1.dist-info/LICENSE,sha256=hcKXAoZnRee1NRWnxTpKyjKCz4aHhw76sZUZoB3qPTw,1068
|
|
16
|
-
denonavr-1.0.1.dist-info/METADATA,sha256=CNw5cVpYvc3owjqaBB0Q3beEDgDB4sohaqD9A9nnDck,5233
|
|
17
|
-
denonavr-1.0.1.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
|
18
|
-
denonavr-1.0.1.dist-info/top_level.txt,sha256=GKwe6bOaw_R68BR7x-C7VD3bDFKKNBf0pRkWywUZWIs,9
|
|
19
|
-
denonavr-1.0.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|