Compare commits
194 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fbd73881d4 | ||
|
|
68c4dadb63 | ||
|
|
87016670d4 | ||
|
|
8701bbe4e2 | ||
|
|
7d1f125b0b | ||
|
|
e433902bd5 | ||
|
|
a653772968 | ||
|
|
d8b938cd5b | ||
|
|
47d76e325a | ||
|
|
7ee7868094 | ||
|
|
3f1183a4f9 | ||
|
|
2b443497ea | ||
|
|
c3972f9524 | ||
|
|
92bbb21c11 | ||
|
|
1980ff2563 | ||
|
|
93d09a1483 | ||
|
|
690d0d99df | ||
|
|
78f689eb2c | ||
|
|
e68f188e8f | ||
|
|
7eda611fe9 | ||
|
|
1d12817942 | ||
|
|
b24efd4c69 | ||
|
|
5533135b05 | ||
|
|
475054fbe0 | ||
|
|
06bad1bbe0 | ||
|
|
f3746ff756 | ||
|
|
9f16d37c8b | ||
|
|
8a13c7940a | ||
|
|
8bea76ff67 | ||
|
|
1504bd744c | ||
|
|
6449f10615 | ||
|
|
d79509bda7 | ||
|
|
630b847466 | ||
|
|
ed11611919 | ||
|
|
e2431c938d | ||
|
|
60f4b4a5ed | ||
|
|
d41097af20 | ||
|
|
8a5d505731 | ||
|
|
36e76c6f41 | ||
|
|
717b9421dd | ||
|
|
d2f71e8c94 | ||
|
|
697991f28f | ||
|
|
b0e18ab766 | ||
|
|
e39a6921d0 | ||
|
|
aac1be0565 | ||
|
|
683fcb2138 | ||
|
|
9fbbef9b18 | ||
|
|
6e0b9a0a7b | ||
|
|
7f472f6f4f | ||
|
|
b7d7b33ab9 | ||
|
|
da11c0bb1f | ||
|
|
eae433d2bd | ||
|
|
c16bc37aff | ||
|
|
255b06ac9e | ||
|
|
29ec619126 | ||
|
|
247def04ff | ||
|
|
4600e7d953 | ||
|
|
850c266555 | ||
|
|
ad374fe2fb | ||
|
|
5ca39b6fe7 | ||
|
|
b50dd26e6f | ||
|
|
53eaccaa9b | ||
|
|
91f207316a | ||
|
|
1e37418909 | ||
|
|
4c09ba5529 | ||
|
|
7bab4747ad | ||
|
|
fd8cc7378c | ||
|
|
8aeef4d5e7 | ||
|
|
4bafde9da7 | ||
|
|
5a3107aecf | ||
|
|
7e758720f0 | ||
|
|
39e3e249f8 | ||
|
|
118c5b056e | ||
|
|
2c3b5599fe | ||
|
|
e421eaa324 | ||
|
|
75d6bc6808 | ||
|
|
98c547e416 | ||
|
|
45250e36e4 | ||
|
|
fa7544d052 | ||
|
|
53f3fc5ee9 | ||
|
|
1b36de4131 | ||
|
|
6f0c6f6284 | ||
|
|
b7dda5bf87 | ||
|
|
14f33a40c3 | ||
|
|
5c904aced0 | ||
|
|
53a3bbf531 | ||
|
|
50586f1ce7 | ||
|
|
9f6235a0fc | ||
|
|
4d21f150ce | ||
|
|
7c0dfc49dd | ||
|
|
269b13f6c1 | ||
|
|
a9bb7d2e5a | ||
|
|
11295f27a7 | ||
|
|
55aa3dd85b | ||
|
|
20272d4360 | ||
|
|
623dc92ef2 | ||
|
|
2d59394b1e | ||
|
|
26c2095ff1 | ||
|
|
ec7d241caa | ||
|
|
d0432ed1aa | ||
|
|
8c5503d002 | ||
|
|
6d6f950c95 | ||
|
|
30745e54ba | ||
|
|
c3fd94e79e | ||
|
|
2924a8d67b | ||
|
|
9f4c4bb9cf | ||
|
|
3d6eebf06e | ||
|
|
b3d9b6ff7e | ||
|
|
60facacc48 | ||
|
|
b8a6063838 | ||
|
|
bcba2be524 | ||
|
|
f7187d2017 | ||
|
|
d91b7c4406 | ||
|
|
248a7e6d69 | ||
|
|
4f2c3e772a | ||
|
|
95f7146eef | ||
|
|
9d5d19cc6b | ||
|
|
cc38129571 | ||
|
|
3dfd9f237d | ||
|
|
f3fe478dbb | ||
|
|
e10f32ae3d | ||
|
|
4e0924aa0e | ||
|
|
d0d3fd3117 | ||
|
|
4de950d8f4 | ||
|
|
03f2a1f9ba | ||
|
|
2653db90e3 | ||
|
|
ddc8c53eb9 | ||
|
|
eb5d1a24ea | ||
|
|
6c0e80265b | ||
|
|
ad3a4ae414 | ||
|
|
3484d43510 | ||
|
|
dd7e352391 | ||
|
|
a32b61fe5d | ||
|
|
597a178009 | ||
|
|
409b2527f0 | ||
|
|
58234fcf7f | ||
|
|
1bf863cca8 | ||
|
|
6482d04185 | ||
|
|
3b58b11501 | ||
|
|
7485b8ef77 | ||
|
|
d2bea227db | ||
|
|
1b7afaaf7e | ||
|
|
96898d639c | ||
|
|
eb439f4dcf | ||
|
|
69f4349393 | ||
|
|
e371bb577c | ||
|
|
2500ec3869 | ||
|
|
5be3187eec | ||
|
|
be1e9127b0 | ||
|
|
13572c4770 | ||
|
|
08fa3961fe | ||
|
|
b5d2809e9c | ||
|
|
aa538d3079 | ||
|
|
e1500bb75c | ||
|
|
7f00a65598 | ||
|
|
64c473a7d4 | ||
|
|
96d9fe8e6c | ||
|
|
0b27400d27 | ||
|
|
666b9dfe94 | ||
|
|
df3a080c9d | ||
|
|
bf3bd7c2b9 | ||
|
|
37fd60b462 | ||
|
|
2245904740 | ||
|
|
7b1b23016e | ||
|
|
b5fcd62e23 | ||
|
|
9057cde274 | ||
|
|
f6d35888fe | ||
|
|
f2abe9fd9e | ||
|
|
7d1a702804 | ||
|
|
65d1695ce4 | ||
|
|
65fd66b8bf | ||
|
|
5db52c46f3 | ||
|
|
d06cb19da3 | ||
|
|
4530d086da | ||
|
|
0bd679f259 | ||
|
|
1ce5bd0566 | ||
|
|
67c3d05ac3 | ||
|
|
c691868e9b | ||
|
|
f5e15b4046 | ||
|
|
e14df696ee | ||
|
|
ce5dfad850 | ||
|
|
5cb45390be | ||
|
|
b5216a24a6 | ||
|
|
dd175ff3a2 | ||
|
|
9b504a3157 | ||
|
|
0bc3bf20ee | ||
|
|
de5380715c | ||
|
|
00a108252d | ||
|
|
e446176922 | ||
|
|
134c44aedc | ||
|
|
a2bb8b5d9b | ||
|
|
62aaf36fd7 | ||
|
|
63023650a9 | ||
|
|
0025c613f0 |
@@ -1,5 +1,5 @@
|
||||
# pyasic
|
||||
*A set of modules for interfacing with many common types of ASIC bitcoin miners, using both their API and SSH.*
|
||||
*A simplified and standardized interface for Bitcoin ASICs.*
|
||||
|
||||
[](https://github.com/psf/black)
|
||||
[](https://pypi.org/project/pyasic/)
|
||||
|
||||
@@ -15,6 +15,7 @@ Use these instead -
|
||||
#### [BOSMiner API][pyasic.API.bosminer.BOSMinerAPI]
|
||||
#### [BTMiner API][pyasic.API.btminer.BTMinerAPI]
|
||||
#### [CGMiner API][pyasic.API.cgminer.CGMinerAPI]
|
||||
#### [LUXMiner API][pyasic.API.luxminer.LUXMinerAPI]
|
||||
#### [Unknown API][pyasic.API.unknown.UnknownAPI]
|
||||
|
||||
<br>
|
||||
|
||||
7
docs/API/luxminer.md
Normal file
7
docs/API/luxminer.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# pyasic
|
||||
## LUXMinerAPI
|
||||
::: pyasic.API.luxminer.LUXMinerAPI
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
165
docs/generate_miners.py
Normal file
165
docs/generate_miners.py
Normal file
@@ -0,0 +1,165 @@
|
||||
import asyncio
|
||||
import importlib
|
||||
import os
|
||||
import warnings
|
||||
|
||||
from pyasic.miners.miner_factory import MINER_CLASSES, MinerTypes
|
||||
|
||||
warnings.filterwarnings("ignore")
|
||||
|
||||
|
||||
def path(cls):
|
||||
module = importlib.import_module(cls.__module__)
|
||||
return module.__name__ + "." + cls.__name__
|
||||
|
||||
|
||||
def make(cls):
|
||||
p = path(cls)
|
||||
return p.split(".")[2]
|
||||
|
||||
|
||||
def model_type(cls):
|
||||
p = path(cls)
|
||||
return p.split(".")[4]
|
||||
|
||||
|
||||
def backend_str(backend: MinerTypes) -> str:
|
||||
match backend:
|
||||
case MinerTypes.ANTMINER:
|
||||
return "Stock Firmware Antminers"
|
||||
case MinerTypes.AVALONMINER:
|
||||
return "Stock Firmware Avalonminers"
|
||||
case MinerTypes.VNISH:
|
||||
return "Vnish Firmware Miners"
|
||||
case MinerTypes.EPIC:
|
||||
return "ePIC Firmware Miners"
|
||||
case MinerTypes.BRAIINS_OS:
|
||||
return "BOS+ Firmware Miners"
|
||||
case MinerTypes.HIVEON:
|
||||
return "HiveOS Firmware Miners"
|
||||
case MinerTypes.INNOSILICON:
|
||||
return "Stock Firmware Innosilicons"
|
||||
case MinerTypes.WHATSMINER:
|
||||
return "Stock Firmware Whatsminers"
|
||||
case MinerTypes.GOLDSHELL:
|
||||
return "Stock Firmware Goldshells"
|
||||
case MinerTypes.LUX_OS:
|
||||
return "LuxOS Firmware Miners"
|
||||
|
||||
|
||||
def create_url_str(mtype: str):
|
||||
return (
|
||||
mtype.lower()
|
||||
.replace(" ", "-")
|
||||
.replace("(", "")
|
||||
.replace(")", "")
|
||||
.replace("+", "_1")
|
||||
)
|
||||
|
||||
|
||||
HEADER_FORMAT = "# pyasic\n## {} Models\n\n"
|
||||
MINER_HEADER_FORMAT = "## {}\n"
|
||||
DATA_FORMAT = """::: {}
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
"""
|
||||
SUPPORTED_TYPES_HEADER = """# pyasic
|
||||
## Supported Miners
|
||||
|
||||
Supported miner types are here on this list. If your miner (or miner version) is not on this list, please feel free to [open an issue on GitHub](https://github.com/UpstreamData/pyasic/issues) to get it added.
|
||||
|
||||
##### pyasic currently supports the following miners and subtypes:
|
||||
<style>
|
||||
details {
|
||||
margin:0px;
|
||||
padding-top:0px;
|
||||
padding-bottom:0px;
|
||||
}
|
||||
</style>
|
||||
"""
|
||||
BACKEND_TYPE_HEADER = """
|
||||
<details>
|
||||
<summary>{}:</summary>
|
||||
<ul>"""
|
||||
|
||||
MINER_TYPE_HEADER = """
|
||||
<details>
|
||||
<summary>{} Series:</summary>
|
||||
<ul>"""
|
||||
|
||||
MINER_DETAILS = """
|
||||
<li><a href="../{}/{}#{}">{}</a></li>"""
|
||||
|
||||
MINER_TYPE_CLOSER = """
|
||||
</ul>
|
||||
</details>"""
|
||||
BACKEND_TYPE_CLOSER = """
|
||||
</ul>
|
||||
</details>"""
|
||||
|
||||
m_data = {}
|
||||
|
||||
|
||||
for m in MINER_CLASSES:
|
||||
for t in MINER_CLASSES[m]:
|
||||
if t is not None:
|
||||
miner = MINER_CLASSES[m][t]
|
||||
if make(miner) not in m_data:
|
||||
m_data[make(miner)] = {}
|
||||
if model_type(miner) not in m_data[make(miner)]:
|
||||
m_data[make(miner)][model_type(miner)] = []
|
||||
m_data[make(miner)][model_type(miner)].append(miner)
|
||||
|
||||
|
||||
async def create_directory_structure(directory, data):
|
||||
if not os.path.exists(directory):
|
||||
os.makedirs(directory)
|
||||
|
||||
for key, value in data.items():
|
||||
subdirectory = os.path.join(directory, key)
|
||||
if isinstance(value, dict):
|
||||
await create_directory_structure(subdirectory, value)
|
||||
elif isinstance(value, list):
|
||||
file_path = os.path.join(subdirectory + ".md")
|
||||
|
||||
with open(file_path, "w") as file:
|
||||
file.write(HEADER_FORMAT.format(key))
|
||||
for item in value:
|
||||
header = await item("1.1.1.1").get_model()
|
||||
file.write(MINER_HEADER_FORMAT.format(header))
|
||||
file.write(DATA_FORMAT.format(path(item)))
|
||||
|
||||
|
||||
async def create_supported_types(directory):
|
||||
with open(os.path.join(directory, "supported_types.md"), "w") as file:
|
||||
file.write(SUPPORTED_TYPES_HEADER)
|
||||
for mback in MINER_CLASSES:
|
||||
backend_types = {}
|
||||
file.write(BACKEND_TYPE_HEADER.format(backend_str(mback)))
|
||||
for mtype in MINER_CLASSES[mback]:
|
||||
if mtype is None:
|
||||
continue
|
||||
m = MINER_CLASSES[mback][mtype]
|
||||
if model_type(m) not in backend_types:
|
||||
backend_types[model_type(m)] = []
|
||||
backend_types[model_type(m)].append(m)
|
||||
|
||||
for mtype in backend_types:
|
||||
file.write(MINER_TYPE_HEADER.format(mtype))
|
||||
for minstance in backend_types[mtype]:
|
||||
model = await minstance("1.1.1.1").get_model()
|
||||
file.write(
|
||||
MINER_DETAILS.format(
|
||||
make(minstance), mtype, create_url_str(model), model
|
||||
)
|
||||
)
|
||||
file.write(MINER_TYPE_CLOSER)
|
||||
file.write(BACKEND_TYPE_CLOSER)
|
||||
|
||||
|
||||
root_directory = os.path.join(os.getcwd(), "miners")
|
||||
asyncio.run(create_directory_structure(root_directory, m_data))
|
||||
asyncio.run(create_supported_types(root_directory))
|
||||
@@ -19,7 +19,7 @@ Getting started with pyasic is easy. First, find your miner (or miners) on the
|
||||
|
||||
## Scanning for miners
|
||||
To scan for miners in pyasic, we use the class [`MinerNetwork`][pyasic.network.MinerNetwork], which abstracts the search, communication, identification, setup, and return of a miner to 1 command.
|
||||
The command [`MinerNetwork().scan_network_for_miners()`][pyasic.network.MinerNetwork.scan_network_for_miners] returns a list that contains any miners found.
|
||||
The command [`MinerNetwork.scan()`][pyasic.network.MinerNetwork.scan] returns a list that contains any miners found.
|
||||
```python
|
||||
import asyncio # asyncio for handling the async part
|
||||
from pyasic.network import MinerNetwork # miner network handles the scanning
|
||||
@@ -28,7 +28,7 @@ from pyasic.network import MinerNetwork # miner network handles the scanning
|
||||
async def scan_miners(): # define async scan function to allow awaiting
|
||||
# create a miner network
|
||||
# you can pass in any IP and it will use that in a subnet with a /24 mask (255 IPs).
|
||||
network = MinerNetwork("192.168.1.50") # this uses the 192.168.1.0-255 network
|
||||
network = MinerNetwork.from_subnet("192.168.1.50/24") # this uses the 192.168.1.0-255 network
|
||||
|
||||
# scan for miners asynchronously
|
||||
# this will return the correct type of miners if they are supported with all functionality.
|
||||
@@ -42,8 +42,8 @@ if __name__ == "__main__":
|
||||
<br>
|
||||
|
||||
## Creating miners based on IP
|
||||
If you already know the IP address of your miner or miners, you can use the [`MinerFactory`][pyasic.miners.miner_factory.MinerFactory] to communicate and identify the miners, or an abstraction of its functionality, [`get_miner()`][pyasic.miners.miner_factory.MinerFactory.get_miner].
|
||||
The function [`get_miner()`][pyasic.miners.miner_factory.MinerFactory.get_miner] will return any miner it found at the IP address specified, or an `UnknownMiner` if it cannot identify the miner.
|
||||
If you already know the IP address of your miner or miners, you can use the [`MinerFactory`][pyasic.miners.miner_factory.MinerFactory] to communicate and identify the miners, or an abstraction of its functionality, [`get_miner()`][pyasic.miners.get_miner].
|
||||
The function [`get_miner()`][pyasic.miners.get_miner] will return any miner it found at the IP address specified, or an `UnknownMiner` if it cannot identify the miner.
|
||||
```python
|
||||
import asyncio # asyncio for handling the async part
|
||||
from pyasic import get_miner # handles miner creation
|
||||
@@ -76,13 +76,14 @@ This function will return an instance of the dataclass [`MinerData`][pyasic.data
|
||||
Each piece of data in a [`MinerData`][pyasic.data.MinerData] instance can be referenced by getting it as an attribute, such as [`MinerData().hashrate`][pyasic.data.MinerData].
|
||||
```python
|
||||
import asyncio
|
||||
from pyasic.miners.miner_factory import MinerFactory
|
||||
from pyasic import get_miner
|
||||
|
||||
async def gather_miner_data():
|
||||
miner = await MinerFactory().get_miner("192.168.1.75")
|
||||
miner_data = await miner.get_data()
|
||||
print(miner_data) # all data from the dataclass
|
||||
print(miner_data.hashrate) # hashrate of the miner in TH/s
|
||||
miner = await get_miner("192.168.1.75")
|
||||
if miner is not None:
|
||||
miner_data = await miner.get_data()
|
||||
print(miner_data) # all data from the dataclass
|
||||
print(miner_data.hashrate) # hashrate of the miner in TH/s
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(gather_miner_data())
|
||||
@@ -126,6 +127,7 @@ These functions are
|
||||
[`restart_backend`](#restart-backend),
|
||||
[`stop_mining`](#stop-mining),
|
||||
[`resume_mining`](#resume-mining),
|
||||
[`is_mining`](#is-mining),
|
||||
[`send_config`](#send-config), and
|
||||
[`set_power_limit`](#set-power-limit).
|
||||
|
||||
@@ -227,6 +229,14 @@ These functions are
|
||||
|
||||
<br>
|
||||
|
||||
### Is Mining
|
||||
::: pyasic.miners.BaseMiner.is_mining
|
||||
handler: python
|
||||
options:
|
||||
heading_level: 4
|
||||
|
||||
<br>
|
||||
|
||||
### Send Config
|
||||
::: pyasic.miners.BaseMiner.send_config
|
||||
handler: python
|
||||
@@ -253,7 +263,7 @@ Pyasic implements a few dataclasses as helpers to make data return types consist
|
||||
|
||||
[`MinerData`][pyasic.data.MinerData] is a return from the [`get_data()`](#get-data) function, and is used to have a consistent dataset across all returns.
|
||||
|
||||
You can call [`MinerData.asdict()`][pyasic.data.MinerData.asdict] to get the dataclass as a dictionary, and there are many other helper functions contained in the class to convert to different data formats.
|
||||
You can call [`MinerData.as_dict()`][pyasic.data.MinerData.as_dict] to get the dataclass as a dictionary, and there are many other helper functions contained in the class to convert to different data formats.
|
||||
|
||||
[`MinerData`][pyasic.data.MinerData] instances can also be added to each other to combine their data and can be divided by a number to divide all their data, allowing you to get average data from many miners by doing -
|
||||
```python
|
||||
@@ -278,3 +288,28 @@ It is the return from [`get_config()`](#get-config).
|
||||
|
||||
Each miner has a unique way to convert the [`MinerConfig`][pyasic.config.MinerConfig] to their specific type, there are helper functions in the class.
|
||||
In most cases these helper functions should not be used, as [`send_config()`](#send-config) takes a [`MinerConfig`][pyasic.config.MinerConfig] and will do the conversion to the right type for you.
|
||||
|
||||
## Settings
|
||||
`pyasic` has settings designed to make using large groups of miners easier. You can set the default password for all types of miners using the [`pyasic.settings`][pyasic.settings] module, used as follows:
|
||||
|
||||
```python
|
||||
from pyasic import settings
|
||||
|
||||
settings.update("default_antminer_password", "my_pwd")
|
||||
```
|
||||
|
||||
Here are of all the settings, and their default values:
|
||||
```
|
||||
"network_ping_retries": 1,
|
||||
"network_ping_timeout": 3,
|
||||
"network_scan_threads": 300,
|
||||
"factory_get_retries": 1,
|
||||
"get_data_retries": 1,
|
||||
"default_whatsminer_password": "admin",
|
||||
"default_innosilicon_password": "admin",
|
||||
"default_antminer_password": "root",
|
||||
"default_bosminer_password": "root",
|
||||
"default_vnish_password": "admin",
|
||||
"default_epic_password": "letmein",
|
||||
"default_goldshell_password": "123456789",
|
||||
```
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
# pyasic
|
||||
## X15 Models
|
||||
|
||||
|
||||
## Z15
|
||||
|
||||
::: pyasic.miners.zec.antminer.cgminer.X15.Z15.CGMinerZ15
|
||||
::: pyasic.miners.antminer.cgminer.X15.Z15.CGMinerZ15
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
|
||||
@@ -2,116 +2,114 @@
|
||||
## X17 Models
|
||||
|
||||
## S17
|
||||
|
||||
::: pyasic.miners.btc.antminer.bmminer.X17.S17.BMMinerS17
|
||||
::: pyasic.miners.antminer.bmminer.X17.S17.BMMinerS17
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S17+
|
||||
|
||||
::: pyasic.miners.btc.antminer.bmminer.X17.S17_Plus.BMMinerS17Plus
|
||||
::: pyasic.miners.antminer.bmminer.X17.S17.BMMinerS17Plus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S17 Pro
|
||||
|
||||
::: pyasic.miners.btc.antminer.bmminer.X17.S17_Pro.BMMinerS17Pro
|
||||
::: pyasic.miners.antminer.bmminer.X17.S17.BMMinerS17Pro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S17e
|
||||
|
||||
::: pyasic.miners.btc.antminer.bmminer.X17.S17e.BMMinerS17e
|
||||
::: pyasic.miners.antminer.bmminer.X17.S17.BMMinerS17e
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## T17
|
||||
|
||||
::: pyasic.miners.btc.antminer.bmminer.X17.T17.BMMinerT17
|
||||
::: pyasic.miners.antminer.bmminer.X17.T17.BMMinerT17
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## T17+
|
||||
|
||||
::: pyasic.miners.btc.antminer.bmminer.X17.T17_Plus.BMMinerT17Plus
|
||||
::: pyasic.miners.antminer.bmminer.X17.T17.BMMinerT17Plus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
|
||||
## T17e
|
||||
|
||||
::: pyasic.miners.btc.antminer.bmminer.X17.T17e.BMMinerT17e
|
||||
::: pyasic.miners.antminer.bmminer.X17.T17.BMMinerT17e
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
|
||||
## S17 (BOS)
|
||||
|
||||
::: pyasic.miners.btc.antminer.bosminer.X17.S17.BOSMinerS17
|
||||
::: pyasic.miners.antminer.bosminer.X17.S17.BOSMinerS17
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S17+ (BOS)
|
||||
|
||||
::: pyasic.miners.btc.antminer.bosminer.X17.S17_Plus.BOSMinerS17Plus
|
||||
::: pyasic.miners.antminer.bosminer.X17.S17.BOSMinerS17Plus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S17 Pro (BOS)
|
||||
|
||||
::: pyasic.miners.btc.antminer.bosminer.X17.S17_Pro.BOSMinerS17Pro
|
||||
::: pyasic.miners.antminer.bosminer.X17.S17.BOSMinerS17Pro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S17e (BOS)
|
||||
|
||||
::: pyasic.miners.btc.antminer.bosminer.X17.S17e.BOSMinerS17e
|
||||
::: pyasic.miners.antminer.bosminer.X17.S17.BOSMinerS17e
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## T17 (BOS)
|
||||
|
||||
::: pyasic.miners.btc.antminer.bosminer.X17.T17.BOSMinerT17
|
||||
::: pyasic.miners.antminer.bosminer.X17.T17.BOSMinerT17
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## T17+ (BOS)
|
||||
|
||||
::: pyasic.miners.btc.antminer.bosminer.X17.T17_Plus.BOSMinerT17Plus
|
||||
::: pyasic.miners.antminer.bosminer.X17.T17.BOSMinerT17Plus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
|
||||
## T17e (BOS)
|
||||
|
||||
::: pyasic.miners.btc.antminer.bosminer.X17.T17e.BOSMinerT17e
|
||||
::: pyasic.miners.antminer.bosminer.X17.T17.BOSMinerT17e
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S17+ (VNish)
|
||||
::: pyasic.miners.antminer.vnish.X17.S17.VNishS17Plus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S17 Pro (VNish)
|
||||
::: pyasic.miners.antminer.vnish.X17.S17.VNishS17Pro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
|
||||
@@ -2,109 +2,233 @@
|
||||
## X19 Models
|
||||
|
||||
## S19
|
||||
|
||||
::: pyasic.miners.btc.antminer.bmminer.X19.S19.BMMinerS19
|
||||
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19L
|
||||
|
||||
::: pyasic.miners.btc.antminer.bmminer.X19.S19L.BMMinerS19L
|
||||
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19L
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19 Pro
|
||||
|
||||
::: pyasic.miners.btc.antminer.bmminer.X19.S19_Pro.BMMinerS19Pro
|
||||
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19Pro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
|
||||
## S19a
|
||||
|
||||
::: pyasic.miners.btc.antminer.bmminer.X19.S19a.BMMinerS19a
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
|
||||
## S19j
|
||||
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19j
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
::: pyasic.miners.btc.antminer.bmminer.X19.S19j.BMMinerS19j
|
||||
## S19i
|
||||
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19i
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19+
|
||||
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19Plus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19j No PIC
|
||||
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19jNoPIC
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19 Pro+
|
||||
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19ProPlus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19j Pro
|
||||
|
||||
::: pyasic.miners.btc.antminer.bmminer.X19.S19j_Pro.BMMinerS19jPro
|
||||
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19jPro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19 XP
|
||||
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19XP
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
::: pyasic.miners.btc.antminer.bmminer.X19.S19_XP.BMMinerS19XP
|
||||
## S19a
|
||||
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19a
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19a Pro
|
||||
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19aPro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## T19
|
||||
|
||||
::: pyasic.miners.btc.antminer.bmminer.X19.T19.BMMinerT19
|
||||
::: pyasic.miners.antminer.bmminer.X19.T19.BMMinerT19
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
|
||||
## S19 (BOS)
|
||||
|
||||
::: pyasic.miners.btc.antminer.bosminer.X19.S19.BOSMinerS19
|
||||
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19 Pro (BOS)
|
||||
|
||||
::: pyasic.miners.btc.antminer.bosminer.X19.S19_Pro.BOSMinerS19Pro
|
||||
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19Pro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
|
||||
## S19j (BOS)
|
||||
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19j
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
::: pyasic.miners.btc.antminer.bosminer.X19.S19j.BOSMinerS19j
|
||||
## S19j No PIC (BOS)
|
||||
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19jNoPIC
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19j Pro (BOS)
|
||||
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19jPro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
::: pyasic.miners.btc.antminer.bosminer.X19.S19j_Pro.BOSMinerS19jPro
|
||||
## S19j Pro (BOS)
|
||||
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19jPro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## T19 (BOS)
|
||||
|
||||
::: pyasic.miners.btc.antminer.bosminer.X19.T19.BOSMinerT19
|
||||
::: pyasic.miners.antminer.bosminer.X19.T19.BOSMinerT19
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19 (VNish)
|
||||
::: pyasic.miners.antminer.vnish.X19.S19.VNishS19
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19 No PIC (VNish)
|
||||
::: pyasic.miners.antminer.vnish.X19.S19.VNishS19NoPIC
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19 Pro (VNish)
|
||||
::: pyasic.miners.antminer.vnish.X19.S19.VNishS19Pro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19j (VNish)
|
||||
::: pyasic.miners.antminer.vnish.X19.S19.VNishS19j
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19j Pro (VNish)
|
||||
::: pyasic.miners.antminer.vnish.X19.S19.VNishS19jPro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19a (VNish)
|
||||
::: pyasic.miners.antminer.vnish.X19.S19.VNishS19a
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19a Pro (VNish)
|
||||
::: pyasic.miners.antminer.vnish.X19.S19.VNishS19aPro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## T19 (VNish)
|
||||
::: pyasic.miners.antminer.vnish.X19.T19.VNishT19
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19 (ePIC)
|
||||
::: pyasic.miners.antminer.epic.X19.S19.ePICS19
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19 Pro (ePIC)
|
||||
::: pyasic.miners.antminer.epic.X19.S19.ePICS19Pro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19j (ePIC)
|
||||
::: pyasic.miners.antminer.epic.X19.S19.ePICS19j
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19j Pro (ePIC)
|
||||
::: pyasic.miners.antminer.epic.X19.S19.ePICS19jPro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19 XP (ePIC)
|
||||
::: pyasic.miners.antminer.epic.X19.S19.ePICS19XP
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
|
||||
@@ -1,11 +1,31 @@
|
||||
# pyasic
|
||||
## X3 Models
|
||||
|
||||
|
||||
## HS3
|
||||
|
||||
::: pyasic.miners.hns.antminer.cgminer.X3.HS3.CGMinerHS3
|
||||
## D3
|
||||
::: pyasic.miners.antminer.cgminer.X3.D3.CGMinerD3
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## HS3
|
||||
::: pyasic.miners.antminer.bmminer.X3.HS3.BMMinerHS3
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## L3+
|
||||
::: pyasic.miners.antminer.bmminer.X3.L3.BMMinerL3Plus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## L3+ (VNish)
|
||||
::: pyasic.miners.antminer.vnish.X3.L3.VnishL3Plus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
# pyasic
|
||||
## X5 Models
|
||||
|
||||
|
||||
## DR5
|
||||
|
||||
::: pyasic.miners.dcr.antminer.cgminer.X5.DR5.CGMinerDR5
|
||||
::: pyasic.miners.antminer.cgminer.X5.DR5.CGMinerDR5
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
# pyasic
|
||||
## X7 Models
|
||||
|
||||
|
||||
## L7
|
||||
|
||||
::: pyasic.miners.ltc.antminer.bmminer.X7.L7.BMMinerL7
|
||||
::: pyasic.miners.antminer.bmminer.X7.L7.BMMinerL7
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
|
||||
@@ -1,44 +1,59 @@
|
||||
# pyasic
|
||||
## X9 Models
|
||||
|
||||
|
||||
## X9 (BOS)
|
||||
|
||||
::: pyasic.miners.btc.antminer.bosminer.X9.S9.BOSMinerS9
|
||||
## E9Pro
|
||||
::: pyasic.miners.antminer.bmminer.X9.E9.BMMinerE9Pro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
|
||||
## S9
|
||||
|
||||
::: pyasic.miners.btc.antminer.bmminer.X9.S9.BMMinerS9
|
||||
::: pyasic.miners.antminer.bmminer.X9.S9.BMMinerS9
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S9i
|
||||
::: pyasic.miners.antminer.bmminer.X9.S9.BMMinerS9i
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
::: pyasic.miners.btc.antminer.bmminer.X9.S9i.BMMinerS9i
|
||||
## S9j
|
||||
::: pyasic.miners.antminer.bmminer.X9.S9.BMMinerS9j
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## T9
|
||||
|
||||
::: pyasic.miners.btc.antminer.bmminer.X9.T9.BMMinerT9
|
||||
::: pyasic.miners.antminer.bmminer.X9.T9.BMMinerT9
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## E9 Pro
|
||||
|
||||
::: pyasic.miners.etc.antminer.cgminer.X9.E9_Pro.CGMinerE9Pro
|
||||
## S9 (BOS)
|
||||
::: pyasic.miners.antminer.bosminer.X9.S9.BOSMinerS9
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## T9 (Hiveon)
|
||||
::: pyasic.miners.antminer.hiveon.X9.T9.HiveonT9
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S9 (LuxOS)
|
||||
::: pyasic.miners.antminer.luxos.X9.S9.LUXMinerS9
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
|
||||
@@ -1,26 +1,24 @@
|
||||
# pyasic
|
||||
## A10X Models
|
||||
|
||||
## A1026
|
||||
|
||||
::: pyasic.miners.btc.avalonminer.cgminer.A10X.A1026.CGMinerAvalon1026
|
||||
## Avalon 1026
|
||||
::: pyasic.miners.avalonminer.cgminer.A10X.A1026.CGMinerAvalon1026
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## A1047
|
||||
|
||||
::: pyasic.miners.btc.avalonminer.cgminer.A10X.A1047.CGMinerAvalon1047
|
||||
## Avalon 1047
|
||||
::: pyasic.miners.avalonminer.cgminer.A10X.A1047.CGMinerAvalon1047
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## A1066
|
||||
|
||||
::: pyasic.miners.btc.avalonminer.cgminer.A10X.A1066.CGMinerAvalon1066
|
||||
## Avalon 1066
|
||||
::: pyasic.miners.avalonminer.cgminer.A10X.A1066.CGMinerAvalon1066
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
|
||||
10
docs/miners/avalonminer/A11X.md
Normal file
10
docs/miners/avalonminer/A11X.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# pyasic
|
||||
## A11X Models
|
||||
|
||||
## Avalon 1166 Pro
|
||||
::: pyasic.miners.avalonminer.cgminer.A11X.A1166.CGMinerAvalon1166Pro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
10
docs/miners/avalonminer/A12X.md
Normal file
10
docs/miners/avalonminer/A12X.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# pyasic
|
||||
## A12X Models
|
||||
|
||||
## Avalon 1246
|
||||
::: pyasic.miners.avalonminer.cgminer.A12X.A1246.CGMinerAvalon1246
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
@@ -1,26 +1,24 @@
|
||||
# pyasic
|
||||
## A7X Models
|
||||
|
||||
## A721
|
||||
|
||||
::: pyasic.miners.btc.avalonminer.cgminer.A7X.A721.CGMinerAvalon721
|
||||
## Avalon 721
|
||||
::: pyasic.miners.avalonminer.cgminer.A7X.A721.CGMinerAvalon721
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## A741
|
||||
|
||||
::: pyasic.miners.btc.avalonminer.cgminer.A7X.A741.CGMinerAvalon741
|
||||
## Avalon 741
|
||||
::: pyasic.miners.avalonminer.cgminer.A7X.A741.CGMinerAvalon741
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## A761
|
||||
|
||||
::: pyasic.miners.btc.avalonminer.cgminer.A7X.A761.CGMinerAvalon761
|
||||
## Avalon 761
|
||||
::: pyasic.miners.avalonminer.cgminer.A7X.A761.CGMinerAvalon761
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
|
||||
@@ -1,26 +1,24 @@
|
||||
# pyasic
|
||||
## A8X Models
|
||||
|
||||
## A821
|
||||
|
||||
::: pyasic.miners.btc.avalonminer.cgminer.A8X.A821.CGMinerAvalon821
|
||||
## Avalon 821
|
||||
::: pyasic.miners.avalonminer.cgminer.A8X.A821.CGMinerAvalon821
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## A841
|
||||
|
||||
::: pyasic.miners.btc.avalonminer.cgminer.A8X.A841.CGMinerAvalon841
|
||||
## Avalon 841
|
||||
::: pyasic.miners.avalonminer.cgminer.A8X.A841.CGMinerAvalon841
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## A851
|
||||
|
||||
::: pyasic.miners.btc.avalonminer.cgminer.A8X.A851.CGMinerAvalon851
|
||||
## Avalon 851
|
||||
::: pyasic.miners.avalonminer.cgminer.A8X.A851.CGMinerAvalon851
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# pyasic
|
||||
## A9X Models
|
||||
|
||||
## A921
|
||||
|
||||
::: pyasic.miners.btc.avalonminer.cgminer.A9X.A921.CGMinerAvalon921
|
||||
## Avalon 921
|
||||
::: pyasic.miners.avalonminer.cgminer.A9X.A921.CGMinerAvalon921
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
# pyasic
|
||||
## CKX Models
|
||||
## ePIC Backend
|
||||
|
||||
## CK5
|
||||
|
||||
::: pyasic.miners.ckb.goldshell.bfgminer.CKX.CK5.BFGMinerCK5
|
||||
::: pyasic.miners.backends.epic.ePIC
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
@@ -1,9 +1,7 @@
|
||||
# pyasic
|
||||
## HSX Models
|
||||
## LUXMiner Backend
|
||||
|
||||
## HS5
|
||||
|
||||
::: pyasic.miners.hns.goldshell.bfgminer.HSX.HS5.BFGMinerHS5
|
||||
::: pyasic.miners.backends.luxminer.LUXMiner
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
8
docs/miners/backends/vnish.md
Normal file
8
docs/miners/backends/vnish.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# pyasic
|
||||
## VNish Backend
|
||||
|
||||
::: pyasic.miners.backends.vnish.VNish
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
@@ -1,19 +0,0 @@
|
||||
# pyasic
|
||||
## KDX Models
|
||||
|
||||
## KD5
|
||||
|
||||
::: pyasic.miners.kda.goldshell.bfgminer.KDX.KD5.BFGMinerKD5
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
|
||||
## KD Max
|
||||
|
||||
::: pyasic.miners.kda.goldshell.bfgminer.KDX.KDMax.BFGMinerKDMax
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
24
docs/miners/goldshell/X5.md
Normal file
24
docs/miners/goldshell/X5.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# pyasic
|
||||
## X5 Models
|
||||
|
||||
## CK5
|
||||
::: pyasic.miners.goldshell.bfgminer.X5.CK5.BFGMinerCK5
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## HS5
|
||||
::: pyasic.miners.goldshell.bfgminer.X5.HS5.BFGMinerHS5
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## KD5
|
||||
::: pyasic.miners.goldshell.bfgminer.X5.KD5.BFGMinerKD5
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
10
docs/miners/goldshell/XMax.md
Normal file
10
docs/miners/goldshell/XMax.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# pyasic
|
||||
## XMax Models
|
||||
|
||||
## KD Max
|
||||
::: pyasic.miners.goldshell.bfgminer.XMax.KDMax.BFGMinerKDMax
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
## A10X Models
|
||||
|
||||
## A10X
|
||||
|
||||
::: pyasic.miners.etc.innosilicon.cgminer.A10X.A10X.CGMinerA10X
|
||||
::: pyasic.miners.innosilicon.cgminer.A10X.A10X.CGMinerA10X
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
## T3X Models
|
||||
|
||||
## T3H+
|
||||
|
||||
::: pyasic.miners.btc.innosilicon.cgminer.T3X.T3H_Plus.CGMinerInnosiliconT3HPlus
|
||||
::: pyasic.miners.innosilicon.cgminer.T3X.T3H.CGMinerT3HPlus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
# pyasic
|
||||
## Miner Factory
|
||||
|
||||
[`MinerFactory`][pyasic.miners.miner_factory.MinerFactory] is the way to create miner types in `pyasic`. The most important method is [`get_miner()`][pyasic.get_miner], which is mapped to [`pyasic.get_miner()`][pyasic.get_miner], and should be used from there.
|
||||
|
||||
The instance used for [`pyasic.get_miner()`][pyasic.get_miner] is `pyasic.miner_factory`.
|
||||
|
||||
[`MinerFactory`][pyasic.MinerFactory] also keeps a cache, which can be cleared if needed with `pyasic.miner_factory.clear_cached_miners()`.
|
||||
|
||||
Finally, there is functionality to get multiple miners without using `asyncio.gather()` explicitly. Use `pyasic.miner_factory.get_multiple_miners()` with a list of IPs as strings to get a list of miner instances. You can also get multiple miners with an `AsyncGenerator` by using `pyasic.miner_factory.get_miner_generator()`.
|
||||
|
||||
::: pyasic.miners.miner_factory.MinerFactory
|
||||
handler: python
|
||||
options:
|
||||
@@ -8,6 +16,14 @@
|
||||
heading_level: 4
|
||||
<br>
|
||||
|
||||
## Get Miner
|
||||
::: pyasic.miners.get_miner
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
<br>
|
||||
|
||||
## AnyMiner
|
||||
::: pyasic.miners.miner_factory.AnyMiner
|
||||
handler: python
|
||||
|
||||
@@ -11,37 +11,74 @@ details {
|
||||
padding-bottom:0px;
|
||||
}
|
||||
</style>
|
||||
<details style="margin:0px; padding-top:0px; padding-bottom:0px;">
|
||||
<summary>Braiins OS+ Devices:</summary>
|
||||
|
||||
<details>
|
||||
<summary>Stock Firmware Antminers:</summary>
|
||||
<ul>
|
||||
<details>
|
||||
<summary>X19 Series:</summary>
|
||||
<summary>X3 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X19#s19-bos">S19</a></li>
|
||||
<li><a href="../antminer/X19#s19-pro-bos">S19 Pro</a></li>
|
||||
<li><a href="../antminer/X19#s19j-bos">S19j</a></li>
|
||||
<li><a href="../antminer/X19#s19j-pro-bos">S19j Pro</a></li>
|
||||
<li><a href="../antminer/X19#t19-bos">T19</a></li>
|
||||
<li><a href="../antminer/X3#d3">D3</a></li>
|
||||
<li><a href="../antminer/X3#hs3">HS3</a></li>
|
||||
<li><a href="../antminer/X3#l3_1">L3+</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>X17 Series:</summary>
|
||||
<summary>X5 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X17#s17-bos">S17</a></li>
|
||||
<li><a href="../antminer/X17#s17-plus-bos">S17+</a></li>
|
||||
<li><a href="../antminer/X17#s17-pro-bos">S17 Pro</a></li>
|
||||
<li><a href="../antminer/X17#s17e-bos">S17e</a></li>
|
||||
<li><a href="../antminer/X17#t17-bos">T17</a></li>
|
||||
<li><a href="../antminer/X17#t17-plus-bos">T17+</a></li>
|
||||
<li><a href="../antminer/X17#t17e-bos">T17e</a></li>
|
||||
<li><a href="../antminer/X5#dr5">DR5</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>X7 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X7#l7">L7</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>X9 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X9#s9-bos">S9</a></li>
|
||||
<li><a href="../antminer/X9#s9-bos">S9i</a></li>
|
||||
<li><a href="../antminer/X9#s9-bos">S9j</a></li>
|
||||
<li><a href="../antminer/X9#e9pro">E9Pro</a></li>
|
||||
<li><a href="../antminer/X9#s9">S9</a></li>
|
||||
<li><a href="../antminer/X9#s9i">S9i</a></li>
|
||||
<li><a href="../antminer/X9#s9j">S9j</a></li>
|
||||
<li><a href="../antminer/X9#t9">T9</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>X15 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X15#z15">Z15</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>X17 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X17#s17">S17</a></li>
|
||||
<li><a href="../antminer/X17#s17_1">S17+</a></li>
|
||||
<li><a href="../antminer/X17#s17-pro">S17 Pro</a></li>
|
||||
<li><a href="../antminer/X17#s17e">S17e</a></li>
|
||||
<li><a href="../antminer/X17#t17">T17</a></li>
|
||||
<li><a href="../antminer/X17#t17_1">T17+</a></li>
|
||||
<li><a href="../antminer/X17#t17e">T17e</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>X19 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X19#s19">S19</a></li>
|
||||
<li><a href="../antminer/X19#s19l">S19L</a></li>
|
||||
<li><a href="../antminer/X19#s19-pro">S19 Pro</a></li>
|
||||
<li><a href="../antminer/X19#s19j">S19j</a></li>
|
||||
<li><a href="../antminer/X19#s19i">S19i</a></li>
|
||||
<li><a href="../antminer/X19#s19_1">S19+</a></li>
|
||||
<li><a href="../antminer/X19#s19j-no-pic">S19j No PIC</a></li>
|
||||
<li><a href="../antminer/X19#s19-pro_1">S19 Pro+</a></li>
|
||||
<li><a href="../antminer/X19#s19j-pro">S19j Pro</a></li>
|
||||
<li><a href="../antminer/X19#s19-xp">S19 XP</a></li>
|
||||
<li><a href="../antminer/X19#s19a">S19a</a></li>
|
||||
<li><a href="../antminer/X19#s19a-pro">S19a Pro</a></li>
|
||||
<li><a href="../antminer/X19#t19">T19</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
@@ -51,440 +88,210 @@ details {
|
||||
<ul>
|
||||
<details>
|
||||
<summary>M2X Series:</summary>
|
||||
<ul>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M2X/#M20'>M20</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M2X/#M20V10'>M20V10</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M2X/#M20S'>M20S</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M2X/#M20SV10'>M20SV10</a></li>
|
||||
<li><a href='../whatsminer/M2X/#M20SV20'>M20SV20</a></li>
|
||||
<li><a href='../whatsminer/M2X/#M20SV30'>M20SV30</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M2X/#M20S_1'>M20S+</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M2X/#M20S_1V30'>M20S+V30</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M2X/#M21'>M21</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M2X/#M21V10'>M21V10</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M2X/#M21S'>M21S</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M2X/#M21SV20'>M21SV20</a></li>
|
||||
<li><a href='../whatsminer/M2X/#M21SV60'>M21SV60</a></li>
|
||||
<li><a href='../whatsminer/M2X/#M21SV70'>M21SV70</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M2X/#M21S_1'>M21S+</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M2X/#M21S_1V20'>M21S+V20</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M2X/#M29'>M29</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M2X/#M29V10'>M29V10</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../whatsminer/M2X#m20-v10">M20 V10</a></li>
|
||||
<li><a href="../whatsminer/M2X#m20s-v10">M20S V10</a></li>
|
||||
<li><a href="../whatsminer/M2X#m20s-v20">M20S V20</a></li>
|
||||
<li><a href="../whatsminer/M2X#m20s-v30">M20S V30</a></li>
|
||||
<li><a href="../whatsminer/M2X#m20p-v10">M20P V10</a></li>
|
||||
<li><a href="../whatsminer/M2X#m20p-v30">M20P V30</a></li>
|
||||
<li><a href="../whatsminer/M2X#m20s_1-v30">M20S+ V30</a></li>
|
||||
<li><a href="../whatsminer/M2X#m21-v10">M21 V10</a></li>
|
||||
<li><a href="../whatsminer/M2X#m21s-v20">M21S V20</a></li>
|
||||
<li><a href="../whatsminer/M2X#m21s-v60">M21S V60</a></li>
|
||||
<li><a href="../whatsminer/M2X#m21s-v70">M21S V70</a></li>
|
||||
<li><a href="../whatsminer/M2X#m21s_1-v20">M21S+ V20</a></li>
|
||||
<li><a href="../whatsminer/M2X#m29-v10">M29 V10</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>M3X Series:</summary>
|
||||
<ul>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M3X/#M30'>M30</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M3X/#M30V10'>M30V10</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30V20'>M30V20</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M3X/#M30S'>M30S</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M3X/#M30SV10'>M30SV10</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30SV20'>M30SV20</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30SV30'>M30SV30</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30SV40'>M30SV40</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30SV50'>M30SV50</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30SV60'>M30SV60</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30SV70'>M30SV70</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30SV80'>M30SV80</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30SVE10'>M30SVE10</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30SVE20'>M30SVE20</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30SVE30'>M30SVE30</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30SVE40'>M30SVE40</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30SVE50'>M30SVE50</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30SVE60'>M30SVE60</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30SVE70'>M30SVE70</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30SVF10'>M30SVF10</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30SVF20'>M30SVF20</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30SVF30'>M30SVF30</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30SVG10'>M30SVG10</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30SVG20'>M30SVG20</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30SVG30'>M30SVG30</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30SVG40'>M30SVG40</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30SVH10'>M30SVH10</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30SVH20'>M30SVH20</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30SVH30'>M30SVH30</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30SVH40'>M30SVH40</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30SVH50'>M30SVH50</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30SVH60'>M30SVH60</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30SVI20'>M30SVI20</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M3X/#M30S_1'>M30S+</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M3X/#M30S_1V10'>M30S+V10</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_1V20'>M30S+V20</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_1V30'>M30S+V30</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_1V40'>M30S+V40</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_1V50'>M30S+V50</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_1V60'>M30S+V60</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_1V70'>M30S+V70</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_1V80'>M30S+V80</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_1V90'>M30S+V90</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_1V100'>M30S+V100</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_1VE30'>M30S+VE30</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_1VE40'>M30S+VE40</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_1VE50'>M30S+VE50</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_1VE60'>M30S+VE60</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_1VE70'>M30S+VE70</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_1VE80'>M30S+VE80</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_1VE90'>M30S+VE90</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_1VE100'>M30S+VE100</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_1VF20'>M30S+VF20</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_1VF30'>M30S+VF30</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M36S_1VG30'>M36S+VG30</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_1VG30'>M30S+VG30</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_1VG40'>M30S+VG40</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_1VG50'>M30S+VG50</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_1VG60'>M30S+VG60</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_1VH10'>M30S+VH10</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_1VH20'>M30S+VH20</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_1VH30'>M30S+VH30</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_1VH40'>M30S+VH40</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_1VH50'>M30S+VH50</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_1VH60'>M30S+VH60</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M3X/#M30S_2'>M30S++</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M3X/#M30S_2V10'>M30S++V10</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_2V20'>M30S++V20</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_2VE30'>M30S++VE30</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_2VE40'>M30S++VE40</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_2VE50'>M30S++VE50</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_2VF40'>M30S++VF40</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_2VG30'>M30S++VG30</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_2VG40'>M30S++VG40</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_2VG50'>M30S++VG50</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_2VH10'>M30S++VH10</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_2VH20'>M30S++VH20</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_2VH30'>M30S++VH30</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_2VH40'>M30S++VH40</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_2VH50'>M30S++VH50</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_2VH60'>M30S++VH60</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_2VH70'>M30S++VH70</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_2VH80'>M30S++VH80</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_2VH90'>M30S++VH90</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_2VH100'>M30S++VH100</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_2VJ20'>M30S++VJ20</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M30S_2VJ30'>M30S++VJ30</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M3X/#M31'>M31</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M3X/#M31V10'>M31V10</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M31V20'>M31V20</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M3X/#M31S'>M31S</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M3X/#M31SV10'>M31SV10</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M31SV20'>M31SV20</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M31SV30'>M31SV30</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M31SV40'>M31SV40</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M31SV50'>M31SV50</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M31SV60'>M31SV60</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M31SV70'>M31SV70</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M31SV80'>M31SV80</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M31SV90'>M31SV90</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M31SVE10'>M31SVE10</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M31SVE20'>M31SVE20</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M31SVE30'>M31SVE30</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M3X/#M31SE'>M31SE</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M3X/#M31SEV10'>M31SEV10</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M31SEV20'>M31SEV20</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M31SEV30'>M31SEV30</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M3X/#M31H'>M31H</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M3X/#M31HV40'>M31HV40</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M3X/#M31S_1'>M31S+</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M3X/#M31S_1V10'>M31S+V10</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M31S_1V20'>M31S+V20</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M31S_1V30'>M31S+V30</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M31S_1V40'>M31S+V40</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M31S_1V50'>M31S+V50</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M31S_1V60'>M31S+V60</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M31S_1V80'>M31S+V80</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M31S_1V90'>M31S+V90</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M31S_1V100'>M31S+V100</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M31S_1VE10'>M31S+VE10</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M31S_1VE20'>M31S+VE20</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M31S_1VE30'>M31S+VE30</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M31S_1VE40'>M31S+VE40</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M31S_1VE50'>M31S+VE50</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M31S_1VE60'>M31S+VE60</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M31S_1VE80'>M31S+VE80</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M31S_1VF20'>M31S+VF20</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M31S_1VF30'>M31S+VF30</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M31S_1VG20'>M31S+VG20</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M31S_1VG30'>M31S+VG30</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M3X/#M32'>M32</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M3X/#M32V10'>M32V10</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M32V20'>M32V20</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M3X/#M33'>M33</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M3X/#M33V10'>M33V10</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M33V20'>M33V20</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M33V30'>M33V30</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M3X/#M33S'>M33S</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M3X/#M33SVG30'>M33SVG30</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M3X/#M33S_1'>M33S+</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M3X/#M33S_1VH20'>M33S+VH20</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M33S_1VH30'>M33S+VH30</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M3X/#M33S_2'>M33S++</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M3X/#M33S_2VH20'>M33S++VH20</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M33S_2VH30'>M33S++VH30</a></li>
|
||||
<li><a href='../whatsminer/M3X/#M33S_2VG40'>M33S++VG40</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M3X/#M34S_1'>M34S+</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M3X/#M34S_1VE10'>M34S+VE10</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M3X/#M36S'>M36S</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M3X/#M36SVE10'>M36SVE10</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M3X/#M36S_1'>M36S+</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M3X/#M36S_1VG30'>M36S+VG30</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M3X/#M36S_2'>M36S++</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M3X/#M36S_2VH30'>M36S++VH30</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M3X/#M39'>M39</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M3X/#M39V20'>M39V20</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../whatsminer/M3X#m30-v10">M30 V10</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30-v20">M30 V20</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30k-v10">M30K V10</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30l-v10">M30L V10</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-v10">M30S V10</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-v20">M30S V20</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-v30">M30S V30</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-v40">M30S V40</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-v50">M30S V50</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-v60">M30S V60</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-v70">M30S V70</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-v80">M30S V80</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-ve10">M30S VE10</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-ve20">M30S VE20</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-ve30">M30S VE30</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-ve40">M30S VE40</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-ve50">M30S VE50</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-ve60">M30S VE60</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-ve70">M30S VE70</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-vf10">M30S VF10</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-vf20">M30S VF20</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-vf30">M30S VF30</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-vg10">M30S VG10</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-vg20">M30S VG20</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-vg30">M30S VG30</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-vg40">M30S VG40</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-vh10">M30S VH10</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-vh20">M30S VH20</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-vh30">M30S VH30</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-vh40">M30S VH40</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-vh50">M30S VH50</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-vh60">M30S VH60</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-vi20">M30S VI20</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-v10">M30S+ V10</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-v20">M30S+ V20</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-v30">M30S+ V30</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-v40">M30S+ V40</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-v50">M30S+ V50</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-v60">M30S+ V60</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-v70">M30S+ V70</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-v80">M30S+ V80</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-v90">M30S+ V90</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-v100">M30S+ V100</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-ve30">M30S+ VE30</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-ve40">M30S+ VE40</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-ve50">M30S+ VE50</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-ve60">M30S+ VE60</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-ve70">M30S+ VE70</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-ve80">M30S+ VE80</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-ve90">M30S+ VE90</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-ve100">M30S+ VE100</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vf20">M30S+ VF20</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vf30">M30S+ VF30</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vg20">M30S+ VG20</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vg30">M30S+ VG30</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vg40">M30S+ VG40</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vg50">M30S+ VG50</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vg60">M30S+ VG60</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vh10">M30S+ VH10</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vh20">M30S+ VH20</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vh30">M30S+ VH30</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vh40">M30S+ VH40</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vh50">M30S+ VH50</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vh60">M30S+ VH60</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-v10">M30S++ V10</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-v20">M30S++ V20</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-ve30">M30S++ VE30</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-ve40">M30S++ VE40</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-ve50">M30S++ VE50</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vf40">M30S++ VF40</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vg30">M30S++ VG30</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vg40">M30S++ VG40</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vg50">M30S++ VG50</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vh10">M30S++ VH10</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vh20">M30S++ VH20</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vh30">M30S++ VH30</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vh40">M30S++ VH40</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vh50">M30S++ VH50</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vh60">M30S++ VH60</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vh70">M30S++ VH70</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vh80">M30S++ VH80</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vh90">M30S++ VH90</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vh100">M30S++ VH100</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vj20">M30S++ VJ20</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vj30">M30S++ VJ30</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31-v10">M31 V10</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31-v20">M31 V20</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31h-v10">M31H V10</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31h-v40">M31H V40</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30l-v10">M30L V10</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s-v10">M31S V10</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s-v20">M31S V20</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s-v30">M31S V30</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s-v40">M31S V40</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s-v50">M31S V50</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s-v60">M31S V60</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s-v70">M31S V70</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s-v80">M31S V80</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s-v90">M31S V90</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s-ve10">M31S VE10</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s-ve20">M31S VE20</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s-ve30">M31S VE30</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31se-v10">M31SE V10</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31se-v20">M31SE V20</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31se-v30">M31SE V30</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-v10">M31S+ V10</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-v20">M31S+ V20</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-v30">M31S+ V30</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-v40">M31S+ V40</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-v50">M31S+ V50</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-v60">M31S+ V60</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-v80">M31S+ V80</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-v90">M31S+ V90</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-v100">M31S+ V100</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-ve10">M31S+ VE10</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-ve20">M31S+ VE20</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-ve30">M31S+ VE30</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-ve40">M31S+ VE40</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-ve50">M31S+ VE50</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-ve60">M31S+ VE60</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-ve80">M31S+ VE80</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-vf20">M31S+ VF20</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-vf30">M31S+ VF30</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-vg20">M31S+ VG20</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-vg30">M31S+ VG30</a></li>
|
||||
<li><a href="../whatsminer/M3X#m32-v10">M32 V10</a></li>
|
||||
<li><a href="../whatsminer/M3X#m32-v20">M32 V20</a></li>
|
||||
<li><a href="../whatsminer/M3X#m33-v10">M33 V10</a></li>
|
||||
<li><a href="../whatsminer/M3X#m33-v20">M33 V20</a></li>
|
||||
<li><a href="../whatsminer/M3X#m33-v30">M33 V30</a></li>
|
||||
<li><a href="../whatsminer/M3X#m33s-vg30">M33S VG30</a></li>
|
||||
<li><a href="../whatsminer/M3X#m33s_1-vg20">M33S+ VG20</a></li>
|
||||
<li><a href="../whatsminer/M3X#m33s_1-vh20">M33S+ VH20</a></li>
|
||||
<li><a href="../whatsminer/M3X#m33s_1-vh30">M33S+ VH30</a></li>
|
||||
<li><a href="../whatsminer/M3X#m33s_1_1-vh20">M33S++ VH20</a></li>
|
||||
<li><a href="../whatsminer/M3X#m33s_1_1-vh30">M33S++ VH30</a></li>
|
||||
<li><a href="../whatsminer/M3X#m33s_1_1-vg40">M33S++ VG40</a></li>
|
||||
<li><a href="../whatsminer/M3X#m34s_1-ve10">M34S+ VE10</a></li>
|
||||
<li><a href="../whatsminer/M3X#m36s-ve10">M36S VE10</a></li>
|
||||
<li><a href="../whatsminer/M3X#m36s_1-vg30">M36S+ VG30</a></li>
|
||||
<li><a href="../whatsminer/M3X#m36s_1_1-vh30">M36S++ VH30</a></li>
|
||||
<li><a href="../whatsminer/M3X#m39-v10">M39 V10</a></li>
|
||||
<li><a href="../whatsminer/M3X#m39-v20">M39 V20</a></li>
|
||||
<li><a href="../whatsminer/M3X#m39-v30">M39 V30</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>M5X Series:</summary>
|
||||
<ul>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M5X/#M50'>M50</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M5X/#M50VG30'>M50VG30</a></li>
|
||||
<li><a href='../whatsminer/M5X/#M50VH10'>M50VH10</a></li>
|
||||
<li><a href='../whatsminer/M5X/#M50VH20'>M50VH20</a></li>
|
||||
<li><a href='../whatsminer/M5X/#M50VH30'>M50VH30</a></li>
|
||||
<li><a href='../whatsminer/M5X/#M50VH40'>M50VH40</a></li>
|
||||
<li><a href='../whatsminer/M5X/#M50VH50'>M50VH50</a></li>
|
||||
<li><a href='../whatsminer/M5X/#M50VH60'>M50VH60</a></li>
|
||||
<li><a href='../whatsminer/M5X/#M50VH70'>M50VH70</a></li>
|
||||
<li><a href='../whatsminer/M5X/#M50VH80'>M50VH80</a></li>
|
||||
<li><a href='../whatsminer/M5X/#M50VJ10'>M50VJ10</a></li>
|
||||
<li><a href='../whatsminer/M5X/#M50VJ20'>M50VJ20</a></li>
|
||||
<li><a href='../whatsminer/M5X/#M50VJ30'>M50VJ30</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M5X/#M50S'>M50S</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M5X/#M50SVJ10'>M50SVJ10</a></li>
|
||||
<li><a href='../whatsminer/M5X/#M50SVJ20'>M50SVJ20</a></li>
|
||||
<li><a href='../whatsminer/M5X/#M50SVJ30'>M50SVJ30</a></li>
|
||||
<li><a href='../whatsminer/M5X/#M50SVH10'>M50SVH10</a></li>
|
||||
<li><a href='../whatsminer/M5X/#M50SVH20'>M50SVH20</a></li>
|
||||
<li><a href='../whatsminer/M5X/#M50SVH30'>M50SVH30</a></li>
|
||||
<li><a href='../whatsminer/M5X/#M50SVH40'>M50SVH40</a></li>
|
||||
<li><a href='../whatsminer/M5X/#M50SVH50'>M50SVH50</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M5X/#M50S_1'>M50S+</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M5X/#M50S_1VH30'>M50S+VH30</a></li>
|
||||
<li><a href='../whatsminer/M5X/#M50S_1VH40'>M50S+VH40</a></li>
|
||||
<li><a href='../whatsminer/M5X/#M50S_1VJ30'>M50S+VJ30</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M5X/#M53'>M53</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M5X/#M53VH30'>M53VH30</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M5X/#M53S'>M53S</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M5X/#M53SVH30'>M53SVH30</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M5X/#M53S_1'>M53S+</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M5X/#M53S_1VJ30'>M53S+VJ30</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M5X/#M56'>M56</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M5X/#M56VH30'>M56VH30</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M5X/#M56S'>M56S</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M5X/#M56SVH30'>M56SVH30</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M5X/#M56S_1'>M56S+</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M5X/#M56S_1VJ30'>M56S+VJ30</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href='../whatsminer/M5X/#M59'>M59</a></summary>
|
||||
<ul>
|
||||
<li><a href='../whatsminer/M5X/#M59VH30'>M59VH30</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Stock Firmware Antminers:</summary>
|
||||
<ul>
|
||||
<details>
|
||||
<summary>X19 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X19/#s19">S19</a></li>
|
||||
<li><a href="../antminer/X19/#s19l">S19L</a></li>
|
||||
<li><a href="../antminer/X19/#s19-pro">S19 Pro</a></li>
|
||||
<li><a href="../antminer/X19/#s19a">S19a</a></li>
|
||||
<li><a href="../antminer/X19/#s19j">S19j</a></li>
|
||||
<li><a href="../antminer/X19/#s19j-pro">S19j Pro</a></li>
|
||||
<li><a href="../antminer/X19/#s19-xp">S19 XP</a></li>
|
||||
<li><a href="../antminer/X19/#t19">T19</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>X17 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X17/#s17">S17</a></li>
|
||||
<li><a href="../antminer/X17/#s17_1">S17+</a></li>
|
||||
<li><a href="../antminer/X17/#s17-pro">S17 Pro</a></li>
|
||||
<li><a href="../antminer/X17/#s17e">S17e</a></li>
|
||||
<li><a href="../antminer/X17/#t17">T17</a></li>
|
||||
<li><a href="../antminer/X17/#t17_1">T17+</a></li>
|
||||
<li><a href="../antminer/X17/#t17e">T17e</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>X15 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X15/#z15">Z15</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>X9 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X9/#s9">S9</a></li>
|
||||
<li><a href="../antminer/X9/#s9i">S9i</a></li>
|
||||
<li><a href="../antminer/X9/#t9">T9</a></li>
|
||||
<li><a href="../antminer/X9/#e9-pro">E9 Pro</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>X7 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X7/#l7">L7</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>X5 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X5/#dr5">DR5</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>X3 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X3/#hs3">HS3</a></li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../whatsminer/M5X#m50-ve30">M50 VE30</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50-vg30">M50 VG30</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50-vh10">M50 VH10</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50-vh20">M50 VH20</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50-vh30">M50 VH30</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50-vh40">M50 VH40</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50-vh50">M50 VH50</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50-vh60">M50 VH60</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50-vh70">M50 VH70</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50-vh80">M50 VH80</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50-vj10">M50 VJ10</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50-vj20">M50 VJ20</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50-vj30">M50 VJ30</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vj10">M50S VJ10</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vj20">M50S VJ20</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vj30">M50S VJ30</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vh10">M50S VH10</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vh20">M50S VH20</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vh30">M50S VH30</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vh40">M50S VH40</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vh50">M50S VH50</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1-vh30">M50S+ VH30</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1-vh40">M50S+ VH40</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1-vj30">M50S+ VJ30</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1-vk20">M50S+ VK20</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1_1-vk10">M50S++ VK10</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1_1-vk20">M50S++ VK20</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1_1-vk30">M50S++ VK30</a></li>
|
||||
<li><a href="../whatsminer/M5X#m53-vh30">M53 VH30</a></li>
|
||||
<li><a href="../whatsminer/M5X#m53s-vh30">M53S VH30</a></li>
|
||||
<li><a href="../whatsminer/M5X#m53s_1-vj30">M53S+ VJ30</a></li>
|
||||
<li><a href="../whatsminer/M5X#m56-vh30">M56 VH30</a></li>
|
||||
<li><a href="../whatsminer/M5X#m56s-vh30">M56S VH30</a></li>
|
||||
<li><a href="../whatsminer/M5X#m56s_1-vj30">M56S+ VJ30</a></li>
|
||||
<li><a href="../whatsminer/M5X#m59-vh30">M59 VH30</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
</details>
|
||||
@@ -492,75 +299,185 @@ details {
|
||||
<summary>Stock Firmware Avalonminers:</summary>
|
||||
<ul>
|
||||
<details>
|
||||
<summary>A7X Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../avalonminer/A7X/#a721">A721</a></li>
|
||||
<li><a href="../avalonminer/A7X/#a741">A741</a></li>
|
||||
<li><a href="../avalonminer/A7X/#a761">A761</a></li>
|
||||
</ul>
|
||||
<summary>A7X Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../avalonminer/A7X#avalon-721">Avalon 721</a></li>
|
||||
<li><a href="../avalonminer/A7X#avalon-741">Avalon 741</a></li>
|
||||
<li><a href="../avalonminer/A7X#avalon-761">Avalon 761</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>A8X Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../avalonminer/A8X/#a821">A821</a></li>
|
||||
<li><a href="../avalonminer/A8X/#a841">A841</a></li>
|
||||
<li><a href="../avalonminer/A8X/#a851">A851</a></li>
|
||||
</ul>
|
||||
<summary>A8X Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../avalonminer/A8X#avalon-821">Avalon 821</a></li>
|
||||
<li><a href="../avalonminer/A8X#avalon-841">Avalon 841</a></li>
|
||||
<li><a href="../avalonminer/A8X#avalon-851">Avalon 851</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>A9X Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../avalonminer/A9X/#a921">A921</a></li>
|
||||
</ul>
|
||||
<summary>A9X Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../avalonminer/A9X#avalon-921">Avalon 921</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>A10X Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../avalonminer/A10X/#a1026">A1026</a></li>
|
||||
<li><a href="../avalonminer/A10X/#a1047">A1047</a></li>
|
||||
<li><a href="../avalonminer/A10X/#a1066">A1066</a></li>
|
||||
</ul>
|
||||
<summary>A10X Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../avalonminer/A10X#avalon-1026">Avalon 1026</a></li>
|
||||
<li><a href="../avalonminer/A10X#avalon-1047">Avalon 1047</a></li>
|
||||
<li><a href="../avalonminer/A10X#avalon-1066">Avalon 1066</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>A11X Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../avalonminer/A11X#avalon-1166-pro">Avalon 1166 Pro</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>A12X Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../avalonminer/A12X#avalon-1246">Avalon 1246</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>Stock Firmware Innosilicon Miners:</summary>
|
||||
<summary>Stock Firmware Innosilicons:</summary>
|
||||
<ul>
|
||||
<details>
|
||||
<summary>T3X Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../innosilicon/T3X/#t3h">T3H+</a></li>
|
||||
</ul>
|
||||
<summary>T3X Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../innosilicon/T3X#t3h_1">T3H+</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>A10X Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../innosilicon/A10X/#a10x">A10X</a></li>
|
||||
</ul>
|
||||
<summary>A10X Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../innosilicon/A10X#a10x">A10X</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>Stock Firmware BFGMinerGoldshell Miners:</summary>
|
||||
<summary>Stock Firmware Goldshells:</summary>
|
||||
<ul>
|
||||
<details>
|
||||
<summary>CKX Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../goldshell/CKX/#ck5">CK5</a></li>
|
||||
</ul>
|
||||
<summary>X5 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../goldshell/X5#ck5">CK5</a></li>
|
||||
<li><a href="../goldshell/X5#hs5">HS5</a></li>
|
||||
<li><a href="../goldshell/X5#kd5">KD5</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>HSX Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../goldshell/HSX/#hs5">HS5</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>KDX Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../goldshell/KDX/#kd5">KD5</a></li>
|
||||
<li><a href="../goldshell/KDX/#kd-max">KD Max</a></li>
|
||||
</ul>
|
||||
<summary>XMax Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../goldshell/XMax#kd-max">KD Max</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>BOS+ Firmware Miners:</summary>
|
||||
<ul>
|
||||
<details>
|
||||
<summary>X9 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X9#s9-bos">S9 (BOS)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>X17 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X17#s17-bos">S17 (BOS)</a></li>
|
||||
<li><a href="../antminer/X17#s17_1-bos">S17+ (BOS)</a></li>
|
||||
<li><a href="../antminer/X17#s17-pro-bos">S17 Pro (BOS)</a></li>
|
||||
<li><a href="../antminer/X17#s17e-bos">S17e (BOS)</a></li>
|
||||
<li><a href="../antminer/X17#t17-bos">T17 (BOS)</a></li>
|
||||
<li><a href="../antminer/X17#t17_1-bos">T17+ (BOS)</a></li>
|
||||
<li><a href="../antminer/X17#t17e-bos">T17e (BOS)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>X19 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X19#s19-bos">S19 (BOS)</a></li>
|
||||
<li><a href="../antminer/X19#s19-pro-bos">S19 Pro (BOS)</a></li>
|
||||
<li><a href="../antminer/X19#s19j-bos">S19j (BOS)</a></li>
|
||||
<li><a href="../antminer/X19#s19j-no-pic-bos">S19j No PIC (BOS)</a></li>
|
||||
<li><a href="../antminer/X19#s19j-pro-bos">S19j Pro (BOS)</a></li>
|
||||
<li><a href="../antminer/X19#s19j-pro-bos">S19j Pro (BOS)</a></li>
|
||||
<li><a href="../antminer/X19#t19-bos">T19 (BOS)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>Vnish Firmware Miners:</summary>
|
||||
<ul>
|
||||
<details>
|
||||
<summary>X3 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X3#l3_1-vnish">L3+ (VNish)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>X17 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X17#s17_1-vnish">S17+ (VNish)</a></li>
|
||||
<li><a href="../antminer/X17#s17-pro-vnish">S17 Pro (VNish)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>X19 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X19#s19-vnish">S19 (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#s19-no-pic-vnish">S19 No PIC (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#s19-pro-vnish">S19 Pro (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#s19j-vnish">S19j (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#s19j-pro-vnish">S19j Pro (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#s19a-vnish">S19a (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#s19a-pro-vnish">S19a Pro (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#t19-vnish">T19 (VNish)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>ePIC Firmware Miners:</summary>
|
||||
<ul>
|
||||
<details>
|
||||
<summary>X19 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X19#s19-epic">S19 (ePIC)</a></li>
|
||||
<li><a href="../antminer/X19#s19-pro-epic">S19 Pro (ePIC)</a></li>
|
||||
<li><a href="../antminer/X19#s19j-epic">S19j (ePIC)</a></li>
|
||||
<li><a href="../antminer/X19#s19j-pro-epic">S19j Pro (ePIC)</a></li>
|
||||
<li><a href="../antminer/X19#s19-xp-epic">S19 XP (ePIC)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>HiveOS Firmware Miners:</summary>
|
||||
<ul>
|
||||
<details>
|
||||
<summary>X9 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X9#t9-hiveon">T9 (Hiveon)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>LuxOS Firmware Miners:</summary>
|
||||
<ul>
|
||||
<details>
|
||||
<summary>X9 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X9#s9-luxos">S9 (LuxOS)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
</details>
|
||||
@@ -1,90 +1,94 @@
|
||||
# pyasic
|
||||
## M2X Models
|
||||
|
||||
## M20V10
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M2X.M20.BTMinerM20V10
|
||||
## M20 V10
|
||||
::: pyasic.miners.whatsminer.btminer.M2X.M20.BTMinerM20V10
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M20SV10
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M2X.M20S.BTMinerM20SV10
|
||||
## M20S V10
|
||||
::: pyasic.miners.whatsminer.btminer.M2X.M20S.BTMinerM20SV10
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M20SV20
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M2X.M20S.BTMinerM20SV20
|
||||
## M20S V20
|
||||
::: pyasic.miners.whatsminer.btminer.M2X.M20S.BTMinerM20SV20
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M20SV30
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M2X.M20S.BTMinerM20SV30
|
||||
## M20S V30
|
||||
::: pyasic.miners.whatsminer.btminer.M2X.M20S.BTMinerM20SV30
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M20S+V30
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M2X.M20S_Plus.BTMinerM20SPlusV30
|
||||
## M20P V10
|
||||
::: pyasic.miners.whatsminer.btminer.M2X.M20P.BTMinerM20PV10
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M21V10
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M2X.M21.BTMinerM21V10
|
||||
## M20P V30
|
||||
::: pyasic.miners.whatsminer.btminer.M2X.M20P.BTMinerM20PV30
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M21SV20
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M2X.M21S.BTMinerM21SV20
|
||||
## M20S+ V30
|
||||
::: pyasic.miners.whatsminer.btminer.M2X.M20S_Plus.BTMinerM20SPlusV30
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M21SV60
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M2X.M21S.BTMinerM21SV60
|
||||
## M21 V10
|
||||
::: pyasic.miners.whatsminer.btminer.M2X.M21.BTMinerM21V10
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M21SV70
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M2X.M21S.BTMinerM21SV70
|
||||
## M21S V20
|
||||
::: pyasic.miners.whatsminer.btminer.M2X.M21S.BTMinerM21SV20
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M21S+V20
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M2X.M21S_Plus.BTMinerM21SPlusV20
|
||||
## M21S V60
|
||||
::: pyasic.miners.whatsminer.btminer.M2X.M21S.BTMinerM21SV60
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M29V10
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M2X.M29.BTMinerM29V10
|
||||
## M21S V70
|
||||
::: pyasic.miners.whatsminer.btminer.M2X.M21S.BTMinerM21SV70
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M21S+ V20
|
||||
::: pyasic.miners.whatsminer.btminer.M2X.M21S_Plus.BTMinerM21SPlusV20
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M29 V10
|
||||
::: pyasic.miners.whatsminer.btminer.M2X.M29.BTMinerM29V10
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,242 +1,248 @@
|
||||
# pyasic
|
||||
## M5X Models
|
||||
|
||||
## M50VG30
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M5X.M50.BTMinerM50VG30
|
||||
## M50 VE30
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VE30
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M50VH10
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M5X.M50.BTMinerM50VH10
|
||||
## M50 VG30
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VG30
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M50VH20
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M5X.M50.BTMinerM50VH20
|
||||
## M50 VH10
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VH10
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M50VH30
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M5X.M50.BTMinerM50VH30
|
||||
## M50 VH20
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VH20
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M50VH40
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M5X.M50.BTMinerM50VH40
|
||||
## M50 VH30
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VH30
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M50VH50
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M5X.M50.BTMinerM50VH50
|
||||
## M50 VH40
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VH40
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M50VH60
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M5X.M50.BTMinerM50VH60
|
||||
## M50 VH50
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VH50
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M50VH70
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M5X.M50.BTMinerM50VH70
|
||||
## M50 VH60
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VH60
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M50VH80
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M5X.M50.BTMinerM50VH80
|
||||
## M50 VH70
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VH70
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M50VJ10
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M5X.M50.BTMinerM50VJ10
|
||||
## M50 VH80
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VH80
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M50VJ20
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M5X.M50.BTMinerM50VJ20
|
||||
## M50 VJ10
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VJ10
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M50VJ30
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M5X.M50.BTMinerM50VJ30
|
||||
## M50 VJ20
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VJ20
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M50SVJ10
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M5X.M50S.BTMinerM50SVJ10
|
||||
## M50 VJ30
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VJ30
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M50SVJ20
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M5X.M50S.BTMinerM50SVJ20
|
||||
## M50S VJ10
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M50S.BTMinerM50SVJ10
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M50SVJ30
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M5X.M50S.BTMinerM50SVJ30
|
||||
## M50S VJ20
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M50S.BTMinerM50SVJ20
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M50SVH10
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M5X.M50S.BTMinerM50SVH10
|
||||
## M50S VJ30
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M50S.BTMinerM50SVJ30
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M50SVH20
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M5X.M50S.BTMinerM50SVH20
|
||||
## M50S VH10
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M50S.BTMinerM50SVH10
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M50SVH30
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M5X.M50S.BTMinerM50SVH30
|
||||
## M50S VH20
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M50S.BTMinerM50SVH20
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M50SVH40
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M5X.M50S.BTMinerM50SVH40
|
||||
## M50S VH30
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M50S.BTMinerM50SVH30
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M50SVH50
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M5X.M50S.BTMinerM50SVH50
|
||||
## M50S VH40
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M50S.BTMinerM50SVH40
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M50S+VH30
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M5X.M50S_Plus.BTMinerM50SPlusVH30
|
||||
## M50S VH50
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M50S.BTMinerM50SVH50
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M50S+VH40
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M5X.M50S_Plus.BTMinerM50SPlusVH40
|
||||
## M50S+ VH30
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M50S_Plus.BTMinerM50SPlusVH30
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M50S+VJ30
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M5X.M50S_Plus.BTMinerM50SPlusVJ30
|
||||
## M50S+ VH40
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M50S_Plus.BTMinerM50SPlusVH40
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M53VH30
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M5X.M53.BTMinerM53VH30
|
||||
## M50S+ VJ30
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M50S_Plus.BTMinerM50SPlusVJ30
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M53SVH30
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M5X.M53S.BTMinerM53SVH30
|
||||
## M50S+ VK20
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M50S_Plus.BTMinerM50SPlusVK20
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M53S+VJ30
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M5X.M53S_Plus.BTMinerM53SPlusVJ30
|
||||
## M50S++ VK10
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M50S_Plus_Plus.BTMinerM50SPlusPlusVK10
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M56VH30
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M5X.M56.BTMinerM56VH30
|
||||
## M50S++ VK20
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M50S_Plus_Plus.BTMinerM50SPlusPlusVK20
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M56SVH30
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M5X.M56S.BTMinerM56SVH30
|
||||
## M50S++ VK30
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M50S_Plus_Plus.BTMinerM50SPlusPlusVK30
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M56S+VJ30
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M5X.M56S_Plus.BTMinerM56SPlusVJ30
|
||||
## M53 VH30
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M53.BTMinerM53VH30
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M59VH30
|
||||
|
||||
::: pyasic.miners.btc.whatsminer.btminer.M5X.M59.BTMinerM59VH30
|
||||
## M53S VH30
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M53S.BTMinerM53SVH30
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M53S+ VJ30
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M53S_Plus.BTMinerM53SPlusVJ30
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M56 VH30
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M56.BTMinerM56VH30
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M56S VH30
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M56S.BTMinerM56SVH30
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M56S+ VJ30
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M56S_Plus.BTMinerM56SPlusVJ30
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M59 VH30
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M59.BTMinerM59VH30
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
# pyasic
|
||||
## Miner Network Range
|
||||
|
||||
[`MinerNetworkRange`][pyasic.network.net_range.MinerNetworkRange] is a class used by [`MinerNetwork`][pyasic.network.MinerNetwork] to handle any constructor stings.
|
||||
The goal is to emulate what is produced by `ipaddress.ip_network` by allowing [`MinerNetwork`][pyasic.network.MinerNetwork] to get a list of hosts.
|
||||
This allows this class to be the [`MinerNetwork.network`][pyasic.network.MinerNetwork] and hence be used for scanning.
|
||||
|
||||
::: pyasic.network.net_range.MinerNetworkRange
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
35
docs/settings/settings.md
Normal file
35
docs/settings/settings.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# pyasic
|
||||
## settings
|
||||
|
||||
All settings here are global settings for all of pyasic. Set these settings with `update(key, value)`.
|
||||
|
||||
Settings options:
|
||||
- `network_ping_retries`
|
||||
- `network_ping_timeout`
|
||||
- `network_scan_threads`
|
||||
- `factory_get_retries`
|
||||
- `factory_get_timeout`
|
||||
- `get_data_retries`
|
||||
- `api_function_timeout`
|
||||
- `default_whatsminer_password`
|
||||
- `default_innosilicon_password`
|
||||
- `default_antminer_password`
|
||||
- `default_bosminer_password`
|
||||
- `default_vnish_password`
|
||||
- `default_goldshell_password`
|
||||
- `socket_linger_time`
|
||||
|
||||
|
||||
### get
|
||||
::: pyasic.settings.get
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
### update
|
||||
::: pyasic.settings.update
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
15
mkdocs.yml
15
mkdocs.yml
@@ -7,7 +7,6 @@ nav:
|
||||
- Miner Factory: "miners/miner_factory.md"
|
||||
- Network:
|
||||
- Miner Network: "network/miner_network.md"
|
||||
- Miner Network Range: "network/miner_network_range.md"
|
||||
- Dataclasses:
|
||||
- Miner Data: "data/miner_data.md"
|
||||
- Error Codes: "data/error_codes.md"
|
||||
@@ -20,6 +19,7 @@ nav:
|
||||
- BOSMiner: "API/bosminer.md"
|
||||
- BTMiner: "API/btminer.md"
|
||||
- CGMiner: "API/cgminer.md"
|
||||
- LUXMiner: "API/luxminer.md"
|
||||
- Unknown: "API/unknown.md"
|
||||
- Backends:
|
||||
- BMMiner: "miners/backends/bmminer.md"
|
||||
@@ -27,6 +27,9 @@ nav:
|
||||
- BFGMiner: "miners/backends/bfgminer.md"
|
||||
- BTMiner: "miners/backends/btminer.md"
|
||||
- CGMiner: "miners/backends/cgminer.md"
|
||||
- LUXMiner: "miners/backends/luxminer.md"
|
||||
- VNish: "miners/backends/vnish.md"
|
||||
- ePIC: "miners/backends/epic.md"
|
||||
- Hiveon: "miners/backends/hiveon.md"
|
||||
- Classes:
|
||||
- Antminer X3: "miners/antminer/X3.md"
|
||||
@@ -40,16 +43,18 @@ nav:
|
||||
- Avalon 8X: "miners/avalonminer/A8X.md"
|
||||
- Avalon 9X: "miners/avalonminer/A9X.md"
|
||||
- Avalon 10X: "miners/avalonminer/A10X.md"
|
||||
- Avalon 11X: "miners/avalonminer/A11X.md"
|
||||
- Avalon 12X: "miners/avalonminer/A12X.md"
|
||||
- Whatsminer M2X: "miners/whatsminer/M2X.md"
|
||||
- Whatsminer M3X: "miners/whatsminer/M3X.md"
|
||||
- Whatsminer M5X: "miners/whatsminer/M5X.md"
|
||||
- Innosilicon T3X: "miners/innosilicon/T3X.md"
|
||||
- Innosilicon A10X: "miners/innosilicon/A10X.md"
|
||||
- Goldshell CKX: "miners/goldshell/CKX.md"
|
||||
- Goldshell HSX: "miners/goldshell/HSX.md"
|
||||
- Goldshell KDX: "miners/goldshell/KDX.md"
|
||||
- Goldshell X5: "miners/goldshell/X5.md"
|
||||
- Goldshell XMax: "miners/goldshell/XMax.md"
|
||||
- Base Miner: "miners/base_miner.md"
|
||||
|
||||
- Settings:
|
||||
- Settings: "settings/settings.md"
|
||||
|
||||
plugins:
|
||||
- mkdocstrings
|
||||
|
||||
@@ -32,6 +32,8 @@ class BaseMinerAPI:
|
||||
# ip address of the miner
|
||||
self.ip = ipaddress.ip_address(ip)
|
||||
|
||||
self.pwd = "admin"
|
||||
|
||||
def __new__(cls, *args, **kwargs):
|
||||
if cls is BaseMinerAPI:
|
||||
raise TypeError(f"Only children of '{cls.__name__}' may be instantiated")
|
||||
@@ -73,18 +75,23 @@ class BaseMinerAPI:
|
||||
# send the command
|
||||
data = await self._send_bytes(json.dumps(cmd).encode("utf-8"))
|
||||
|
||||
if data == b"Socket connect failed: Connection refused\n":
|
||||
if not ignore_errors:
|
||||
raise APIError(data.decode("utf-8"))
|
||||
return {}
|
||||
|
||||
data = self._load_api_data(data)
|
||||
|
||||
# check for if the user wants to allow errors to return
|
||||
if not ignore_errors:
|
||||
# validate the command succeeded
|
||||
validation = self._validate_command_output(data)
|
||||
if not validation[0]:
|
||||
if allow_warning:
|
||||
logging.warning(
|
||||
f"{self.ip}: API Command Error: {command}: {validation[1]}"
|
||||
)
|
||||
validation = self._validate_command_output(data)
|
||||
if not validation[0]:
|
||||
if not ignore_errors:
|
||||
# validate the command succeeded
|
||||
raise APIError(validation[1])
|
||||
if allow_warning:
|
||||
logging.warning(
|
||||
f"{self.ip}: API Command Error: {command}: {validation[1]}"
|
||||
)
|
||||
|
||||
logging.debug(f"{self} - (Send Command) - Received data.")
|
||||
return data
|
||||
@@ -111,16 +118,29 @@ class BaseMinerAPI:
|
||||
data = await self.send_command(command, allow_warning=allow_warning)
|
||||
except APIError as e:
|
||||
# try to identify the error
|
||||
if ":" in e.message:
|
||||
err_command = e.message.split(":")[0]
|
||||
if err_command in commands:
|
||||
commands.remove(err_command)
|
||||
continue
|
||||
if e.message is not None:
|
||||
if ":" in e.message:
|
||||
err_command = e.message.split(":")[0]
|
||||
if err_command in commands:
|
||||
commands.remove(err_command)
|
||||
continue
|
||||
return {command: [{}] for command in commands}
|
||||
logging.debug(f"{self} - (Multicommand) - Received data")
|
||||
data["multicommand"] = True
|
||||
return data
|
||||
|
||||
async def _handle_multicommand(self, command: str, allow_warning: bool = True):
|
||||
try:
|
||||
data = await self.send_command(command, allow_warning=allow_warning)
|
||||
if not "+" in command:
|
||||
return {command: [data]}
|
||||
return data
|
||||
|
||||
except APIError:
|
||||
if "+" in command:
|
||||
return {command: [{}] for command in command.split("+")}
|
||||
return {command: [{}]}
|
||||
|
||||
@property
|
||||
def commands(self) -> list:
|
||||
return self.get_commands()
|
||||
@@ -164,7 +184,11 @@ If you are sure you want to use this command please use API.send_command("{comma
|
||||
)
|
||||
return return_commands
|
||||
|
||||
async def _send_bytes(self, data: bytes, timeout: int = 100) -> bytes:
|
||||
async def _send_bytes(
|
||||
self,
|
||||
data: bytes,
|
||||
timeout: int = 100,
|
||||
) -> bytes:
|
||||
logging.debug(f"{self} - ([Hidden] Send Bytes) - Sending")
|
||||
try:
|
||||
# get reader and writer streams
|
||||
@@ -183,16 +207,18 @@ If you are sure you want to use this command please use API.send_command("{comma
|
||||
logging.debug(f"{self} - ([Hidden] Send Bytes) - Draining")
|
||||
await writer.drain()
|
||||
try:
|
||||
ret_data = await asyncio.wait_for(reader.read(4096), timeout=timeout)
|
||||
except ConnectionAbortedError:
|
||||
return b"{}"
|
||||
try:
|
||||
# TO address a situation where a whatsminer has an unknown PW -AND-
|
||||
# Fix for stupid whatsminer bug, reboot/restart seem to not load properly in the loop
|
||||
# have to receive, save the data, check if there is more data by reading with a short timeout
|
||||
# append that data if there is more, and then onto the main loop.
|
||||
ret_data += await asyncio.wait_for(reader.read(1), timeout=1)
|
||||
except asyncio.TimeoutError:
|
||||
return ret_data
|
||||
# the password timeout might need to be longer than 1, but it seems to work for now.
|
||||
ret_data = await asyncio.wait_for(reader.read(1), timeout=1)
|
||||
except (asyncio.TimeoutError):
|
||||
return b"{}"
|
||||
try:
|
||||
ret_data += await asyncio.wait_for(reader.read(4096), timeout=timeout)
|
||||
except (ConnectionAbortedError):
|
||||
return b"{}"
|
||||
|
||||
# loop to receive all the data
|
||||
logging.debug(f"{self} - ([Hidden] Send Bytes) - Receiving")
|
||||
@@ -231,13 +257,22 @@ If you are sure you want to use this command please use API.send_command("{comma
|
||||
# this is an error
|
||||
return False, f"{key}: " + data[key][0]["STATUS"][0]["Msg"]
|
||||
elif "id" not in data.keys():
|
||||
if isinstance(data["STATUS"], list):
|
||||
if data["STATUS"][0].get("STATUS", None) in ["S", "I"]:
|
||||
return True, None
|
||||
else:
|
||||
return False, data["STATUS"][0]["Msg"]
|
||||
|
||||
if data["STATUS"] not in ["S", "I"]:
|
||||
return False, data["Msg"]
|
||||
else:
|
||||
# make sure the command succeeded
|
||||
if type(data["STATUS"]) == str:
|
||||
if isinstance(data["STATUS"], str):
|
||||
if data["STATUS"] in ["RESTART"]:
|
||||
return True, None
|
||||
elif isinstance(data["STATUS"], dict):
|
||||
if data["STATUS"].get("STATUS") in ["S", "I"]:
|
||||
return True, None
|
||||
elif data["STATUS"][0]["STATUS"] not in ("S", "I"):
|
||||
# this is an error
|
||||
if data["STATUS"][0]["STATUS"] not in ("S", "I"):
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
|
||||
from pyasic.API import APIError, BaseMinerAPI
|
||||
@@ -56,19 +56,19 @@ class BFGMinerAPI(BaseMinerAPI):
|
||||
return data
|
||||
|
||||
async def _x19_multicommand(self, *commands) -> dict:
|
||||
data = None
|
||||
try:
|
||||
data = {}
|
||||
# send all commands individually
|
||||
for cmd in commands:
|
||||
data[cmd] = []
|
||||
data[cmd].append(await self.send_command(cmd, allow_warning=True))
|
||||
except APIError:
|
||||
pass
|
||||
except Exception as e:
|
||||
logging.warning(
|
||||
f"{self} - ([Hidden] X19 Multicommand) - API Command Error {e}"
|
||||
tasks = []
|
||||
# send all commands individually
|
||||
for cmd in commands:
|
||||
tasks.append(
|
||||
asyncio.create_task(self._handle_multicommand(cmd, allow_warning=True))
|
||||
)
|
||||
|
||||
all_data = await asyncio.gather(*tasks)
|
||||
|
||||
data = {}
|
||||
for item in all_data:
|
||||
data.update(item)
|
||||
|
||||
return data
|
||||
|
||||
async def version(self) -> dict:
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
import asyncio
|
||||
import logging
|
||||
|
||||
from pyasic.API import APIError, BaseMinerAPI
|
||||
@@ -57,21 +58,19 @@ class BMMinerAPI(BaseMinerAPI):
|
||||
return data
|
||||
|
||||
async def _x19_multicommand(self, *commands, allow_warning: bool = True) -> dict:
|
||||
data = None
|
||||
try:
|
||||
data = {}
|
||||
# send all commands individually
|
||||
for cmd in commands:
|
||||
data[cmd] = []
|
||||
data[cmd].append(
|
||||
await self.send_command(cmd, allow_warning=allow_warning)
|
||||
)
|
||||
except APIError:
|
||||
pass
|
||||
except Exception as e:
|
||||
logging.warning(
|
||||
f"{self} - ([Hidden] X19 Multicommand) - API Command Error {e}"
|
||||
tasks = []
|
||||
# send all commands individually
|
||||
for cmd in commands:
|
||||
tasks.append(
|
||||
asyncio.create_task(self._handle_multicommand(cmd, allow_warning=True))
|
||||
)
|
||||
|
||||
all_data = await asyncio.gather(*tasks)
|
||||
|
||||
data = {}
|
||||
for item in all_data:
|
||||
data.update(item)
|
||||
|
||||
return data
|
||||
|
||||
async def version(self) -> dict:
|
||||
|
||||
@@ -22,15 +22,15 @@ import hashlib
|
||||
import json
|
||||
import logging
|
||||
import re
|
||||
from typing import Union
|
||||
from typing import Literal, Union
|
||||
|
||||
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
||||
from passlib.handlers.md5_crypt import md5_crypt
|
||||
|
||||
from pyasic import settings
|
||||
from pyasic.API import BaseMinerAPI
|
||||
from pyasic.errors import APIError
|
||||
from pyasic.misc import api_min_version
|
||||
from pyasic.settings import PyasicSettings
|
||||
|
||||
### IMPORTANT ###
|
||||
# you need to change the password of the miners using the Whatsminer
|
||||
@@ -40,6 +40,12 @@ from pyasic.settings import PyasicSettings
|
||||
# you change the password, you can pass that to this class as pwd,
|
||||
# or add it as the Whatsminer_pwd in the settings.toml file.
|
||||
|
||||
PrePowerOnMessage = Union[
|
||||
Literal["wait for adjust temp"],
|
||||
Literal["adjust complete"],
|
||||
Literal["adjust continue"],
|
||||
]
|
||||
|
||||
|
||||
def _crypt(word: str, salt: str) -> str:
|
||||
"""Encrypts a word with a salt, using a standard salt format.
|
||||
@@ -186,7 +192,7 @@ class BTMinerAPI(BaseMinerAPI):
|
||||
ip: str,
|
||||
api_ver: str = "0.0.0",
|
||||
port: int = 4028,
|
||||
pwd: str = PyasicSettings().global_whatsminer_password,
|
||||
pwd: str = settings.get("default_whatsminer_password", "admin"),
|
||||
):
|
||||
super().__init__(ip, port)
|
||||
self.pwd = pwd
|
||||
@@ -203,27 +209,35 @@ class BTMinerAPI(BaseMinerAPI):
|
||||
# make sure we can actually run each command, otherwise they will fail
|
||||
commands = self._check_commands(*commands)
|
||||
# standard multicommand format is "command1+command2"
|
||||
# commands starting with "get_" aren't supported, but we can fake that
|
||||
get_commands_data = {}
|
||||
# commands starting with "get_" and the "status" command aren't supported, but we can fake that
|
||||
|
||||
tasks = []
|
||||
|
||||
for command in list(commands):
|
||||
if command.startswith("get_"):
|
||||
if command.startswith("get_") or command == "status":
|
||||
commands.remove(command)
|
||||
# send seperately and append later
|
||||
try:
|
||||
get_commands_data[command] = [
|
||||
await self.send_command(command, allow_warning=allow_warning)
|
||||
]
|
||||
except APIError:
|
||||
get_commands_data[command] = [{}]
|
||||
tasks.append(
|
||||
asyncio.create_task(
|
||||
self._handle_multicommand(command, allow_warning=allow_warning)
|
||||
)
|
||||
)
|
||||
|
||||
command = "+".join(commands)
|
||||
try:
|
||||
main_data = await self.send_command(command, allow_warning=allow_warning)
|
||||
except APIError:
|
||||
main_data = {command: [{}] for command in commands}
|
||||
tasks.append(
|
||||
asyncio.create_task(
|
||||
self._handle_multicommand(command, allow_warning=allow_warning)
|
||||
)
|
||||
)
|
||||
|
||||
all_data = await asyncio.gather(*tasks)
|
||||
|
||||
logging.debug(f"{self} - (Multicommand) - Received data")
|
||||
|
||||
data = dict(**main_data, **get_commands_data)
|
||||
data = {}
|
||||
for item in all_data:
|
||||
data.update(item)
|
||||
|
||||
data["multicommand"] = True
|
||||
return data
|
||||
|
||||
@@ -685,7 +699,7 @@ class BTMinerAPI(BaseMinerAPI):
|
||||
)
|
||||
return await self.send_privileged_command("set_power_pct", percent=str(percent))
|
||||
|
||||
async def pre_power_on(self, complete: bool, msg: str) -> dict:
|
||||
async def pre_power_on(self, complete: bool, msg: PrePowerOnMessage) -> dict:
|
||||
"""Configure or check status of pre power on.
|
||||
|
||||
<details>
|
||||
@@ -705,7 +719,7 @@ class BTMinerAPI(BaseMinerAPI):
|
||||
</details>
|
||||
"""
|
||||
|
||||
if not msg == "wait for adjust temp" or "adjust complete" or "adjust continue":
|
||||
if msg not in ("wait for adjust temp", "adjust complete", "adjust continue"):
|
||||
raise APIError(
|
||||
"Message is incorrect, please choose one of "
|
||||
'["wait for adjust temp", '
|
||||
@@ -721,6 +735,34 @@ class BTMinerAPI(BaseMinerAPI):
|
||||
)
|
||||
|
||||
### ADDED IN V2.0.5 Whatsminer API ###
|
||||
|
||||
@api_min_version("2.0.5")
|
||||
async def set_power_pct_v2(self, percent: int) -> dict:
|
||||
"""Set the power percentage of the miner based on current power. Used for temporary adjustment. Added in API v2.0.5.
|
||||
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Set the power percentage of the miner, only works after changing
|
||||
the password of the miner using the Whatsminer tool.
|
||||
|
||||
Parameters:
|
||||
percent: The power percentage to set.
|
||||
Returns:
|
||||
A reply informing of the status of setting the power percentage.
|
||||
</details>
|
||||
"""
|
||||
|
||||
if not 0 < percent < 100:
|
||||
raise APIError(
|
||||
f"Power PCT % is outside of the allowed "
|
||||
f"range. Please set a % between 0 and "
|
||||
f"100"
|
||||
)
|
||||
return await self.send_privileged_command(
|
||||
"set_power_pct_v2", percent=str(percent)
|
||||
)
|
||||
|
||||
@api_min_version("2.0.5")
|
||||
async def set_temp_offset(self, temp_offset: int) -> dict:
|
||||
"""Set the offset of miner hash board target temperature.
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
|
||||
from pyasic.API import APIError, BaseMinerAPI
|
||||
@@ -56,19 +56,19 @@ class CGMinerAPI(BaseMinerAPI):
|
||||
return data
|
||||
|
||||
async def _x19_multicommand(self, *commands) -> dict:
|
||||
data = None
|
||||
try:
|
||||
data = {}
|
||||
# send all commands individually
|
||||
for cmd in commands:
|
||||
data[cmd] = []
|
||||
data[cmd].append(await self.send_command(cmd, allow_warning=True))
|
||||
except APIError:
|
||||
pass
|
||||
except Exception as e:
|
||||
logging.warning(
|
||||
f"{self} - ([Hidden] X19 Multicommand) - API Command Error {e}"
|
||||
tasks = []
|
||||
# send all commands individually
|
||||
for cmd in commands:
|
||||
tasks.append(
|
||||
asyncio.create_task(self._handle_multicommand(cmd, allow_warning=True))
|
||||
)
|
||||
|
||||
all_data = await asyncio.gather(*tasks)
|
||||
|
||||
data = {}
|
||||
for item in all_data:
|
||||
data.update(item)
|
||||
|
||||
return data
|
||||
|
||||
async def version(self) -> dict:
|
||||
|
||||
759
pyasic/API/luxminer.py
Normal file
759
pyasic/API/luxminer.py
Normal file
@@ -0,0 +1,759 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Copyright 2022 Upstream Data Inc -
|
||||
# -
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||
# you may not use this file except in compliance with the License. -
|
||||
# You may obtain a copy of the License at -
|
||||
# -
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||
# -
|
||||
# Unless required by applicable law or agreed to in writing, software -
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
from typing import Literal
|
||||
|
||||
from pyasic.API import BaseMinerAPI
|
||||
|
||||
|
||||
class LUXMinerAPI(BaseMinerAPI):
|
||||
"""An abstraction of the LUXMiner API.
|
||||
|
||||
Each method corresponds to an API command in LUXMiner.
|
||||
|
||||
[LUXMiner API documentation](https://docs.firmware.luxor.tech/API/intro)
|
||||
|
||||
This class abstracts use of the LUXMiner API, as well as the
|
||||
methods for sending commands to it. The `self.send_command()`
|
||||
function handles sending a command to the miner asynchronously, and
|
||||
as such is the base for many of the functions in this class, which
|
||||
rely on it to send the command for them.
|
||||
|
||||
Parameters:
|
||||
ip: The IP of the miner to reference the API on.
|
||||
port: The port to reference the API on. Default is 4028.
|
||||
"""
|
||||
|
||||
def __init__(self, ip: str, api_ver: str = "0.0.0", port: int = 4028) -> None:
|
||||
super().__init__(ip, port=port)
|
||||
self.api_ver = api_ver
|
||||
|
||||
async def addgroup(self, name: str, quota: int) -> dict:
|
||||
"""Add a pool group.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
name: The group name.
|
||||
quota: The group quota.
|
||||
|
||||
Returns:
|
||||
Confirmation of adding a pool group.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("addgroup", parameters=f"{name},{quota}")
|
||||
|
||||
async def addpool(
|
||||
self, url: str, user: str, pwd: str = "", group_id: str = None
|
||||
) -> dict:
|
||||
"""Add a pool.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
url: The pool url.
|
||||
user: The pool username.
|
||||
pwd: The pool password.
|
||||
group_id: The group ID to use.
|
||||
|
||||
Returns:
|
||||
Confirmation of adding a pool.
|
||||
</details>
|
||||
"""
|
||||
pool_data = [url, user, pwd]
|
||||
if group_id is not None:
|
||||
pool_data.append(group_id)
|
||||
return await self.send_command("addpool", parameters=",".join(pool_data))
|
||||
|
||||
async def asc(self, n: int) -> dict:
|
||||
"""Get data for ASC device n.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
n: The device to get data for.
|
||||
|
||||
Returns:
|
||||
The data for ASC device n.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("asc", parameters=n)
|
||||
|
||||
async def asccount(self) -> dict:
|
||||
"""Get data on the number of ASC devices and their info.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Returns:
|
||||
Data on all ASC devices.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("asccount")
|
||||
|
||||
async def check(self, command: str) -> dict:
|
||||
"""Check if the command `command` exists in LUXMiner.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
command: The command to check.
|
||||
|
||||
Returns:
|
||||
## Information about a command:
|
||||
* Exists (Y/N) <- the command exists in this version
|
||||
* Access (Y/N) <- you have access to use the command
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("check", parameters=command)
|
||||
|
||||
async def coin(self) -> dict:
|
||||
"""Get information on the current coin.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Returns:
|
||||
## Information about the current coin being mined:
|
||||
* Hash Method <- the hashing algorithm
|
||||
* Current Block Time <- blocktime as a float, 0 means none
|
||||
* Current Block Hash <- the hash of the current block, blank means none
|
||||
* LP <- whether LP is in use on at least 1 pool
|
||||
* Network Difficulty: the current network difficulty
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("coin")
|
||||
|
||||
async def config(self) -> dict:
|
||||
"""Get some basic configuration info.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Returns:
|
||||
Miner configuration information.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("config")
|
||||
|
||||
async def curtail(self, session_id: str) -> dict:
|
||||
"""Put the miner into sleep mode. Requires a session_id from logon.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
session_id: Session id from the logon command.
|
||||
|
||||
Returns:
|
||||
A confirmation of putting the miner to sleep.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("curtail", parameters=session_id)
|
||||
|
||||
async def devdetails(self) -> dict:
|
||||
"""Get data on all devices with their static details.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Returns:
|
||||
Data on all devices with their static details.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("devdetails")
|
||||
|
||||
async def devs(self) -> dict:
|
||||
"""Get data on each PGA/ASC with their details.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Returns:
|
||||
Data on each PGA/ASC with their details.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("devs")
|
||||
|
||||
async def disablepool(self, n: int) -> dict:
|
||||
"""Disable a pool.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
n: Pool to disable.
|
||||
|
||||
Returns:
|
||||
A confirmation of diabling the pool.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("disablepool", parameters=n)
|
||||
|
||||
async def edevs(self) -> dict:
|
||||
"""Alias for devs"""
|
||||
return await self.devs()
|
||||
|
||||
async def enablepool(self, n: int) -> dict:
|
||||
"""Enable pool n.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
n: The pool to enable.
|
||||
|
||||
Returns:
|
||||
A confirmation of enabling pool n.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("enablepool", parameters=n)
|
||||
|
||||
async def estats(self) -> dict:
|
||||
"""Alias for stats"""
|
||||
return await self.stats()
|
||||
|
||||
async def fans(self) -> dict:
|
||||
"""Get fan data.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Returns:
|
||||
Data on the fans of the miner.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("fans")
|
||||
|
||||
async def fanset(self, session_id: str, speed: int, min_fans: int = None) -> dict:
|
||||
"""Set fan control. Requires a session_id from logon.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
session_id: Session id from the logon command.
|
||||
speed: The fan speed to set. Use -1 to set automatically.
|
||||
min_fans: The minimum number of fans to use. Optional.
|
||||
|
||||
Returns:
|
||||
A confirmation of setting fan control values.
|
||||
</details>
|
||||
"""
|
||||
fanset_data = [str(session_id), str(speed)]
|
||||
if min_fans is not None:
|
||||
fanset_data.append(str(min_fans))
|
||||
return await self.send_command("fanset", parameters=",".join(fanset_data))
|
||||
|
||||
async def frequencyget(self, board_n: int, chip_n: int = None) -> dict:
|
||||
"""Get frequency data for a board and chips.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
board_n: The board number to get frequency info from.
|
||||
chip_n: The chip number to get frequency info from. Optional.
|
||||
|
||||
Returns:
|
||||
Board and/or chip frequency values.
|
||||
</details>
|
||||
"""
|
||||
frequencyget_data = [str(board_n)]
|
||||
if chip_n is not None:
|
||||
frequencyget_data.append(str(chip_n))
|
||||
return await self.send_command(
|
||||
"frequencyget", parameters=",".join(frequencyget_data)
|
||||
)
|
||||
|
||||
async def frequencyset(self, session_id: str, board_n: int, freq: int) -> dict:
|
||||
"""Set frequency. Requires a session_id from logon.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
session_id: Session id from the logon command.
|
||||
board_n: The board number to set frequency on.
|
||||
freq: The frequency to set.
|
||||
|
||||
Returns:
|
||||
A confirmation of setting frequency values.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command(
|
||||
"frequencyset", parameters=f"{session_id},{board_n},{freq}"
|
||||
)
|
||||
|
||||
async def frequencystop(self, session_id: str, board_n: int) -> dict:
|
||||
"""Stop set frequency. Requires a session_id from logon.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
session_id: Session id from the logon command.
|
||||
board_n: The board number to set frequency on.
|
||||
|
||||
Returns:
|
||||
A confirmation of stopping frequencyset value.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command(
|
||||
"frequencystop", parameters=f"{session_id},{board_n}"
|
||||
)
|
||||
|
||||
async def groupquota(self, group_n: int, quota: int) -> dict:
|
||||
"""Set a group's quota.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
group_n: The group number to set quota on.
|
||||
quota: The quota to use.
|
||||
|
||||
Returns:
|
||||
A confirmation of setting quota value.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("groupquota", parameters=f"{group_n},{quota}")
|
||||
|
||||
async def groups(self) -> dict:
|
||||
"""Get pool group data.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Returns:
|
||||
Data on the pool groups on the miner.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("groups")
|
||||
|
||||
async def healthchipget(self, board_n: int, chip_n: int = None) -> dict:
|
||||
"""Get chip health.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
board_n: The board number to get chip health of.
|
||||
chip_n: The chip number to get chip health of. Optional.
|
||||
|
||||
Returns:
|
||||
Chip health data.
|
||||
</details>
|
||||
"""
|
||||
healthchipget_data = [str(board_n)]
|
||||
if chip_n is not None:
|
||||
healthchipget_data.append(str(chip_n))
|
||||
return await self.send_command(
|
||||
"healthchipget", parameters=",".join(healthchipget_data)
|
||||
)
|
||||
|
||||
async def healthchipset(
|
||||
self, session_id: str, board_n: int, chip_n: int = None
|
||||
) -> dict:
|
||||
"""Select the next chip to have its health checked. Requires a session_id from logon.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
session_id: Session id from the logon command.
|
||||
board_n: The board number to next get chip health of.
|
||||
chip_n: The chip number to next get chip health of. Optional.
|
||||
|
||||
Returns:
|
||||
Confirmation of selecting the next health check chip.
|
||||
</details>
|
||||
"""
|
||||
healthchipset_data = [session_id, str(board_n)]
|
||||
if chip_n is not None:
|
||||
healthchipset_data.append(str(chip_n))
|
||||
return await self.send_command(
|
||||
"healthchipset", parameters=",".join(healthchipset_data)
|
||||
)
|
||||
|
||||
async def healthctrl(self) -> dict:
|
||||
"""Get health check config.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Returns:
|
||||
Health check config.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("healthctrl")
|
||||
|
||||
async def healthctrlset(
|
||||
self, session_id: str, num_readings: int, amplified_factor: float
|
||||
) -> dict:
|
||||
"""Set health control config. Requires a session_id from logon.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
session_id: Session id from the logon command.
|
||||
num_readings: The minimum number of readings for evaluation.
|
||||
amplified_factor: Performance factor of the evaluation.
|
||||
|
||||
Returns:
|
||||
A confirmation of setting health control config.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command(
|
||||
"healthctrlset",
|
||||
parameters=f"{session_id},{num_readings},{amplified_factor}",
|
||||
)
|
||||
|
||||
async def kill(self) -> dict:
|
||||
"""Forced session kill. Use logoff instead.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Returns:
|
||||
A confirmation of killing the active session.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("kill")
|
||||
|
||||
async def lcd(self) -> dict:
|
||||
"""Get a general all-in-one status summary of the miner. Always zeros on LUXMiner.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Returns:
|
||||
An all-in-one status summary of the miner.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("lcd")
|
||||
|
||||
async def ledset(
|
||||
self,
|
||||
session_id: str,
|
||||
color: Literal["red"],
|
||||
state: Literal["on", "off", "blink"],
|
||||
) -> dict:
|
||||
"""Set led. Requires a session_id from logon.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
session_id: Session id from the logon command.
|
||||
color: The color LED to set. Can be "red".
|
||||
state: The state to set the LED to. Can be "on", "off", or "blink".
|
||||
|
||||
Returns:
|
||||
A confirmation of setting LED.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command(
|
||||
"ledset", parameters=f"{session_id},{color},{state}"
|
||||
)
|
||||
|
||||
async def limits(self) -> dict:
|
||||
"""Get max and min values of config parameters.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Returns:
|
||||
Data on max and min values of config parameters.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("limits")
|
||||
|
||||
async def logoff(self, session_id: str) -> dict:
|
||||
"""Log off of a session. Requires a session id from an active session.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
session_id: Session id from the logon command.
|
||||
|
||||
Returns:
|
||||
Confirmation of logging off a session.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("logoff", parameters=session_id)
|
||||
|
||||
async def logon(self) -> dict:
|
||||
"""Get or create a session.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Returns:
|
||||
The Session ID to be used.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("logon")
|
||||
|
||||
async def pools(self) -> dict:
|
||||
"""Get pool information.
|
||||
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Returns:
|
||||
Miner pool information.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("pools")
|
||||
|
||||
async def power(self) -> dict:
|
||||
"""Get the estimated power usage in watts.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Returns:
|
||||
Estimated power usage in watts.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("power")
|
||||
|
||||
async def profiles(self) -> dict:
|
||||
"""Get the available profiles.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Returns:
|
||||
Data on available profiles.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("profiles")
|
||||
|
||||
async def profileset(self, session_id: str, board_n: int, profile: str) -> dict:
|
||||
"""Set active profile for a board. Requires a session_id from logon.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
session_id: Session id from the logon command.
|
||||
board_n: The board to set the profile on.
|
||||
profile: The profile name to use.
|
||||
|
||||
Returns:
|
||||
A confirmation of setting the profile on board_n.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command(
|
||||
"profileset", parameters=f"{session_id},{board_n},{profile}"
|
||||
)
|
||||
|
||||
async def reboot(self, session_id: str, board_n: int, delay_s: int = None) -> dict:
|
||||
"""Reboot a board. Requires a session_id from logon.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
session_id: Session id from the logon command.
|
||||
board_n: The board to reboot.
|
||||
delay_s: The number of seconds to delay until startup. If it is 0, the board will just stop. Optional.
|
||||
|
||||
Returns:
|
||||
A confirmation of rebooting board_n.
|
||||
</details>
|
||||
"""
|
||||
reboot_data = [session_id, str(board_n)]
|
||||
if delay_s is not None:
|
||||
reboot_data.append(str(delay_s))
|
||||
return await self.send_command("reboot", parameters=",".join(reboot_data))
|
||||
|
||||
async def rebootdevice(self, session_id: str) -> dict:
|
||||
"""Reboot the miner. Requires a session_id from logon.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
session_id: Session id from the logon command.
|
||||
|
||||
Returns:
|
||||
A confirmation of rebooting the miner.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("rebootdevice", parameters=session_id)
|
||||
|
||||
async def removegroup(self, group_id: str) -> dict:
|
||||
"""Remove a pool group.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
group_id: Group id to remove.
|
||||
|
||||
Returns:
|
||||
A confirmation of removing the pool group.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("removegroup", parameters=group_id)
|
||||
|
||||
async def resetminer(self, session_id: str) -> dict:
|
||||
"""Restart the mining process. Requires a session_id from logon.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
session_id: Session id from the logon command.
|
||||
|
||||
Returns:
|
||||
A confirmation of restarting the mining process.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("resetminer", parameters=session_id)
|
||||
|
||||
async def removepool(self, pool_id: int) -> dict:
|
||||
"""Remove a pool.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
pool_id: Pool to remove.
|
||||
|
||||
Returns:
|
||||
A confirmation of removing the pool.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("removepool", parameters=str(pool_id))
|
||||
|
||||
async def session(self) -> dict:
|
||||
"""Get the current session.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Returns:
|
||||
Data on the current session.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("session")
|
||||
|
||||
async def tempctrlset(self, target: int, hot: int, dangerous: int) -> dict:
|
||||
"""Set temp control values.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
target: Target temp.
|
||||
hot: Hot temp.
|
||||
dangerous: Dangerous temp.
|
||||
|
||||
Returns:
|
||||
A confirmation of setting the temp control config.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command(
|
||||
"tempctrlset", parameters=f"{target},{hot},{dangerous}"
|
||||
)
|
||||
|
||||
async def stats(self) -> dict:
|
||||
"""Get stats of each device/pool with more than 1 getwork.
|
||||
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Returns:
|
||||
Stats of each device/pool with more than 1 getwork.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("stats")
|
||||
|
||||
async def summary(self) -> dict:
|
||||
"""Get the status summary of the miner.
|
||||
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Returns:
|
||||
The status summary of the miner.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("summary")
|
||||
|
||||
async def switchpool(self, pool_id: int) -> dict:
|
||||
"""Switch to a pool.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
pool_id: Pool to switch to.
|
||||
|
||||
Returns:
|
||||
A confirmation of switching to the pool.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("switchpool", parameters=str(pool_id))
|
||||
|
||||
async def tempctrl(self) -> dict:
|
||||
"""Get temperature control data.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Returns:
|
||||
Data about the temp control settings of the miner.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("tempctrl")
|
||||
|
||||
async def temps(self) -> dict:
|
||||
"""Get temperature data.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Returns:
|
||||
Data on the temps of the miner.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("temps")
|
||||
|
||||
async def version(self) -> dict:
|
||||
"""Get miner version info.
|
||||
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Returns:
|
||||
Miner version information.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("version")
|
||||
|
||||
async def voltageget(self, board_n: int) -> dict:
|
||||
"""Get voltage data for a board.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
board_n: The board number to get voltage info from.
|
||||
|
||||
Returns:
|
||||
Board voltage values.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("frequencyget", parameters=str(board_n))
|
||||
|
||||
async def voltageset(self, session_id: str, board_n: int, voltage: float) -> dict:
|
||||
"""Set voltage values.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
session_id: Session id from the logon command.
|
||||
board_n: The board to set the voltage on.
|
||||
voltage: The voltage to use.
|
||||
|
||||
Returns:
|
||||
A confirmation of setting the voltage.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command(
|
||||
"voltageset", parameters=f"{session_id},{board_n},{voltage}"
|
||||
)
|
||||
|
||||
async def wakeup(self, session_id: str) -> dict:
|
||||
"""Take the miner out of sleep mode. Requires a session_id from logon.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
session_id: Session id from the logon command.
|
||||
|
||||
Returns:
|
||||
A confirmation of resuming mining.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("wakeup", parameters=session_id)
|
||||
@@ -13,6 +13,7 @@
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
from pyasic import settings
|
||||
from pyasic.API.bmminer import BMMinerAPI
|
||||
from pyasic.API.bosminer import BOSMinerAPI
|
||||
from pyasic.API.btminer import BTMinerAPI
|
||||
@@ -29,10 +30,9 @@ from pyasic.data import (
|
||||
from pyasic.errors import APIError, APIWarning
|
||||
from pyasic.miners import get_miner
|
||||
from pyasic.miners.base import AnyMiner
|
||||
from pyasic.miners.miner_factory import MinerFactory
|
||||
from pyasic.miners.miner_factory import MinerFactory, miner_factory
|
||||
from pyasic.miners.miner_listener import MinerListener
|
||||
from pyasic.network import MinerNetwork
|
||||
from pyasic.settings import PyasicSettings
|
||||
|
||||
__all__ = [
|
||||
"BMMinerAPI",
|
||||
@@ -51,7 +51,8 @@ __all__ = [
|
||||
"get_miner",
|
||||
"AnyMiner",
|
||||
"MinerFactory",
|
||||
"miner_factory",
|
||||
"MinerListener",
|
||||
"MinerNetwork",
|
||||
"PyasicSettings",
|
||||
"settings",
|
||||
]
|
||||
|
||||
@@ -215,7 +215,7 @@ class _PoolGroup:
|
||||
return pools
|
||||
|
||||
def as_x17(self, user_suffix: str = None) -> dict:
|
||||
"""Convert the data in this class to a list usable by an X5 device.
|
||||
"""Convert the data in this class to a list usable by an X17 device.
|
||||
|
||||
Parameters:
|
||||
user_suffix: The suffix to append to username.
|
||||
@@ -547,11 +547,11 @@ class MinerConfig:
|
||||
"""
|
||||
logging.debug(f"MinerConfig - (As X19) - Generating X19 config")
|
||||
cfg = {
|
||||
"pools": self.pool_groups[0].as_x19(user_suffix=user_suffix),
|
||||
"bitmain-fan-ctrl": False,
|
||||
"bitmain-fan-pwn": "100",
|
||||
"freq-level": "100",
|
||||
"miner-mode": str(self.miner_mode.value),
|
||||
"freq-level": "100"
|
||||
"pools": self.pool_groups[0].as_x19(user_suffix=user_suffix),
|
||||
}
|
||||
|
||||
if not self.temp_mode == "auto":
|
||||
@@ -560,9 +560,6 @@ class MinerConfig:
|
||||
if self.fan_speed:
|
||||
cfg["bitmain-fan-pwn"] = str(self.fan_speed)
|
||||
|
||||
if self.miner_mode == X19PowerMode.Sleep:
|
||||
cfg["freq-level"] = "0"
|
||||
|
||||
return cfg
|
||||
|
||||
def as_x17(self, user_suffix: str = None) -> dict:
|
||||
|
||||
@@ -20,7 +20,7 @@ import logging
|
||||
import time
|
||||
from dataclasses import asdict, dataclass, field, fields
|
||||
from datetime import datetime, timezone
|
||||
from typing import List, Union
|
||||
from typing import Any, List, Union
|
||||
|
||||
from .error_codes import BraiinsOSError, InnosiliconError, WhatsminerError, X19Error
|
||||
|
||||
@@ -40,13 +40,28 @@ class HashBoard:
|
||||
"""
|
||||
|
||||
slot: int = 0
|
||||
hashrate: float = 0.0
|
||||
temp: int = -1
|
||||
chip_temp: int = -1
|
||||
chips: int = 0
|
||||
expected_chips: int = 0
|
||||
hashrate: float = None
|
||||
temp: int = None
|
||||
chip_temp: int = None
|
||||
chips: int = None
|
||||
expected_chips: int = None
|
||||
missing: bool = True
|
||||
|
||||
def get(self, __key: str, default: Any = None):
|
||||
try:
|
||||
val = self.__getitem__(__key)
|
||||
if val is None:
|
||||
return default
|
||||
return val
|
||||
except KeyError:
|
||||
return default
|
||||
|
||||
def __getitem__(self, item: str):
|
||||
try:
|
||||
return getattr(self, item)
|
||||
except AttributeError:
|
||||
raise KeyError(f"{item}")
|
||||
|
||||
|
||||
@dataclass
|
||||
class Fan:
|
||||
@@ -56,7 +71,22 @@ class Fan:
|
||||
speed: The speed of the fan.
|
||||
"""
|
||||
|
||||
speed: int = -1
|
||||
speed: int = None
|
||||
|
||||
def get(self, __key: str, default: Any = None):
|
||||
try:
|
||||
val = self.__getitem__(__key)
|
||||
if val is None:
|
||||
return default
|
||||
return val
|
||||
except KeyError:
|
||||
return default
|
||||
|
||||
def __getitem__(self, item: str):
|
||||
try:
|
||||
return getattr(self, item)
|
||||
except AttributeError:
|
||||
raise KeyError(f"{item}")
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -66,34 +96,23 @@ class MinerData:
|
||||
Attributes:
|
||||
ip: The IP of the miner as a str.
|
||||
datetime: The time and date this data was generated.
|
||||
uptime: The uptime of the miner in seconds.
|
||||
mac: The MAC address of the miner as a str.
|
||||
model: The model of the miner as a str.
|
||||
make: The make of the miner as a str.
|
||||
api_ver: The current api version on the miner as a str.
|
||||
fw_ver: The current firmware version on the miner as a str.
|
||||
hostname: The network hostname of the miner as a str.
|
||||
hashrate: The hashrate of the miner in TH/s as a float.
|
||||
hashrate: The hashrate of the miner in TH/s as a float. Calculated automatically.
|
||||
_hashrate: Backup for hashrate found via API instead of hashboards.
|
||||
nominal_hashrate: The factory nominal hashrate of the miner in TH/s as a float.
|
||||
left_board_hashrate: The hashrate of the left board of the miner in TH/s as a float.
|
||||
center_board_hashrate: The hashrate of the center board of the miner in TH/s as a float.
|
||||
right_board_hashrate: The hashrate of the right board of the miner in TH/s as a float.
|
||||
hashboards: A list of hashboards on the miner with their statistics.
|
||||
temperature_avg: The average temperature across the boards. Calculated automatically.
|
||||
env_temp: The environment temps as a float.
|
||||
left_board_temp: The temp of the left PCB as an int.
|
||||
left_board_chip_temp: The temp of the left board chips as an int.
|
||||
center_board_temp: The temp of the center PCB as an int.
|
||||
center_board_chip_temp: The temp of the center board chips as an int.
|
||||
right_board_temp: The temp of the right PCB as an int.
|
||||
right_board_chip_temp: The temp of the right board chips as an int.
|
||||
wattage: Current power draw of the miner as an int.
|
||||
wattage_limit: Power limit of the miner as an int.
|
||||
fan_1: The speed of the first fan as an int.
|
||||
fan_2: The speed of the second fan as an int.
|
||||
fan_3: The speed of the third fan as an int.
|
||||
fan_4: The speed of the fourth fan as an int.
|
||||
fans: A list of fans on the miner with their speeds.
|
||||
fan_psu: The speed of the PSU on the fan if the miner collects it.
|
||||
left_chips: The number of chips online in the left board as an int.
|
||||
center_chips: The number of chips online in the left board as an int.
|
||||
right_chips: The number of chips online in the left board as an int.
|
||||
total_chips: The total number of chips on all boards. Calculated automatically.
|
||||
ideal_chips: The ideal number of chips in the miner as an int.
|
||||
percent_ideal_chips: The percent of total chips out of the ideal count. Calculated automatically.
|
||||
@@ -106,51 +125,37 @@ class MinerData:
|
||||
pool_2_url: The second pool url on the miner as a str.
|
||||
pool_2_user: The second pool user on the miner as a str.
|
||||
errors: A list of errors on the miner.
|
||||
fault_light: Whether or not the fault light is on as a boolean.
|
||||
fault_light: Whether the fault light is on as a boolean.
|
||||
efficiency: Efficiency of the miner in J/TH (Watts per TH/s). Calculated automatically.
|
||||
is_mining: Whether the miner is mining.
|
||||
"""
|
||||
|
||||
ip: str
|
||||
datetime: datetime = None
|
||||
mac: str = "00:00:00:00:00:00"
|
||||
model: str = "Unknown"
|
||||
make: str = "Unknown"
|
||||
api_ver: str = "Unknown"
|
||||
fw_ver: str = "Unknown"
|
||||
hostname: str = "Unknown"
|
||||
uptime: int = None
|
||||
mac: str = None
|
||||
model: str = None
|
||||
make: str = None
|
||||
api_ver: str = None
|
||||
fw_ver: str = None
|
||||
hostname: str = None
|
||||
hashrate: float = field(init=False)
|
||||
_hashrate: float = 0
|
||||
nominal_hashrate: float = 0
|
||||
_hashrate: float = None
|
||||
nominal_hashrate: float = None
|
||||
hashboards: List[HashBoard] = field(default_factory=list)
|
||||
ideal_hashboards: int = 1
|
||||
left_board_hashrate: float = field(init=False)
|
||||
center_board_hashrate: float = field(init=False)
|
||||
right_board_hashrate: float = field(init=False)
|
||||
ideal_hashboards: int = None
|
||||
temperature_avg: int = field(init=False)
|
||||
env_temp: float = -1.0
|
||||
left_board_temp: int = field(init=False)
|
||||
left_board_chip_temp: int = field(init=False)
|
||||
center_board_temp: int = field(init=False)
|
||||
center_board_chip_temp: int = field(init=False)
|
||||
right_board_temp: int = field(init=False)
|
||||
right_board_chip_temp: int = field(init=False)
|
||||
wattage: int = -1
|
||||
wattage_limit: int = -1
|
||||
env_temp: float = None
|
||||
wattage: int = None
|
||||
wattage_limit: int = None
|
||||
fans: List[Fan] = field(default_factory=list)
|
||||
fan_1: int = field(init=False)
|
||||
fan_2: int = field(init=False)
|
||||
fan_3: int = field(init=False)
|
||||
fan_4: int = field(init=False)
|
||||
fan_psu: int = -1
|
||||
left_chips: int = field(init=False)
|
||||
center_chips: int = field(init=False)
|
||||
right_chips: int = field(init=False)
|
||||
fan_psu: int = None
|
||||
total_chips: int = field(init=False)
|
||||
ideal_chips: int = 1
|
||||
ideal_chips: int = None
|
||||
percent_ideal_chips: float = field(init=False)
|
||||
percent_ideal_hashrate: float = field(init=False)
|
||||
percent_ideal_wattage: float = field(init=False)
|
||||
nominal: int = field(init=False)
|
||||
nominal: bool = field(init=False)
|
||||
pool_split: str = "0"
|
||||
pool_1_url: str = "Unknown"
|
||||
pool_1_user: str = "Unknown"
|
||||
@@ -161,6 +166,7 @@ class MinerData:
|
||||
] = field(default_factory=list)
|
||||
fault_light: Union[bool, None] = None
|
||||
efficiency: int = field(init=False)
|
||||
is_mining: bool = True
|
||||
|
||||
@classmethod
|
||||
def fields(cls):
|
||||
@@ -169,7 +175,16 @@ class MinerData:
|
||||
def __post_init__(self):
|
||||
self.datetime = datetime.now(timezone.utc).astimezone()
|
||||
|
||||
def __getitem__(self, item):
|
||||
def get(self, __key: str, default: Any = None):
|
||||
try:
|
||||
val = self.__getitem__(__key)
|
||||
if val is None:
|
||||
return default
|
||||
return val
|
||||
except KeyError:
|
||||
return default
|
||||
|
||||
def __getitem__(self, item: str):
|
||||
try:
|
||||
return getattr(self, item)
|
||||
except AttributeError:
|
||||
@@ -221,204 +236,37 @@ class MinerData:
|
||||
@property
|
||||
def hashrate(self): # noqa - Skip PyCharm inspection
|
||||
if len(self.hashboards) > 0:
|
||||
return round(sum(map(lambda x: x.hashrate, self.hashboards)), 2)
|
||||
hr_data = []
|
||||
for item in self.hashboards:
|
||||
if item.hashrate is not None:
|
||||
hr_data.append(item.hashrate)
|
||||
if len(hr_data) > 0:
|
||||
return round(sum(hr_data), 2)
|
||||
return self._hashrate
|
||||
|
||||
@hashrate.setter
|
||||
def hashrate(self, val):
|
||||
self._hashrate = val
|
||||
|
||||
@property
|
||||
def fan_1(self): # noqa - Skip PyCharm inspection
|
||||
if len(self.fans) > 0:
|
||||
return self.fans[0].speed
|
||||
|
||||
@fan_1.setter
|
||||
def fan_1(self, val):
|
||||
pass
|
||||
|
||||
@property
|
||||
def fan_2(self): # noqa - Skip PyCharm inspection
|
||||
if len(self.fans) > 1:
|
||||
return self.fans[1].speed
|
||||
|
||||
@fan_2.setter
|
||||
def fan_2(self, val):
|
||||
pass
|
||||
|
||||
@property
|
||||
def fan_3(self): # noqa - Skip PyCharm inspection
|
||||
if len(self.fans) > 2:
|
||||
return self.fans[2].speed
|
||||
|
||||
@fan_3.setter
|
||||
def fan_3(self, val):
|
||||
pass
|
||||
|
||||
@property
|
||||
def fan_4(self): # noqa - Skip PyCharm inspection
|
||||
if len(self.fans) > 3:
|
||||
return self.fans[3].speed
|
||||
|
||||
@fan_4.setter
|
||||
def fan_4(self, val):
|
||||
pass
|
||||
|
||||
@property
|
||||
def total_chips(self): # noqa - Skip PyCharm inspection
|
||||
return sum([hb.chips for hb in self.hashboards])
|
||||
if len(self.hashboards) > 0:
|
||||
chip_data = []
|
||||
for item in self.hashboards:
|
||||
if item.chips is not None:
|
||||
chip_data.append(item.chips)
|
||||
if len(chip_data) > 0:
|
||||
return sum(chip_data)
|
||||
return None
|
||||
|
||||
@total_chips.setter
|
||||
def total_chips(self, val):
|
||||
pass
|
||||
|
||||
@property
|
||||
def left_chips(self): # noqa - Skip PyCharm inspection
|
||||
if len(self.hashboards) in [2, 3, 4]:
|
||||
return self.hashboards[0].chips
|
||||
|
||||
return 0
|
||||
|
||||
@left_chips.setter
|
||||
def left_chips(self, val):
|
||||
pass
|
||||
|
||||
@property
|
||||
def center_chips(self): # noqa - Skip PyCharm inspection
|
||||
if len(self.hashboards) == 1:
|
||||
return self.hashboards[0].chips
|
||||
if len(self.hashboards) in [2, 3, 4]:
|
||||
return self.hashboards[1].chips
|
||||
return 0
|
||||
|
||||
@center_chips.setter
|
||||
def center_chips(self, val):
|
||||
pass
|
||||
|
||||
@property
|
||||
def right_chips(self): # noqa - Skip PyCharm inspection
|
||||
if len(self.hashboards) == 2:
|
||||
return self.hashboards[1].chips
|
||||
if len(self.hashboards) == 3:
|
||||
return self.hashboards[2].chips
|
||||
if len(self.hashboards) > 3:
|
||||
return self.hashboards[-1:][0].chips
|
||||
return 0
|
||||
|
||||
@right_chips.setter
|
||||
def right_chips(self, val):
|
||||
pass
|
||||
|
||||
@property
|
||||
def left_board_hashrate(self): # noqa - Skip PyCharm inspection
|
||||
if len(self.hashboards) in [2, 3, 4]:
|
||||
return self.hashboards[0].hashrate
|
||||
return 0
|
||||
|
||||
@left_board_hashrate.setter
|
||||
def left_board_hashrate(self, val):
|
||||
pass
|
||||
|
||||
@property
|
||||
def center_board_hashrate(self): # noqa - Skip PyCharm inspection
|
||||
if len(self.hashboards) == 1:
|
||||
return self.hashboards[0].hashrate
|
||||
if len(self.hashboards) in [2, 3, 4]:
|
||||
return self.hashboards[1].hashrate
|
||||
return 0
|
||||
|
||||
@center_board_hashrate.setter
|
||||
def center_board_hashrate(self, val):
|
||||
pass
|
||||
|
||||
@property
|
||||
def right_board_hashrate(self): # noqa - Skip PyCharm inspection
|
||||
if len(self.hashboards) == 2:
|
||||
return self.hashboards[1].hashrate
|
||||
if len(self.hashboards) == 3:
|
||||
return self.hashboards[2].hashrate
|
||||
if len(self.hashboards) > 3:
|
||||
return self.hashboards[-1:][0].hashrate
|
||||
return 0
|
||||
|
||||
@right_board_hashrate.setter
|
||||
def right_board_hashrate(self, val):
|
||||
pass
|
||||
|
||||
@property
|
||||
def left_board_temp(self): # noqa - Skip PyCharm inspection
|
||||
if len(self.hashboards) in [2, 3, 4]:
|
||||
return self.hashboards[0].temp
|
||||
return 0
|
||||
|
||||
@left_board_temp.setter
|
||||
def left_board_temp(self, val):
|
||||
pass
|
||||
|
||||
@property
|
||||
def center_board_temp(self): # noqa - Skip PyCharm inspection
|
||||
if len(self.hashboards) == 1:
|
||||
return self.hashboards[0].temp
|
||||
if len(self.hashboards) in [2, 3, 4]:
|
||||
return self.hashboards[1].temp
|
||||
return 0
|
||||
|
||||
@center_board_temp.setter
|
||||
def center_board_temp(self, val):
|
||||
pass
|
||||
|
||||
@property
|
||||
def right_board_temp(self): # noqa - Skip PyCharm inspection
|
||||
if len(self.hashboards) == 2:
|
||||
return self.hashboards[1].temp
|
||||
if len(self.hashboards) == 3:
|
||||
return self.hashboards[2].temp
|
||||
if len(self.hashboards) > 3:
|
||||
return self.hashboards[-1:][0].temp
|
||||
return 0
|
||||
|
||||
@right_board_temp.setter
|
||||
def right_board_temp(self, val):
|
||||
pass
|
||||
|
||||
@property
|
||||
def left_board_chip_temp(self): # noqa - Skip PyCharm inspection
|
||||
if len(self.hashboards) in [2, 3, 4]:
|
||||
return self.hashboards[0].chip_temp
|
||||
return 0
|
||||
|
||||
@left_board_chip_temp.setter
|
||||
def left_board_chip_temp(self, val):
|
||||
pass
|
||||
|
||||
@property
|
||||
def center_board_chip_temp(self): # noqa - Skip PyCharm inspection
|
||||
if len(self.hashboards) == 1:
|
||||
return self.hashboards[0].chip_temp
|
||||
if len(self.hashboards) in [2, 3, 4]:
|
||||
return self.hashboards[1].chip_temp
|
||||
return 0
|
||||
|
||||
@center_board_chip_temp.setter
|
||||
def center_board_chip_temp(self, val):
|
||||
pass
|
||||
|
||||
@property
|
||||
def right_board_chip_temp(self): # noqa - Skip PyCharm inspection
|
||||
if len(self.hashboards) == 2:
|
||||
return self.hashboards[1].chip_temp
|
||||
if len(self.hashboards) == 3:
|
||||
return self.hashboards[2].chip_temp
|
||||
if len(self.hashboards) > 3:
|
||||
return self.hashboards[-1:][0].chip_temp
|
||||
return 0
|
||||
|
||||
@right_board_chip_temp.setter
|
||||
def right_board_chip_temp(self, val):
|
||||
pass
|
||||
|
||||
@property
|
||||
def nominal(self): # noqa - Skip PyCharm inspection
|
||||
if self.total_chips is None or self.ideal_chips is None:
|
||||
return None
|
||||
return self.ideal_chips == self.total_chips
|
||||
|
||||
@nominal.setter
|
||||
@@ -427,6 +275,8 @@ class MinerData:
|
||||
|
||||
@property
|
||||
def percent_ideal_chips(self): # noqa - Skip PyCharm inspection
|
||||
if self.total_chips is None or self.ideal_chips is None:
|
||||
return None
|
||||
if self.total_chips == 0 or self.ideal_chips == 0:
|
||||
return 0
|
||||
return round((self.total_chips / self.ideal_chips) * 100)
|
||||
@@ -437,6 +287,8 @@ class MinerData:
|
||||
|
||||
@property
|
||||
def percent_ideal_hashrate(self): # noqa - Skip PyCharm inspection
|
||||
if self.hashrate is None or self.nominal_hashrate is None:
|
||||
return None
|
||||
if self.hashrate == 0 or self.nominal_hashrate == 0:
|
||||
return 0
|
||||
return round((self.hashrate / self.nominal_hashrate) * 100)
|
||||
@@ -447,6 +299,8 @@ class MinerData:
|
||||
|
||||
@property
|
||||
def percent_ideal_wattage(self): # noqa - Skip PyCharm inspection
|
||||
if self.wattage_limit is None or self.wattage is None:
|
||||
return None
|
||||
if self.wattage_limit == 0 or self.wattage == 0:
|
||||
return 0
|
||||
return round((self.wattage / self.wattage_limit) * 100)
|
||||
@@ -460,11 +314,11 @@ class MinerData:
|
||||
total_temp = 0
|
||||
temp_count = 0
|
||||
for hb in self.hashboards:
|
||||
if hb.temp and not hb.temp == -1:
|
||||
if hb.temp is not None:
|
||||
total_temp += hb.temp
|
||||
temp_count += 1
|
||||
if not temp_count > 0:
|
||||
return 0
|
||||
return None
|
||||
return round(total_temp / temp_count)
|
||||
|
||||
@temperature_avg.setter
|
||||
@@ -473,7 +327,9 @@ class MinerData:
|
||||
|
||||
@property
|
||||
def efficiency(self): # noqa - Skip PyCharm inspection
|
||||
if self.hashrate == 0 or self.wattage == -1:
|
||||
if self.hashrate is None or self.wattage is None:
|
||||
return None
|
||||
if self.hashrate == 0 or self.wattage == 0:
|
||||
return 0
|
||||
return round(self.wattage / self.hashrate)
|
||||
|
||||
@@ -482,13 +338,16 @@ class MinerData:
|
||||
pass
|
||||
|
||||
def asdict(self) -> dict:
|
||||
logging.debug(f"MinerData - (To Dict) - Dumping Dict data")
|
||||
return asdict(self)
|
||||
|
||||
def as_dict(self) -> dict:
|
||||
"""Get this dataclass as a dictionary.
|
||||
|
||||
Returns:
|
||||
A dictionary version of this class.
|
||||
"""
|
||||
logging.debug(f"MinerData - (To Dict) - Dumping Dict data")
|
||||
return asdict(self)
|
||||
return self.asdict()
|
||||
|
||||
def as_json(self) -> str:
|
||||
"""Get this dataclass as JSON.
|
||||
@@ -533,27 +392,45 @@ class MinerData:
|
||||
tags = ["ip", "mac", "model", "hostname"]
|
||||
for attribute in self:
|
||||
if attribute in tags:
|
||||
escaped_data = self[attribute].replace(" ", "\\ ")
|
||||
escaped_data = self.get(attribute, "Unknown").replace(" ", "\\ ")
|
||||
tag_data.append(f"{attribute}={escaped_data}")
|
||||
continue
|
||||
if isinstance(self[attribute], str):
|
||||
elif str(attribute).startswith("_"):
|
||||
continue
|
||||
elif isinstance(self[attribute], str):
|
||||
field_data.append(f'{attribute}="{self[attribute]}"')
|
||||
continue
|
||||
if isinstance(self[attribute], bool):
|
||||
elif isinstance(self[attribute], bool):
|
||||
field_data.append(f"{attribute}={str(self[attribute]).lower()}")
|
||||
continue
|
||||
if isinstance(self[attribute], int):
|
||||
elif isinstance(self[attribute], int):
|
||||
field_data.append(f"{attribute}={self[attribute]}")
|
||||
continue
|
||||
if isinstance(self[attribute], float):
|
||||
elif isinstance(self[attribute], float):
|
||||
field_data.append(f"{attribute}={self[attribute]}")
|
||||
continue
|
||||
if attribute == "fault_light" and not self[attribute]:
|
||||
field_data.append(f"{attribute}=false")
|
||||
continue
|
||||
if attribute == "errors":
|
||||
elif attribute == "errors":
|
||||
for idx, item in enumerate(self[attribute]):
|
||||
field_data.append(f'error_{idx+1}="{item.error_message}"')
|
||||
elif attribute == "hashboards":
|
||||
for idx, item in enumerate(self[attribute]):
|
||||
field_data.append(
|
||||
f"hashboard_{idx+1}_hashrate={item.get('hashrate', 0.0)}"
|
||||
)
|
||||
field_data.append(
|
||||
f"hashboard_{idx+1}_temperature={item.get('temp', 0)}"
|
||||
)
|
||||
field_data.append(
|
||||
f"hashboard_{idx+1}_chip_temperature={item.get('chip_temp', 0)}"
|
||||
)
|
||||
field_data.append(f"hashboard_{idx+1}_chips={item.get('chips', 0)}")
|
||||
field_data.append(
|
||||
f"hashboard_{idx+1}_expected_chips={item.get('expected_chips', 0)}"
|
||||
)
|
||||
elif attribute == "fans":
|
||||
for idx, item in enumerate(self[attribute]):
|
||||
if item.speed is not None:
|
||||
field_data.append(f"fan_{idx+1}={item.speed}")
|
||||
|
||||
tags_str = ",".join(tag_data)
|
||||
field_str = ",".join(field_data)
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
from dataclasses import asdict, dataclass, field, fields
|
||||
|
||||
C_N_CODES = ["52", "53", "54", "55", "56"]
|
||||
|
||||
|
||||
@dataclass
|
||||
class WhatsminerError:
|
||||
@@ -37,10 +35,8 @@ class WhatsminerError:
|
||||
|
||||
@property
|
||||
def error_message(self): # noqa - Skip PyCharm inspection
|
||||
if len(str(self.error_code)) > 3 and str(self.error_code)[:2] in C_N_CODES:
|
||||
# 55 error code base has chip numbers, so the format is
|
||||
# 55 -> board num len 1 -> chip num len 3
|
||||
err_type = 55
|
||||
if len(str(self.error_code)) == 6 and not str(self.error_code)[:1] == "1":
|
||||
err_type = int(str(self.error_code)[:2])
|
||||
err_subtype = int(str(self.error_code)[2:3])
|
||||
err_value = int(str(self.error_code)[3:])
|
||||
else:
|
||||
@@ -88,7 +84,9 @@ class WhatsminerError:
|
||||
|
||||
ERROR_CODES = {
|
||||
1: { # Fan error
|
||||
0: {0: "Fan unknown."},
|
||||
0: {
|
||||
0: "Fan unknown.",
|
||||
},
|
||||
1: { # Fan speed error of 1000+
|
||||
0: "Intake fan speed error.",
|
||||
1: "Exhaust fan speed error.",
|
||||
@@ -101,7 +99,9 @@ ERROR_CODES = {
|
||||
0: "Intake fan speed error. Fan speed deviates by more than 3000.",
|
||||
1: "Exhaust fan speed error. Fan speed deviates by more than 3000.",
|
||||
},
|
||||
4: {0: "Fan speed too high."}, # High speed
|
||||
4: {
|
||||
0: "Fan speed too high.",
|
||||
}, # High speed
|
||||
},
|
||||
2: { # Power error
|
||||
0: {
|
||||
@@ -126,6 +126,7 @@ ERROR_CODES = {
|
||||
6: "Power remained unchanged for a long time.",
|
||||
7: "Power set enable error.",
|
||||
8: "Power input voltage is lower than 230V for high power mode.",
|
||||
9: "Power input current is incorrect.",
|
||||
},
|
||||
3: {
|
||||
3: "Power output high temperature protection error.",
|
||||
@@ -159,6 +160,8 @@ ERROR_CODES = {
|
||||
6: {
|
||||
3: "Power communication warning.",
|
||||
4: "Power communication error.",
|
||||
5: "Power unknown error.",
|
||||
6: "Power unknown error.",
|
||||
7: "Power watchdog protection.",
|
||||
8: "Power output high current protection.",
|
||||
9: "Power input high current protection.",
|
||||
@@ -170,57 +173,134 @@ ERROR_CODES = {
|
||||
3: "Power input too high warning.",
|
||||
4: "Power fan warning.",
|
||||
5: "Power high temperature warning.",
|
||||
6: "Power unknown error.",
|
||||
7: "Power unknown error.",
|
||||
8: "Power unknown error.",
|
||||
9: "Power unknown error.",
|
||||
},
|
||||
8: {
|
||||
0: "Power unknown error.",
|
||||
1: "Power vendor status 1 bit 0 error.",
|
||||
2: "Power vendor status 1 bit 1 error.",
|
||||
3: "Power vendor status 1 bit 2 error.",
|
||||
4: "Power vendor status 1 bit 3 error.",
|
||||
5: "Power vendor status 1 bit 4 error.",
|
||||
6: "Power vendor status 1 bit 5 error.",
|
||||
7: "Power vendor status 1 bit 6 error.",
|
||||
8: "Power vendor status 1 bit 7 error.",
|
||||
9: "Power vendor status 2 bit 0 error.",
|
||||
},
|
||||
9: {
|
||||
0: "Power vendor status 2 bit 1 error.",
|
||||
1: "Power vendor status 2 bit 2 error.",
|
||||
2: "Power vendor status 2 bit 3 error.",
|
||||
3: "Power vendor status 2 bit 4 error.",
|
||||
4: "Power vendor status 2 bit 5 error.",
|
||||
5: "Power vendor status 2 bit 6 error.",
|
||||
6: "Power vendor status 2 bit 7 error.",
|
||||
},
|
||||
},
|
||||
3: { # temperature error
|
||||
0: { # sensor detection error
|
||||
"n": "Slot {n} temperature sensor detection error."
|
||||
"n": "Slot {n} temperature sensor detection error.",
|
||||
},
|
||||
2: { # temperature reading error
|
||||
"n": "Slot {n} temperature reading error.",
|
||||
9: "Control board temperature sensor communication error.",
|
||||
},
|
||||
5: {"n": "Slot {n} temperature protecting."}, # temperature protection
|
||||
6: {0: "Hashboard high temperature error."}, # high temp
|
||||
5: {
|
||||
"n": "Slot {n} temperature protecting.",
|
||||
}, # temperature protection
|
||||
6: {
|
||||
0: "Hashboard high temperature error.",
|
||||
1: "Hashboard high temperature error.",
|
||||
2: "Hashboard high temperature error.",
|
||||
3: "Hashboard high temperature error.",
|
||||
}, # high temp
|
||||
7: {
|
||||
0: "The environment temperature fluctuates too much.",
|
||||
}, # env temp
|
||||
8: {
|
||||
0: "Humidity sensor not found.",
|
||||
1: "Humidity sensor read error.",
|
||||
2: "Humidity sensor read error.",
|
||||
3: "Humidity sensor protecting.",
|
||||
},
|
||||
}, # humidity
|
||||
},
|
||||
4: { # EEPROM error
|
||||
0: {0: "Eeprom unknown error."},
|
||||
1: {"n": "Slot {n} eeprom detection error."}, # EEPROM detection error
|
||||
2: {"n": "Slot {n} eeprom parsing error."}, # EEPROM parsing error
|
||||
3: {"n": "Slot {n} chip bin type error."}, # chip bin error
|
||||
4: {"n": "Slot {n} eeprom chip number X error."}, # EEPROM chip number error
|
||||
5: {"n": "Slot {n} eeprom xfer error."}, # EEPROM xfer error
|
||||
0: {
|
||||
0: "Eeprom unknown error.",
|
||||
},
|
||||
1: {
|
||||
"n": "Slot {n} eeprom detection error.",
|
||||
}, # EEPROM detection error
|
||||
2: {
|
||||
"n": "Slot {n} eeprom parsing error.",
|
||||
}, # EEPROM parsing error
|
||||
3: {
|
||||
"n": "Slot {n} chip bin type error.",
|
||||
}, # chip bin error
|
||||
4: {
|
||||
"n": "Slot {n} eeprom chip number X error.",
|
||||
}, # EEPROM chip number error
|
||||
5: {
|
||||
"n": "Slot {n} eeprom xfer error.",
|
||||
}, # EEPROM xfer error
|
||||
},
|
||||
5: { # hashboard error
|
||||
0: {0: "Board unknown error."},
|
||||
1: {"n": "Slot {n} miner type error."}, # board miner type error
|
||||
2: {"n": "Slot {n} bin type error."}, # chip bin type error
|
||||
3: {"n": "Slot {n} not found."}, # board not found error
|
||||
4: {"n": "Slot {n} error reading chip id."}, # reading chip id error
|
||||
5: {"n": "Slot {n} has bad chips."}, # board has bad chips error
|
||||
6: {"n": "Slot {n} loss of balance error."}, # loss of balance error
|
||||
7: {"n": "Slot {n} xfer error chip."}, # xfer error
|
||||
8: {"n": "Slot {n} reset error."}, # reset error
|
||||
9: {"n": "Slot {n} frequency too low."}, # freq error
|
||||
0: {
|
||||
0: "Board unknown error.",
|
||||
},
|
||||
1: {
|
||||
"n": "Slot {n} miner type error.",
|
||||
}, # board miner type error
|
||||
2: {
|
||||
"n": "Slot {n} bin type error.",
|
||||
}, # chip bin type error
|
||||
3: {
|
||||
"n": "Slot {n} not found.",
|
||||
}, # board not found error
|
||||
4: {
|
||||
"n": "Slot {n} error reading chip id.",
|
||||
}, # reading chip id error
|
||||
5: {
|
||||
"n": "Slot {n} has bad chips.",
|
||||
}, # board has bad chips error
|
||||
6: {
|
||||
"n": "Slot {n} loss of balance error.",
|
||||
}, # loss of balance error
|
||||
7: {
|
||||
"n": "Slot {n} xfer error chip.",
|
||||
}, # xfer error
|
||||
8: {
|
||||
"n": "Slot {n} reset error.",
|
||||
}, # reset error
|
||||
9: {
|
||||
"n": "Slot {n} frequency too low.",
|
||||
}, # freq error
|
||||
},
|
||||
6: { # env temp error
|
||||
0: {0: "Environment temperature is too high."}, # normal env temp error
|
||||
0: {
|
||||
0: "Environment temperature is too high.",
|
||||
}, # normal env temp error
|
||||
1: { # high power env temp error
|
||||
0: "Environment temperature is too high for high performance mode."
|
||||
0: "Environment temperature is too high for high performance mode.",
|
||||
},
|
||||
},
|
||||
7: { # control board error
|
||||
0: {0: "MAC address invalid", 1: "Control board no support chip."},
|
||||
0: {
|
||||
0: "MAC address invalid",
|
||||
1: "Control board no support chip.",
|
||||
},
|
||||
1: {
|
||||
0: "Control board rebooted as an exception.",
|
||||
1: "Control board rebooted as exception and cpufreq reduced, please upgrade the firmware",
|
||||
2: "Control board rebooted as an exception.",
|
||||
3: "The network is unstable, change time.",
|
||||
4: "Unknown error.",
|
||||
},
|
||||
2: {
|
||||
"n": "Control board slot {n} frame error.",
|
||||
},
|
||||
},
|
||||
8: { # checksum error
|
||||
@@ -228,63 +308,152 @@ ERROR_CODES = {
|
||||
0: "CGMiner checksum error.",
|
||||
1: "System monitor checksum error.",
|
||||
2: "Remote daemon checksum error.",
|
||||
}
|
||||
},
|
||||
1: {0: "Air to liquid PCB serial # does not match."},
|
||||
},
|
||||
9: {0: {1: "Power rate error."}}, # power rate error
|
||||
9: {
|
||||
0: {0: "Unknown error.", 1: "Power rate error.", 2: "Unknown error."}
|
||||
}, # power rate error
|
||||
20: { # pool error
|
||||
1: {0: "All pools are disabled."}, # all disabled error
|
||||
2: {"n": "Pool {n} connection failed."}, # pool connection failed error
|
||||
3: {0: "High rejection rate on pool."}, # rejection rate error
|
||||
0: {
|
||||
0: "No pool information configured.",
|
||||
},
|
||||
1: {
|
||||
0: "All pools are disabled.",
|
||||
}, # all disabled error
|
||||
2: {
|
||||
"n": "Pool {n} connection failed.",
|
||||
}, # pool connection failed error
|
||||
3: {
|
||||
0: "High rejection rate on pool.",
|
||||
}, # rejection rate error
|
||||
4: { # asicboost not supported error
|
||||
0: "The pool does not support asicboost mode."
|
||||
0: "The pool does not support asicboost mode.",
|
||||
},
|
||||
},
|
||||
21: {1: {"n": "Slot {n} factory test step failed."}},
|
||||
21: {
|
||||
1: {
|
||||
"n": "Slot {n} factory test step failed.",
|
||||
}
|
||||
},
|
||||
23: { # hashrate error
|
||||
1: {0: "Hashrate is too low."},
|
||||
2: {0: "Hashrate is too low."},
|
||||
3: {0: "Hashrate loss is too high."},
|
||||
4: {0: "Hashrate loss is too high."},
|
||||
5: {0: "Hashrate loss."},
|
||||
1: {
|
||||
0: "Hashrate is too low.",
|
||||
},
|
||||
2: {
|
||||
0: "Hashrate is too low.",
|
||||
},
|
||||
3: {
|
||||
0: "Hashrate loss is too high.",
|
||||
},
|
||||
4: {
|
||||
0: "Hashrate loss is too high.",
|
||||
},
|
||||
5: {
|
||||
0: "Hashrate loss.",
|
||||
},
|
||||
},
|
||||
50: { # water velocity error/voltage error
|
||||
1: {"n": "Slot {n} chip voltage too low."},
|
||||
2: {"n": "Slot {n} chip voltage changed."},
|
||||
3: {"n": "Slot {n} chip temperature difference is too large."},
|
||||
4: {"n": "Slot {n} chip hottest temperature difference is too large."},
|
||||
7: {"n": "Slot {n} water velocity is abnormal."}, # abnormal water velocity
|
||||
8: {0: "Chip temp calibration failed, please restore factory settings."},
|
||||
9: {"n": "Slot {n} chip temp calibration check no balance."},
|
||||
1: {
|
||||
"n": "Slot {n} chip voltage too low.",
|
||||
},
|
||||
2: {
|
||||
"n": "Slot {n} chip voltage changed.",
|
||||
},
|
||||
3: {
|
||||
"n": "Slot {n} chip temperature difference is too large.",
|
||||
},
|
||||
4: {
|
||||
"n": "Slot {n} chip hottest temperature difference is too large.",
|
||||
},
|
||||
5: {"n": "Slot {n} stopped hashing, chips temperature protecting."},
|
||||
7: {
|
||||
"n": "Slot {n} water velocity is abnormal.",
|
||||
}, # abnormal water velocity
|
||||
8: {
|
||||
0: "Chip temp calibration failed, please restore factory settings.",
|
||||
},
|
||||
9: {
|
||||
"n": "Slot {n} chip temp calibration check no balance.",
|
||||
},
|
||||
},
|
||||
51: { # frequency error
|
||||
1: {"n": "Slot {n} frequency up timeout."}, # frequency up timeout
|
||||
7: {"n": "Slot {n} frequency up timeout."}, # frequency up timeout
|
||||
1: {
|
||||
"n": "Slot {n} frequency up timeout.",
|
||||
}, # frequency up timeout
|
||||
2: {"n": "Slot {n} too many CRC errors."},
|
||||
3: {"n": "Slot {n} unstable."},
|
||||
7: {
|
||||
"n": "Slot {n} frequency up timeout.",
|
||||
}, # frequency up timeout
|
||||
},
|
||||
52: {
|
||||
"n": {
|
||||
"c": "Slot {n} chip {c} error nonce.",
|
||||
},
|
||||
},
|
||||
53: {
|
||||
"n": {
|
||||
"c": "Slot {n} chip {c} too few nonce.",
|
||||
},
|
||||
},
|
||||
54: {
|
||||
"n": {
|
||||
"c": "Slot {n} chip {c} temp protected.",
|
||||
},
|
||||
},
|
||||
55: {
|
||||
"n": {
|
||||
"c": "Slot {n} chip {c} has been reset.",
|
||||
},
|
||||
},
|
||||
56: {
|
||||
"n": {
|
||||
"c": "Slot {n} chip {c} zero nonce.",
|
||||
},
|
||||
},
|
||||
52: {"n": {"c": "Slot {n} chip {c} error nonce."}},
|
||||
53: {"n": {"c": "Slot {n} chip {c} too few nonce."}},
|
||||
54: {"n": {"c": "Slot {n} chip {c} temp protected."}},
|
||||
55: {"n": {"c": "Slot {n} chip {c} has been reset."}},
|
||||
56: {"n": {"c": "Slot {n} chip {c} does not return to the nonce."}},
|
||||
80: {
|
||||
0: {0: "The tool version is too low, please update."},
|
||||
1: {0: "Low freq."},
|
||||
2: {0: "Low hashrate."},
|
||||
3: {5: "High env temp."},
|
||||
0: {
|
||||
0: "The tool version is too low, please update.",
|
||||
},
|
||||
1: {
|
||||
0: "Low freq.",
|
||||
},
|
||||
2: {
|
||||
0: "Low hashrate.",
|
||||
},
|
||||
3: {
|
||||
5: "High env temp.",
|
||||
},
|
||||
},
|
||||
81: {
|
||||
0: {0: "Chip data error."},
|
||||
0: {
|
||||
0: "Chip data error.",
|
||||
},
|
||||
},
|
||||
82: {
|
||||
0: {0: "Power version error."},
|
||||
1: {0: "Miner type error."},
|
||||
2: {0: "Version info error."},
|
||||
0: {
|
||||
0: "Power version error.",
|
||||
},
|
||||
1: {
|
||||
0: "Miner type error.",
|
||||
},
|
||||
2: {
|
||||
0: "Version info error.",
|
||||
},
|
||||
},
|
||||
83: {
|
||||
0: {0: "Empty level error."},
|
||||
0: {
|
||||
0: "Empty level error.",
|
||||
},
|
||||
},
|
||||
84: {
|
||||
0: {0: "Old firmware."},
|
||||
1: {0: "Software version error."},
|
||||
0: {
|
||||
0: "Old firmware.",
|
||||
},
|
||||
1: {
|
||||
0: "Software version error.",
|
||||
},
|
||||
},
|
||||
85: {
|
||||
"n": {
|
||||
@@ -296,8 +465,12 @@ ERROR_CODES = {
|
||||
},
|
||||
},
|
||||
86: {
|
||||
0: {0: "Missing product serial #."},
|
||||
1: {0: "Missing product type."},
|
||||
0: {
|
||||
0: "Missing product serial #.",
|
||||
},
|
||||
1: {
|
||||
0: "Missing product type.",
|
||||
},
|
||||
2: {
|
||||
0: "Missing miner serial #.",
|
||||
1: "Wrong miner serial # length.",
|
||||
@@ -314,12 +487,34 @@ ERROR_CODES = {
|
||||
3: "Wrong power model rate.",
|
||||
4: "Wrong power model format.",
|
||||
},
|
||||
5: {0: "Wrong hash board struct."},
|
||||
6: {0: "Wrong miner cooling type."},
|
||||
7: {0: "Missing PCB serial #."},
|
||||
5: {
|
||||
0: "Wrong hash board struct.",
|
||||
},
|
||||
6: {
|
||||
0: "Wrong miner cooling type.",
|
||||
},
|
||||
7: {
|
||||
0: "Missing PCB serial #.",
|
||||
},
|
||||
},
|
||||
87: {
|
||||
0: {
|
||||
0: "Miner power mismatch.",
|
||||
},
|
||||
},
|
||||
90: {
|
||||
0: {
|
||||
0: "Process error, exited with signal: 3.",
|
||||
},
|
||||
1: {
|
||||
0: "Process error, exited with signal: 3.",
|
||||
},
|
||||
},
|
||||
99: {
|
||||
9: {
|
||||
9: "Miner unknown error.",
|
||||
},
|
||||
},
|
||||
87: {0: {0: "Miner power mismatch."}},
|
||||
99: {9: {9: "Miner unknown error."}},
|
||||
1000: {
|
||||
0: {
|
||||
0: "Security library error, please upgrade firmware",
|
||||
@@ -328,7 +523,11 @@ ERROR_CODES = {
|
||||
3: "/antiv/dig/pf_partial.dig illegal.",
|
||||
},
|
||||
},
|
||||
1001: {0: {0: "Security BTMiner removed, please upgrade firmware."}},
|
||||
1001: {
|
||||
0: {
|
||||
0: "Security BTMiner removed, please upgrade firmware.",
|
||||
},
|
||||
},
|
||||
1100: {
|
||||
0: {
|
||||
0: "Security illegal file, please upgrade firmware.",
|
||||
|
||||
@@ -19,21 +19,8 @@ from typing import List, Union
|
||||
|
||||
from pyasic.errors import APIError
|
||||
from pyasic.miners import AnyMiner
|
||||
from pyasic.miners.backends import ( # noqa - Ignore access to _module
|
||||
AntminerModern,
|
||||
BOSMiner,
|
||||
BTMiner,
|
||||
)
|
||||
from pyasic.miners.btc._types import ( # noqa - Ignore access to _module
|
||||
S9,
|
||||
S17,
|
||||
T17,
|
||||
S17e,
|
||||
S17Plus,
|
||||
S17Pro,
|
||||
T17e,
|
||||
T17Plus,
|
||||
)
|
||||
from pyasic.miners.backends import AntminerModern, BOSMiner, BTMiner
|
||||
from pyasic.miners.types import S9, S17, T17, S17e, S17Plus, S17Pro, T17e, T17Plus
|
||||
|
||||
FAN_USAGE = 50 # 50 W per fan
|
||||
|
||||
@@ -162,10 +149,10 @@ class _MinerPhaseBalancer:
|
||||
not self.miners[data_point.ip]["shutdown"]
|
||||
):
|
||||
# cant do anything with it so need to find a semi-accurate power limit
|
||||
if not data_point.wattage_limit == -1:
|
||||
if not data_point.wattage_limit == None:
|
||||
self.miners[data_point.ip]["max"] = int(data_point.wattage_limit)
|
||||
self.miners[data_point.ip]["min"] = int(data_point.wattage_limit)
|
||||
elif not data_point.wattage == -1:
|
||||
elif not data_point.wattage == None:
|
||||
self.miners[data_point.ip]["max"] = int(data_point.wattage)
|
||||
self.miners[data_point.ip]["min"] = int(data_point.wattage)
|
||||
|
||||
|
||||
@@ -16,31 +16,29 @@
|
||||
|
||||
import logging
|
||||
|
||||
from pyasic.settings import PyasicSettings
|
||||
|
||||
|
||||
def init_logger():
|
||||
if PyasicSettings().logfile:
|
||||
logging.basicConfig(
|
||||
filename="logfile.txt",
|
||||
filemode="a",
|
||||
format="%(pathname)s:%(lineno)d in %(funcName)s\n[%(levelname)s][%(asctime)s](%(name)s) - %(message)s",
|
||||
datefmt="%x %X",
|
||||
)
|
||||
else:
|
||||
logging.basicConfig(
|
||||
format="%(pathname)s:%(lineno)d in %(funcName)s\n[%(levelname)s][%(asctime)s](%(name)s) - %(message)s",
|
||||
datefmt="%x %X",
|
||||
)
|
||||
# if PyasicSettings().logfile:
|
||||
# logging.basicConfig(
|
||||
# filename="logfile.txt",
|
||||
# filemode="a",
|
||||
# format="%(pathname)s:%(lineno)d in %(funcName)s\n[%(levelname)s][%(asctime)s](%(name)s) - %(message)s",
|
||||
# datefmt="%x %X",
|
||||
# )
|
||||
# else:
|
||||
logging.basicConfig(
|
||||
format="%(pathname)s:%(lineno)d in %(funcName)s\n[%(levelname)s][%(asctime)s](%(name)s) - %(message)s",
|
||||
datefmt="%x %X",
|
||||
)
|
||||
|
||||
_logger = logging.getLogger()
|
||||
|
||||
if PyasicSettings().debug:
|
||||
_logger.setLevel(logging.DEBUG)
|
||||
logging.getLogger("asyncssh").setLevel(logging.DEBUG)
|
||||
else:
|
||||
_logger.setLevel(logging.WARNING)
|
||||
logging.getLogger("asyncssh").setLevel(logging.WARNING)
|
||||
# if PyasicSettings().debug:
|
||||
# _logger.setLevel(logging.DEBUG)
|
||||
# logging.getLogger("asyncssh").setLevel(logging.DEBUG)
|
||||
# else:
|
||||
_logger.setLevel(logging.WARNING)
|
||||
logging.getLogger("asyncssh").setLevel(logging.WARNING)
|
||||
|
||||
return _logger
|
||||
|
||||
|
||||
@@ -18,9 +18,9 @@ import ipaddress
|
||||
from typing import Union
|
||||
|
||||
from pyasic.miners.base import AnyMiner, BaseMiner
|
||||
from pyasic.miners.miner_factory import MinerFactory
|
||||
from pyasic.miners.miner_factory import miner_factory
|
||||
|
||||
|
||||
# abstracted version of get miner that is easier to access
|
||||
async def get_miner(ip: Union[ipaddress.ip_address, str]) -> AnyMiner:
|
||||
return await MinerFactory().get_miner(ip)
|
||||
return await miner_factory.get_miner(ip)
|
||||
|
||||
@@ -18,4 +18,6 @@ from .bmminer import *
|
||||
from .bosminer import *
|
||||
from .cgminer import *
|
||||
from .hiveon import *
|
||||
from .luxos import *
|
||||
from .vnish import *
|
||||
from .epic import *
|
||||
34
pyasic/miners/antminer/bmminer/X17/S17.py
Normal file
34
pyasic/miners/antminer/bmminer/X17/S17.py
Normal file
@@ -0,0 +1,34 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Copyright 2022 Upstream Data Inc -
|
||||
# -
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||
# you may not use this file except in compliance with the License. -
|
||||
# You may obtain a copy of the License at -
|
||||
# -
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||
# -
|
||||
# Unless required by applicable law or agreed to in writing, software -
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.backends import AntminerOld
|
||||
from pyasic.miners.types import S17, S17e, S17Plus, S17Pro
|
||||
|
||||
|
||||
class BMMinerS17(AntminerOld, S17):
|
||||
pass
|
||||
|
||||
|
||||
class BMMinerS17Plus(AntminerOld, S17Plus):
|
||||
pass
|
||||
|
||||
|
||||
class BMMinerS17Pro(AntminerOld, S17Pro):
|
||||
pass
|
||||
|
||||
|
||||
class BMMinerS17e(AntminerOld, S17e):
|
||||
pass
|
||||
@@ -15,9 +15,16 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.backends import AntminerOld
|
||||
from pyasic.miners.ltc._types import L3Plus # noqa - Ignore access to _module
|
||||
from pyasic.miners.types import T17, T17e, T17Plus
|
||||
|
||||
|
||||
class BMMinerL3Plus(AntminerOld, L3Plus):
|
||||
def __init__(self, ip: str, api_ver: str = "0.0.0"):
|
||||
super().__init__(ip, api_ver)
|
||||
class BMMinerT17(AntminerOld, T17):
|
||||
pass
|
||||
|
||||
|
||||
class BMMinerT17Plus(AntminerOld, T17Plus):
|
||||
pass
|
||||
|
||||
|
||||
class BMMinerT17e(AntminerOld, T17e):
|
||||
pass
|
||||
18
pyasic/miners/antminer/bmminer/X17/__init__.py
Normal file
18
pyasic/miners/antminer/bmminer/X17/__init__.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Copyright 2022 Upstream Data Inc -
|
||||
# -
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||
# you may not use this file except in compliance with the License. -
|
||||
# You may obtain a copy of the License at -
|
||||
# -
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||
# -
|
||||
# Unless required by applicable law or agreed to in writing, software -
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from .S17 import BMMinerS17, BMMinerS17e, BMMinerS17Plus, BMMinerS17Pro
|
||||
from .T17 import BMMinerT17, BMMinerT17e, BMMinerT17Plus
|
||||
@@ -15,9 +15,52 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.backends import AntminerModern
|
||||
from pyasic.miners.btc._types import S19j, S19jNoPIC # noqa - Ignore access to _module
|
||||
from pyasic.miners.types import (
|
||||
S19,
|
||||
S19L,
|
||||
S19XP,
|
||||
S19a,
|
||||
S19aPro,
|
||||
S19i,
|
||||
S19j,
|
||||
S19jNoPIC,
|
||||
S19jPro,
|
||||
S19Plus,
|
||||
S19Pro,
|
||||
S19ProPlus,
|
||||
)
|
||||
|
||||
# noqa - Ignore access to _module
|
||||
|
||||
class BMMinerS19(AntminerModern, S19):
|
||||
pass
|
||||
|
||||
|
||||
class BMMinerS19Plus(AntminerModern, S19Plus):
|
||||
pass
|
||||
|
||||
|
||||
class BMMinerS19i(AntminerModern, S19i):
|
||||
pass
|
||||
|
||||
|
||||
class BMMinerS19Pro(AntminerModern, S19Pro):
|
||||
pass
|
||||
|
||||
|
||||
class BMMinerS19ProPlus(AntminerModern, S19ProPlus):
|
||||
pass
|
||||
|
||||
|
||||
class BMMinerS19XP(AntminerModern, S19XP):
|
||||
pass
|
||||
|
||||
|
||||
class BMMinerS19a(AntminerModern, S19a):
|
||||
pass
|
||||
|
||||
|
||||
class BMMinerS19aPro(AntminerModern, S19aPro):
|
||||
pass
|
||||
|
||||
|
||||
class BMMinerS19j(AntminerModern, S19j):
|
||||
@@ -26,3 +69,11 @@ class BMMinerS19j(AntminerModern, S19j):
|
||||
|
||||
class BMMinerS19jNoPIC(AntminerModern, S19jNoPIC):
|
||||
pass
|
||||
|
||||
|
||||
class BMMinerS19jPro(AntminerModern, S19jPro):
|
||||
pass
|
||||
|
||||
|
||||
class BMMinerS19L(AntminerModern, S19L):
|
||||
pass
|
||||
@@ -15,7 +15,7 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.backends import AntminerModern
|
||||
from pyasic.miners.btc._types import T19 # noqa - Ignore access to _module
|
||||
from pyasic.miners.types import T19
|
||||
|
||||
# noqa - Ignore access to _module
|
||||
|
||||
@@ -14,13 +14,18 @@
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from .S19 import S19
|
||||
from .S19_Pro import S19Pro
|
||||
from .S19_Pro_Plus import S19ProPlus
|
||||
from .S19_XP import S19XP
|
||||
from .S19a import S19a
|
||||
from .S19a_Pro import S19aPro
|
||||
from .S19j import S19j, S19jNoPIC
|
||||
from .S19j_Pro import S19jPro
|
||||
from .S19L import S19L
|
||||
from .T19 import T19
|
||||
from .S19 import (
|
||||
BMMinerS19,
|
||||
BMMinerS19a,
|
||||
BMMinerS19aPro,
|
||||
BMMinerS19i,
|
||||
BMMinerS19j,
|
||||
BMMinerS19jNoPIC,
|
||||
BMMinerS19jPro,
|
||||
BMMinerS19L,
|
||||
BMMinerS19Plus,
|
||||
BMMinerS19Pro,
|
||||
BMMinerS19ProPlus,
|
||||
BMMinerS19XP,
|
||||
)
|
||||
from .T19 import BMMinerT19
|
||||
@@ -15,10 +15,10 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.backends import AntminerModern
|
||||
from pyasic.miners.hns._types import HS3 # noqa - Ignore access to _module
|
||||
from pyasic.miners.types import HS3
|
||||
|
||||
|
||||
class CGMinerHS3(AntminerModern, HS3):
|
||||
class BMMinerHS3(AntminerModern, HS3):
|
||||
def __init__(self, ip: str, api_ver: str = "0.0.0"):
|
||||
super().__init__(ip, api_ver)
|
||||
self.supports_shutdown = False
|
||||
@@ -14,8 +14,9 @@
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.backends import CGMinerAvalon # noqa - Ignore access to _module
|
||||
from pyasic.miners.backends import AntminerOld
|
||||
from pyasic.miners.types import L3Plus
|
||||
|
||||
|
||||
class CGMinerA10X(CGMinerAvalon):
|
||||
class BMMinerL3Plus(AntminerOld, L3Plus):
|
||||
pass
|
||||
@@ -13,6 +13,5 @@
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
from .X9 import *
|
||||
from .X17 import *
|
||||
from .X19 import *
|
||||
from .HS3 import BMMinerHS3
|
||||
from .L3 import BMMinerL3Plus
|
||||
@@ -14,7 +14,7 @@
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
from pyasic.miners.backends import AntminerModern
|
||||
from pyasic.miners.ltc._types import L7 # noqa - Ignore access to _module
|
||||
from pyasic.miners.types import L7
|
||||
|
||||
|
||||
class BMMinerL7(AntminerModern, L7):
|
||||
@@ -15,10 +15,10 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.backends import AntminerModern
|
||||
from pyasic.miners.etc._types import E9Pro # noqa - Ignore access to _module
|
||||
from pyasic.miners.types import E9Pro
|
||||
|
||||
|
||||
class CGMinerE9Pro(AntminerModern, E9Pro):
|
||||
class BMMinerE9Pro(AntminerModern, E9Pro):
|
||||
def __init__(self, ip: str, api_ver: str = "0.0.0"):
|
||||
super().__init__(ip, api_ver)
|
||||
self.supports_shutdown = False
|
||||
@@ -15,8 +15,16 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.backends import BMMiner
|
||||
from pyasic.miners.btc._types import S9i # noqa - Ignore access to _module
|
||||
from pyasic.miners.types import S9, S9i, S9j
|
||||
|
||||
|
||||
class BMMinerS9(BMMiner, S9):
|
||||
pass
|
||||
|
||||
|
||||
class BMMinerS9i(BMMiner, S9i):
|
||||
pass
|
||||
|
||||
|
||||
class BMMinerS9j(BMMiner, S9j):
|
||||
pass
|
||||
@@ -15,7 +15,7 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.backends import BMMiner
|
||||
from pyasic.miners.btc._types import T9 # noqa - Ignore access to _module
|
||||
from pyasic.miners.types import T9
|
||||
|
||||
|
||||
class BMMinerT9(BMMiner, T9):
|
||||
@@ -14,7 +14,6 @@
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from .S9 import BMMinerS9
|
||||
from .S9i import BMMinerS9i
|
||||
from .S9j import BMMinerS9j
|
||||
from .E9 import BMMinerE9Pro
|
||||
from .S9 import BMMinerS9, BMMinerS9i, BMMinerS9j
|
||||
from .T9 import BMMinerT9
|
||||
@@ -13,6 +13,8 @@
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
from .X3 import *
|
||||
from .X7 import *
|
||||
from .X9 import *
|
||||
from .X17 import *
|
||||
from .X19 import *
|
||||
@@ -15,8 +15,20 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.backends import BOSMiner
|
||||
from pyasic.miners.btc._types import S17Plus # noqa - Ignore access to _module
|
||||
from pyasic.miners.types import S17, S17e, S17Plus, S17Pro
|
||||
|
||||
|
||||
class BOSMinerS17(BOSMiner, S17):
|
||||
pass
|
||||
|
||||
|
||||
class BOSMinerS17Plus(BOSMiner, S17Plus):
|
||||
pass
|
||||
|
||||
|
||||
class BOSMinerS17Pro(BOSMiner, S17Pro):
|
||||
pass
|
||||
|
||||
|
||||
class BOSMinerS17e(BOSMiner, S17e):
|
||||
pass
|
||||
@@ -15,8 +15,16 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.backends import BOSMiner
|
||||
from pyasic.miners.btc._types import T17Plus # noqa - Ignore access to _module
|
||||
from pyasic.miners.types import T17, T17e, T17Plus
|
||||
|
||||
|
||||
class BOSMinerT17(BOSMiner, T17):
|
||||
pass
|
||||
|
||||
|
||||
class BOSMinerT17Plus(BOSMiner, T17Plus):
|
||||
pass
|
||||
|
||||
|
||||
class BOSMinerT17e(BOSMiner, T17e):
|
||||
pass
|
||||
18
pyasic/miners/antminer/bosminer/X17/__init__.py
Normal file
18
pyasic/miners/antminer/bosminer/X17/__init__.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Copyright 2022 Upstream Data Inc -
|
||||
# -
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||
# you may not use this file except in compliance with the License. -
|
||||
# You may obtain a copy of the License at -
|
||||
# -
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||
# -
|
||||
# Unless required by applicable law or agreed to in writing, software -
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from .S17 import BOSMinerS17, BOSMinerS17e, BOSMinerS17Plus, BOSMinerS17Pro
|
||||
from .T17 import BOSMinerT17, BOSMinerT17e, BOSMinerT17Plus
|
||||
@@ -15,7 +15,15 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.backends import BOSMiner
|
||||
from pyasic.miners.btc._types import S19j, S19jNoPIC # noqa - Ignore access to _module
|
||||
from pyasic.miners.types import S19, S19j, S19jNoPIC, S19jPro, S19Pro
|
||||
|
||||
|
||||
class BOSMinerS19(BOSMiner, S19):
|
||||
pass
|
||||
|
||||
|
||||
class BOSMinerS19Pro(BOSMiner, S19Pro):
|
||||
pass
|
||||
|
||||
|
||||
class BOSMinerS19j(BOSMiner, S19j):
|
||||
@@ -24,3 +32,7 @@ class BOSMinerS19j(BOSMiner, S19j):
|
||||
|
||||
class BOSMinerS19jNoPIC(BOSMiner, S19jNoPIC):
|
||||
pass
|
||||
|
||||
|
||||
class BOSMinerS19jPro(BOSMiner, S19jPro):
|
||||
pass
|
||||
@@ -15,7 +15,7 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.backends import BOSMiner
|
||||
from pyasic.miners.btc._types import T19 # noqa - Ignore access to _module
|
||||
from pyasic.miners.types import T19
|
||||
|
||||
|
||||
class BOSMinerT19(BOSMiner, T19):
|
||||
24
pyasic/miners/antminer/bosminer/X19/__init__.py
Normal file
24
pyasic/miners/antminer/bosminer/X19/__init__.py
Normal file
@@ -0,0 +1,24 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Copyright 2022 Upstream Data Inc -
|
||||
# -
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||
# you may not use this file except in compliance with the License. -
|
||||
# You may obtain a copy of the License at -
|
||||
# -
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||
# -
|
||||
# Unless required by applicable law or agreed to in writing, software -
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from .S19 import (
|
||||
BOSMinerS19,
|
||||
BOSMinerS19j,
|
||||
BOSMinerS19jNoPIC,
|
||||
BOSMinerS19jPro,
|
||||
BOSMinerS19Pro,
|
||||
)
|
||||
from .T19 import BOSMinerT19
|
||||
@@ -15,7 +15,7 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.backends import BOSMiner
|
||||
from pyasic.miners.btc._types import S9 # noqa - Ignore access to _module
|
||||
from pyasic.miners.types import S9
|
||||
|
||||
|
||||
class BOSMinerS9(BOSMiner, S9):
|
||||
@@ -15,7 +15,7 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.backends import AntminerOld
|
||||
from pyasic.miners.zec._types import Z15 # noqa - Ignore access to _module
|
||||
from pyasic.miners.types import Z15
|
||||
|
||||
|
||||
class CGMinerZ15(AntminerOld, Z15):
|
||||
@@ -13,9 +13,8 @@
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.backends import AntminerOld
|
||||
from pyasic.miners.dsh._types import D3 # noqa - Ignore access to _module
|
||||
from pyasic.miners.types import D3
|
||||
|
||||
|
||||
class CGMinerD3(AntminerOld, D3):
|
||||
@@ -13,4 +13,5 @@
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from .D3 import CGMinerD3
|
||||
@@ -15,7 +15,7 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.backends import AntminerOld
|
||||
from pyasic.miners.dcr._types import DR5 # noqa - Ignore access to _module
|
||||
from pyasic.miners.types import DR5
|
||||
|
||||
|
||||
class CGMinerDR5(AntminerOld, DR5):
|
||||
@@ -13,4 +13,7 @@
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from .X3 import *
|
||||
from .X5 import *
|
||||
from .X15 import *
|
||||
40
pyasic/miners/antminer/epic/X19/S19.py
Normal file
40
pyasic/miners/antminer/epic/X19/S19.py
Normal file
@@ -0,0 +1,40 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Copyright 2022 Upstream Data Inc -
|
||||
# -
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||
# you may not use this file except in compliance with the License. -
|
||||
# You may obtain a copy of the License at -
|
||||
# -
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||
# -
|
||||
# Unless required by applicable law or agreed to in writing, software -
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.backends import ePIC
|
||||
from pyasic.miners.types import (
|
||||
S19,
|
||||
S19Pro,
|
||||
S19j,
|
||||
S19jPro,
|
||||
S19XP,
|
||||
)
|
||||
|
||||
|
||||
class ePICS19(ePIC, S19):
|
||||
pass
|
||||
|
||||
class ePICS19Pro(ePIC, S19Pro):
|
||||
pass
|
||||
|
||||
class ePICS19j(ePIC, S19j):
|
||||
pass
|
||||
|
||||
class ePICS19jPro(ePIC, S19jPro):
|
||||
pass
|
||||
|
||||
class ePICS19XP(ePIC, S19XP):
|
||||
pass
|
||||
23
pyasic/miners/antminer/epic/X19/__init__.py
Normal file
23
pyasic/miners/antminer/epic/X19/__init__.py
Normal file
@@ -0,0 +1,23 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Copyright 2022 Upstream Data Inc -
|
||||
# -
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||
# you may not use this file except in compliance with the License. -
|
||||
# You may obtain a copy of the License at -
|
||||
# -
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||
# -
|
||||
# Unless required by applicable law or agreed to in writing, software -
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from .S19 import (
|
||||
ePICS19,
|
||||
ePICS19Pro,
|
||||
ePICS19j,
|
||||
ePICS19jPro,
|
||||
ePICS19XP,
|
||||
)
|
||||
@@ -20,8 +20,8 @@ import asyncssh
|
||||
|
||||
from pyasic.data import HashBoard
|
||||
from pyasic.errors import APIError
|
||||
from pyasic.miners.backends import Hiveon # noqa - Ignore access to _module
|
||||
from pyasic.miners.btc._types import T9 # noqa - Ignore access to _module
|
||||
from pyasic.miners.backends import Hiveon
|
||||
from pyasic.miners.types import T9
|
||||
|
||||
|
||||
class HiveonT9(Hiveon, T9):
|
||||
@@ -58,7 +58,7 @@ class HiveonT9(Hiveon, T9):
|
||||
hashrate = 0
|
||||
chips = 0
|
||||
for chipset in board_map[board]:
|
||||
if hashboard.chip_temp == -1:
|
||||
if hashboard.chip_temp == None:
|
||||
try:
|
||||
hashboard.board_temp = api_stats["STATS"][1][f"temp{chipset}"]
|
||||
hashboard.chip_temp = api_stats["STATS"][1][f"temp2_{chipset}"]
|
||||
@@ -14,8 +14,9 @@
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.backends import CGMinerAvalon # noqa - Ignore access to _module
|
||||
from pyasic.miners.backends import LUXMiner
|
||||
from pyasic.miners.types import S9
|
||||
|
||||
|
||||
class CGMinerA7X(CGMinerAvalon):
|
||||
class LUXMinerS9(LUXMiner, S9):
|
||||
pass
|
||||
@@ -14,4 +14,4 @@
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from .T3X import *
|
||||
from .S9 import LUXMinerS9
|
||||
@@ -13,4 +13,5 @@
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from .X9 import *
|
||||
@@ -13,11 +13,13 @@
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.btc._types import S17Pro # noqa - Ignore access to _module
|
||||
|
||||
from .X17 import BMMinerX17
|
||||
from pyasic.miners.backends import VNish
|
||||
from pyasic.miners.types import S17Plus, S17Pro
|
||||
|
||||
|
||||
class BMMinerS17Pro(BMMinerX17, S17Pro):
|
||||
class VNishS17Plus(VNish, S17Plus):
|
||||
pass
|
||||
|
||||
|
||||
class VNishS17Pro(VNish, S17Pro):
|
||||
pass
|
||||
@@ -13,5 +13,4 @@
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from .T3H_Plus import InnosiliconT3HPlus
|
||||
from .S17 import VNishS17Plus, VNishS17Pro
|
||||
@@ -14,8 +14,45 @@
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.backends import VNish # noqa - Ignore access to _module
|
||||
from pyasic.miners.btc._types import S19jPro # noqa - Ignore access to _module
|
||||
from pyasic.miners.backends import VNish
|
||||
from pyasic.miners.types import (
|
||||
S19,
|
||||
S19XP,
|
||||
S19a,
|
||||
S19aPro,
|
||||
S19j,
|
||||
S19jPro,
|
||||
S19NoPIC,
|
||||
S19Pro,
|
||||
)
|
||||
|
||||
|
||||
class VNishS19(VNish, S19):
|
||||
pass
|
||||
|
||||
|
||||
class VNishS19NoPIC(VNish, S19NoPIC):
|
||||
pass
|
||||
|
||||
|
||||
class VNishS19Pro(VNish, S19Pro):
|
||||
pass
|
||||
|
||||
|
||||
class VNishS19XP(VNish, S19XP):
|
||||
pass
|
||||
|
||||
|
||||
class VNishS19a(VNish, S19a):
|
||||
pass
|
||||
|
||||
|
||||
class VNishS19aPro(VNish, S19aPro):
|
||||
pass
|
||||
|
||||
|
||||
class VNishS19j(VNish, S19j):
|
||||
pass
|
||||
|
||||
|
||||
class VNishS19jPro(VNish, S19jPro):
|
||||
@@ -14,8 +14,9 @@
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.backends import CGMinerAvalon # noqa - Ignore access to _module
|
||||
from pyasic.miners.backends import VNish
|
||||
from pyasic.miners.types import T19
|
||||
|
||||
|
||||
class CGMinerA8X(CGMinerAvalon):
|
||||
class VNishT19(VNish, T19):
|
||||
pass
|
||||
@@ -14,10 +14,14 @@
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
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
|
||||
from .S19 import (
|
||||
VNishS19,
|
||||
VNishS19a,
|
||||
VNishS19aPro,
|
||||
VNishS19j,
|
||||
VNishS19jPro,
|
||||
VNishS19NoPIC,
|
||||
VNishS19Pro,
|
||||
VNishS19XP,
|
||||
)
|
||||
from .T19 import VNishT19
|
||||
@@ -15,7 +15,7 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.backends import VNish
|
||||
from pyasic.miners.ltc._types import L3Plus # noqa - Ignore access to _module
|
||||
from pyasic.miners.types import L3Plus
|
||||
|
||||
|
||||
class VnishL3Plus(VNish, L3Plus):
|
||||
17
pyasic/miners/antminer/vnish/X3/__init__.py
Normal file
17
pyasic/miners/antminer/vnish/X3/__init__.py
Normal file
@@ -0,0 +1,17 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Copyright 2022 Upstream Data Inc -
|
||||
# -
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||
# you may not use this file except in compliance with the License. -
|
||||
# You may obtain a copy of the License at -
|
||||
# -
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||
# -
|
||||
# Unless required by applicable law or agreed to in writing, software -
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from .L3 import VnishL3Plus
|
||||
@@ -14,6 +14,6 @@
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from .X9 import *
|
||||
from .X3 import *
|
||||
from .X17 import *
|
||||
from .X19 import *
|
||||
@@ -14,10 +14,9 @@
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.btc._types import Avalon1026 # noqa - Ignore access to _module
|
||||
|
||||
from .A10X import CGMinerA10X
|
||||
from pyasic.miners.backends import CGMinerAvalon
|
||||
from pyasic.miners.types import Avalon1026
|
||||
|
||||
|
||||
class CGMinerAvalon1026(CGMinerA10X, Avalon1026):
|
||||
class CGMinerAvalon1026(CGMinerAvalon, Avalon1026):
|
||||
pass
|
||||
@@ -14,10 +14,9 @@
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.btc._types import Avalon1047 # noqa - Ignore access to _module
|
||||
|
||||
from .A10X import CGMinerA10X
|
||||
from pyasic.miners.backends import CGMinerAvalon
|
||||
from pyasic.miners.types import Avalon1047
|
||||
|
||||
|
||||
class CGMinerAvalon1047(CGMinerA10X, Avalon1047):
|
||||
class CGMinerAvalon1047(CGMinerAvalon, Avalon1047):
|
||||
pass
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user