Compare commits
56 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3d265e823b | ||
|
|
5e6bc8c8ef | ||
|
|
871499b77f | ||
|
|
117a161fd5 | ||
|
|
40bacbf41c | ||
|
|
e091863aa7 | ||
|
|
85e8ac63f1 | ||
|
|
a5252e3a84 | ||
|
|
404d6590db | ||
|
|
1d04399daf | ||
|
|
03ebcacca5 | ||
|
|
75934fd7fe | ||
|
|
bbeca15799 | ||
|
|
45befb569b | ||
|
|
61334ed99e | ||
|
|
2bf059df01 | ||
|
|
9c2de26182 | ||
|
|
714983cddc | ||
|
|
191f1d24b9 | ||
|
|
5a0bafb964 | ||
|
|
67aedd319d | ||
|
|
44012c50d6 | ||
|
|
06540efc98 | ||
|
|
9d0d1a24d9 | ||
|
|
8568f91482 | ||
|
|
64918e5552 | ||
|
|
53d5ecd04a | ||
|
|
1b0e80a418 | ||
|
|
9ad506a313 | ||
|
|
18c4bbd09c | ||
|
|
0d123d5dd8 | ||
|
|
b9b91293fe | ||
|
|
47a702c94c | ||
|
|
6d5a288120 | ||
|
|
038aae95ac | ||
|
|
dd84aede25 | ||
|
|
dc8ad271de | ||
|
|
b78c1cdca5 | ||
|
|
0eb7ced932 | ||
|
|
8e58f4492f | ||
|
|
95fb32de19 | ||
|
|
5145dc19f8 | ||
|
|
1808d62bba | ||
|
|
97ef4dfe37 | ||
|
|
174a132e75 | ||
|
|
84d6e58ebe | ||
|
|
e9a1483e5f | ||
|
|
4eb51eed20 | ||
|
|
066fc1a4b3 | ||
|
|
cc24236c0a | ||
|
|
564cd42eae | ||
|
|
8677eff491 | ||
|
|
63a21ea9aa | ||
|
|
1c9d3dc84d | ||
|
|
0dacd3d294 | ||
|
|
6fa74613b4 |
@@ -193,6 +193,8 @@ If you are sure you want to use this command please use API.send_command("{item}
|
||||
str_data = str_data.replace("}{", "},{")
|
||||
# fix an error with a bmminer return having a specific comma that breaks json.loads()
|
||||
str_data = str_data.replace("[,{", "[{")
|
||||
# fix an error with a btminer return having a specific comma that breaks json.loads()
|
||||
str_data = str_data.replace("inf", "0")
|
||||
# parse the json
|
||||
parsed_data = json.loads(str_data)
|
||||
# handle bad json
|
||||
|
||||
106
README.md
106
README.md
@@ -18,7 +18,7 @@ if __name__ == '__main__':
|
||||
main()
|
||||
```
|
||||
2. Make a build of the CFG Util for your system using cx_freeze and ```make_cfg_tool_exe.py```
|
||||
(Alternatively, you can get a build made by me here -> https://drive.google.com/drive/folders/1nzojuGRu0IszIGpwx7SvG5RlJ2_KXIOv)
|
||||
(Alternatively, you can get a build made by me here -> https://drive.google.com/drive/folders/147vBXbuaX85inataXeSAiKk8IKf-7xtR)
|
||||
1. Open either Command Prompt on Windows or Terminal on Mac or UNIX.
|
||||
2. Navigate to this directory, and run ```make_cfg_tool_exe.py build``` on Windows or ```python3 make_cfg_tool_exe.py``` on Mac or UNIX.
|
||||
|
||||
@@ -102,57 +102,6 @@ async def get_miner_hashrate(ip: str):
|
||||
print(data)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
asyncio.new_event_loop().run_until_complete(
|
||||
get_miner_hashrate(str("192.168.1.69")))
|
||||
```
|
||||
|
||||
<br>
|
||||
Or generate a miner directly without the factory:
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
from miners.bosminer import BOSMiner
|
||||
from tools.cfg_util_old.func.parse_data import safe_parse_api_data
|
||||
|
||||
|
||||
async def get_miner_hashrate(ip: str):
|
||||
# Create a BOSminer miner object
|
||||
miner = BOSMiner(ip)
|
||||
# Get the API data
|
||||
summary = await miner.api.summary()
|
||||
# safe_parse_api_data parses the data from a miner API
|
||||
# It will raise an APIError (from API import APIError) if there is a problem
|
||||
data = await safe_parse_api_data(summary, 'SUMMARY', 0, 'MHS 5s')
|
||||
print(data)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
asyncio.new_event_loop().run_until_complete(
|
||||
get_miner_hashrate(str("192.168.1.69")))
|
||||
```
|
||||
|
||||
<br>
|
||||
Or finally, just get the API directly:
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
from API.bosminer import BOSMinerAPI
|
||||
from tools.cfg_util_old.func.parse_data import safe_parse_api_data
|
||||
|
||||
|
||||
async def get_miner_hashrate(ip: str):
|
||||
# Create a BOSminerAPI object
|
||||
# Port can be declared manually, if not it defaults to 4028
|
||||
api = BOSMinerAPI(ip, port=4028)
|
||||
# Get the API data
|
||||
summary = await api.summary()
|
||||
# safe_parse_api_data parses the data from a miner API
|
||||
# It will raise an APIError (from API import APIError) if there is a problem
|
||||
data = await safe_parse_api_data(summary, 'SUMMARY', 0, 'MHS 5s')
|
||||
print(data)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
asyncio.new_event_loop().run_until_complete(
|
||||
get_miner_hashrate(str("192.168.1.69")))
|
||||
@@ -162,13 +111,40 @@ if __name__ == '__main__':
|
||||
Now that you know that, lets move on to some common API functions that you might want to use.
|
||||
|
||||
### Common commands:
|
||||
* Get the data used by the config utility, this includes pool data, wattage use, temperature, hashrate, etc:
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
import ipaddress
|
||||
from miners.miner_factory import MinerFactory
|
||||
|
||||
|
||||
async def get_miner_pool_data(ip: str):
|
||||
# Instantiate a Miner Factory to generate miners from their IP
|
||||
miner_factory = MinerFactory()
|
||||
# Make the string IP into an IP address
|
||||
miner_ip = ipaddress.ip_address(ip)
|
||||
# Wait for the factory to return the miner
|
||||
miner = await miner_factory.get_miner(miner_ip)
|
||||
# Get the data
|
||||
data = await miner.get_data()
|
||||
|
||||
print(data)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
asyncio.new_event_loop().run_until_complete(
|
||||
get_miner_pool_data(str("192.168.1.69")))
|
||||
```
|
||||
|
||||
|
||||
|
||||
* Getting pool data:
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
import ipaddress
|
||||
from miners.miner_factory import MinerFactory
|
||||
from tools.cfg_util_old.func.parse_data import safe_parse_api_data
|
||||
|
||||
|
||||
async def get_miner_pool_data(ip: str):
|
||||
@@ -182,7 +158,7 @@ async def get_miner_pool_data(ip: str):
|
||||
pools = await miner.api.pools()
|
||||
# safe_parse_api_data parses the data from a miner API
|
||||
# It will raise an APIError (from API import APIError) if there is a problem
|
||||
data = await safe_parse_api_data(pools, 'POOLS')
|
||||
data = pools["POOLS"]
|
||||
# parse further from here to get all the pool info you want.
|
||||
# each pool is on a different index eg:
|
||||
# data[0] is pool 1
|
||||
@@ -208,7 +184,6 @@ A pretty good example of really trying to make this robust is in ```cfg_util.fun
|
||||
import asyncio
|
||||
import ipaddress
|
||||
from miners.miner_factory import MinerFactory
|
||||
from tools.cfg_util_old.func.parse_data import safe_parse_api_data
|
||||
|
||||
|
||||
async def get_miner_temperature_data(ip: str):
|
||||
@@ -220,9 +195,8 @@ async def get_miner_temperature_data(ip: str):
|
||||
miner = await miner_factory.get_miner(miner_ip)
|
||||
# Get the API data
|
||||
summary = await miner.api.summary()
|
||||
# safe_parse_api_data parses the data from a miner API
|
||||
# It will raise an APIError (from API import APIError) if there is a problem
|
||||
data = await safe_parse_api_data(summary, 'SUMMARY', 0, "Temperature")
|
||||
|
||||
data = summary['SUMMARY'][0]["Temperature"]
|
||||
print(data)
|
||||
|
||||
|
||||
@@ -239,10 +213,10 @@ How about data on the power usage of the miner? This one only works for Whatsmi
|
||||
import asyncio
|
||||
import ipaddress
|
||||
from miners.miner_factory import MinerFactory
|
||||
from tools.cfg_util_old.func.parse_data import safe_parse_api_data
|
||||
|
||||
|
||||
async def get_miner_power_data(ip: str):
|
||||
data = None
|
||||
# Instantiate a Miner Factory to generate miners from their IP
|
||||
miner_factory = MinerFactory()
|
||||
# Make the string IP into an IP address
|
||||
@@ -254,16 +228,16 @@ async def get_miner_power_data(ip: str):
|
||||
# send the command
|
||||
tunerstatus = await miner.api.tunerstatus()
|
||||
# parse the return
|
||||
data = await safe_parse_api_data(tunerstatus, 'TUNERSTATUS', 0,
|
||||
"PowerLimit")
|
||||
data = tunerstatus['TUNERSTATUS'][0]["PowerLimit"]
|
||||
else:
|
||||
# send the command
|
||||
# whatsminers have the power info in summary
|
||||
summary = await miner.api.summary()
|
||||
# parse the return
|
||||
data = await safe_parse_api_data(summary, 'SUMMARY', 0, "Power")
|
||||
data = summary['SUMMARY'][0]["Power"]
|
||||
|
||||
print(data)
|
||||
if data:
|
||||
print(data)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
@@ -293,12 +267,10 @@ async def get_miner_hashrate_and_pool(ip: str):
|
||||
# Get the API data
|
||||
api_data = await miner.api.multicommand("pools", "summary")
|
||||
if "pools" in api_data.keys():
|
||||
user = await safe_parse_api_data(api_data, "pools", 0, "POOLS", 0,
|
||||
"User")
|
||||
user = api_data["pools"][0]["POOLS"][0]["User"]
|
||||
print(user)
|
||||
if "summary" in api_data.keys():
|
||||
hashrate = await safe_parse_api_data(api_data, "summary", 0, "SUMMARY",
|
||||
0, "MHS av")
|
||||
hashrate = api_data["summary"][0]["SUMMARY"][0]["MHS av"]
|
||||
print(hashrate)
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
from tools.bad_board_util import main
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,44 +0,0 @@
|
||||
"""
|
||||
Make a build of the board tool.
|
||||
|
||||
Usage: make_board_tool_exe.py build
|
||||
|
||||
The build will show up in the build directory.
|
||||
"""
|
||||
import datetime
|
||||
import sys
|
||||
import os
|
||||
from cx_Freeze import setup, Executable
|
||||
|
||||
base = None
|
||||
if sys.platform == "win32":
|
||||
base = "Win32GUI"
|
||||
|
||||
version = datetime.datetime.now()
|
||||
version = version.strftime("%y.%m.%d")
|
||||
print(version)
|
||||
|
||||
|
||||
setup(
|
||||
name="UpstreamBoardUtil.exe",
|
||||
version=version,
|
||||
description="Upstream Data Board Utility Build",
|
||||
options={
|
||||
"build_exe": {
|
||||
"build_exe": f"{os.getcwd()}\\build\\board_util\\UpstreamBoardUtil-{version}-{sys.platform}\\",
|
||||
"include_files": [
|
||||
os.path.join(os.getcwd(), "settings/settings.toml"),
|
||||
],
|
||||
"include_msvcr": True,
|
||||
"add_to_path": True,
|
||||
},
|
||||
},
|
||||
executables=[
|
||||
Executable(
|
||||
"board_util.py",
|
||||
base=base,
|
||||
icon="icon.ico",
|
||||
target_name="UpstreamBoardUtil.exe",
|
||||
)
|
||||
],
|
||||
)
|
||||
@@ -1,28 +1,22 @@
|
||||
from API.bmminer import BMMinerAPI
|
||||
from API.bosminer import BOSMinerAPI
|
||||
from API.cgminer import CGMinerAPI
|
||||
from API.btminer import BTMinerAPI
|
||||
from API.unknown import UnknownAPI
|
||||
import ipaddress
|
||||
import asyncssh
|
||||
import logging
|
||||
|
||||
|
||||
class BaseMiner:
|
||||
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
|
||||
self.api = api
|
||||
def __init__(self, *args) -> None:
|
||||
self.ip = None
|
||||
self.uname = "root"
|
||||
self.pwd = "admin"
|
||||
self.api = None
|
||||
self.api_type = None
|
||||
self.model = None
|
||||
self.light = None
|
||||
self.hostname = None
|
||||
self.nominal_chips = 1
|
||||
self.version = None
|
||||
|
||||
def __repr__(self):
|
||||
return f"{'' if not self.api_type else self.api_type} {'' if not self.model else self.model}: {str(self.ip)}"
|
||||
|
||||
async def _get_ssh_connection(self) -> asyncssh.connect:
|
||||
"""Create a new asyncssh connection"""
|
||||
@@ -40,7 +34,7 @@ class BaseMiner:
|
||||
conn = await asyncssh.connect(
|
||||
str(self.ip),
|
||||
known_hosts=None,
|
||||
username="admin",
|
||||
username="root",
|
||||
password="admin",
|
||||
server_host_key_algs=["ssh-rsa"],
|
||||
)
|
||||
@@ -48,9 +42,9 @@ class BaseMiner:
|
||||
except Exception as e:
|
||||
# logging.warning(f"{self} raised an exception: {e}")
|
||||
raise e
|
||||
except OSError:
|
||||
except OSError as e:
|
||||
logging.warning(f"Connection refused: {self}")
|
||||
return None
|
||||
raise e
|
||||
except Exception as e:
|
||||
# logging.warning(f"{self} raised an exception: {e}")
|
||||
raise e
|
||||
@@ -89,6 +83,9 @@ class BaseMiner:
|
||||
async def send_config(self, *args, **kwargs):
|
||||
return None
|
||||
|
||||
async def get_mac(self):
|
||||
return None
|
||||
|
||||
async def get_data(self):
|
||||
data = {
|
||||
"IP": str(self.ip),
|
||||
|
||||
5
miners/_backends/__init__.py
Normal file
5
miners/_backends/__init__.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from .bmminer import BMMiner
|
||||
from .bosminer import BOSMiner
|
||||
from .btminer import BTMiner
|
||||
from .cgminer import CGMiner
|
||||
from .hiveon import Hiveon
|
||||
@@ -6,16 +6,13 @@ from settings import MINER_FACTORY_GET_VERSION_RETRIES as DATA_RETRIES
|
||||
|
||||
class BMMiner(BaseMiner):
|
||||
def __init__(self, ip: str) -> None:
|
||||
api = BMMinerAPI(ip)
|
||||
super().__init__(ip, api)
|
||||
self.model = None
|
||||
self.config = None
|
||||
super().__init__(ip)
|
||||
self.ip = ip
|
||||
self.api = BMMinerAPI(ip)
|
||||
self.api_type = "BMMiner"
|
||||
self.uname = "root"
|
||||
self.pwd = "admin"
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"BMMiner: {str(self.ip)}"
|
||||
|
||||
async def get_model(self) -> str or None:
|
||||
"""Get miner model.
|
||||
|
||||
@@ -133,7 +130,13 @@ class BMMiner(BaseMiner):
|
||||
"Temperature": 0,
|
||||
"Pool User": "Unknown",
|
||||
"Wattage": 0,
|
||||
"Split": 0,
|
||||
"Total": 0,
|
||||
"Ideal": self.nominal_chips * 3,
|
||||
"Left Board": 0,
|
||||
"Center Board": 0,
|
||||
"Right Board": 0,
|
||||
"Nominal": False,
|
||||
"Split": "0",
|
||||
"Pool 1": "Unknown",
|
||||
"Pool 1 User": "Unknown",
|
||||
"Pool 2": "",
|
||||
@@ -166,10 +169,22 @@ class BMMiner(BaseMiner):
|
||||
hr = summary.get("SUMMARY")
|
||||
if hr:
|
||||
if len(hr) > 0:
|
||||
hr = hr[0].get("GHS 5s")
|
||||
hr = hr[0].get("GHS av")
|
||||
if hr:
|
||||
data["Hashrate"] = round(hr / 1000, 2)
|
||||
|
||||
if stats:
|
||||
boards = stats.get("STATS")
|
||||
if boards:
|
||||
if len(boards) > 0:
|
||||
data["Left Board"] = boards[1].get("chain_acn1")
|
||||
data["Center Board"] = boards[1].get("chain_acn2")
|
||||
data["Right Board"] = boards[1].get("chain_acn3")
|
||||
data["Total"] = boards[1].get("total_acn")
|
||||
|
||||
if data["Total"] == data["Ideal"]:
|
||||
data["Nominal"] = True
|
||||
|
||||
if stats:
|
||||
temp = stats.get("STATS")
|
||||
if temp:
|
||||
@@ -8,17 +8,12 @@ from settings import MINER_FACTORY_GET_VERSION_RETRIES as DATA_RETRIES
|
||||
|
||||
class BOSMiner(BaseMiner):
|
||||
def __init__(self, ip: str) -> None:
|
||||
api = BOSMinerAPI(ip)
|
||||
super().__init__(ip, api)
|
||||
self.model = None
|
||||
self.config = None
|
||||
self.version = None
|
||||
super().__init__(ip)
|
||||
self.ip = ip
|
||||
self.api = BOSMinerAPI(ip)
|
||||
self.api_type = "BOSMiner"
|
||||
self.uname = "root"
|
||||
self.pwd = "admin"
|
||||
self.nominal_chips = 63
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"BOSminer: {str(self.ip)}"
|
||||
|
||||
async def send_ssh_command(self, cmd: str) -> str or None:
|
||||
"""Send a command to the miner over ssh.
|
||||
@@ -202,6 +197,10 @@ class BOSMiner(BaseMiner):
|
||||
offset = devs[0]["ID"]
|
||||
for board in devs:
|
||||
boards[board["ID"] - offset] = []
|
||||
if not board["Chips"] == self.nominal_chips:
|
||||
nominal = False
|
||||
else:
|
||||
nominal = True
|
||||
if not board["Chips"] == self.nominal_chips:
|
||||
nominal = False
|
||||
else:
|
||||
@@ -249,6 +248,12 @@ class BOSMiner(BaseMiner):
|
||||
"Temperature": 0,
|
||||
"Pool User": "Unknown",
|
||||
"Wattage": 0,
|
||||
"Total": 0,
|
||||
"Ideal": self.nominal_chips * 3,
|
||||
"Left Board": 0,
|
||||
"Center Board": 0,
|
||||
"Right Board": 0,
|
||||
"Nominal": False,
|
||||
"Split": "0",
|
||||
"Pool 1": "Unknown",
|
||||
"Pool 1 User": "Unknown",
|
||||
@@ -267,7 +272,7 @@ class BOSMiner(BaseMiner):
|
||||
miner_data = None
|
||||
for i in range(DATA_RETRIES):
|
||||
miner_data = await self.api.multicommand(
|
||||
"summary", "temps", "tunerstatus", "pools"
|
||||
"summary", "temps", "tunerstatus", "pools", "devdetails"
|
||||
)
|
||||
if miner_data:
|
||||
break
|
||||
@@ -277,12 +282,13 @@ class BOSMiner(BaseMiner):
|
||||
temps = miner_data.get("temps")[0]
|
||||
tunerstatus = miner_data.get("tunerstatus")[0]
|
||||
pools = miner_data.get("pools")[0]
|
||||
devdetails = miner_data.get("devdetails")[0]
|
||||
|
||||
if summary:
|
||||
hr = summary.get("SUMMARY")
|
||||
if hr:
|
||||
if len(hr) > 0:
|
||||
hr = hr[0].get("MHS 5s")
|
||||
hr = hr[0].get("MHS av")
|
||||
if hr:
|
||||
data["Hashrate"] = round(hr / 1000000, 2)
|
||||
|
||||
@@ -347,4 +353,23 @@ class BOSMiner(BaseMiner):
|
||||
if wattage:
|
||||
data["Wattage"] = wattage
|
||||
|
||||
if devdetails:
|
||||
boards = devdetails.get("DEVDETAILS")
|
||||
if boards:
|
||||
if len(boards) > 0:
|
||||
board_map = {0: "Left Board", 1: "Center Board", 2: "Right Board"}
|
||||
offset = boards[0]["ID"]
|
||||
for board in boards:
|
||||
id = board["ID"] - offset
|
||||
chips = board["Chips"]
|
||||
data["Total"] += chips
|
||||
data[board_map[id]] = chips
|
||||
|
||||
if data["Total"] == data["Ideal"]:
|
||||
data["Nominal"] = True
|
||||
|
||||
return data
|
||||
|
||||
async def get_mac(self):
|
||||
result = await self.send_ssh_command("cat /sys/class/net/eth0/address")
|
||||
return result.upper()
|
||||
46
miners/_backends/bosminer_old.py
Normal file
46
miners/_backends/bosminer_old.py
Normal file
@@ -0,0 +1,46 @@
|
||||
from miners import BaseMiner
|
||||
from API.bosminer import BOSMinerAPI
|
||||
import toml
|
||||
from config.bos import bos_config_convert, general_config_convert_bos
|
||||
import logging
|
||||
from settings import MINER_FACTORY_GET_VERSION_RETRIES as DATA_RETRIES
|
||||
import asyncssh
|
||||
|
||||
|
||||
class BOSMinerOld(BaseMiner):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.api = BOSMinerAPI(ip)
|
||||
self.api_type = "BOSMiner"
|
||||
self.uname = "root"
|
||||
self.pwd = "admin"
|
||||
|
||||
async def send_ssh_command(self, cmd: str) -> str or None:
|
||||
"""Send a command to the miner over ssh.
|
||||
|
||||
:return: Result of the command or None.
|
||||
"""
|
||||
result = None
|
||||
|
||||
# open an ssh connection
|
||||
async with await asyncssh.connect("192.168.1.11", username="root") as conn:
|
||||
# 3 retries
|
||||
for i in range(3):
|
||||
try:
|
||||
# run the command and get the result
|
||||
result = await conn.run(cmd)
|
||||
result = result.stdout
|
||||
except Exception as e:
|
||||
# if the command fails, log it
|
||||
logging.warning(f"{self} command {cmd} error: {e}")
|
||||
|
||||
# on the 3rd retry, return None
|
||||
if i == 3:
|
||||
return
|
||||
continue
|
||||
# return the result, either command output or None
|
||||
return str(result)
|
||||
|
||||
async def update_to_plus(self):
|
||||
result = await self.send_ssh_command("opkg update && opkg install bos_plus")
|
||||
return result
|
||||
@@ -7,13 +7,10 @@ from settings import MINER_FACTORY_GET_VERSION_RETRIES as DATA_RETRIES
|
||||
|
||||
class BTMiner(BaseMiner):
|
||||
def __init__(self, ip: str) -> None:
|
||||
api = BTMinerAPI(ip)
|
||||
self.model = None
|
||||
super().__init__(ip, api)
|
||||
self.nominal_chips = 66
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"BTMiner: {str(self.ip)}"
|
||||
super().__init__(ip)
|
||||
self.ip = ip
|
||||
self.api = BTMinerAPI(ip)
|
||||
self.api_type = "BTMiner"
|
||||
|
||||
async def get_model(self):
|
||||
if self.model:
|
||||
@@ -75,6 +72,15 @@ class BTMiner(BaseMiner):
|
||||
logging.debug(f"Found board data for {self}: {boards}")
|
||||
return boards
|
||||
|
||||
async def get_mac(self):
|
||||
mac = ""
|
||||
data = await self.api.get_miner_info()
|
||||
if data:
|
||||
if "Msg" in data.keys():
|
||||
if "mac" in data["Msg"].keys():
|
||||
mac = data["Msg"]["mac"]
|
||||
return str(mac).upper()
|
||||
|
||||
async def get_data(self):
|
||||
data = {
|
||||
"IP": str(self.ip),
|
||||
@@ -84,15 +90,28 @@ class BTMiner(BaseMiner):
|
||||
"Temperature": 0,
|
||||
"Pool User": "Unknown",
|
||||
"Wattage": 0,
|
||||
"Split": 0,
|
||||
"Total": 0,
|
||||
"Ideal": self.nominal_chips * 3,
|
||||
"Left Board": 0,
|
||||
"Center Board": 0,
|
||||
"Right Board": 0,
|
||||
"Nominal": False,
|
||||
"Split": "0",
|
||||
"Pool 1": "Unknown",
|
||||
"Pool 1 User": "Unknown",
|
||||
"Pool 2": "",
|
||||
"Pool 2 User": "",
|
||||
}
|
||||
|
||||
model = await self.get_model()
|
||||
hostname = await self.get_hostname()
|
||||
try:
|
||||
model = await self.get_model()
|
||||
hostname = await self.get_hostname()
|
||||
except APIError:
|
||||
logging.warning(f"Failed to get hostname and model: {self}")
|
||||
model = None
|
||||
data["Model"] = "Whatsminer"
|
||||
hostname = None
|
||||
data["Hostname"] = "Whatsminer"
|
||||
|
||||
if model:
|
||||
data["Model"] = model
|
||||
@@ -101,9 +120,12 @@ class BTMiner(BaseMiner):
|
||||
data["Hostname"] = hostname
|
||||
miner_data = None
|
||||
for i in range(DATA_RETRIES):
|
||||
miner_data = await self.api.multicommand("summary", "devs", "pools")
|
||||
if miner_data:
|
||||
break
|
||||
try:
|
||||
miner_data = await self.api.multicommand("summary", "devs", "pools")
|
||||
if miner_data:
|
||||
break
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
if not miner_data:
|
||||
return data
|
||||
@@ -116,7 +138,7 @@ class BTMiner(BaseMiner):
|
||||
summary_data = summary.get("SUMMARY")
|
||||
if summary_data:
|
||||
if len(summary_data) > 0:
|
||||
hr = summary_data[0].get("MHS 5s")
|
||||
hr = summary_data[0].get("MHS av")
|
||||
if hr:
|
||||
data["Hashrate"] = round(hr / 1000000, 2)
|
||||
|
||||
@@ -133,6 +155,25 @@ class BTMiner(BaseMiner):
|
||||
data["Temperature"] = round(temp)
|
||||
break
|
||||
|
||||
if devs:
|
||||
boards = devs.get("DEVS")
|
||||
if boards:
|
||||
if len(boards) > 0:
|
||||
board_map = {0: "Left Board", 1: "Center Board", 2: "Right Board"}
|
||||
if "ID" in boards[0].keys():
|
||||
id_key = "ID"
|
||||
else:
|
||||
id_key = "ASC"
|
||||
offset = boards[0][id_key]
|
||||
for board in boards:
|
||||
id = board[id_key] - offset
|
||||
chips = board["Effective Chips"]
|
||||
data["Total"] += chips
|
||||
data[board_map[id]] = chips
|
||||
|
||||
if data["Total"] == data["Ideal"]:
|
||||
data["Nominal"] = True
|
||||
|
||||
if pools:
|
||||
pool_1 = None
|
||||
pool_2 = None
|
||||
@@ -7,16 +7,13 @@ import logging
|
||||
|
||||
class CGMiner(BaseMiner):
|
||||
def __init__(self, ip: str) -> None:
|
||||
api = CGMinerAPI(ip)
|
||||
super().__init__(ip, api)
|
||||
self.model = None
|
||||
self.config = None
|
||||
super().__init__(ip)
|
||||
self.ip = ip
|
||||
self.api = CGMinerAPI(ip)
|
||||
self.api_type = "CGMiner"
|
||||
self.uname = "root"
|
||||
self.pwd = "admin"
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"CGMiner: {str(self.ip)}"
|
||||
|
||||
async def get_model(self):
|
||||
if self.model:
|
||||
return self.model
|
||||
@@ -145,7 +142,7 @@ class CGMiner(BaseMiner):
|
||||
hr = summary.get("SUMMARY")
|
||||
if hr:
|
||||
if len(hr) > 0:
|
||||
hr = hr[0].get("GHS 5s")
|
||||
hr = hr[0].get("GHS av")
|
||||
if hr:
|
||||
data["Hashrate"] = round(hr / 1000, 2)
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
from miners.bmminer import BMMiner
|
||||
from miners._backends import BMMiner
|
||||
|
||||
|
||||
class HiveonT9(BMMiner):
|
||||
class Hiveon(BMMiner):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.model = "T9"
|
||||
self.ip = ip
|
||||
self.api_type = "Hiveon"
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"HiveonT9: {str(self.ip)}"
|
||||
self.uname = "root"
|
||||
self.pwd = "admin"
|
||||
|
||||
async def get_board_info(self) -> dict:
|
||||
"""Gets data on each board and chain in the miner."""
|
||||
3
miners/_types/__init__.py
Normal file
3
miners/_types/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from .antminer import *
|
||||
from .avalonminer import *
|
||||
from .whatsminer import *
|
||||
9
miners/_types/antminer/X17/S17.py
Normal file
9
miners/_types/antminer/X17/S17.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from miners import BaseMiner
|
||||
|
||||
|
||||
class S17(BaseMiner):
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "S17"
|
||||
self.nominal_chips = 48
|
||||
9
miners/_types/antminer/X17/S17_Plus.py
Normal file
9
miners/_types/antminer/X17/S17_Plus.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from miners import BaseMiner
|
||||
|
||||
|
||||
class S17Plus(BaseMiner):
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "S17+"
|
||||
self.nominal_chips = 65
|
||||
9
miners/_types/antminer/X17/S17_Pro.py
Normal file
9
miners/_types/antminer/X17/S17_Pro.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from miners import BaseMiner
|
||||
|
||||
|
||||
class S17Pro(BaseMiner):
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "S17 Pro"
|
||||
self.nominal_chips = 48
|
||||
9
miners/_types/antminer/X17/S17e.py
Normal file
9
miners/_types/antminer/X17/S17e.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from miners import BaseMiner
|
||||
|
||||
|
||||
class S17e(BaseMiner):
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "S17e"
|
||||
self.nominal_chips = 135
|
||||
9
miners/_types/antminer/X17/T17.py
Normal file
9
miners/_types/antminer/X17/T17.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from miners import BaseMiner
|
||||
|
||||
|
||||
class T17(BaseMiner):
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "T17"
|
||||
self.nominal_chips = 30
|
||||
9
miners/_types/antminer/X17/T17_Plus.py
Normal file
9
miners/_types/antminer/X17/T17_Plus.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from miners import BaseMiner
|
||||
|
||||
|
||||
class T17Plus(BaseMiner):
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "T17+"
|
||||
self.nominal_chips = 44
|
||||
9
miners/_types/antminer/X17/T17e.py
Normal file
9
miners/_types/antminer/X17/T17e.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from miners import BaseMiner
|
||||
|
||||
|
||||
class T17e(BaseMiner):
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "T17e"
|
||||
self.nominal_chips = 78
|
||||
8
miners/_types/antminer/X17/__init__.py
Normal file
8
miners/_types/antminer/X17/__init__.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from .S17 import S17
|
||||
from .S17_Plus import S17Plus
|
||||
from .S17_Pro import S17Pro
|
||||
from .S17e import S17e
|
||||
|
||||
from .T17 import T17
|
||||
from .T17_Plus import T17Plus
|
||||
from .T17e import T17e
|
||||
9
miners/_types/antminer/X19/S19.py
Normal file
9
miners/_types/antminer/X19/S19.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from miners import BaseMiner
|
||||
|
||||
|
||||
class S19(BaseMiner):
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "S19"
|
||||
self.nominal_chips = 76
|
||||
9
miners/_types/antminer/X19/S19_Pro.py
Normal file
9
miners/_types/antminer/X19/S19_Pro.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from miners import BaseMiner
|
||||
|
||||
|
||||
class S19Pro(BaseMiner):
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "S19 Pro"
|
||||
self.nominal_chips = 114
|
||||
9
miners/_types/antminer/X19/S19a.py
Normal file
9
miners/_types/antminer/X19/S19a.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from miners import BaseMiner
|
||||
|
||||
|
||||
class S19a(BaseMiner):
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "S19a"
|
||||
self.nominal_chips = 72
|
||||
9
miners/_types/antminer/X19/S19j.py
Normal file
9
miners/_types/antminer/X19/S19j.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from miners import BaseMiner
|
||||
|
||||
|
||||
class S19j(BaseMiner):
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "S19j"
|
||||
self.nominal_chips = 114
|
||||
9
miners/_types/antminer/X19/S19j_Pro.py
Normal file
9
miners/_types/antminer/X19/S19j_Pro.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from miners import BaseMiner
|
||||
|
||||
|
||||
class S19jPro(BaseMiner):
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "S19j Pro"
|
||||
self.nominal_chips = 126
|
||||
9
miners/_types/antminer/X19/T19.py
Normal file
9
miners/_types/antminer/X19/T19.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from miners import BaseMiner
|
||||
|
||||
|
||||
class T19(BaseMiner):
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "T19"
|
||||
self.nominal_chips = 76
|
||||
9
miners/_types/antminer/X19/__init__.py
Normal file
9
miners/_types/antminer/X19/__init__.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from .S19 import S19
|
||||
from .S19_Pro import S19Pro
|
||||
|
||||
from .S19j import S19j
|
||||
from .S19j_Pro import S19jPro
|
||||
|
||||
from .S19a import S19a
|
||||
|
||||
from .T19 import T19
|
||||
9
miners/_types/antminer/X9/S9.py
Normal file
9
miners/_types/antminer/X9/S9.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from miners import BaseMiner
|
||||
|
||||
|
||||
class S9(BaseMiner):
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "S9"
|
||||
self.nominal_chips = 63
|
||||
9
miners/_types/antminer/X9/T9.py
Normal file
9
miners/_types/antminer/X9/T9.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from miners import BaseMiner
|
||||
|
||||
|
||||
class T9(BaseMiner):
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "T9"
|
||||
self.nominal_chips = 57
|
||||
2
miners/_types/antminer/X9/__init__.py
Normal file
2
miners/_types/antminer/X9/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
from .S9 import S9
|
||||
from .T9 import T9
|
||||
3
miners/_types/antminer/__init__.py
Normal file
3
miners/_types/antminer/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from .X9 import *
|
||||
from .X17 import *
|
||||
from .X19 import *
|
||||
9
miners/_types/avalonminer/A10X/A1047.py
Normal file
9
miners/_types/avalonminer/A10X/A1047.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from miners import BaseMiner
|
||||
|
||||
|
||||
class Avalon1047(BaseMiner):
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "Avalon 1047"
|
||||
self.nominal_chips = 114
|
||||
9
miners/_types/avalonminer/A10X/A1066.py
Normal file
9
miners/_types/avalonminer/A10X/A1066.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from miners import BaseMiner
|
||||
|
||||
|
||||
class Avalon1066(BaseMiner):
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "Avalon 1066"
|
||||
self.nominal_chips = 114
|
||||
2
miners/_types/avalonminer/A10X/__init__.py
Normal file
2
miners/_types/avalonminer/A10X/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
from .A1047 import Avalon1047
|
||||
from .A1066 import Avalon1066
|
||||
8
miners/_types/avalonminer/A8X/A821.py
Normal file
8
miners/_types/avalonminer/A8X/A821.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from miners import BaseMiner
|
||||
|
||||
|
||||
class Avalon821(BaseMiner):
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "Avalon 821"
|
||||
8
miners/_types/avalonminer/A8X/A841.py
Normal file
8
miners/_types/avalonminer/A8X/A841.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from miners import BaseMiner
|
||||
|
||||
|
||||
class Avalon841(BaseMiner):
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "Avalon 841"
|
||||
2
miners/_types/avalonminer/A8X/__init__.py
Normal file
2
miners/_types/avalonminer/A8X/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
from .A821 import Avalon821
|
||||
from .A841 import Avalon841
|
||||
2
miners/_types/avalonminer/__init__.py
Normal file
2
miners/_types/avalonminer/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
from .A8X import *
|
||||
from .A10X import *
|
||||
9
miners/_types/whatsminer/M2X/M20S.py
Normal file
9
miners/_types/whatsminer/M2X/M20S.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from miners import BaseMiner
|
||||
|
||||
|
||||
class M20S(BaseMiner):
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "M20S"
|
||||
self.nominal_chips = 66
|
||||
9
miners/_types/whatsminer/M2X/M20S_Plus.py
Normal file
9
miners/_types/whatsminer/M2X/M20S_Plus.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from miners import BaseMiner
|
||||
|
||||
|
||||
class M20SPlus(BaseMiner):
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "M20S+"
|
||||
self.nominal_chips = 66
|
||||
9
miners/_types/whatsminer/M2X/M21.py
Normal file
9
miners/_types/whatsminer/M2X/M21.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from miners import BaseMiner
|
||||
|
||||
|
||||
class M21(BaseMiner):
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "M21"
|
||||
self.nominal_chips = 105
|
||||
9
miners/_types/whatsminer/M2X/M21S.py
Normal file
9
miners/_types/whatsminer/M2X/M21S.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from miners import BaseMiner
|
||||
|
||||
|
||||
class M21S(BaseMiner):
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "M21S"
|
||||
self.nominal_chips = 105
|
||||
9
miners/_types/whatsminer/M2X/M21S_Plus.py
Normal file
9
miners/_types/whatsminer/M2X/M21S_Plus.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from miners import BaseMiner
|
||||
|
||||
|
||||
class M21SPlus(BaseMiner):
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "M21S+"
|
||||
self.nominal_chips = 105
|
||||
6
miners/_types/whatsminer/M2X/__init__.py
Normal file
6
miners/_types/whatsminer/M2X/__init__.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from .M20S import M20S
|
||||
from .M20S_Plus import M20SPlus
|
||||
|
||||
from .M21 import M21
|
||||
from .M21S import M21S
|
||||
from .M21S_Plus import M21SPlus
|
||||
8
miners/_types/whatsminer/M3X/M30S.py
Normal file
8
miners/_types/whatsminer/M3X/M30S.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from miners import BaseMiner
|
||||
|
||||
|
||||
class M30S(BaseMiner):
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "M30S"
|
||||
9
miners/_types/whatsminer/M3X/M30S_Plus.py
Normal file
9
miners/_types/whatsminer/M3X/M30S_Plus.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from miners import BaseMiner
|
||||
|
||||
|
||||
class M30SPlus(BaseMiner):
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "M30S+"
|
||||
self.nominal_chips = 156
|
||||
12
miners/_types/whatsminer/M3X/M30S_Plus_Plus.py
Normal file
12
miners/_types/whatsminer/M3X/M30S_Plus_Plus.py
Normal file
@@ -0,0 +1,12 @@
|
||||
from miners import BaseMiner
|
||||
|
||||
|
||||
class M30SPlusPlus(BaseMiner):
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "M30S++"
|
||||
self.nominal_chips = 117
|
||||
|
||||
|
||||
# TODO: handle different chip counts, 111, 117,(128)
|
||||
8
miners/_types/whatsminer/M3X/M31S.py
Normal file
8
miners/_types/whatsminer/M3X/M31S.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from miners import BaseMiner
|
||||
|
||||
|
||||
class M31S(BaseMiner):
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "M31S"
|
||||
8
miners/_types/whatsminer/M3X/M31S_Plus.py
Normal file
8
miners/_types/whatsminer/M3X/M31S_Plus.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from miners import BaseMiner
|
||||
|
||||
|
||||
class M31SPlus(BaseMiner):
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "M31S+"
|
||||
9
miners/_types/whatsminer/M3X/M32S.py
Normal file
9
miners/_types/whatsminer/M3X/M32S.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from miners import BaseMiner
|
||||
|
||||
|
||||
class M32S(BaseMiner):
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "M32S"
|
||||
self.nominal_chips = 78
|
||||
8
miners/_types/whatsminer/M3X/__init__.py
Normal file
8
miners/_types/whatsminer/M3X/__init__.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from .M30S import M30S
|
||||
from .M30S_Plus import M30SPlus
|
||||
from .M30S_Plus_Plus import M30SPlusPlus
|
||||
|
||||
from .M31S import M31S
|
||||
from .M31S_Plus import M31SPlus
|
||||
|
||||
from .M32S import M32S
|
||||
2
miners/_types/whatsminer/__init__.py
Normal file
2
miners/_types/whatsminer/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
from .M2X import *
|
||||
from .M3X import *
|
||||
@@ -1,11 +0,0 @@
|
||||
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,15 +0,0 @@
|
||||
import logging
|
||||
import toml
|
||||
|
||||
from miners.bosminer import BOSMiner
|
||||
from config.bos import general_config_convert_bos
|
||||
|
||||
|
||||
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)}"
|
||||
@@ -1,11 +0,0 @@
|
||||
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)}"
|
||||
@@ -1,11 +0,0 @@
|
||||
from miners.bmminer import BMMiner
|
||||
|
||||
|
||||
class BMMinerT9(BMMiner):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.model = "T9"
|
||||
self.api_type = "BMMiner"
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"BMMinerT9: {str(self.ip)}"
|
||||
@@ -1,9 +0,0 @@
|
||||
from miners.bmminer import BMMiner
|
||||
|
||||
|
||||
class BMMinerX17(BMMiner):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"BMMinerX17: {str(self.ip)}"
|
||||
@@ -1,11 +0,0 @@
|
||||
from miners.bosminer import BOSMiner
|
||||
|
||||
|
||||
class BOSMinerX17(BOSMiner):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.api_type = "BOSMiner"
|
||||
self.nominal_chips = 65
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"BOSminerX17: {str(self.ip)}"
|
||||
@@ -1,10 +0,0 @@
|
||||
from miners.cgminer import CGMiner
|
||||
|
||||
|
||||
class CGMinerX17(CGMiner):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.api_type = "CGMiner"
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"CGMinerX17: {str(self.ip)}"
|
||||
@@ -1,22 +0,0 @@
|
||||
from miners.bmminer import BMMiner
|
||||
import logging
|
||||
|
||||
|
||||
class BMMinerX19(BMMiner):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"BMMinerX19: {str(self.ip)}"
|
||||
|
||||
async def get_model(self):
|
||||
if self.model:
|
||||
logging.debug(f"Found model for {self.ip}: {self.model}")
|
||||
return self.model
|
||||
version_data = await self.api.version()
|
||||
if version_data:
|
||||
self.model = version_data["VERSION"][0]["Type"].replace("Antminer ", "")
|
||||
logging.debug(f"Found model for {self.ip}: {self.model}")
|
||||
return self.model
|
||||
logging.warning(f"Failed to get model for miner: {self}")
|
||||
return None
|
||||
@@ -1,11 +0,0 @@
|
||||
from miners.bosminer import BOSMiner
|
||||
|
||||
|
||||
class BOSMinerX19(BOSMiner):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.api_type = "BOSMiner"
|
||||
self.nominal_chips = 114
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"BOSminerX19: {str(self.ip)}"
|
||||
@@ -1,23 +0,0 @@
|
||||
from miners.cgminer import CGMiner
|
||||
import logging
|
||||
|
||||
|
||||
class CGMinerX19(CGMiner):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.api_type = "CGMiner"
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"CGMinerX19: {str(self.ip)}"
|
||||
|
||||
async def get_model(self):
|
||||
if self.model:
|
||||
logging.debug(f"Found model for {self.ip}: {self.model}")
|
||||
return self.model
|
||||
version_data = await self.api.version()
|
||||
if version_data:
|
||||
self.model = version_data["VERSION"][0]["Type"].replace("Antminer ", "")
|
||||
logging.debug(f"Found model for {self.ip}: {self.model}")
|
||||
return self.model
|
||||
logging.warning(f"Failed to get model for miner: {self}")
|
||||
return None
|
||||
@@ -0,0 +1,4 @@
|
||||
from .bmminer import *
|
||||
from .bosminer import *
|
||||
from .cgminer import *
|
||||
from .hiveon import *
|
||||
|
||||
8
miners/antminer/bmminer/X17/S17.py
Normal file
8
miners/antminer/bmminer/X17/S17.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from miners._backends import BMMiner
|
||||
from miners._types import S17
|
||||
|
||||
|
||||
class BMMinerS17(BMMiner, S17):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.ip = ip
|
||||
8
miners/antminer/bmminer/X17/S17_Plus.py
Normal file
8
miners/antminer/bmminer/X17/S17_Plus.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from miners._backends import BMMiner
|
||||
from miners._types import S17Plus
|
||||
|
||||
|
||||
class BMMinerS17Plus(BMMiner, S17Plus):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.ip = ip
|
||||
8
miners/antminer/bmminer/X17/S17_Pro.py
Normal file
8
miners/antminer/bmminer/X17/S17_Pro.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from miners._backends import BMMiner
|
||||
from miners._types import S17Pro
|
||||
|
||||
|
||||
class BMMinerS17Pro(BMMiner, S17Pro):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.ip = ip
|
||||
8
miners/antminer/bmminer/X17/S17e.py
Normal file
8
miners/antminer/bmminer/X17/S17e.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from miners._backends import BMMiner
|
||||
from miners._types import S17e
|
||||
|
||||
|
||||
class BMMinerS17e(BMMiner, S17e):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.ip = ip
|
||||
8
miners/antminer/bmminer/X17/T17.py
Normal file
8
miners/antminer/bmminer/X17/T17.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from miners._backends import BMMiner
|
||||
from miners._types import T17
|
||||
|
||||
|
||||
class BMMinerT17(BMMiner, T17):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.ip = ip
|
||||
8
miners/antminer/bmminer/X17/T17_Plus.py
Normal file
8
miners/antminer/bmminer/X17/T17_Plus.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from miners._backends import BMMiner
|
||||
from miners._types import T17Plus
|
||||
|
||||
|
||||
class BMMinerT17Plus(BMMiner, T17Plus):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.ip = ip
|
||||
8
miners/antminer/bmminer/X17/T17e.py
Normal file
8
miners/antminer/bmminer/X17/T17e.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from miners._backends import BMMiner
|
||||
from miners._types import T17e
|
||||
|
||||
|
||||
class BMMinerT17e(BMMiner, T17e):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.ip = ip
|
||||
8
miners/antminer/bmminer/X17/__init__.py
Normal file
8
miners/antminer/bmminer/X17/__init__.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from .S17 import BMMinerS17
|
||||
from .S17_Plus import BMMinerS17Plus
|
||||
from .S17_Pro import BMMinerS17Pro
|
||||
from .S17e import BMMinerS17e
|
||||
|
||||
from .T17 import BMMinerT17
|
||||
from .T17_Plus import BMMinerT17Plus
|
||||
from .T17e import BMMinerT17e
|
||||
8
miners/antminer/bmminer/X19/S19.py
Normal file
8
miners/antminer/bmminer/X19/S19.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from miners._backends import BMMiner
|
||||
from miners._types import S19
|
||||
|
||||
|
||||
class BMMinerS19(BMMiner, S19):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.ip = ip
|
||||
8
miners/antminer/bmminer/X19/S19_Pro.py
Normal file
8
miners/antminer/bmminer/X19/S19_Pro.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from miners._backends import BMMiner
|
||||
from miners._types import S19Pro
|
||||
|
||||
|
||||
class BMMinerS19Pro(BMMiner, S19Pro):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.ip = ip
|
||||
8
miners/antminer/bmminer/X19/S19a.py
Normal file
8
miners/antminer/bmminer/X19/S19a.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from miners._backends import BMMiner
|
||||
from miners._types import S19a
|
||||
|
||||
|
||||
class BMMinerS19a(BMMiner, S19a):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.ip = ip
|
||||
8
miners/antminer/bmminer/X19/S19j.py
Normal file
8
miners/antminer/bmminer/X19/S19j.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from miners._backends import BMMiner
|
||||
from miners._types import S19j
|
||||
|
||||
|
||||
class BMMinerS19j(BMMiner, S19j):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.ip = ip
|
||||
8
miners/antminer/bmminer/X19/S19j_Pro.py
Normal file
8
miners/antminer/bmminer/X19/S19j_Pro.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from miners._backends import BMMiner
|
||||
from miners._types import S19jPro
|
||||
|
||||
|
||||
class BMMinerS19jPro(BMMiner, S19jPro):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.ip = ip
|
||||
8
miners/antminer/bmminer/X19/T19.py
Normal file
8
miners/antminer/bmminer/X19/T19.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from miners._backends import BMMiner
|
||||
from miners._types import T19
|
||||
|
||||
|
||||
class BMMinerT19(BMMiner, T19):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.ip = ip
|
||||
9
miners/antminer/bmminer/X19/__init__.py
Normal file
9
miners/antminer/bmminer/X19/__init__.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from .S19 import BMMinerS19
|
||||
from .S19_Pro import BMMinerS19Pro
|
||||
|
||||
from .S19j import BMMinerS19j
|
||||
from .S19j_Pro import BMMinerS19jPro
|
||||
|
||||
from .S19a import BMMinerS19a
|
||||
|
||||
from .T19 import BMMinerT19
|
||||
8
miners/antminer/bmminer/X9/S9.py
Normal file
8
miners/antminer/bmminer/X9/S9.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from miners._backends import BMMiner
|
||||
from miners._types import S9
|
||||
|
||||
|
||||
class BMMinerS9(BMMiner, S9):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.ip = ip
|
||||
8
miners/antminer/bmminer/X9/T9.py
Normal file
8
miners/antminer/bmminer/X9/T9.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from miners._backends import BMMiner
|
||||
from miners._types import T9
|
||||
|
||||
|
||||
class BMMinerT9(BMMiner, T9):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.ip = ip
|
||||
2
miners/antminer/bmminer/X9/__init__.py
Normal file
2
miners/antminer/bmminer/X9/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
from .S9 import BMMinerS9
|
||||
from .T9 import BMMinerT9
|
||||
3
miners/antminer/bmminer/__init__.py
Normal file
3
miners/antminer/bmminer/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from .X9 import *
|
||||
from .X17 import *
|
||||
from .X19 import *
|
||||
8
miners/antminer/bosminer/X17/S17.py
Normal file
8
miners/antminer/bosminer/X17/S17.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from miners._backends import BOSMiner
|
||||
from miners._types import S17
|
||||
|
||||
|
||||
class BOSMinerS17(BOSMiner, S17):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.ip = ip
|
||||
8
miners/antminer/bosminer/X17/S17_Plus.py
Normal file
8
miners/antminer/bosminer/X17/S17_Plus.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from miners._backends import BOSMiner
|
||||
from miners._types import S17Plus
|
||||
|
||||
|
||||
class BOSMinerS17Plus(BOSMiner, S17Plus):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.ip = ip
|
||||
8
miners/antminer/bosminer/X17/S17_Pro.py
Normal file
8
miners/antminer/bosminer/X17/S17_Pro.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from miners._backends import BOSMiner
|
||||
from miners._types import S17Pro
|
||||
|
||||
|
||||
class BOSMinerS17Pro(BOSMiner, S17Pro):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.ip = ip
|
||||
8
miners/antminer/bosminer/X17/S17e.py
Normal file
8
miners/antminer/bosminer/X17/S17e.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from miners._backends import BOSMiner
|
||||
from miners._types import S17e
|
||||
|
||||
|
||||
class BOSMinerS17e(BOSMiner, S17e):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.ip = ip
|
||||
8
miners/antminer/bosminer/X17/T17.py
Normal file
8
miners/antminer/bosminer/X17/T17.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from miners._backends import BOSMiner
|
||||
from miners._types import T17
|
||||
|
||||
|
||||
class BOSMinerT17(BOSMiner, T17):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.ip = ip
|
||||
8
miners/antminer/bosminer/X17/T17_Plus.py
Normal file
8
miners/antminer/bosminer/X17/T17_Plus.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from miners._backends import BOSMiner
|
||||
from miners._types import T17Plus
|
||||
|
||||
|
||||
class BOSMinerT17Plus(BOSMiner, T17Plus):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.ip = ip
|
||||
8
miners/antminer/bosminer/X17/T17e.py
Normal file
8
miners/antminer/bosminer/X17/T17e.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from miners._backends import BOSMiner
|
||||
from miners._types import T17e
|
||||
|
||||
|
||||
class BOSMinerT17e(BOSMiner, T17e):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.ip = ip
|
||||
8
miners/antminer/bosminer/X17/__init__.py
Normal file
8
miners/antminer/bosminer/X17/__init__.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from .S17 import BOSMinerS17
|
||||
from .S17_Plus import BOSMinerS17Plus
|
||||
from .S17_Pro import BOSMinerS17Pro
|
||||
from .S17e import BOSMinerS17e
|
||||
|
||||
from .T17 import BOSMinerT17
|
||||
from .T17_Plus import BOSMinerT17Plus
|
||||
from .T17e import BOSMinerT17e
|
||||
8
miners/antminer/bosminer/X19/S19.py
Normal file
8
miners/antminer/bosminer/X19/S19.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from miners._backends import BOSMiner
|
||||
from miners._types import S19
|
||||
|
||||
|
||||
class BOSMinerS19(BOSMiner, S19):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.ip = ip
|
||||
8
miners/antminer/bosminer/X19/S19_Pro.py
Normal file
8
miners/antminer/bosminer/X19/S19_Pro.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from miners._backends import BOSMiner
|
||||
from miners._types import S19Pro
|
||||
|
||||
|
||||
class BOSMinerS19Pro(BOSMiner, S19Pro):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.ip = ip
|
||||
8
miners/antminer/bosminer/X19/S19j.py
Normal file
8
miners/antminer/bosminer/X19/S19j.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from miners._backends import BOSMiner
|
||||
from miners._types import S19j
|
||||
|
||||
|
||||
class BOSMinerS19j(BOSMiner, S19j):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.ip = ip
|
||||
8
miners/antminer/bosminer/X19/S19j_Pro.py
Normal file
8
miners/antminer/bosminer/X19/S19j_Pro.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from miners._backends import BOSMiner
|
||||
from miners._types import S19jPro
|
||||
|
||||
|
||||
class BOSMinerS19jPro(BOSMiner, S19jPro):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.ip = ip
|
||||
8
miners/antminer/bosminer/X19/T19.py
Normal file
8
miners/antminer/bosminer/X19/T19.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from miners._backends import BOSMiner
|
||||
from miners._types import T19
|
||||
|
||||
|
||||
class BOSMinerT19(BOSMiner, T19):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.ip = ip
|
||||
7
miners/antminer/bosminer/X19/__init__.py
Normal file
7
miners/antminer/bosminer/X19/__init__.py
Normal file
@@ -0,0 +1,7 @@
|
||||
from .S19 import BOSMinerS19
|
||||
from .S19_Pro import BOSMinerS19Pro
|
||||
|
||||
from .S19j import BOSMinerS19j
|
||||
from .S19j_Pro import BOSMinerS19jPro
|
||||
|
||||
from .T19 import BOSMinerT19
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user