diff --git a/.vscode/settings.json b/.vscode/settings.json index dfc0998..cb8749d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,10 +1,11 @@ { - "python.linting.flake8Enabled": true, + "python.formatting.provider": "black", + "editor.formatOnSave": true, "python.linting.enabled": true, "python.testing.pytestArgs": [ "tests" ], - "python.testing.unittestEnabled": false, - "python.testing.nosetestsEnabled": false, - "python.testing.pytestEnabled": true + "python.testing.unittestEnabled": false, + "python.testing.pytestEnabled": true, + "python.linting.flake8Enabled": true } diff --git a/anthemav/protocol.py b/anthemav/protocol.py index b6184e1..b137ec1 100755 --- a/anthemav/protocol.py +++ b/anthemav/protocol.py @@ -170,7 +170,17 @@ COMMANDS_X20 = ["IDN", "ECH", "SIP", "Z1ARC", "FPB"] COMMANDS_X40 = ["PVOL", "WMAC", "EMAC", "IS1ARC", "GCFPB", "GCTXS"] -COMMANDS_MDX_IGNORE = ["IDR"] +COMMANDS_MDX_IGNORE = [ + "IDR", + "Z1IRH", + "Z1IRV", + "Z1AIC", + "Z1BRT", + "Z1AIN", + "Z1DYN", + "Z1DIA", + "Z1ALM", +] COMMANDS_MDX = ["MAC"] EMPTY_MAC = "00:00:00:00:00:00" @@ -222,6 +232,7 @@ def __init__( self._last_command = "" self._deviceinfo_received = asyncio.Event() self._alm_number = {"None": 0} + self._available_input_numbers = [] self.zones: Dict[int, Zone] = {1: Zone(self, 1)} for key in LOOKUP: @@ -276,7 +287,7 @@ async def poweron_refresh(self): return else: await self.refresh_all() - await asyncio.sleep(2) + await asyncio.sleep(5) await self.poweron_refresh() async def refresh_all(self): @@ -291,6 +302,9 @@ async def refresh_all(self): self.log.debug("refresh_all") # refresh main attribues await self.query_commands(LOOKUP) + if self._model_series == "mdx": + # MDX receivers don't returns the list of available input numbers and have a fixed list + self._populate_inputs(12) async def refresh_power(self): """Refresh power of all zones.""" @@ -398,7 +412,11 @@ def _populate_inputs(self, total): if self._model_series == "x40": self.query(f"IS{input_number}IN") else: - self.query(f"ISN{input_number:02d}") + if ( + len(self._available_input_numbers) == 0 + or input_number in self._available_input_numbers + ): + self.query(f"ISN{input_number:02d}") async def _parse_message(self, data: str): """Interpret each message datagram from device and do the needful. @@ -638,10 +656,12 @@ def set_model_command(self, model: str): def set_zones(self, model: str): """Set zones for the appropriate objects.""" number_of_zones: int = 0 - if model == "MDX 16" or model == "MDA 16": + if model == "MDX16" or model == "MDA16": number_of_zones = 8 - elif model == "MDX 8" or model == "MDA 8": + elif model == "MDX8" or model == "MDA8": number_of_zones = 4 + # MDX 16 input number range is 1 to 12, but MDX 8 only have 1 to 4 and 9 + self._available_input_numbers = [1, 2, 3, 4, 9] else: number_of_zones = 2 diff --git a/setup.py b/setup.py index 054127a..144c2f2 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ def readme(): setup( name="anthemav", - version="1.4.0", + version="1.4.0b2", author="David McNett", author_email="nugget@macnugget.org", url="https://github.com/nugget/python-anthemav", diff --git a/tests/test_protocol.py b/tests/test_protocol.py index d1f97ce..7b49a8a 100644 --- a/tests/test_protocol.py +++ b/tests/test_protocol.py @@ -85,23 +85,48 @@ async def test_zone_created_x40(self): async def test_zone_created_MDX8(self): avr = AVR() with patch.object(avr, "query"): - await avr._parse_message("IDMMDX 8") + await avr._parse_message("IDMMDX8") assert len(avr.zones) == 4 async def test_zone_created_MDX16(self): avr = AVR() with patch.object(avr, "query"): - await avr._parse_message("IDMMDX 16") + await avr._parse_message("IDMMDX16") + assert len(avr.zones) == 8 + + async def test_zone_created_MDA16(self): + avr = AVR() + with patch.object(avr, "query"): + await avr._parse_message("IDMMDA16") assert len(avr.zones) == 8 async def test_power_refreshed_MDX16(self): avr = AVR() with patch.object(avr, "query") as mock: - await avr._parse_message("IDMMDX 16") + await avr._parse_message("IDMMDX16") for zone in range(1, 9): mock.assert_any_call(f"Z{zone}POW") assert call("Z9POW") not in mock.mock_calls + async def test_input_name_queried_for_MDX16(self): + avr = AVR() + with patch.object(avr, "query") as mock, patch.object(avr, "transport"): + await avr._parse_message("IDMMDX16") + await avr.refresh_all() + for input_number in range(1, 13): + mock.assert_any_call(f"ISN{input_number:02d}") + + async def test_input_name_queried_for_MDX8(self): + avr = AVR() + with patch.object(avr, "query") as mock, patch.object(avr, "transport"): + await avr._parse_message("IDMMDX8") + await avr.refresh_all() + for input_number in range(1, 13): + if input_number in [1, 2, 3, 4, 9]: + mock.assert_any_call(f"ISN{input_number:02d}") + else: + assert call(f"ISN{input_number:02d}") not in mock.mock_calls + async def test_pvol_x40(self): avr = AVR() with patch.object(avr, "query"):