diff --git a/miners/__init__.py b/miners/__init__.py index fe182a33..69eb8a39 100644 --- a/miners/__init__.py +++ b/miners/__init__.py @@ -1,5 +1,6 @@ import asyncssh import logging +import ipaddress class BaseMiner: @@ -18,6 +19,15 @@ class BaseMiner: def __repr__(self): return f"{'' if not self.api_type else self.api_type} {'' if not self.model else self.model}: {str(self.ip)}" + def __lt__(self, other): + return ipaddress.ip_address(self.ip) < ipaddress.ip_address(other.ip) + + def __gt__(self, other): + return ipaddress.ip_address(self.ip) > ipaddress.ip_address(other.ip) + + def __eq__(self, other): + return ipaddress.ip_address(self.ip) == ipaddress.ip_address(other.ip) + async def _get_ssh_connection(self) -> asyncssh.connect: """Create a new asyncssh connection""" try: diff --git a/miners/_backends/bmminer.py b/miners/_backends/bmminer.py index 2bf1fc50..109a80ea 100644 --- a/miners/_backends/bmminer.py +++ b/miners/_backends/bmminer.py @@ -2,12 +2,13 @@ from API.bmminer import BMMinerAPI from miners import BaseMiner import logging from settings import MINER_FACTORY_GET_VERSION_RETRIES as DATA_RETRIES +import ipaddress class BMMiner(BaseMiner): def __init__(self, ip: str) -> None: super().__init__(ip) - self.ip = ip + self.ip = ipaddress.ip_address(ip) self.api = BMMinerAPI(ip) self.api_type = "BMMiner" self.uname = "root" diff --git a/miners/_backends/bosminer.py b/miners/_backends/bosminer.py index ded08787..c0e0f6f4 100644 --- a/miners/_backends/bosminer.py +++ b/miners/_backends/bosminer.py @@ -1,3 +1,5 @@ +import ipaddress + from miners import BaseMiner from API.bosminer import BOSMinerAPI import toml @@ -9,7 +11,7 @@ from settings import MINER_FACTORY_GET_VERSION_RETRIES as DATA_RETRIES class BOSMiner(BaseMiner): def __init__(self, ip: str) -> None: super().__init__(ip) - self.ip = ip + self.ip = ipaddress.ip_address(ip) self.api = BOSMinerAPI(ip) self.api_type = "BOSMiner" self.uname = "root" diff --git a/miners/_backends/btminer.py b/miners/_backends/btminer.py index 936fb856..573b0ae1 100644 --- a/miners/_backends/btminer.py +++ b/miners/_backends/btminer.py @@ -3,12 +3,13 @@ from miners import BaseMiner from API import APIError import logging from settings import MINER_FACTORY_GET_VERSION_RETRIES as DATA_RETRIES +import ipaddress class BTMiner(BaseMiner): def __init__(self, ip: str) -> None: super().__init__(ip) - self.ip = ip + self.ip = ipaddress.ip_address(ip) self.api = BTMinerAPI(ip) self.api_type = "BTMiner" diff --git a/miners/_backends/cgminer.py b/miners/_backends/cgminer.py index 6186645b..8856175e 100644 --- a/miners/_backends/cgminer.py +++ b/miners/_backends/cgminer.py @@ -3,12 +3,13 @@ from API.cgminer import CGMinerAPI from API import APIError from settings import MINER_FACTORY_GET_VERSION_RETRIES as DATA_RETRIES import logging +import ipaddress class CGMiner(BaseMiner): def __init__(self, ip: str) -> None: super().__init__(ip) - self.ip = ip + self.ip = ipaddress.ip_address(ip) self.api = CGMinerAPI(ip) self.api_type = "CGMiner" self.uname = "root" diff --git a/miners/_backends/hiveon.py b/miners/_backends/hiveon.py index 6c98d214..bfeb8b85 100644 --- a/miners/_backends/hiveon.py +++ b/miners/_backends/hiveon.py @@ -1,10 +1,11 @@ from miners._backends import BMMiner +import ipaddress class Hiveon(BMMiner): def __init__(self, ip: str) -> None: super().__init__(ip) - self.ip = ip + self.ip = ipaddress.ip_address(ip) self.api_type = "Hiveon" self.uname = "root" self.pwd = "admin" diff --git a/network/__init__.py b/network/__init__.py index 95a86579..64a88260 100644 --- a/network/__init__.py +++ b/network/__init__.py @@ -66,7 +66,7 @@ class MinerNetwork: # create a list of tasks and miner IPs scan_tasks = [] - miner_ips = [] + miners = [] # for each IP in the network for host in local_network.hosts(): @@ -74,32 +74,21 @@ class MinerNetwork: # make sure we don't exceed the allowed async tasks if len(scan_tasks) < SCAN_THREADS: # add the task to the list - scan_tasks.append(self.ping_miner(host)) + scan_tasks.append(self.ping_and_get_miner(host)) else: # run the scan tasks - miner_ips_scan = await asyncio.gather(*scan_tasks) + miners_scan = await asyncio.gather(*scan_tasks) # add scanned miners to the list of found miners - miner_ips.extend(miner_ips_scan) + miners.extend(miners_scan) # empty the task list scan_tasks = [] # do a final scan to empty out the list - miner_ips_scan = await asyncio.gather(*scan_tasks) - miner_ips.extend(miner_ips_scan) + miners_scan = await asyncio.gather(*scan_tasks) + miners.extend(miners_scan) # remove all None from the miner list - miner_ips = list(filter(None, miner_ips)) - print(f"Found {len(miner_ips)} connected miners...") - - # create a list of tasks to get miners - create_miners_tasks = [] - - # try to get each miner found - for miner_ip in miner_ips: - # append to the list of tasks - create_miners_tasks.append(MinerFactory().get_miner(miner_ip)) - - # get all miners in the list - miners = await asyncio.gather(*create_miners_tasks) + miners = list(filter(None, miners)) + print(f"Found {len(miners)} connected miners...") # return the miner objects return miners diff --git a/tools/cfg_util/scan/__init__.py b/tools/cfg_util/scan/__init__.py index 52d677cb..f040fdd3 100644 --- a/tools/cfg_util/scan/__init__.py +++ b/tools/cfg_util/scan/__init__.py @@ -36,52 +36,54 @@ async def btn_scan(scan_ip: str): @disable_buttons("Scanning") async def _scan_miners(network: MinerNetwork): + """Scan the given network for miners, get data, and fill in the table.""" + # clear the tables on the config tool to prepare for new miners clear_tables() - scan_generator = network.scan_network_generator() + + # clear miner factory cache to make sure we are getting correct miners MinerFactory().clear_cached_miners() + # create async generator to scan network for miners + scan_generator = network.scan_network_generator() + + # set progress bar length to 2x network size and reset it to 0 global progress_bar_len progress_bar_len = 0 - network_size = len(network) - await update_prog_bar(progress_bar_len, _max=(3 * network_size)) + await update_prog_bar(progress_bar_len, _max=(2 * network_size)) - scanned_miners = [] + # asynchronously get each miner scanned by the generator + miners = [] async for miner in scan_generator: + # if the generator yields a miner, add it to our list if miner: - scanned_miners.append(miner) + miners.append(miner) + + # sort the list of miners by IP + miners.sort() + + _data = {} + for key in DEFAULT_DATA: + _data[key] = "" + _data["IP"] = str(miner.ip) + TableManager().update_item(_data) + + asyncio.create_task(_get_miner_data(miner)) + progress_bar_len += 1 await update_prog_bar(progress_bar_len) - progress_bar_len += network_size - len(scanned_miners) + progress_bar_len += network_size - len(miners) await update_prog_bar(progress_bar_len) - get_miner_genenerator = MinerFactory().get_miner_generator(scanned_miners) - resolved_miners = [] - async for found_miner in get_miner_genenerator: - resolved_miners.append(found_miner) - resolved_miners.sort(key=lambda x: x.ip) - _data = {} - for key in DEFAULT_DATA: - _data[key] = "" - _data["IP"] = str(found_miner.ip) - TableManager().update_item(_data) - progress_bar_len += 1 - await update_prog_bar(progress_bar_len) - progress_bar_len += network_size - len(resolved_miners) - await update_prog_bar(progress_bar_len) - await _get_miners_data(resolved_miners) - - -async def _get_miners_data(miners: list): +async def _get_miner_data(miner): global progress_bar_len - data_generator = asyncio.as_completed([_get_data(miner) for miner in miners]) - for all_data in data_generator: - data = await all_data - TableManager().update_item(data) - progress_bar_len += 1 - await update_prog_bar(progress_bar_len) + + TableManager().update_item(await _get_data(miner)) + + progress_bar_len += 1 + await update_prog_bar(progress_bar_len) async def _get_data(miner):