Compare commits

...

56 Commits

Author SHA1 Message Date
UpstreamData
3d265e823b update README.md 2022-05-17 09:08:50 -06:00
UpstreamData
5e6bc8c8ef add mac addresses for bosminer, and reformat 2022-05-17 08:51:56 -06:00
UpstreamData
871499b77f fix some bugs in miner listener 2022-05-16 16:22:05 -06:00
UpstreamData
117a161fd5 added miner listener to listen for ip reporting 2022-05-16 16:16:22 -06:00
UpstreamData
40bacbf41c add getting mac for whatsminers 2022-05-16 15:01:04 -06:00
UpstreamData
e091863aa7 fixed a bug with suspended whatsminers 2022-05-16 14:06:23 -06:00
UpstreamData
85e8ac63f1 update light column 2022-05-16 13:46:16 -06:00
UpstreamData
a5252e3a84 update README.md 2022-05-16 12:30:04 -06:00
UpstreamData
404d6590db improved resizing and light 2022-05-16 11:55:13 -06:00
UpstreamData
1d04399daf made the window of the cfg util resizeable 2022-05-16 11:35:45 -06:00
UpstreamData
03ebcacca5 added an old version of Bosminer for non plus miners to be able to update 2022-05-16 11:24:32 -06:00
UpstreamData
75934fd7fe fixed another bug with testbench putting miners into recovery mode 2022-05-16 10:50:07 -06:00
UpstreamData
bbeca15799 attempted to fix a bug with testbench 2022-05-16 10:40:28 -06:00
UpstreamData
45befb569b updated a bunch of miner chip counts, added S19a, and fixed a bug with whatsminer M30S++ 2022-05-16 08:42:26 -06:00
UpstreamData
61334ed99e Merge remote-tracking branch 'origin/combine_board_cfg_util' into combine_board_cfg_util 2022-05-13 15:37:27 -06:00
UpstreamData
2bf059df01 remove board util 2022-05-13 15:35:42 -06:00
UpstreamData
9c2de26182 switched over to hashrate av to be more accurate when getting data 2022-05-13 15:35:42 -06:00
UpstreamData
714983cddc added exporting reports from config tool 2022-05-13 15:35:42 -06:00
UpstreamData
191f1d24b9 improved send command functionality with a generator and added progress to it 2022-05-13 15:35:42 -06:00
UpstreamData
5a0bafb964 fixed a bug for scanning S9s with no boards for testing 2022-05-13 15:35:42 -06:00
UpstreamData
67aedd319d update README.md 2022-05-13 15:35:41 -06:00
UpstreamData
44012c50d6 finished updating the miner type handlers to create subclasses of the backend and type to create a miner, each of which handles its own data to simplify creation of new miner types 2022-05-13 15:35:41 -06:00
UpstreamData
06540efc98 changed the way antminers and whatsminers are handled in the factory to allow for more precision on chip counts 2022-05-13 15:35:41 -06:00
UpstreamData
9d0d1a24d9 added S19 board handler 2022-05-13 15:35:41 -06:00
UpstreamData
8568f91482 added btminer board data 2022-05-13 15:35:41 -06:00
UpstreamData
64918e5552 added bosminer board data 2022-05-13 15:35:41 -06:00
UpstreamData
53d5ecd04a added images for boards 2022-05-13 15:35:41 -06:00
UpstreamData
1b0e80a418 added basic framework for boards in config util 2022-05-13 15:35:41 -06:00
UpstreamData
9ad506a313 remove board util 2022-05-13 15:35:11 -06:00
UpstreamData
18c4bbd09c switched over to hashrate av to be more accurate when getting data 2022-05-13 15:31:32 -06:00
UpstreamData
0d123d5dd8 added exporting reports from config tool 2022-05-13 15:23:51 -06:00
UpstreamData
b9b91293fe improved send command functionality with a generator and added progress to it 2022-05-13 14:28:51 -06:00
UpstreamData
47a702c94c fixed a bug for scanning S9s with no boards for testing 2022-05-13 14:03:27 -06:00
UpstreamData
6d5a288120 update README.md 2022-05-13 11:35:37 -06:00
UpstreamData
038aae95ac finished updating the miner type handlers to create subclasses of the backend and type to create a miner, each of which handles its own data to simplify creation of new miner types 2022-05-13 11:27:56 -06:00
UpstreamData
dd84aede25 changed the way antminers and whatsminers are handled in the factory to allow for more precision on chip counts 2022-05-12 16:42:02 -06:00
UpstreamData
dc8ad271de added S19 board handler 2022-05-12 15:16:05 -06:00
UpstreamData
b78c1cdca5 added wattage to configure tab 2022-05-12 14:42:37 -06:00
UpstreamData
0eb7ced932 added btminer board data 2022-05-12 13:20:57 -06:00
UpstreamData
8e58f4492f added bosminer board data 2022-05-12 13:12:54 -06:00
UpstreamData
95fb32de19 added images for boards 2022-05-12 12:35:33 -06:00
UpstreamData
5145dc19f8 added basic framework for boards in config util 2022-05-12 11:29:28 -06:00
UpstreamData
1808d62bba fix references to some table headers 2022-05-11 14:42:47 -06:00
UpstreamData
97ef4dfe37 fixed some bugs with testbench on the latest version 2022-05-11 14:28:53 -06:00
UpstreamData
174a132e75 attempt to fix a bug in testbench 2022-05-11 14:04:05 -06:00
UpstreamData
84d6e58ebe change progress bar completion animation 2022-05-11 13:24:54 -06:00
UpstreamData
e9a1483e5f fixed some small bugs with whatsminers and progress bar 2022-05-11 13:20:14 -06:00
UpstreamData
4eb51eed20 update CFG-Util-README.md 2022-05-11 10:51:36 -06:00
UpstreamData
066fc1a4b3 changed Temperature to Temp and added more spacing to pool user 2022-05-11 08:43:32 -06:00
UpstreamData
cc24236c0a update requirements.txt 2022-05-11 08:40:00 -06:00
UpstreamData
564cd42eae added ctrl c and ctrl a functionality to the tables 2022-05-11 08:37:17 -06:00
UpstreamData
8677eff491 moved miner count and hashrate to top of tool 2022-05-10 14:00:50 -06:00
UpstreamData
63a21ea9aa updated formatting on scrollbars 2022-05-10 13:53:18 -06:00
UpstreamData
1c9d3dc84d updated formatting on page 2022-05-10 13:44:08 -06:00
UpstreamData
0dacd3d294 changed sorting to show up on the table headers 2022-05-10 11:51:26 -06:00
UpstreamData
6fa74613b4 updated look of CFG util 2022-05-10 11:13:27 -06:00
181 changed files with 2635 additions and 988 deletions

View File

@@ -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
View File

@@ -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)

View File

@@ -1,4 +0,0 @@
from tools.bad_board_util import main
if __name__ == "__main__":
main()

View File

@@ -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",
)
],
)

View File

@@ -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),

View 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

View File

@@ -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:

View File

@@ -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()

View 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

View File

@@ -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

View File

@@ -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)

View File

@@ -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."""

View File

@@ -0,0 +1,3 @@
from .antminer import *
from .avalonminer import *
from .whatsminer import *

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View File

@@ -0,0 +1,2 @@
from .S9 import S9
from .T9 import T9

View File

@@ -0,0 +1,3 @@
from .X9 import *
from .X17 import *
from .X19 import *

View 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

View 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

View File

@@ -0,0 +1,2 @@
from .A1047 import Avalon1047
from .A1066 import Avalon1066

View 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"

View 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"

View File

@@ -0,0 +1,2 @@
from .A821 import Avalon821
from .A841 import Avalon841

View File

@@ -0,0 +1,2 @@
from .A8X import *
from .A10X import *

View 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

View 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

View 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

View 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

View 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

View 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

View 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"

View 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

View 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)

View 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"

View 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+"

View 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

View 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

View File

@@ -0,0 +1,2 @@
from .M2X import *
from .M3X import *

View File

@@ -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)}"

View File

@@ -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)}"

View File

@@ -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)}"

View File

@@ -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)}"

View File

@@ -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)}"

View File

@@ -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)}"

View File

@@ -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)}"

View File

@@ -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

View File

@@ -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)}"

View File

@@ -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

View File

@@ -0,0 +1,4 @@
from .bmminer import *
from .bosminer import *
from .cgminer import *
from .hiveon import *

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View File

@@ -0,0 +1,2 @@
from .S9 import BMMinerS9
from .T9 import BMMinerT9

View File

@@ -0,0 +1,3 @@
from .X9 import *
from .X17 import *
from .X19 import *

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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