diff --git a/setup.py b/setup.py index 759b61e..8099c9f 100644 --- a/setup.py +++ b/setup.py @@ -18,6 +18,7 @@ "aiohttp>=3.5.4, <4", "async_timeout>=4.0.2", "voluptuous>=0.11.5", + "mypy_extensions", ], setup_requires=[ "setuptools_scm", diff --git a/solax/discovery.py b/solax/discovery.py index c595513..78429d3 100644 --- a/solax/discovery.py +++ b/solax/discovery.py @@ -1,3 +1,4 @@ +import asyncio from typing import Type from solax.http_client import all_variations @@ -26,18 +27,13 @@ class DiscoveryError(Exception): async def discover(host, port, pwd="") -> Inverter: failures: list = [] clients = all_variations(host, port, pwd) - for client_name, client in clients.items(): - try: - response = await client.request() - except InverterError as ex: - failures.append( - ( - client_name, - ex, - ) - ) - continue + pending = [] + + async def identify_inverter(sleep, client_name, client): + await asyncio.sleep(sleep) # don't spam the inverter + response = await client.request() for inverter_class in REGISTRY: + await asyncio.sleep(0) try: inverter = inverter_class(client) if inverter.identify(response): @@ -58,6 +54,32 @@ async def discover(host, port, pwd="") -> Inverter: ex, ) ) + + for sleep, (name, client) in enumerate(clients.items()): + pending.append(asyncio.create_task( + identify_inverter(sleep, name, client), + name=name, + )) + + while pending: + done, pending = await asyncio.wait(pending, return_when=asyncio.FIRST_COMPLETED) + + for task in done: + if task.cancelled(): + continue + + try: + return await task + except Exception as ex: + failures.append( + ( + task.get_name(), + ex, + ) + ) + + + msg = ( "Unable to connect to the inverter at " f"host={host} port={port}, or your inverter is not supported yet.\n"