Compare commits
144 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2d029b65e6 | ||
|
|
993b7efeef | ||
|
|
b7a81097a4 | ||
|
|
651bef8203 | ||
|
|
a9e5c99ab2 | ||
|
|
30216fdd5b | ||
|
|
341cc13d83 | ||
|
|
05a4ae6f04 | ||
|
|
5971d9fd83 | ||
|
|
3968f2275c | ||
|
|
84344ca883 | ||
|
|
59b80254eb | ||
|
|
06fdb19e0b | ||
|
|
75222e8cd2 | ||
|
|
5a067d60e7 | ||
|
|
2fbc4fcb4a | ||
|
|
13fe60504a | ||
|
|
cdc52c3605 | ||
|
|
a9db097355 | ||
|
|
ec5557cf88 | ||
|
|
a8ea84d2f3 | ||
|
|
58d369eedf | ||
|
|
f8f9dd7070 | ||
|
|
01b72e1ee6 | ||
|
|
e367e630b8 | ||
|
|
385cca6fc0 | ||
|
|
75a3a466a3 | ||
|
|
4bf08dbfe6 | ||
|
|
833d061315 | ||
|
|
a85558278d | ||
|
|
bf5087b06d | ||
|
|
ec58d13bae | ||
|
|
75993564ab | ||
|
|
f3ea169dec | ||
|
|
39b3fe5c25 | ||
|
|
5c79c6cb0c | ||
|
|
bab4261bed | ||
|
|
e1d5c89388 | ||
|
|
5f6c8cca18 | ||
|
|
39db14b002 | ||
|
|
3be04c678b | ||
|
|
099ec35a8f | ||
|
|
113dfb9170 | ||
|
|
8d19e0ebbb | ||
|
|
ec064eba65 | ||
|
|
3451127761 | ||
|
|
b3be52ca77 | ||
|
|
b6ec6caa72 | ||
|
|
8e81e18622 | ||
|
|
6ea26e0e19 | ||
|
|
be446f94c1 | ||
|
|
3d94e30f22 | ||
|
|
d5a7ff3a46 | ||
|
|
bbfa97632d | ||
|
|
ecf0ce22d6 | ||
|
|
d56da007a5 | ||
|
|
2c86b2da7e | ||
|
|
c73b1ceb07 | ||
|
|
a320c8967d | ||
|
|
e21e340f60 | ||
|
|
f63d8f4b91 | ||
|
|
ba6a1606b6 | ||
|
|
51b0c0456f | ||
|
|
04bd03b496 | ||
|
|
bc5764c8ff | ||
|
|
1f2e066f4c | ||
|
|
74c457a694 | ||
|
|
4a1c53dfd7 | ||
|
|
81b77f8768 | ||
|
|
3b127b6862 | ||
|
|
2815d2ba11 | ||
|
|
1ff20fc6f0 | ||
|
|
797c847055 | ||
|
|
65c7f2f66f | ||
|
|
445d621590 | ||
|
|
d39ecfd6b4 | ||
|
|
36663471fb | ||
|
|
80293ac52f | ||
|
|
70b45f40f5 | ||
|
|
a511fabd9c | ||
|
|
8bc8f6f178 | ||
|
|
b790ad58a7 | ||
|
|
354ab793a2 | ||
|
|
59346d641f | ||
|
|
11d770771b | ||
|
|
1b6db7ed45 | ||
|
|
55c4e10fae | ||
|
|
77c06dad61 | ||
|
|
68d250d2f2 | ||
|
|
094a17ac68 | ||
|
|
dbcdeaa3de | ||
|
|
872cac811a | ||
|
|
d324c2fee9 | ||
|
|
577e8df612 | ||
|
|
4b54cf67ba | ||
|
|
0e00fe3114 | ||
|
|
15d1dc5bb6 | ||
|
|
2af0003843 | ||
|
|
3c227be170 | ||
|
|
e889780bad | ||
|
|
cc3d4fa805 | ||
|
|
743823f66e | ||
|
|
227e1e2d2d | ||
|
|
d6c8ff0910 | ||
|
|
bd20e051b0 | ||
|
|
2eb6697e9a | ||
|
|
c5817fcc36 | ||
|
|
f2391bcb2d | ||
|
|
bc3bd9e5da | ||
|
|
3f0959d75e | ||
|
|
31f7b56724 | ||
|
|
072954d755 | ||
|
|
d271e0f9c8 | ||
|
|
8f1408ce17 | ||
|
|
825d1f4cfb | ||
|
|
c6bcd7e05a | ||
|
|
5d80051f3b | ||
|
|
b71c448199 | ||
|
|
c82148412c | ||
|
|
a582ee63a0 | ||
|
|
db7c19c486 | ||
|
|
599f71da19 | ||
|
|
0995744d90 | ||
|
|
4073a27aba | ||
|
|
bec9c31c97 | ||
|
|
acdd615c53 | ||
|
|
8091617ee2 | ||
|
|
c25ff6fcef | ||
|
|
ab0dcd607b | ||
|
|
ce288e472f | ||
|
|
02d8f25daf | ||
|
|
a76d1c6149 | ||
|
|
17f5eade19 | ||
|
|
b6a2a5054b | ||
|
|
5984338c64 | ||
|
|
07d1c48e33 | ||
|
|
d2abae947c | ||
|
|
e4a0f2451a | ||
|
|
880c598b1a | ||
|
|
3632c2c4d8 | ||
|
|
09bc9686ae | ||
|
|
34584ab098 | ||
|
|
554d99ca08 | ||
|
|
5c5d688ffa |
@@ -1,16 +1,16 @@
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.3.0
|
||||
rev: v4.5.0
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
- id: check-yaml
|
||||
- id: check-added-large-files
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 22.6.0
|
||||
rev: 24.3.0
|
||||
hooks:
|
||||
- id: black
|
||||
- repo: https://github.com/pycqa/isort
|
||||
rev: 5.10.1
|
||||
rev: 5.13.2
|
||||
hooks:
|
||||
- id: isort
|
||||
name: isort (python)
|
||||
|
||||
35
README.md
35
README.md
@@ -9,7 +9,7 @@
|
||||
[](https://github.com/UpstreamData/pyasic/commits/master/)
|
||||
|
||||
[](https://github.com/psf/black)
|
||||
[](https://pyasic.readthedocs.io/en/latest/)
|
||||
[](https://docs.pyasic.org)
|
||||
[](https://github.com/UpstreamData/pyasic/blob/master/LICENSE.txt)
|
||||
|
||||
---
|
||||
@@ -17,7 +17,38 @@
|
||||
|
||||
Welcome to `pyasic`! `pyasic` uses an asynchronous method of communicating with ASIC miners on your network, which makes it super fast.
|
||||
|
||||
[Click here to view supported miner types](miners/supported_types.md)
|
||||
[Click here to view supported miner types](https://docs.pyasic.org/en/latest/miners/supported_types/)
|
||||
|
||||
---
|
||||
## Installation
|
||||
|
||||
It is recommended to install `pyasic` in a [virtual environment](https://realpython.com/python-virtual-environments-a-primer/#what-other-popular-options-exist-aside-from-venv) to isolate it from the rest of your system. Options include:
|
||||
- [pypoetry](https://python-poetry.org/): the reccommended way, since pyasic already uses it by default
|
||||
|
||||
```
|
||||
poetry install
|
||||
```
|
||||
|
||||
- [venv](https://docs.python.org/3/library/venv.html): included in Python standard library but has fewer features than other options
|
||||
- [pyenv-virtualenv](https://github.com/pyenv/pyenv-virtualenv): [pyenv](https://github.com/pyenv/pyenv) plugin for managing virtualenvs
|
||||
|
||||
```
|
||||
pyenv install <python version number>
|
||||
pyenv virtualenv <python version number> <env name>
|
||||
pyenv activate <env name>
|
||||
```
|
||||
|
||||
- [conda](https://docs.conda.io/en/latest/)
|
||||
|
||||
##### Installing `pyasic`
|
||||
|
||||
`python -m pip install .` or `poetry install`
|
||||
|
||||
##### Additional Developer Setup
|
||||
```
|
||||
poetry install --with dev
|
||||
pre-commit install
|
||||
```
|
||||
|
||||
---
|
||||
## Getting started
|
||||
|
||||
@@ -27,6 +27,8 @@ def backend_str(backend: MinerTypes) -> str:
|
||||
match backend:
|
||||
case MinerTypes.ANTMINER:
|
||||
return "Stock Firmware Antminers"
|
||||
case MinerTypes.AURADINE:
|
||||
return "Stock Firmware Auradine Miners"
|
||||
case MinerTypes.AVALONMINER:
|
||||
return "Stock Firmware Avalonminers"
|
||||
case MinerTypes.VNISH:
|
||||
@@ -45,6 +47,8 @@ def backend_str(backend: MinerTypes) -> str:
|
||||
return "Stock Firmware Goldshells"
|
||||
case MinerTypes.LUX_OS:
|
||||
return "LuxOS Firmware Miners"
|
||||
case MinerTypes.MARATHON:
|
||||
return "Mara Firmware Miners"
|
||||
|
||||
|
||||
def create_url_str(mtype: str):
|
||||
|
||||
@@ -18,6 +18,31 @@ Welcome to `pyasic`! `pyasic` uses an asynchronous method of communicating with
|
||||
|
||||
[Click here to view supported miner types](miners/supported_types.md)
|
||||
|
||||
---
|
||||
## Installation
|
||||
|
||||
It is recommended to install `pyasic` in a [virtual environment](https://realpython.com/python-virtual-environments-a-primer/#what-other-popular-options-exist-aside-from-venv) to isolate it from the rest of your system. Options include:
|
||||
- [pypoetry](https://python-poetry.org/): the reccommended way, since pyasic already uses it by default
|
||||
|
||||
```
|
||||
poetry install
|
||||
```
|
||||
|
||||
- [venv](https://docs.python.org/3/library/venv.html): included in Python standard library but has fewer features than other options
|
||||
- [pyenv-virtualenv](https://github.com/pyenv/pyenv-virtualenv): [pyenv](https://github.com/pyenv/pyenv) plugin for managing virtualenvs
|
||||
|
||||
```
|
||||
pyenv install <python version number>
|
||||
pyenv virtualenv <python version number> <env name>
|
||||
pyenv activate <env name>
|
||||
```
|
||||
|
||||
- [conda](https://docs.conda.io/en/latest/)
|
||||
|
||||
##### Installing `pyasic`
|
||||
|
||||
`python -m pip install .` or `poetry install`
|
||||
|
||||
---
|
||||
## Getting started
|
||||
---
|
||||
@@ -236,6 +261,7 @@ settings.update("default_antminer_password", "my_pwd")
|
||||
"factory_get_timeout": 3,
|
||||
"get_data_retries": 1,
|
||||
"api_function_timeout": 5,
|
||||
"antminer_mining_mode_as_str": False,
|
||||
"default_whatsminer_password": "admin",
|
||||
"default_innosilicon_password": "admin",
|
||||
"default_antminer_password": "root",
|
||||
|
||||
@@ -50,49 +50,49 @@
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S17 (BOS)
|
||||
## S17 (BOS+)
|
||||
::: pyasic.miners.antminer.bosminer.X17.S17.BOSMinerS17
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S17+ (BOS)
|
||||
## S17+ (BOS+)
|
||||
::: pyasic.miners.antminer.bosminer.X17.S17.BOSMinerS17Plus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S17 Pro (BOS)
|
||||
## S17 Pro (BOS+)
|
||||
::: pyasic.miners.antminer.bosminer.X17.S17.BOSMinerS17Pro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S17e (BOS)
|
||||
## S17e (BOS+)
|
||||
::: pyasic.miners.antminer.bosminer.X17.S17.BOSMinerS17e
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## T17 (BOS)
|
||||
## T17 (BOS+)
|
||||
::: pyasic.miners.antminer.bosminer.X17.T17.BOSMinerT17
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## T17+ (BOS)
|
||||
## T17+ (BOS+)
|
||||
::: pyasic.miners.antminer.bosminer.X17.T17.BOSMinerT17Plus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## T17e (BOS)
|
||||
## T17e (BOS+)
|
||||
::: pyasic.miners.antminer.bosminer.X17.T17.BOSMinerT17e
|
||||
handler: python
|
||||
options:
|
||||
|
||||
@@ -85,6 +85,34 @@
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19 Hydro
|
||||
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19Hydro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19 Pro Hydro
|
||||
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19ProHydro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19 Pro+ Hydro
|
||||
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19ProPlusHydro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19K Pro
|
||||
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19KPro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## T19
|
||||
::: pyasic.miners.antminer.bmminer.X19.T19.BMMinerT19
|
||||
handler: python
|
||||
@@ -92,49 +120,105 @@
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19 (BOS)
|
||||
## S19
|
||||
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19 Pro (BOS)
|
||||
## S19+
|
||||
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19Plus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19 Pro
|
||||
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19Pro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19j (BOS)
|
||||
## S19a
|
||||
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19a
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19a Pro
|
||||
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19aPro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19j
|
||||
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19j
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19j No PIC (BOS)
|
||||
## S19j No PIC
|
||||
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19jNoPIC
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19j Pro (BOS)
|
||||
## S19j Pro
|
||||
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19jPro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19j Pro (BOS)
|
||||
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19jPro
|
||||
## S19j Pro No PIC
|
||||
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19jProNoPIC
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## T19 (BOS)
|
||||
## S19j Pro+
|
||||
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19jProPlus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19j Pro+
|
||||
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19jProPlus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19j Pro+ No PIC
|
||||
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19jProPlusNoPIC
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19k Pro No PIC
|
||||
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19kProNoPIC
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19 XP
|
||||
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19XP
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## T19
|
||||
::: pyasic.miners.antminer.bosminer.X19.T19.BOSMinerT19
|
||||
handler: python
|
||||
options:
|
||||
@@ -225,6 +309,20 @@
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19j Pro+ (ePIC)
|
||||
::: pyasic.miners.antminer.epic.X19.S19.ePICS19jProPlus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19k Pro (ePIC)
|
||||
::: pyasic.miners.antminer.epic.X19.S19.ePICS19kPro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19 XP (ePIC)
|
||||
::: pyasic.miners.antminer.epic.X19.S19.ePICS19XP
|
||||
handler: python
|
||||
@@ -232,3 +330,101 @@
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19 (LuxOS)
|
||||
::: pyasic.miners.antminer.luxos.X19.S19.LUXMinerS19
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19 Pro (LuxOS)
|
||||
::: pyasic.miners.antminer.luxos.X19.S19.LUXMinerS19Pro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19j Pro (LuxOS)
|
||||
::: pyasic.miners.antminer.luxos.X19.S19.LUXMinerS19jPro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19j Pro+ (LuxOS)
|
||||
::: pyasic.miners.antminer.luxos.X19.S19.LUXMinerS19jProPlus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19k Pro (LuxOS)
|
||||
::: pyasic.miners.antminer.luxos.X19.S19.LUXMinerS19kPro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19 XP (LuxOS)
|
||||
::: pyasic.miners.antminer.luxos.X19.S19.LUXMinerS19XP
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## T19 (LuxOS)
|
||||
::: pyasic.miners.antminer.luxos.X19.T19.LUXMinerT19
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19 (MaraFW)
|
||||
::: pyasic.miners.antminer.marathon.X19.S19.MaraS19
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19 Pro (MaraFW)
|
||||
::: pyasic.miners.antminer.marathon.X19.S19.MaraS19Pro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19j (MaraFW)
|
||||
::: pyasic.miners.antminer.marathon.X19.S19.MaraS19j
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19j No PIC (MaraFW)
|
||||
::: pyasic.miners.antminer.marathon.X19.S19.MaraS19jNoPIC
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19j Pro (MaraFW)
|
||||
::: pyasic.miners.antminer.marathon.X19.S19.MaraS19jPro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19 XP (MaraFW)
|
||||
::: pyasic.miners.antminer.marathon.X19.S19.MaraS19XP
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S19K Pro (MaraFW)
|
||||
::: pyasic.miners.antminer.marathon.X19.S19.MaraS19KPro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
|
||||
59
docs/miners/antminer/X21.md
Normal file
59
docs/miners/antminer/X21.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# pyasic
|
||||
## X21 Models
|
||||
|
||||
## S21
|
||||
::: pyasic.miners.antminer.bmminer.X21.S21.BMMinerS21
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## T21
|
||||
::: pyasic.miners.antminer.bmminer.X21.T21.BMMinerT21
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S21
|
||||
::: pyasic.miners.antminer.bosminer.X21.S21.BOSMinerS21
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S21 (ePIC)
|
||||
::: pyasic.miners.antminer.epic.X21.S21.ePICS21
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## T21 (ePIC)
|
||||
::: pyasic.miners.antminer.epic.X21.T21.ePICT21
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S21 (LuxOS)
|
||||
::: pyasic.miners.antminer.luxos.X21.S21.LUXMinerS21
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S21 (MaraFW)
|
||||
::: pyasic.miners.antminer.marathon.X21.S21.MaraS21
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## T21 (MaraFW)
|
||||
::: pyasic.miners.antminer.marathon.X21.T21.MaraT21
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
@@ -29,3 +29,10 @@
|
||||
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
|
||||
|
||||
|
||||
@@ -8,3 +8,10 @@
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## L7 (VNish)
|
||||
::: pyasic.miners.antminer.vnish.X7.L7.VnishL7
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
|
||||
@@ -36,14 +36,14 @@
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S9 (BOS)
|
||||
## S9 (BOS+)
|
||||
::: pyasic.miners.antminer.bosminer.X9.S9.BOSMinerS9
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## T9 (Hiveon)
|
||||
## T9 (Hive)
|
||||
::: pyasic.miners.antminer.hiveon.X9.T9.HiveonT9
|
||||
handler: python
|
||||
options:
|
||||
|
||||
24
docs/miners/auradine/AD.md
Normal file
24
docs/miners/auradine/AD.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# pyasic
|
||||
## AD Models
|
||||
|
||||
## AT1500
|
||||
::: pyasic.miners.auradine.flux.AD.AT1.AuradineFluxAT1500
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## AT2860
|
||||
::: pyasic.miners.auradine.flux.AD.AT2.AuradineFluxAT2860
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## AT2880
|
||||
::: pyasic.miners.auradine.flux.AD.AT2.AuradineFluxAT2880
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
17
docs/miners/auradine/AI.md
Normal file
17
docs/miners/auradine/AI.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# pyasic
|
||||
## AI Models
|
||||
|
||||
## AI2500
|
||||
::: pyasic.miners.auradine.flux.AI.AI2.AuradineFluxAI2500
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## AI3680
|
||||
::: pyasic.miners.auradine.flux.AI.AI3.AuradineFluxAI3680
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
17
docs/miners/auradine/AT.md
Normal file
17
docs/miners/auradine/AT.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# pyasic
|
||||
## AT Models
|
||||
|
||||
## AD2500
|
||||
::: pyasic.miners.auradine.flux.AT.AD2.AuradineFluxAD2500
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## AD3500
|
||||
::: pyasic.miners.auradine.flux.AT.AD3.AuradineFluxAD3500
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
@@ -21,3 +21,4 @@
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
|
||||
17
docs/miners/goldshell/XBox.md
Normal file
17
docs/miners/goldshell/XBox.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# pyasic
|
||||
## XBox Models
|
||||
|
||||
## KD Box II
|
||||
::: pyasic.miners.goldshell.bfgminer.XBox.KDBox.GoldshellKDBoxII
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## KD Box Pro
|
||||
::: pyasic.miners.goldshell.bfgminer.XBox.KDBox.GoldshellKDBoxPro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
## XMax Models
|
||||
|
||||
## KD Max
|
||||
::: pyasic.miners.goldshell.bfgminer.XMax.KDMax.KDMax
|
||||
::: pyasic.miners.goldshell.bfgminer.XMax.KDMax.GoldshellKDMax
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
|
||||
@@ -7,3 +7,4 @@
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
|
||||
@@ -7,3 +7,4 @@
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
# pyasic
|
||||
## Miner Factory
|
||||
|
||||
[`MinerFactory`][pyasic.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.
|
||||
[`MinerFactory`][pyasic.miners.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()`.
|
||||
[`MinerFactory`][pyasic.miners.factory.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()`.
|
||||
|
||||
@@ -32,5 +32,5 @@ Finally, there is functionality to get multiple miners without using `asyncio.ga
|
||||
heading_level: 4
|
||||
|
||||
[`AnyMiner`][pyasic.miners.base.AnyMiner] is a placeholder type variable used for typing returns of functions.
|
||||
A function returning [`AnyMiner`][pyasic.miners.base.AnyMiner] will always return a subclass of [`BaseMiner`][pyasic.miners.BaseMiner],
|
||||
A function returning [`AnyMiner`][pyasic.miners.base.AnyMiner] will always return a subclass of [`BaseMiner`][pyasic.miners.base.BaseMiner],
|
||||
and is used to specify a function returning some arbitrary type of miner class instance.
|
||||
|
||||
@@ -78,9 +78,20 @@ details {
|
||||
<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#s19-hydro">S19 Hydro</a></li>
|
||||
<li><a href="../antminer/X19#s19-pro-hydro">S19 Pro Hydro</a></li>
|
||||
<li><a href="../antminer/X19#s19-pro_1-hydro">S19 Pro+ Hydro</a></li>
|
||||
<li><a href="../antminer/X19#s19k-pro">S19K Pro</a></li>
|
||||
<li><a href="../antminer/X19#t19">T19</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>X21 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X21#s21">S21</a></li>
|
||||
<li><a href="../antminer/X21#t21">T21</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
@@ -286,13 +297,39 @@ details {
|
||||
<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-vj40">M53S VJ40</a></li>
|
||||
<li><a href="../whatsminer/M5X#m53s_1-vj30">M53S+ VJ30</a></li>
|
||||
<li><a href="../whatsminer/M5X#m53s_1_1-vk10">M53S++ VK10</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>
|
||||
<details>
|
||||
<summary>M6X Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../whatsminer/M6X#m60-vk10">M60 VK10</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60-vk20">M60 VK20</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60-vk30">M60 VK30</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60-vk40">M60 VK40</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60s-vk10">M60S VK10</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60s-vk20">M60S VK20</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60s-vk30">M60S VK30</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60s-vk40">M60S VK40</a></li>
|
||||
<li><a href="../whatsminer/M6X#m63-vk10">M63 VK10</a></li>
|
||||
<li><a href="../whatsminer/M6X#m63-vk20">M63 VK20</a></li>
|
||||
<li><a href="../whatsminer/M6X#m63-vk30">M63 VK30</a></li>
|
||||
<li><a href="../whatsminer/M6X#m63s-vk10">M63S VK10</a></li>
|
||||
<li><a href="../whatsminer/M6X#m63s-vk20">M63S VK20</a></li>
|
||||
<li><a href="../whatsminer/M6X#m63s-vk30">M63S VK30</a></li>
|
||||
<li><a href="../whatsminer/M6X#m66-vk20">M66 VK20</a></li>
|
||||
<li><a href="../whatsminer/M6X#m66-vk30">M66 VK30</a></li>
|
||||
<li><a href="../whatsminer/M6X#m66s-vk20">M66S VK20</a></li>
|
||||
<li><a href="../whatsminer/M6X#m66s-vk30">M66S VK30</a></li>
|
||||
<li><a href="../whatsminer/M6X#m66s-vk40">M66S VK40</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
@@ -376,6 +413,13 @@ details {
|
||||
<li><a href="../goldshell/XMax#kd-max">KD Max</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>XBox Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../goldshell/XBox#kd-box-ii">KD Box II</a></li>
|
||||
<li><a href="../goldshell/XBox#kd-box-pro">KD Box Pro</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
@@ -384,31 +428,45 @@ details {
|
||||
<details>
|
||||
<summary>X9 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X9#s9-bos">S9 (BOS)</a></li>
|
||||
<li><a href="../antminer/X9#s9-bos_1">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>
|
||||
<li><a href="../antminer/X17#s17-bos_1">S17 (BOS+)</a></li>
|
||||
<li><a href="../antminer/X17#s17_1-bos_1">S17+ (BOS+)</a></li>
|
||||
<li><a href="../antminer/X17#s17-pro-bos_1">S17 Pro (BOS+)</a></li>
|
||||
<li><a href="../antminer/X17#s17e-bos_1">S17e (BOS+)</a></li>
|
||||
<li><a href="../antminer/X17#t17-bos_1">T17 (BOS+)</a></li>
|
||||
<li><a href="../antminer/X17#t17_1-bos_1">T17+ (BOS+)</a></li>
|
||||
<li><a href="../antminer/X17#t17e-bos_1">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>
|
||||
<li><a href="../antminer/X19#s19">S19</a></li>
|
||||
<li><a href="../antminer/X19#s19_1">S19+</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#s19a-pro">S19a Pro</a></li>
|
||||
<li><a href="../antminer/X19#s19j">S19j</a></li>
|
||||
<li><a href="../antminer/X19#s19j-no-pic">S19j No PIC</a></li>
|
||||
<li><a href="../antminer/X19#s19j-pro">S19j Pro</a></li>
|
||||
<li><a href="../antminer/X19#s19j-pro-no-pic">S19j Pro No PIC</a></li>
|
||||
<li><a href="../antminer/X19#s19j-pro_1">S19j Pro+</a></li>
|
||||
<li><a href="../antminer/X19#s19j-pro_1">S19j Pro+</a></li>
|
||||
<li><a href="../antminer/X19#s19j-pro_1-no-pic">S19j Pro+ No PIC</a></li>
|
||||
<li><a href="../antminer/X19#s19k-pro-no-pic">S19k Pro No PIC</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>X21 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X21#s21">S21</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
@@ -420,6 +478,13 @@ details {
|
||||
<summary>X3 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X3#l3_1-vnish">L3+ (VNish)</a></li>
|
||||
<li><a href="../antminer/X3#l3_1-vnish">L3+ (VNish)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>X7 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X7#l7-vnish">L7 (VNish)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
@@ -454,9 +519,25 @@ details {
|
||||
<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#s19j-pro_1-epic">S19j Pro+ (ePIC)</a></li>
|
||||
<li><a href="../antminer/X19#s19k-pro-epic">S19k Pro (ePIC)</a></li>
|
||||
<li><a href="../antminer/X19#s19-xp-epic">S19 XP (ePIC)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>X21 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X21#s21-epic">S21 (ePIC)</a></li>
|
||||
<li><a href="../antminer/X21#t21-epic">T21 (ePIC)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>blockminer Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../blockminer/blockminer#blockminer-520i-epic">BlockMiner 520i (ePIC)</a></li>
|
||||
<li><a href="../blockminer/blockminer#blockminer-720i-epic">BlockMiner 720i (ePIC)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
@@ -465,7 +546,7 @@ details {
|
||||
<details>
|
||||
<summary>X9 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X9#t9-hiveon">T9 (Hiveon)</a></li>
|
||||
<li><a href="../antminer/X9#t9-hive">T9 (Hive)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
@@ -479,5 +560,74 @@ details {
|
||||
<li><a href="../antminer/X9#s9-luxos">S9 (LuxOS)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>X19 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X19#s19-luxos">S19 (LuxOS)</a></li>
|
||||
<li><a href="../antminer/X19#s19-pro-luxos">S19 Pro (LuxOS)</a></li>
|
||||
<li><a href="../antminer/X19#s19j-pro-luxos">S19j Pro (LuxOS)</a></li>
|
||||
<li><a href="../antminer/X19#s19j-pro_1-luxos">S19j Pro+ (LuxOS)</a></li>
|
||||
<li><a href="../antminer/X19#s19k-pro-luxos">S19k Pro (LuxOS)</a></li>
|
||||
<li><a href="../antminer/X19#s19-xp-luxos">S19 XP (LuxOS)</a></li>
|
||||
<li><a href="../antminer/X19#t19-luxos">T19 (LuxOS)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>X21 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X21#s21-luxos">S21 (LuxOS)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>Stock Firmware Auradine Miners:</summary>
|
||||
<ul>
|
||||
<details>
|
||||
<summary>AD Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../auradine/AD#at1500">AT1500</a></li>
|
||||
<li><a href="../auradine/AD#at2860">AT2860</a></li>
|
||||
<li><a href="../auradine/AD#at2880">AT2880</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>AI Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../auradine/AI#ai2500">AI2500</a></li>
|
||||
<li><a href="../auradine/AI#ai3680">AI3680</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>AT Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../auradine/AT#ad2500">AD2500</a></li>
|
||||
<li><a href="../auradine/AT#ad3500">AD3500</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>Mara Firmware Miners:</summary>
|
||||
<ul>
|
||||
<details>
|
||||
<summary>X19 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X19#s19-marafw">S19 (MaraFW)</a></li>
|
||||
<li><a href="../antminer/X19#s19-pro-marafw">S19 Pro (MaraFW)</a></li>
|
||||
<li><a href="../antminer/X19#s19j-marafw">S19j (MaraFW)</a></li>
|
||||
<li><a href="../antminer/X19#s19j-no-pic-marafw">S19j No PIC (MaraFW)</a></li>
|
||||
<li><a href="../antminer/X19#s19j-pro-marafw">S19j Pro (MaraFW)</a></li>
|
||||
<li><a href="../antminer/X19#s19-xp-marafw">S19 XP (MaraFW)</a></li>
|
||||
<li><a href="../antminer/X19#s19k-pro-marafw">S19K Pro (MaraFW)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>X21 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X21#s21-marafw">S21 (MaraFW)</a></li>
|
||||
<li><a href="../antminer/X21#t21-marafw">T21 (MaraFW)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
</details>
|
||||
@@ -211,6 +211,13 @@
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M53S VJ40
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M53S.BTMinerM53SVJ40
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M53S+ VJ30
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M53S_Plus.BTMinerM53SPlusVJ30
|
||||
handler: python
|
||||
@@ -218,6 +225,13 @@
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M53S++ VK10
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M53S_Plus_Plus.BTMinerM53SPlusPlusVK10
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M56 VH30
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M56.BTMinerM56VH30
|
||||
handler: python
|
||||
|
||||
136
docs/miners/whatsminer/M6X.md
Normal file
136
docs/miners/whatsminer/M6X.md
Normal file
@@ -0,0 +1,136 @@
|
||||
# pyasic
|
||||
## M6X Models
|
||||
|
||||
## M60 VK10
|
||||
::: pyasic.miners.whatsminer.btminer.M6X.M60.BTMinerM60VK10
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M60 VK20
|
||||
::: pyasic.miners.whatsminer.btminer.M6X.M60.BTMinerM60VK20
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M60 VK30
|
||||
::: pyasic.miners.whatsminer.btminer.M6X.M60.BTMinerM60VK30
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M60 VK40
|
||||
::: pyasic.miners.whatsminer.btminer.M6X.M60.BTMinerM60VK40
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M60S VK10
|
||||
::: pyasic.miners.whatsminer.btminer.M6X.M60S.BTMinerM60SVK10
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M60S VK20
|
||||
::: pyasic.miners.whatsminer.btminer.M6X.M60S.BTMinerM60SVK20
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M60S VK30
|
||||
::: pyasic.miners.whatsminer.btminer.M6X.M60S.BTMinerM60SVK30
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M60S VK40
|
||||
::: pyasic.miners.whatsminer.btminer.M6X.M60S.BTMinerM60SVK40
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M63 VK10
|
||||
::: pyasic.miners.whatsminer.btminer.M6X.M63.BTMinerM63VK10
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M63 VK20
|
||||
::: pyasic.miners.whatsminer.btminer.M6X.M63.BTMinerM63VK20
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M63 VK30
|
||||
::: pyasic.miners.whatsminer.btminer.M6X.M63.BTMinerM63VK30
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M63S VK10
|
||||
::: pyasic.miners.whatsminer.btminer.M6X.M63S.BTMinerM63SVK10
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M63S VK20
|
||||
::: pyasic.miners.whatsminer.btminer.M6X.M63S.BTMinerM63SVK20
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M63S VK30
|
||||
::: pyasic.miners.whatsminer.btminer.M6X.M63S.BTMinerM63SVK30
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M66 VK20
|
||||
::: pyasic.miners.whatsminer.btminer.M6X.M66.BTMinerM66VK20
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M66 VK30
|
||||
::: pyasic.miners.whatsminer.btminer.M6X.M66.BTMinerM66VK30
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M66S VK20
|
||||
::: pyasic.miners.whatsminer.btminer.M6X.M66S.BTMinerM66SVK20
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M66S VK30
|
||||
::: pyasic.miners.whatsminer.btminer.M6X.M66S.BTMinerM66SVK30
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M66S VK40
|
||||
::: pyasic.miners.whatsminer.btminer.M6X.M66S.BTMinerM66SVK40
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# pyasic
|
||||
## Miner APIs
|
||||
Each miner has a unique API that is used to communicate with it.
|
||||
## Miner RPC APIs
|
||||
Each miner has a unique RPC API that is used to communicate with it.
|
||||
Each of these API types has commands that differ between them, and some commands have data that others do not.
|
||||
Each miner that is a subclass of [`BaseMiner`][pyasic.miners.BaseMiner] should have an API linked to it as `Miner.api`.
|
||||
Each miner that is a subclass of [`BaseMiner`][pyasic.miners.base.BaseMiner] may have an API linked to it as `Miner.rpc`.
|
||||
|
||||
All API implementations inherit from [`BaseMinerRPCAPI`][pyasic.rpc.base.BaseMinerRPCAPI], which implements the basic communications protocols.
|
||||
All RPC API implementations inherit from [`BaseMinerRPCAPI`][pyasic.rpc.base.BaseMinerRPCAPI], which implements the basic communications protocols.
|
||||
|
||||
[`BaseMinerRPCAPI`][pyasic.rpc.base.BaseMinerRPCAPI] should never be used unless inheriting to create a new miner API class for a new type of miner (which should be exceedingly rare).
|
||||
[`BaseMinerRPCAPI`][pyasic.rpc.base.BaseMinerRPCAPI] cannot be instantiated directly, it will raise a `TypeError`.
|
||||
|
||||
@@ -12,6 +12,7 @@ Settings options:
|
||||
- `factory_get_timeout`
|
||||
- `get_data_retries`
|
||||
- `api_function_timeout`
|
||||
- `antminer_mining_mode_as_str`
|
||||
- `default_whatsminer_password`
|
||||
- `default_innosilicon_password`
|
||||
- `default_antminer_password`
|
||||
|
||||
14
docs/web/antminer.md
Normal file
14
docs/web/antminer.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# pyasic
|
||||
## AntminerModernWebAPI
|
||||
::: pyasic.web.antminer.AntminerModernWebAPI
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## AntminerOldWebAPI
|
||||
::: pyasic.web.antminer.AntminerOldWebAPI
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
27
docs/web/api.md
Normal file
27
docs/web/api.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# pyasic
|
||||
## Miner Web APIs
|
||||
Each miner has a unique Web API that is used to communicate with it.
|
||||
Each of these API types has commands that differ between them, and some commands have data that others do not.
|
||||
Each miner that is a subclass of [`BaseMiner`][pyasic.miners.base.BaseMiner] may have an API linked to it as `Miner.web`.
|
||||
|
||||
All API implementations inherit from [`BaseWebAPI`][pyasic.web.BaseWebAPI], which implements the basic communications protocols.
|
||||
|
||||
[`BaseWebAPI`][pyasic.web.BaseWebAPI] should never be used unless inheriting to create a new miner API class for a new type of miner (which should be exceedingly rare).
|
||||
Use these instead -
|
||||
|
||||
#### [AntminerModerNWebAPI][pyasic.web.antminer.AntminerModernWebAPI]
|
||||
#### [AntminerOldWebAPI][pyasic.web.antminer.AntminerOldWebAPI]
|
||||
#### [AuradineWebAPI][pyasic.web.auradine.AuradineWebAPI]
|
||||
#### [ePICWebAPI][pyasic.web.epic.ePICWebAPI]
|
||||
#### [GoldshellWebAPI][pyasic.web.goldshell.GoldshellWebAPI]
|
||||
#### [InnosiliconWebAPI][pyasic.web.innosilicon.InnosiliconWebAPI]
|
||||
#### [MaraWebAPI][pyasic.web.marathon.MaraWebAPI]
|
||||
#### [VNishWebAPI][pyasic.web.vnish.VNishWebAPI]
|
||||
|
||||
<br>
|
||||
|
||||
## BaseWebAPI
|
||||
::: pyasic.web.BaseWebAPI
|
||||
handler: python
|
||||
options:
|
||||
heading_level: 4
|
||||
7
docs/web/auradine.md
Normal file
7
docs/web/auradine.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# pyasic
|
||||
## AuradineWebAPI
|
||||
::: pyasic.web.auradine.AuradineWebAPI
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
7
docs/web/epic.md
Normal file
7
docs/web/epic.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# pyasic
|
||||
## ePICWebAPI
|
||||
::: pyasic.web.epic.ePICWebAPI
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
7
docs/web/goldshell.md
Normal file
7
docs/web/goldshell.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# pyasic
|
||||
## GoldshellWebAPI
|
||||
::: pyasic.web.goldshell.GoldshellWebAPI
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
7
docs/web/innosilicon.md
Normal file
7
docs/web/innosilicon.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# pyasic
|
||||
## InnosiliconWebAPI
|
||||
::: pyasic.web.innosilicon.InnosiliconWebAPI
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
7
docs/web/marathon.md
Normal file
7
docs/web/marathon.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# pyasic
|
||||
## MaraWebAPI
|
||||
::: pyasic.web.marathon.MaraWebAPI
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
7
docs/web/vnish.md
Normal file
7
docs/web/vnish.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# pyasic
|
||||
## VNishWebAPI
|
||||
::: pyasic.web.vnish.VNishWebAPI
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
15
mkdocs.yml
15
mkdocs.yml
@@ -22,6 +22,15 @@ nav:
|
||||
- CGMiner: "rpc/cgminer.md"
|
||||
- LUXMiner: "rpc/luxminer.md"
|
||||
- Unknown: "rpc/unknown.md"
|
||||
- Web APIs:
|
||||
- Intro: "web/api.md"
|
||||
- Antminer: "web/antminer.md"
|
||||
- Auradine: "web/auradine.md"
|
||||
- ePIC: "web/epic.md"
|
||||
- Goldshell: "web/goldshell.md"
|
||||
- Innosilicon: "web/innosilicon.md"
|
||||
- Marathon: "web/marathon.md"
|
||||
- VNish: "web/vnish.md"
|
||||
- Backends:
|
||||
- BMMiner: "miners/backends/bmminer.md"
|
||||
- BOSMiner: "miners/backends/bosminer.md"
|
||||
@@ -40,6 +49,7 @@ nav:
|
||||
- Antminer X15: "miners/antminer/X15.md"
|
||||
- Antminer X17: "miners/antminer/X17.md"
|
||||
- Antminer X19: "miners/antminer/X19.md"
|
||||
- Antminer X21: "miners/antminer/X21.md"
|
||||
- Avalon 7X: "miners/avalonminer/A7X.md"
|
||||
- Avalon 8X: "miners/avalonminer/A8X.md"
|
||||
- Avalon 9X: "miners/avalonminer/A9X.md"
|
||||
@@ -49,10 +59,15 @@ nav:
|
||||
- Whatsminer M2X: "miners/whatsminer/M2X.md"
|
||||
- Whatsminer M3X: "miners/whatsminer/M3X.md"
|
||||
- Whatsminer M5X: "miners/whatsminer/M5X.md"
|
||||
- Whatsminer M6X: "miners/whatsminer/M6X.md"
|
||||
- Innosilicon T3X: "miners/innosilicon/T3X.md"
|
||||
- Innosilicon A10X: "miners/innosilicon/A10X.md"
|
||||
- Goldshell X5: "miners/goldshell/X5.md"
|
||||
- Goldshell XMax: "miners/goldshell/XMax.md"
|
||||
- Goldshell XBox: "miners/goldshell/XBox.md"
|
||||
- Auradine AD: "miners/auradine/AD.md"
|
||||
- Auradine AI: "miners/auradine/AI.md"
|
||||
- Auradine AT: "miners/auradine/AT.md"
|
||||
- Base Miner: "miners/base_miner.md"
|
||||
- Settings:
|
||||
- Settings: "settings/settings.md"
|
||||
|
||||
@@ -25,6 +25,9 @@ from pyasic.misc import merge_dicts
|
||||
|
||||
@dataclass
|
||||
class MinerConfig:
|
||||
"""Represents the configuration for a miner including pool configuration,
|
||||
fan mode, temperature settings, mining mode, and power scaling."""
|
||||
|
||||
pools: PoolConfig = field(default_factory=PoolConfig.default)
|
||||
fan_mode: FanModeConfig = field(default_factory=FanModeConfig.default)
|
||||
temperature: TemperatureConfig = field(default_factory=TemperatureConfig.default)
|
||||
@@ -34,9 +37,11 @@ class MinerConfig:
|
||||
)
|
||||
|
||||
def as_dict(self) -> dict:
|
||||
"""Converts the MinerConfig object to a dictionary."""
|
||||
return asdict(self)
|
||||
|
||||
def as_am_modern(self, user_suffix: str = None) -> dict:
|
||||
"""Generates the configuration in the format suitable for modern Antminers."""
|
||||
return {
|
||||
**self.fan_mode.as_am_modern(),
|
||||
"freq-level": "100",
|
||||
@@ -47,6 +52,7 @@ class MinerConfig:
|
||||
}
|
||||
|
||||
def as_wm(self, user_suffix: str = None) -> dict:
|
||||
"""Generates the configuration in the format suitable for Whatsminers."""
|
||||
return {
|
||||
**self.fan_mode.as_wm(),
|
||||
**self.mining_mode.as_wm(),
|
||||
@@ -56,6 +62,7 @@ class MinerConfig:
|
||||
}
|
||||
|
||||
def as_am_old(self, user_suffix: str = None) -> dict:
|
||||
"""Generates the configuration in the format suitable for old versions of Antminers."""
|
||||
return {
|
||||
**self.fan_mode.as_am_old(),
|
||||
**self.mining_mode.as_am_old(),
|
||||
@@ -65,6 +72,7 @@ class MinerConfig:
|
||||
}
|
||||
|
||||
def as_goldshell(self, user_suffix: str = None) -> dict:
|
||||
"""Generates the configuration in the format suitable for Goldshell miners."""
|
||||
return {
|
||||
**self.fan_mode.as_goldshell(),
|
||||
**self.mining_mode.as_goldshell(),
|
||||
@@ -74,6 +82,7 @@ class MinerConfig:
|
||||
}
|
||||
|
||||
def as_avalon(self, user_suffix: str = None) -> dict:
|
||||
"""Generates the configuration in the format suitable for Avalonminers."""
|
||||
return {
|
||||
**self.fan_mode.as_avalon(),
|
||||
**self.mining_mode.as_avalon(),
|
||||
@@ -83,6 +92,7 @@ class MinerConfig:
|
||||
}
|
||||
|
||||
def as_inno(self, user_suffix: str = None) -> dict:
|
||||
"""Generates the configuration in the format suitable for Innosilicon miners."""
|
||||
return {
|
||||
**self.fan_mode.as_inno(),
|
||||
**self.mining_mode.as_inno(),
|
||||
@@ -92,6 +102,7 @@ class MinerConfig:
|
||||
}
|
||||
|
||||
def as_bosminer(self, user_suffix: str = None) -> dict:
|
||||
"""Generates the configuration in the bosminer.toml format."""
|
||||
return {
|
||||
**merge_dicts(self.fan_mode.as_bosminer(), self.temperature.as_bosminer()),
|
||||
**self.mining_mode.as_bosminer(),
|
||||
@@ -100,6 +111,7 @@ class MinerConfig:
|
||||
}
|
||||
|
||||
def as_boser(self, user_suffix: str = None) -> dict:
|
||||
""" "Generates the configuration in the format suitable for BOSer."""
|
||||
return {
|
||||
**self.fan_mode.as_boser(),
|
||||
**self.temperature.as_boser(),
|
||||
@@ -109,6 +121,7 @@ class MinerConfig:
|
||||
}
|
||||
|
||||
def as_epic(self, user_suffix: str = None) -> dict:
|
||||
"""Generates the configuration in the format suitable for ePIC miners."""
|
||||
return {
|
||||
**merge_dicts(self.fan_mode.as_epic(), self.temperature.as_epic()),
|
||||
**self.mining_mode.as_epic(),
|
||||
@@ -117,6 +130,7 @@ class MinerConfig:
|
||||
}
|
||||
|
||||
def as_auradine(self, user_suffix: str = None) -> dict:
|
||||
"""Generates the configuration in the format suitable for Auradine miners."""
|
||||
return {
|
||||
**self.fan_mode.as_auradine(),
|
||||
**self.temperature.as_auradine(),
|
||||
@@ -125,8 +139,18 @@ class MinerConfig:
|
||||
**self.power_scaling.as_auradine(),
|
||||
}
|
||||
|
||||
def as_mara(self, user_suffix: str = None) -> dict:
|
||||
return {
|
||||
**self.fan_mode.as_mara(),
|
||||
**self.temperature.as_mara(),
|
||||
**self.mining_mode.as_mara(),
|
||||
**self.pools.as_mara(user_suffix=user_suffix),
|
||||
**self.power_scaling.as_mara(),
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, dict_conf: dict) -> "MinerConfig":
|
||||
"""Constructs a MinerConfig object from a dictionary."""
|
||||
return cls(
|
||||
pools=PoolConfig.from_dict(dict_conf.get("pools")),
|
||||
mining_mode=MiningModeConfig.from_dict(dict_conf.get("mining_mode")),
|
||||
@@ -137,10 +161,12 @@ class MinerConfig:
|
||||
|
||||
@classmethod
|
||||
def from_api(cls, api_pools: dict) -> "MinerConfig":
|
||||
"""Constructs a MinerConfig object from API pool data."""
|
||||
return cls(pools=PoolConfig.from_api(api_pools))
|
||||
|
||||
@classmethod
|
||||
def from_am_modern(cls, web_conf: dict) -> "MinerConfig":
|
||||
"""Constructs a MinerConfig object from web configuration for modern Antminers."""
|
||||
return cls(
|
||||
pools=PoolConfig.from_am_modern(web_conf),
|
||||
mining_mode=MiningModeConfig.from_am_modern(web_conf),
|
||||
@@ -149,18 +175,22 @@ class MinerConfig:
|
||||
|
||||
@classmethod
|
||||
def from_am_old(cls, web_conf: dict) -> "MinerConfig":
|
||||
"""Constructs a MinerConfig object from web configuration for old versions of Antminers."""
|
||||
return cls.from_am_modern(web_conf)
|
||||
|
||||
@classmethod
|
||||
def from_goldshell(cls, web_conf: dict) -> "MinerConfig":
|
||||
"""Constructs a MinerConfig object from web configuration for Goldshell miners."""
|
||||
return cls(pools=PoolConfig.from_am_modern(web_conf))
|
||||
|
||||
@classmethod
|
||||
def from_inno(cls, web_pools: list) -> "MinerConfig":
|
||||
"""Constructs a MinerConfig object from web configuration for Innosilicon miners."""
|
||||
return cls(pools=PoolConfig.from_inno(web_pools))
|
||||
|
||||
@classmethod
|
||||
def from_bosminer(cls, toml_conf: dict) -> "MinerConfig":
|
||||
"""Constructs a MinerConfig object from the bosminer.toml file, same as the `as_bosminer` dumps a dict for writing to that file as toml."""
|
||||
return cls(
|
||||
pools=PoolConfig.from_bosminer(toml_conf),
|
||||
mining_mode=MiningModeConfig.from_bosminer(toml_conf),
|
||||
@@ -171,6 +201,7 @@ class MinerConfig:
|
||||
|
||||
@classmethod
|
||||
def from_boser(cls, grpc_miner_conf: dict) -> "MinerConfig":
|
||||
"""Constructs a MinerConfig object from gRPC configuration for BOSer."""
|
||||
return cls(
|
||||
pools=PoolConfig.from_boser(grpc_miner_conf),
|
||||
mining_mode=MiningModeConfig.from_boser(grpc_miner_conf),
|
||||
@@ -181,6 +212,7 @@ class MinerConfig:
|
||||
|
||||
@classmethod
|
||||
def from_epic(cls, web_conf: dict) -> "MinerConfig":
|
||||
"""Constructs a MinerConfig object from web configuration for ePIC miners."""
|
||||
return cls(
|
||||
pools=PoolConfig.from_epic(web_conf),
|
||||
fan_mode=FanModeConfig.from_epic(web_conf),
|
||||
@@ -190,6 +222,7 @@ class MinerConfig:
|
||||
|
||||
@classmethod
|
||||
def from_vnish(cls, web_settings: dict) -> "MinerConfig":
|
||||
"""Constructs a MinerConfig object from web settings for VNish miners."""
|
||||
return cls(
|
||||
pools=PoolConfig.from_vnish(web_settings),
|
||||
fan_mode=FanModeConfig.from_vnish(web_settings),
|
||||
@@ -199,8 +232,17 @@ class MinerConfig:
|
||||
|
||||
@classmethod
|
||||
def from_auradine(cls, web_conf: dict) -> "MinerConfig":
|
||||
"""Constructs a MinerConfig object from web configuration for Auradine miners."""
|
||||
return cls(
|
||||
pools=PoolConfig.from_api(web_conf["pools"]),
|
||||
fan_mode=FanModeConfig.from_auradine(web_conf["fan"]),
|
||||
mining_mode=MiningModeConfig.from_auradine(web_conf["mode"]),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_mara(cls, web_miner_config: dict) -> "MinerConfig":
|
||||
return cls(
|
||||
pools=PoolConfig.from_mara(web_miner_config),
|
||||
fan_mode=FanModeConfig.from_mara(web_miner_config),
|
||||
mining_mode=MiningModeConfig.from_mara(web_miner_config),
|
||||
)
|
||||
|
||||
@@ -57,6 +57,9 @@ class MinerConfigOption(Enum):
|
||||
def as_auradine(self) -> dict:
|
||||
return self.value.as_auradine()
|
||||
|
||||
def as_mara(self) -> dict:
|
||||
return self.value.as_mara()
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
return self.value(*args, **kwargs)
|
||||
|
||||
@@ -106,3 +109,6 @@ class MinerConfigValue:
|
||||
|
||||
def as_auradine(self) -> dict:
|
||||
return {}
|
||||
|
||||
def as_mara(self) -> dict:
|
||||
return {}
|
||||
|
||||
@@ -44,23 +44,42 @@ class FanModeNormal(MinerConfigValue):
|
||||
cls_conf["minimum_speed"] = web_cooling_settings["fan_min_duty"]
|
||||
return cls(**cls_conf)
|
||||
|
||||
@classmethod
|
||||
def from_bosminer(cls, toml_fan_conf: dict):
|
||||
cls_conf = {}
|
||||
if toml_fan_conf.get("min_fans") is not None:
|
||||
cls_conf["minimum_fans"] = toml_fan_conf["min_fans"]
|
||||
return cls(**cls_conf)
|
||||
|
||||
def as_am_modern(self) -> dict:
|
||||
return {"bitmain-fan-ctrl": False, "bitmain-fan-pwn": "100"}
|
||||
|
||||
def as_bosminer(self) -> dict:
|
||||
return {"temp_control": {"mode": "auto"}}
|
||||
return {
|
||||
"temp_control": {"mode": "auto"},
|
||||
"fan_control": {"min_fans": self.minimum_fans},
|
||||
}
|
||||
|
||||
def as_epic(self) -> dict:
|
||||
return {
|
||||
"fans": {
|
||||
"Auto": {
|
||||
"Idle Speed": self.minimum_speed
|
||||
if not self.minimum_speed == 0
|
||||
else 100
|
||||
"Idle Speed": (
|
||||
self.minimum_speed if not self.minimum_speed == 0 else 100
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def as_mara(self) -> dict:
|
||||
return {
|
||||
"general-config": {"environment-profile": "AirCooling"},
|
||||
"advance-config": {
|
||||
"override-fan-control": False,
|
||||
"fan-fixed-percent": 0,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@dataclass
|
||||
class FanModeManual(MinerConfigValue):
|
||||
@@ -96,7 +115,7 @@ class FanModeManual(MinerConfigValue):
|
||||
return cls(**cls_conf)
|
||||
|
||||
def as_am_modern(self) -> dict:
|
||||
return {"bitmain-fan-ctrl": True, "bitmain-fan-pwn": str(self.speed)}
|
||||
return {"bitmain-fan-ctrl": True, "bitmain-fan-pwm": str(self.speed)}
|
||||
|
||||
def as_bosminer(self) -> dict:
|
||||
return {
|
||||
@@ -110,6 +129,15 @@ class FanModeManual(MinerConfigValue):
|
||||
def as_epic(self) -> dict:
|
||||
return {"fans": {"Manual": {"speed": self.speed}}}
|
||||
|
||||
def as_mara(self) -> dict:
|
||||
return {
|
||||
"general-config": {"environment-profile": "AirCooling"},
|
||||
"advance-config": {
|
||||
"override-fan-control": True,
|
||||
"fan-fixed-percent": self.speed,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@dataclass
|
||||
class FanModeImmersion(MinerConfigValue):
|
||||
@@ -120,14 +148,19 @@ class FanModeImmersion(MinerConfigValue):
|
||||
return cls()
|
||||
|
||||
def as_am_modern(self) -> dict:
|
||||
return {"bitmain-fan-ctrl": True, "bitmain-fan-pwn": "0"}
|
||||
return {"bitmain-fan-ctrl": True, "bitmain-fan-pwm": "0"}
|
||||
|
||||
def as_bosminer(self) -> dict:
|
||||
return {"temp_control": {"mode": "disabled"}}
|
||||
return {
|
||||
"fan_control": {"min_fans": 0},
|
||||
}
|
||||
|
||||
def as_auradine(self) -> dict:
|
||||
return {"fan": {"percentage": 0}}
|
||||
|
||||
def as_mara(self) -> dict:
|
||||
return {"general-config": {"environment-profile": "OilImmersionCooling"}}
|
||||
|
||||
|
||||
class FanModeConfig(MinerConfigOption):
|
||||
normal = FanModeNormal
|
||||
@@ -156,7 +189,10 @@ class FanModeConfig(MinerConfigOption):
|
||||
if web_conf.get("bitmain-fan-ctrl") is not None:
|
||||
fan_manual = web_conf["bitmain-fan-ctrl"]
|
||||
if fan_manual:
|
||||
return cls.manual(speed=web_conf["bitmain-fan-pwm"])
|
||||
speed = int(web_conf["bitmain-fan-pwm"])
|
||||
if speed == 0:
|
||||
return cls.immersion()
|
||||
return cls.manual(speed=speed)
|
||||
else:
|
||||
return cls.normal()
|
||||
else:
|
||||
@@ -175,20 +211,28 @@ class FanModeConfig(MinerConfigOption):
|
||||
|
||||
@classmethod
|
||||
def from_bosminer(cls, toml_conf: dict):
|
||||
if toml_conf.get("temp_control") is None:
|
||||
return cls.default()
|
||||
if toml_conf["temp_control"].get("mode") is None:
|
||||
try:
|
||||
mode = toml_conf["temp_control"]["mode"]
|
||||
fan_config = toml_conf.get("fan_control", {})
|
||||
if mode == "auto":
|
||||
return cls.normal().from_bosminer(fan_config)
|
||||
elif mode == "manual":
|
||||
if toml_conf.get("fan_control"):
|
||||
return cls.manual().from_bosminer(fan_config)
|
||||
return cls.manual()
|
||||
elif mode == "disabled":
|
||||
return cls.immersion()
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
try:
|
||||
min_fans = toml_conf["fan_control"]["min_fans"]
|
||||
except KeyError:
|
||||
return cls.default()
|
||||
|
||||
mode = toml_conf["temp_control"]["mode"]
|
||||
if mode == "auto":
|
||||
return cls.normal()
|
||||
elif mode == "manual":
|
||||
if toml_conf.get("fan_control"):
|
||||
return cls.manual().from_bosminer(toml_conf["fan_control"])
|
||||
return cls.manual()
|
||||
elif mode == "disabled":
|
||||
if min_fans == 0:
|
||||
return cls.immersion()
|
||||
return cls.normal(minimum_fans=min_fans)
|
||||
|
||||
@classmethod
|
||||
def from_vnish(cls, web_settings: dict):
|
||||
@@ -232,4 +276,18 @@ class FanModeConfig(MinerConfigOption):
|
||||
fan_1_target = fan_data["Target"]
|
||||
return cls.manual(speed=round((fan_1_target / fan_1_max) * 100))
|
||||
except LookupError:
|
||||
return cls.default()
|
||||
pass
|
||||
return cls.default()
|
||||
|
||||
@classmethod
|
||||
def from_mara(cls, web_config: dict):
|
||||
try:
|
||||
mode = web_config["general-config"]["environment-profile"]
|
||||
if mode == "AirCooling":
|
||||
if web_config["advance-config"]["override-fan-control"]:
|
||||
return cls.manual(web_config["advance-config"]["fan-fixed-percent"])
|
||||
return cls.normal()
|
||||
return cls.immersion()
|
||||
except LookupError:
|
||||
pass
|
||||
return cls.default()
|
||||
|
||||
@@ -17,6 +17,7 @@ from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
|
||||
from pyasic import settings
|
||||
from pyasic.config.base import MinerConfigOption, MinerConfigValue
|
||||
from pyasic.web.braiins_os.proto.braiins.bos.v1 import (
|
||||
HashrateTargetMode,
|
||||
@@ -39,7 +40,9 @@ class MiningModeNormal(MinerConfigValue):
|
||||
return cls()
|
||||
|
||||
def as_am_modern(self) -> dict:
|
||||
return {"miner-mode": "0"}
|
||||
if settings.get("antminer_mining_mode_as_str", False):
|
||||
return {"miner-mode": "0"}
|
||||
return {"miner-mode": 0}
|
||||
|
||||
def as_wm(self) -> dict:
|
||||
return {"mode": self.mode}
|
||||
@@ -50,6 +53,16 @@ class MiningModeNormal(MinerConfigValue):
|
||||
def as_epic(self) -> dict:
|
||||
return {"ptune": {"enabled": False}}
|
||||
|
||||
def as_goldshell(self) -> dict:
|
||||
return {"settings": {"level": 0}}
|
||||
|
||||
def as_mara(self) -> dict:
|
||||
return {
|
||||
"mode": {
|
||||
"work-mode-selector": "Stock",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@dataclass
|
||||
class MiningModeSleep(MinerConfigValue):
|
||||
@@ -60,7 +73,9 @@ class MiningModeSleep(MinerConfigValue):
|
||||
return cls()
|
||||
|
||||
def as_am_modern(self) -> dict:
|
||||
return {"miner-mode": "1"}
|
||||
if settings.get("antminer_mining_mode_as_str", False):
|
||||
return {"miner-mode": "1"}
|
||||
return {"miner-mode": 1}
|
||||
|
||||
def as_wm(self) -> dict:
|
||||
return {"mode": self.mode}
|
||||
@@ -71,6 +86,16 @@ class MiningModeSleep(MinerConfigValue):
|
||||
def as_epic(self) -> dict:
|
||||
return {"ptune": {"algo": "Sleep", "target": 0}}
|
||||
|
||||
def as_goldshell(self) -> dict:
|
||||
return {"settings": {"level": 3}}
|
||||
|
||||
def as_mara(self) -> dict:
|
||||
return {
|
||||
"mode": {
|
||||
"work-mode-selector": "Sleep",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@dataclass
|
||||
class MiningModeLPM(MinerConfigValue):
|
||||
@@ -81,7 +106,9 @@ class MiningModeLPM(MinerConfigValue):
|
||||
return cls()
|
||||
|
||||
def as_am_modern(self) -> dict:
|
||||
return {"miner-mode": "3"}
|
||||
if settings.get("antminer_mining_mode_as_str", False):
|
||||
return {"miner-mode": "3"}
|
||||
return {"miner-mode": 3}
|
||||
|
||||
def as_wm(self) -> dict:
|
||||
return {"mode": self.mode}
|
||||
@@ -89,6 +116,9 @@ class MiningModeLPM(MinerConfigValue):
|
||||
def as_auradine(self) -> dict:
|
||||
return {"mode": {"mode": "eco"}}
|
||||
|
||||
def as_goldshell(self) -> dict:
|
||||
return {"settings": {"level": 1}}
|
||||
|
||||
|
||||
@dataclass
|
||||
class MiningModeHPM(MinerConfigValue):
|
||||
@@ -99,7 +129,9 @@ class MiningModeHPM(MinerConfigValue):
|
||||
return cls()
|
||||
|
||||
def as_am_modern(self) -> dict:
|
||||
return {"miner-mode": "0"}
|
||||
if settings.get("antminer_mining_mode_as_str", False):
|
||||
return {"miner-mode": "0"}
|
||||
return {"miner-mode": 0}
|
||||
|
||||
def as_wm(self) -> dict:
|
||||
return {"mode": self.mode}
|
||||
@@ -108,6 +140,7 @@ class MiningModeHPM(MinerConfigValue):
|
||||
return {"mode": {"mode": "turbo"}}
|
||||
|
||||
|
||||
@dataclass
|
||||
class StandardTuneAlgo(MinerConfigValue):
|
||||
mode: str = field(init=False, default="standard")
|
||||
|
||||
@@ -115,20 +148,22 @@ class StandardTuneAlgo(MinerConfigValue):
|
||||
return VOptAlgo().as_epic()
|
||||
|
||||
|
||||
@dataclass
|
||||
class VOptAlgo(MinerConfigValue):
|
||||
mode: str = field(init=False, default="standard")
|
||||
mode: str = field(init=False, default="voltage_optimizer")
|
||||
|
||||
def as_epic(self) -> str:
|
||||
return "VoltageOptimizer"
|
||||
|
||||
|
||||
class ChipTuneAlgo(MinerConfigValue):
|
||||
mode: str = field(init=False, default="standard")
|
||||
mode: str = field(init=False, default="chip_tune")
|
||||
|
||||
def as_epic(self) -> str:
|
||||
return "ChipTune"
|
||||
|
||||
|
||||
@dataclass
|
||||
class TunerAlgo(MinerConfigOption):
|
||||
standard = StandardTuneAlgo
|
||||
voltage_optimizer = VOptAlgo
|
||||
@@ -138,6 +173,16 @@ class TunerAlgo(MinerConfigOption):
|
||||
def default(cls):
|
||||
return cls.standard()
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, dict_conf: dict | None):
|
||||
mode = dict_conf.get("mode")
|
||||
if mode is None:
|
||||
return cls.default()
|
||||
|
||||
cls_attr = getattr(cls, mode)
|
||||
if cls_attr is not None:
|
||||
return cls_attr().from_dict(dict_conf)
|
||||
|
||||
|
||||
@dataclass
|
||||
class MiningModePowerTune(MinerConfigValue):
|
||||
@@ -151,12 +196,14 @@ class MiningModePowerTune(MinerConfigValue):
|
||||
if dict_conf.get("power"):
|
||||
cls_conf["power"] = dict_conf["power"]
|
||||
if dict_conf.get("algo"):
|
||||
cls_conf["algo"] = dict_conf["algo"]
|
||||
cls_conf["algo"] = TunerAlgo.from_dict(dict_conf["algo"])
|
||||
|
||||
return cls(**cls_conf)
|
||||
|
||||
def as_am_modern(self) -> dict:
|
||||
return {"miner-mode": "0"}
|
||||
if settings.get("antminer_mining_mode_as_str", False):
|
||||
return {"miner-mode": "0"}
|
||||
return {"miner-mode": 0}
|
||||
|
||||
def as_wm(self) -> dict:
|
||||
if self.power is not None:
|
||||
@@ -164,7 +211,10 @@ class MiningModePowerTune(MinerConfigValue):
|
||||
return {}
|
||||
|
||||
def as_bosminer(self) -> dict:
|
||||
return {"autotuning": {"enabled": True, "psu_power_limit": self.power}}
|
||||
conf = {"enabled": True, "mode": "power_target"}
|
||||
if self.power is not None:
|
||||
conf["power_target"] = self.power
|
||||
return {"autotuning": conf}
|
||||
|
||||
def as_boser(self) -> dict:
|
||||
return {
|
||||
@@ -183,6 +233,17 @@ class MiningModePowerTune(MinerConfigValue):
|
||||
def as_auradine(self) -> dict:
|
||||
return {"mode": {"mode": "custom", "tune": "power", "power": self.power}}
|
||||
|
||||
def as_mara(self) -> dict:
|
||||
return {
|
||||
"mode": {
|
||||
"work-mode-selector": "Auto",
|
||||
"concorde": {
|
||||
"mode-select": "PowerTarget",
|
||||
"power-target": self.power,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@dataclass
|
||||
class MiningModeHashrateTune(MinerConfigValue):
|
||||
@@ -192,10 +253,24 @@ class MiningModeHashrateTune(MinerConfigValue):
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, dict_conf: dict | None) -> "MiningModeHashrateTune":
|
||||
return cls(dict_conf.get("hashrate"))
|
||||
cls_conf = {}
|
||||
if dict_conf.get("hashrate"):
|
||||
cls_conf["hashrate"] = dict_conf["hashrate"]
|
||||
if dict_conf.get("algo"):
|
||||
cls_conf["algo"] = TunerAlgo.from_dict(dict_conf["algo"])
|
||||
|
||||
return cls(**cls_conf)
|
||||
|
||||
def as_am_modern(self) -> dict:
|
||||
return {"miner-mode": "0"}
|
||||
if settings.get("antminer_mining_mode_as_str", False):
|
||||
return {"miner-mode": "0"}
|
||||
return {"miner-mode": 0}
|
||||
|
||||
def as_bosminer(self) -> dict:
|
||||
conf = {"enabled": True, "mode": "hashrate_target"}
|
||||
if self.hashrate is not None:
|
||||
conf["hashrate_target"] = self.hashrate
|
||||
return {"autotuning": conf}
|
||||
|
||||
def as_boser(self) -> dict:
|
||||
return {
|
||||
@@ -219,6 +294,17 @@ class MiningModeHashrateTune(MinerConfigValue):
|
||||
def as_epic(self) -> dict:
|
||||
return {"ptune": {"algo": self.algo.as_epic(), "target": self.hashrate}}
|
||||
|
||||
def as_mara(self) -> dict:
|
||||
return {
|
||||
"mode": {
|
||||
"work-mode-selector": "Auto",
|
||||
"concorde": {
|
||||
"mode-select": "Hashrate",
|
||||
"hash-target": self.hashrate,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@dataclass
|
||||
class ManualBoardSettings(MinerConfigValue):
|
||||
@@ -230,7 +316,9 @@ class ManualBoardSettings(MinerConfigValue):
|
||||
return cls(freq=dict_conf["freq"], volt=dict_conf["volt"])
|
||||
|
||||
def as_am_modern(self) -> dict:
|
||||
return {"miner-mode": "0"}
|
||||
if settings.get("antminer_mining_mode_as_str", False):
|
||||
return {"miner-mode": "0"}
|
||||
return {"miner-mode": 0}
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -250,7 +338,9 @@ class MiningModeManual(MinerConfigValue):
|
||||
)
|
||||
|
||||
def as_am_modern(self) -> dict:
|
||||
return {"miner-mode": "0"}
|
||||
if settings.get("antminer_mining_mode_as_str", False):
|
||||
return {"miner-mode": "0"}
|
||||
return {"miner-mode": 0}
|
||||
|
||||
@classmethod
|
||||
def from_vnish(cls, web_overclock_settings: dict) -> "MiningModeManual":
|
||||
@@ -266,6 +356,17 @@ class MiningModeManual(MinerConfigValue):
|
||||
}
|
||||
return cls(global_freq=freq, global_volt=voltage, boards=boards)
|
||||
|
||||
def as_mara(self) -> dict:
|
||||
return {
|
||||
"mode": {
|
||||
"work-mode-selector": "Fixed",
|
||||
"fixed": {
|
||||
"frequency": str(self.global_freq),
|
||||
"voltage": self.global_volt,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class MiningModeConfig(MinerConfigOption):
|
||||
normal = MiningModeNormal
|
||||
@@ -414,3 +515,28 @@ class MiningModeConfig(MinerConfigOption):
|
||||
return cls.power_tuning(mode_data["Power"])
|
||||
except LookupError:
|
||||
return cls.default()
|
||||
|
||||
@classmethod
|
||||
def from_mara(cls, web_config: dict):
|
||||
try:
|
||||
mode = web_config["mode"]["work-mode-selector"]
|
||||
if mode == "Fixed":
|
||||
fixed_conf = web_config["mode"]["fixed"]
|
||||
return cls.manual(
|
||||
global_freq=int(fixed_conf["frequency"]),
|
||||
global_volt=fixed_conf["voltage"],
|
||||
)
|
||||
elif mode == "Stock":
|
||||
return cls.normal()
|
||||
elif mode == "Sleep":
|
||||
return cls.sleep()
|
||||
elif mode == "Auto":
|
||||
auto_conf = web_config["mode"]["concorde"]
|
||||
auto_mode = auto_conf["mode-select"]
|
||||
if auto_mode == "Hashrate":
|
||||
return cls.hashrate_tuning(hashrate=auto_conf["hash-target"])
|
||||
elif auto_mode == "PowerTarget":
|
||||
return cls.power_tuning(power=auto_conf["power-target"])
|
||||
except LookupError:
|
||||
pass
|
||||
return cls.default()
|
||||
|
||||
@@ -118,6 +118,15 @@ class Pool(MinerConfigValue):
|
||||
}
|
||||
return {"pool": self.url, "login": self.user, "password": self.password}
|
||||
|
||||
def as_mara(self, user_suffix: str = None) -> dict:
|
||||
if user_suffix is not None:
|
||||
return {
|
||||
"url": self.url,
|
||||
"user": f"{self.user}{user_suffix}",
|
||||
"pass": self.password,
|
||||
}
|
||||
return {"url": self.url, "user": self.user, "pass": self.password}
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, dict_conf: dict | None) -> "Pool":
|
||||
return cls(
|
||||
@@ -177,6 +186,14 @@ class Pool(MinerConfigValue):
|
||||
password=grpc_pool["password"],
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_mara(cls, web_pool: dict) -> "Pool":
|
||||
return cls(
|
||||
url=web_pool["url"],
|
||||
user=web_pool["user"],
|
||||
password=web_pool["pass"],
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
class PoolGroup(MinerConfigValue):
|
||||
@@ -264,9 +281,12 @@ class PoolGroup(MinerConfigValue):
|
||||
def as_auradine(self, user_suffix: str = None) -> list:
|
||||
return [p.as_auradine(user_suffix=user_suffix) for p in self.pools]
|
||||
|
||||
def as_epic(self, user_suffix: str = None) -> dict:
|
||||
def as_epic(self, user_suffix: str = None) -> list:
|
||||
return [p.as_epic(user_suffix=user_suffix) for p in self.pools]
|
||||
|
||||
def as_mara(self, user_suffix: str = None) -> list:
|
||||
return [p.as_mara(user_suffix=user_suffix) for p in self.pools]
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, dict_conf: dict | None) -> "PoolGroup":
|
||||
cls_conf = {}
|
||||
@@ -327,13 +347,19 @@ class PoolGroup(MinerConfigValue):
|
||||
return cls(
|
||||
pools=[Pool.from_boser(p) for p in grpc_pool_group["pools"]],
|
||||
name=grpc_pool_group["name"],
|
||||
quota=grpc_pool_group["quota"]["value"]
|
||||
if grpc_pool_group.get("quota") is not None
|
||||
else 1,
|
||||
quota=(
|
||||
grpc_pool_group["quota"]["value"]
|
||||
if grpc_pool_group.get("quota") is not None
|
||||
else 1
|
||||
),
|
||||
)
|
||||
except LookupError:
|
||||
return cls()
|
||||
|
||||
@classmethod
|
||||
def from_mara(cls, web_config_pools: dict) -> "PoolGroup":
|
||||
return cls(pools=[Pool.from_mara(pool_conf) for pool_conf in web_config_pools])
|
||||
|
||||
|
||||
@dataclass
|
||||
class PoolConfig(MinerConfigValue):
|
||||
@@ -425,6 +451,11 @@ class PoolConfig(MinerConfigValue):
|
||||
}
|
||||
}
|
||||
|
||||
def as_mara(self, user_suffix: str = None) -> dict:
|
||||
if len(self.groups) > 0:
|
||||
return {"pools": self.groups[0].as_mara(user_suffix=user_suffix)}
|
||||
return {"pools": []}
|
||||
|
||||
@classmethod
|
||||
def from_api(cls, api_pools: dict) -> "PoolConfig":
|
||||
try:
|
||||
@@ -479,3 +510,7 @@ class PoolConfig(MinerConfigValue):
|
||||
)
|
||||
except LookupError:
|
||||
return cls()
|
||||
|
||||
@classmethod
|
||||
def from_mara(cls, web_config: dict) -> "PoolConfig":
|
||||
return cls(groups=[PoolGroup.from_mara(web_config["pools"])])
|
||||
|
||||
@@ -114,6 +114,8 @@ class PowerScalingEnabled(MinerConfigValue):
|
||||
def from_bosminer(cls, power_scaling_conf: dict) -> "PowerScalingEnabled":
|
||||
power_step = power_scaling_conf.get("power_step")
|
||||
min_power = power_scaling_conf.get("min_psu_power_limit")
|
||||
if min_power is None:
|
||||
min_power = power_scaling_conf.get("min_power_target")
|
||||
sd_mode = PowerScalingShutdown.from_bosminer(power_scaling_conf)
|
||||
|
||||
return cls(
|
||||
@@ -138,12 +140,12 @@ class PowerScalingEnabled(MinerConfigValue):
|
||||
if self.power_step is not None:
|
||||
cfg["power_step"] = self.power_step
|
||||
if self.minimum_power is not None:
|
||||
cfg["min_psu_power_limit"] = self.minimum_power
|
||||
cfg["min_power_target"] = self.minimum_power
|
||||
|
||||
if self.shutdown_enabled is not None:
|
||||
cfg = {**cfg, **self.shutdown_enabled.as_bosminer()}
|
||||
|
||||
return {"power_scaling": cfg}
|
||||
return {"performance_scaling": cfg}
|
||||
|
||||
def as_boser(self) -> dict:
|
||||
return {
|
||||
@@ -189,6 +191,8 @@ class PowerScalingConfig(MinerConfigOption):
|
||||
@classmethod
|
||||
def from_bosminer(cls, toml_conf: dict):
|
||||
power_scaling = toml_conf.get("power_scaling")
|
||||
if power_scaling is None:
|
||||
power_scaling = toml_conf.get("performance_scaling")
|
||||
if power_scaling is not None:
|
||||
enabled = power_scaling.get("enabled")
|
||||
if enabled is not None:
|
||||
|
||||
@@ -95,7 +95,12 @@ class MinerData:
|
||||
nominal: bool = field(init=False)
|
||||
config: MinerConfig = None
|
||||
errors: List[
|
||||
Union[WhatsminerError, BraiinsOSError, X19Error, InnosiliconError]
|
||||
Union[
|
||||
WhatsminerError,
|
||||
BraiinsOSError,
|
||||
X19Error,
|
||||
InnosiliconError,
|
||||
]
|
||||
] = field(default_factory=list)
|
||||
fault_light: Union[bool, None] = None
|
||||
efficiency: int = field(init=False)
|
||||
|
||||
@@ -20,4 +20,5 @@ from .cgminer import *
|
||||
from .epic import *
|
||||
from .hiveon import *
|
||||
from .luxos import *
|
||||
from .marathon import *
|
||||
from .vnish import *
|
||||
|
||||
@@ -21,6 +21,7 @@ from pyasic.miners.models import (
|
||||
S19XP,
|
||||
S19a,
|
||||
S19aPro,
|
||||
S19Hydro,
|
||||
S19i,
|
||||
S19j,
|
||||
S19jNoPIC,
|
||||
@@ -29,6 +30,8 @@ from pyasic.miners.models import (
|
||||
S19Pro,
|
||||
S19ProHydro,
|
||||
S19ProPlus,
|
||||
S19ProPlusHydro,
|
||||
S19KPro,
|
||||
)
|
||||
|
||||
|
||||
@@ -82,3 +85,15 @@ class BMMinerS19L(AntminerModern, S19L):
|
||||
|
||||
class BMMinerS19ProHydro(AntminerModern, S19ProHydro):
|
||||
pass
|
||||
|
||||
|
||||
class BMMinerS19Hydro(AntminerModern, S19Hydro):
|
||||
pass
|
||||
|
||||
|
||||
class BMMinerS19ProPlusHydro(AntminerModern, S19ProPlusHydro):
|
||||
pass
|
||||
|
||||
|
||||
class BMMinerS19KPro(AntminerModern, S19KPro):
|
||||
pass
|
||||
|
||||
@@ -18,6 +18,7 @@ from .S19 import (
|
||||
BMMinerS19,
|
||||
BMMinerS19a,
|
||||
BMMinerS19aPro,
|
||||
BMMinerS19Hydro,
|
||||
BMMinerS19i,
|
||||
BMMinerS19j,
|
||||
BMMinerS19jNoPIC,
|
||||
@@ -27,6 +28,8 @@ from .S19 import (
|
||||
BMMinerS19Pro,
|
||||
BMMinerS19ProHydro,
|
||||
BMMinerS19ProPlus,
|
||||
BMMinerS19ProPlusHydro,
|
||||
BMMinerS19XP,
|
||||
BMMinerS19KPro,
|
||||
)
|
||||
from .T19 import BMMinerT19
|
||||
|
||||
22
pyasic/miners/antminer/bmminer/X21/S21.py
Normal file
22
pyasic/miners/antminer/bmminer/X21/S21.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# 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 AntminerModern
|
||||
from pyasic.miners.models import S21
|
||||
|
||||
|
||||
class BMMinerS21(AntminerModern, S21):
|
||||
pass
|
||||
22
pyasic/miners/antminer/bmminer/X21/T21.py
Normal file
22
pyasic/miners/antminer/bmminer/X21/T21.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# 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 AntminerModern
|
||||
from pyasic.miners.models import T21
|
||||
|
||||
|
||||
class BMMinerT21(AntminerModern, T21):
|
||||
pass
|
||||
17
pyasic/miners/antminer/bmminer/X21/__init__.py
Normal file
17
pyasic/miners/antminer/bmminer/X21/__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 .S21 import BMMinerS21
|
||||
from .T21 import BMMinerT21
|
||||
@@ -18,3 +18,4 @@ from .X7 import *
|
||||
from .X9 import *
|
||||
from .X17 import *
|
||||
from .X19 import *
|
||||
from .X21 import *
|
||||
|
||||
@@ -23,7 +23,9 @@ from pyasic.miners.models import (
|
||||
S19j,
|
||||
S19jNoPIC,
|
||||
S19jPro,
|
||||
S19jProNoPIC,
|
||||
S19jProPlus,
|
||||
S19jProPlusNoPIC,
|
||||
S19kProNoPIC,
|
||||
S19Plus,
|
||||
S19Pro,
|
||||
@@ -58,6 +60,10 @@ class BOSMinerS19jPro(BOSer, S19jPro):
|
||||
pass
|
||||
|
||||
|
||||
class BOSMinerS19jProNoPIC(BOSer, S19jProNoPIC):
|
||||
pass
|
||||
|
||||
|
||||
class BOSMinerS19kProNoPIC(BOSer, S19kProNoPIC):
|
||||
pass
|
||||
|
||||
@@ -70,5 +76,9 @@ class BOSMinerS19jProPlus(BOSer, S19jProPlus):
|
||||
pass
|
||||
|
||||
|
||||
class BOSMinerS19jProPlusNoPIC(BOSer, S19jProPlusNoPIC):
|
||||
pass
|
||||
|
||||
|
||||
class BOSMinerS19XP(BOSer, S19XP):
|
||||
pass
|
||||
|
||||
@@ -21,7 +21,9 @@ from .S19 import (
|
||||
BOSMinerS19j,
|
||||
BOSMinerS19jNoPIC,
|
||||
BOSMinerS19jPro,
|
||||
BOSMinerS19jProNoPIC,
|
||||
BOSMinerS19jProPlus,
|
||||
BOSMinerS19jProPlusNoPIC,
|
||||
BOSMinerS19kProNoPIC,
|
||||
BOSMinerS19Plus,
|
||||
BOSMinerS19Pro,
|
||||
|
||||
22
pyasic/miners/antminer/bosminer/X21/S21.py
Normal file
22
pyasic/miners/antminer/bosminer/X21/S21.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# 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 BOSer
|
||||
from pyasic.miners.models import S21
|
||||
|
||||
|
||||
class BOSMinerS21(BOSer, S21):
|
||||
pass
|
||||
17
pyasic/miners/antminer/bosminer/X21/__init__.py
Normal file
17
pyasic/miners/antminer/bosminer/X21/__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 .S21 import BOSMinerS21
|
||||
@@ -17,3 +17,4 @@
|
||||
from .X9 import *
|
||||
from .X17 import *
|
||||
from .X19 import *
|
||||
from .X21 import *
|
||||
|
||||
22
pyasic/miners/antminer/epic/X21/S21.py
Normal file
22
pyasic/miners/antminer/epic/X21/S21.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# 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.models import S21
|
||||
|
||||
|
||||
class ePICS21(ePIC, S21):
|
||||
pass
|
||||
22
pyasic/miners/antminer/epic/X21/T21.py
Normal file
22
pyasic/miners/antminer/epic/X21/T21.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# 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.models import T21
|
||||
|
||||
|
||||
class ePICT21(ePIC, T21):
|
||||
pass
|
||||
23
pyasic/miners/antminer/epic/X21/__init__.py
Normal file
23
pyasic/miners/antminer/epic/X21/__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 .S21 import (
|
||||
ePICS21,
|
||||
)
|
||||
|
||||
from .T21 import (
|
||||
ePICT21,
|
||||
)
|
||||
@@ -15,3 +15,4 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from .X19 import *
|
||||
from .X21 import *
|
||||
|
||||
42
pyasic/miners/antminer/luxos/X19/S19.py
Normal file
42
pyasic/miners/antminer/luxos/X19/S19.py
Normal file
@@ -0,0 +1,42 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# 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 LUXMiner
|
||||
from pyasic.miners.models import S19, S19XP, S19jPro, S19jProPlus, S19kPro, S19Pro
|
||||
|
||||
|
||||
class LUXMinerS19(LUXMiner, S19):
|
||||
pass
|
||||
|
||||
|
||||
class LUXMinerS19Pro(LUXMiner, S19Pro):
|
||||
pass
|
||||
|
||||
|
||||
class LUXMinerS19jPro(LUXMiner, S19jPro):
|
||||
pass
|
||||
|
||||
|
||||
class LUXMinerS19jProPlus(LUXMiner, S19jProPlus):
|
||||
pass
|
||||
|
||||
|
||||
class LUXMinerS19kPro(LUXMiner, S19kPro):
|
||||
pass
|
||||
|
||||
|
||||
class LUXMinerS19XP(LUXMiner, S19XP):
|
||||
pass
|
||||
22
pyasic/miners/antminer/luxos/X19/T19.py
Normal file
22
pyasic/miners/antminer/luxos/X19/T19.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# 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 LUXMiner
|
||||
from pyasic.miners.models import T19
|
||||
|
||||
|
||||
class LUXMinerT19(LUXMiner, T19):
|
||||
pass
|
||||
25
pyasic/miners/antminer/luxos/X19/__init__.py
Normal file
25
pyasic/miners/antminer/luxos/X19/__init__.py
Normal file
@@ -0,0 +1,25 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# 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 (
|
||||
LUXMinerS19,
|
||||
LUXMinerS19jPro,
|
||||
LUXMinerS19jProPlus,
|
||||
LUXMinerS19kPro,
|
||||
LUXMinerS19Pro,
|
||||
LUXMinerS19XP,
|
||||
)
|
||||
from .T19 import LUXMinerT19
|
||||
22
pyasic/miners/antminer/luxos/X21/S21.py
Normal file
22
pyasic/miners/antminer/luxos/X21/S21.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# 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 LUXMiner
|
||||
from pyasic.miners.models import S21
|
||||
|
||||
|
||||
class LUXMinerS21(LUXMiner, S21):
|
||||
pass
|
||||
17
pyasic/miners/antminer/luxos/X21/__init__.py
Normal file
17
pyasic/miners/antminer/luxos/X21/__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 .S21 import LUXMinerS21
|
||||
@@ -15,3 +15,5 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from .X9 import *
|
||||
from .X19 import *
|
||||
from .X21 import *
|
||||
|
||||
46
pyasic/miners/antminer/marathon/X19/S19.py
Normal file
46
pyasic/miners/antminer/marathon/X19/S19.py
Normal file
@@ -0,0 +1,46 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# 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 MaraMiner
|
||||
from pyasic.miners.models import S19, S19XP, S19j, S19jNoPIC, S19jPro, S19KPro, S19Pro
|
||||
|
||||
|
||||
class MaraS19(MaraMiner, S19):
|
||||
pass
|
||||
|
||||
|
||||
class MaraS19Pro(MaraMiner, S19Pro):
|
||||
pass
|
||||
|
||||
|
||||
class MaraS19XP(MaraMiner, S19XP):
|
||||
pass
|
||||
|
||||
|
||||
class MaraS19j(MaraMiner, S19j):
|
||||
pass
|
||||
|
||||
|
||||
class MaraS19jNoPIC(MaraMiner, S19jNoPIC):
|
||||
pass
|
||||
|
||||
|
||||
class MaraS19jPro(MaraMiner, S19jPro):
|
||||
pass
|
||||
|
||||
|
||||
class MaraS19KPro(MaraMiner, S19KPro):
|
||||
pass
|
||||
9
pyasic/miners/antminer/marathon/X19/__init__.py
Normal file
9
pyasic/miners/antminer/marathon/X19/__init__.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from .S19 import (
|
||||
MaraS19,
|
||||
MaraS19j,
|
||||
MaraS19jNoPIC,
|
||||
MaraS19jPro,
|
||||
MaraS19KPro,
|
||||
MaraS19Pro,
|
||||
MaraS19XP,
|
||||
)
|
||||
22
pyasic/miners/antminer/marathon/X21/S21.py
Normal file
22
pyasic/miners/antminer/marathon/X21/S21.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# 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 MaraMiner
|
||||
from pyasic.miners.models import S21
|
||||
|
||||
|
||||
class MaraS21(MaraMiner, S21):
|
||||
pass
|
||||
22
pyasic/miners/antminer/marathon/X21/T21.py
Normal file
22
pyasic/miners/antminer/marathon/X21/T21.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# 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 MaraMiner
|
||||
from pyasic.miners.models import T21
|
||||
|
||||
|
||||
class MaraT21(MaraMiner, T21):
|
||||
pass
|
||||
2
pyasic/miners/antminer/marathon/X21/__init__.py
Normal file
2
pyasic/miners/antminer/marathon/X21/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
from .S21 import MaraS21
|
||||
from .T21 import MaraT21
|
||||
2
pyasic/miners/antminer/marathon/__init__.py
Normal file
2
pyasic/miners/antminer/marathon/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
from .X19 import *
|
||||
from .X21 import *
|
||||
22
pyasic/miners/antminer/vnish/X7/L7.py
Normal file
22
pyasic/miners/antminer/vnish/X7/L7.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# 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 VNish
|
||||
from pyasic.miners.models import L7
|
||||
|
||||
|
||||
class VnishL7(VNish, L7):
|
||||
pass
|
||||
17
pyasic/miners/antminer/vnish/X7/__init__.py
Normal file
17
pyasic/miners/antminer/vnish/X7/__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 .L7 import VnishL7
|
||||
@@ -15,5 +15,6 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from .X3 import *
|
||||
from .X7 import *
|
||||
from .X17 import *
|
||||
from .X19 import *
|
||||
|
||||
@@ -26,5 +26,6 @@ from .goldshell import GoldshellMiner
|
||||
from .hiveon import Hiveon
|
||||
from .innosilicon import Innosilicon
|
||||
from .luxminer import LUXMiner
|
||||
from .marathon import MaraMiner
|
||||
from .vnish import VNish
|
||||
from .whatsminer import M2X, M3X, M5X, M6X
|
||||
|
||||
@@ -22,6 +22,7 @@ from pyasic.data.error_codes import MinerErrorData, X19Error
|
||||
from pyasic.errors import APIError
|
||||
from pyasic.miners.backends.bmminer import BMMiner
|
||||
from pyasic.miners.backends.cgminer import CGMiner
|
||||
from pyasic.miners.base import BaseMiner
|
||||
from pyasic.miners.data import (
|
||||
DataFunction,
|
||||
DataLocations,
|
||||
@@ -29,6 +30,7 @@ from pyasic.miners.data import (
|
||||
RPCAPICommand,
|
||||
WebAPICommand,
|
||||
)
|
||||
from pyasic.rpc.antminer import AntminerRPCAPI
|
||||
from pyasic.ssh.antminer import AntminerModernSSH
|
||||
from pyasic.web.antminer import AntminerModernWebAPI, AntminerOldWebAPI
|
||||
|
||||
@@ -88,12 +90,16 @@ class AntminerModern(BMMiner):
|
||||
_web_cls = AntminerModernWebAPI
|
||||
web: AntminerModernWebAPI
|
||||
|
||||
_rpc_cls = AntminerRPCAPI
|
||||
web: AntminerRPCAPI
|
||||
|
||||
_ssh_cls = AntminerModernSSH
|
||||
ssh: AntminerModernSSH
|
||||
|
||||
data_locations = ANTMINER_MODERN_DATA_LOC
|
||||
|
||||
supports_shutdown = True
|
||||
supports_power_modes = True
|
||||
|
||||
async def get_config(self) -> MinerConfig:
|
||||
data = await self.web.get_miner_conf()
|
||||
@@ -206,7 +212,7 @@ class AntminerModern(BMMiner):
|
||||
]
|
||||
|
||||
try:
|
||||
rpc_stats = await self.rpc.send_command("stats", new_api=True)
|
||||
rpc_stats = await self.rpc.stats(new_api=True)
|
||||
except APIError:
|
||||
return hashboards
|
||||
|
||||
|
||||
@@ -124,6 +124,7 @@ class Auradine(BaseMiner):
|
||||
data_locations = AURADINE_DATA_LOC
|
||||
|
||||
supports_shutdown = True
|
||||
supports_power_modes = True
|
||||
supports_autotuning = True
|
||||
|
||||
async def fault_light_on(self) -> bool:
|
||||
|
||||
@@ -35,6 +35,7 @@ from pyasic.miners.data import (
|
||||
from pyasic.rpc.bosminer import BOSMinerRPCAPI
|
||||
from pyasic.ssh.braiins_os import BOSMinerSSH
|
||||
from pyasic.web.braiins_os import BOSerWebAPI, BOSMinerWebAPI
|
||||
from pyasic.web.braiins_os.proto.braiins.bos.v1 import SaveAction
|
||||
|
||||
BOSMINER_DATA_LOC = DataLocations(
|
||||
**{
|
||||
@@ -180,16 +181,17 @@ class BOSMiner(BaseMiner):
|
||||
|
||||
async def send_config(self, config: MinerConfig, user_suffix: str = None) -> None:
|
||||
self.config = config
|
||||
parsed_cfg = config.as_bosminer(user_suffix=user_suffix)
|
||||
|
||||
toml_conf = toml.dumps(
|
||||
{
|
||||
"format": {
|
||||
"version": "1.2+",
|
||||
"version": "2.0",
|
||||
"generator": "pyasic",
|
||||
"model": f"{self.make.replace('Miner', 'miner')} {self.raw_model.replace('j', 'J')}",
|
||||
"timestamp": int(time.time()),
|
||||
},
|
||||
**config.as_bosminer(user_suffix=user_suffix),
|
||||
**parsed_cfg,
|
||||
}
|
||||
)
|
||||
try:
|
||||
@@ -199,9 +201,7 @@ class BOSMiner(BaseMiner):
|
||||
|
||||
async with conn:
|
||||
await conn.run("/etc/init.d/bosminer stop")
|
||||
async with conn.start_sftp_client() as sftp:
|
||||
async with sftp.open("/etc/bosminer.toml", "w+") as file:
|
||||
await file.write(toml_conf)
|
||||
await conn.run("echo '" + toml_conf + "' > /etc/bosminer.toml")
|
||||
await conn.run("/etc/init.d/bosminer start")
|
||||
|
||||
async def set_power_limit(self, wattage: int) -> bool:
|
||||
@@ -640,6 +640,8 @@ class BOSer(BaseMiner):
|
||||
_web_cls = BOSerWebAPI
|
||||
web: BOSerWebAPI
|
||||
|
||||
firmware = "BOS+"
|
||||
|
||||
data_locations = BOSER_DATA_LOC
|
||||
|
||||
supports_autotuning = True
|
||||
@@ -691,7 +693,9 @@ class BOSer(BaseMiner):
|
||||
|
||||
async def set_power_limit(self, wattage: int) -> bool:
|
||||
try:
|
||||
result = await self.web.set_power_target(wattage)
|
||||
result = await self.web.set_power_target(
|
||||
wattage, save_action=SaveAction.SAVE_ACTION_SAVE_AND_FORCE_APPLY
|
||||
)
|
||||
except APIError:
|
||||
return False
|
||||
|
||||
|
||||
@@ -119,6 +119,7 @@ class BTMiner(BaseMiner):
|
||||
data_locations = BTMINER_DATA_LOC
|
||||
|
||||
supports_shutdown = True
|
||||
supports_power_modes = True
|
||||
|
||||
async def _reset_rpc_pwd_to_admin(self, pwd: str):
|
||||
try:
|
||||
|
||||
@@ -51,7 +51,7 @@ EPIC_DATA_LOC = DataLocations(
|
||||
"_get_hashboards",
|
||||
[
|
||||
WebAPICommand("web_summary", "summary"),
|
||||
WebAPICommand("web_hashrate", "hashrate"),
|
||||
WebAPICommand("web_capabilities", "capabilities"),
|
||||
],
|
||||
),
|
||||
str(DataOptions.WATTAGE): DataFunction(
|
||||
@@ -74,6 +74,10 @@ EPIC_DATA_LOC = DataLocations(
|
||||
"_get_uptime",
|
||||
[WebAPICommand("web_summary", "summary")],
|
||||
),
|
||||
str(DataOptions.IS_MINING): DataFunction(
|
||||
"_is_mining",
|
||||
[WebAPICommand("web_summary", "summary")],
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
@@ -284,7 +288,7 @@ class ePIC(BaseMiner):
|
||||
return fans
|
||||
|
||||
async def _get_hashboards(
|
||||
self, web_summary: dict = None, web_hashrate: dict = None
|
||||
self, web_summary: dict = None, web_capabilities: dict = None
|
||||
) -> List[HashBoard]:
|
||||
if web_summary is None:
|
||||
try:
|
||||
@@ -292,32 +296,39 @@ class ePIC(BaseMiner):
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
if web_hashrate is not None:
|
||||
if web_capabilities is not None:
|
||||
try:
|
||||
web_hashrate = await self.web.hashrate()
|
||||
web_capabilities = await self.web.capabilities()
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
hb_list = [
|
||||
HashBoard(slot=i, expected_chips=self.expected_chips)
|
||||
for i in range(self.expected_hashboards)
|
||||
]
|
||||
|
||||
if web_summary.get("HBs") is not None:
|
||||
for hb in web_summary["HBs"]:
|
||||
for hr in web_hashrate:
|
||||
if hr["Index"] == hb["Index"]:
|
||||
num_of_chips = len(hr["Data"])
|
||||
hashrate = hb["Hashrate"][0]
|
||||
# Update the Hashboard object
|
||||
hb_list[hr["Index"]].expected_chips = num_of_chips
|
||||
hb_list[hr["Index"]].missing = False
|
||||
hb_list[hr["Index"]].hashrate = round(hashrate / 1000000, 2)
|
||||
hb_list[hr["Index"]].chips = num_of_chips
|
||||
hb_list[hr["Index"]].temp = hb["Temperature"]
|
||||
num_of_chips = web_capabilities["Performance Estimator"]["Chip Count"]
|
||||
hashrate = hb["Hashrate"][0]
|
||||
# Update the Hashboard object
|
||||
hb_list[hb["Index"]].missing = False
|
||||
hb_list[hb["Index"]].hashrate = round(hashrate / 1000000, 2)
|
||||
hb_list[hb["Index"]].chips = num_of_chips
|
||||
hb_list[hb["Index"]].temp = hb["Temperature"]
|
||||
return hb_list
|
||||
|
||||
async def _is_mining(self, *args, **kwargs) -> Optional[bool]:
|
||||
return None
|
||||
async def _is_mining(self, web_summary, *args, **kwargs) -> Optional[bool]:
|
||||
if web_summary is None:
|
||||
try:
|
||||
web_summary = await self.web.summary()
|
||||
except APIError:
|
||||
pass
|
||||
if web_summary is not None:
|
||||
try:
|
||||
op_state = web_summary["Status"]["Operating State"]
|
||||
return not op_state == "Idling"
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
async def _get_uptime(self, web_summary: dict = None) -> Optional[int]:
|
||||
if web_summary is None:
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
from typing import List
|
||||
|
||||
from pyasic.config import MinerConfig
|
||||
from pyasic.config import MinerConfig, MiningModeConfig
|
||||
from pyasic.data import HashBoard
|
||||
from pyasic.errors import APIError
|
||||
from pyasic.logger import logger
|
||||
@@ -74,6 +74,9 @@ class GoldshellMiner(BFGMiner):
|
||||
|
||||
data_locations = GOLDSHELL_DATA_LOC
|
||||
|
||||
supports_shutdown = True
|
||||
supports_power_modes = True
|
||||
|
||||
async def get_config(self) -> MinerConfig:
|
||||
# get pool data
|
||||
try:
|
||||
@@ -96,13 +99,19 @@ class GoldshellMiner(BFGMiner):
|
||||
)
|
||||
|
||||
self.config = config
|
||||
|
||||
cfg = config.as_goldshell(user_suffix=user_suffix)
|
||||
# send them back 1 at a time
|
||||
for pool in config.as_goldshell(user_suffix=user_suffix)["pools"]:
|
||||
for pool in cfg["pools"]:
|
||||
await self.web.newpool(
|
||||
url=pool["url"], user=pool["user"], password=pool["pass"]
|
||||
)
|
||||
|
||||
settings = await self.web.setting()
|
||||
for idx, plan in enumerate(settings["powerplans"]):
|
||||
if plan["level"] == cfg["settings"]["level"]:
|
||||
settings["select"] = idx
|
||||
await self.web.set_setting(settings)
|
||||
|
||||
async def _get_mac(self, web_setting: dict = None) -> str:
|
||||
if web_setting is None:
|
||||
try:
|
||||
@@ -178,3 +187,25 @@ class GoldshellMiner(BFGMiner):
|
||||
logger.error(self, rpc_devdetails)
|
||||
|
||||
return hashboards
|
||||
|
||||
async def stop_mining(self) -> bool:
|
||||
settings = await self.web.setting()
|
||||
mode = MiningModeConfig.sleep()
|
||||
cfg = mode.as_goldshell()
|
||||
level = cfg["settings"]["level"]
|
||||
for idx, plan in enumerate(settings["powerplans"]):
|
||||
if plan["level"] == level:
|
||||
settings["select"] = idx
|
||||
await self.web.set_setting(settings)
|
||||
return True
|
||||
|
||||
async def resume_mining(self) -> bool:
|
||||
settings = await self.web.setting()
|
||||
mode = MiningModeConfig.normal()
|
||||
cfg = mode.as_goldshell()
|
||||
level = cfg["settings"]["level"]
|
||||
for idx, plan in enumerate(settings["powerplans"]):
|
||||
if plan["level"] == level:
|
||||
settings["select"] = idx
|
||||
await self.web.set_setting(settings)
|
||||
return True
|
||||
|
||||
298
pyasic/miners/backends/marathon.py
Normal file
298
pyasic/miners/backends/marathon.py
Normal file
@@ -0,0 +1,298 @@
|
||||
from typing import List, Optional
|
||||
|
||||
from pyasic import MinerConfig
|
||||
from pyasic.config import MiningModeConfig
|
||||
from pyasic.data import Fan, HashBoard
|
||||
from pyasic.errors import APIError
|
||||
from pyasic.miners.base import BaseMiner
|
||||
from pyasic.miners.data import DataFunction, DataLocations, DataOptions, WebAPICommand
|
||||
from pyasic.misc import merge_dicts
|
||||
from pyasic.web.marathon import MaraWebAPI
|
||||
|
||||
MARA_DATA_LOC = DataLocations(
|
||||
**{
|
||||
str(DataOptions.MAC): DataFunction(
|
||||
"_get_mac",
|
||||
[WebAPICommand("web_overview", "overview")],
|
||||
),
|
||||
str(DataOptions.FW_VERSION): DataFunction(
|
||||
"_get_fw_ver",
|
||||
[WebAPICommand("web_overview", "overview")],
|
||||
),
|
||||
str(DataOptions.HOSTNAME): DataFunction(
|
||||
"_get_hostname",
|
||||
[WebAPICommand("web_network_config", "network_config")],
|
||||
),
|
||||
str(DataOptions.HASHRATE): DataFunction(
|
||||
"_get_hashrate",
|
||||
[WebAPICommand("web_brief", "brief")],
|
||||
),
|
||||
str(DataOptions.EXPECTED_HASHRATE): DataFunction(
|
||||
"_get_expected_hashrate",
|
||||
[WebAPICommand("web_brief", "brief")],
|
||||
),
|
||||
str(DataOptions.HASHBOARDS): DataFunction(
|
||||
"_get_hashboards",
|
||||
[WebAPICommand("web_hashboards", "hashboards")],
|
||||
),
|
||||
str(DataOptions.WATTAGE): DataFunction(
|
||||
"_get_wattage",
|
||||
[WebAPICommand("web_brief", "brief")],
|
||||
),
|
||||
str(DataOptions.WATTAGE_LIMIT): DataFunction(
|
||||
"_get_wattage_limit",
|
||||
[WebAPICommand("web_miner_config", "miner_config")],
|
||||
),
|
||||
str(DataOptions.FANS): DataFunction(
|
||||
"_get_fans",
|
||||
[WebAPICommand("web_fans", "fans")],
|
||||
),
|
||||
str(DataOptions.FAULT_LIGHT): DataFunction(
|
||||
"_get_fault_light",
|
||||
[WebAPICommand("web_locate_miner", "locate_miner")],
|
||||
),
|
||||
str(DataOptions.IS_MINING): DataFunction(
|
||||
"_is_mining",
|
||||
[WebAPICommand("web_brief", "brief")],
|
||||
),
|
||||
str(DataOptions.UPTIME): DataFunction(
|
||||
"_get_uptime",
|
||||
[WebAPICommand("web_brief", "brief")],
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class MaraMiner(BaseMiner):
|
||||
_web_cls = MaraWebAPI
|
||||
web: MaraWebAPI
|
||||
|
||||
data_locations = MARA_DATA_LOC
|
||||
|
||||
firmware = "MaraFW"
|
||||
|
||||
async def fault_light_off(self) -> bool:
|
||||
res = await self.web.set_locate_miner(blinking=False)
|
||||
return res.get("blinking") is False
|
||||
|
||||
async def fault_light_on(self) -> bool:
|
||||
res = await self.web.set_locate_miner(blinking=True)
|
||||
return res.get("blinking") is True
|
||||
|
||||
async def get_config(self) -> MinerConfig:
|
||||
data = await self.web.get_miner_config()
|
||||
if data:
|
||||
self.config = MinerConfig.from_mara(data)
|
||||
return self.config
|
||||
|
||||
async def send_config(self, config: MinerConfig, user_suffix: str = None) -> None:
|
||||
data = await self.web.get_miner_config()
|
||||
cfg_data = config.as_mara(user_suffix=user_suffix)
|
||||
merged_cfg = merge_dicts(data, cfg_data)
|
||||
await self.web.set_miner_config(**merged_cfg)
|
||||
|
||||
async def set_power_limit(self, wattage: int) -> bool:
|
||||
cfg = await self.get_config()
|
||||
cfg.mining_mode = MiningModeConfig.power_tuning(wattage)
|
||||
await self.send_config(cfg)
|
||||
return True
|
||||
|
||||
async def stop_mining(self) -> bool:
|
||||
data = await self.web.get_miner_config()
|
||||
data["mode"]["work-mode-selector"] = "Sleep"
|
||||
await self.web.set_miner_config(**data)
|
||||
return True
|
||||
|
||||
async def resume_mining(self) -> bool:
|
||||
data = await self.web.get_miner_config()
|
||||
data["mode"]["work-mode-selector"] = "Auto"
|
||||
await self.web.set_miner_config(**data)
|
||||
return True
|
||||
|
||||
async def reboot(self) -> bool:
|
||||
await self.web.reboot()
|
||||
return True
|
||||
|
||||
async def restart_backend(self) -> bool:
|
||||
await self.web.reload()
|
||||
return True
|
||||
|
||||
async def _get_wattage(self, web_brief: dict = None) -> Optional[int]:
|
||||
if web_brief is None:
|
||||
try:
|
||||
web_brief = await self.web.brief()
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
if web_brief is not None:
|
||||
try:
|
||||
return round(web_brief["power_consumption_estimated"])
|
||||
except LookupError:
|
||||
pass
|
||||
|
||||
async def _is_mining(self, web_brief: dict = None) -> Optional[bool]:
|
||||
if web_brief is None:
|
||||
try:
|
||||
web_brief = await self.web.brief()
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
if web_brief is not None:
|
||||
try:
|
||||
return web_brief["status"] == "Mining"
|
||||
except LookupError:
|
||||
pass
|
||||
|
||||
async def _get_uptime(self, web_brief: dict = None) -> Optional[int]:
|
||||
if web_brief is None:
|
||||
try:
|
||||
web_brief = await self.web.brief()
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
if web_brief is not None:
|
||||
try:
|
||||
return web_brief["elapsed"]
|
||||
except LookupError:
|
||||
pass
|
||||
|
||||
async def _get_hashboards(self, web_hashboards: dict = None) -> List[HashBoard]:
|
||||
hashboards = [
|
||||
HashBoard(slot=i, expected_chips=self.expected_chips)
|
||||
for i in range(self.expected_hashboards)
|
||||
]
|
||||
|
||||
if web_hashboards is None:
|
||||
try:
|
||||
web_hashboards = await self.web.hashboards()
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
if web_hashboards is not None:
|
||||
try:
|
||||
for hb in web_hashboards["hashboards"]:
|
||||
idx = hb["index"]
|
||||
hashboards[idx].hashrate = round(hb["hashrate_average"] / 1000, 2)
|
||||
hashboards[idx].temp = round(
|
||||
sum(hb["temperature_pcb"]) / len(hb["temperature_pcb"]), 2
|
||||
)
|
||||
hashboards[idx].chip_temp = round(
|
||||
sum(hb["temperature_chip"]) / len(hb["temperature_chip"]), 2
|
||||
)
|
||||
hashboards[idx].chips = hb["asic_num"]
|
||||
hashboards[idx].serial_number = hb["serial_number"]
|
||||
hashboards[idx].missing = False
|
||||
except LookupError:
|
||||
pass
|
||||
return hashboards
|
||||
|
||||
async def _get_mac(self, web_overview: dict = None) -> Optional[str]:
|
||||
if web_overview is None:
|
||||
try:
|
||||
web_overview = await self.web.overview()
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
if web_overview is not None:
|
||||
try:
|
||||
return web_overview["mac"].upper()
|
||||
except LookupError:
|
||||
pass
|
||||
|
||||
async def _get_fw_ver(self, web_overview: dict = None) -> Optional[str]:
|
||||
if web_overview is None:
|
||||
try:
|
||||
web_overview = await self.web.overview()
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
if web_overview is not None:
|
||||
try:
|
||||
return web_overview["version_firmware"]
|
||||
except LookupError:
|
||||
pass
|
||||
|
||||
async def _get_hostname(self, web_network_config: dict = None) -> Optional[str]:
|
||||
if web_network_config is None:
|
||||
try:
|
||||
web_network_config = await self.web.get_network_config()
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
if web_network_config is not None:
|
||||
try:
|
||||
return web_network_config["hostname"]
|
||||
except LookupError:
|
||||
pass
|
||||
|
||||
async def _get_hashrate(self, web_brief: dict = None) -> Optional[float]:
|
||||
if web_brief is None:
|
||||
try:
|
||||
web_brief = await self.web.brief()
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
if web_brief is not None:
|
||||
try:
|
||||
return round(web_brief["hashrate_realtime"], 2)
|
||||
except LookupError:
|
||||
pass
|
||||
|
||||
async def _get_fans(self, web_fans: dict = None) -> List[Fan]:
|
||||
if web_fans is None:
|
||||
try:
|
||||
web_fans = await self.web.fans()
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
if web_fans is not None:
|
||||
fans = []
|
||||
for n in range(self.expected_fans):
|
||||
try:
|
||||
fans.append(Fan(web_fans["fans"][n]["current_speed"]))
|
||||
except (IndexError, KeyError):
|
||||
pass
|
||||
return fans
|
||||
return [Fan() for _ in range(self.expected_fans)]
|
||||
|
||||
async def _get_fault_light(self, web_locate_miner: dict = None) -> bool:
|
||||
if web_locate_miner is None:
|
||||
try:
|
||||
web_locate_miner = await self.web.get_locate_miner()
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
if web_locate_miner is not None:
|
||||
try:
|
||||
return web_locate_miner["blinking"]
|
||||
except LookupError:
|
||||
pass
|
||||
return False
|
||||
|
||||
async def _get_expected_hashrate(self, web_brief: dict = None) -> Optional[float]:
|
||||
if web_brief is None:
|
||||
try:
|
||||
web_brief = await self.web.brief()
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
if web_brief is not None:
|
||||
try:
|
||||
return round(web_brief["hashrate_ideal"] / 1000, 2)
|
||||
except LookupError:
|
||||
pass
|
||||
|
||||
async def _get_wattage_limit(
|
||||
self, web_miner_config: dict = None
|
||||
) -> Optional[float]:
|
||||
if web_miner_config is None:
|
||||
try:
|
||||
web_miner_config = await self.web.get_miner_config()
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
if web_miner_config is not None:
|
||||
try:
|
||||
return web_miner_config["mode"]["concorde"]["power-target"]
|
||||
except LookupError:
|
||||
pass
|
||||
@@ -74,6 +74,10 @@ VNISH_DATA_LOC = DataLocations(
|
||||
"_get_uptime",
|
||||
[RPCAPICommand("rpc_stats", "stats")],
|
||||
),
|
||||
str(DataOptions.IS_MINING): DataFunction(
|
||||
"_is_mining",
|
||||
[WebAPICommand("web_summary", "summary")],
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
@@ -84,6 +88,8 @@ class VNish(BMMiner):
|
||||
_web_cls = VNishWebAPI
|
||||
web: VNishWebAPI
|
||||
|
||||
supports_shutdown = True
|
||||
|
||||
firmware = "VNish"
|
||||
|
||||
data_locations = VNISH_DATA_LOC
|
||||
@@ -125,16 +131,6 @@ class VNish(BMMiner):
|
||||
return False
|
||||
|
||||
async def _get_mac(self, web_summary: dict = None) -> str:
|
||||
if web_summary is None:
|
||||
web_info = await self.web.info()
|
||||
|
||||
if web_info is not None:
|
||||
try:
|
||||
mac = web_info["system"]["network_status"]["mac"]
|
||||
return mac
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
if web_summary is not None:
|
||||
try:
|
||||
mac = web_summary["system"]["network_status"]["mac"]
|
||||
@@ -142,6 +138,15 @@ class VNish(BMMiner):
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
web_info = await self.web.info()
|
||||
|
||||
if web_info is not None:
|
||||
try:
|
||||
mac = web_info["system"]["network_status"]["mac"]
|
||||
return mac
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
async def _get_hostname(self, web_summary: dict = None) -> str:
|
||||
if web_summary is None:
|
||||
web_info = await self.web.info()
|
||||
@@ -214,6 +219,20 @@ class VNish(BMMiner):
|
||||
except LookupError:
|
||||
return fw_ver
|
||||
|
||||
async def _is_mining(self, web_summary: dict = None) -> Optional[bool]:
|
||||
if web_summary is None:
|
||||
web_summary = await self.web.summary()
|
||||
|
||||
if web_summary is not None:
|
||||
try:
|
||||
is_mining = not web_summary["miner"]["miner_status"]["miner_state"] in [
|
||||
"stopped",
|
||||
"shutting-down",
|
||||
]
|
||||
return is_mining
|
||||
except LookupError:
|
||||
pass
|
||||
|
||||
async def get_config(self) -> MinerConfig:
|
||||
try:
|
||||
web_settings = await self.web.settings()
|
||||
|
||||
@@ -47,6 +47,7 @@ class MinerProtocol(Protocol):
|
||||
data_locations: DataLocations = None
|
||||
|
||||
supports_shutdown: bool = False
|
||||
supports_power_modes: bool = False
|
||||
supports_autotuning: bool = False
|
||||
|
||||
api_ver: str = None
|
||||
@@ -68,7 +69,12 @@ class MinerProtocol(Protocol):
|
||||
|
||||
@property
|
||||
def model(self) -> str:
|
||||
model_data = [self.raw_model if self.raw_model is not None else "Unknown"]
|
||||
if self.raw_model is not None:
|
||||
model_data = [self.raw_model]
|
||||
elif self.make is not None:
|
||||
model_data = [self.make]
|
||||
else:
|
||||
model_data = ["Unknown"]
|
||||
if self.firmware is not None:
|
||||
model_data.append(f"({self.firmware})")
|
||||
return " ".join(model_data)
|
||||
@@ -461,9 +467,11 @@ class MinerProtocol(Protocol):
|
||||
ip=str(self.ip),
|
||||
make=self.make,
|
||||
model=self.model,
|
||||
expected_chips=self.expected_chips * self.expected_hashboards
|
||||
if self.expected_chips is not None
|
||||
else 0,
|
||||
expected_chips=(
|
||||
self.expected_chips * self.expected_hashboards
|
||||
if self.expected_chips is not None
|
||||
else 0
|
||||
),
|
||||
expected_hashboards=self.expected_hashboards,
|
||||
hashboards=[
|
||||
HashBoard(slot=i, expected_chips=self.expected_chips)
|
||||
|
||||
17
pyasic/miners/blockminer/__init__.py
Normal file
17
pyasic/miners/blockminer/__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 .epic import *
|
||||
17
pyasic/miners/blockminer/epic/__init__.py
Normal file
17
pyasic/miners/blockminer/epic/__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 .blockminer import *
|
||||
20
pyasic/miners/blockminer/epic/blockminer/__init__.py
Normal file
20
pyasic/miners/blockminer/epic/blockminer/__init__.py
Normal file
@@ -0,0 +1,20 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# 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 .blockminer import (
|
||||
ePICBlockMiner520i,
|
||||
ePICBlockMiner720i,
|
||||
)
|
||||
27
pyasic/miners/blockminer/epic/blockminer/blockminer.py
Normal file
27
pyasic/miners/blockminer/epic/blockminer/blockminer.py
Normal file
@@ -0,0 +1,27 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# 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.models import BlockMiner520i
|
||||
from pyasic.miners.models import BlockMiner720i
|
||||
|
||||
|
||||
class ePICBlockMiner520i(ePIC, BlockMiner520i):
|
||||
pass
|
||||
|
||||
|
||||
class ePICBlockMiner720i(ePIC, BlockMiner720i):
|
||||
pass
|
||||
@@ -30,23 +30,13 @@ from pyasic.logger import logger
|
||||
from pyasic.miners.antminer import *
|
||||
from pyasic.miners.auradine import *
|
||||
from pyasic.miners.avalonminer import *
|
||||
from pyasic.miners.backends import (
|
||||
Auradine,
|
||||
AvalonMiner,
|
||||
BMMiner,
|
||||
BOSMiner,
|
||||
BTMiner,
|
||||
GoldshellMiner,
|
||||
Hiveon,
|
||||
Innosilicon,
|
||||
LUXMiner,
|
||||
VNish,
|
||||
ePIC,
|
||||
)
|
||||
from pyasic.miners.backends import *
|
||||
from pyasic.miners.backends.unknown import UnknownMiner
|
||||
from pyasic.miners.base import AnyMiner
|
||||
from pyasic.miners.blockminer import *
|
||||
from pyasic.miners.goldshell import *
|
||||
from pyasic.miners.innosilicon import *
|
||||
from pyasic.miners.makes import *
|
||||
from pyasic.miners.whatsminer import *
|
||||
|
||||
|
||||
@@ -62,11 +52,12 @@ class MinerTypes(enum.Enum):
|
||||
LUX_OS = 8
|
||||
EPIC = 9
|
||||
AURADINE = 10
|
||||
MARATHON = 11
|
||||
|
||||
|
||||
MINER_CLASSES = {
|
||||
MinerTypes.ANTMINER: {
|
||||
None: BMMiner,
|
||||
None: type("AntminerUnknown", (BMMiner, AntMinerMake), {}),
|
||||
"ANTMINER D3": CGMinerD3,
|
||||
"ANTMINER HS3": BMMinerHS3,
|
||||
"ANTMINER L3+": BMMinerL3Plus,
|
||||
@@ -97,11 +88,16 @@ MINER_CLASSES = {
|
||||
"ANTMINER S19 XP": BMMinerS19XP,
|
||||
"ANTMINER S19A": BMMinerS19a,
|
||||
"ANTMINER S19A PRO": BMMinerS19aPro,
|
||||
"ANTMINER S19 HYDRO": BMMinerS19Hydro,
|
||||
"ANTMINER S19 PRO HYD.": BMMinerS19ProHydro,
|
||||
"ANTMINER S19 PRO+ HYD.": BMMinerS19ProPlusHydro,
|
||||
"ANTMINER S19K PRO": BMMinerS19KPro,
|
||||
"ANTMINER T19": BMMinerT19,
|
||||
"ANTMINER S21": BMMinerS21,
|
||||
"ANTMINER T21": BMMinerT21,
|
||||
},
|
||||
MinerTypes.WHATSMINER: {
|
||||
None: BTMiner,
|
||||
None: type("WhatsminerUnknown", (BTMiner, WhatsMinerMake), {}),
|
||||
"M20V10": BTMinerM20V10,
|
||||
"M20SV10": BTMinerM20SV10,
|
||||
"M20SV20": BTMinerM20SV20,
|
||||
@@ -317,7 +313,7 @@ MINER_CLASSES = {
|
||||
"M66SVK40": BTMinerM66SVK40,
|
||||
},
|
||||
MinerTypes.AVALONMINER: {
|
||||
None: AvalonMiner,
|
||||
None: type("AvalonUnknown", (AvalonMiner, AvalonMinerMake), {}),
|
||||
"AVALONMINER 721": CGMinerAvalon721,
|
||||
"AVALONMINER 741": CGMinerAvalon741,
|
||||
"AVALONMINER 761": CGMinerAvalon761,
|
||||
@@ -332,16 +328,18 @@ MINER_CLASSES = {
|
||||
"AVALONMINER 1246": CGMinerAvalon1246,
|
||||
},
|
||||
MinerTypes.INNOSILICON: {
|
||||
None: Innosilicon,
|
||||
None: type("InnosiliconUnknown", (Innosilicon, InnosiliconMake), {}),
|
||||
"T3H+": InnosiliconT3HPlus,
|
||||
"A10X": InnosiliconA10X,
|
||||
},
|
||||
MinerTypes.GOLDSHELL: {
|
||||
None: GoldshellMiner,
|
||||
None: type("GoldshellUnknown", (GoldshellMiner, GoldshellMake), {}),
|
||||
"GOLDSHELL CK5": GoldshellCK5,
|
||||
"GOLDSHELL HS5": GoldshellHS5,
|
||||
"GOLDSHELL KD5": GoldshellKD5,
|
||||
"GOLDSHELL KDMAX": GoldshellKDMax,
|
||||
"GOLDSHELL KDBOXII": GoldshellKDBoxII,
|
||||
"GOLDSHELL KDBOXPRO": GoldshellKDBoxPro,
|
||||
},
|
||||
MinerTypes.BRAIINS_OS: {
|
||||
None: BOSMiner,
|
||||
@@ -361,15 +359,20 @@ MINER_CLASSES = {
|
||||
"ANTMINER S19J": BOSMinerS19j,
|
||||
"ANTMINER S19J88NOPIC": BOSMinerS19jNoPIC,
|
||||
"ANTMINER S19J PRO": BOSMinerS19jPro,
|
||||
"ANTMINER S19J PRO NOPIC": BOSMinerS19jPro,
|
||||
"ANTMINER S19J PRO NOPIC": BOSMinerS19jProNoPIC,
|
||||
"ANTMINER S19J PRO+": BOSMinerS19jProPlus,
|
||||
"ANTMINER S19J PRO PLUS": BOSMinerS19jProPlus,
|
||||
"ANTMINER S19J PRO PLUS NOPIC": BOSMinerS19jProPlusNoPIC,
|
||||
"ANTMINER S19K PRO NOPIC": BOSMinerS19kProNoPIC,
|
||||
"ANTMINER S19XP": BOSMinerS19XP,
|
||||
"ANTMINER S19 XP": BOSMinerS19XP,
|
||||
"ANTMINER T19": BOSMinerT19,
|
||||
"ANTMINER S21": BOSMinerS21,
|
||||
},
|
||||
MinerTypes.VNISH: {
|
||||
None: VNish,
|
||||
"L3+": VnishL3Plus,
|
||||
"ANTMINER L3+": VnishL3Plus,
|
||||
"ANTMINER L7": VnishL7,
|
||||
"ANTMINER S17+": VNishS17Plus,
|
||||
"ANTMINER S17 PRO": VNishS17Pro,
|
||||
"ANTMINER S19": VNishS19,
|
||||
@@ -390,6 +393,10 @@ MINER_CLASSES = {
|
||||
"ANTMINER S19J PRO+": ePICS19jProPlus,
|
||||
"ANTMINER S19K PRO": ePICS19kPro,
|
||||
"ANTMINER S19 XP": ePICS19XP,
|
||||
"ANTMINER S21": ePICS21,
|
||||
"ANTMINER T21": ePICT21,
|
||||
"BLOCKMINER 520I": ePICBlockMiner520i,
|
||||
"BLOCKMINER 720I": ePICBlockMiner720i,
|
||||
},
|
||||
MinerTypes.HIVEON: {
|
||||
None: Hiveon,
|
||||
@@ -398,9 +405,17 @@ MINER_CLASSES = {
|
||||
MinerTypes.LUX_OS: {
|
||||
None: LUXMiner,
|
||||
"ANTMINER S9": LUXMinerS9,
|
||||
"ANTMINER S19": LUXMinerS19,
|
||||
"ANTMINER S19 PRO": LUXMinerS19Pro,
|
||||
"ANTMINER S19J PRO": LUXMinerS19jPro,
|
||||
"ANTMINER S19J PRO+": LUXMinerS19jProPlus,
|
||||
"ANTMINER S19K PRO": LUXMinerS19kPro,
|
||||
"ANTMINER S19 XP": LUXMinerS19XP,
|
||||
"ANTMINER T19": LUXMinerT19,
|
||||
"ANTMINER S21": LUXMinerS21,
|
||||
},
|
||||
MinerTypes.AURADINE: {
|
||||
None: Auradine,
|
||||
None: type("AuradineUnknown", (Auradine, AuradineMake), {}),
|
||||
"AT1500": AuradineFluxAT1500,
|
||||
"AT2860": AuradineFluxAT2860,
|
||||
"AT2880": AuradineFluxAT2880,
|
||||
@@ -409,6 +424,18 @@ MINER_CLASSES = {
|
||||
"AD2500": AuradineFluxAD2500,
|
||||
"AD3500": AuradineFluxAD3500,
|
||||
},
|
||||
MinerTypes.MARATHON: {
|
||||
None: MaraMiner,
|
||||
"ANTMINER S19": MaraS19,
|
||||
"ANTMINER S19 PRO": MaraS19Pro,
|
||||
"ANTMINER S19J": MaraS19j,
|
||||
"ANTMINER S19J88NOPIC": MaraS19jNoPIC,
|
||||
"ANTMINER S19J PRO": MaraS19jPro,
|
||||
"ANTMINER S19 XP": MaraS19XP,
|
||||
"ANTMINER S19K PRO": MaraS19KPro,
|
||||
"ANTMINER S21": MaraS21,
|
||||
"ANTMINER T21": MaraT21,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -484,6 +511,7 @@ class MinerFactory:
|
||||
MinerTypes.HIVEON: self.get_miner_model_hiveon,
|
||||
MinerTypes.LUX_OS: self.get_miner_model_luxos,
|
||||
MinerTypes.AURADINE: self.get_miner_model_auradine,
|
||||
MinerTypes.MARATHON: self.get_miner_model_marathon,
|
||||
}
|
||||
fn = miner_model_fns.get(miner_type)
|
||||
|
||||
@@ -496,7 +524,6 @@ class MinerFactory:
|
||||
)
|
||||
except asyncio.TimeoutError:
|
||||
pass
|
||||
|
||||
miner = self._select_miner_from_classes(
|
||||
ip,
|
||||
miner_type=miner_type,
|
||||
@@ -514,30 +541,26 @@ class MinerFactory:
|
||||
return await concurrent_get_first_result(tasks, lambda x: x is not None)
|
||||
|
||||
async def _get_miner_web(self, ip: str) -> MinerTypes | None:
|
||||
tasks = []
|
||||
try:
|
||||
urls = [f"http://{ip}/", f"https://{ip}/"]
|
||||
async with httpx.AsyncClient(
|
||||
transport=settings.transport(verify=False)
|
||||
) as session:
|
||||
tasks = [
|
||||
asyncio.create_task(self._web_ping(session, url)) for url in urls
|
||||
]
|
||||
urls = [f"http://{ip}/", f"https://{ip}/"]
|
||||
async with httpx.AsyncClient(
|
||||
transport=settings.transport(verify=False)
|
||||
) as session:
|
||||
tasks = [asyncio.create_task(self._web_ping(session, url)) for url in urls]
|
||||
|
||||
text, resp = await concurrent_get_first_result(
|
||||
tasks,
|
||||
lambda x: x[0] is not None
|
||||
and self._parse_web_type(x[0], x[1]) is not None,
|
||||
)
|
||||
if text is not None:
|
||||
return self._parse_web_type(text, resp)
|
||||
except asyncio.CancelledError:
|
||||
for t in tasks:
|
||||
t.cancel()
|
||||
try:
|
||||
await t
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
text, resp = await concurrent_get_first_result(
|
||||
tasks,
|
||||
lambda x: x[0] is not None
|
||||
and self._parse_web_type(x[0], x[1]) is not None,
|
||||
)
|
||||
if text is not None:
|
||||
mtype = self._parse_web_type(text, resp)
|
||||
if mtype == MinerTypes.ANTMINER:
|
||||
# could still be mara
|
||||
auth = httpx.DigestAuth("root", "root")
|
||||
res = await self.send_web_command(ip, "/kaonsu/v1/brief", auth=auth)
|
||||
if res is not None:
|
||||
mtype = MinerTypes.MARATHON
|
||||
return mtype
|
||||
|
||||
@staticmethod
|
||||
async def _web_ping(
|
||||
@@ -585,27 +608,16 @@ class MinerFactory:
|
||||
return MinerTypes.AURADINE
|
||||
|
||||
async def _get_miner_socket(self, ip: str) -> MinerTypes | None:
|
||||
tasks = []
|
||||
try:
|
||||
commands = ["version", "devdetails"]
|
||||
tasks = [
|
||||
asyncio.create_task(self._socket_ping(ip, cmd)) for cmd in commands
|
||||
]
|
||||
commands = ["version", "devdetails"]
|
||||
tasks = [asyncio.create_task(self._socket_ping(ip, cmd)) for cmd in commands]
|
||||
|
||||
data = await concurrent_get_first_result(
|
||||
tasks,
|
||||
lambda x: x is not None and self._parse_socket_type(x) is not None,
|
||||
)
|
||||
if data is not None:
|
||||
d = self._parse_socket_type(data)
|
||||
return d
|
||||
except asyncio.CancelledError:
|
||||
for t in tasks:
|
||||
t.cancel()
|
||||
try:
|
||||
await t
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
data = await concurrent_get_first_result(
|
||||
tasks,
|
||||
lambda x: x is not None and self._parse_socket_type(x) is not None,
|
||||
)
|
||||
if data is not None:
|
||||
d = self._parse_socket_type(data)
|
||||
return d
|
||||
|
||||
@staticmethod
|
||||
async def _socket_ping(ip: str, cmd: str) -> str | None:
|
||||
@@ -666,9 +678,15 @@ class MinerFactory:
|
||||
return MinerTypes.HIVEON
|
||||
if "LUXMINER" in upper_data:
|
||||
return MinerTypes.LUX_OS
|
||||
if "KAONSU" in upper_data:
|
||||
return MinerTypes.MARATHON
|
||||
if "ANTMINER" in upper_data and "DEVDETAILS" not in upper_data:
|
||||
return MinerTypes.ANTMINER
|
||||
if "INTCHAINS_QOMO" in upper_data:
|
||||
if (
|
||||
"INTCHAINS_QOMO" in upper_data
|
||||
or "KDAMINER" in upper_data
|
||||
or "BFGMINER" in upper_data
|
||||
):
|
||||
return MinerTypes.GOLDSHELL
|
||||
if "AVALON" in upper_data:
|
||||
return MinerTypes.AVALONMINER
|
||||
@@ -892,10 +910,11 @@ class MinerFactory:
|
||||
async def get_miner_model_braiins_os(self, ip: str) -> str | None:
|
||||
sock_json_data = await self.send_api_command(ip, "devdetails")
|
||||
try:
|
||||
miner_model = sock_json_data["DEVDETAILS"][0]["Model"].replace(
|
||||
"Bitmain ", ""
|
||||
miner_model = (
|
||||
sock_json_data["DEVDETAILS"][0]["Model"]
|
||||
.replace("Bitmain ", "")
|
||||
.replace("S19XP", "S19 XP")
|
||||
)
|
||||
|
||||
return miner_model
|
||||
except (TypeError, LookupError):
|
||||
pass
|
||||
@@ -908,7 +927,9 @@ class MinerFactory:
|
||||
)
|
||||
if d.status_code == 200:
|
||||
json_data = d.json()
|
||||
miner_model = json_data["data"]["bosminer"]["info"]["modelName"]
|
||||
miner_model = json_data["data"]["bosminer"]["info"][
|
||||
"modelName"
|
||||
].replace("S19XP", "S19 XP")
|
||||
return miner_model
|
||||
except (httpx.HTTPError, LookupError):
|
||||
pass
|
||||
@@ -932,12 +953,16 @@ class MinerFactory:
|
||||
pass
|
||||
|
||||
async def get_miner_model_epic(self, ip: str) -> str | None:
|
||||
sock_json_data = await self.send_web_command(ip, ":4028/capabilities")
|
||||
try:
|
||||
miner_model = sock_json_data["Model"]
|
||||
return miner_model
|
||||
except (TypeError, LookupError):
|
||||
pass
|
||||
for retry_cnt in range(settings.get("get_data_retries", 1)):
|
||||
sock_json_data = await self.send_web_command(ip, ":4028/capabilities")
|
||||
try:
|
||||
miner_model = sock_json_data["Model"]
|
||||
return miner_model
|
||||
except (TypeError, LookupError):
|
||||
if retry_cnt < settings.get("get_data_retries", 1) - 1:
|
||||
continue
|
||||
else:
|
||||
pass
|
||||
|
||||
async def get_miner_model_hiveon(self, ip: str) -> str | None:
|
||||
sock_json_data = await self.send_api_command(ip, "version")
|
||||
@@ -967,6 +992,21 @@ class MinerFactory:
|
||||
except LookupError:
|
||||
pass
|
||||
|
||||
async def get_miner_model_marathon(self, ip: str) -> str | None:
|
||||
auth = httpx.DigestAuth("root", "root")
|
||||
web_json_data = await self.send_web_command(
|
||||
ip, "/kaonsu/v1/overview", auth=auth
|
||||
)
|
||||
|
||||
try:
|
||||
miner_model = web_json_data["model"]
|
||||
if miner_model == "":
|
||||
return None
|
||||
|
||||
return miner_model
|
||||
except (TypeError, LookupError):
|
||||
pass
|
||||
|
||||
|
||||
miner_factory = MinerFactory()
|
||||
|
||||
|
||||
25
pyasic/miners/goldshell/bfgminer/XBox/KDBox.py
Normal file
25
pyasic/miners/goldshell/bfgminer/XBox/KDBox.py
Normal file
@@ -0,0 +1,25 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# 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 GoldshellMiner
|
||||
from pyasic.miners.models import KDBoxII, KDBoxPro
|
||||
|
||||
|
||||
class GoldshellKDBoxII(GoldshellMiner, KDBoxII):
|
||||
pass
|
||||
|
||||
|
||||
class GoldshellKDBoxPro(GoldshellMiner, KDBoxPro):
|
||||
pass
|
||||
16
pyasic/miners/goldshell/bfgminer/XBox/__init__.py
Normal file
16
pyasic/miners/goldshell/bfgminer/XBox/__init__.py
Normal file
@@ -0,0 +1,16 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# 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 .KDBox import GoldshellKDBoxII, GoldshellKDBoxPro
|
||||
@@ -14,4 +14,5 @@
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
from .X5 import *
|
||||
from .XBox import *
|
||||
from .XMax import *
|
||||
|
||||
@@ -21,22 +21,33 @@ class MinerListenerProtocol(asyncio.Protocol):
|
||||
def __init__(self):
|
||||
self.responses = {}
|
||||
self.transport = None
|
||||
self.new_miner = None
|
||||
|
||||
async def get_new_miner(self):
|
||||
try:
|
||||
while self.new_miner is None:
|
||||
await asyncio.sleep(0)
|
||||
return self.new_miner
|
||||
finally:
|
||||
self.new_miner = None
|
||||
|
||||
def connection_made(self, transport):
|
||||
self.transport = transport
|
||||
|
||||
@staticmethod
|
||||
def datagram_received(data, _addr):
|
||||
def datagram_received(self, data, _addr):
|
||||
if data == b"OK\x00\x00\x00\x00\x00\x00\x00\x00":
|
||||
return
|
||||
m = data.decode()
|
||||
if "," in m:
|
||||
ip, mac = m.split(",")
|
||||
if "/" in ip:
|
||||
ip = ip.replace("[", "").split("/")[0]
|
||||
else:
|
||||
d = m[:-1].split("MAC")
|
||||
ip = d[0][3:]
|
||||
mac = d[1][1:]
|
||||
|
||||
new_miner = {"IP": ip, "MAC": mac.upper()}
|
||||
MinerListener().new_miner = new_miner
|
||||
self.new_miner = {"IP": ip, "MAC": mac.upper()}
|
||||
|
||||
def connection_lost(self, _):
|
||||
pass
|
||||
@@ -45,32 +56,32 @@ class MinerListenerProtocol(asyncio.Protocol):
|
||||
class MinerListener:
|
||||
def __init__(self, bind_addr: str = "0.0.0.0"):
|
||||
self.found_miners = []
|
||||
self.new_miner = None
|
||||
self.stop = False
|
||||
self.stop = asyncio.Event()
|
||||
self.bind_addr = bind_addr
|
||||
|
||||
async def listen(self):
|
||||
self.stop = False
|
||||
|
||||
loop = asyncio.get_running_loop()
|
||||
|
||||
transport_14235, _ = await loop.create_datagram_endpoint(
|
||||
transport_14235, protocol_14235 = await loop.create_datagram_endpoint(
|
||||
MinerListenerProtocol, local_addr=(self.bind_addr, 14235)
|
||||
)
|
||||
transport_8888, _ = await loop.create_datagram_endpoint(
|
||||
transport_8888, protocol_8888 = await loop.create_datagram_endpoint(
|
||||
MinerListenerProtocol, local_addr=(self.bind_addr, 8888)
|
||||
)
|
||||
try:
|
||||
while not self.stop.is_set():
|
||||
tasks = [
|
||||
asyncio.create_task(protocol_14235.get_new_miner()),
|
||||
asyncio.create_task(protocol_8888.get_new_miner()),
|
||||
]
|
||||
await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
|
||||
for t in tasks:
|
||||
if t.done():
|
||||
yield t.result()
|
||||
|
||||
while True:
|
||||
if self.new_miner:
|
||||
yield self.new_miner
|
||||
self.found_miners.append(self.new_miner)
|
||||
self.new_miner = None
|
||||
if self.stop:
|
||||
transport_14235.close()
|
||||
transport_8888.close()
|
||||
break
|
||||
await asyncio.sleep(0)
|
||||
finally:
|
||||
transport_14235.close()
|
||||
transport_8888.close()
|
||||
|
||||
async def cancel(self):
|
||||
self.stop = True
|
||||
|
||||
@@ -39,3 +39,7 @@ class GoldshellMake(BaseMiner):
|
||||
|
||||
class AuradineMake(BaseMiner):
|
||||
make = "Auradine"
|
||||
|
||||
|
||||
class ePICMake(BaseMiner):
|
||||
make = "ePIC"
|
||||
|
||||
@@ -20,3 +20,4 @@ from .avalonminer import *
|
||||
from .goldshell import *
|
||||
from .innosilicon import *
|
||||
from .whatsminer import *
|
||||
from .epic import *
|
||||
|
||||
@@ -89,12 +89,24 @@ class S19jPro(AntMinerMake):
|
||||
expected_fans = 4
|
||||
|
||||
|
||||
class S19jProNoPIC(AntMinerMake):
|
||||
raw_model = "S19j Pro No PIC"
|
||||
expected_chips = 126
|
||||
expected_fans = 4
|
||||
|
||||
|
||||
class S19jProPlus(AntMinerMake):
|
||||
raw_model = "S19j Pro+"
|
||||
expected_chips = 120
|
||||
expected_fans = 4
|
||||
|
||||
|
||||
class S19jProPlusNoPIC(AntMinerMake):
|
||||
raw_model = "S19j Pro+ No PIC"
|
||||
expected_chips = 120
|
||||
expected_fans = 4
|
||||
|
||||
|
||||
class S19kPro(AntMinerMake):
|
||||
raw_model = "S19k Pro"
|
||||
expected_chips = 77
|
||||
@@ -113,8 +125,28 @@ class S19kProNoPIC(AntMinerMake):
|
||||
expected_fans = 4
|
||||
|
||||
|
||||
class S19Hydro(AntMinerMake):
|
||||
raw_model = "S19 Hydro"
|
||||
expected_chips = 104
|
||||
expected_hashboards = 4
|
||||
expected_fans = 0
|
||||
|
||||
|
||||
class S19ProHydro(AntMinerMake):
|
||||
raw_model = "S19 Pro Hydro"
|
||||
expected_chips = 180
|
||||
expected_hashboards = 4
|
||||
expected_fans = 0
|
||||
|
||||
|
||||
class S19ProPlusHydro(AntMinerMake):
|
||||
raw_model = "S19 Pro+ Hydro"
|
||||
expected_chips = 180
|
||||
expected_hashboards = 4
|
||||
expected_fans = 0
|
||||
|
||||
|
||||
class S19KPro(AntMinerMake):
|
||||
raw_model = "S19K Pro"
|
||||
expected_chips = 77
|
||||
expected_fans = 4
|
||||
|
||||
@@ -20,17 +20,22 @@ from .S19 import (
|
||||
S19XP,
|
||||
S19a,
|
||||
S19aPro,
|
||||
S19Hydro,
|
||||
S19i,
|
||||
S19j,
|
||||
S19jNoPIC,
|
||||
S19jPro,
|
||||
S19jProNoPIC,
|
||||
S19jProPlus,
|
||||
S19jProPlusNoPIC,
|
||||
S19kPro,
|
||||
S19KPro,
|
||||
S19kProNoPIC,
|
||||
S19NoPIC,
|
||||
S19Plus,
|
||||
S19Pro,
|
||||
S19ProHydro,
|
||||
S19ProPlus,
|
||||
S19ProPlusHydro,
|
||||
)
|
||||
from .T19 import T19
|
||||
|
||||
23
pyasic/miners/models/antminer/X21/S21.py
Normal file
23
pyasic/miners/models/antminer/X21/S21.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 pyasic.miners.makes import AntMinerMake
|
||||
|
||||
|
||||
class S21(AntMinerMake):
|
||||
raw_model = "S21"
|
||||
expected_chips = 108
|
||||
expected_fans = 4
|
||||
23
pyasic/miners/models/antminer/X21/T21.py
Normal file
23
pyasic/miners/models/antminer/X21/T21.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 pyasic.miners.makes import AntMinerMake
|
||||
|
||||
|
||||
class T21(AntMinerMake):
|
||||
raw_model = "T21"
|
||||
expected_chips = 108
|
||||
expected_fans = 4
|
||||
22
pyasic/miners/models/antminer/X21/__init__.py
Normal file
22
pyasic/miners/models/antminer/X21/__init__.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# 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 .S21 import (
|
||||
S21,
|
||||
)
|
||||
from .T21 import (
|
||||
T21,
|
||||
)
|
||||
@@ -20,3 +20,4 @@ from .X9 import *
|
||||
from .X15 import *
|
||||
from .X17 import *
|
||||
from .X19 import *
|
||||
from .X21 import *
|
||||
|
||||
1
pyasic/miners/models/epic/__init__.py
Normal file
1
pyasic/miners/models/epic/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from .blockminer import *
|
||||
1
pyasic/miners/models/epic/blockminer/__init__.py
Normal file
1
pyasic/miners/models/epic/blockminer/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from .blockminer import *
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user