update miner factory to handle some types of stock fw S9s
This commit is contained in:
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user