added get_model to get the model of the miner, and reformatted the style of the miner factory getting miner to get a different miner for each type of supported miner
This commit is contained in:
@@ -10,3 +10,8 @@ class BaseMiner:
|
|||||||
def __init__(self, ip: str, api: BMMinerAPI | BOSMinerAPI | CGMinerAPI | BTMinerAPI | UnknownAPI) -> None:
|
def __init__(self, ip: str, api: BMMinerAPI | BOSMinerAPI | CGMinerAPI | BTMinerAPI | UnknownAPI) -> None:
|
||||||
self.ip = ipaddress.ip_address(ip)
|
self.ip = ipaddress.ip_address(ip)
|
||||||
self.api = api
|
self.api = api
|
||||||
|
self.api_type = None
|
||||||
|
self.model = None
|
||||||
|
|
||||||
|
def _init(self):
|
||||||
|
pass
|
||||||
|
|||||||
11
miners/antminer/S9/bmminer.py
Normal file
11
miners/antminer/S9/bmminer.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
from miners.bmminer import BMMiner
|
||||||
|
|
||||||
|
|
||||||
|
class BMMinerS9(BMMiner):
|
||||||
|
def __init__(self, ip: str) -> None:
|
||||||
|
super().__init__(ip)
|
||||||
|
self.model = "S9"
|
||||||
|
self.api_type = "BMMiner"
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f"BMMinerS9: {str(self.ip)}"
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
from miners import BaseMiner
|
|
||||||
from API.bosminer import BOSMinerAPI
|
|
||||||
import asyncssh
|
|
||||||
import toml
|
|
||||||
from config.bos import bos_config_convert, general_config_convert_bos
|
|
||||||
|
|
||||||
|
|
||||||
class BOSMinerS9(BaseMiner):
|
|
||||||
def __init__(self, ip: str) -> None:
|
|
||||||
api = BOSMinerAPI(ip)
|
|
||||||
super().__init__(ip, api)
|
|
||||||
self.config = None
|
|
||||||
self.uname = 'root'
|
|
||||||
self.pwd = 'admin'
|
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
|
||||||
return f"S9 - BOSminer: {str(self.ip)}"
|
|
||||||
|
|
||||||
async def _get_ssh_connection(self) -> asyncssh.connect:
|
|
||||||
"""Create a new asyncssh connection"""
|
|
||||||
conn = await asyncssh.connect(str(self.ip), known_hosts=None, username=self.uname, password=self.pwd,
|
|
||||||
server_host_key_algs=['ssh-rsa'])
|
|
||||||
# return created connection
|
|
||||||
return conn
|
|
||||||
|
|
||||||
async def send_ssh_command(self, cmd: str) -> None:
|
|
||||||
"""Sends SSH command to miner."""
|
|
||||||
# creates result variable
|
|
||||||
result = None
|
|
||||||
|
|
||||||
# runs the command on the miner
|
|
||||||
async with (await self._get_ssh_connection()) as conn:
|
|
||||||
# attempt to run command up to 3 times
|
|
||||||
for i in range(3):
|
|
||||||
try:
|
|
||||||
# save result of the command
|
|
||||||
result = await conn.run(cmd)
|
|
||||||
except Exception as e:
|
|
||||||
print(f"{cmd} error: {e}")
|
|
||||||
if i == 3:
|
|
||||||
return
|
|
||||||
continue
|
|
||||||
|
|
||||||
# let the user know the result of the command
|
|
||||||
if result is not None:
|
|
||||||
if result.stdout != "":
|
|
||||||
print(result.stdout)
|
|
||||||
if result.stderr != "":
|
|
||||||
print("ERROR: " + result.stderr)
|
|
||||||
elif result.stderr != "":
|
|
||||||
print("ERROR: " + result.stderr)
|
|
||||||
else:
|
|
||||||
print(cmd)
|
|
||||||
|
|
||||||
async def fault_light_on(self) -> None:
|
|
||||||
"""Sends command to turn on fault light on the miner."""
|
|
||||||
await self.send_ssh_command('miner fault_light on')
|
|
||||||
|
|
||||||
async def fault_light_off(self) -> None:
|
|
||||||
"""Sends command to turn off fault light on the miner."""
|
|
||||||
await self.send_ssh_command('miner fault_light off')
|
|
||||||
|
|
||||||
async def restart_backend(self) -> None:
|
|
||||||
"""Restart bosminer hashing process."""
|
|
||||||
await self.send_ssh_command('/etc/init.d/bosminer restart')
|
|
||||||
|
|
||||||
async def reboot(self) -> None:
|
|
||||||
"""Reboots power to the physical miner."""
|
|
||||||
await self.send_ssh_command('/sbin/reboot')
|
|
||||||
|
|
||||||
async def get_config(self) -> None:
|
|
||||||
async with (await self._get_ssh_connection()) as conn:
|
|
||||||
async with conn.start_sftp_client() as sftp:
|
|
||||||
async with sftp.open('/etc/bosminer.toml') as file:
|
|
||||||
toml_data = toml.loads(await file.read())
|
|
||||||
cfg = await bos_config_convert(toml_data)
|
|
||||||
self.config = cfg
|
|
||||||
|
|
||||||
async def get_hostname(self) -> str:
|
|
||||||
"""Attempts to get hostname from miner."""
|
|
||||||
try:
|
|
||||||
async with (await self._get_ssh_connection()) as conn:
|
|
||||||
data = await conn.run('cat /proc/sys/kernel/hostname')
|
|
||||||
return data.stdout.strip()
|
|
||||||
except Exception as e:
|
|
||||||
print(self.ip, e)
|
|
||||||
return "BOSMiner Unknown"
|
|
||||||
|
|
||||||
async def send_config(self, yaml_config) -> None:
|
|
||||||
"""Configures miner with yaml config."""
|
|
||||||
toml_conf = await general_config_convert_bos(yaml_config)
|
|
||||||
async with (await self._get_ssh_connection()) as conn:
|
|
||||||
async with conn.start_sftp_client() as sftp:
|
|
||||||
async with sftp.open('/etc/bosminer.toml', 'w+') as file:
|
|
||||||
await file.write(toml_conf)
|
|
||||||
await conn.run("/etc/init.d/bosminer restart")
|
|
||||||
|
|
||||||
async def get_bad_boards(self) -> list:
|
|
||||||
"""Checks for and provides list of non working boards."""
|
|
||||||
devs = await self.api.devdetails()
|
|
||||||
bad = 0
|
|
||||||
chains = devs['DEVDETAILS']
|
|
||||||
for chain in chains:
|
|
||||||
if chain['Chips'] == 0:
|
|
||||||
bad += 1
|
|
||||||
if bad > 0:
|
|
||||||
return [str(self.ip), bad]
|
|
||||||
|
|
||||||
async def check_good_boards(self) -> str:
|
|
||||||
"""Checks for and provides list for working boards."""
|
|
||||||
devs = await self.api.devdetails()
|
|
||||||
bad = 0
|
|
||||||
chains = devs['DEVDETAILS']
|
|
||||||
for chain in chains:
|
|
||||||
if chain['Chips'] == 0:
|
|
||||||
bad += 1
|
|
||||||
if not bad > 0:
|
|
||||||
return str(self.ip)
|
|
||||||
11
miners/antminer/S9/bosminer.py
Normal file
11
miners/antminer/S9/bosminer.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
from miners.bosminer import BOSminer
|
||||||
|
|
||||||
|
|
||||||
|
class BOSMinerS9(BOSminer):
|
||||||
|
def __init__(self, ip: str) -> None:
|
||||||
|
super().__init__(ip)
|
||||||
|
self.model = "S9"
|
||||||
|
self.api_type = "BOSMiner"
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f"BOSminerS9: {str(self.ip)}"
|
||||||
11
miners/antminer/S9/cgminer.py
Normal file
11
miners/antminer/S9/cgminer.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
from miners.cgminer import CGMiner
|
||||||
|
|
||||||
|
|
||||||
|
class CGMinerS9(CGMiner):
|
||||||
|
def __init__(self, ip: str) -> None:
|
||||||
|
super().__init__(ip)
|
||||||
|
self.model = "S9"
|
||||||
|
self.api_type = "CGMiner"
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f"CGMinerS9: {str(self.ip)}"
|
||||||
7
miners/antminer/X17/bmminer.py
Normal file
7
miners/antminer/X17/bmminer.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
from miners.bmminer import BMMiner
|
||||||
|
|
||||||
|
|
||||||
|
class BMMinerX17(BMMiner):
|
||||||
|
def __init__(self, ip: str) -> None:
|
||||||
|
super().__init__(ip)
|
||||||
|
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
from miners import BaseMiner
|
|
||||||
from API.bosminer import BOSMinerAPI
|
|
||||||
import asyncssh
|
|
||||||
import toml
|
|
||||||
from config.bos import bos_config_convert, general_config_convert_bos
|
|
||||||
|
|
||||||
|
|
||||||
class BOSMinerX17(BaseMiner):
|
|
||||||
def __init__(self, ip: str) -> None:
|
|
||||||
api = BOSMinerAPI(ip)
|
|
||||||
super().__init__(ip, api)
|
|
||||||
self.config = None
|
|
||||||
self.uname = 'root'
|
|
||||||
self.pwd = 'admin'
|
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
|
||||||
return f"X17 - BOSminer: {str(self.ip)}"
|
|
||||||
|
|
||||||
async def _get_ssh_connection(self) -> asyncssh.connect:
|
|
||||||
"""Create a new asyncssh connection"""
|
|
||||||
conn = await asyncssh.connect(str(self.ip), known_hosts=None, username=self.uname, password=self.pwd,
|
|
||||||
server_host_key_algs=['ssh-rsa'])
|
|
||||||
# return created connection
|
|
||||||
return conn
|
|
||||||
|
|
||||||
async def send_ssh_command(self, cmd: str) -> None:
|
|
||||||
"""Sends SSH command to miner."""
|
|
||||||
# creates result variable
|
|
||||||
result = None
|
|
||||||
|
|
||||||
# runs the command on the miner
|
|
||||||
async with (await self._get_ssh_connection()) as conn:
|
|
||||||
# attempt to run command up to 3 times
|
|
||||||
for i in range(3):
|
|
||||||
try:
|
|
||||||
# save result of the command
|
|
||||||
result = await conn.run(cmd)
|
|
||||||
except Exception as e:
|
|
||||||
print(f"{cmd} error: {e}")
|
|
||||||
if i == 3:
|
|
||||||
return
|
|
||||||
continue
|
|
||||||
|
|
||||||
# let the user know the result of the command
|
|
||||||
if result is not None:
|
|
||||||
if result.stdout != "":
|
|
||||||
print(result.stdout)
|
|
||||||
if result.stderr != "":
|
|
||||||
print("ERROR: " + result.stderr)
|
|
||||||
elif result.stderr != "":
|
|
||||||
print("ERROR: " + result.stderr)
|
|
||||||
else:
|
|
||||||
print(cmd)
|
|
||||||
|
|
||||||
async def fault_light_on(self) -> None:
|
|
||||||
"""Sends command to turn on fault light on the miner."""
|
|
||||||
await self.send_ssh_command('miner fault_light on')
|
|
||||||
|
|
||||||
async def fault_light_off(self) -> None:
|
|
||||||
"""Sends command to turn off fault light on the miner."""
|
|
||||||
await self.send_ssh_command('miner fault_light off')
|
|
||||||
|
|
||||||
async def restart_backend(self) -> None:
|
|
||||||
"""Restart bosminer hashing process."""
|
|
||||||
await self.send_ssh_command('/etc/init.d/bosminer restart')
|
|
||||||
|
|
||||||
async def reboot(self) -> None:
|
|
||||||
"""Reboots power to the physical miner."""
|
|
||||||
await self.send_ssh_command('/sbin/reboot')
|
|
||||||
|
|
||||||
async def get_config(self) -> None:
|
|
||||||
async with (await self._get_ssh_connection()) as conn:
|
|
||||||
async with conn.start_sftp_client() as sftp:
|
|
||||||
async with sftp.open('/etc/bosminer.toml') as file:
|
|
||||||
toml_data = toml.loads(await file.read())
|
|
||||||
cfg = await bos_config_convert(toml_data)
|
|
||||||
self.config = cfg
|
|
||||||
|
|
||||||
async def get_hostname(self) -> str:
|
|
||||||
"""Attempts to get hostname from miner."""
|
|
||||||
try:
|
|
||||||
async with (await self._get_ssh_connection()) as conn:
|
|
||||||
data = await conn.run('cat /proc/sys/kernel/hostname')
|
|
||||||
return data.stdout.strip()
|
|
||||||
except Exception as e:
|
|
||||||
print(self.ip, e)
|
|
||||||
return "BOSMiner Unknown"
|
|
||||||
|
|
||||||
async def send_config(self, yaml_config) -> None:
|
|
||||||
"""Configures miner with yaml config."""
|
|
||||||
toml_conf = await general_config_convert_bos(yaml_config)
|
|
||||||
async with (await self._get_ssh_connection()) as conn:
|
|
||||||
async with conn.start_sftp_client() as sftp:
|
|
||||||
async with sftp.open('/etc/bosminer.toml', 'w+') as file:
|
|
||||||
await file.write(toml_conf)
|
|
||||||
await conn.run("/etc/init.d/bosminer restart")
|
|
||||||
|
|
||||||
async def get_bad_boards(self) -> list:
|
|
||||||
"""Checks for and provides list of non working boards."""
|
|
||||||
devs = await self.api.devdetails()
|
|
||||||
bad = 0
|
|
||||||
chains = devs['DEVDETAILS']
|
|
||||||
for chain in chains:
|
|
||||||
if chain['Chips'] == 0:
|
|
||||||
bad += 1
|
|
||||||
if bad > 0:
|
|
||||||
return [str(self.ip), bad]
|
|
||||||
|
|
||||||
async def check_good_boards(self) -> str:
|
|
||||||
"""Checks for and provides list for working boards."""
|
|
||||||
devs = await self.api.devdetails()
|
|
||||||
bad = 0
|
|
||||||
chains = devs['DEVDETAILS']
|
|
||||||
for chain in chains:
|
|
||||||
if chain['Chips'] == 0:
|
|
||||||
bad += 1
|
|
||||||
if not bad > 0:
|
|
||||||
return str(self.ip)
|
|
||||||
10
miners/antminer/X17/bosminer.py
Normal file
10
miners/antminer/X17/bosminer.py
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
from miners.bosminer import BOSminer
|
||||||
|
|
||||||
|
|
||||||
|
class BOSMinerX17(BOSminer):
|
||||||
|
def __init__(self, ip: str) -> None:
|
||||||
|
super().__init__(ip)
|
||||||
|
self.api_type = "BOSMiner"
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f"BOSminerX17: {str(self.ip)}"
|
||||||
123
miners/antminer/X17/cgminer.py
Normal file
123
miners/antminer/X17/cgminer.py
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
from miners import BaseMiner
|
||||||
|
from API.cgminer import CGMinerAPI
|
||||||
|
import asyncssh
|
||||||
|
|
||||||
|
|
||||||
|
class CGMinerX17(BaseMiner):
|
||||||
|
def __init__(self, ip: str) -> None:
|
||||||
|
api = CGMinerAPI(ip)
|
||||||
|
super().__init__(ip, api)
|
||||||
|
self.config = None
|
||||||
|
self.uname = 'root'
|
||||||
|
self.pwd = 'admin'
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f"CGMiner: {str(self.ip)}"
|
||||||
|
|
||||||
|
async def get_hostname(self) -> str:
|
||||||
|
try:
|
||||||
|
async with (await self._get_ssh_connection()) as conn:
|
||||||
|
if conn is not None:
|
||||||
|
data = await conn.run('cat /proc/sys/kernel/hostname')
|
||||||
|
return data.stdout.strip()
|
||||||
|
else:
|
||||||
|
return "CGMiner Unknown"
|
||||||
|
except Exception:
|
||||||
|
return "CGMiner Unknown"
|
||||||
|
|
||||||
|
async def send_config(self, _):
|
||||||
|
return None # ignore for now
|
||||||
|
|
||||||
|
async def _get_ssh_connection(self) -> asyncssh.connect:
|
||||||
|
try:
|
||||||
|
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'])
|
||||||
|
return conn
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
except OSError:
|
||||||
|
print(str(self.ip) + " Connection refused.")
|
||||||
|
return None
|
||||||
|
|
||||||
|
async def send_ssh_command(self, cmd):
|
||||||
|
result = None
|
||||||
|
async with (await self._get_ssh_connection()) as conn:
|
||||||
|
for i in range(3):
|
||||||
|
try:
|
||||||
|
result = await conn.run(cmd)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"{cmd} error: {e}")
|
||||||
|
if i == 3:
|
||||||
|
return
|
||||||
|
continue
|
||||||
|
# handle result
|
||||||
|
self._result_handler(result)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _result_handler(result: asyncssh.process.SSHCompletedProcess) -> None:
|
||||||
|
if result is not None:
|
||||||
|
# noinspection PyUnresolvedReferences
|
||||||
|
if len(result.stdout) > 0:
|
||||||
|
# noinspection PyUnresolvedReferences
|
||||||
|
print("ssh stdout: \n" + result.stdout)
|
||||||
|
# noinspection PyUnresolvedReferences
|
||||||
|
if len(result.stderr) > 0:
|
||||||
|
# noinspection PyUnresolvedReferences
|
||||||
|
print("ssh stderr: \n" + result.stderrr)
|
||||||
|
# noinspection PyUnresolvedReferences
|
||||||
|
if len(result.stdout) <= 0 and len(result.stderr) <= 0:
|
||||||
|
print("ssh stdout stderr empty")
|
||||||
|
# if result.stdout != "":
|
||||||
|
# print(result.stdout)
|
||||||
|
# if result.stderr != "":
|
||||||
|
# print("ERROR: " + result.stderr)
|
||||||
|
# elif result.stderr != "":
|
||||||
|
# print("ERROR: " + result.stderr)
|
||||||
|
# else:
|
||||||
|
# print(cmd)
|
||||||
|
|
||||||
|
async def restart_cgminer(self) -> None:
|
||||||
|
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:
|
||||||
|
commands = ['reboot']
|
||||||
|
commands = ';'.join(commands)
|
||||||
|
await self.send_ssh_command(commands)
|
||||||
|
|
||||||
|
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)
|
||||||
|
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)
|
||||||
|
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'
|
||||||
|
result = await conn.run(command, check=True)
|
||||||
|
self._result_handler(result)
|
||||||
|
self.config = result.stdout
|
||||||
|
print(str(self.config))
|
||||||
26
miners/antminer/X19/bmminer.py
Normal file
26
miners/antminer/X19/bmminer.py
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
from API.bmminer import BMMinerAPI
|
||||||
|
from miners import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
|
class BMMinerX19(BaseMiner):
|
||||||
|
def __init__(self, ip: str) -> None:
|
||||||
|
api = BMMinerAPI(ip)
|
||||||
|
super().__init__(ip, api)
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f"BMMiner: {str(self.ip)}"
|
||||||
|
|
||||||
|
async def get_hostname(self) -> str:
|
||||||
|
return "BMMiner Unknown"
|
||||||
|
|
||||||
|
async def send_config(self, _):
|
||||||
|
return None # ignore for now
|
||||||
|
|
||||||
|
async def restart_backend(self) -> None:
|
||||||
|
return None # Murray
|
||||||
|
|
||||||
|
async def reboot(self) -> None:
|
||||||
|
return None # Murray
|
||||||
|
|
||||||
|
async def get_config(self) -> None:
|
||||||
|
return None # Murray
|
||||||
123
miners/antminer/X19/cgminer.py
Normal file
123
miners/antminer/X19/cgminer.py
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
from miners import BaseMiner
|
||||||
|
from API.cgminer import CGMinerAPI
|
||||||
|
import asyncssh
|
||||||
|
|
||||||
|
|
||||||
|
class CGMinerX19(BaseMiner):
|
||||||
|
def __init__(self, ip: str) -> None:
|
||||||
|
api = CGMinerAPI(ip)
|
||||||
|
super().__init__(ip, api)
|
||||||
|
self.config = None
|
||||||
|
self.uname = 'root'
|
||||||
|
self.pwd = 'admin'
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f"CGMiner: {str(self.ip)}"
|
||||||
|
|
||||||
|
async def get_hostname(self) -> str:
|
||||||
|
try:
|
||||||
|
async with (await self._get_ssh_connection()) as conn:
|
||||||
|
if conn is not None:
|
||||||
|
data = await conn.run('cat /proc/sys/kernel/hostname')
|
||||||
|
return data.stdout.strip()
|
||||||
|
else:
|
||||||
|
return "CGMiner Unknown"
|
||||||
|
except Exception:
|
||||||
|
return "CGMiner Unknown"
|
||||||
|
|
||||||
|
async def send_config(self, _):
|
||||||
|
return None # ignore for now
|
||||||
|
|
||||||
|
async def _get_ssh_connection(self) -> asyncssh.connect:
|
||||||
|
try:
|
||||||
|
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'])
|
||||||
|
return conn
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
except OSError:
|
||||||
|
print(str(self.ip) + " Connection refused.")
|
||||||
|
return None
|
||||||
|
|
||||||
|
async def send_ssh_command(self, cmd):
|
||||||
|
result = None
|
||||||
|
async with (await self._get_ssh_connection()) as conn:
|
||||||
|
for i in range(3):
|
||||||
|
try:
|
||||||
|
result = await conn.run(cmd)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"{cmd} error: {e}")
|
||||||
|
if i == 3:
|
||||||
|
return
|
||||||
|
continue
|
||||||
|
# handle result
|
||||||
|
self._result_handler(result)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _result_handler(result: asyncssh.process.SSHCompletedProcess) -> None:
|
||||||
|
if result is not None:
|
||||||
|
# noinspection PyUnresolvedReferences
|
||||||
|
if len(result.stdout) > 0:
|
||||||
|
# noinspection PyUnresolvedReferences
|
||||||
|
print("ssh stdout: \n" + result.stdout)
|
||||||
|
# noinspection PyUnresolvedReferences
|
||||||
|
if len(result.stderr) > 0:
|
||||||
|
# noinspection PyUnresolvedReferences
|
||||||
|
print("ssh stderr: \n" + result.stderrr)
|
||||||
|
# noinspection PyUnresolvedReferences
|
||||||
|
if len(result.stdout) <= 0 and len(result.stderr) <= 0:
|
||||||
|
print("ssh stdout stderr empty")
|
||||||
|
# if result.stdout != "":
|
||||||
|
# print(result.stdout)
|
||||||
|
# if result.stderr != "":
|
||||||
|
# print("ERROR: " + result.stderr)
|
||||||
|
# elif result.stderr != "":
|
||||||
|
# print("ERROR: " + result.stderr)
|
||||||
|
# else:
|
||||||
|
# print(cmd)
|
||||||
|
|
||||||
|
async def restart_cgminer(self) -> None:
|
||||||
|
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:
|
||||||
|
commands = ['reboot']
|
||||||
|
commands = ';'.join(commands)
|
||||||
|
await self.send_ssh_command(commands)
|
||||||
|
|
||||||
|
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)
|
||||||
|
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)
|
||||||
|
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'
|
||||||
|
result = await conn.run(command, check=True)
|
||||||
|
self._result_handler(result)
|
||||||
|
self.config = result.stdout
|
||||||
|
print(str(self.config))
|
||||||
@@ -86,6 +86,12 @@ class BOSminer(BaseMiner):
|
|||||||
print(self.ip, e)
|
print(self.ip, e)
|
||||||
return "BOSMiner Unknown"
|
return "BOSMiner Unknown"
|
||||||
|
|
||||||
|
async def get_model(self):
|
||||||
|
version_data = await self.api.devdetails()
|
||||||
|
if version_data:
|
||||||
|
return version_data["DEVDETAILS"][0]["Model"].replace("Antminer ", "")
|
||||||
|
return None
|
||||||
|
|
||||||
async def send_config(self, yaml_config) -> None:
|
async def send_config(self, yaml_config) -> None:
|
||||||
"""Configures miner with yaml config."""
|
"""Configures miner with yaml config."""
|
||||||
toml_conf = await general_config_convert_bos(yaml_config)
|
toml_conf = await general_config_convert_bos(yaml_config)
|
||||||
|
|||||||
@@ -1,5 +1,14 @@
|
|||||||
from miners.antminer.S9.bos import BOSMinerS9
|
from miners.antminer.S9.bosminer import BOSMinerS9
|
||||||
from miners.antminer.X17.bos import BOSMinerX17
|
from miners.antminer.S9.bmminer import BMMinerS9
|
||||||
|
from miners.antminer.S9.cgminer import CGMinerS9
|
||||||
|
|
||||||
|
|
||||||
|
from miners.antminer.X17.bosminer import BOSMinerX17
|
||||||
|
from miners.antminer.X17.bmminer import BMMinerX17
|
||||||
|
from miners.antminer.X17.cgminer import CGMinerX17
|
||||||
|
|
||||||
|
from miners.antminer.X19.bmminer import BMMinerX19
|
||||||
|
from miners.antminer.X19.cgminer import CGMinerX19
|
||||||
|
|
||||||
from miners.whatsminer.M20 import BTMinerM20
|
from miners.whatsminer.M20 import BTMinerM20
|
||||||
from miners.whatsminer.M21 import BTMinerM21
|
from miners.whatsminer.M21 import BTMinerM21
|
||||||
@@ -7,10 +16,8 @@ from miners.whatsminer.M30 import BTMinerM30
|
|||||||
from miners.whatsminer.M31 import BTMinerM31
|
from miners.whatsminer.M31 import BTMinerM31
|
||||||
from miners.whatsminer.M32 import BTMinerM32
|
from miners.whatsminer.M32 import BTMinerM32
|
||||||
|
|
||||||
from miners.bosminer import BOSminer
|
|
||||||
from miners.bmminer import BMMiner
|
from miners.bmminer import BMMiner
|
||||||
from miners.cgminer import CGMiner
|
from miners.cgminer import CGMiner
|
||||||
from miners.btminer import BTMiner
|
|
||||||
from miners.unknown import UnknownMiner
|
from miners.unknown import UnknownMiner
|
||||||
from API import APIError
|
from API import APIError
|
||||||
import asyncio
|
import asyncio
|
||||||
@@ -41,7 +48,7 @@ class MinerFactory:
|
|||||||
for miner in scanned:
|
for miner in scanned:
|
||||||
yield await miner
|
yield await miner
|
||||||
|
|
||||||
async def get_miner(self, ip: ipaddress.ip_address) -> BOSminer or CGMiner or BMMiner or BTMiner or UnknownMiner:
|
async def get_miner(self, ip: ipaddress.ip_address):
|
||||||
"""Decide a miner type using the IP address of the miner."""
|
"""Decide a miner type using the IP address of the miner."""
|
||||||
# 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:
|
||||||
@@ -63,21 +70,21 @@ class MinerFactory:
|
|||||||
if "BOSMiner" in api:
|
if "BOSMiner" in api:
|
||||||
miner = BOSMinerS9(str(ip))
|
miner = BOSMinerS9(str(ip))
|
||||||
elif "CGMiner" in api:
|
elif "CGMiner" in api:
|
||||||
miner = CGMiner(str(ip))
|
miner = CGMinerS9(str(ip))
|
||||||
elif "BMMiner" in api:
|
elif "BMMiner" in api:
|
||||||
miner = BMMiner(str(ip))
|
miner = BMMinerS9(str(ip))
|
||||||
elif "17" in model:
|
elif "17" in model:
|
||||||
if "BOSMiner" in api:
|
if "BOSMiner" in api:
|
||||||
miner = BOSMinerX17(str(ip))
|
miner = BOSMinerX17(str(ip))
|
||||||
elif "CGMiner" in api:
|
elif "CGMiner" in api:
|
||||||
miner = CGMiner(str(ip))
|
miner = CGMinerX17(str(ip))
|
||||||
elif "BMMiner" in api:
|
elif "BMMiner" in api:
|
||||||
miner = BMMiner(str(ip))
|
miner = BMMinerX17(str(ip))
|
||||||
elif "19" in model:
|
elif "19" in model:
|
||||||
if "CGMiner" in api:
|
if "CGMiner" in api:
|
||||||
miner = CGMiner(str(ip))
|
miner = CGMinerX19(str(ip))
|
||||||
elif "BMMiner" in api:
|
elif "BMMiner" in api:
|
||||||
miner = BMMiner(str(ip))
|
miner = BMMinerX19(str(ip))
|
||||||
elif "M20" in model:
|
elif "M20" in model:
|
||||||
miner = BTMinerM20(str(ip))
|
miner = BTMinerM20(str(ip))
|
||||||
elif "M21" in model:
|
elif "M21" in model:
|
||||||
@@ -117,6 +124,7 @@ class MinerFactory:
|
|||||||
print(ip, e)
|
print(ip, e)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
async def _send_api_command(self, ip: ipaddress.ip_address or str, command: str):
|
async def _send_api_command(self, ip: ipaddress.ip_address or str, command: str):
|
||||||
try:
|
try:
|
||||||
# get reader and writer streams
|
# get reader and writer streams
|
||||||
|
|||||||
Reference in New Issue
Block a user