update miner factory to handle some types of stock fw S9s

This commit is contained in:
UpstreamData
2022-07-19 11:18:55 -06:00
parent f8590b0c5f
commit e65cb0573d

View File

@@ -1,6 +1,7 @@
from typing import TypeVar, Tuple, List, Union from typing import TypeVar, Tuple, List, Union
from collections.abc import AsyncIterable from collections.abc import AsyncIterable
from pyasic.miners import BaseMiner from pyasic.miners import BaseMiner
import httpx
from pyasic.miners.antminer import * from pyasic.miners.antminer import *
from pyasic.miners.avalonminer import * from pyasic.miners.avalonminer import *
@@ -252,7 +253,6 @@ class MinerFactory(metaclass=Singleton):
# create a list of tasks # create a list of tasks
scan_tasks = [] scan_tasks = []
# for each miner IP that was passed in, add a task to get its class # for each miner IP that was passed in, add a task to get its class
logging.debug(f"Getting miners with generator: [{ips}]")
for miner in ips: for miner in ips:
scan_tasks.append(loop.create_task(self.get_miner(miner))) scan_tasks.append(loop.create_task(self.get_miner(miner)))
# asynchronously run the tasks and return them as they complete # asynchronously run the tasks and return them as they complete
@@ -274,7 +274,6 @@ class MinerFactory(metaclass=Singleton):
ip = ipaddress.ip_address(ip) ip = ipaddress.ip_address(ip)
# check if the miner already exists in cache # check if the miner already exists in cache
if ip in self.miners: if ip in self.miners:
logging.debug(f"Miner exists in cache: {self.miners[ip]}")
return self.miners[ip] return self.miners[ip]
# if everything fails, the miner is already set to unknown # if everything fails, the miner is already set to unknown
miner = UnknownMiner(str(ip)) miner = UnknownMiner(str(ip))
@@ -298,9 +297,6 @@ class MinerFactory(metaclass=Singleton):
ver = new_ver ver = new_ver
# if we find the API and model, don't need to loop anymore # if we find the API and model, don't need to loop anymore
if api and model: if api and model:
logging.debug(
f"Miner api and model found: API - {api}, Model - {model}"
)
break break
except asyncio.TimeoutError: except asyncio.TimeoutError:
logging.warning(f"{ip}: Get Miner Timed Out") logging.warning(f"{ip}: Get Miner Timed Out")
@@ -344,13 +340,11 @@ class MinerFactory(metaclass=Singleton):
self.miners[ip] = miner self.miners[ip] = miner
# return the miner # return the miner
logging.debug(f"Found miner: {miner}")
return miner return miner
def clear_cached_miners(self) -> None: def clear_cached_miners(self) -> None:
"""Clear the miner factory cache.""" """Clear the miner factory cache."""
# empty out self.miners # empty out self.miners
logging.debug("Clearing MinerFactory cache.")
self.miners = {} self.miners = {}
async def _get_miner_type( async def _get_miner_type(
@@ -376,16 +370,12 @@ class MinerFactory(metaclass=Singleton):
version = data["version"][0] version = data["version"][0]
except APIError: except APIError:
logging.debug(f"API Error when getting miner type: {str(ip)}")
try: try:
# try devdetails and version separately (X19s mainly require this) # try devdetails and version separately (X19s mainly require this)
# get devdetails and validate # get devdetails and validate
devdetails = await self._send_api_command(str(ip), "devdetails") devdetails = await self._send_api_command(str(ip), "devdetails")
validation = await self._validate_command(devdetails) validation = await self._validate_command(devdetails)
if not validation[0]: if not validation[0]:
logging.debug(
f"Splitting commands failed when getting miner type: {str(ip)}"
)
# if devdetails fails try version instead # if devdetails fails try version instead
devdetails = None devdetails = None
@@ -399,15 +389,12 @@ class MinerFactory(metaclass=Singleton):
# if this fails we raise an error to be caught below # if this fails we raise an error to be caught below
if not validation[0]: if not validation[0]:
logging.debug(
f"get_version failed when getting miner type: {str(ip)}"
)
raise APIError(validation[1]) raise APIError(validation[1])
except APIError as e: except APIError as e:
# catch APIError and let the factory know we cant get data # catch APIError and let the factory know we cant get data
logging.warning(f"{ip}: API Command Error: {e.__name__} - {e}") logging.warning(f"{ip}: API Command Error: {e}")
return None, None, None return None, None, None
except OSError: except OSError as e:
# miner refused connection on API port, we wont be able to get data this way # miner refused connection on API port, we wont be able to get data this way
# try ssh # try ssh
try: try:
@@ -432,6 +419,18 @@ class MinerFactory(metaclass=Singleton):
return model, api, None return model, api, None
except asyncssh.misc.PermissionDenied: except asyncssh.misc.PermissionDenied:
try:
url = f"http://{self.ip}/cgi-bin/get_system_info.cgi"
auth = httpx.DigestAuth("root", "root")
async with httpx.AsyncClient() as client:
data = await client.get(url, auth=auth)
if data.status_code == 200:
data = data.json()
if "minertype" in data.keys():
model = data["minertype"]
if "bmminer" in "\t".join(data.keys()):
api = "BMMiner"
except:
return None, None, None return None, None, None
# if we have devdetails, we can get model data from there # if we have devdetails, we can get model data from there