191191EMPTY_MAC = "00:00:00:00:00:00"
192192UNKNOWN_MODEL = "Unknown Model"
193193
194+ MODEL_X40 = "x40"
195+ MODEL_X20 = "x20"
196+ MODEL_MDX = "mdx"
197+
194198
195199# pylint: disable=too-many-instance-attributes, too-many-public-methods
196200class AVR (asyncio .Protocol ):
@@ -307,7 +311,7 @@ async def refresh_all(self):
307311 self .log .debug ("refresh_all" )
308312 # refresh main attribues
309313 await self .query_commands (LOOKUP )
310- if self ._model_series == "mdx" :
314+ if self ._model_series == MODEL_MDX :
311315 # MDX receivers don't returns the list of available input numbers and have a fixed list
312316 self ._populate_inputs (12 )
313317
@@ -414,7 +418,7 @@ def _populate_inputs(self, total):
414418 """
415419 total = total + 1
416420 for input_number in range (1 , total ):
417- if self ._model_series == "x40" :
421+ if self ._model_series == MODEL_X40 :
418422 self .query (f"IS{ input_number } IN" )
419423 else :
420424 if (
@@ -640,30 +644,30 @@ def set_model_command(self, model: str):
640644 if "40" in model or "70" in model or "90" in model :
641645 self .log .debug ("Set Command to Model x40" )
642646 self ._ignored_commands = COMMANDS_X20 + COMMANDS_MDX
643- self ._model_series = "x40"
647+ self ._model_series = MODEL_X40
644648 self .query ("GCTXS" )
645649 self .query ("EMAC" )
646650 self .query ("WMAC" )
647651 self ._alm_number = ALM_NUMBER_x40
648652 elif "MDX" in model or "MDA" in model :
649653 self .log .debug ("Set Command to Model MDX" )
650654 self ._ignored_commands = COMMANDS_X20 + COMMANDS_X40 + COMMANDS_MDX_IGNORE
651- self ._model_series = "mdx"
655+ self ._model_series = MODEL_MDX
652656 self .query ("MAC" )
653657 else :
654658 self .log .debug ("Set Command to Model x20" )
655659 self ._ignored_commands = COMMANDS_X40 + COMMANDS_MDX
656- self ._model_series = "x20"
660+ self ._model_series = MODEL_X20
657661 self ._alm_number = ALM_NUMBER_x20
658662 self .command ("ECH1" )
659663 self .query ("IDN" )
660664
661665 def set_zones (self , model : str ):
662666 """Set zones for the appropriate objects."""
663667 number_of_zones : int = 0
664- if model == "MDX16" or model == "MDA16" :
668+ if self . _model_series == MODEL_MDX and "16" in model :
665669 number_of_zones = 8
666- elif model == "MDX8" or model == "MDA8" :
670+ elif self . _model_series == MODEL_MDX and "8" in model :
667671 number_of_zones = 4
668672 # MDX 16 input number range is 1 to 12, but MDX 8 only have 1 to 4 and 9
669673 self ._available_input_numbers = [1 , 2 , 3 , 4 , 9 ]
@@ -862,15 +866,6 @@ def arc(self):
862866 def arc (self , value ):
863867 self ._set_boolean ("Z1ARC" , value )
864868
865- @property
866- def mute (self ):
867- """Mute on or off (read/write)."""
868- return self .zones [1 ].mute
869-
870- @mute .setter
871- def mute (self , value ):
872- self .zones [1 ].mute = value
873-
874869 #
875870 # Read-only text properties
876871 #
@@ -1123,26 +1118,6 @@ def input_list(self):
11231118 """List of all enabled inputs."""
11241119 return list (self ._input_numbers .keys ())
11251120
1126- @property
1127- def input_name (self ):
1128- """Name of currently active input (read-write)."""
1129- return self ._input_names .get (self .input_number , "Unknown" )
1130-
1131- @input_name .setter
1132- def input_name (self , value ):
1133- number = self ._input_numbers .get (value , 0 )
1134- if number > 0 :
1135- self .input_number = number
1136-
1137- @property
1138- def input_number (self ):
1139- """Number of currently active input (read-write)."""
1140- return self .zones [1 ].input_number
1141-
1142- @input_number .setter
1143- def input_number (self , number ):
1144- self .zones [1 ].input_number = number
1145-
11461121 #
11471122 # Miscellany
11481123 #
@@ -1175,15 +1150,15 @@ def command(self, command: str) -> None:
11751150 def query (self , command : str ) -> None :
11761151 self ._avr .query (f"Z{ self ._zone } { command } " )
11771152
1178- def _get_integer (self , key , default : int = 0 ):
1153+ def _get_integer (self , key , default : int = 0 ) -> int :
11791154 if key not in self .values :
11801155 return default
11811156 try :
11821157 return int (self .values [key ])
11831158 except ValueError :
11841159 return 0
11851160
1186- def _get_boolean (self , key ):
1161+ def _get_boolean (self , key ) -> bool :
11871162 if key not in self .values :
11881163 return False
11891164 try :
@@ -1193,12 +1168,27 @@ def _get_boolean(self, key):
11931168 except AttributeError :
11941169 return False
11951170
1196- def _set_boolean (self , key , value ):
1171+ def _set_boolean (self , key : str , value : bool ):
11971172 if value is True :
11981173 self .command (key + "1" )
11991174 else :
12001175 self .command (key + "0" )
12011176
1177+ @property
1178+ def support_audio_listening_mode (self ) -> bool :
1179+ """Return true if the zone support audio listening mode."""
1180+ return self ._zone == 1 and self ._avr ._model_series != MODEL_MDX
1181+
1182+ @property
1183+ def support_attenuation (self ) -> bool :
1184+ """Return true if the zone support sound mode and sound mode list."""
1185+ return self ._avr ._model_series == MODEL_X20
1186+
1187+ @property
1188+ def support_profile (self ) -> bool :
1189+ """Return true if the zone support sound mode and sound mode list."""
1190+ return self ._zone == 1 and self ._avr ._model_series != MODEL_MDX
1191+
12021192 #
12031193 # Volume and Attenuation handlers. The Anthem tracks volume internally as
12041194 # an attenuation level ranging from -90dB (silent) to 0dB (bleeding ears)
@@ -1211,7 +1201,7 @@ def _set_boolean(self, key, value):
12111201 # - volume_as_percentage (0-1 floating point)
12121202 #
12131203
1214- def attenuation_to_volume (self , value ) :
1204+ def attenuation_to_volume (self , value : int ) -> int :
12151205 """Convert a native attenuation value to a volume value.
12161206
12171207 Takes an attenuation in dB from the Anthem (-90 to 0) and converts it
@@ -1227,7 +1217,7 @@ def attenuation_to_volume(self, value):
12271217 except ValueError :
12281218 return 0
12291219
1230- def volume_to_attenuation (self , value ):
1220+ def volume_to_attenuation (self , value : int ):
12311221 """Convert a volume value to a native attenuation value.
12321222
12331223 Takes a volume value and turns it into an attenuation value suitable
@@ -1244,20 +1234,20 @@ def volume_to_attenuation(self, value):
12441234 return - 90
12451235
12461236 @property
1247- def power (self ):
1237+ def power (self ) -> bool :
12481238 """Report if device powered on or off (read/write).
12491239
12501240 Returns and expects a boolean value.
12511241 """
12521242 return self ._get_boolean ("POW" )
12531243
12541244 @power .setter
1255- def power (self , value ):
1245+ def power (self , value : bool ):
12561246 self ._set_boolean ("POW" , value )
12571247 self .query ("POW" )
12581248
12591249 @property
1260- def volume (self ):
1250+ def volume (self ) -> int :
12611251 """Current volume level (read/write).
12621252
12631253 You can get or set the current volume value on the device with this
@@ -1268,25 +1258,25 @@ def volume(self):
12681258 >>> volvalue = volume
12691259 >>> volume = 20
12701260 """
1271- if self ._avr ._model_series == "x40" and "PVOL" in self .values :
1261+ if self ._avr ._model_series == MODEL_X40 and "PVOL" in self .values :
12721262 return self ._get_integer ("PVOL" )
1273- elif self ._avr ._model_series == "mdx" :
1263+ elif self ._avr ._model_series == MODEL_MDX :
12741264 return self ._get_integer ("VOL" )
12751265 else :
12761266 return self .attenuation_to_volume (self .attenuation )
12771267
12781268 @volume .setter
1279- def volume (self , value ):
1280- if isinstance ( value , int ) and 0 <= value <= 100 :
1281- if self ._avr ._model_series == "x40" :
1269+ def volume (self , value : int ):
1270+ if 0 <= value <= 100 :
1271+ if self ._avr ._model_series == MODEL_X40 :
12821272 self .command (f"PVOL{ value } " )
1283- elif self ._avr ._model_series == "mdx" :
1273+ elif self ._avr ._model_series == MODEL_MDX :
12841274 self .command (f"VOL{ value } " )
12851275 else :
12861276 self .attenuation = self .volume_to_attenuation (value )
12871277
12881278 @property
1289- def volume_as_percentage (self ):
1279+ def volume_as_percentage (self ) -> float :
12901280 """Current volume as percentage (read/write).
12911281
12921282 You can get or set the current volume value as a percentage. Valid
@@ -1301,14 +1291,13 @@ def volume_as_percentage(self):
13011291 return volume_per
13021292
13031293 @volume_as_percentage .setter
1304- def volume_as_percentage (self , value ):
1305- if isinstance (value , float ) or isinstance (value , int ):
1306- if 0 <= value <= 1 :
1307- value = round (value * 100 )
1308- self .volume = value
1294+ def volume_as_percentage (self , value : float ):
1295+ if 0 <= value <= 1 :
1296+ value = round (value * 100 )
1297+ self .volume = value
13091298
13101299 @property
1311- def attenuation (self ):
1300+ def attenuation (self ) -> int :
13121301 """Current volume attenuation in dB (read/write).
13131302
13141303 You can get or set the current attenuation value on the device with this
@@ -1322,54 +1311,51 @@ def attenuation(self):
13221311 return self ._get_integer ("VOL" , - 90 )
13231312
13241313 @attenuation .setter
1325- def attenuation (self , value ):
1326- if isinstance ( value , int ) and - 90 <= value <= 0 :
1314+ def attenuation (self , value : int ):
1315+ if - 90 <= value <= 0 :
13271316 self ._avr .log .debug ("Setting attenuation to %s" , str (value ))
13281317 self .command (f"VOL{ value } " )
13291318
13301319 @property
1331- def mute (self ):
1320+ def mute (self ) -> bool :
13321321 """Mute on or off (read/write)."""
13331322 return self ._get_boolean ("MUT" )
13341323
13351324 @mute .setter
1336- def mute (self , value ):
1325+ def mute (self , value : bool ):
13371326 self ._set_boolean ("MUT" , value )
13381327 # Query mute because the AVR doesn't always return back the state
13391328 # (eg: after power on without changing the volume first)
13401329 self .query ("MUT" )
13411330
13421331 @property
1343- def input_number (self ):
1332+ def input_number (self ) -> int :
13441333 """Number of currently active input (read-write)."""
13451334 return self ._get_integer ("INP" )
13461335
13471336 @input_number .setter
1348- def input_number (self , number ):
1349- if isinstance (number , int ):
1350- if 1 <= number <= 99 :
1351- self ._avr .log .debug (
1352- f"Switching input to { number } for zone { self ._zone } "
1353- )
1354- self .command (f"INP{ number } " )
1355- # Query to make sure it actually changes
1356- self .query ("INP" )
1337+ def input_number (self , number : int ):
1338+ if 1 <= number <= 99 :
1339+ self ._avr .log .debug (f"Switching input to { number } for zone { self ._zone } " )
1340+ self .command (f"INP{ number } " )
1341+ # Query to make sure it actually changes
1342+ self .query ("INP" )
13571343
13581344 @property
1359- def input_name (self ):
1345+ def input_name (self ) -> str :
13601346 """Name of currently active input (read-write)."""
13611347 return self ._avr ._input_names .get (self .input_number , "Unknown" )
13621348
13631349 @input_name .setter
1364- def input_name (self , value ):
1350+ def input_name (self , value : str ):
13651351 number = self ._avr ._input_numbers .get (value , 0 )
13661352 if number > 0 :
13671353 self .input_number = number
13681354
13691355 @property
1370- def input_format (self ):
1356+ def input_format (self ) -> str :
13711357 """Input video and audio format for the current zone if available (usually only zone 1)"""
1372- if self ._zone == 1 and self ._avr ._model_series != "mdx" :
1358+ if self ._zone == 1 and self ._avr ._model_series != MODEL_MDX :
13731359 return (
13741360 f"{ self ._avr .video_input_resolution_text } { self ._avr .audio_input_name } "
13751361 )
0 commit comments