reformatted all files to use the Black formatting style
This commit is contained in:
@@ -9,7 +9,11 @@ import logging
|
||||
|
||||
|
||||
class BaseMiner:
|
||||
def __init__(self, ip: str, api: BMMinerAPI or BOSMinerAPI or CGMinerAPI or BTMinerAPI or UnknownAPI) -> None:
|
||||
def __init__(
|
||||
self,
|
||||
ip: str,
|
||||
api: BMMinerAPI or BOSMinerAPI or CGMinerAPI or BTMinerAPI or UnknownAPI,
|
||||
) -> None:
|
||||
self.ip = ipaddress.ip_address(ip)
|
||||
self.uname = None
|
||||
self.pwd = None
|
||||
@@ -20,19 +24,23 @@ class BaseMiner:
|
||||
async def _get_ssh_connection(self) -> asyncssh.connect:
|
||||
"""Create a new asyncssh connection"""
|
||||
try:
|
||||
conn = await asyncssh.connect(str(self.ip),
|
||||
known_hosts=None,
|
||||
username=self.uname,
|
||||
password=self.pwd,
|
||||
server_host_key_algs=['ssh-rsa'])
|
||||
conn = await asyncssh.connect(
|
||||
str(self.ip),
|
||||
known_hosts=None,
|
||||
username=self.uname,
|
||||
password=self.pwd,
|
||||
server_host_key_algs=["ssh-rsa"],
|
||||
)
|
||||
return conn
|
||||
except asyncssh.misc.PermissionDenied:
|
||||
try:
|
||||
conn = await asyncssh.connect(str(self.ip),
|
||||
known_hosts=None,
|
||||
username="admin",
|
||||
password="admin",
|
||||
server_host_key_algs=['ssh-rsa'])
|
||||
conn = await asyncssh.connect(
|
||||
str(self.ip),
|
||||
known_hosts=None,
|
||||
username="admin",
|
||||
password="admin",
|
||||
server_host_key_algs=["ssh-rsa"],
|
||||
)
|
||||
return conn
|
||||
except Exception as e:
|
||||
logging.warning(f"{self} raised an exception: {e}")
|
||||
|
||||
@@ -24,7 +24,7 @@ class BOSMinerS9(BOSMiner):
|
||||
logging.debug(f"{self}: Opening SFTP connection.")
|
||||
async with conn.start_sftp_client() as sftp:
|
||||
logging.debug(f"{self}: Opening config file.")
|
||||
async with sftp.open('/etc/bosminer.toml', 'w+') as file:
|
||||
async with sftp.open("/etc/bosminer.toml", "w+") as file:
|
||||
await file.write(toml_conf)
|
||||
logging.debug(f"{self}: Restarting BOSMiner")
|
||||
await conn.run("/etc/init.d/bosminer restart")
|
||||
|
||||
@@ -13,7 +13,7 @@ class HiveonT9(BMMiner):
|
||||
async def get_board_info(self) -> dict:
|
||||
"""Gets data on each board and chain in the miner."""
|
||||
board_stats = await self.api.stats()
|
||||
stats = board_stats['STATS'][1]
|
||||
stats = board_stats["STATS"][1]
|
||||
boards = {}
|
||||
board_chains = {0: [2, 9, 10], 1: [3, 11, 12], 2: [4, 13, 14]}
|
||||
for idx, board in enumerate(board_chains):
|
||||
@@ -25,12 +25,14 @@ class HiveonT9(BMMiner):
|
||||
nominal = False
|
||||
else:
|
||||
nominal = True
|
||||
boards[board].append({
|
||||
"chain": chain,
|
||||
"chip_count": count,
|
||||
"chip_status": chips,
|
||||
"nominal": nominal
|
||||
})
|
||||
boards[board].append(
|
||||
{
|
||||
"chain": chain,
|
||||
"chip_count": count,
|
||||
"chip_status": chips,
|
||||
"nominal": nominal,
|
||||
}
|
||||
)
|
||||
return boards
|
||||
|
||||
async def get_bad_boards(self) -> dict:
|
||||
@@ -43,4 +45,4 @@ class HiveonT9(BMMiner):
|
||||
if board not in bad_boards.keys():
|
||||
bad_boards[board] = []
|
||||
bad_boards[board].append(chain)
|
||||
return bad_boards
|
||||
return bad_boards
|
||||
|
||||
@@ -7,155 +7,157 @@ class CGMinerAvalon8(CGMiner):
|
||||
super().__init__(ip)
|
||||
self.model = "Avalon 8"
|
||||
self.api_type = "CGMiner"
|
||||
self.pattern = re.compile(r'Ver\[(?P<Ver>[-0-9A-Fa-f+]+)\]\s'
|
||||
'DNA\[(?P<DNA>[0-9A-Fa-f]+)\]\s'
|
||||
'Elapsed\[(?P<Elapsed>[-0-9]+)\]\s'
|
||||
'MW\[(?P<MW>[-\s0-9]+)\]\s'
|
||||
'LW\[(?P<LW>[-0-9]+)\]\s'
|
||||
'MH\[(?P<MH>[-\s0-9]+)\]\s'
|
||||
'HW\[(?P<HW>[-0-9]+)\]\s'
|
||||
'Temp\[(?P<Temp>[0-9]+)\]\s'
|
||||
'TMax\[(?P<TMax>[0-9]+)\]\s'
|
||||
'Fan\[(?P<Fan>[0-9]+)\]\s'
|
||||
'FanR\[(?P<FanR>[0-9]+)%\]\s'
|
||||
'Vi\[(?P<Vi>[-\s0-9]+)\]\s'
|
||||
'Vo\[(?P<Vo>[-\s0-9]+)\]\s'
|
||||
'('
|
||||
'PLL0\[(?P<PLL0>[-\s0-9]+)\]\s'
|
||||
'PLL1\[(?P<PLL1>[-\s0-9]+)\]\s'
|
||||
'PLL2\[(?P<PLL2>[-\s0-9]+)\]\s'
|
||||
'PLL3\[(?P<PLL3>[-\s0-9]+)\]\s'
|
||||
')?'
|
||||
'GHSmm\[(?P<GHSmm>[-.0-9]+)\]\s'
|
||||
'WU\[(?P<WU>[-.0-9]+)\]\s'
|
||||
'Freq\[(?P<Freq>[.0-9]+)\]\s'
|
||||
'PG\[(?P<PG>[0-9]+)\]\s'
|
||||
'Led\[(?P<LED>0|1)\]\s'
|
||||
'MW0\[(?P<MW0>[0-9\s]+)\]\s'
|
||||
'MW1\[(?P<MW1>[0-9\s]+)\]\s'
|
||||
'MW2\[(?P<MW2>[0-9\s]+)\]\s'
|
||||
'MW3\[(?P<MW3>[0-9\s]+)\]\s'
|
||||
'TA\[(?P<TA>[0-9]+)\]\s'
|
||||
'ECHU\[(?P<ECHU>[0-9\s]+)\]\s'
|
||||
'ECMM\[(?P<ECMM>[0-9]+)\]\s.*'
|
||||
'FAC0\[(?P<FAC0>[-0-9]+)\]\s'
|
||||
'OC\[(?P<OC>[0-9]+)\]\s'
|
||||
'SF0\[(?P<SF0>[-\s0-9]+)\]\s'
|
||||
'SF1\[(?P<SF1>[-\s0-9]+)\]\s'
|
||||
'SF2\[(?P<SF2>[-\s0-9]+)\]\s'
|
||||
'SF3\[(?P<SF3>[-\s0-9]+)\]\s'
|
||||
'PMUV\[(?P<PMUV>[-\s\S*]+)\]\s'
|
||||
'PVT_T0\[(?P<PVT_T0>[-0-9\s]+)\]\s'
|
||||
'PVT_T1\[(?P<PVT_T1>[-0-9\s]+)\]\s'
|
||||
'PVT_T2\[(?P<PVT_T2>[-0-9\s]+)\]\s'
|
||||
'PVT_T3\[(?P<PVT_T3>[-0-9\s]+)\]\s'
|
||||
'PVT_V0_0\[(?P<PVT_V0_0>[-0-9\s]+)\]\s'
|
||||
'PVT_V0_1\[(?P<PVT_V0_1>[-0-9\s]+)\]\s'
|
||||
'PVT_V0_2\[(?P<PVT_V0_2>[-0-9\s]+)\]\s'
|
||||
'PVT_V0_3\[(?P<PVT_V0_3>[-0-9\s]+)\]\s'
|
||||
'PVT_V0_4\[(?P<PVT_V0_4>[-0-9\s]+)\]\s'
|
||||
'PVT_V0_5\[(?P<PVT_V0_5>[-0-9\s]+)\]\s'
|
||||
'PVT_V0_6\[(?P<PVT_V0_6>[-0-9\s]+)\]\s'
|
||||
'PVT_V0_7\[(?P<PVT_V0_7>[-0-9\s]+)\]\s'
|
||||
'PVT_V0_8\[(?P<PVT_V0_8>[-0-9\s]+)\]\s'
|
||||
'PVT_V0_9\[(?P<PVT_V0_9>[-0-9\s]+)\]\s'
|
||||
'PVT_V0_10\[(?P<PVT_V0_10>[-0-9\s]+)\]\s'
|
||||
'PVT_V0_11\[(?P<PVT_V0_11>[-0-9\s]+)\]\s'
|
||||
'PVT_V0_12\[(?P<PVT_V0_12>[-0-9\s]+)\]\s'
|
||||
'PVT_V0_13\[(?P<PVT_V0_13>[-0-9\s]+)\]\s'
|
||||
'PVT_V0_14\[(?P<PVT_V0_14>[-0-9\s]+)\]\s'
|
||||
'PVT_V0_15\[(?P<PVT_V0_15>[-0-9\s]+)\]\s'
|
||||
'PVT_V0_16\[(?P<PVT_V0_16>[-0-9\s]+)\]\s'
|
||||
'PVT_V0_17\[(?P<PVT_V0_17>[-0-9\s]+)\]\s'
|
||||
'PVT_V0_18\[(?P<PVT_V0_18>[-0-9\s]+)\]\s'
|
||||
'PVT_V0_19\[(?P<PVT_V0_19>[-0-9\s]+)\]\s'
|
||||
'PVT_V0_20\[(?P<PVT_V0_20>[-0-9\s]+)\]\s'
|
||||
'PVT_V0_21\[(?P<PVT_V0_21>[-0-9\s]+)\]\s'
|
||||
'PVT_V0_22\[(?P<PVT_V0_22>[-0-9\s]+)\]\s'
|
||||
'PVT_V0_23\[(?P<PVT_V0_23>[-0-9\s]+)\]\s'
|
||||
'PVT_V0_24\[(?P<PVT_V0_24>[-0-9\s]+)\]\s'
|
||||
'PVT_V0_25\[(?P<PVT_V0_25>[-0-9\s]+)\]\s'
|
||||
'PVT_V1_0\[(?P<PVT_V1_0>[-0-9\s]+)\]\s'
|
||||
'PVT_V1_1\[(?P<PVT_V1_1>[-0-9\s]+)\]\s'
|
||||
'PVT_V1_2\[(?P<PVT_V1_2>[-0-9\s]+)\]\s'
|
||||
'PVT_V1_3\[(?P<PVT_V1_3>[-0-9\s]+)\]\s'
|
||||
'PVT_V1_4\[(?P<PVT_V1_4>[-0-9\s]+)\]\s'
|
||||
'PVT_V1_5\[(?P<PVT_V1_5>[-0-9\s]+)\]\s'
|
||||
'PVT_V1_6\[(?P<PVT_V1_6>[-0-9\s]+)\]\s'
|
||||
'PVT_V1_7\[(?P<PVT_V1_7>[-0-9\s]+)\]\s'
|
||||
'PVT_V1_8\[(?P<PVT_V1_8>[-0-9\s]+)\]\s'
|
||||
'PVT_V1_9\[(?P<PVT_V1_9>[-0-9\s]+)\]\s'
|
||||
'PVT_V1_10\[(?P<PVT_V1_10>[-0-9\s]+)\]\s'
|
||||
'PVT_V1_11\[(?P<PVT_V1_11>[-0-9\s]+)\]\s'
|
||||
'PVT_V1_12\[(?P<PVT_V1_12>[-0-9\s]+)\]\s'
|
||||
'PVT_V1_13\[(?P<PVT_V1_13>[-0-9\s]+)\]\s'
|
||||
'PVT_V1_14\[(?P<PVT_V1_14>[-0-9\s]+)\]\s'
|
||||
'PVT_V1_15\[(?P<PVT_V1_15>[-0-9\s]+)\]\s'
|
||||
'PVT_V1_16\[(?P<PVT_V1_16>[-0-9\s]+)\]\s'
|
||||
'PVT_V1_17\[(?P<PVT_V1_17>[-0-9\s]+)\]\s'
|
||||
'PVT_V1_18\[(?P<PVT_V1_18>[-0-9\s]+)\]\s'
|
||||
'PVT_V1_19\[(?P<PVT_V1_19>[-0-9\s]+)\]\s'
|
||||
'PVT_V1_20\[(?P<PVT_V1_20>[-0-9\s]+)\]\s'
|
||||
'PVT_V1_21\[(?P<PVT_V1_21>[-0-9\s]+)\]\s'
|
||||
'PVT_V1_22\[(?P<PVT_V1_22>[-0-9\s]+)\]\s'
|
||||
'PVT_V1_23\[(?P<PVT_V1_23>[-0-9\s]+)\]\s'
|
||||
'PVT_V1_24\[(?P<PVT_V1_24>[-0-9\s]+)\]\s'
|
||||
'PVT_V1_25\[(?P<PVT_V1_25>[-0-9\s]+)\]\s'
|
||||
'PVT_V2_0\[(?P<PVT_V2_0>[-0-9\s]+)\]\s'
|
||||
'PVT_V2_1\[(?P<PVT_V2_1>[-0-9\s]+)\]\s'
|
||||
'PVT_V2_2\[(?P<PVT_V2_2>[-0-9\s]+)\]\s'
|
||||
'PVT_V2_3\[(?P<PVT_V2_3>[-0-9\s]+)\]\s'
|
||||
'PVT_V2_4\[(?P<PVT_V2_4>[-0-9\s]+)\]\s'
|
||||
'PVT_V2_5\[(?P<PVT_V2_5>[-0-9\s]+)\]\s'
|
||||
'PVT_V2_6\[(?P<PVT_V2_6>[-0-9\s]+)\]\s'
|
||||
'PVT_V2_7\[(?P<PVT_V2_7>[-0-9\s]+)\]\s'
|
||||
'PVT_V2_8\[(?P<PVT_V2_8>[-0-9\s]+)\]\s'
|
||||
'PVT_V2_9\[(?P<PVT_V2_9>[-0-9\s]+)\]\s'
|
||||
'PVT_V2_10\[(?P<PVT_V2_10>[-0-9\s]+)\]\s'
|
||||
'PVT_V2_11\[(?P<PVT_V2_11>[-0-9\s]+)\]\s'
|
||||
'PVT_V2_12\[(?P<PVT_V2_12>[-0-9\s]+)\]\s'
|
||||
'PVT_V2_13\[(?P<PVT_V2_13>[-0-9\s]+)\]\s'
|
||||
'PVT_V2_14\[(?P<PVT_V2_14>[-0-9\s]+)\]\s'
|
||||
'PVT_V2_15\[(?P<PVT_V2_15>[-0-9\s]+)\]\s'
|
||||
'PVT_V2_16\[(?P<PVT_V2_16>[-0-9\s]+)\]\s'
|
||||
'PVT_V2_17\[(?P<PVT_V2_17>[-0-9\s]+)\]\s'
|
||||
'PVT_V2_18\[(?P<PVT_V2_18>[-0-9\s]+)\]\s'
|
||||
'PVT_V2_19\[(?P<PVT_V2_19>[-0-9\s]+)\]\s'
|
||||
'PVT_V2_20\[(?P<PVT_V2_20>[-0-9\s]+)\]\s'
|
||||
'PVT_V2_21\[(?P<PVT_V2_21>[-0-9\s]+)\]\s'
|
||||
'PVT_V2_22\[(?P<PVT_V2_22>[-0-9\s]+)\]\s'
|
||||
'PVT_V2_23\[(?P<PVT_V2_23>[-0-9\s]+)\]\s'
|
||||
'PVT_V2_24\[(?P<PVT_V2_24>[-0-9\s]+)\]\s'
|
||||
'PVT_V2_25\[(?P<PVT_V2_25>[-0-9\s]+)\]\s'
|
||||
'PVT_V3_0\[(?P<PVT_V3_0>[-0-9\s]+)\]\s'
|
||||
'PVT_V3_1\[(?P<PVT_V3_1>[-0-9\s]+)\]\s'
|
||||
'PVT_V3_2\[(?P<PVT_V3_2>[-0-9\s]+)\]\s'
|
||||
'PVT_V3_3\[(?P<PVT_V3_3>[-0-9\s]+)\]\s'
|
||||
'PVT_V3_4\[(?P<PVT_V3_4>[-0-9\s]+)\]\s'
|
||||
'PVT_V3_5\[(?P<PVT_V3_5>[-0-9\s]+)\]\s'
|
||||
'PVT_V3_6\[(?P<PVT_V3_6>[-0-9\s]+)\]\s'
|
||||
'PVT_V3_7\[(?P<PVT_V3_7>[-0-9\s]+)\]\s'
|
||||
'PVT_V3_8\[(?P<PVT_V3_8>[-0-9\s]+)\]\s'
|
||||
'PVT_V3_9\[(?P<PVT_V3_9>[-0-9\s]+)\]\s'
|
||||
'PVT_V3_10\[(?P<PVT_V3_10>[-0-9\s]+)\]\s'
|
||||
'PVT_V3_11\[(?P<PVT_V3_11>[-0-9\s]+)\]\s'
|
||||
'PVT_V3_12\[(?P<PVT_V3_12>[-0-9\s]+)\]\s'
|
||||
'PVT_V3_13\[(?P<PVT_V3_13>[-0-9\s]+)\]\s'
|
||||
'PVT_V3_14\[(?P<PVT_V3_14>[-0-9\s]+)\]\s'
|
||||
'PVT_V3_15\[(?P<PVT_V3_15>[-0-9\s]+)\]\s'
|
||||
'PVT_V3_16\[(?P<PVT_V3_16>[-0-9\s]+)\]\s'
|
||||
'PVT_V3_17\[(?P<PVT_V3_17>[-0-9\s]+)\]\s'
|
||||
'PVT_V3_18\[(?P<PVT_V3_18>[-0-9\s]+)\]\s'
|
||||
'PVT_V3_19\[(?P<PVT_V3_19>[-0-9\s]+)\]\s'
|
||||
'PVT_V3_20\[(?P<PVT_V3_20>[-0-9\s]+)\]\s'
|
||||
'PVT_V3_21\[(?P<PVT_V3_21>[-0-9\s]+)\]\s'
|
||||
'PVT_V3_22\[(?P<PVT_V3_22>[-0-9\s]+)\]\s'
|
||||
'PVT_V3_23\[(?P<PVT_V3_23>[-0-9\s]+)\]\s'
|
||||
'PVT_V3_24\[(?P<PVT_V3_24>[-0-9\s]+)\]\s'
|
||||
'PVT_V3_25\[(?P<PVT_V3_25>[-0-9\s]+)\]\s'
|
||||
'FM\[(?P<FM>[0-9]+)\]\s'
|
||||
'CRC\[(?P<CRC>[0-9\s]+)\]', re.X
|
||||
)
|
||||
self.pattern = re.compile(
|
||||
r"Ver\[(?P<Ver>[-0-9A-Fa-f+]+)\]\s"
|
||||
"DNA\[(?P<DNA>[0-9A-Fa-f]+)\]\s"
|
||||
"Elapsed\[(?P<Elapsed>[-0-9]+)\]\s"
|
||||
"MW\[(?P<MW>[-\s0-9]+)\]\s"
|
||||
"LW\[(?P<LW>[-0-9]+)\]\s"
|
||||
"MH\[(?P<MH>[-\s0-9]+)\]\s"
|
||||
"HW\[(?P<HW>[-0-9]+)\]\s"
|
||||
"Temp\[(?P<Temp>[0-9]+)\]\s"
|
||||
"TMax\[(?P<TMax>[0-9]+)\]\s"
|
||||
"Fan\[(?P<Fan>[0-9]+)\]\s"
|
||||
"FanR\[(?P<FanR>[0-9]+)%\]\s"
|
||||
"Vi\[(?P<Vi>[-\s0-9]+)\]\s"
|
||||
"Vo\[(?P<Vo>[-\s0-9]+)\]\s"
|
||||
"("
|
||||
"PLL0\[(?P<PLL0>[-\s0-9]+)\]\s"
|
||||
"PLL1\[(?P<PLL1>[-\s0-9]+)\]\s"
|
||||
"PLL2\[(?P<PLL2>[-\s0-9]+)\]\s"
|
||||
"PLL3\[(?P<PLL3>[-\s0-9]+)\]\s"
|
||||
")?"
|
||||
"GHSmm\[(?P<GHSmm>[-.0-9]+)\]\s"
|
||||
"WU\[(?P<WU>[-.0-9]+)\]\s"
|
||||
"Freq\[(?P<Freq>[.0-9]+)\]\s"
|
||||
"PG\[(?P<PG>[0-9]+)\]\s"
|
||||
"Led\[(?P<LED>0|1)\]\s"
|
||||
"MW0\[(?P<MW0>[0-9\s]+)\]\s"
|
||||
"MW1\[(?P<MW1>[0-9\s]+)\]\s"
|
||||
"MW2\[(?P<MW2>[0-9\s]+)\]\s"
|
||||
"MW3\[(?P<MW3>[0-9\s]+)\]\s"
|
||||
"TA\[(?P<TA>[0-9]+)\]\s"
|
||||
"ECHU\[(?P<ECHU>[0-9\s]+)\]\s"
|
||||
"ECMM\[(?P<ECMM>[0-9]+)\]\s.*"
|
||||
"FAC0\[(?P<FAC0>[-0-9]+)\]\s"
|
||||
"OC\[(?P<OC>[0-9]+)\]\s"
|
||||
"SF0\[(?P<SF0>[-\s0-9]+)\]\s"
|
||||
"SF1\[(?P<SF1>[-\s0-9]+)\]\s"
|
||||
"SF2\[(?P<SF2>[-\s0-9]+)\]\s"
|
||||
"SF3\[(?P<SF3>[-\s0-9]+)\]\s"
|
||||
"PMUV\[(?P<PMUV>[-\s\S*]+)\]\s"
|
||||
"PVT_T0\[(?P<PVT_T0>[-0-9\s]+)\]\s"
|
||||
"PVT_T1\[(?P<PVT_T1>[-0-9\s]+)\]\s"
|
||||
"PVT_T2\[(?P<PVT_T2>[-0-9\s]+)\]\s"
|
||||
"PVT_T3\[(?P<PVT_T3>[-0-9\s]+)\]\s"
|
||||
"PVT_V0_0\[(?P<PVT_V0_0>[-0-9\s]+)\]\s"
|
||||
"PVT_V0_1\[(?P<PVT_V0_1>[-0-9\s]+)\]\s"
|
||||
"PVT_V0_2\[(?P<PVT_V0_2>[-0-9\s]+)\]\s"
|
||||
"PVT_V0_3\[(?P<PVT_V0_3>[-0-9\s]+)\]\s"
|
||||
"PVT_V0_4\[(?P<PVT_V0_4>[-0-9\s]+)\]\s"
|
||||
"PVT_V0_5\[(?P<PVT_V0_5>[-0-9\s]+)\]\s"
|
||||
"PVT_V0_6\[(?P<PVT_V0_6>[-0-9\s]+)\]\s"
|
||||
"PVT_V0_7\[(?P<PVT_V0_7>[-0-9\s]+)\]\s"
|
||||
"PVT_V0_8\[(?P<PVT_V0_8>[-0-9\s]+)\]\s"
|
||||
"PVT_V0_9\[(?P<PVT_V0_9>[-0-9\s]+)\]\s"
|
||||
"PVT_V0_10\[(?P<PVT_V0_10>[-0-9\s]+)\]\s"
|
||||
"PVT_V0_11\[(?P<PVT_V0_11>[-0-9\s]+)\]\s"
|
||||
"PVT_V0_12\[(?P<PVT_V0_12>[-0-9\s]+)\]\s"
|
||||
"PVT_V0_13\[(?P<PVT_V0_13>[-0-9\s]+)\]\s"
|
||||
"PVT_V0_14\[(?P<PVT_V0_14>[-0-9\s]+)\]\s"
|
||||
"PVT_V0_15\[(?P<PVT_V0_15>[-0-9\s]+)\]\s"
|
||||
"PVT_V0_16\[(?P<PVT_V0_16>[-0-9\s]+)\]\s"
|
||||
"PVT_V0_17\[(?P<PVT_V0_17>[-0-9\s]+)\]\s"
|
||||
"PVT_V0_18\[(?P<PVT_V0_18>[-0-9\s]+)\]\s"
|
||||
"PVT_V0_19\[(?P<PVT_V0_19>[-0-9\s]+)\]\s"
|
||||
"PVT_V0_20\[(?P<PVT_V0_20>[-0-9\s]+)\]\s"
|
||||
"PVT_V0_21\[(?P<PVT_V0_21>[-0-9\s]+)\]\s"
|
||||
"PVT_V0_22\[(?P<PVT_V0_22>[-0-9\s]+)\]\s"
|
||||
"PVT_V0_23\[(?P<PVT_V0_23>[-0-9\s]+)\]\s"
|
||||
"PVT_V0_24\[(?P<PVT_V0_24>[-0-9\s]+)\]\s"
|
||||
"PVT_V0_25\[(?P<PVT_V0_25>[-0-9\s]+)\]\s"
|
||||
"PVT_V1_0\[(?P<PVT_V1_0>[-0-9\s]+)\]\s"
|
||||
"PVT_V1_1\[(?P<PVT_V1_1>[-0-9\s]+)\]\s"
|
||||
"PVT_V1_2\[(?P<PVT_V1_2>[-0-9\s]+)\]\s"
|
||||
"PVT_V1_3\[(?P<PVT_V1_3>[-0-9\s]+)\]\s"
|
||||
"PVT_V1_4\[(?P<PVT_V1_4>[-0-9\s]+)\]\s"
|
||||
"PVT_V1_5\[(?P<PVT_V1_5>[-0-9\s]+)\]\s"
|
||||
"PVT_V1_6\[(?P<PVT_V1_6>[-0-9\s]+)\]\s"
|
||||
"PVT_V1_7\[(?P<PVT_V1_7>[-0-9\s]+)\]\s"
|
||||
"PVT_V1_8\[(?P<PVT_V1_8>[-0-9\s]+)\]\s"
|
||||
"PVT_V1_9\[(?P<PVT_V1_9>[-0-9\s]+)\]\s"
|
||||
"PVT_V1_10\[(?P<PVT_V1_10>[-0-9\s]+)\]\s"
|
||||
"PVT_V1_11\[(?P<PVT_V1_11>[-0-9\s]+)\]\s"
|
||||
"PVT_V1_12\[(?P<PVT_V1_12>[-0-9\s]+)\]\s"
|
||||
"PVT_V1_13\[(?P<PVT_V1_13>[-0-9\s]+)\]\s"
|
||||
"PVT_V1_14\[(?P<PVT_V1_14>[-0-9\s]+)\]\s"
|
||||
"PVT_V1_15\[(?P<PVT_V1_15>[-0-9\s]+)\]\s"
|
||||
"PVT_V1_16\[(?P<PVT_V1_16>[-0-9\s]+)\]\s"
|
||||
"PVT_V1_17\[(?P<PVT_V1_17>[-0-9\s]+)\]\s"
|
||||
"PVT_V1_18\[(?P<PVT_V1_18>[-0-9\s]+)\]\s"
|
||||
"PVT_V1_19\[(?P<PVT_V1_19>[-0-9\s]+)\]\s"
|
||||
"PVT_V1_20\[(?P<PVT_V1_20>[-0-9\s]+)\]\s"
|
||||
"PVT_V1_21\[(?P<PVT_V1_21>[-0-9\s]+)\]\s"
|
||||
"PVT_V1_22\[(?P<PVT_V1_22>[-0-9\s]+)\]\s"
|
||||
"PVT_V1_23\[(?P<PVT_V1_23>[-0-9\s]+)\]\s"
|
||||
"PVT_V1_24\[(?P<PVT_V1_24>[-0-9\s]+)\]\s"
|
||||
"PVT_V1_25\[(?P<PVT_V1_25>[-0-9\s]+)\]\s"
|
||||
"PVT_V2_0\[(?P<PVT_V2_0>[-0-9\s]+)\]\s"
|
||||
"PVT_V2_1\[(?P<PVT_V2_1>[-0-9\s]+)\]\s"
|
||||
"PVT_V2_2\[(?P<PVT_V2_2>[-0-9\s]+)\]\s"
|
||||
"PVT_V2_3\[(?P<PVT_V2_3>[-0-9\s]+)\]\s"
|
||||
"PVT_V2_4\[(?P<PVT_V2_4>[-0-9\s]+)\]\s"
|
||||
"PVT_V2_5\[(?P<PVT_V2_5>[-0-9\s]+)\]\s"
|
||||
"PVT_V2_6\[(?P<PVT_V2_6>[-0-9\s]+)\]\s"
|
||||
"PVT_V2_7\[(?P<PVT_V2_7>[-0-9\s]+)\]\s"
|
||||
"PVT_V2_8\[(?P<PVT_V2_8>[-0-9\s]+)\]\s"
|
||||
"PVT_V2_9\[(?P<PVT_V2_9>[-0-9\s]+)\]\s"
|
||||
"PVT_V2_10\[(?P<PVT_V2_10>[-0-9\s]+)\]\s"
|
||||
"PVT_V2_11\[(?P<PVT_V2_11>[-0-9\s]+)\]\s"
|
||||
"PVT_V2_12\[(?P<PVT_V2_12>[-0-9\s]+)\]\s"
|
||||
"PVT_V2_13\[(?P<PVT_V2_13>[-0-9\s]+)\]\s"
|
||||
"PVT_V2_14\[(?P<PVT_V2_14>[-0-9\s]+)\]\s"
|
||||
"PVT_V2_15\[(?P<PVT_V2_15>[-0-9\s]+)\]\s"
|
||||
"PVT_V2_16\[(?P<PVT_V2_16>[-0-9\s]+)\]\s"
|
||||
"PVT_V2_17\[(?P<PVT_V2_17>[-0-9\s]+)\]\s"
|
||||
"PVT_V2_18\[(?P<PVT_V2_18>[-0-9\s]+)\]\s"
|
||||
"PVT_V2_19\[(?P<PVT_V2_19>[-0-9\s]+)\]\s"
|
||||
"PVT_V2_20\[(?P<PVT_V2_20>[-0-9\s]+)\]\s"
|
||||
"PVT_V2_21\[(?P<PVT_V2_21>[-0-9\s]+)\]\s"
|
||||
"PVT_V2_22\[(?P<PVT_V2_22>[-0-9\s]+)\]\s"
|
||||
"PVT_V2_23\[(?P<PVT_V2_23>[-0-9\s]+)\]\s"
|
||||
"PVT_V2_24\[(?P<PVT_V2_24>[-0-9\s]+)\]\s"
|
||||
"PVT_V2_25\[(?P<PVT_V2_25>[-0-9\s]+)\]\s"
|
||||
"PVT_V3_0\[(?P<PVT_V3_0>[-0-9\s]+)\]\s"
|
||||
"PVT_V3_1\[(?P<PVT_V3_1>[-0-9\s]+)\]\s"
|
||||
"PVT_V3_2\[(?P<PVT_V3_2>[-0-9\s]+)\]\s"
|
||||
"PVT_V3_3\[(?P<PVT_V3_3>[-0-9\s]+)\]\s"
|
||||
"PVT_V3_4\[(?P<PVT_V3_4>[-0-9\s]+)\]\s"
|
||||
"PVT_V3_5\[(?P<PVT_V3_5>[-0-9\s]+)\]\s"
|
||||
"PVT_V3_6\[(?P<PVT_V3_6>[-0-9\s]+)\]\s"
|
||||
"PVT_V3_7\[(?P<PVT_V3_7>[-0-9\s]+)\]\s"
|
||||
"PVT_V3_8\[(?P<PVT_V3_8>[-0-9\s]+)\]\s"
|
||||
"PVT_V3_9\[(?P<PVT_V3_9>[-0-9\s]+)\]\s"
|
||||
"PVT_V3_10\[(?P<PVT_V3_10>[-0-9\s]+)\]\s"
|
||||
"PVT_V3_11\[(?P<PVT_V3_11>[-0-9\s]+)\]\s"
|
||||
"PVT_V3_12\[(?P<PVT_V3_12>[-0-9\s]+)\]\s"
|
||||
"PVT_V3_13\[(?P<PVT_V3_13>[-0-9\s]+)\]\s"
|
||||
"PVT_V3_14\[(?P<PVT_V3_14>[-0-9\s]+)\]\s"
|
||||
"PVT_V3_15\[(?P<PVT_V3_15>[-0-9\s]+)\]\s"
|
||||
"PVT_V3_16\[(?P<PVT_V3_16>[-0-9\s]+)\]\s"
|
||||
"PVT_V3_17\[(?P<PVT_V3_17>[-0-9\s]+)\]\s"
|
||||
"PVT_V3_18\[(?P<PVT_V3_18>[-0-9\s]+)\]\s"
|
||||
"PVT_V3_19\[(?P<PVT_V3_19>[-0-9\s]+)\]\s"
|
||||
"PVT_V3_20\[(?P<PVT_V3_20>[-0-9\s]+)\]\s"
|
||||
"PVT_V3_21\[(?P<PVT_V3_21>[-0-9\s]+)\]\s"
|
||||
"PVT_V3_22\[(?P<PVT_V3_22>[-0-9\s]+)\]\s"
|
||||
"PVT_V3_23\[(?P<PVT_V3_23>[-0-9\s]+)\]\s"
|
||||
"PVT_V3_24\[(?P<PVT_V3_24>[-0-9\s]+)\]\s"
|
||||
"PVT_V3_25\[(?P<PVT_V3_25>[-0-9\s]+)\]\s"
|
||||
"FM\[(?P<FM>[0-9]+)\]\s"
|
||||
"CRC\[(?P<CRC>[0-9\s]+)\]",
|
||||
re.X,
|
||||
)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"CGMinerAvalon8: {str(self.ip)}"
|
||||
@@ -163,7 +165,7 @@ class CGMinerAvalon8(CGMiner):
|
||||
def parse_estats(self, estats):
|
||||
for estat in estats:
|
||||
for key in estat:
|
||||
if key[:5] == 'MM ID':
|
||||
if key[:5] == "MM ID":
|
||||
self._parse_estat(estat, key)
|
||||
|
||||
def _parse_estat(self, estat, key):
|
||||
|
||||
@@ -9,8 +9,8 @@ class BMMiner(BaseMiner):
|
||||
super().__init__(ip, api)
|
||||
self.model = None
|
||||
self.config = None
|
||||
self.uname = 'root'
|
||||
self.pwd = 'admin'
|
||||
self.uname = "root"
|
||||
self.pwd = "admin"
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"BMMiner: {str(self.ip)}"
|
||||
@@ -31,7 +31,7 @@ class BMMiner(BaseMiner):
|
||||
try:
|
||||
async with (await self._get_ssh_connection()) as conn:
|
||||
if conn is not None:
|
||||
data = await conn.run('cat /proc/sys/kernel/hostname')
|
||||
data = await conn.run("cat /proc/sys/kernel/hostname")
|
||||
host = data.stdout.strip()
|
||||
logging.debug(f"Found hostname for {self.ip}: {host}")
|
||||
return host
|
||||
|
||||
@@ -4,14 +4,15 @@ import toml
|
||||
from config.bos import bos_config_convert, general_config_convert_bos
|
||||
import logging
|
||||
|
||||
|
||||
class BOSMiner(BaseMiner):
|
||||
def __init__(self, ip: str) -> None:
|
||||
api = BOSMinerAPI(ip)
|
||||
super().__init__(ip, api)
|
||||
self.model = None
|
||||
self.config = None
|
||||
self.uname = 'root'
|
||||
self.pwd = 'admin'
|
||||
self.uname = "root"
|
||||
self.pwd = "admin"
|
||||
self.nominal_chips = 63
|
||||
|
||||
def __repr__(self) -> str:
|
||||
@@ -39,13 +40,13 @@ class BOSMiner(BaseMiner):
|
||||
async def fault_light_on(self) -> None:
|
||||
"""Sends command to turn on fault light on the miner."""
|
||||
logging.debug(f"{self}: Sending fault_light on command.")
|
||||
await self.send_ssh_command('miner fault_light on')
|
||||
await self.send_ssh_command("miner fault_light on")
|
||||
logging.debug(f"{self}: fault_light on command completed.")
|
||||
|
||||
async def fault_light_off(self) -> None:
|
||||
"""Sends command to turn off fault light on the miner."""
|
||||
logging.debug(f"{self}: Sending fault_light off command.")
|
||||
await self.send_ssh_command('miner fault_light off')
|
||||
await self.send_ssh_command("miner fault_light off")
|
||||
logging.debug(f"{self}: fault_light off command completed.")
|
||||
|
||||
async def restart_backend(self):
|
||||
@@ -54,7 +55,7 @@ class BOSMiner(BaseMiner):
|
||||
async def restart_bosminer(self) -> None:
|
||||
"""Restart bosminer hashing process."""
|
||||
logging.debug(f"{self}: Sending bosminer restart command.")
|
||||
await self.send_ssh_command('/etc/init.d/bosminer restart')
|
||||
await self.send_ssh_command("/etc/init.d/bosminer restart")
|
||||
logging.debug(f"{self}: bosminer restart command completed.")
|
||||
|
||||
async def reboot(self) -> None:
|
||||
@@ -69,7 +70,7 @@ class BOSMiner(BaseMiner):
|
||||
logging.debug(f"{self}: Opening SFTP connection.")
|
||||
async with conn.start_sftp_client() as sftp:
|
||||
logging.debug(f"{self}: Reading config file.")
|
||||
async with sftp.open('/etc/bosminer.toml') as file:
|
||||
async with sftp.open("/etc/bosminer.toml") as file:
|
||||
toml_data = toml.loads(await file.read())
|
||||
logging.debug(f"{self}: Converting config file.")
|
||||
cfg = await bos_config_convert(toml_data)
|
||||
@@ -80,7 +81,7 @@ class BOSMiner(BaseMiner):
|
||||
try:
|
||||
async with (await self._get_ssh_connection()) as conn:
|
||||
if conn is not None:
|
||||
data = await conn.run('cat /proc/sys/kernel/hostname')
|
||||
data = await conn.run("cat /proc/sys/kernel/hostname")
|
||||
host = data.stdout.strip()
|
||||
logging.debug(f"Found hostname for {self.ip}: {host}")
|
||||
return host
|
||||
@@ -98,7 +99,9 @@ class BOSMiner(BaseMiner):
|
||||
version_data = await self.api.devdetails()
|
||||
if version_data:
|
||||
if not version_data["DEVDETAILS"] == []:
|
||||
self.model = version_data["DEVDETAILS"][0]["Model"].replace("Antminer ", "")
|
||||
self.model = version_data["DEVDETAILS"][0]["Model"].replace(
|
||||
"Antminer ", ""
|
||||
)
|
||||
logging.debug(f"Found model for {self.ip}: {self.model} (BOS)")
|
||||
return self.model + " (BOS)"
|
||||
logging.warning(f"Failed to get model for miner: {self}")
|
||||
@@ -112,7 +115,7 @@ class BOSMiner(BaseMiner):
|
||||
logging.debug(f"{self}: Opening SFTP connection.")
|
||||
async with conn.start_sftp_client() as sftp:
|
||||
logging.debug(f"{self}: Opening config file.")
|
||||
async with sftp.open('/etc/bosminer.toml', 'w+') as file:
|
||||
async with sftp.open("/etc/bosminer.toml", "w+") as file:
|
||||
await file.write(toml_conf)
|
||||
logging.debug(f"{self}: Restarting BOSMiner")
|
||||
await conn.run("/etc/init.d/bosminer restart")
|
||||
@@ -124,21 +127,23 @@ class BOSMiner(BaseMiner):
|
||||
if not devdetails.get("DEVDETAILS"):
|
||||
print("devdetails error", devdetails)
|
||||
return {0: [], 1: [], 2: []}
|
||||
devs = devdetails['DEVDETAILS']
|
||||
devs = devdetails["DEVDETAILS"]
|
||||
boards = {}
|
||||
offset = devs[0]["ID"]
|
||||
for board in devs:
|
||||
boards[board["ID"] - offset] = []
|
||||
if not board['Chips'] == self.nominal_chips:
|
||||
if not board["Chips"] == self.nominal_chips:
|
||||
nominal = False
|
||||
else:
|
||||
nominal = True
|
||||
boards[board["ID"] - offset].append({
|
||||
"chain": board["ID"] - offset,
|
||||
"chip_count": board['Chips'],
|
||||
"chip_status": "o" * board['Chips'],
|
||||
"nominal": nominal
|
||||
})
|
||||
boards[board["ID"] - offset].append(
|
||||
{
|
||||
"chain": board["ID"] - offset,
|
||||
"chip_count": board["Chips"],
|
||||
"chip_status": "o" * board["Chips"],
|
||||
"nominal": nominal,
|
||||
}
|
||||
)
|
||||
logging.debug(f"Found board data for {self}: {boards}")
|
||||
return boards
|
||||
|
||||
@@ -158,9 +163,9 @@ class BOSMiner(BaseMiner):
|
||||
"""Checks for and provides list for working boards."""
|
||||
devs = await self.api.devdetails()
|
||||
bad = 0
|
||||
chains = devs['DEVDETAILS']
|
||||
chains = devs["DEVDETAILS"]
|
||||
for chain in chains:
|
||||
if chain['Chips'] == 0:
|
||||
if chain["Chips"] == 0:
|
||||
bad += 1
|
||||
if not bad > 0:
|
||||
return str(self.ip)
|
||||
|
||||
@@ -53,16 +53,18 @@ class BTMiner(BaseMiner):
|
||||
for board in devs:
|
||||
boards[board["ID"] - offset] = []
|
||||
if "Effective Chips" in board.keys():
|
||||
if not board['Effective Chips'] in self.nominal_chips:
|
||||
if not board["Effective Chips"] in self.nominal_chips:
|
||||
nominal = False
|
||||
else:
|
||||
nominal = True
|
||||
boards[board["ID"] - offset].append({
|
||||
"chain": board["ID"] - offset,
|
||||
"chip_count": board['Effective Chips'],
|
||||
"chip_status": "o" * board['Effective Chips'],
|
||||
"nominal": nominal
|
||||
})
|
||||
boards[board["ID"] - offset].append(
|
||||
{
|
||||
"chain": board["ID"] - offset,
|
||||
"chip_count": board["Effective Chips"],
|
||||
"chip_status": "o" * board["Effective Chips"],
|
||||
"nominal": nominal,
|
||||
}
|
||||
)
|
||||
else:
|
||||
logging.warning(f"Incorrect board data from {self}: {board}")
|
||||
print(board)
|
||||
|
||||
@@ -9,8 +9,8 @@ class CGMiner(BaseMiner):
|
||||
super().__init__(ip, api)
|
||||
self.model = None
|
||||
self.config = None
|
||||
self.uname = 'root'
|
||||
self.pwd = 'admin'
|
||||
self.uname = "root"
|
||||
self.pwd = "admin"
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"CGMiner: {str(self.ip)}"
|
||||
@@ -23,8 +23,7 @@ class CGMiner(BaseMiner):
|
||||
except APIError:
|
||||
return None
|
||||
if version_data:
|
||||
self.model = version_data["DEVDETAILS"][0]["Model"].replace(
|
||||
"Antminer ", "")
|
||||
self.model = version_data["DEVDETAILS"][0]["Model"].replace("Antminer ", "")
|
||||
return self.model
|
||||
return None
|
||||
|
||||
@@ -32,7 +31,7 @@ class CGMiner(BaseMiner):
|
||||
try:
|
||||
async with (await self._get_ssh_connection()) as conn:
|
||||
if conn is not None:
|
||||
data = await conn.run('cat /proc/sys/kernel/hostname')
|
||||
data = await conn.run("cat /proc/sys/kernel/hostname")
|
||||
return data.stdout.strip()
|
||||
else:
|
||||
return "?"
|
||||
@@ -56,33 +55,36 @@ class CGMiner(BaseMiner):
|
||||
await self.restart_cgminer()
|
||||
|
||||
async def restart_cgminer(self) -> None:
|
||||
commands = ['cgminer-api restart',
|
||||
'/usr/bin/cgminer-monitor >/dev/null 2>&1']
|
||||
commands = ';'.join(commands)
|
||||
commands = ["cgminer-api restart", "/usr/bin/cgminer-monitor >/dev/null 2>&1"]
|
||||
commands = ";".join(commands)
|
||||
await self.send_ssh_command(commands)
|
||||
|
||||
async def reboot(self) -> None:
|
||||
await self.send_ssh_command("reboot")
|
||||
|
||||
async def start_cgminer(self) -> None:
|
||||
commands = ['mkdir -p /etc/tmp/',
|
||||
'echo \"*/3 * * * * /usr/bin/cgminer-monitor\" > /etc/tmp/root',
|
||||
'crontab -u root /etc/tmp/root',
|
||||
'/usr/bin/cgminer-monitor >/dev/null 2>&1']
|
||||
commands = ';'.join(commands)
|
||||
commands = [
|
||||
"mkdir -p /etc/tmp/",
|
||||
'echo "*/3 * * * * /usr/bin/cgminer-monitor" > /etc/tmp/root',
|
||||
"crontab -u root /etc/tmp/root",
|
||||
"/usr/bin/cgminer-monitor >/dev/null 2>&1",
|
||||
]
|
||||
commands = ";".join(commands)
|
||||
await self.send_ssh_command(commands)
|
||||
|
||||
async def stop_cgminer(self) -> None:
|
||||
commands = ['mkdir -p /etc/tmp/',
|
||||
'echo \"\" > /etc/tmp/root',
|
||||
'crontab -u root /etc/tmp/root',
|
||||
'killall cgminer']
|
||||
commands = ';'.join(commands)
|
||||
commands = [
|
||||
"mkdir -p /etc/tmp/",
|
||||
'echo "" > /etc/tmp/root',
|
||||
"crontab -u root /etc/tmp/root",
|
||||
"killall cgminer",
|
||||
]
|
||||
commands = ";".join(commands)
|
||||
await self.send_ssh_command(commands)
|
||||
|
||||
async def get_config(self) -> None:
|
||||
async with (await self._get_ssh_connection()) as conn:
|
||||
command = 'cat /etc/config/cgminer'
|
||||
command = "cat /etc/config/cgminer"
|
||||
result = await conn.run(command, check=True)
|
||||
self.config = result.stdout
|
||||
print(str(self.config))
|
||||
|
||||
@@ -46,10 +46,7 @@ class MinerFactory:
|
||||
|
||||
def __new__(cls):
|
||||
if not cls._instance:
|
||||
cls._instance = super(
|
||||
MinerFactory,
|
||||
cls
|
||||
).__new__(cls)
|
||||
cls._instance = super(MinerFactory, cls).__new__(cls)
|
||||
return cls._instance
|
||||
|
||||
async def get_miner_generator(self, ips: list):
|
||||
@@ -221,7 +218,10 @@ class MinerFactory:
|
||||
model = data["VERSION"][0]["Type"]
|
||||
else:
|
||||
# make sure devdetails actually contains data, if its empty, there are no devices
|
||||
if "DEVDETAILS" in data.keys() and not data["DEVDETAILS"] == []:
|
||||
if (
|
||||
"DEVDETAILS" in data.keys()
|
||||
and not data["DEVDETAILS"] == []
|
||||
):
|
||||
|
||||
# check for model, for most miners
|
||||
if not data["DEVDETAILS"][0]["Model"] == "":
|
||||
@@ -261,7 +261,7 @@ class MinerFactory:
|
||||
cmd = {"command": command}
|
||||
|
||||
# send the command
|
||||
writer.write(json.dumps(cmd).encode('utf-8'))
|
||||
writer.write(json.dumps(cmd).encode("utf-8"))
|
||||
await writer.drain()
|
||||
|
||||
# instantiate data
|
||||
@@ -281,10 +281,10 @@ class MinerFactory:
|
||||
# some json from the API returns with a null byte (\x00) on the end
|
||||
if data.endswith(b"\x00"):
|
||||
# handle the null byte
|
||||
str_data = data.decode('utf-8')[:-1]
|
||||
str_data = data.decode("utf-8")[:-1]
|
||||
else:
|
||||
# no null byte
|
||||
str_data = data.decode('utf-8')
|
||||
str_data = data.decode("utf-8")
|
||||
# fix an error with a btminer return having an extra comma that breaks json.loads()
|
||||
str_data = str_data.replace(",}", "}")
|
||||
# fix an error with a btminer return having a newline that breaks json.loads()
|
||||
@@ -321,19 +321,27 @@ class MinerFactory:
|
||||
if data["STATUS"][0].get("STATUS") in ["I", "S"]:
|
||||
|
||||
# check if there are any BMMiner strings in any of the dict keys
|
||||
if any("BMMiner" in string for string in data["VERSION"][0].keys()):
|
||||
if any(
|
||||
"BMMiner" in string for string in data["VERSION"][0].keys()
|
||||
):
|
||||
api = "BMMiner"
|
||||
|
||||
# check if there are any CGMiner strings in any of the dict keys
|
||||
elif any("CGMiner" in string for string in data["VERSION"][0].keys()):
|
||||
elif any(
|
||||
"CGMiner" in string for string in data["VERSION"][0].keys()
|
||||
):
|
||||
api = "CGMiner"
|
||||
|
||||
# check if there are any BOSMiner strings in any of the dict keys
|
||||
elif any("BOSminer" in string for string in data["VERSION"][0].keys()):
|
||||
elif any(
|
||||
"BOSminer" in string for string in data["VERSION"][0].keys()
|
||||
):
|
||||
api = "BOSMiner"
|
||||
|
||||
# if all that fails, check the Description to see if it is a whatsminer
|
||||
elif data.get("Description") and "whatsminer" in data.get("Description"):
|
||||
elif data.get("Description") and "whatsminer" in data.get(
|
||||
"Description"
|
||||
):
|
||||
api = "BTMiner"
|
||||
|
||||
# return the API if we found it
|
||||
|
||||
Reference in New Issue
Block a user