denonavr 0.11.6__py3-none-any.whl → 1.0.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 CHANGED
@@ -10,8 +10,6 @@ Automation Library for Denon AVR receivers.
10
10
  # Set default logging handler to avoid "No handler found" warnings.
11
11
  import logging
12
12
 
13
- from .decorators import run_async_synchronously
14
-
15
13
  # Import denonavr module
16
14
  from .denonavr import DenonAVR
17
15
  from .ssdp import async_identify_denonavr_receivers
@@ -19,7 +17,7 @@ from .ssdp import async_identify_denonavr_receivers
19
17
  logging.getLogger(__name__).addHandler(logging.NullHandler())
20
18
 
21
19
  __title__ = "denonavr"
22
- __version__ = "0.11.6"
20
+ __version__ = "1.0.0"
23
21
 
24
22
 
25
23
  async def async_discover():
@@ -33,17 +31,6 @@ async def async_discover():
33
31
  return await async_identify_denonavr_receivers()
34
32
 
35
33
 
36
- @run_async_synchronously(async_func=async_discover)
37
- def discover():
38
- """
39
- Discover all Denon AVR devices in LAN zone.
40
-
41
- Returns a list of dictionaries which includes all discovered Denon AVR
42
- devices with keys "host", "modelName", "friendlyName", "presentationURL".
43
- By default SSDP broadcasts are sent once with a 2 seconds timeout.
44
- """
45
-
46
-
47
34
  async def async_init_all_receivers():
48
35
  """
49
36
  Initialize all discovered Denon AVR receivers in LAN zone.
@@ -58,13 +45,3 @@ async def async_init_all_receivers():
58
45
  init_receiver = DenonAVR(receiver["host"])
59
46
  init_receivers.append(init_receiver)
60
47
  return init_receivers
61
-
62
-
63
- @run_async_synchronously(async_func=async_init_all_receivers)
64
- def init_all_receivers():
65
- """
66
- Initialize all discovered Denon AVR receivers in LAN zone.
67
-
68
- Returns a list of created Denon AVR instances.
69
- By default SSDP broadcasts are sent up to 3 times with a 2 seconds timeout.
70
- """
denonavr/api.py CHANGED
@@ -401,9 +401,9 @@ class DenonAVRTelnetProtocol(asyncio.Protocol):
401
401
 
402
402
  def connection_lost(self, exc: Optional[Exception]) -> None:
403
403
  """Handle connection lost."""
404
- self.transport = None
405
404
  self._on_connection_lost()
406
- return super().connection_lost(exc)
405
+ super().connection_lost(exc)
406
+ self.transport = None
407
407
 
408
408
 
409
409
  @attr.s(auto_attribs=True, hash=False, on_setattr=DENON_ATTR_SETATTR)
@@ -413,9 +413,6 @@ class DenonAVRTelnetApi:
413
413
  host: str = attr.ib(converter=str, default="localhost")
414
414
  timeout: float = attr.ib(converter=float, default=2.0)
415
415
  _connection_enabled: bool = attr.ib(default=False)
416
- _healthy: Optional[bool] = attr.ib(
417
- converter=attr.converters.optional(bool), default=None
418
- )
419
416
  _last_message_time: float = attr.ib(default=-1.0)
420
417
  _connect_lock: asyncio.Lock = attr.ib(default=attr.Factory(asyncio.Lock))
421
418
  _reconnect_task: asyncio.Task = attr.ib(default=None)
@@ -474,17 +471,17 @@ class DenonAVRTelnetApi:
474
471
  raise AvrTimoutError(f"TimeoutException: {err}", "telnet connect") from err
475
472
  except ConnectionRefusedError as err:
476
473
  _LOGGER.debug(
477
- "%s: Connection refused on telnet connect", self.host, exc_info=True
474
+ "%s: Connection refused on telnet connect: %s", self.host, err
478
475
  )
479
476
  raise AvrNetworkError(
480
477
  f"ConnectionRefusedError: {err}", "telnet connect"
481
478
  ) from err
482
479
  except (OSError, IOError) as err:
483
480
  _LOGGER.debug(
484
- "%s: Connection failed on telnet reconnect", self.host, exc_info=True
481
+ "%s: Connection failed on telnet reconnect: %s", self.host, err
485
482
  )
486
483
  raise AvrNetworkError(f"OSError: {err}", "telnet connect") from err
487
- _LOGGER.debug("%s: telnet connection complete", self.host)
484
+ _LOGGER.debug("%s: telnet connection established", self.host)
488
485
  self._protocol = cast(DenonAVRTelnetProtocol, transport_protocol[1])
489
486
  self._connection_enabled = True
490
487
  self._last_message_time = time.monotonic()
@@ -507,6 +504,7 @@ class DenonAVRTelnetApi:
507
504
  "PSREFLEV ?",
508
505
  "PSDYNVOL ?",
509
506
  "MS?",
507
+ skip_confirmation=True,
510
508
  )
511
509
 
512
510
  def _schedule_monitor(self) -> None:
@@ -527,8 +525,6 @@ class DenonAVRTelnetApi:
527
525
  _LOGGER.info(
528
526
  "%s: Keep alive failed, disconnecting and reconnecting", self.host
529
527
  )
530
- if self._protocol is not None:
531
- self._protocol.close()
532
528
  self._handle_disconnected()
533
529
  return
534
530
 
@@ -540,8 +536,10 @@ class DenonAVRTelnetApi:
540
536
 
541
537
  def _handle_disconnected(self) -> None:
542
538
  """Handle disconnected."""
543
- _LOGGER.debug("%s: disconnected", self.host)
544
- self._protocol = None
539
+ _LOGGER.debug("%s: handle disconnected", self.host)
540
+ if self._protocol is not None:
541
+ self._protocol.close()
542
+ self._protocol = None
545
543
  self._stop_monitor()
546
544
  if not self._connection_enabled:
547
545
  return
@@ -550,6 +548,7 @@ class DenonAVRTelnetApi:
550
548
  async def async_disconnect(self) -> None:
551
549
  """Close the connection to the receiver asynchronously."""
552
550
  async with self._connect_lock:
551
+ _LOGGER.debug("%s: telnet disconnecting", self.host)
553
552
  self._connection_enabled = False
554
553
  self._stop_monitor()
555
554
  reconnect_task = self._reconnect_task
@@ -565,6 +564,7 @@ class DenonAVRTelnetApi:
565
564
  await reconnect_task
566
565
  except asyncio.CancelledError:
567
566
  pass
567
+ _LOGGER.debug("%s: telnet disconnected", self.host)
568
568
 
569
569
  async def _async_reconnect(self) -> None:
570
570
  """Reconnect to the receiver asynchronously."""
@@ -572,19 +572,20 @@ class DenonAVRTelnetApi:
572
572
 
573
573
  while self._connection_enabled and not self.healthy:
574
574
  async with self._connect_lock:
575
+ _LOGGER.debug("%s: Telnet reconnecting", self.host)
575
576
  try:
576
577
  await self._async_establish_connection()
577
578
  except AvrTimoutError:
578
579
  _LOGGER.debug(
579
580
  "%s: Timeout exception on telnet reconnect", self.host
580
581
  )
581
- except AvrNetworkError as ex:
582
- _LOGGER.debug("%s: %s", self.host, ex, exc_info=True)
583
- except Exception: # pylint: disable=broad-except
582
+ except AvrNetworkError as err:
583
+ _LOGGER.debug("%s: %s", self.host, err)
584
+ except Exception as err: # pylint: disable=broad-except
584
585
  _LOGGER.error(
585
586
  "%s: Unexpected exception on telnet reconnect",
586
587
  self.host,
587
- exc_info=True,
588
+ exc_info=err,
588
589
  )
589
590
  else:
590
591
  _LOGGER.info("%s: Telnet reconnected", self.host)
@@ -682,7 +683,7 @@ class DenonAVRTelnetApi:
682
683
  # We don't want a single bad callback to trip up the
683
684
  # whole system and prevent further execution
684
685
  _LOGGER.error(
685
- "%s: Raw callback caused an unhandled exception %s",
686
+ "%s: Raw callback caused an unhandled exception: %s",
686
687
  self.host,
687
688
  err,
688
689
  )
@@ -695,7 +696,7 @@ class DenonAVRTelnetApi:
695
696
  # We don't want a single bad callback to trip up the
696
697
  # whole system and prevent further execution
697
698
  _LOGGER.error(
698
- "%s: Event callback caused an unhandled exception %s",
699
+ "%s: Event callback caused an unhandled exception: %s",
699
700
  self.host,
700
701
  err,
701
702
  )
@@ -708,7 +709,7 @@ class DenonAVRTelnetApi:
708
709
  # We don't want a single bad callback to trip up the
709
710
  # whole system and prevent further execution
710
711
  _LOGGER.error(
711
- "%s: Event callback caused an unhandled exception %s",
712
+ "%s: Event callback caused an unhandled exception: %s",
712
713
  self.host,
713
714
  err,
714
715
  )
@@ -731,35 +732,45 @@ class DenonAVRTelnetApi:
731
732
  self._send_confirmation_event.set()
732
733
  _LOGGER.debug("Command %s confirmed", command)
733
734
 
734
- async def _async_send_command(self, command: str) -> None:
735
+ async def _async_send_command(
736
+ self, command: str, skip_confirmation: bool = False
737
+ ) -> None:
735
738
  """Send one telnet command to the receiver."""
736
739
  async with self._send_lock:
737
- self._send_confirmation_command = command
738
- self._send_confirmation_event.clear()
740
+ if not skip_confirmation:
741
+ self._send_confirmation_command = command
742
+ self._send_confirmation_event.clear()
739
743
  if not self.connected or not self.healthy:
740
744
  raise AvrProcessingError(
741
745
  f"Error sending command {command}. Telnet connected: "
742
746
  f"{self.connected}, Connection healthy: {self.healthy}"
743
747
  )
744
748
  self._protocol.write(f"{command}\r")
745
- try:
746
- await asyncio.wait_for(
747
- self._send_confirmation_event.wait(),
748
- self._send_confirmation_timeout,
749
- )
750
- except asyncio.TimeoutError:
751
- _LOGGER.info("Timeout waiting for confirmation of command: %s", command)
752
- finally:
753
- self._send_confirmation_command = ""
749
+ if not skip_confirmation:
750
+ try:
751
+ await asyncio.wait_for(
752
+ self._send_confirmation_event.wait(),
753
+ self._send_confirmation_timeout,
754
+ )
755
+ except asyncio.TimeoutError:
756
+ _LOGGER.info(
757
+ "Timeout waiting for confirmation of command: %s", command
758
+ )
759
+ finally:
760
+ self._send_confirmation_command = ""
754
761
 
755
- async def async_send_commands(self, *commands: str) -> None:
762
+ async def async_send_commands(
763
+ self, *commands: str, skip_confirmation: bool = False
764
+ ) -> None:
756
765
  """Send telnet commands to the receiver."""
757
766
  for command in commands:
758
- await self._async_send_command(command)
767
+ await self._async_send_command(command, skip_confirmation=skip_confirmation)
759
768
 
760
- def send_commands(self, *commands: str) -> None:
769
+ def send_commands(self, *commands: str, skip_confirmation: bool = False) -> None:
761
770
  """Send telnet commands to the receiver."""
762
- task = asyncio.create_task(self.async_send_commands(*commands))
771
+ task = asyncio.create_task(
772
+ self.async_send_commands(*commands, skip_confirmation=skip_confirmation)
773
+ )
763
774
  self._send_tasks.add(task)
764
775
  task.add_done_callback(self._send_tasks.discard)
765
776
 
denonavr/audyssey.py CHANGED
@@ -99,12 +99,14 @@ class DenonAVRAudyssey(DenonAVRFoundation):
99
99
  self, global_update: bool = False, cache_id: Optional[Hashable] = None
100
100
  ) -> None:
101
101
  """Update Audyssey asynchronously."""
102
+ _LOGGER.debug("Starting Audyssey update")
102
103
  # Ensure instance is setup before updating
103
104
  if not self._is_setup:
104
105
  self.setup()
105
106
 
106
107
  # Update state
107
108
  await self.async_update_audyssey(global_update=global_update, cache_id=cache_id)
109
+ _LOGGER.debug("Finished Audyssey update")
108
110
 
109
111
  async def async_update_audyssey(
110
112
  self, global_update: bool = False, cache_id: Optional[Hashable] = None
@@ -117,13 +119,16 @@ class DenonAVRAudyssey(DenonAVRFoundation):
117
119
 
118
120
  # Audyssey is only available for avr 2016 update
119
121
  if self._device.use_avr_2016_update:
120
- await self.async_update_attrs_appcommand(
121
- self.appcommand0300_attrs,
122
- appcommand0300=True,
123
- global_update=global_update,
124
- cache_id=cache_id,
125
- ignore_missing_response=True,
126
- )
122
+ try:
123
+ await self.async_update_attrs_appcommand(
124
+ self.appcommand0300_attrs,
125
+ appcommand0300=True,
126
+ global_update=global_update,
127
+ cache_id=cache_id,
128
+ )
129
+ except AvrProcessingError as err:
130
+ # Don't raise an error here, because not all devices support it
131
+ _LOGGER.debug("Updating Audyssey failed: %s", err)
127
132
 
128
133
  async def _async_set_audyssey(self, cmd: AppCommandCmd) -> None:
129
134
  """Set Audyssey parameter."""
denonavr/const.py CHANGED
@@ -43,6 +43,17 @@ ReceiverURLs = namedtuple(
43
43
  "command_set_all_zone_stereo",
44
44
  "command_pause",
45
45
  "command_play",
46
+ "command_cusor_up",
47
+ "command_cusor_down",
48
+ "command_cusor_left",
49
+ "command_cusor_right",
50
+ "command_cusor_enter",
51
+ "command_back",
52
+ "command_info",
53
+ "command_options",
54
+ "command_setup_open",
55
+ "command_setup_close",
56
+ "command_setup_query",
46
57
  ],
47
58
  )
48
59
  TelnetCommands = namedtuple(
@@ -68,6 +79,17 @@ TelnetCommands = namedtuple(
68
79
  "command_tonecontrol",
69
80
  "command_bass",
70
81
  "command_treble",
82
+ "command_cusor_up",
83
+ "command_cusor_down",
84
+ "command_cusor_left",
85
+ "command_cusor_right",
86
+ "command_cusor_enter",
87
+ "command_back",
88
+ "command_info",
89
+ "command_options",
90
+ "command_setup_open",
91
+ "command_setup_close",
92
+ "command_setup_query",
71
93
  ],
72
94
  )
73
95
 
@@ -168,40 +190,40 @@ ALL_ZONE_STEREO = "ALL ZONE STEREO"
168
190
 
169
191
  SOUND_MODE_MAPPING = {
170
192
  "MUSIC": [
171
- "PLII MUSIC",
172
- "DTS NEO:6 MUSIC",
193
+ "DOLBY D +NEO:X M",
194
+ "DOLBY PL2 M",
195
+ "DOLBY PL2 MUSIC",
196
+ "DOLBY PL2 X MUSIC",
173
197
  "DTS NEO:6 M",
198
+ "DTS NEO:6 MUSIC",
174
199
  "DTS NEO:X M",
175
- "DOLBY D +NEO:X M",
176
200
  "DTS NEO:X MUSIC",
177
- "DOLBY PL2 MUSIC",
178
- "DOLBY PL2 M",
201
+ "PLII MUSIC",
179
202
  "PLIIX MUSIC",
180
- "DOLBY PL2 X MUSIC",
181
203
  ],
182
204
  "MOVIE": [
183
- "PLII MOVIE",
184
- "PLII CINEMA",
185
- "DTS NEO:X CINEMA",
186
- "DTS NEO:X C",
187
- "DTS NEO:6 CINEMA",
188
- "DTS NEO:6 C",
189
205
  "DOLBY D +NEO:X C",
190
- "PLIIX CINEMA",
191
- "DOLBY PLII MOVIE",
192
- "MULTI IN + VIRTUAL:X",
193
- "DOLBY PL2 CINEMA",
194
206
  "DOLBY PL2 C",
195
- "DOLBY PL2 X MOVIE",
207
+ "DOLBY PL2 CINEMA",
196
208
  "DOLBY PL2 MOVIE",
209
+ "DOLBY PL2 X MOVIE",
210
+ "DOLBY PLII MOVIE",
211
+ "DTS NEO:6 C",
212
+ "DTS NEO:6 CINEMA",
213
+ "DTS NEO:X C",
214
+ "DTS NEO:X CINEMA",
215
+ "MULTI IN + VIRTUAL:X",
216
+ "PLII CINEMA",
217
+ "PLII MOVIE",
218
+ "PLIIX CINEMA",
197
219
  ],
198
220
  "GAME": [
199
- "PLII GAME",
200
221
  "DOLBY D +NEO:X G",
201
- "DOLBY PL2 GAME",
202
222
  "DOLBY PL2 G",
223
+ "DOLBY PL2 GAME",
203
224
  "DOLBY PL2 X GAME",
204
225
  "DOLBY PLII GAME",
226
+ "PLII GAME",
205
227
  ],
206
228
  "AUTO": ["None"],
207
229
  "STANDARD": ["None2"],
@@ -214,64 +236,74 @@ SOUND_MODE_MAPPING = {
214
236
  "DIRECT": ["DIRECT"],
215
237
  "PURE DIRECT": ["PURE_DIRECT", "PURE DIRECT"],
216
238
  "DOLBY DIGITAL": [
217
- "DOLBY DIGITAL",
218
- "DOLBY D + DOLBY SURROUND",
219
- "DOLBY D+DS",
220
- "DOLBY D+ +DS",
221
- "DOLBY DIGITAL +",
222
- "STANDARD(DOLBY)",
223
- "DOLBY SURROUND",
224
- "DOLBY D + +DOLBY SURROUND",
225
- "NEURAL",
226
- "NEURAL:X",
227
- "DOLBY HD",
228
- "DOLBY HD + DOLBY SURROUND",
229
- "MULTI IN + DSUR",
230
- "MULTI IN + NEURAL:X",
231
- "MULTI IN + DOLBY SURROUND",
232
- "DOLBY D + NEURAL:X",
233
- "DOLBY DIGITAL + NEURAL:X",
234
- "DOLBY DIGITAL + + NEURAL:X",
235
239
  "DOLBY ATMOS",
236
- "DOLBY AUDIO - DOLBY SURROUND",
237
- "DOLBY TRUEHD",
240
+ "DOLBY AUDIO - DD + DSUR",
241
+ "DOLBY AUDIO - DD + NEURAL:X",
242
+ "DOLBY AUDIO - DD+ + DSUR",
243
+ "DOLBY AUDIO - DD+ + NEURAL:X",
238
244
  "DOLBY AUDIO - DOLBY DIGITAL PLUS",
239
- "DOLBY AUDIO - TRUEHD + DSUR",
245
+ "DOLBY AUDIO - DOLBY DIGITAL",
246
+ "DOLBY AUDIO - DOLBY SURROUND",
240
247
  "DOLBY AUDIO - DOLBY TRUEHD",
248
+ "DOLBY AUDIO - TRUEHD + DSUR",
241
249
  "DOLBY AUDIO - TRUEHD + NEURAL:X",
242
- "DOLBY AUDIO - DD + NEURAL:X",
243
- "DOLBY AUDIO - DD + DSUR",
244
- "DOLBY AUDIO - DD+ + NEURAL:X",
245
- "DOLBY AUDIO - DD+ + DSUR",
250
+ "DOLBY AUDIO-DD",
246
251
  "DOLBY AUDIO-DD+ +DSUR",
247
- "DOLBY AUDIO - DOLBY DIGITAL",
248
- "DOLBY AUDIO-DSUR",
252
+ "DOLBY AUDIO-DD+ +NEURAL:X",
253
+ "DOLBY AUDIO-DD+",
249
254
  "DOLBY AUDIO-DD+DSUR",
255
+ "DOLBY AUDIO-DSUR",
256
+ "DOLBY AUDIO-TRUEHD",
257
+ "DOLBY AUDIO-TRUEHD+DSUR",
258
+ "DOLBY AUDIO-TRUEHD+NEURAL:X",
259
+ "DOLBY D + +DOLBY SURROUND",
260
+ "DOLBY D + DOLBY SURROUND",
261
+ "DOLBY D + NEURAL:X",
262
+ "DOLBY D+ +DS",
263
+ "DOLBY D+",
264
+ "DOLBY D+DS",
265
+ "DOLBY DIGITAL + + NEURAL:X",
266
+ "DOLBY DIGITAL + NEURAL:X",
267
+ "DOLBY DIGITAL +",
268
+ "DOLBY DIGITAL",
269
+ "DOLBY HD + DOLBY SURROUND",
270
+ "DOLBY HD",
250
271
  "DOLBY PRO LOGIC",
272
+ "DOLBY SURROUND",
273
+ "DOLBY TRUEHD",
274
+ "MULTI IN + DOLBY SURROUND",
275
+ "MULTI IN + DSUR",
276
+ "MULTI IN + NEURAL:X",
277
+ "NEURAL:X",
278
+ "NEURAL",
279
+ "STANDARD(DOLBY)",
251
280
  ],
252
281
  "DTS SURROUND": [
253
- "DTS SURROUND",
254
- "DTS NEURAL:X",
255
- "STANDARD(DTS)",
282
+ "DTS + DOLBY SURROUND",
256
283
  "DTS + NEURAL:X",
257
- "MULTI CH IN",
258
- "DTS-HD MSTR",
259
- "DTS VIRTUAL:X",
260
- "DTS-HD + NEURAL:X",
261
- "DTS-HD",
262
284
  "DTS + VIRTUAL:X",
263
- "DTS + DOLBY SURROUND",
285
+ "DTS NEURAL:X",
286
+ "DTS SURROUND",
287
+ "DTS VIRTUAL:X",
264
288
  "DTS-HD + DOLBY SURROUND",
265
289
  "DTS-HD + DSUR",
290
+ "DTS-HD + NEURAL:X",
291
+ "DTS-HD MSTR",
292
+ "DTS-HD",
266
293
  "DTS:X MSTR",
294
+ "DTS:X",
295
+ "M CH IN+DSUR",
296
+ "MULTI CH IN",
297
+ "STANDARD(DTS)",
298
+ "VIRTUAL:X",
267
299
  ],
268
- "AURO3D": ["AURO-3D"],
269
- "AURO2DSURR": ["AURO-2D SURROUND"],
300
+ "AURO3D": ["AURO-3D", "AURO3D"],
301
+ "AURO2DSURR": ["AURO-2D SURROUND", "AURO2DSURR"],
270
302
  "MCH STEREO": [
271
- "MULTI CH STEREO",
272
- "MULTI_CH_STEREO",
273
303
  "MCH STEREO",
274
304
  "MULTI CH IN 7.1",
305
+ "MULTI CH STEREO",
306
+ "MULTI_CH_STEREO",
275
307
  ],
276
308
  "STEREO": ["STEREO"],
277
309
  ALL_ZONE_STEREO: ["ALL ZONE STEREO"],
@@ -327,6 +359,17 @@ COMMAND_MUTE_ON_URL = "/goform/formiPhoneAppMute.xml?1+MuteOn"
327
359
  COMMAND_MUTE_OFF_URL = "/goform/formiPhoneAppMute.xml?1+MuteOff"
328
360
  COMMAND_SEL_SM_URL = "/goform/formiPhoneAppDirect.xml?MS"
329
361
  COMMAND_SET_ZST_URL = "/goform/formiPhoneAppDirect.xml?MN"
362
+ COMMAND_CURSOR_UP = "/goform/formiPhoneAppDirect.xml?MNCUP"
363
+ COMMAND_CURSOR_DOWN = "/goform/formiPhoneAppDirect.xml?MNCDN"
364
+ COMMAND_CURSOR_LEFT = "/goform/formiPhoneAppDirect.xml?MNCLT"
365
+ COMMAND_CURSOR_RIGHT = "/goform/formiPhoneAppDirect.xml?MNCRT"
366
+ COMMAND_CURSOR_ENTER = "/goform/formiPhoneAppDirect.xml?MNENT"
367
+ COMMAND_BACK = "/goform/formiPhoneAppDirect.xml?MNRTN"
368
+ COMMAND_INFO = "/goform/formiPhoneAppDirect.xml?MNINF"
369
+ COMMAND_OPTIONS = "/goform/formiPhoneAppDirect.xml?MNOPT"
370
+ COMMAND_SETUP_OPEN = "/goform/formiPhoneAppDirect.xml?MNMEN%20ON"
371
+ COMMAND_SETUP_CLOSE = "/goform/formiPhoneAppDirect.xml?MNMEN%20OFF"
372
+ COMMAND_SETUP_QUERY = "/goform/formiPhoneAppDirect.xml?MNMEN?"
330
373
 
331
374
  # Zone 2 URLs
332
375
  STATUS_Z2_URL = "/goform/formZone2_Zone2XmlStatus.xml"
@@ -375,6 +418,17 @@ DENONAVR_URLS = ReceiverURLs(
375
418
  command_set_all_zone_stereo=COMMAND_SET_ZST_URL,
376
419
  command_pause=COMMAND_PAUSE,
377
420
  command_play=COMMAND_PLAY,
421
+ command_cusor_up=COMMAND_CURSOR_UP,
422
+ command_cusor_down=COMMAND_CURSOR_DOWN,
423
+ command_cusor_left=COMMAND_CURSOR_LEFT,
424
+ command_cusor_right=COMMAND_CURSOR_RIGHT,
425
+ command_cusor_enter=COMMAND_CURSOR_ENTER,
426
+ command_back=COMMAND_BACK,
427
+ command_info=COMMAND_INFO,
428
+ command_options=COMMAND_OPTIONS,
429
+ command_setup_open=COMMAND_SETUP_OPEN,
430
+ command_setup_close=COMMAND_SETUP_CLOSE,
431
+ command_setup_query=COMMAND_SETUP_QUERY,
378
432
  )
379
433
 
380
434
  ZONE2_URLS = ReceiverURLs(
@@ -400,6 +454,17 @@ ZONE2_URLS = ReceiverURLs(
400
454
  command_set_all_zone_stereo=COMMAND_SET_ZST_URL,
401
455
  command_pause=COMMAND_PAUSE,
402
456
  command_play=COMMAND_PLAY,
457
+ command_cusor_up=COMMAND_CURSOR_UP,
458
+ command_cusor_down=COMMAND_CURSOR_DOWN,
459
+ command_cusor_left=COMMAND_CURSOR_LEFT,
460
+ command_cusor_right=COMMAND_CURSOR_RIGHT,
461
+ command_cusor_enter=COMMAND_CURSOR_ENTER,
462
+ command_back=COMMAND_BACK,
463
+ command_info=COMMAND_INFO,
464
+ command_options=COMMAND_OPTIONS,
465
+ command_setup_open=COMMAND_SETUP_OPEN,
466
+ command_setup_close=COMMAND_SETUP_CLOSE,
467
+ command_setup_query=COMMAND_SETUP_QUERY,
403
468
  )
404
469
 
405
470
  ZONE3_URLS = ReceiverURLs(
@@ -425,6 +490,17 @@ ZONE3_URLS = ReceiverURLs(
425
490
  command_set_all_zone_stereo=COMMAND_SET_ZST_URL,
426
491
  command_pause=COMMAND_PAUSE,
427
492
  command_play=COMMAND_PLAY,
493
+ command_cusor_up=COMMAND_CURSOR_UP,
494
+ command_cusor_down=COMMAND_CURSOR_DOWN,
495
+ command_cusor_left=COMMAND_CURSOR_LEFT,
496
+ command_cusor_right=COMMAND_CURSOR_RIGHT,
497
+ command_cusor_enter=COMMAND_CURSOR_ENTER,
498
+ command_back=COMMAND_BACK,
499
+ command_info=COMMAND_INFO,
500
+ command_options=COMMAND_OPTIONS,
501
+ command_setup_open=COMMAND_SETUP_OPEN,
502
+ command_setup_close=COMMAND_SETUP_CLOSE,
503
+ command_setup_query=COMMAND_SETUP_QUERY,
428
504
  )
429
505
 
430
506
  # Telnet Events
@@ -503,6 +579,17 @@ DENONAVR_TELNET_COMMANDS = TelnetCommands(
503
579
  command_tonecontrol="PSTONE CTRL ",
504
580
  command_bass="PSBAS ",
505
581
  command_treble="PSTRE ",
582
+ command_cusor_up="MNCUP",
583
+ command_cusor_down="MNCDN",
584
+ command_cusor_left="MNCLT",
585
+ command_cusor_right="MNCRT",
586
+ command_cusor_enter="MNENT",
587
+ command_back="MNRTN",
588
+ command_info="MNINF",
589
+ command_options="MNOPT",
590
+ command_setup_open="MNMEN ON",
591
+ command_setup_close="MNMEN OFF",
592
+ command_setup_query="MNMEN?",
506
593
  )
507
594
 
508
595
  ZONE2_TELNET_COMMANDS = TelnetCommands(
@@ -526,6 +613,17 @@ ZONE2_TELNET_COMMANDS = TelnetCommands(
526
613
  command_tonecontrol="PSTONE CTRL ",
527
614
  command_bass="PSBAS ",
528
615
  command_treble="PSTRE ",
616
+ command_cusor_up="MNCUP",
617
+ command_cusor_down="MNCDN",
618
+ command_cusor_left="MNCLT",
619
+ command_cusor_right="MNCRT",
620
+ command_cusor_enter="MNENT",
621
+ command_back="MNRTN",
622
+ command_info="MNINF",
623
+ command_options="MNOPT",
624
+ command_setup_open="MNMEN ON",
625
+ command_setup_close="MNMEN OFF",
626
+ command_setup_query="MNMEN?",
529
627
  )
530
628
 
531
629
  ZONE3_TELNET_COMMANDS = TelnetCommands(
@@ -549,6 +647,17 @@ ZONE3_TELNET_COMMANDS = TelnetCommands(
549
647
  command_tonecontrol="PSTONE CTRL ",
550
648
  command_bass="PSBAS ",
551
649
  command_treble="PSTRE ",
650
+ command_cusor_up="MNCUP",
651
+ command_cusor_down="MNCDN",
652
+ command_cusor_left="MNCLT",
653
+ command_cusor_right="MNCRT",
654
+ command_cusor_enter="MNENT",
655
+ command_back="MNRTN",
656
+ command_info="MNINF",
657
+ command_options="MNOPT",
658
+ command_setup_open="MNMEN ON",
659
+ command_setup_close="MNMEN OFF",
660
+ command_setup_query="MNMEN?",
552
661
  )
553
662
 
554
663
  # States