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/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 DENON_ATTR_SETATTR, MAIN_ZONE, STATE_ON
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
1
+ Metadata-Version: 2.4
2
2
  Name: denonavr
3
- Version: 1.0.1
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.7
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
  [![Release](https://img.shields.io/github/v/release/ol-iver/denonavr?sort=semver)](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 `doc` folder.
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,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.6.0)
2
+ Generator: setuptools (80.3.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -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,,