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/foundation.py CHANGED
@@ -12,7 +12,7 @@ import logging
12
12
  import xml.etree.ElementTree as ET
13
13
  from collections.abc import Hashable
14
14
  from copy import deepcopy
15
- from typing import Dict, List, Optional, Union
15
+ from typing import Dict, List, Literal, Optional, Union, get_args
16
16
 
17
17
  import attr
18
18
 
@@ -21,30 +21,55 @@ from .appcommand import AppCommandCmd, AppCommands
21
21
  from .const import (
22
22
  APPCOMMAND_CMD_TEXT,
23
23
  APPCOMMAND_NAME,
24
+ AUDIO_RESTORER_MAP,
25
+ AUDIO_RESTORER_MAP_LABELS,
24
26
  AVR,
25
27
  AVR_X,
26
28
  AVR_X_2016,
29
+ BLUETOOTH_OUTPUT_MAP_LABELS,
30
+ BLUETOOTH_OUTPUT_MODES_MAP,
31
+ CHANNEL_VOLUME_MAP,
27
32
  DENON_ATTR_SETATTR,
28
33
  DENONAVR_TELNET_COMMANDS,
29
34
  DENONAVR_URLS,
30
35
  DESCRIPTION_TYPES,
31
36
  DEVICEINFO_AVR_X_PATTERN,
32
37
  DEVICEINFO_COMMAPI_PATTERN,
38
+ DIMMER_MODE_MAP,
39
+ DIMMER_MODE_MAP_LABELS,
40
+ ECO_MODE_MAP,
41
+ ECO_MODE_MAP_LABELS,
42
+ HDMI_OUTPUT_MAP_LABELS,
33
43
  MAIN_ZONE,
34
44
  POWER_STATES,
45
+ SETTINGS_MENU_STATES,
35
46
  VALID_RECEIVER_TYPES,
36
47
  VALID_ZONES,
48
+ VIDEO_PROCESSING_MODES_MAP,
49
+ VIDEO_PROCESSING_MODES_MAP_LABELS,
37
50
  ZONE2,
38
51
  ZONE2_TELNET_COMMANDS,
39
52
  ZONE2_URLS,
40
53
  ZONE3,
41
54
  ZONE3_TELNET_COMMANDS,
42
55
  ZONE3_URLS,
56
+ AudioRestorers,
57
+ AutoStandbys,
58
+ BluetoothOutputModes,
59
+ DimmerModes,
60
+ EcoModes,
61
+ HDMIAudioDecodes,
62
+ HDMIOutputs,
63
+ PanelLocks,
43
64
  ReceiverType,
44
65
  ReceiverURLs,
66
+ RoomSizes,
45
67
  TelnetCommands,
68
+ TransducerLPFs,
69
+ VideoProcessingModes,
46
70
  )
47
71
  from .exceptions import (
72
+ AvrCommandError,
48
73
  AvrForbiddenError,
49
74
  AvrIncompleteResponseError,
50
75
  AvrNetworkError,
@@ -57,6 +82,26 @@ from .ssdp import evaluate_scpd_xml
57
82
  _LOGGER = logging.getLogger(__name__)
58
83
 
59
84
 
85
+ def convert_on_off_bool(value: str) -> Optional[bool]:
86
+ """Convert a ON/OFF string to bool."""
87
+ if value is None:
88
+ return None
89
+ if value.lower() == "on":
90
+ return True
91
+ if value.lower() == "off":
92
+ return False
93
+ return None
94
+
95
+
96
+ def convert_on_off_bool_str(value: str) -> Optional[Union[bool, str]]:
97
+ """Convert a ON/OFF string to bool with fallback to raw value."""
98
+ val = convert_on_off_bool(value)
99
+ if val is not None:
100
+ return val
101
+
102
+ return value
103
+
104
+
60
105
  @attr.s(auto_attribs=True, on_setattr=DENON_ATTR_SETATTR)
61
106
  class DenonAVRDeviceInfo:
62
107
  """Implements a class with device information of the receiver."""
@@ -102,6 +147,75 @@ class DenonAVRDeviceInfo:
102
147
  _power: Optional[str] = attr.ib(
103
148
  converter=attr.converters.optional(str), default=None
104
149
  )
150
+ _settings_menu: Optional[bool] = attr.ib(
151
+ converter=attr.converters.optional(convert_on_off_bool), default=None
152
+ )
153
+ _dimmer: Optional[str] = attr.ib(
154
+ converter=attr.converters.optional(str), default=None
155
+ )
156
+ _auto_standby: Optional[str] = attr.ib(
157
+ converter=attr.converters.optional(str), default=None
158
+ )
159
+ _auto_standbys = get_args(AutoStandbys)
160
+ _sleep: Optional[Union[str, int]] = attr.ib(
161
+ converter=attr.converters.optional(str), default=None
162
+ )
163
+ _delay: Optional[int] = attr.ib(
164
+ converter=attr.converters.optional(int), default=None
165
+ )
166
+ _eco_mode: Optional[str] = attr.ib(
167
+ converter=attr.converters.optional(str), default=None
168
+ )
169
+ _hdmi_output: Optional[str] = attr.ib(
170
+ converter=attr.converters.optional(str), default=None
171
+ )
172
+ _hdmi_audio_decode: Optional[str] = attr.ib(
173
+ converter=attr.converters.optional(str), default=None
174
+ )
175
+ _hdmi_audio_decodes = get_args(HDMIAudioDecodes)
176
+ _video_processing_mode: Optional[str] = attr.ib(
177
+ converter=attr.converters.optional(str), default=None
178
+ )
179
+ _video_processing_modes = get_args(VideoProcessingModes)
180
+ _tactile_transducer: Optional[str] = attr.ib(
181
+ converter=attr.converters.optional(str), default=None
182
+ )
183
+ _tactile_transducer_level: Optional[float] = attr.ib(
184
+ converter=attr.converters.optional(float), default=None
185
+ )
186
+ _tactile_transducer_lpf: Optional[str] = attr.ib(
187
+ converter=attr.converters.optional(str), default=None
188
+ )
189
+ _tactile_transducer_lpfs = get_args(TransducerLPFs)
190
+ _room_size: Optional[str] = attr.ib(
191
+ converter=attr.converters.optional(str), default=None
192
+ )
193
+ _room_sizes = get_args(RoomSizes)
194
+ _triggers: Optional[Dict[int, str]] = attr.ib(default=None)
195
+ _speaker_preset: Optional[int] = attr.ib(
196
+ converter=attr.converters.optional(str), default=None
197
+ )
198
+ _bt_transmitter: Optional[bool] = attr.ib(
199
+ converter=attr.converters.optional(convert_on_off_bool), default=None
200
+ )
201
+ _bt_output_mode: Optional[str] = attr.ib(
202
+ converter=attr.converters.optional(str), default=None
203
+ )
204
+ _bt_output_modes = get_args(BluetoothOutputModes)
205
+ _delay_time: Optional[int] = attr.ib(
206
+ converter=attr.converters.optional(int), default=None
207
+ )
208
+ _audio_restorer: Optional[str] = attr.ib(
209
+ converter=attr.converters.optional(str), default=None
210
+ )
211
+ _audio_restorers = get_args(AudioRestorers)
212
+ _panel_locks = get_args(PanelLocks)
213
+ _graphic_eq: Optional[bool] = attr.ib(
214
+ converter=attr.converters.optional(convert_on_off_bool), default=None
215
+ )
216
+ _headphone_eq: Optional[bool] = attr.ib(
217
+ converter=attr.converters.optional(convert_on_off_bool), default=None
218
+ )
105
219
  _is_setup: bool = attr.ib(converter=bool, default=False, init=False)
106
220
  _allow_recovery: bool = attr.ib(converter=bool, default=True, init=True)
107
221
  _setup_lock: asyncio.Lock = attr.ib(default=attr.Factory(asyncio.Lock))
@@ -128,6 +242,181 @@ class DenonAVRDeviceInfo:
128
242
  if self.zone == zone and parameter in POWER_STATES:
129
243
  self._power = parameter
130
244
 
245
+ async def _async_settings_menu_callback(
246
+ self, zone: str, event: str, parameter: str
247
+ ) -> None:
248
+ """Handle a settings menu event."""
249
+ if (
250
+ event == "MN"
251
+ and parameter[0:3] == "MEN"
252
+ and parameter[4:] in SETTINGS_MENU_STATES
253
+ ):
254
+ self._settings_menu = parameter[4:]
255
+
256
+ async def _async_dimmer_callback(
257
+ self, zone: str, event: str, parameter: str
258
+ ) -> None:
259
+ """Handle a dimmer change event."""
260
+ if event == "DIM" and parameter[1:] in DIMMER_MODE_MAP_LABELS:
261
+ self._dimmer = DIMMER_MODE_MAP_LABELS[parameter[1:]]
262
+
263
+ async def _async_auto_standby_callback(
264
+ self, zone: str, event: str, parameter: str
265
+ ) -> None:
266
+ """Handle a auto standby change event."""
267
+ if zone == "Main" and event == "STBY":
268
+ self._auto_standby = parameter
269
+
270
+ async def _async_auto_sleep_callback(
271
+ self, zone: str, event: str, parameter: str
272
+ ) -> None:
273
+ """Handle a sleep change event."""
274
+ if event != "SLP":
275
+ return
276
+
277
+ if parameter == "OFF":
278
+ self._sleep = parameter
279
+ else:
280
+ self._sleep = int(parameter)
281
+
282
+ async def _async_room_size_callback(
283
+ self, zone: str, event: str, parameter: str
284
+ ) -> None:
285
+ """Handle a room size change event."""
286
+ if parameter[:3] != "RSZ":
287
+ return
288
+
289
+ self._room_size = parameter[4:]
290
+
291
+ async def _async_trigger_callback(
292
+ self, zone: str, event: str, parameter: str
293
+ ) -> None:
294
+ """Handle a trigger change event."""
295
+ if event != "TR":
296
+ return
297
+
298
+ values = parameter.split()
299
+ if len(values) != 2:
300
+ return
301
+
302
+ if self._triggers is None:
303
+ self._triggers = {}
304
+
305
+ self._triggers[int(values[0])] = values[1]
306
+
307
+ async def _async_delay_callback(
308
+ self, zone: str, event: str, parameter: str
309
+ ) -> None:
310
+ """Handle a delay change event."""
311
+ if event == "PS" and parameter[0:3] == "DEL":
312
+ self._delay = int(parameter[4:])
313
+
314
+ async def _async_eco_mode_callback(
315
+ self, zone: str, event: str, parameter: str
316
+ ) -> None:
317
+ """Handle an Eco-mode change event."""
318
+ if event == "ECO" and parameter in ECO_MODE_MAP_LABELS:
319
+ self._eco_mode = ECO_MODE_MAP_LABELS[parameter]
320
+
321
+ async def _async_hdmi_output_callback(
322
+ self, zone: str, event: str, parameter: str
323
+ ) -> None:
324
+ """Handle a HDMI output change event."""
325
+ if event == "VS" and parameter[0:4] == "MONI":
326
+ self._hdmi_output = HDMI_OUTPUT_MAP_LABELS[parameter]
327
+
328
+ async def _async_hdmi_audio_decode_callback(
329
+ self, zone: str, event: str, parameter: str
330
+ ) -> None:
331
+ """Handle a HDMI Audio Decode mode change event."""
332
+ if event == "VS" and parameter[0:5] == "AUDIO":
333
+ self._hdmi_audio_decode = parameter[6:]
334
+
335
+ async def _async_video_processing_mode_callback(
336
+ self, zone: str, event: str, parameter: str
337
+ ) -> None:
338
+ """Handle a Video Processing Mode change event."""
339
+ if event == "VS" and parameter[0:3] == "VPM":
340
+ self._video_processing_mode = VIDEO_PROCESSING_MODES_MAP_LABELS[
341
+ parameter[3:]
342
+ ]
343
+
344
+ async def _async_tactile_transducer_callback(
345
+ self, zone: str, event: str, parameter: str
346
+ ) -> None:
347
+ """Handle a tactile transducer change event."""
348
+ key_value = parameter.split()
349
+ if len(key_value) != 2 or parameter[0:3] != "TTR":
350
+ return
351
+
352
+ key = key_value[0]
353
+ value = key_value[1]
354
+ if value == "END":
355
+ return
356
+
357
+ if key == "TTR":
358
+ self._tactile_transducer = value
359
+ elif key == "TTRLEV":
360
+ self._tactile_transducer_level = CHANNEL_VOLUME_MAP[value]
361
+ elif key == "TTRLPF":
362
+ self._tactile_transducer_lpf = f"{int(value)} Hz"
363
+
364
+ async def _async_speaker_preset_callback(
365
+ self, zone: str, event: str, parameter: str
366
+ ) -> None:
367
+ """Handle a speaker preset change event."""
368
+ if event != "SP":
369
+ return
370
+
371
+ if parameter[0:2] == "PR":
372
+ self._speaker_preset = int(parameter[3:])
373
+
374
+ async def _async_bt_callback(self, zone: str, event: str, parameter: str) -> None:
375
+ """Handle a Bluetooth change event."""
376
+ if event != "BT" or parameter[0:2] != "TX":
377
+ return
378
+
379
+ if parameter[3:] in ("ON", "OFF"):
380
+ self._bt_transmitter = parameter[3:]
381
+ else:
382
+ self._bt_output_mode = BLUETOOTH_OUTPUT_MAP_LABELS[parameter[3:]]
383
+
384
+ async def _async_delay_time_callback(
385
+ self, zone: str, event: str, parameter: str
386
+ ) -> None:
387
+ """Handle a delay time change event."""
388
+ if event != "PS" or parameter[0:3] != "DEL":
389
+ return
390
+
391
+ self._delay_time = int(parameter[4:])
392
+
393
+ async def _async_audio_restorer_callback(
394
+ self, zone: str, event: str, parameter: str
395
+ ) -> None:
396
+ """Handle an audio restorer change event."""
397
+ if event != "PS" or parameter[0:4] != "RSTR":
398
+ return
399
+
400
+ self._audio_restorer = AUDIO_RESTORER_MAP_LABELS[parameter[5:]]
401
+
402
+ async def _async_graphic_eq_callback(
403
+ self, zone: str, event: str, parameter: str
404
+ ) -> None:
405
+ """Handle a Graphic EQ change event."""
406
+ if parameter[0:3] != "GEQ":
407
+ return
408
+
409
+ self._graphic_eq = parameter[4:]
410
+
411
+ async def _async_headphone_eq_callback(
412
+ self, zone: str, event: str, parameter: str
413
+ ) -> None:
414
+ """Handle a Headphone EQ change event."""
415
+ if parameter[0:3] != "HEQ":
416
+ return
417
+
418
+ self._headphone_eq = parameter[4:]
419
+
131
420
  def get_own_zone(self) -> str:
132
421
  """
133
422
  Get zone from actual instance.
@@ -167,6 +456,31 @@ class DenonAVRDeviceInfo:
167
456
  power_event = "Z3"
168
457
  self.telnet_api.register_callback(power_event, self._async_power_callback)
169
458
 
459
+ self.telnet_api.register_callback("MN", self._async_settings_menu_callback)
460
+ self.telnet_api.register_callback("DIM", self._async_dimmer_callback)
461
+ self.telnet_api.register_callback("PS", self._async_delay_callback)
462
+ self.telnet_api.register_callback("ECO", self._async_eco_mode_callback)
463
+ self.telnet_api.register_callback("VS", self._async_hdmi_output_callback)
464
+ self.telnet_api.register_callback(
465
+ "VS", self._async_hdmi_audio_decode_callback
466
+ )
467
+ self.telnet_api.register_callback(
468
+ "VS", self._async_video_processing_mode_callback
469
+ )
470
+ self.telnet_api.register_callback(
471
+ "SS", self._async_tactile_transducer_callback
472
+ )
473
+ self.telnet_api.register_callback("STBY", self._async_auto_standby_callback)
474
+ self.telnet_api.register_callback("SLP", self._async_auto_sleep_callback)
475
+ self.telnet_api.register_callback("PS", self._async_room_size_callback)
476
+ self.telnet_api.register_callback("TR", self._async_trigger_callback)
477
+ self.telnet_api.register_callback("SP", self._async_speaker_preset_callback)
478
+ self.telnet_api.register_callback("BT", self._async_bt_callback)
479
+ self.telnet_api.register_callback("PS", self._async_delay_time_callback)
480
+ self.telnet_api.register_callback("PS", self._async_audio_restorer_callback)
481
+ self.telnet_api.register_callback("PS", self._async_graphic_eq_callback)
482
+ self.telnet_api.register_callback("PS", self._async_headphone_eq_callback)
483
+
170
484
  self._is_setup = True
171
485
  _LOGGER.debug("Finished device setup")
172
486
 
@@ -521,11 +835,241 @@ class DenonAVRDeviceInfo:
521
835
  """
522
836
  return self._power
523
837
 
838
+ @property
839
+ def settings_menu(self) -> Optional[bool]:
840
+ """
841
+ Returns the settings menu state of the device.
842
+
843
+ Only available if using Telnet.
844
+ """
845
+ return self._settings_menu
846
+
847
+ @property
848
+ def dimmer(self) -> Optional[str]:
849
+ """
850
+ Returns the dimmer state of the device.
851
+
852
+ Only available if using Telnet.
853
+
854
+ Possible values are: "Off", "Dark", "Dim" and "Bright"
855
+ """
856
+ return self._dimmer
857
+
858
+ @property
859
+ def auto_standby(self) -> Optional[str]:
860
+ """
861
+ Return the auto-standby state of the device.
862
+
863
+ Only available if using Telnet.
864
+
865
+ Possible values are: "OFF", "15M", "30M", "60M"
866
+ """
867
+ return self._auto_standby
868
+
869
+ @property
870
+ def sleep(self) -> Optional[Union[str, int]]:
871
+ """
872
+ Return the sleep timer for the device.
873
+
874
+ Only available if using Telnet.
875
+
876
+ Possible values are: "OFF" and 1-120 (in minutes)
877
+ """
878
+ return self._sleep
879
+
880
+ @property
881
+ def delay(self) -> Optional[int]:
882
+ """
883
+ Return the audio delay for the device in ms.
884
+
885
+ Only available if using Telnet.
886
+ """
887
+ return self._delay
888
+
889
+ @property
890
+ def eco_mode(self) -> Optional[str]:
891
+ """
892
+ Returns the eco-mode for the device.
893
+
894
+ Only available if using Telnet.
895
+
896
+ Possible values are: "Off", "On", "Auto"
897
+ """
898
+ return self._eco_mode
899
+
900
+ @property
901
+ def hdmi_output(self) -> Optional[str]:
902
+ """
903
+ Returns the HDMI-output for the device.
904
+
905
+ Only available if using Telnet.
906
+
907
+ Possible values are: "Auto", "HDMI1", "HDMI2"
908
+ """
909
+ return self._hdmi_output
910
+
911
+ @property
912
+ def hdmi_audio_decode(self) -> Optional[str]:
913
+ """
914
+ Returns the HDMI Audio Decode for the device.
915
+
916
+ Only available if using Telnet.
917
+
918
+ Possible values are: "AMP", "TV"
919
+ """
920
+ return self._hdmi_audio_decode
921
+
922
+ @property
923
+ def video_processing_mode(self) -> Optional[str]:
924
+ """
925
+ Return the video processing mode for the device.
926
+
927
+ Only available if using Telnet.
928
+
929
+ Possible values are: "Auto", "Game", "Movie", "Bypass"
930
+ """
931
+ return self._video_processing_mode
932
+
933
+ @property
934
+ def tactile_transducer(self) -> Optional[str]:
935
+ """
936
+ Return the tactile transducer state of the device.
937
+
938
+ Only available if using Telnet.
939
+ """
940
+ return self._tactile_transducer
941
+
942
+ @property
943
+ def tactile_transducer_level(self) -> Optional[float]:
944
+ """
945
+ Return the tactile transducer level in dB.
946
+
947
+ Only available if using Telnet.
948
+ """
949
+ return self._tactile_transducer_level
950
+
951
+ @property
952
+ def tactile_transducer_lpf(self) -> Optional[str]:
953
+ """
954
+ Return the tactile transducer low pass filter frequency.
955
+
956
+ Only available if using Telnet.
957
+ """
958
+ return self._tactile_transducer_lpf
959
+
960
+ @property
961
+ def room_size(self) -> Optional[str]:
962
+ """
963
+ Return the room size for the device.
964
+
965
+ Only available if using Telnet.
966
+
967
+ Possible values are: "S", "MS", "M", "ML", "L"
968
+ """
969
+ return self._room_size
970
+
971
+ @property
972
+ def triggers(self) -> Dict[int, str]:
973
+ """
974
+ Return the triggers and their statuses for the device.
975
+
976
+ Only available if using Telnet.
977
+ """
978
+ return self._triggers
979
+
980
+ @property
981
+ def speaker_preset(self) -> Optional[int]:
982
+ """
983
+ Return the speaker preset for the device.
984
+
985
+ Only available if using Telnet.
986
+
987
+ Possible values are: "1", "2"
988
+ """
989
+ return self._speaker_preset
990
+
991
+ @property
992
+ def bt_transmitter(self) -> Optional[bool]:
993
+ """
994
+ Return the Bluetooth transmitter state for the device.
995
+
996
+ Only available if using Telnet.
997
+ """
998
+ return self._bt_transmitter
999
+
1000
+ @property
1001
+ def bt_output_mode(self) -> Optional[str]:
1002
+ """
1003
+ Return the Bluetooth output mode for the device.
1004
+
1005
+ Only available if using Telnet.
1006
+
1007
+ Possible values are: "Bluetooth + Speakers", "Bluetooth Only"
1008
+ """
1009
+ return self._bt_output_mode
1010
+
1011
+ @property
1012
+ def delay_time(self) -> Optional[int]:
1013
+ """
1014
+ Return the delay time for the device in ms.
1015
+
1016
+ Only available if using Telnet.
1017
+ """
1018
+ return self._delay_time
1019
+
1020
+ @property
1021
+ def audio_restorer(self) -> Optional[str]:
1022
+ """
1023
+ Return the audio restorer for the device.
1024
+
1025
+ Only available if using Telnet.
1026
+
1027
+ Possible values are: "Off", "Low", "Medium", "High"
1028
+ """
1029
+ return self._audio_restorer
1030
+
1031
+ @property
1032
+ def graphic_eq(self) -> Optional[bool]:
1033
+ """
1034
+ Return the Graphic EQ status for the device.
1035
+
1036
+ Only available if using Telnet.
1037
+ """
1038
+ return self._graphic_eq
1039
+
1040
+ @property
1041
+ def headphone_eq(self) -> Optional[bool]:
1042
+ """
1043
+ Return the Headphone EQ status for the device.
1044
+
1045
+ Only available if using Telnet.
1046
+ """
1047
+ return self._headphone_eq
1048
+
524
1049
  @property
525
1050
  def telnet_available(self) -> bool:
526
1051
  """Return true if telnet is connected and healthy."""
527
1052
  return self.telnet_api.connected and self.telnet_api.healthy
528
1053
 
1054
+ ##########
1055
+ # Getter #
1056
+ ##########
1057
+
1058
+ def get_trigger(self, trigger: int) -> Optional[str]:
1059
+ """
1060
+ Return the status of a specific trigger.
1061
+
1062
+ Only available if using Telnet.
1063
+
1064
+ Valid trigger values are 1-3.
1065
+ """
1066
+ if trigger < 1 or trigger > 3:
1067
+ raise AvrCommandError(f"Invalid trigger {trigger}, must be between 1 and 3")
1068
+
1069
+ if self._triggers is None:
1070
+ return None
1071
+ return self._triggers.get(trigger)
1072
+
529
1073
  ##########
530
1074
  # Setter #
531
1075
  ##########
@@ -552,7 +1096,7 @@ class DenonAVRDeviceInfo:
552
1096
  """Cursor Up on receiver via HTTP get command."""
553
1097
  if self.telnet_available:
554
1098
  await self.telnet_api.async_send_commands(
555
- self.telnet_commands.command_cusor_up
1099
+ self.telnet_commands.command_cusor_up, skip_confirmation=True
556
1100
  )
557
1101
  else:
558
1102
  await self.api.async_get_command(self.urls.command_cusor_up)
@@ -561,7 +1105,7 @@ class DenonAVRDeviceInfo:
561
1105
  """Cursor Down on receiver via HTTP get command."""
562
1106
  if self.telnet_available:
563
1107
  await self.telnet_api.async_send_commands(
564
- self.telnet_commands.command_cusor_down
1108
+ self.telnet_commands.command_cusor_down, skip_confirmation=True
565
1109
  )
566
1110
  else:
567
1111
  await self.api.async_get_command(self.urls.command_cusor_down)
@@ -570,7 +1114,7 @@ class DenonAVRDeviceInfo:
570
1114
  """Cursor Left on receiver via HTTP get command."""
571
1115
  if self.telnet_available:
572
1116
  await self.telnet_api.async_send_commands(
573
- self.telnet_commands.command_cusor_left
1117
+ self.telnet_commands.command_cusor_left, skip_confirmation=True
574
1118
  )
575
1119
  else:
576
1120
  await self.api.async_get_command(self.urls.command_cusor_left)
@@ -579,7 +1123,7 @@ class DenonAVRDeviceInfo:
579
1123
  """Cursor Right on receiver via HTTP get command."""
580
1124
  if self.telnet_available:
581
1125
  await self.telnet_api.async_send_commands(
582
- self.telnet_commands.command_cusor_right
1126
+ self.telnet_commands.command_cusor_right, skip_confirmation=True
583
1127
  )
584
1128
  else:
585
1129
  await self.api.async_get_command(self.urls.command_cusor_right)
@@ -588,7 +1132,7 @@ class DenonAVRDeviceInfo:
588
1132
  """Cursor Enter on receiver via HTTP get command."""
589
1133
  if self.telnet_available:
590
1134
  await self.telnet_api.async_send_commands(
591
- self.telnet_commands.command_cusor_enter
1135
+ self.telnet_commands.command_cusor_enter, skip_confirmation=True
592
1136
  )
593
1137
  else:
594
1138
  await self.api.async_get_command(self.urls.command_cusor_enter)
@@ -596,38 +1140,664 @@ class DenonAVRDeviceInfo:
596
1140
  async def async_back(self) -> None:
597
1141
  """Back command on receiver via HTTP get command."""
598
1142
  if self.telnet_available:
599
- await self.telnet_api.async_send_commands(self.telnet_commands.command_back)
1143
+ await self.telnet_api.async_send_commands(
1144
+ self.telnet_commands.command_back, skip_confirmation=True
1145
+ )
600
1146
  else:
601
1147
  await self.api.async_get_command(self.urls.command_back)
602
1148
 
603
1149
  async def async_info(self) -> None:
604
1150
  """Info OSD on receiver via HTTP get command."""
605
1151
  if self.telnet_available:
606
- await self.telnet_api.async_send_commands(self.telnet_commands.command_info)
1152
+ await self.telnet_api.async_send_commands(
1153
+ self.telnet_commands.command_info, skip_confirmation=True
1154
+ )
607
1155
  else:
608
1156
  await self.api.async_get_command(self.urls.command_info)
609
1157
 
610
1158
  async def async_options(self) -> None:
611
1159
  """Options menu on receiver via HTTP get command."""
612
- await self.api.async_get_command(self.urls.command_options)
613
-
614
- async def async_settings_menu(self) -> None:
615
- """Options menu on receiver via HTTP get command."""
616
- res = await self.api.async_get_command(self.urls.command_setup_query)
617
1160
  if self.telnet_available:
618
- if res is not None and res == "MNMEN ON":
1161
+ await self.telnet_api.async_send_commands(
1162
+ self.telnet_commands.command_options, skip_confirmation=True
1163
+ )
1164
+ else:
1165
+ await self.api.async_get_command(self.urls.command_options)
1166
+
1167
+ async def async_settings_menu(self) -> None:
1168
+ """
1169
+ Options menu on receiver via HTTP get command.
1170
+
1171
+ Only available if using Telnet.
1172
+ """
1173
+ if self._settings_menu:
1174
+ await self.telnet_api.async_send_commands(
1175
+ self.telnet_commands.command_setup_close
1176
+ )
1177
+ else:
1178
+ await self.telnet_api.async_send_commands(
1179
+ self.telnet_commands.command_setup_open
1180
+ )
1181
+
1182
+ async def async_channel_level_adjust(self) -> None:
1183
+ """Toggle the channel level adjust menu on receiver via HTTP get command."""
1184
+ if self.telnet_available:
1185
+ await self.telnet_api.async_send_commands(
1186
+ self.telnet_commands.command_channel_level_adjust
1187
+ )
1188
+ else:
1189
+ await self.api.async_get_command(self.urls.command_channel_level_adjust)
1190
+
1191
+ async def async_dimmer_toggle(self) -> None:
1192
+ """Toggle dimmer on receiver via HTTP get command."""
1193
+ if self.telnet_available:
1194
+ await self.telnet_api.async_send_commands(
1195
+ self.telnet_commands.command_dimmer_toggle
1196
+ )
1197
+ else:
1198
+ await self.api.async_get_command(self.urls.command_dimmer_toggle)
1199
+
1200
+ async def async_dimmer(self, mode: DimmerModes) -> None:
1201
+ """Set dimmer mode on receiver via HTTP get command."""
1202
+ if mode not in DimmerModes:
1203
+ raise AvrCommandError("Invalid dimmer mode")
1204
+
1205
+ mapped_mode = DIMMER_MODE_MAP[mode]
1206
+ if self.telnet_available:
1207
+ await self.telnet_api.async_send_commands(
1208
+ self.telnet_commands.command_dimmer_set.format(mode=mapped_mode)
1209
+ )
1210
+ else:
1211
+ await self.api.async_get_command(
1212
+ self.urls.command_dimmer_set.format(mode=mapped_mode)
1213
+ )
1214
+
1215
+ async def async_tactile_transducer_on(self) -> None:
1216
+ """Turn on tactile transducer on receiver via HTTP get command."""
1217
+ if self.telnet_available:
1218
+ await self.telnet_api.async_send_commands(
1219
+ self.telnet_commands.command_tactile_transducer.format(mode="ON")
1220
+ )
1221
+ else:
1222
+ await self.api.async_get_command(
1223
+ self.urls.command_tactile_transducer.format(mode="ON")
1224
+ )
1225
+
1226
+ async def async_auto_standby(self, auto_standby: AutoStandbys) -> None:
1227
+ """Set auto standby on receiver via HTTP get command."""
1228
+ if auto_standby not in self._auto_standbys:
1229
+ raise AvrCommandError("Invalid Auto Standby mode")
1230
+ if self.telnet_available:
1231
+ await self.telnet_api.async_send_commands(
1232
+ self.telnet_commands.command_auto_standby.format(mode=auto_standby)
1233
+ )
1234
+ else:
1235
+ await self.api.async_get_command(
1236
+ self.urls.command_auto_standby.format(mode=auto_standby)
1237
+ )
1238
+
1239
+ async def async_sleep(self, sleep: Union[Literal["OFF"], int]) -> None:
1240
+ """
1241
+ Set auto standby on receiver via HTTP get command.
1242
+
1243
+ Valid sleep values are "OFF" and 1-120 (in minutes)
1244
+ """
1245
+ if sleep != "OFF" and sleep not in range(1, 120):
1246
+ raise AvrCommandError("Invalid sleep value")
1247
+
1248
+ local_sleep = f"{sleep:03}" if isinstance(sleep, int) else sleep
1249
+ if self.telnet_available:
1250
+ await self.telnet_api.async_send_commands(
1251
+ self.telnet_commands.command_sleep.format(value=local_sleep)
1252
+ )
1253
+ else:
1254
+ await self.api.async_get_command(
1255
+ self.urls.command_sleep.format(value=local_sleep)
1256
+ )
1257
+
1258
+ async def async_tactile_transducer_off(self) -> None:
1259
+ """Turn on tactile transducer on receiver via HTTP get command."""
1260
+ if self.telnet_available:
1261
+ await self.telnet_api.async_send_commands(
1262
+ self.telnet_commands.command_tactile_transducer.format(mode="OFF")
1263
+ )
1264
+ else:
1265
+ await self.api.async_get_command(
1266
+ self.urls.command_tactile_transducer.format(mode="OFF")
1267
+ )
1268
+
1269
+ async def async_tactile_transducer_toggle(self) -> None:
1270
+ """
1271
+ Turn on tactile transducer on receiver via HTTP get command.
1272
+
1273
+ Only available if using Telnet.
1274
+ """
1275
+ if self._tactile_transducer != "OFF":
1276
+ await self.async_tactile_transducer_off()
1277
+ else:
1278
+ await self.async_tactile_transducer_on()
1279
+
1280
+ async def async_tactile_transducer_level_up(self) -> None:
1281
+ """Increase the transducer level on receiver via HTTP get command."""
1282
+ if self.telnet_available:
1283
+ await self.telnet_api.async_send_commands(
1284
+ self.telnet_commands.command_tactile_transducer_level.format(mode="UP")
1285
+ )
1286
+ else:
1287
+ await self.api.async_get_command(
1288
+ self.urls.command_tactile_transducer_level.format(mode="UP")
1289
+ )
1290
+
1291
+ async def async_tactile_transducer_level_down(self) -> None:
1292
+ """Decrease the transducer level on receiver via HTTP get command."""
1293
+ if self.telnet_available:
1294
+ await self.telnet_api.async_send_commands(
1295
+ self.telnet_commands.command_tactile_transducer_level.format(
1296
+ mode="DOWN"
1297
+ )
1298
+ )
1299
+ else:
1300
+ await self.api.async_get_command(
1301
+ self.urls.command_tactile_transducer_level.format(mode="DOWN")
1302
+ )
1303
+
1304
+ async def async_transducer_lpf(self, lpf: TransducerLPFs):
1305
+ """Set transducer low pass filter on receiver via HTTP get command."""
1306
+ if lpf not in self._tactile_transducer_lpfs:
1307
+ raise AvrCommandError("Invalid tactile transducer low pass filter")
1308
+
1309
+ frequency = lpf.split()[0]
1310
+ if len(frequency) == 2:
1311
+ frequency = f"0{frequency}"
1312
+ if self.telnet_available:
1313
+ await self.telnet_api.async_send_commands(
1314
+ self.telnet_commands.command_tactile_transducer_lpf.format(
1315
+ frequency=frequency
1316
+ )
1317
+ )
1318
+ else:
1319
+ await self.api.async_get_command(
1320
+ self.urls.command_tactile_transducer_lpf.format(frequency=frequency)
1321
+ )
1322
+
1323
+ async def async_room_size(self, room_size: RoomSizes) -> None:
1324
+ """Set room size on receiver via HTTP get command."""
1325
+ if room_size not in self._room_sizes:
1326
+ raise AvrCommandError("Invalid room size")
1327
+
1328
+ if self.telnet_available:
1329
+ await self.telnet_api.async_send_commands(
1330
+ self.telnet_commands.command_room_size.format(size=room_size)
1331
+ )
1332
+ else:
1333
+ await self.api.async_get_command(
1334
+ self.urls.command_room_size.format(size=room_size)
1335
+ )
1336
+
1337
+ async def async_trigger_on(self, trigger: int) -> None:
1338
+ """
1339
+ Set trigger to ON on receiver via HTTP get command.
1340
+
1341
+ :param trigger: Trigger number to set to ON. Valid values are 1-3.
1342
+ """
1343
+ if trigger < 1 or trigger > 3:
1344
+ raise AvrCommandError("Trigger number must be between 1 and 3")
1345
+
1346
+ if self.telnet_available:
1347
+ await self.telnet_api.async_send_commands(
1348
+ self.telnet_commands.command_trigger.format(number=trigger, mode="ON")
1349
+ )
1350
+ else:
1351
+ await self.api.async_get_command(
1352
+ self.urls.command_trigger.format(number=trigger, mode="ON")
1353
+ )
1354
+
1355
+ async def async_trigger_off(self, trigger: int) -> None:
1356
+ """
1357
+ Set trigger to OFF on receiver via HTTP get command.
1358
+
1359
+ :param trigger: Trigger number to set to OFF. Valid values are 1-3.
1360
+ """
1361
+ if trigger < 1 or trigger > 3:
1362
+ raise AvrCommandError("Trigger number must be between 1 and 3")
1363
+
1364
+ if self.telnet_available:
1365
+ await self.telnet_api.async_send_commands(
1366
+ self.telnet_commands.command_trigger.format(number=trigger, mode="OFF")
1367
+ )
1368
+ else:
1369
+ await self.api.async_get_command(
1370
+ self.urls.command_trigger.format(number=trigger, mode="OFF")
1371
+ )
1372
+
1373
+ async def async_trigger_toggle(self, trigger: int) -> None:
1374
+ """
1375
+ Toggle trigger on receiver via HTTP get command.
1376
+
1377
+ Only available if using Telnet.
1378
+
1379
+ :param trigger: Trigger number to toggle. Valid values are 1-3.
1380
+ """
1381
+ if trigger < 1 or trigger > 3:
1382
+ raise AvrCommandError("Trigger number must be between 1 and 3")
1383
+
1384
+ trigger_status = self._triggers.get(trigger)
1385
+ if trigger_status == "ON":
1386
+ await self.async_trigger_off(trigger)
1387
+ else:
1388
+ await self.async_trigger_on(trigger)
1389
+
1390
+ async def async_quick_select_mode(self, quick_select_number: int) -> None:
1391
+ """
1392
+ Set quick select mode on receiver via HTTP get command.
1393
+
1394
+ :param quick_select_number: Quick select number to set. Valid values are 1-5.
1395
+ """
1396
+ if quick_select_number not in range(1, 5):
1397
+ raise AvrCommandError("Quick select number must be between 1 and 5")
1398
+
1399
+ if self.telnet_available:
1400
+ await self.telnet_api.async_send_commands(
1401
+ self.telnet_commands.command_quick_select_mode.format(
1402
+ number=quick_select_number
1403
+ )
1404
+ )
1405
+ else:
1406
+ await self.api.async_get_command(
1407
+ self.urls.command_quick_select_mode.format(number=quick_select_number)
1408
+ )
1409
+
1410
+ async def async_quick_select_memory(self, quick_select_number: int) -> None:
1411
+ """
1412
+ Set quick select memory on receiver via HTTP get command.
1413
+
1414
+ :param quick_select_number: Quick select number to set. Valid values are 1-5.
1415
+ """
1416
+ if quick_select_number not in range(1, 5):
1417
+ raise AvrCommandError("Quick select number must be between 1 and 5")
1418
+
1419
+ if self.telnet_available:
1420
+ await self.telnet_api.async_send_commands(
1421
+ self.telnet_commands.command_quick_select_memory.format(
1422
+ number=quick_select_number
1423
+ )
1424
+ )
1425
+ else:
1426
+ await self.api.async_get_command(
1427
+ self.urls.command_quick_select_memory.format(number=quick_select_number)
1428
+ )
1429
+
1430
+ async def async_delay_up(self) -> None:
1431
+ """Delay up on receiver via HTTP get command."""
1432
+ if self.telnet_available:
1433
+ await self.telnet_api.async_send_commands(
1434
+ self.telnet_commands.command_delay_up
1435
+ )
1436
+ else:
1437
+ await self.api.async_get_command(self.urls.command_delay_up)
1438
+
1439
+ async def async_delay_down(self) -> None:
1440
+ """Delay down on receiver via HTTP get command."""
1441
+ if self.telnet_available:
1442
+ await self.telnet_api.async_send_commands(
1443
+ self.telnet_commands.command_delay_down
1444
+ )
1445
+ else:
1446
+ await self.api.async_get_command(self.urls.command_delay_down)
1447
+
1448
+ async def async_eco_mode(self, mode: EcoModes) -> None:
1449
+ """Set Eco mode."""
1450
+ if mode not in EcoModes:
1451
+ raise AvrCommandError("Invalid Eco mode")
1452
+
1453
+ mapped_mode = ECO_MODE_MAP[mode]
1454
+ if self.telnet_available:
1455
+ await self.telnet_api.async_send_commands(
1456
+ self.telnet_commands.command_eco_mode.format(mode=mapped_mode)
1457
+ )
1458
+ else:
1459
+ await self.api.async_get_command(
1460
+ self.urls.command_eco_mode.format(mode=mapped_mode)
1461
+ )
1462
+
1463
+ async def async_hdmi_output(self, output: HDMIOutputs) -> None:
1464
+ """Set HDMI output."""
1465
+ if output not in HDMIOutputs:
1466
+ raise AvrCommandError("Invalid HDMI output mode")
1467
+
1468
+ mapped_output = HDMIOutputs[output]
1469
+ if self.telnet_available:
1470
+ await self.telnet_api.async_send_commands(
1471
+ self.telnet_commands.command_hdmi_output.format(output=mapped_output)
1472
+ )
1473
+ else:
1474
+ await self.api.async_get_command(
1475
+ self.urls.command_hdmi_output.format(output=mapped_output)
1476
+ )
1477
+
1478
+ async def async_hdmi_audio_decode(self, mode: HDMIAudioDecodes) -> None:
1479
+ """Set HDMI Audio Decode mode on receiver via HTTP get command."""
1480
+ if mode not in self._hdmi_audio_decodes:
1481
+ raise AvrCommandError("Invalid HDMI Audio Decode mode")
1482
+
1483
+ if self.telnet_available:
1484
+ await self.telnet_api.async_send_commands(
1485
+ self.telnet_commands.command_hdmi_audio_decode.format(mode=mode)
1486
+ )
1487
+ else:
1488
+ await self.api.async_get_command(
1489
+ self.urls.command_hdmi_audio_decode.format(mode=mode)
1490
+ )
1491
+
1492
+ async def async_video_processing_mode(self, mode: VideoProcessingModes) -> None:
1493
+ """Set video processing mode on receiver via HTTP get command."""
1494
+ if mode not in self._video_processing_modes:
1495
+ raise AvrCommandError("Invalid video processing mode")
1496
+ processing_mode = VIDEO_PROCESSING_MODES_MAP[mode]
1497
+ if self.telnet_available:
1498
+ await self.telnet_api.async_send_commands(
1499
+ self.telnet_commands.command_video_processing_mode.format(
1500
+ mode=processing_mode
1501
+ )
1502
+ )
1503
+ else:
1504
+ await self.api.async_get_command(
1505
+ self.urls.command_video_processing_mode.format(mode=processing_mode)
1506
+ )
1507
+
1508
+ async def async_status(self) -> str:
1509
+ """Get status of receiver via HTTP get command."""
1510
+ if "denon" not in self.manufacturer.lower():
1511
+ raise AvrCommandError("Status command is only supported for Denon devices")
1512
+ return await self.api.async_get_command(self.urls.command_status)
1513
+
1514
+ async def async_system_reset(self) -> None:
1515
+ """DANGER! Reset the receiver via HTTP get command."""
1516
+ if self.telnet_available:
1517
+ await self.telnet_api.async_send_commands(
1518
+ self.telnet_commands.command_system_reset
1519
+ )
1520
+ else:
1521
+ await self.api.async_get_command(self.urls.command_system_reset)
1522
+
1523
+ async def async_network_restart(self) -> None:
1524
+ """Restart the network on the receiver via HTTP get command."""
1525
+ if self.telnet_available:
1526
+ await self.telnet_api.async_send_commands(
1527
+ self.telnet_commands.command_network_restart
1528
+ )
1529
+ else:
1530
+ await self.api.async_get_command(self.urls.command_network_restart)
1531
+
1532
+ async def async_speaker_preset(self, preset: int) -> None:
1533
+ """
1534
+ Set speaker preset on receiver via HTTP get command.
1535
+
1536
+ Valid preset values are 1-2.
1537
+ """
1538
+ if preset < 1 or preset > 2:
1539
+ raise AvrCommandError("Speaker preset number must be 1 or 2")
1540
+
1541
+ if self.telnet_available:
1542
+ await self.telnet_api.async_send_commands(
1543
+ self.telnet_commands.command_speaker_preset.format(number=preset)
1544
+ )
1545
+ else:
1546
+ await self.api.async_get_command(
1547
+ self.urls.command_speaker_preset.format(number=preset)
1548
+ )
1549
+
1550
+ async def async_speaker_preset_toggle(self) -> None:
1551
+ """
1552
+ Toggle speaker preset on receiver via HTTP get command.
1553
+
1554
+ Only available if using Telnet.
1555
+ """
1556
+ speaker_preset = 1 if self._speaker_preset == 2 else 2
1557
+ await self.async_speaker_preset(speaker_preset)
1558
+
1559
+ async def async_bt_transmitter_on(
1560
+ self,
1561
+ ) -> None:
1562
+ """Turn on Bluetooth transmitter on receiver via HTTP get command."""
1563
+ if self.telnet_available:
1564
+ await self.telnet_api.async_send_commands(
1565
+ self.telnet_commands.command_bluetooth_transmitter.format(mode="ON")
1566
+ )
1567
+ else:
1568
+ await self.api.async_get_command(
1569
+ self.urls.command_bluetooth_transmitter.format(mode="ON")
1570
+ )
1571
+
1572
+ async def async_bt_transmitter_off(
1573
+ self,
1574
+ ) -> None:
1575
+ """Turn off Bluetooth transmitter on receiver via HTTP get command."""
1576
+ if self.telnet_available:
1577
+ await self.telnet_api.async_send_commands(
1578
+ self.telnet_commands.command_bluetooth_transmitter.format(mode="OFF")
1579
+ )
1580
+ else:
1581
+ await self.api.async_get_command(
1582
+ self.urls.command_bluetooth_transmitter.format(mode="OFF")
1583
+ )
1584
+
1585
+ async def async_bt_transmitter_toggle(self) -> None:
1586
+ """
1587
+ Toggle Bluetooth transmitter mode on receiver via HTTP get command.
1588
+
1589
+ Only available if using Telnet.
1590
+ """
1591
+ if self.bt_transmitter:
1592
+ await self.async_bt_transmitter_off()
1593
+ else:
1594
+ await self.async_bt_transmitter_on()
1595
+
1596
+ async def async_bt_output_mode(self, mode: BluetoothOutputModes) -> None:
1597
+ """Set Bluetooth transmitter mode on receiver via HTTP get command."""
1598
+ if mode not in self._bt_output_modes:
1599
+ raise AvrCommandError("Invalid Bluetooth output mode")
1600
+
1601
+ mapped_mode = BLUETOOTH_OUTPUT_MODES_MAP[mode]
1602
+ if self.telnet_available:
1603
+ await self.telnet_api.async_send_commands(
1604
+ self.telnet_commands.command_bluetooth_transmitter.format(
1605
+ mode=mapped_mode
1606
+ )
1607
+ )
1608
+ else:
1609
+ await self.api.async_get_command(
1610
+ self.urls.command_bluetooth_transmitter.format(mode=mapped_mode)
1611
+ )
1612
+
1613
+ async def async_bt_output_mode_toggle(self) -> None:
1614
+ """
1615
+ Toggle Bluetooth output mode on receiver via HTTP get command.
1616
+
1617
+ Only available if using Telnet.
1618
+ """
1619
+ if self.bt_output_mode == "Bluetooth + Speakers":
1620
+ await self.async_bt_output_mode("Bluetooth Only")
1621
+ else:
1622
+ await self.async_bt_output_mode("Bluetooth + Speakers")
1623
+
1624
+ async def async_delay_time_up(self) -> None:
1625
+ """Delay time up on receiver via HTTP get command."""
1626
+ if self.telnet_available:
1627
+ await self.telnet_api.async_send_commands(
1628
+ self.telnet_commands.command_delay_time.format(value="UP")
1629
+ )
1630
+ else:
1631
+ await self.api.async_get_command(
1632
+ self.urls.command_delay_time.format(value="UP")
1633
+ )
1634
+
1635
+ async def async_delay_time_down(self) -> None:
1636
+ """Delay time up on receiver via HTTP get command."""
1637
+ if self.telnet_available:
1638
+ await self.telnet_api.async_send_commands(
1639
+ self.telnet_commands.command_delay_time.format(value="DOWN")
1640
+ )
1641
+ else:
1642
+ await self.api.async_get_command(
1643
+ self.urls.command_delay_time.format(value="DOWN")
1644
+ )
1645
+
1646
+ async def async_delay_time(self, delay_time: int) -> None:
1647
+ """
1648
+ Set delay time on receiver via HTTP get command.
1649
+
1650
+ :param delay_time: Delay time in ms. Valid values are 0-999.
1651
+ """
1652
+ if delay_time < 0 or delay_time > 999:
1653
+ raise AvrCommandError("Invalid delay time value")
1654
+
1655
+ if self.telnet_available:
1656
+ await self.telnet_api.async_send_commands(
1657
+ self.telnet_commands.command_delay_time.format(value=delay_time)
1658
+ )
1659
+ else:
1660
+ await self.api.async_get_command(
1661
+ self.urls.command_delay_time.format(value=delay_time)
1662
+ )
1663
+
1664
+ async def async_audio_restorer(self, mode: AudioRestorers):
1665
+ """Set audio restorer on receiver via HTTP get command."""
1666
+ if mode not in self._audio_restorers:
1667
+ raise AvrCommandError("Invalid audio restorer mode")
1668
+
1669
+ mapped_mode = AUDIO_RESTORER_MAP[mode]
1670
+ if self.telnet_available:
1671
+ await self.telnet_api.async_send_commands(
1672
+ self.telnet_commands.command_audio_restorer.format(mode=mapped_mode)
1673
+ )
1674
+ else:
1675
+ await self.api.async_get_command(
1676
+ self.urls.command_audio_restorer.format(mode=mapped_mode)
1677
+ )
1678
+
1679
+ async def async_remote_control_lock(self):
1680
+ """Set remote control lock on receiver via HTTP get command."""
1681
+ if self.telnet_available:
1682
+ await self.telnet_api.async_send_commands(
1683
+ self.telnet_commands.command_remote_control_lock.format(mode="ON")
1684
+ )
1685
+ else:
1686
+ await self.api.async_get_command(
1687
+ self.urls.command_remote_control_lock.format(mode="ON")
1688
+ )
1689
+
1690
+ async def async_remote_control_unlock(self):
1691
+ """Set remote control unlock on receiver via HTTP get command."""
1692
+ if self.telnet_available:
1693
+ await self.telnet_api.async_send_commands(
1694
+ self.telnet_commands.command_remote_control_lock.format(mode="OFF")
1695
+ )
1696
+ else:
1697
+ await self.api.async_get_command(
1698
+ self.urls.command_remote_control_lock.format(mode="OFF")
1699
+ )
1700
+
1701
+ async def async_panel_lock(self, panel_lock_mode: PanelLocks):
1702
+ """Set panel lock on receiver via HTTP get command."""
1703
+ if panel_lock_mode not in self._panel_locks:
1704
+ raise AvrCommandError("Invalid panel lock mode")
1705
+
1706
+ if self.telnet_available:
1707
+ if panel_lock_mode == "Panel":
619
1708
  await self.telnet_api.async_send_commands(
620
- self.telnet_commands.command_setup_close
1709
+ self.telnet_commands.command_panel_lock.format(mode="ON")
621
1710
  )
622
1711
  else:
623
1712
  await self.telnet_api.async_send_commands(
624
- self.telnet_commands.command_setup_open
1713
+ self.telnet_commands.command_panel_and_volume_lock
625
1714
  )
626
1715
  else:
627
- if res is not None and res == "MNMEN ON":
628
- await self.api.async_get_command(self.urls.command_setup_close)
1716
+ if panel_lock_mode == "Panel":
1717
+ await self.api.async_get_command(
1718
+ self.urls.command_panel_lock.format(mode="ON")
1719
+ )
629
1720
  else:
630
- await self.api.async_get_command(self.urls.command_setup_open)
1721
+ await self.api.async_get_command(
1722
+ self.urls.command_panel_and_volume_lock
1723
+ )
1724
+
1725
+ async def async_panel_unlock(self):
1726
+ """Set panel unlock on receiver via HTTP get command."""
1727
+ if self.telnet_available:
1728
+ await self.telnet_api.async_send_commands(
1729
+ self.telnet_commands.command_panel_lock.format(mode="OFF")
1730
+ )
1731
+ else:
1732
+ await self.api.async_get_command(
1733
+ self.urls.command_panel_lock.format(mode="OFF")
1734
+ )
1735
+
1736
+ async def async_graphic_eq_on(self) -> None:
1737
+ """Turn on Graphic EQ on receiver via HTTP get command."""
1738
+ if self.telnet_available:
1739
+ await self.telnet_api.async_send_commands(
1740
+ self.telnet_commands.command_graphic_eq.format(mode="ON")
1741
+ )
1742
+ else:
1743
+ await self.api.async_get_command(
1744
+ self.urls.command_graphic_eq.format(mode="ON")
1745
+ )
1746
+
1747
+ async def async_graphic_eq_off(self) -> None:
1748
+ """Turn off Graphic EQ on receiver via HTTP get command."""
1749
+ if self.telnet_available:
1750
+ await self.telnet_api.async_send_commands(
1751
+ self.telnet_commands.command_graphic_eq.format(mode="OFF")
1752
+ )
1753
+ else:
1754
+ await self.api.async_get_command(
1755
+ self.urls.command_graphic_eq.format(mode="OFF")
1756
+ )
1757
+
1758
+ async def async_graphic_eq_toggle(self) -> None:
1759
+ """
1760
+ Toggle Graphic EQ on receiver via HTTP get command.
1761
+
1762
+ Only available if using Telnet.
1763
+ """
1764
+ if self._graphic_eq:
1765
+ await self.async_graphic_eq_off()
1766
+ else:
1767
+ await self.async_graphic_eq_on()
1768
+
1769
+ async def async_headphone_eq_on(self) -> None:
1770
+ """Turn on Headphone EQ on receiver via HTTP get command."""
1771
+ if self.telnet_available:
1772
+ await self.telnet_api.async_send_commands(
1773
+ self.telnet_commands.command_headphone_eq.format(mode="ON")
1774
+ )
1775
+ else:
1776
+ await self.api.async_get_command(
1777
+ self.urls.command_headphone_eq.format(mode="ON")
1778
+ )
1779
+
1780
+ async def async_headphone_eq_off(self) -> None:
1781
+ """Turn off Headphone EQ on receiver via HTTP get command."""
1782
+ if self.telnet_available:
1783
+ await self.telnet_api.async_send_commands(
1784
+ self.telnet_commands.command_headphone_eq.format(mode="OFF")
1785
+ )
1786
+ else:
1787
+ await self.api.async_get_command(
1788
+ self.urls.command_headphone_eq.format(mode="OFF")
1789
+ )
1790
+
1791
+ async def async_headphone_eq_toggle(self) -> None:
1792
+ """
1793
+ Toggle Headphone EQ on receiver via HTTP get command.
1794
+
1795
+ Only available if using Telnet.
1796
+ """
1797
+ if self._headphone_eq:
1798
+ await self.async_headphone_eq_off()
1799
+ else:
1800
+ await self.async_headphone_eq_on()
631
1801
 
632
1802
 
633
1803
  @attr.s(auto_attribs=True, on_setattr=DENON_ATTR_SETATTR)
@@ -836,6 +2006,7 @@ def set_api_timeout(
836
2006
  instance._device.api.timeout = value
837
2007
  instance._device.api.read_timeout = max(value, 15.0)
838
2008
  instance._device.telnet_api.timeout = value
2009
+ instance._device.telnet_api._send_confirmation_timeout = value
839
2010
  return value
840
2011
 
841
2012