Compare commits
151 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fc77aded28 | ||
|
|
a5cafd1fb8 | ||
|
|
db0444a8eb | ||
|
|
0cab872baf | ||
|
|
7f191eb2fd | ||
|
|
52adc2553b | ||
|
|
de49fd7e95 | ||
|
|
7eb61473a8 | ||
|
|
f6a134342a | ||
|
|
1d67e5ed68 | ||
|
|
7d4aa80966 | ||
|
|
742dde622b | ||
|
|
497aa6a42c | ||
|
|
40ebf42da1 | ||
|
|
2f8aea5285 | ||
|
|
53f545ba13 | ||
|
|
689b34611e | ||
|
|
d55c3f45ef | ||
|
|
5ac533616f | ||
|
|
96ea5f5d16 | ||
|
|
87526f5efc | ||
|
|
d31bafbc0e | ||
|
|
66bae47bb9 | ||
|
|
7a09b66d4e | ||
|
|
de5932184f | ||
|
|
2cba62e050 | ||
|
|
c7520d98e0 | ||
|
|
92e9f7bc08 | ||
|
|
e0becce349 | ||
|
|
a65c4ba215 | ||
|
|
4cd0c3357b | ||
|
|
d5cabf8af5 | ||
|
|
3120de757d | ||
|
|
0b69fe591e | ||
|
|
032288d062 | ||
|
|
1d6618c1c0 | ||
|
|
7126e03f0d | ||
|
|
c27556c809 | ||
|
|
99ff28d3e1 | ||
|
|
8ad6f60757 | ||
|
|
5f67b987a0 | ||
|
|
5842b3c4aa | ||
|
|
e2e1d2f2fd | ||
|
|
dd205c0f06 | ||
|
|
79e247c0cf | ||
|
|
836d045b65 | ||
|
|
2d029b65e6 | ||
|
|
993b7efeef | ||
|
|
7e02a6b932 | ||
|
|
60e38fb8bc | ||
|
|
4fc2757ffa | ||
|
|
c89b25d7c9 | ||
|
|
f2fc354f8c | ||
|
|
0e7eca339c | ||
|
|
5f76cb9f0a | ||
|
|
ed3a4bd32a | ||
|
|
a0a1b68f68 | ||
|
|
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 | ||
|
|
3b2b586420 | ||
|
|
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 | ||
|
|
743823f66e |
@@ -1,16 +1,16 @@
|
|||||||
repos:
|
repos:
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
rev: v4.3.0
|
rev: v4.5.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: trailing-whitespace
|
- id: trailing-whitespace
|
||||||
- id: check-yaml
|
- id: check-yaml
|
||||||
- id: check-added-large-files
|
- id: check-added-large-files
|
||||||
- repo: https://github.com/psf/black
|
- repo: https://github.com/psf/black
|
||||||
rev: 22.6.0
|
rev: 24.3.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: black
|
- id: black
|
||||||
- repo: https://github.com/pycqa/isort
|
- repo: https://github.com/pycqa/isort
|
||||||
rev: 5.10.1
|
rev: 5.13.2
|
||||||
hooks:
|
hooks:
|
||||||
- id: isort
|
- id: isort
|
||||||
name: isort (python)
|
name: isort (python)
|
||||||
|
|||||||
18
README.md
18
README.md
@@ -23,19 +23,33 @@ Welcome to `pyasic`! `pyasic` uses an asynchronous method of communicating with
|
|||||||
## Installation
|
## 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:
|
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
|
- [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-virtualenv](https://github.com/pyenv/pyenv-virtualenv): [pyenv](https://github.com/pyenv/pyenv) plugin for managing virtualenvs
|
||||||
```
|
|
||||||
|
```
|
||||||
pyenv install <python version number>
|
pyenv install <python version number>
|
||||||
pyenv virtualenv <python version number> <env name>
|
pyenv virtualenv <python version number> <env name>
|
||||||
pyenv activate <env name>
|
pyenv activate <env name>
|
||||||
```
|
```
|
||||||
|
|
||||||
- [conda](https://docs.conda.io/en/latest/)
|
- [conda](https://docs.conda.io/en/latest/)
|
||||||
|
|
||||||
##### Installing `pyasic`
|
##### Installing `pyasic`
|
||||||
|
|
||||||
`python -m pip install .` or `poetry install`
|
`python -m pip install .` or `poetry install`
|
||||||
|
|
||||||
|
##### Additional Developer Setup
|
||||||
|
```
|
||||||
|
poetry install --with dev
|
||||||
|
pre-commit install
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
## Getting started
|
## Getting started
|
||||||
|
|
||||||
|
|||||||
@@ -47,8 +47,8 @@ def backend_str(backend: MinerTypes) -> str:
|
|||||||
return "Stock Firmware Goldshells"
|
return "Stock Firmware Goldshells"
|
||||||
case MinerTypes.LUX_OS:
|
case MinerTypes.LUX_OS:
|
||||||
return "LuxOS Firmware Miners"
|
return "LuxOS Firmware Miners"
|
||||||
case MinerTypes.EPIC:
|
case MinerTypes.MARATHON:
|
||||||
return "ePIC Firmware Miners"
|
return "Mara Firmware Miners"
|
||||||
|
|
||||||
|
|
||||||
def create_url_str(mtype: str):
|
def create_url_str(mtype: str):
|
||||||
|
|||||||
@@ -22,13 +22,21 @@ Welcome to `pyasic`! `pyasic` uses an asynchronous method of communicating with
|
|||||||
## Installation
|
## 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:
|
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
|
- [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-virtualenv](https://github.com/pyenv/pyenv-virtualenv): [pyenv](https://github.com/pyenv/pyenv) plugin for managing virtualenvs
|
||||||
```
|
|
||||||
|
```
|
||||||
pyenv install <python version number>
|
pyenv install <python version number>
|
||||||
pyenv virtualenv <python version number> <env name>
|
pyenv virtualenv <python version number> <env name>
|
||||||
pyenv activate <env name>
|
pyenv activate <env name>
|
||||||
```
|
```
|
||||||
|
|
||||||
- [conda](https://docs.conda.io/en/latest/)
|
- [conda](https://docs.conda.io/en/latest/)
|
||||||
|
|
||||||
##### Installing `pyasic`
|
##### Installing `pyasic`
|
||||||
|
|||||||
@@ -106,6 +106,13 @@
|
|||||||
show_root_heading: false
|
show_root_heading: false
|
||||||
heading_level: 4
|
heading_level: 4
|
||||||
|
|
||||||
|
## S19K Pro
|
||||||
|
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19KPro
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
## T19
|
## T19
|
||||||
::: pyasic.miners.antminer.bmminer.X19.T19.BMMinerT19
|
::: pyasic.miners.antminer.bmminer.X19.T19.BMMinerT19
|
||||||
handler: python
|
handler: python
|
||||||
@@ -169,8 +176,8 @@
|
|||||||
show_root_heading: false
|
show_root_heading: false
|
||||||
heading_level: 4
|
heading_level: 4
|
||||||
|
|
||||||
## S19j Pro
|
## S19j Pro No PIC
|
||||||
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19jPro
|
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19jProNoPIC
|
||||||
handler: python
|
handler: python
|
||||||
options:
|
options:
|
||||||
show_root_heading: false
|
show_root_heading: false
|
||||||
@@ -183,6 +190,20 @@
|
|||||||
show_root_heading: false
|
show_root_heading: false
|
||||||
heading_level: 4
|
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
|
## S19k Pro No PIC
|
||||||
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19kProNoPIC
|
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19kProNoPIC
|
||||||
handler: python
|
handler: python
|
||||||
@@ -358,3 +379,52 @@
|
|||||||
show_root_heading: false
|
show_root_heading: false
|
||||||
heading_level: 4
|
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
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,27 @@
|
|||||||
# pyasic
|
# pyasic
|
||||||
## X21 Models
|
## 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)
|
## S21 (ePIC)
|
||||||
::: pyasic.miners.antminer.epic.X21.S21.ePICS21
|
::: pyasic.miners.antminer.epic.X21.S21.ePICS21
|
||||||
handler: python
|
handler: python
|
||||||
@@ -8,6 +29,13 @@
|
|||||||
show_root_heading: false
|
show_root_heading: false
|
||||||
heading_level: 4
|
heading_level: 4
|
||||||
|
|
||||||
|
## T21 (ePIC)
|
||||||
|
::: pyasic.miners.antminer.epic.X21.T21.ePICT21
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
## S21 (LuxOS)
|
## S21 (LuxOS)
|
||||||
::: pyasic.miners.antminer.luxos.X21.S21.LUXMinerS21
|
::: pyasic.miners.antminer.luxos.X21.S21.LUXMinerS21
|
||||||
handler: python
|
handler: python
|
||||||
@@ -15,3 +43,17 @@
|
|||||||
show_root_heading: false
|
show_root_heading: false
|
||||||
heading_level: 4
|
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
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
# pyasic
|
# pyasic
|
||||||
## Miner Factory
|
## 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`.
|
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()`.
|
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
|
heading_level: 4
|
||||||
|
|
||||||
[`AnyMiner`][pyasic.miners.base.AnyMiner] is a placeholder type variable used for typing returns of functions.
|
[`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.
|
and is used to specify a function returning some arbitrary type of miner class instance.
|
||||||
|
|||||||
@@ -81,9 +81,17 @@ details {
|
|||||||
<li><a href="../antminer/X19#s19-hydro">S19 Hydro</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-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#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>
|
<li><a href="../antminer/X19#t19">T19</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</details>
|
</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>
|
</ul>
|
||||||
</details>
|
</details>
|
||||||
<details>
|
<details>
|
||||||
@@ -446,13 +454,21 @@ details {
|
|||||||
<li><a href="../antminer/X19#s19j">S19j</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-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">S19j Pro</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">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#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#s19-xp">S19 XP</a></li>
|
||||||
<li><a href="../antminer/X19#t19">T19</a></li>
|
<li><a href="../antminer/X19#t19">T19</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</details>
|
</details>
|
||||||
|
<details>
|
||||||
|
<summary>X21 Series:</summary>
|
||||||
|
<ul>
|
||||||
|
<li><a href="../antminer/X21#s21">S21</a></li>
|
||||||
|
</ul>
|
||||||
|
</details>
|
||||||
</ul>
|
</ul>
|
||||||
</details>
|
</details>
|
||||||
<details>
|
<details>
|
||||||
@@ -512,12 +528,14 @@ details {
|
|||||||
<summary>X21 Series:</summary>
|
<summary>X21 Series:</summary>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="../antminer/X21#s21-epic">S21 (ePIC)</a></li>
|
<li><a href="../antminer/X21#s21-epic">S21 (ePIC)</a></li>
|
||||||
|
<li><a href="../antminer/X21#t21-epic">T21 (ePIC)</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</details>
|
</details>
|
||||||
<details>
|
<details>
|
||||||
<summary>blockminer Series:</summary>
|
<summary>blockminer Series:</summary>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="../blockminer/blockminer#blockminer-520i-epic">BlockMiner 520i (ePIC)</a></li>
|
<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>
|
</ul>
|
||||||
</details>
|
</details>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -588,4 +606,28 @@ details {
|
|||||||
</ul>
|
</ul>
|
||||||
</details>
|
</details>
|
||||||
</ul>
|
</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>
|
</details>
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
jinja2<3.1.3
|
jinja2<3.1.4
|
||||||
mkdocs
|
mkdocs
|
||||||
mkdocstrings[python]
|
mkdocstrings[python]
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
# pyasic
|
# pyasic
|
||||||
## Miner APIs
|
## Miner RPC APIs
|
||||||
Each miner has a unique API that is used to communicate with it.
|
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 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] 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`.
|
[`BaseMinerRPCAPI`][pyasic.rpc.base.BaseMinerRPCAPI] cannot be instantiated directly, it will raise a `TypeError`.
|
||||||
|
|||||||
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
|
||||||
14
mkdocs.yml
14
mkdocs.yml
@@ -22,6 +22,15 @@ nav:
|
|||||||
- CGMiner: "rpc/cgminer.md"
|
- CGMiner: "rpc/cgminer.md"
|
||||||
- LUXMiner: "rpc/luxminer.md"
|
- LUXMiner: "rpc/luxminer.md"
|
||||||
- Unknown: "rpc/unknown.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:
|
- Backends:
|
||||||
- BMMiner: "miners/backends/bmminer.md"
|
- BMMiner: "miners/backends/bmminer.md"
|
||||||
- BOSMiner: "miners/backends/bosminer.md"
|
- BOSMiner: "miners/backends/bosminer.md"
|
||||||
@@ -50,10 +59,15 @@ nav:
|
|||||||
- Whatsminer M2X: "miners/whatsminer/M2X.md"
|
- Whatsminer M2X: "miners/whatsminer/M2X.md"
|
||||||
- Whatsminer M3X: "miners/whatsminer/M3X.md"
|
- Whatsminer M3X: "miners/whatsminer/M3X.md"
|
||||||
- Whatsminer M5X: "miners/whatsminer/M5X.md"
|
- Whatsminer M5X: "miners/whatsminer/M5X.md"
|
||||||
|
- Whatsminer M6X: "miners/whatsminer/M6X.md"
|
||||||
- Innosilicon T3X: "miners/innosilicon/T3X.md"
|
- Innosilicon T3X: "miners/innosilicon/T3X.md"
|
||||||
- Innosilicon A10X: "miners/innosilicon/A10X.md"
|
- Innosilicon A10X: "miners/innosilicon/A10X.md"
|
||||||
- Goldshell X5: "miners/goldshell/X5.md"
|
- Goldshell X5: "miners/goldshell/X5.md"
|
||||||
- Goldshell XMax: "miners/goldshell/XMax.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"
|
- Base Miner: "miners/base_miner.md"
|
||||||
- Settings:
|
- Settings:
|
||||||
- Settings: "settings/settings.md"
|
- Settings: "settings/settings.md"
|
||||||
|
|||||||
@@ -25,6 +25,9 @@ from pyasic.misc import merge_dicts
|
|||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class MinerConfig:
|
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)
|
pools: PoolConfig = field(default_factory=PoolConfig.default)
|
||||||
fan_mode: FanModeConfig = field(default_factory=FanModeConfig.default)
|
fan_mode: FanModeConfig = field(default_factory=FanModeConfig.default)
|
||||||
temperature: TemperatureConfig = field(default_factory=TemperatureConfig.default)
|
temperature: TemperatureConfig = field(default_factory=TemperatureConfig.default)
|
||||||
@@ -33,10 +36,18 @@ class MinerConfig:
|
|||||||
default_factory=PowerScalingConfig.default
|
default_factory=PowerScalingConfig.default
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def __getitem__(self, item):
|
||||||
|
try:
|
||||||
|
return getattr(self, item)
|
||||||
|
except AttributeError:
|
||||||
|
raise KeyError
|
||||||
|
|
||||||
def as_dict(self) -> dict:
|
def as_dict(self) -> dict:
|
||||||
|
"""Converts the MinerConfig object to a dictionary."""
|
||||||
return asdict(self)
|
return asdict(self)
|
||||||
|
|
||||||
def as_am_modern(self, user_suffix: str = None) -> dict:
|
def as_am_modern(self, user_suffix: str = None) -> dict:
|
||||||
|
"""Generates the configuration in the format suitable for modern Antminers."""
|
||||||
return {
|
return {
|
||||||
**self.fan_mode.as_am_modern(),
|
**self.fan_mode.as_am_modern(),
|
||||||
"freq-level": "100",
|
"freq-level": "100",
|
||||||
@@ -47,6 +58,7 @@ class MinerConfig:
|
|||||||
}
|
}
|
||||||
|
|
||||||
def as_wm(self, user_suffix: str = None) -> dict:
|
def as_wm(self, user_suffix: str = None) -> dict:
|
||||||
|
"""Generates the configuration in the format suitable for Whatsminers."""
|
||||||
return {
|
return {
|
||||||
**self.fan_mode.as_wm(),
|
**self.fan_mode.as_wm(),
|
||||||
**self.mining_mode.as_wm(),
|
**self.mining_mode.as_wm(),
|
||||||
@@ -56,6 +68,7 @@ class MinerConfig:
|
|||||||
}
|
}
|
||||||
|
|
||||||
def as_am_old(self, user_suffix: str = None) -> dict:
|
def as_am_old(self, user_suffix: str = None) -> dict:
|
||||||
|
"""Generates the configuration in the format suitable for old versions of Antminers."""
|
||||||
return {
|
return {
|
||||||
**self.fan_mode.as_am_old(),
|
**self.fan_mode.as_am_old(),
|
||||||
**self.mining_mode.as_am_old(),
|
**self.mining_mode.as_am_old(),
|
||||||
@@ -65,6 +78,7 @@ class MinerConfig:
|
|||||||
}
|
}
|
||||||
|
|
||||||
def as_goldshell(self, user_suffix: str = None) -> dict:
|
def as_goldshell(self, user_suffix: str = None) -> dict:
|
||||||
|
"""Generates the configuration in the format suitable for Goldshell miners."""
|
||||||
return {
|
return {
|
||||||
**self.fan_mode.as_goldshell(),
|
**self.fan_mode.as_goldshell(),
|
||||||
**self.mining_mode.as_goldshell(),
|
**self.mining_mode.as_goldshell(),
|
||||||
@@ -74,6 +88,7 @@ class MinerConfig:
|
|||||||
}
|
}
|
||||||
|
|
||||||
def as_avalon(self, user_suffix: str = None) -> dict:
|
def as_avalon(self, user_suffix: str = None) -> dict:
|
||||||
|
"""Generates the configuration in the format suitable for Avalonminers."""
|
||||||
return {
|
return {
|
||||||
**self.fan_mode.as_avalon(),
|
**self.fan_mode.as_avalon(),
|
||||||
**self.mining_mode.as_avalon(),
|
**self.mining_mode.as_avalon(),
|
||||||
@@ -83,6 +98,7 @@ class MinerConfig:
|
|||||||
}
|
}
|
||||||
|
|
||||||
def as_inno(self, user_suffix: str = None) -> dict:
|
def as_inno(self, user_suffix: str = None) -> dict:
|
||||||
|
"""Generates the configuration in the format suitable for Innosilicon miners."""
|
||||||
return {
|
return {
|
||||||
**self.fan_mode.as_inno(),
|
**self.fan_mode.as_inno(),
|
||||||
**self.mining_mode.as_inno(),
|
**self.mining_mode.as_inno(),
|
||||||
@@ -92,6 +108,7 @@ class MinerConfig:
|
|||||||
}
|
}
|
||||||
|
|
||||||
def as_bosminer(self, user_suffix: str = None) -> dict:
|
def as_bosminer(self, user_suffix: str = None) -> dict:
|
||||||
|
"""Generates the configuration in the bosminer.toml format."""
|
||||||
return {
|
return {
|
||||||
**merge_dicts(self.fan_mode.as_bosminer(), self.temperature.as_bosminer()),
|
**merge_dicts(self.fan_mode.as_bosminer(), self.temperature.as_bosminer()),
|
||||||
**self.mining_mode.as_bosminer(),
|
**self.mining_mode.as_bosminer(),
|
||||||
@@ -100,6 +117,7 @@ class MinerConfig:
|
|||||||
}
|
}
|
||||||
|
|
||||||
def as_boser(self, user_suffix: str = None) -> dict:
|
def as_boser(self, user_suffix: str = None) -> dict:
|
||||||
|
""" "Generates the configuration in the format suitable for BOSer."""
|
||||||
return {
|
return {
|
||||||
**self.fan_mode.as_boser(),
|
**self.fan_mode.as_boser(),
|
||||||
**self.temperature.as_boser(),
|
**self.temperature.as_boser(),
|
||||||
@@ -109,6 +127,7 @@ class MinerConfig:
|
|||||||
}
|
}
|
||||||
|
|
||||||
def as_epic(self, user_suffix: str = None) -> dict:
|
def as_epic(self, user_suffix: str = None) -> dict:
|
||||||
|
"""Generates the configuration in the format suitable for ePIC miners."""
|
||||||
return {
|
return {
|
||||||
**merge_dicts(self.fan_mode.as_epic(), self.temperature.as_epic()),
|
**merge_dicts(self.fan_mode.as_epic(), self.temperature.as_epic()),
|
||||||
**self.mining_mode.as_epic(),
|
**self.mining_mode.as_epic(),
|
||||||
@@ -117,6 +136,7 @@ class MinerConfig:
|
|||||||
}
|
}
|
||||||
|
|
||||||
def as_auradine(self, user_suffix: str = None) -> dict:
|
def as_auradine(self, user_suffix: str = None) -> dict:
|
||||||
|
"""Generates the configuration in the format suitable for Auradine miners."""
|
||||||
return {
|
return {
|
||||||
**self.fan_mode.as_auradine(),
|
**self.fan_mode.as_auradine(),
|
||||||
**self.temperature.as_auradine(),
|
**self.temperature.as_auradine(),
|
||||||
@@ -125,8 +145,18 @@ class MinerConfig:
|
|||||||
**self.power_scaling.as_auradine(),
|
**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
|
@classmethod
|
||||||
def from_dict(cls, dict_conf: dict) -> "MinerConfig":
|
def from_dict(cls, dict_conf: dict) -> "MinerConfig":
|
||||||
|
"""Constructs a MinerConfig object from a dictionary."""
|
||||||
return cls(
|
return cls(
|
||||||
pools=PoolConfig.from_dict(dict_conf.get("pools")),
|
pools=PoolConfig.from_dict(dict_conf.get("pools")),
|
||||||
mining_mode=MiningModeConfig.from_dict(dict_conf.get("mining_mode")),
|
mining_mode=MiningModeConfig.from_dict(dict_conf.get("mining_mode")),
|
||||||
@@ -137,10 +167,12 @@ class MinerConfig:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_api(cls, api_pools: dict) -> "MinerConfig":
|
def from_api(cls, api_pools: dict) -> "MinerConfig":
|
||||||
|
"""Constructs a MinerConfig object from API pool data."""
|
||||||
return cls(pools=PoolConfig.from_api(api_pools))
|
return cls(pools=PoolConfig.from_api(api_pools))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_am_modern(cls, web_conf: dict) -> "MinerConfig":
|
def from_am_modern(cls, web_conf: dict) -> "MinerConfig":
|
||||||
|
"""Constructs a MinerConfig object from web configuration for modern Antminers."""
|
||||||
return cls(
|
return cls(
|
||||||
pools=PoolConfig.from_am_modern(web_conf),
|
pools=PoolConfig.from_am_modern(web_conf),
|
||||||
mining_mode=MiningModeConfig.from_am_modern(web_conf),
|
mining_mode=MiningModeConfig.from_am_modern(web_conf),
|
||||||
@@ -149,18 +181,22 @@ class MinerConfig:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_am_old(cls, web_conf: dict) -> "MinerConfig":
|
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)
|
return cls.from_am_modern(web_conf)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_goldshell(cls, web_conf: dict) -> "MinerConfig":
|
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))
|
return cls(pools=PoolConfig.from_am_modern(web_conf))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_inno(cls, web_pools: list) -> "MinerConfig":
|
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))
|
return cls(pools=PoolConfig.from_inno(web_pools))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_bosminer(cls, toml_conf: dict) -> "MinerConfig":
|
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(
|
return cls(
|
||||||
pools=PoolConfig.from_bosminer(toml_conf),
|
pools=PoolConfig.from_bosminer(toml_conf),
|
||||||
mining_mode=MiningModeConfig.from_bosminer(toml_conf),
|
mining_mode=MiningModeConfig.from_bosminer(toml_conf),
|
||||||
@@ -171,6 +207,7 @@ class MinerConfig:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_boser(cls, grpc_miner_conf: dict) -> "MinerConfig":
|
def from_boser(cls, grpc_miner_conf: dict) -> "MinerConfig":
|
||||||
|
"""Constructs a MinerConfig object from gRPC configuration for BOSer."""
|
||||||
return cls(
|
return cls(
|
||||||
pools=PoolConfig.from_boser(grpc_miner_conf),
|
pools=PoolConfig.from_boser(grpc_miner_conf),
|
||||||
mining_mode=MiningModeConfig.from_boser(grpc_miner_conf),
|
mining_mode=MiningModeConfig.from_boser(grpc_miner_conf),
|
||||||
@@ -181,6 +218,7 @@ class MinerConfig:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_epic(cls, web_conf: dict) -> "MinerConfig":
|
def from_epic(cls, web_conf: dict) -> "MinerConfig":
|
||||||
|
"""Constructs a MinerConfig object from web configuration for ePIC miners."""
|
||||||
return cls(
|
return cls(
|
||||||
pools=PoolConfig.from_epic(web_conf),
|
pools=PoolConfig.from_epic(web_conf),
|
||||||
fan_mode=FanModeConfig.from_epic(web_conf),
|
fan_mode=FanModeConfig.from_epic(web_conf),
|
||||||
@@ -190,6 +228,7 @@ class MinerConfig:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_vnish(cls, web_settings: dict) -> "MinerConfig":
|
def from_vnish(cls, web_settings: dict) -> "MinerConfig":
|
||||||
|
"""Constructs a MinerConfig object from web settings for VNish miners."""
|
||||||
return cls(
|
return cls(
|
||||||
pools=PoolConfig.from_vnish(web_settings),
|
pools=PoolConfig.from_vnish(web_settings),
|
||||||
fan_mode=FanModeConfig.from_vnish(web_settings),
|
fan_mode=FanModeConfig.from_vnish(web_settings),
|
||||||
@@ -199,8 +238,17 @@ class MinerConfig:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_auradine(cls, web_conf: dict) -> "MinerConfig":
|
def from_auradine(cls, web_conf: dict) -> "MinerConfig":
|
||||||
|
"""Constructs a MinerConfig object from web configuration for Auradine miners."""
|
||||||
return cls(
|
return cls(
|
||||||
pools=PoolConfig.from_api(web_conf["pools"]),
|
pools=PoolConfig.from_api(web_conf["pools"]),
|
||||||
fan_mode=FanModeConfig.from_auradine(web_conf["fan"]),
|
fan_mode=FanModeConfig.from_auradine(web_conf["fan"]),
|
||||||
mining_mode=MiningModeConfig.from_auradine(web_conf["mode"]),
|
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:
|
def as_auradine(self) -> dict:
|
||||||
return self.value.as_auradine()
|
return self.value.as_auradine()
|
||||||
|
|
||||||
|
def as_mara(self) -> dict:
|
||||||
|
return self.value.as_mara()
|
||||||
|
|
||||||
def __call__(self, *args, **kwargs):
|
def __call__(self, *args, **kwargs):
|
||||||
return self.value(*args, **kwargs)
|
return self.value(*args, **kwargs)
|
||||||
|
|
||||||
@@ -64,6 +67,13 @@ class MinerConfigOption(Enum):
|
|||||||
def default(cls):
|
def default(cls):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def __getitem__(self, item):
|
||||||
|
try:
|
||||||
|
return getattr(self, item)
|
||||||
|
except AttributeError:
|
||||||
|
raise KeyError
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class MinerConfigValue:
|
class MinerConfigValue:
|
||||||
@@ -106,3 +116,12 @@ class MinerConfigValue:
|
|||||||
|
|
||||||
def as_auradine(self) -> dict:
|
def as_auradine(self) -> dict:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
def as_mara(self) -> dict:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
def __getitem__(self, item):
|
||||||
|
try:
|
||||||
|
return getattr(self, item)
|
||||||
|
except AttributeError:
|
||||||
|
raise KeyError
|
||||||
|
|||||||
@@ -44,11 +44,21 @@ class FanModeNormal(MinerConfigValue):
|
|||||||
cls_conf["minimum_speed"] = web_cooling_settings["fan_min_duty"]
|
cls_conf["minimum_speed"] = web_cooling_settings["fan_min_duty"]
|
||||||
return cls(**cls_conf)
|
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:
|
def as_am_modern(self) -> dict:
|
||||||
return {"bitmain-fan-ctrl": False, "bitmain-fan-pwn": "100"}
|
return {"bitmain-fan-ctrl": False, "bitmain-fan-pwn": "100"}
|
||||||
|
|
||||||
def as_bosminer(self) -> dict:
|
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:
|
def as_epic(self) -> dict:
|
||||||
return {
|
return {
|
||||||
@@ -61,6 +71,15 @@ class FanModeNormal(MinerConfigValue):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def as_mara(self) -> dict:
|
||||||
|
return {
|
||||||
|
"general-config": {"environment-profile": "AirCooling"},
|
||||||
|
"advance-config": {
|
||||||
|
"override-fan-control": False,
|
||||||
|
"fan-fixed-percent": 0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class FanModeManual(MinerConfigValue):
|
class FanModeManual(MinerConfigValue):
|
||||||
@@ -96,7 +115,7 @@ class FanModeManual(MinerConfigValue):
|
|||||||
return cls(**cls_conf)
|
return cls(**cls_conf)
|
||||||
|
|
||||||
def as_am_modern(self) -> dict:
|
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:
|
def as_bosminer(self) -> dict:
|
||||||
return {
|
return {
|
||||||
@@ -110,6 +129,15 @@ class FanModeManual(MinerConfigValue):
|
|||||||
def as_epic(self) -> dict:
|
def as_epic(self) -> dict:
|
||||||
return {"fans": {"Manual": {"speed": self.speed}}}
|
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
|
@dataclass
|
||||||
class FanModeImmersion(MinerConfigValue):
|
class FanModeImmersion(MinerConfigValue):
|
||||||
@@ -120,14 +148,19 @@ class FanModeImmersion(MinerConfigValue):
|
|||||||
return cls()
|
return cls()
|
||||||
|
|
||||||
def as_am_modern(self) -> dict:
|
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:
|
def as_bosminer(self) -> dict:
|
||||||
return {"temp_control": {"mode": "disabled"}}
|
return {
|
||||||
|
"fan_control": {"min_fans": 0},
|
||||||
|
}
|
||||||
|
|
||||||
def as_auradine(self) -> dict:
|
def as_auradine(self) -> dict:
|
||||||
return {"fan": {"percentage": 0}}
|
return {"fan": {"percentage": 0}}
|
||||||
|
|
||||||
|
def as_mara(self) -> dict:
|
||||||
|
return {"general-config": {"environment-profile": "OilImmersionCooling"}}
|
||||||
|
|
||||||
|
|
||||||
class FanModeConfig(MinerConfigOption):
|
class FanModeConfig(MinerConfigOption):
|
||||||
normal = FanModeNormal
|
normal = FanModeNormal
|
||||||
@@ -156,7 +189,10 @@ class FanModeConfig(MinerConfigOption):
|
|||||||
if web_conf.get("bitmain-fan-ctrl") is not None:
|
if web_conf.get("bitmain-fan-ctrl") is not None:
|
||||||
fan_manual = web_conf["bitmain-fan-ctrl"]
|
fan_manual = web_conf["bitmain-fan-ctrl"]
|
||||||
if fan_manual:
|
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:
|
else:
|
||||||
return cls.normal()
|
return cls.normal()
|
||||||
else:
|
else:
|
||||||
@@ -175,20 +211,28 @@ class FanModeConfig(MinerConfigOption):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_bosminer(cls, toml_conf: dict):
|
def from_bosminer(cls, toml_conf: dict):
|
||||||
if toml_conf.get("temp_control") is None:
|
try:
|
||||||
return cls.default()
|
mode = toml_conf["temp_control"]["mode"]
|
||||||
if toml_conf["temp_control"].get("mode") is None:
|
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()
|
return cls.default()
|
||||||
|
|
||||||
mode = toml_conf["temp_control"]["mode"]
|
if min_fans == 0:
|
||||||
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":
|
|
||||||
return cls.immersion()
|
return cls.immersion()
|
||||||
|
return cls.normal(minimum_fans=min_fans)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_vnish(cls, web_settings: dict):
|
def from_vnish(cls, web_settings: dict):
|
||||||
@@ -232,4 +276,18 @@ class FanModeConfig(MinerConfigOption):
|
|||||||
fan_1_target = fan_data["Target"]
|
fan_1_target = fan_data["Target"]
|
||||||
return cls.manual(speed=round((fan_1_target / fan_1_max) * 100))
|
return cls.manual(speed=round((fan_1_target / fan_1_max) * 100))
|
||||||
except LookupError:
|
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()
|
||||||
|
|||||||
@@ -56,6 +56,13 @@ class MiningModeNormal(MinerConfigValue):
|
|||||||
def as_goldshell(self) -> dict:
|
def as_goldshell(self) -> dict:
|
||||||
return {"settings": {"level": 0}}
|
return {"settings": {"level": 0}}
|
||||||
|
|
||||||
|
def as_mara(self) -> dict:
|
||||||
|
return {
|
||||||
|
"mode": {
|
||||||
|
"work-mode-selector": "Stock",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class MiningModeSleep(MinerConfigValue):
|
class MiningModeSleep(MinerConfigValue):
|
||||||
@@ -82,6 +89,13 @@ class MiningModeSleep(MinerConfigValue):
|
|||||||
def as_goldshell(self) -> dict:
|
def as_goldshell(self) -> dict:
|
||||||
return {"settings": {"level": 3}}
|
return {"settings": {"level": 3}}
|
||||||
|
|
||||||
|
def as_mara(self) -> dict:
|
||||||
|
return {
|
||||||
|
"mode": {
|
||||||
|
"work-mode-selector": "Sleep",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class MiningModeLPM(MinerConfigValue):
|
class MiningModeLPM(MinerConfigValue):
|
||||||
@@ -126,6 +140,7 @@ class MiningModeHPM(MinerConfigValue):
|
|||||||
return {"mode": {"mode": "turbo"}}
|
return {"mode": {"mode": "turbo"}}
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
class StandardTuneAlgo(MinerConfigValue):
|
class StandardTuneAlgo(MinerConfigValue):
|
||||||
mode: str = field(init=False, default="standard")
|
mode: str = field(init=False, default="standard")
|
||||||
|
|
||||||
@@ -133,20 +148,23 @@ class StandardTuneAlgo(MinerConfigValue):
|
|||||||
return VOptAlgo().as_epic()
|
return VOptAlgo().as_epic()
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
class VOptAlgo(MinerConfigValue):
|
class VOptAlgo(MinerConfigValue):
|
||||||
mode: str = field(init=False, default="standard")
|
mode: str = field(init=False, default="voltage_optimizer")
|
||||||
|
|
||||||
def as_epic(self) -> str:
|
def as_epic(self) -> str:
|
||||||
return "VoltageOptimizer"
|
return "VoltageOptimizer"
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
class ChipTuneAlgo(MinerConfigValue):
|
class ChipTuneAlgo(MinerConfigValue):
|
||||||
mode: str = field(init=False, default="standard")
|
mode: str = field(init=False, default="chip_tune")
|
||||||
|
|
||||||
def as_epic(self) -> str:
|
def as_epic(self) -> str:
|
||||||
return "ChipTune"
|
return "ChipTune"
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
class TunerAlgo(MinerConfigOption):
|
class TunerAlgo(MinerConfigOption):
|
||||||
standard = StandardTuneAlgo
|
standard = StandardTuneAlgo
|
||||||
voltage_optimizer = VOptAlgo
|
voltage_optimizer = VOptAlgo
|
||||||
@@ -156,6 +174,16 @@ class TunerAlgo(MinerConfigOption):
|
|||||||
def default(cls):
|
def default(cls):
|
||||||
return cls.standard()
|
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
|
@dataclass
|
||||||
class MiningModePowerTune(MinerConfigValue):
|
class MiningModePowerTune(MinerConfigValue):
|
||||||
@@ -169,7 +197,7 @@ class MiningModePowerTune(MinerConfigValue):
|
|||||||
if dict_conf.get("power"):
|
if dict_conf.get("power"):
|
||||||
cls_conf["power"] = dict_conf["power"]
|
cls_conf["power"] = dict_conf["power"]
|
||||||
if dict_conf.get("algo"):
|
if dict_conf.get("algo"):
|
||||||
cls_conf["algo"] = dict_conf["algo"]
|
cls_conf["algo"] = TunerAlgo.from_dict(dict_conf["algo"])
|
||||||
|
|
||||||
return cls(**cls_conf)
|
return cls(**cls_conf)
|
||||||
|
|
||||||
@@ -184,7 +212,10 @@ class MiningModePowerTune(MinerConfigValue):
|
|||||||
return {}
|
return {}
|
||||||
|
|
||||||
def as_bosminer(self) -> dict:
|
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:
|
def as_boser(self) -> dict:
|
||||||
return {
|
return {
|
||||||
@@ -203,22 +234,51 @@ class MiningModePowerTune(MinerConfigValue):
|
|||||||
def as_auradine(self) -> dict:
|
def as_auradine(self) -> dict:
|
||||||
return {"mode": {"mode": "custom", "tune": "power", "power": self.power}}
|
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
|
@dataclass
|
||||||
class MiningModeHashrateTune(MinerConfigValue):
|
class MiningModeHashrateTune(MinerConfigValue):
|
||||||
mode: str = field(init=False, default="hashrate_tuning")
|
mode: str = field(init=False, default="hashrate_tuning")
|
||||||
hashrate: int = None
|
hashrate: int = None
|
||||||
|
throttle_limit: int = None
|
||||||
|
throttle_step: int = None
|
||||||
algo: TunerAlgo = field(default_factory=TunerAlgo.default)
|
algo: TunerAlgo = field(default_factory=TunerAlgo.default)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_dict(cls, dict_conf: dict | None) -> "MiningModeHashrateTune":
|
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("throttle_limit"):
|
||||||
|
cls_conf["throttle_limit"] = dict_conf["throttle_limit"]
|
||||||
|
if dict_conf.get("throttle_step"):
|
||||||
|
cls_conf["throttle_step"] = dict_conf["throttle_step"]
|
||||||
|
if dict_conf.get("algo"):
|
||||||
|
cls_conf["algo"] = TunerAlgo.from_dict(dict_conf["algo"])
|
||||||
|
|
||||||
|
return cls(**cls_conf)
|
||||||
|
|
||||||
def as_am_modern(self) -> dict:
|
def as_am_modern(self) -> dict:
|
||||||
if settings.get("antminer_mining_mode_as_str", False):
|
if settings.get("antminer_mining_mode_as_str", False):
|
||||||
return {"miner-mode": "0"}
|
return {"miner-mode": "0"}
|
||||||
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:
|
def as_boser(self) -> dict:
|
||||||
return {
|
return {
|
||||||
"set_performance_mode": SetPerformanceModeRequest(
|
"set_performance_mode": SetPerformanceModeRequest(
|
||||||
@@ -239,7 +299,28 @@ class MiningModeHashrateTune(MinerConfigValue):
|
|||||||
return {"mode": {"mode": "custom", "tune": "ths", "ths": self.hashrate}}
|
return {"mode": {"mode": "custom", "tune": "ths", "ths": self.hashrate}}
|
||||||
|
|
||||||
def as_epic(self) -> dict:
|
def as_epic(self) -> dict:
|
||||||
return {"ptune": {"algo": self.algo.as_epic(), "target": self.hashrate}}
|
mode = {
|
||||||
|
"ptune": {
|
||||||
|
"algo": self.algo.as_epic(),
|
||||||
|
"target": self.hashrate,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if self.throttle_limit is not None:
|
||||||
|
mode["ptune"]["min_throttle"] = self.throttle_limit
|
||||||
|
if self.throttle_step is not None:
|
||||||
|
mode["ptune"]["throttle_step"] = self.throttle_step
|
||||||
|
return mode
|
||||||
|
|
||||||
|
def as_mara(self) -> dict:
|
||||||
|
return {
|
||||||
|
"mode": {
|
||||||
|
"work-mode-selector": "Auto",
|
||||||
|
"concorde": {
|
||||||
|
"mode-select": "Hashrate",
|
||||||
|
"hash-target": self.hashrate,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@@ -292,6 +373,17 @@ class MiningModeManual(MinerConfigValue):
|
|||||||
}
|
}
|
||||||
return cls(global_freq=freq, global_volt=voltage, boards=boards)
|
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):
|
class MiningModeConfig(MinerConfigOption):
|
||||||
normal = MiningModeNormal
|
normal = MiningModeNormal
|
||||||
@@ -341,13 +433,19 @@ class MiningModeConfig(MinerConfigOption):
|
|||||||
algo_info = web_conf["PerpetualTune"]["Algorithm"]
|
algo_info = web_conf["PerpetualTune"]["Algorithm"]
|
||||||
if algo_info.get("VoltageOptimizer") is not None:
|
if algo_info.get("VoltageOptimizer") is not None:
|
||||||
return cls.hashrate_tuning(
|
return cls.hashrate_tuning(
|
||||||
hashrate=algo_info["VoltageOptimizer"]["Target"],
|
hashrate=algo_info["VoltageOptimizer"].get("Target"),
|
||||||
algo=TunerAlgo.voltage_optimizer,
|
throttle_limit=algo_info["VoltageOptimizer"].get(
|
||||||
|
"Min Throttle Target"
|
||||||
|
),
|
||||||
|
throttle_step=algo_info["VoltageOptimizer"].get(
|
||||||
|
"Throttle Step"
|
||||||
|
),
|
||||||
|
algo=TunerAlgo.voltage_optimizer(),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
return cls.hashrate_tuning(
|
return cls.hashrate_tuning(
|
||||||
hashrate=algo_info["ChipTune"]["Target"],
|
hashrate=algo_info["ChipTune"]["Target"],
|
||||||
algo=TunerAlgo.chip_tune,
|
algo=TunerAlgo.chip_tune(),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
return cls.normal()
|
return cls.normal()
|
||||||
@@ -440,3 +538,28 @@ class MiningModeConfig(MinerConfigOption):
|
|||||||
return cls.power_tuning(mode_data["Power"])
|
return cls.power_tuning(mode_data["Power"])
|
||||||
except LookupError:
|
except LookupError:
|
||||||
return cls.default()
|
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}
|
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
|
@classmethod
|
||||||
def from_dict(cls, dict_conf: dict | None) -> "Pool":
|
def from_dict(cls, dict_conf: dict | None) -> "Pool":
|
||||||
return cls(
|
return cls(
|
||||||
@@ -177,6 +186,14 @@ class Pool(MinerConfigValue):
|
|||||||
password=grpc_pool["password"],
|
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
|
@dataclass
|
||||||
class PoolGroup(MinerConfigValue):
|
class PoolGroup(MinerConfigValue):
|
||||||
@@ -264,9 +281,12 @@ class PoolGroup(MinerConfigValue):
|
|||||||
def as_auradine(self, user_suffix: str = None) -> list:
|
def as_auradine(self, user_suffix: str = None) -> list:
|
||||||
return [p.as_auradine(user_suffix=user_suffix) for p in self.pools]
|
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]
|
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
|
@classmethod
|
||||||
def from_dict(cls, dict_conf: dict | None) -> "PoolGroup":
|
def from_dict(cls, dict_conf: dict | None) -> "PoolGroup":
|
||||||
cls_conf = {}
|
cls_conf = {}
|
||||||
@@ -336,6 +356,10 @@ class PoolGroup(MinerConfigValue):
|
|||||||
except LookupError:
|
except LookupError:
|
||||||
return cls()
|
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
|
@dataclass
|
||||||
class PoolConfig(MinerConfigValue):
|
class PoolConfig(MinerConfigValue):
|
||||||
@@ -427,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
|
@classmethod
|
||||||
def from_api(cls, api_pools: dict) -> "PoolConfig":
|
def from_api(cls, api_pools: dict) -> "PoolConfig":
|
||||||
try:
|
try:
|
||||||
@@ -481,3 +510,7 @@ class PoolConfig(MinerConfigValue):
|
|||||||
)
|
)
|
||||||
except LookupError:
|
except LookupError:
|
||||||
return cls()
|
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":
|
def from_bosminer(cls, power_scaling_conf: dict) -> "PowerScalingEnabled":
|
||||||
power_step = power_scaling_conf.get("power_step")
|
power_step = power_scaling_conf.get("power_step")
|
||||||
min_power = power_scaling_conf.get("min_psu_power_limit")
|
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)
|
sd_mode = PowerScalingShutdown.from_bosminer(power_scaling_conf)
|
||||||
|
|
||||||
return cls(
|
return cls(
|
||||||
@@ -138,12 +140,12 @@ class PowerScalingEnabled(MinerConfigValue):
|
|||||||
if self.power_step is not None:
|
if self.power_step is not None:
|
||||||
cfg["power_step"] = self.power_step
|
cfg["power_step"] = self.power_step
|
||||||
if self.minimum_power is not None:
|
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:
|
if self.shutdown_enabled is not None:
|
||||||
cfg = {**cfg, **self.shutdown_enabled.as_bosminer()}
|
cfg = {**cfg, **self.shutdown_enabled.as_bosminer()}
|
||||||
|
|
||||||
return {"power_scaling": cfg}
|
return {"performance_scaling": cfg}
|
||||||
|
|
||||||
def as_boser(self) -> dict:
|
def as_boser(self) -> dict:
|
||||||
return {
|
return {
|
||||||
@@ -189,6 +191,8 @@ class PowerScalingConfig(MinerConfigOption):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def from_bosminer(cls, toml_conf: dict):
|
def from_bosminer(cls, toml_conf: dict):
|
||||||
power_scaling = toml_conf.get("power_scaling")
|
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:
|
if power_scaling is not None:
|
||||||
enabled = power_scaling.get("enabled")
|
enabled = power_scaling.get("enabled")
|
||||||
if enabled is not None:
|
if enabled is not None:
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ class TemperatureConfig(MinerConfigValue):
|
|||||||
temp_cfg["hot_temp"] = self.hot
|
temp_cfg["hot_temp"] = self.hot
|
||||||
if self.danger is not None:
|
if self.danger is not None:
|
||||||
temp_cfg["dangerous_temp"] = self.danger
|
temp_cfg["dangerous_temp"] = self.danger
|
||||||
|
if len(temp_cfg) == 0:
|
||||||
|
return {}
|
||||||
return {"temp_control": temp_cfg}
|
return {"temp_control": temp_cfg}
|
||||||
|
|
||||||
def as_epic(self) -> dict:
|
def as_epic(self) -> dict:
|
||||||
@@ -47,7 +49,9 @@ class TemperatureConfig(MinerConfigValue):
|
|||||||
else:
|
else:
|
||||||
temps_config["fans"]["Auto"]["Target Temperature"] = 60
|
temps_config["fans"]["Auto"]["Target Temperature"] = 60
|
||||||
if self.danger is not None:
|
if self.danger is not None:
|
||||||
temps_config["temps"]["shutdown"] = self.danger
|
temps_config["temps"]["critical"] = self.danger
|
||||||
|
if self.hot is not None:
|
||||||
|
temps_config["temps"]["shutdown"] = self.hot
|
||||||
return temps_config
|
return temps_config
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -67,20 +71,25 @@ class TemperatureConfig(MinerConfigValue):
|
|||||||
hot=temp_control.get("hot_temp"),
|
hot=temp_control.get("hot_temp"),
|
||||||
danger=temp_control.get("dangerous_temp"),
|
danger=temp_control.get("dangerous_temp"),
|
||||||
)
|
)
|
||||||
|
return cls()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_epic(cls, web_conf: dict) -> "TemperatureConfig":
|
def from_epic(cls, web_conf: dict) -> "TemperatureConfig":
|
||||||
try:
|
try:
|
||||||
dangerous_temp = web_conf["Misc"]["Shutdown Temp"]
|
dangerous_temp = web_conf["Misc"]["Critical Temp"]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
dangerous_temp = None
|
dangerous_temp = None
|
||||||
|
try:
|
||||||
|
hot_temp = web_conf["Misc"]["Shutdown Temp"]
|
||||||
|
except KeyError:
|
||||||
|
hot_temp = None
|
||||||
# Need to do this in two blocks to avoid KeyError if one is missing
|
# Need to do this in two blocks to avoid KeyError if one is missing
|
||||||
try:
|
try:
|
||||||
target_temp = web_conf["Fans"]["Fan Mode"]["Auto"]["Target Temperature"]
|
target_temp = web_conf["Fans"]["Fan Mode"]["Auto"]["Target Temperature"]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
target_temp = None
|
target_temp = None
|
||||||
|
|
||||||
return cls(target=target_temp, danger=dangerous_temp)
|
return cls(target=target_temp, hot=hot_temp, danger=dangerous_temp)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_vnish(cls, web_settings: dict) -> "TemperatureConfig":
|
def from_vnish(cls, web_settings: dict) -> "TemperatureConfig":
|
||||||
|
|||||||
@@ -25,8 +25,10 @@ from pyasic.config import MinerConfig
|
|||||||
from pyasic.config.mining import MiningModePowerTune
|
from pyasic.config.mining import MiningModePowerTune
|
||||||
|
|
||||||
from .boards import HashBoard
|
from .boards import HashBoard
|
||||||
|
from .device import DeviceInfo
|
||||||
from .error_codes import BraiinsOSError, InnosiliconError, WhatsminerError, X19Error
|
from .error_codes import BraiinsOSError, InnosiliconError, WhatsminerError, X19Error
|
||||||
from .fans import Fan
|
from .fans import Fan
|
||||||
|
from .hashrate import AlgoHashRate, HashUnit
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@@ -38,8 +40,11 @@ class MinerData:
|
|||||||
datetime: The time and date this data was generated.
|
datetime: The time and date this data was generated.
|
||||||
uptime: The uptime of the miner in seconds.
|
uptime: The uptime of the miner in seconds.
|
||||||
mac: The MAC address of the miner as a str.
|
mac: The MAC address of the miner as a str.
|
||||||
|
device_info: Info about the device, such as model, make, and firmware.
|
||||||
model: The model of the miner as a str.
|
model: The model of the miner as a str.
|
||||||
make: The make of the miner as a str.
|
make: The make of the miner as a str.
|
||||||
|
firmware: The firmware on the miner as a str.
|
||||||
|
algo: The mining algorithm of the miner as a str.
|
||||||
api_ver: The current api version on the miner as a str.
|
api_ver: The current api version on the miner as a str.
|
||||||
fw_ver: The current firmware version on the miner as a str.
|
fw_ver: The current firmware version on the miner as a str.
|
||||||
hostname: The network hostname of the miner as a str.
|
hostname: The network hostname of the miner as a str.
|
||||||
@@ -50,8 +55,10 @@ class MinerData:
|
|||||||
temperature_avg: The average temperature across the boards. Calculated automatically.
|
temperature_avg: The average temperature across the boards. Calculated automatically.
|
||||||
env_temp: The environment temps as a float.
|
env_temp: The environment temps as a float.
|
||||||
wattage: Current power draw of the miner as an int.
|
wattage: Current power draw of the miner as an int.
|
||||||
|
voltage: Current output voltage of the PSU as an float.
|
||||||
wattage_limit: Power limit of the miner as an int.
|
wattage_limit: Power limit of the miner as an int.
|
||||||
fans: A list of fans on the miner with their speeds.
|
fans: A list of fans on the miner with their speeds.
|
||||||
|
expected_fans: The number of fans expected on a miner.
|
||||||
fan_psu: The speed of the PSU on the fan if the miner collects it.
|
fan_psu: The speed of the PSU on the fan if the miner collects it.
|
||||||
total_chips: The total number of chips on all boards. Calculated automatically.
|
total_chips: The total number of chips on all boards. Calculated automatically.
|
||||||
expected_chips: The expected number of chips in the miner as an int.
|
expected_chips: The expected number of chips in the miner as an int.
|
||||||
@@ -66,38 +73,75 @@ class MinerData:
|
|||||||
is_mining: Whether the miner is mining.
|
is_mining: Whether the miner is mining.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# general
|
||||||
ip: str
|
ip: str
|
||||||
datetime: datetime = None
|
_datetime: datetime = field(repr=False, default=None)
|
||||||
uptime: int = None
|
datetime: str = field(init=False)
|
||||||
|
timestamp: int = field(init=False)
|
||||||
|
|
||||||
|
# about
|
||||||
|
device_info: DeviceInfo = None
|
||||||
|
make: str = field(init=False)
|
||||||
|
model: str = field(init=False)
|
||||||
|
firmware: str = field(init=False)
|
||||||
|
algo: str = field(init=False)
|
||||||
mac: str = None
|
mac: str = None
|
||||||
model: str = None
|
|
||||||
make: str = None
|
|
||||||
api_ver: str = None
|
api_ver: str = None
|
||||||
fw_ver: str = None
|
fw_ver: str = None
|
||||||
hostname: str = None
|
hostname: str = None
|
||||||
hashrate: float = field(init=False)
|
|
||||||
_hashrate: float = field(repr=False, default=None)
|
# hashrate
|
||||||
|
hashrate: AlgoHashRate = field(init=False)
|
||||||
|
_hashrate: AlgoHashRate = field(repr=False, default=None)
|
||||||
|
|
||||||
|
# expected
|
||||||
expected_hashrate: float = None
|
expected_hashrate: float = None
|
||||||
hashboards: List[HashBoard] = field(default_factory=list)
|
|
||||||
expected_hashboards: int = None
|
expected_hashboards: int = None
|
||||||
temperature_avg: int = field(init=False)
|
|
||||||
env_temp: float = None
|
|
||||||
wattage: int = None
|
|
||||||
wattage_limit: int = field(init=False)
|
|
||||||
_wattage_limit: int = field(repr=False, default=None)
|
|
||||||
fans: List[Fan] = field(default_factory=list)
|
|
||||||
fan_psu: int = None
|
|
||||||
total_chips: int = field(init=False)
|
|
||||||
expected_chips: int = None
|
expected_chips: int = None
|
||||||
|
expected_fans: int = None
|
||||||
|
|
||||||
|
# % expected
|
||||||
percent_expected_chips: float = field(init=False)
|
percent_expected_chips: float = field(init=False)
|
||||||
percent_expected_hashrate: float = field(init=False)
|
percent_expected_hashrate: float = field(init=False)
|
||||||
percent_expected_wattage: float = field(init=False)
|
percent_expected_wattage: float = field(init=False)
|
||||||
|
|
||||||
|
# temperature
|
||||||
|
temperature_avg: int = field(init=False)
|
||||||
|
env_temp: float = None
|
||||||
|
|
||||||
|
# power
|
||||||
|
wattage: int = None
|
||||||
|
wattage_limit: int = field(init=False)
|
||||||
|
voltage: float = None
|
||||||
|
_wattage_limit: int = field(repr=False, default=None)
|
||||||
|
|
||||||
|
# fans
|
||||||
|
fans: List[Fan] = field(default_factory=list)
|
||||||
|
fan_psu: int = None
|
||||||
|
|
||||||
|
# boards
|
||||||
|
hashboards: List[HashBoard] = field(default_factory=list)
|
||||||
|
total_chips: int = field(init=False)
|
||||||
nominal: bool = field(init=False)
|
nominal: bool = field(init=False)
|
||||||
|
|
||||||
|
# config
|
||||||
config: MinerConfig = None
|
config: MinerConfig = None
|
||||||
errors: List[Union[WhatsminerError, BraiinsOSError, X19Error, InnosiliconError]] = field(default_factory=list)
|
|
||||||
fault_light: Union[bool, None] = None
|
fault_light: Union[bool, None] = None
|
||||||
efficiency: int = field(init=False)
|
|
||||||
|
# errors
|
||||||
|
errors: List[
|
||||||
|
Union[
|
||||||
|
WhatsminerError,
|
||||||
|
BraiinsOSError,
|
||||||
|
X19Error,
|
||||||
|
InnosiliconError,
|
||||||
|
]
|
||||||
|
] = field(default_factory=list)
|
||||||
|
|
||||||
|
# mining state
|
||||||
is_mining: bool = True
|
is_mining: bool = True
|
||||||
|
uptime: int = None
|
||||||
|
efficiency: int = field(init=False)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def fields(cls):
|
def fields(cls):
|
||||||
@@ -108,7 +152,7 @@ class MinerData:
|
|||||||
return {k: v for (k, v) in x if not k.startswith("_")}
|
return {k: v for (k, v) in x if not k.startswith("_")}
|
||||||
|
|
||||||
def __post_init__(self):
|
def __post_init__(self):
|
||||||
self.datetime = datetime.now(timezone.utc).astimezone()
|
self._datetime = datetime.now(timezone.utc).astimezone()
|
||||||
|
|
||||||
def get(self, __key: str, default: Any = None):
|
def get(self, __key: str, default: Any = None):
|
||||||
try:
|
try:
|
||||||
@@ -176,7 +220,7 @@ class MinerData:
|
|||||||
if item.hashrate is not None:
|
if item.hashrate is not None:
|
||||||
hr_data.append(item.hashrate)
|
hr_data.append(item.hashrate)
|
||||||
if len(hr_data) > 0:
|
if len(hr_data) > 0:
|
||||||
return round(sum(hr_data), 2)
|
return sum(hr_data, start=type(hr_data[0])(0))
|
||||||
return self._hashrate
|
return self._hashrate
|
||||||
|
|
||||||
@hashrate.setter
|
@hashrate.setter
|
||||||
@@ -235,9 +279,10 @@ class MinerData:
|
|||||||
def percent_expected_hashrate(self): # noqa - Skip PyCharm inspection
|
def percent_expected_hashrate(self): # noqa - Skip PyCharm inspection
|
||||||
if self.hashrate is None or self.expected_hashrate is None:
|
if self.hashrate is None or self.expected_hashrate is None:
|
||||||
return None
|
return None
|
||||||
if self.hashrate == 0 or self.expected_hashrate == 0:
|
try:
|
||||||
|
return round((self.hashrate / self.expected_hashrate) * 100)
|
||||||
|
except ZeroDivisionError:
|
||||||
return 0
|
return 0
|
||||||
return round((self.hashrate / self.expected_hashrate) * 100)
|
|
||||||
|
|
||||||
@percent_expected_hashrate.setter
|
@percent_expected_hashrate.setter
|
||||||
def percent_expected_hashrate(self, val):
|
def percent_expected_hashrate(self, val):
|
||||||
@@ -247,9 +292,10 @@ class MinerData:
|
|||||||
def percent_expected_wattage(self): # noqa - Skip PyCharm inspection
|
def percent_expected_wattage(self): # noqa - Skip PyCharm inspection
|
||||||
if self.wattage_limit is None or self.wattage is None:
|
if self.wattage_limit is None or self.wattage is None:
|
||||||
return None
|
return None
|
||||||
if self.wattage_limit == 0 or self.wattage == 0:
|
try:
|
||||||
|
return round((self.wattage / self.wattage_limit) * 100)
|
||||||
|
except ZeroDivisionError:
|
||||||
return 0
|
return 0
|
||||||
return round((self.wattage / self.wattage_limit) * 100)
|
|
||||||
|
|
||||||
@percent_expected_wattage.setter
|
@percent_expected_wattage.setter
|
||||||
def percent_expected_wattage(self, val):
|
def percent_expected_wattage(self, val):
|
||||||
@@ -275,14 +321,70 @@ class MinerData:
|
|||||||
def efficiency(self): # noqa - Skip PyCharm inspection
|
def efficiency(self): # noqa - Skip PyCharm inspection
|
||||||
if self.hashrate is None or self.wattage is None:
|
if self.hashrate is None or self.wattage is None:
|
||||||
return None
|
return None
|
||||||
if self.hashrate == 0 or self.wattage == 0:
|
try:
|
||||||
|
return round(self.wattage / float(self.hashrate))
|
||||||
|
except ZeroDivisionError:
|
||||||
return 0
|
return 0
|
||||||
return round(self.wattage / self.hashrate)
|
|
||||||
|
|
||||||
@efficiency.setter
|
@efficiency.setter
|
||||||
def efficiency(self, val):
|
def efficiency(self, val):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@property
|
||||||
|
def datetime(self): # noqa - Skip PyCharm inspection
|
||||||
|
return self._datetime.isoformat()
|
||||||
|
|
||||||
|
@datetime.setter
|
||||||
|
def datetime(self, val):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@property
|
||||||
|
def timestamp(self): # noqa - Skip PyCharm inspection
|
||||||
|
return int(time.mktime(self._datetime.timetuple()))
|
||||||
|
|
||||||
|
@timestamp.setter
|
||||||
|
def timestamp(self, val):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@property
|
||||||
|
def make(self): # noqa - Skip PyCharm inspection
|
||||||
|
if self.device_info.make is not None:
|
||||||
|
return str(self.device_info.make)
|
||||||
|
|
||||||
|
@make.setter
|
||||||
|
def make(self, val):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@property
|
||||||
|
def model(self): # noqa - Skip PyCharm inspection
|
||||||
|
if self.device_info.model is not None:
|
||||||
|
return str(self.device_info.model)
|
||||||
|
|
||||||
|
@model.setter
|
||||||
|
def model(self, val):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@property
|
||||||
|
def firmware(self): # noqa - Skip PyCharm inspection
|
||||||
|
if self.device_info.firmware is not None:
|
||||||
|
return str(self.device_info.firmware)
|
||||||
|
|
||||||
|
@firmware.setter
|
||||||
|
def firmware(self, val):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@property
|
||||||
|
def algo(self): # noqa - Skip PyCharm inspection
|
||||||
|
if self.device_info.algo is not None:
|
||||||
|
return str(self.device_info.algo)
|
||||||
|
|
||||||
|
@algo.setter
|
||||||
|
def algo(self, val):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def keys(self) -> list:
|
||||||
|
return [f.name for f in fields(self)]
|
||||||
|
|
||||||
def asdict(self) -> dict:
|
def asdict(self) -> dict:
|
||||||
return asdict(self, dict_factory=self.dict_factory)
|
return asdict(self, dict_factory=self.dict_factory)
|
||||||
|
|
||||||
@@ -300,9 +402,7 @@ class MinerData:
|
|||||||
Returns:
|
Returns:
|
||||||
A JSON version of this class.
|
A JSON version of this class.
|
||||||
"""
|
"""
|
||||||
data = self.asdict()
|
return json.dumps(self.as_dict())
|
||||||
data["datetime"] = str(int(time.mktime(data["datetime"].timetuple())))
|
|
||||||
return json.dumps(data)
|
|
||||||
|
|
||||||
def as_csv(self) -> str:
|
def as_csv(self) -> str:
|
||||||
"""Get this dataclass as CSV.
|
"""Get this dataclass as CSV.
|
||||||
@@ -311,7 +411,6 @@ class MinerData:
|
|||||||
A CSV version of this class with no headers.
|
A CSV version of this class with no headers.
|
||||||
"""
|
"""
|
||||||
data = self.asdict()
|
data = self.asdict()
|
||||||
data["datetime"] = str(int(time.mktime(data["datetime"].timetuple())))
|
|
||||||
errs = []
|
errs = []
|
||||||
for error in data["errors"]:
|
for error in data["errors"]:
|
||||||
errs.append(error["error_message"])
|
errs.append(error["error_message"])
|
||||||
@@ -376,6 +475,6 @@ class MinerData:
|
|||||||
|
|
||||||
tags_str = ",".join(tag_data)
|
tags_str = ",".join(tag_data)
|
||||||
field_str = ",".join(field_data)
|
field_str = ",".join(field_data)
|
||||||
timestamp = str(int(time.mktime(self.datetime.timetuple()) * 1e9))
|
timestamp = str(self.timestamp * 1e9)
|
||||||
|
|
||||||
return " ".join([tags_str, field_str, timestamp])
|
return " ".join([tags_str, field_str, timestamp])
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
from .hashrate import AlgoHashRate
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class HashBoard:
|
class HashBoard:
|
||||||
@@ -34,7 +36,7 @@ class HashBoard:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
slot: int = 0
|
slot: int = 0
|
||||||
hashrate: float = None
|
hashrate: AlgoHashRate = None
|
||||||
temp: int = None
|
temp: int = None
|
||||||
chip_temp: int = None
|
chip_temp: int = None
|
||||||
chips: int = None
|
chips: int = None
|
||||||
|
|||||||
14
pyasic/data/device.py
Normal file
14
pyasic/data/device.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
from pyasic.device.algorithm import MinerAlgo
|
||||||
|
from pyasic.device.firmware import MinerFirmware
|
||||||
|
from pyasic.device.makes import MinerMake
|
||||||
|
from pyasic.device.models import MinerModel
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class DeviceInfo:
|
||||||
|
make: MinerMake = None
|
||||||
|
model: MinerModel = None
|
||||||
|
firmware: MinerFirmware = None
|
||||||
|
algo: MinerAlgo = None
|
||||||
15
pyasic/data/hashrate/__init__.py
Normal file
15
pyasic/data/hashrate/__init__.py
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
from pyasic.data.hashrate.sha256 import SHA256HashRate
|
||||||
|
from pyasic.device.algorithm.sha256 import SHA256Unit
|
||||||
|
|
||||||
|
|
||||||
|
class AlgoHashRate(Enum):
|
||||||
|
SHA256 = SHA256HashRate
|
||||||
|
|
||||||
|
def __call__(self, *args, **kwargs):
|
||||||
|
return self.value(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class HashUnit:
|
||||||
|
SHA256 = SHA256Unit
|
||||||
54
pyasic/data/hashrate/sha256.py
Normal file
54
pyasic/data/hashrate/sha256.py
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
from pyasic.device.algorithm import MinerAlgo
|
||||||
|
from pyasic.device.algorithm.sha256 import SHA256Unit
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class SHA256HashRate:
|
||||||
|
rate: float
|
||||||
|
unit: SHA256Unit = MinerAlgo.SHA256.unit.default
|
||||||
|
|
||||||
|
def __float__(self):
|
||||||
|
return float(self.rate)
|
||||||
|
|
||||||
|
def __int__(self):
|
||||||
|
return int(self.rate)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"{self.rate} {str(self.unit)}"
|
||||||
|
|
||||||
|
def __round__(self, n: int = None):
|
||||||
|
return round(self.rate, n)
|
||||||
|
|
||||||
|
def __add__(self, other: SHA256HashRate | int | float) -> SHA256HashRate:
|
||||||
|
if isinstance(other, SHA256HashRate):
|
||||||
|
return SHA256HashRate(self.rate + other.into(self.unit).rate, self.unit)
|
||||||
|
return SHA256HashRate(self.rate + other, self.unit)
|
||||||
|
|
||||||
|
def __sub__(self, other: SHA256HashRate | int | float) -> SHA256HashRate:
|
||||||
|
if isinstance(other, SHA256HashRate):
|
||||||
|
return SHA256HashRate(self.rate - other.into(self.unit).rate, self.unit)
|
||||||
|
return SHA256HashRate(self.rate - other, self.unit)
|
||||||
|
|
||||||
|
def __truediv__(self, other: SHA256HashRate | int | float):
|
||||||
|
if isinstance(other, SHA256HashRate):
|
||||||
|
return SHA256HashRate(self.rate / other.into(self.unit).rate, self.unit)
|
||||||
|
return SHA256HashRate(self.rate / other, self.unit)
|
||||||
|
|
||||||
|
def __floordiv__(self, other: SHA256HashRate | int | float):
|
||||||
|
if isinstance(other, SHA256HashRate):
|
||||||
|
return SHA256HashRate(self.rate // other.into(self.unit).rate, self.unit)
|
||||||
|
return SHA256HashRate(self.rate // other, self.unit)
|
||||||
|
|
||||||
|
def __mul__(self, other: SHA256HashRate | int | float):
|
||||||
|
if isinstance(other, SHA256HashRate):
|
||||||
|
return SHA256HashRate(self.rate * other.into(self.unit).rate, self.unit)
|
||||||
|
return SHA256HashRate(self.rate * other, self.unit)
|
||||||
|
|
||||||
|
def into(self, other: SHA256Unit) -> SHA256HashRate:
|
||||||
|
return SHA256HashRate(
|
||||||
|
rate=self.rate / (other.value / self.unit.value), unit=other
|
||||||
|
)
|
||||||
4
pyasic/device/__init__.py
Normal file
4
pyasic/device/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
from .algorithm import MinerAlgo
|
||||||
|
from .firmware import MinerFirmware
|
||||||
|
from .makes import MinerMake
|
||||||
|
from .models import MinerModel
|
||||||
5
pyasic/device/algorithm/__init__.py
Normal file
5
pyasic/device/algorithm/__init__.py
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
from pyasic.device.algorithm.sha256 import SHA256Algo
|
||||||
|
|
||||||
|
|
||||||
|
class MinerAlgo:
|
||||||
|
SHA256 = SHA256Algo
|
||||||
68
pyasic/device/algorithm/sha256.py
Normal file
68
pyasic/device/algorithm/sha256.py
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from enum import IntEnum
|
||||||
|
|
||||||
|
|
||||||
|
class SHA256Unit(IntEnum):
|
||||||
|
H = 1
|
||||||
|
KH = int(H) * 1000
|
||||||
|
MH = int(KH) * 1000
|
||||||
|
GH = int(MH) * 1000
|
||||||
|
TH = int(GH) * 1000
|
||||||
|
PH = int(TH) * 1000
|
||||||
|
EH = int(PH) * 1000
|
||||||
|
ZH = int(EH) * 1000
|
||||||
|
|
||||||
|
default = TH
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
if self.value == self.H:
|
||||||
|
return "H/s"
|
||||||
|
if self.value == self.KH:
|
||||||
|
return "KH/s"
|
||||||
|
if self.value == self.MH:
|
||||||
|
return "MH/s"
|
||||||
|
if self.value == self.GH:
|
||||||
|
return "GH/s"
|
||||||
|
if self.value == self.TH:
|
||||||
|
return "TH/s"
|
||||||
|
if self.value == self.PH:
|
||||||
|
return "PH/s"
|
||||||
|
if self.value == self.EH:
|
||||||
|
return "EH/s"
|
||||||
|
if self.value == self.ZH:
|
||||||
|
return "ZH/s"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_str(cls, value: str):
|
||||||
|
if value == "H":
|
||||||
|
return cls.H
|
||||||
|
elif value == "KH":
|
||||||
|
return cls.KH
|
||||||
|
elif value == "MH":
|
||||||
|
return cls.MH
|
||||||
|
elif value == "GH":
|
||||||
|
return cls.GH
|
||||||
|
elif value == "TH":
|
||||||
|
return cls.TH
|
||||||
|
elif value == "PH":
|
||||||
|
return cls.PH
|
||||||
|
elif value == "EH":
|
||||||
|
return cls.EH
|
||||||
|
elif value == "ZH":
|
||||||
|
return cls.ZH
|
||||||
|
return cls.default
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return str(self)
|
||||||
|
|
||||||
|
|
||||||
|
# make this json serializable
|
||||||
|
class _SHA256Algo(str):
|
||||||
|
unit = SHA256Unit
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "SHA256Algo"
|
||||||
|
|
||||||
|
|
||||||
|
SHA256Algo = _SHA256Algo("SHA256")
|
||||||
27
pyasic/device/firmware.py
Normal file
27
pyasic/device/firmware.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 enum import StrEnum
|
||||||
|
|
||||||
|
|
||||||
|
class MinerFirmware(StrEnum):
|
||||||
|
STOCK = "Stock"
|
||||||
|
BRAIINS_OS = "BOS+"
|
||||||
|
VNISH = "VNish"
|
||||||
|
EPIC = "ePIC"
|
||||||
|
HIVEON = "Hive"
|
||||||
|
LUXOS = "LuxOS"
|
||||||
|
MARATHON = "MaraFW"
|
||||||
27
pyasic/device/makes.py
Normal file
27
pyasic/device/makes.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 enum import StrEnum
|
||||||
|
|
||||||
|
|
||||||
|
class MinerMake(StrEnum):
|
||||||
|
WHATSMINER = "WhatsMiner"
|
||||||
|
ANTMINER = "AntMiner"
|
||||||
|
AVALONMINER = "AvalonMiner"
|
||||||
|
INNOSILICON = "Innosilicon"
|
||||||
|
GOLDSHELL = "Goldshell"
|
||||||
|
AURADINE = "Auradine"
|
||||||
|
EPIC = "ePIC"
|
||||||
318
pyasic/device/models.py
Normal file
318
pyasic/device/models.py
Normal file
@@ -0,0 +1,318 @@
|
|||||||
|
from enum import StrEnum
|
||||||
|
|
||||||
|
|
||||||
|
class AntminerModels(StrEnum):
|
||||||
|
D3 = "D3"
|
||||||
|
HS3 = "HS3"
|
||||||
|
L3Plus = "L3+"
|
||||||
|
DR5 = "DR5"
|
||||||
|
L7 = "L7"
|
||||||
|
E9Pro = "E9Pro"
|
||||||
|
S9 = "S9"
|
||||||
|
S9i = "S9i"
|
||||||
|
S9j = "S9j"
|
||||||
|
T9 = "T9"
|
||||||
|
Z15 = "Z15"
|
||||||
|
S17 = "S17"
|
||||||
|
S17Plus = "S17+"
|
||||||
|
S17Pro = "S17 Pro"
|
||||||
|
S17e = "S17e"
|
||||||
|
T17 = "T17"
|
||||||
|
T17Plus = "T17+"
|
||||||
|
T17e = "T17e"
|
||||||
|
S19 = "S19"
|
||||||
|
S19NoPIC = "S19 No PIC"
|
||||||
|
S19L = "S19L"
|
||||||
|
S19Pro = "S19 Pro"
|
||||||
|
S19j = "S19j"
|
||||||
|
S19i = "S19i"
|
||||||
|
S19Plus = "S19+"
|
||||||
|
S19jNoPIC = "S19j No PIC"
|
||||||
|
S19ProPlus = "S19 Pro+"
|
||||||
|
S19jPro = "S19j Pro"
|
||||||
|
S19jProNoPIC = "S19j Pro No PIC"
|
||||||
|
S19jProPlus = "S19j Pro+"
|
||||||
|
S19jProPlusNoPIC = "S19j Pro+ No PIC"
|
||||||
|
S19XP = "S19 XP"
|
||||||
|
S19a = "S19a"
|
||||||
|
S19aPro = "S19a Pro"
|
||||||
|
S19Hydro = "S19 Hydro"
|
||||||
|
S19ProHydro = "S19 Pro Hydro"
|
||||||
|
S19ProPlusHydro = "S19 Pro+ Hydro"
|
||||||
|
S19KPro = "S19K Pro"
|
||||||
|
S19kPro = "S19k Pro"
|
||||||
|
S19kProNoPIC = "S19k Pro No PIC"
|
||||||
|
T19 = "T19"
|
||||||
|
S21 = "S21"
|
||||||
|
T21 = "T21"
|
||||||
|
|
||||||
|
|
||||||
|
class WhatsminerModels(StrEnum):
|
||||||
|
M20V10 = "M20 V10"
|
||||||
|
M20SV10 = "M20S V10"
|
||||||
|
M20SV20 = "M20S V20"
|
||||||
|
M20SV30 = "M20S V30"
|
||||||
|
M20PV10 = "M20P V10"
|
||||||
|
M20PV30 = "M20P V30"
|
||||||
|
M20SPlusV30 = "M20S+ V30"
|
||||||
|
M21V10 = "M21 V10"
|
||||||
|
M21SV20 = "M21S V20"
|
||||||
|
M21SV60 = "M21S V60"
|
||||||
|
M21SV70 = "M21S V70"
|
||||||
|
M21SPlusV20 = "M21S+ V20"
|
||||||
|
M29V10 = "M29 V10"
|
||||||
|
M30V10 = "M30 V10"
|
||||||
|
M30V20 = "M30 V20"
|
||||||
|
M30KV10 = "M30K V10"
|
||||||
|
M30LV10 = "M30L V10"
|
||||||
|
M30SV10 = "M30S V10"
|
||||||
|
M30SV20 = "M30S V20"
|
||||||
|
M30SV30 = "M30S V30"
|
||||||
|
M30SV40 = "M30S V40"
|
||||||
|
M30SV50 = "M30S V50"
|
||||||
|
M30SV60 = "M30S V60"
|
||||||
|
M30SV70 = "M30S V70"
|
||||||
|
M30SV80 = "M30S V80"
|
||||||
|
M30SVE10 = "M30S VE10"
|
||||||
|
M30SVE20 = "M30S VE20"
|
||||||
|
M30SVE30 = "M30S VE30"
|
||||||
|
M30SVE40 = "M30S VE40"
|
||||||
|
M30SVE50 = "M30S VE50"
|
||||||
|
M30SVE60 = "M30S VE60"
|
||||||
|
M30SVE70 = "M30S VE70"
|
||||||
|
M30SVF10 = "M30S VF10"
|
||||||
|
M30SVF20 = "M30S VF20"
|
||||||
|
M30SVF30 = "M30S VF30"
|
||||||
|
M30SVG10 = "M30S VG10"
|
||||||
|
M30SVG20 = "M30S VG20"
|
||||||
|
M30SVG30 = "M30S VG30"
|
||||||
|
M30SVG40 = "M30S VG40"
|
||||||
|
M30SVH10 = "M30S VH10"
|
||||||
|
M30SVH20 = "M30S VH20"
|
||||||
|
M30SVH30 = "M30S VH30"
|
||||||
|
M30SVH40 = "M30S VH40"
|
||||||
|
M30SVH50 = "M30S VH50"
|
||||||
|
M30SVH60 = "M30S VH60"
|
||||||
|
M30SVI20 = "M30S VI20"
|
||||||
|
M30SPlusV10 = "M30S+ V10"
|
||||||
|
M30SPlusV20 = "M30S+ V20"
|
||||||
|
M30SPlusV30 = "M30S+ V30"
|
||||||
|
M30SPlusV40 = "M30S+ V40"
|
||||||
|
M30SPlusV50 = "M30S+ V50"
|
||||||
|
M30SPlusV60 = "M30S+ V60"
|
||||||
|
M30SPlusV70 = "M30S+ V70"
|
||||||
|
M30SPlusV80 = "M30S+ V80"
|
||||||
|
M30SPlusV90 = "M30S+ V90"
|
||||||
|
M30SPlusV100 = "M30S+ V100"
|
||||||
|
M30SPlusVE30 = "M30S+ VE30"
|
||||||
|
M30SPlusVE40 = "M30S+ VE40"
|
||||||
|
M30SPlusVE50 = "M30S+ VE50"
|
||||||
|
M30SPlusVE60 = "M30S+ VE60"
|
||||||
|
M30SPlusVE70 = "M30S+ VE70"
|
||||||
|
M30SPlusVE80 = "M30S+ VE80"
|
||||||
|
M30SPlusVE90 = "M30S+ VE90"
|
||||||
|
M30SPlusVE100 = "M30S+ VE100"
|
||||||
|
M30SPlusVF20 = "M30S+ VF20"
|
||||||
|
M30SPlusVF30 = "M30S+ VF30"
|
||||||
|
M30SPlusVG20 = "M30S+ VG20"
|
||||||
|
M30SPlusVG30 = "M30S+ VG30"
|
||||||
|
M30SPlusVG40 = "M30S+ VG40"
|
||||||
|
M30SPlusVG50 = "M30S+ VG50"
|
||||||
|
M30SPlusVG60 = "M30S+ VG60"
|
||||||
|
M30SPlusVH10 = "M30S+ VH10"
|
||||||
|
M30SPlusVH20 = "M30S+ VH20"
|
||||||
|
M30SPlusVH30 = "M30S+ VH30"
|
||||||
|
M30SPlusVH40 = "M30S+ VH40"
|
||||||
|
M30SPlusVH50 = "M30S+ VH50"
|
||||||
|
M30SPlusVH60 = "M30S+ VH60"
|
||||||
|
M30SPlusPlusV10 = "M30S++ V10"
|
||||||
|
M30SPlusPlusV20 = "M30S++ V20"
|
||||||
|
M30SPlusPlusVE30 = "M30S++ VE30"
|
||||||
|
M30SPlusPlusVE40 = "M30S++ VE40"
|
||||||
|
M30SPlusPlusVE50 = "M30S++ VE50"
|
||||||
|
M30SPlusPlusVF40 = "M30S++ VF40"
|
||||||
|
M30SPlusPlusVG30 = "M30S++ VG30"
|
||||||
|
M30SPlusPlusVG40 = "M30S++ VG40"
|
||||||
|
M30SPlusPlusVG50 = "M30S++ VG50"
|
||||||
|
M30SPlusPlusVH10 = "M30S++ VH10"
|
||||||
|
M30SPlusPlusVH20 = "M30S++ VH20"
|
||||||
|
M30SPlusPlusVH30 = "M30S++ VH30"
|
||||||
|
M30SPlusPlusVH40 = "M30S++ VH40"
|
||||||
|
M30SPlusPlusVH50 = "M30S++ VH50"
|
||||||
|
M30SPlusPlusVH60 = "M30S++ VH60"
|
||||||
|
M30SPlusPlusVH70 = "M30S++ VH70"
|
||||||
|
M30SPlusPlusVH80 = "M30S++ VH80"
|
||||||
|
M30SPlusPlusVH90 = "M30S++ VH90"
|
||||||
|
M30SPlusPlusVH100 = "M30S++ VH100"
|
||||||
|
M30SPlusPlusVJ20 = "M30S++ VJ20"
|
||||||
|
M30SPlusPlusVJ30 = "M30S++ VJ30"
|
||||||
|
M31V10 = "M31 V10"
|
||||||
|
M31V20 = "M31 V20"
|
||||||
|
M31HV10 = "M31H V10"
|
||||||
|
M31HV40 = "M31H V40"
|
||||||
|
M31LV10 = "M30L V10"
|
||||||
|
M31SV10 = "M31S V10"
|
||||||
|
M31SV20 = "M31S V20"
|
||||||
|
M31SV30 = "M31S V30"
|
||||||
|
M31SV40 = "M31S V40"
|
||||||
|
M31SV50 = "M31S V50"
|
||||||
|
M31SV60 = "M31S V60"
|
||||||
|
M31SV70 = "M31S V70"
|
||||||
|
M31SV80 = "M31S V80"
|
||||||
|
M31SV90 = "M31S V90"
|
||||||
|
M31SVE10 = "M31S VE10"
|
||||||
|
M31SVE20 = "M31S VE20"
|
||||||
|
M31SVE30 = "M31S VE30"
|
||||||
|
M31SEV10 = "M31SE V10"
|
||||||
|
M31SEV20 = "M31SE V20"
|
||||||
|
M31SEV30 = "M31SE V30"
|
||||||
|
M31SPlusV10 = "M31S+ V10"
|
||||||
|
M31SPlusV20 = "M31S+ V20"
|
||||||
|
M31SPlusV30 = "M31S+ V30"
|
||||||
|
M31SPlusV40 = "M31S+ V40"
|
||||||
|
M31SPlusV50 = "M31S+ V50"
|
||||||
|
M31SPlusV60 = "M31S+ V60"
|
||||||
|
M31SPlusV80 = "M31S+ V80"
|
||||||
|
M31SPlusV90 = "M31S+ V90"
|
||||||
|
M31SPlusV100 = "M31S+ V100"
|
||||||
|
M31SPlusVE10 = "M31S+ VE10"
|
||||||
|
M31SPlusVE20 = "M31S+ VE20"
|
||||||
|
M31SPlusVE30 = "M31S+ VE30"
|
||||||
|
M31SPlusVE40 = "M31S+ VE40"
|
||||||
|
M31SPlusVE50 = "M31S+ VE50"
|
||||||
|
M31SPlusVE60 = "M31S+ VE60"
|
||||||
|
M31SPlusVE80 = "M31S+ VE80"
|
||||||
|
M31SPlusVF20 = "M31S+ VF20"
|
||||||
|
M31SPlusVF30 = "M31S+ VF30"
|
||||||
|
M31SPlusVG20 = "M31S+ VG20"
|
||||||
|
M31SPlusVG30 = "M31S+ VG30"
|
||||||
|
M32V10 = "M32 V10"
|
||||||
|
M32V20 = "M32 V20"
|
||||||
|
M32S = "M32S"
|
||||||
|
M33V10 = "M33 V10"
|
||||||
|
M33V20 = "M33 V20"
|
||||||
|
M33V30 = "M33 V30"
|
||||||
|
M33SVG30 = "M33S VG30"
|
||||||
|
M33SPlusVG20 = "M33S+ VG20"
|
||||||
|
M33SPlusVH20 = "M33S+ VH20"
|
||||||
|
M33SPlusVH30 = "M33S+ VH30"
|
||||||
|
M33SPlusPlusVH20 = "M33S++ VH20"
|
||||||
|
M33SPlusPlusVH30 = "M33S++ VH30"
|
||||||
|
M33SPlusPlusVG40 = "M33S++ VG40"
|
||||||
|
M34SPlusVE10 = "M34S+ VE10"
|
||||||
|
M36SVE10 = "M36S VE10"
|
||||||
|
M36SPlusVG30 = "M36S+ VG30"
|
||||||
|
M36SPlusPlusVH30 = "M36S++ VH30"
|
||||||
|
M39V10 = "M39 V10"
|
||||||
|
M39V20 = "M39 V20"
|
||||||
|
M39V30 = "M39 V30"
|
||||||
|
M50VE30 = "M50 VE30"
|
||||||
|
M50VG30 = "M50 VG30"
|
||||||
|
M50VH10 = "M50 VH10"
|
||||||
|
M50VH20 = "M50 VH20"
|
||||||
|
M50VH30 = "M50 VH30"
|
||||||
|
M50VH40 = "M50 VH40"
|
||||||
|
M50VH50 = "M50 VH50"
|
||||||
|
M50VH60 = "M50 VH60"
|
||||||
|
M50VH70 = "M50 VH70"
|
||||||
|
M50VH80 = "M50 VH80"
|
||||||
|
M50VJ10 = "M50 VJ10"
|
||||||
|
M50VJ20 = "M50 VJ20"
|
||||||
|
M50VJ30 = "M50 VJ30"
|
||||||
|
M50SVJ10 = "M50S VJ10"
|
||||||
|
M50SVJ20 = "M50S VJ20"
|
||||||
|
M50SVJ30 = "M50S VJ30"
|
||||||
|
M50SVH10 = "M50S VH10"
|
||||||
|
M50SVH20 = "M50S VH20"
|
||||||
|
M50SVH30 = "M50S VH30"
|
||||||
|
M50SVH40 = "M50S VH40"
|
||||||
|
M50SVH50 = "M50S VH50"
|
||||||
|
M50SPlusVH30 = "M50S+ VH30"
|
||||||
|
M50SPlusVH40 = "M50S+ VH40"
|
||||||
|
M50SPlusVJ30 = "M50S+ VJ30"
|
||||||
|
M50SPlusVK20 = "M50S+ VK20"
|
||||||
|
M50SPlusPlusVK10 = "M50S++ VK10"
|
||||||
|
M50SPlusPlusVK20 = "M50S++ VK20"
|
||||||
|
M50SPlusPlusVK30 = "M50S++ VK30"
|
||||||
|
M53VH30 = "M53 VH30"
|
||||||
|
M53SVH30 = "M53S VH30"
|
||||||
|
M53SVJ40 = "M53S VJ40"
|
||||||
|
M53SPlusVJ30 = "M53S+ VJ30"
|
||||||
|
M53SPlusPlusVK10 = "M53S++ VK10"
|
||||||
|
M56VH30 = "M56 VH30"
|
||||||
|
M56SVH30 = "M56S VH30"
|
||||||
|
M56SPlusVJ30 = "M56S+ VJ30"
|
||||||
|
M59VH30 = "M59 VH30"
|
||||||
|
M60VK10 = "M60 VK10"
|
||||||
|
M60VK20 = "M60 VK20"
|
||||||
|
M60VK30 = "M60 VK30"
|
||||||
|
M60VK40 = "M60 VK40"
|
||||||
|
M60SVK10 = "M60S VK10"
|
||||||
|
M60SVK20 = "M60S VK20"
|
||||||
|
M60SVK30 = "M60S VK30"
|
||||||
|
M60SVK40 = "M60S VK40"
|
||||||
|
M63VK10 = "M63 VK10"
|
||||||
|
M63VK20 = "M63 VK20"
|
||||||
|
M63VK30 = "M63 VK30"
|
||||||
|
M63SVK10 = "M63S VK10"
|
||||||
|
M63SVK20 = "M63S VK20"
|
||||||
|
M63SVK30 = "M63S VK30"
|
||||||
|
M66VK20 = "M66 VK20"
|
||||||
|
M66VK30 = "M66 VK30"
|
||||||
|
M66SVK20 = "M66S VK20"
|
||||||
|
M66SVK30 = "M66S VK30"
|
||||||
|
M66SVK40 = "M66S VK40"
|
||||||
|
|
||||||
|
|
||||||
|
class AvalonminerModels(StrEnum):
|
||||||
|
Avalon721 = "Avalon 721"
|
||||||
|
Avalon741 = "Avalon 741"
|
||||||
|
Avalon761 = "Avalon 761"
|
||||||
|
Avalon821 = "Avalon 821"
|
||||||
|
Avalon841 = "Avalon 841"
|
||||||
|
Avalon851 = "Avalon 851"
|
||||||
|
Avalon921 = "Avalon 921"
|
||||||
|
Avalon1026 = "Avalon 1026"
|
||||||
|
Avalon1047 = "Avalon 1047"
|
||||||
|
Avalon1066 = "Avalon 1066"
|
||||||
|
Avalon1166Pro = "Avalon 1166 Pro"
|
||||||
|
Avalon1246 = "Avalon 1246"
|
||||||
|
|
||||||
|
|
||||||
|
class InnosiliconModels(StrEnum):
|
||||||
|
T3HPlus = "T3H+"
|
||||||
|
A10X = "A10X"
|
||||||
|
|
||||||
|
|
||||||
|
class GoldshellModels(StrEnum):
|
||||||
|
CK5 = "CK5"
|
||||||
|
HS5 = "HS5"
|
||||||
|
KD5 = "KD5"
|
||||||
|
KDMax = "KD Max"
|
||||||
|
KDBoxII = "KD Box II"
|
||||||
|
KDBoxPro = "KD Box Pro"
|
||||||
|
|
||||||
|
|
||||||
|
class ePICModels(StrEnum):
|
||||||
|
BM520i = "BlockMiner 520i"
|
||||||
|
BM720i = "BlockMiner 720i"
|
||||||
|
|
||||||
|
|
||||||
|
class AuradineModels(StrEnum):
|
||||||
|
AT1500 = "AT1500"
|
||||||
|
AT2860 = "AT2860"
|
||||||
|
AT2880 = "AT2880"
|
||||||
|
AI2500 = "AI2500"
|
||||||
|
AI3680 = "AI3680"
|
||||||
|
AD2500 = "AD2500"
|
||||||
|
AD3500 = "AD3500"
|
||||||
|
|
||||||
|
|
||||||
|
class MinerModel:
|
||||||
|
ANTMINER = AntminerModels
|
||||||
|
WHATSMINER = WhatsminerModels
|
||||||
|
AVALONMINER = AvalonminerModels
|
||||||
|
INNOSILICON = InnosiliconModels
|
||||||
|
GOLDSHELL = GoldshellModels
|
||||||
|
AURADINE = AuradineModels
|
||||||
|
EPIC = ePICModels
|
||||||
@@ -20,7 +20,16 @@ from typing import List, Union
|
|||||||
from pyasic.errors import APIError
|
from pyasic.errors import APIError
|
||||||
from pyasic.miners import AnyMiner
|
from pyasic.miners import AnyMiner
|
||||||
from pyasic.miners.backends import AntminerModern, BOSMiner, BTMiner
|
from pyasic.miners.backends import AntminerModern, BOSMiner, BTMiner
|
||||||
from pyasic.miners.models import S9, S17, T17, S17e, S17Plus, S17Pro, T17e, T17Plus
|
from pyasic.miners.device.models import (
|
||||||
|
S9,
|
||||||
|
S17,
|
||||||
|
T17,
|
||||||
|
S17e,
|
||||||
|
S17Plus,
|
||||||
|
S17Pro,
|
||||||
|
T17e,
|
||||||
|
T17Plus,
|
||||||
|
)
|
||||||
|
|
||||||
FAN_USAGE = 50 # 50 W per fan
|
FAN_USAGE = 50 # 50 W per fan
|
||||||
|
|
||||||
|
|||||||
@@ -20,4 +20,5 @@ from .cgminer import *
|
|||||||
from .epic import *
|
from .epic import *
|
||||||
from .hiveon import *
|
from .hiveon import *
|
||||||
from .luxos import *
|
from .luxos import *
|
||||||
|
from .marathon import *
|
||||||
from .vnish import *
|
from .vnish import *
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import AntminerOld
|
from pyasic.miners.backends import AntminerOld
|
||||||
from pyasic.miners.models import S17, S17e, S17Plus, S17Pro
|
from pyasic.miners.device.models import S17, S17e, S17Plus, S17Pro
|
||||||
|
|
||||||
|
|
||||||
class BMMinerS17(AntminerOld, S17):
|
class BMMinerS17(AntminerOld, S17):
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import AntminerOld
|
from pyasic.miners.backends import AntminerOld
|
||||||
from pyasic.miners.models import T17, T17e, T17Plus
|
from pyasic.miners.device.models import T17, T17e, T17Plus
|
||||||
|
|
||||||
|
|
||||||
class BMMinerT17(AntminerOld, T17):
|
class BMMinerT17(AntminerOld, T17):
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import AntminerModern
|
from pyasic.miners.backends import AntminerModern
|
||||||
from pyasic.miners.models import (
|
from pyasic.miners.device.models import (
|
||||||
S19,
|
S19,
|
||||||
S19L,
|
S19L,
|
||||||
S19XP,
|
S19XP,
|
||||||
@@ -26,6 +26,7 @@ from pyasic.miners.models import (
|
|||||||
S19j,
|
S19j,
|
||||||
S19jNoPIC,
|
S19jNoPIC,
|
||||||
S19jPro,
|
S19jPro,
|
||||||
|
S19KPro,
|
||||||
S19Plus,
|
S19Plus,
|
||||||
S19Pro,
|
S19Pro,
|
||||||
S19ProHydro,
|
S19ProHydro,
|
||||||
@@ -92,3 +93,7 @@ class BMMinerS19Hydro(AntminerModern, S19Hydro):
|
|||||||
|
|
||||||
class BMMinerS19ProPlusHydro(AntminerModern, S19ProPlusHydro):
|
class BMMinerS19ProPlusHydro(AntminerModern, S19ProPlusHydro):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class BMMinerS19KPro(AntminerModern, S19KPro):
|
||||||
|
pass
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import AntminerModern
|
from pyasic.miners.backends import AntminerModern
|
||||||
from pyasic.miners.models import T19
|
from pyasic.miners.device.models import T19
|
||||||
|
|
||||||
|
|
||||||
class BMMinerT19(AntminerModern, T19):
|
class BMMinerT19(AntminerModern, T19):
|
||||||
|
|||||||
@@ -30,5 +30,6 @@ from .S19 import (
|
|||||||
BMMinerS19ProPlus,
|
BMMinerS19ProPlus,
|
||||||
BMMinerS19ProPlusHydro,
|
BMMinerS19ProPlusHydro,
|
||||||
BMMinerS19XP,
|
BMMinerS19XP,
|
||||||
|
BMMinerS19KPro,
|
||||||
)
|
)
|
||||||
from .T19 import BMMinerT19
|
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.device.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.device.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
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import AntminerModern
|
from pyasic.miners.backends import AntminerModern
|
||||||
from pyasic.miners.models import HS3
|
from pyasic.miners.device.models import HS3
|
||||||
|
|
||||||
|
|
||||||
class BMMinerHS3(AntminerModern, HS3):
|
class BMMinerHS3(AntminerModern, HS3):
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import AntminerOld
|
from pyasic.miners.backends import AntminerOld
|
||||||
from pyasic.miners.models import L3Plus
|
from pyasic.miners.device.models import L3Plus
|
||||||
|
|
||||||
|
|
||||||
class BMMinerL3Plus(AntminerOld, L3Plus):
|
class BMMinerL3Plus(AntminerOld, L3Plus):
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
# limitations under the License. -
|
# limitations under the License. -
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
from pyasic.miners.backends import AntminerModern
|
from pyasic.miners.backends import AntminerModern
|
||||||
from pyasic.miners.models import L7
|
from pyasic.miners.device.models import L7
|
||||||
|
|
||||||
|
|
||||||
class BMMinerL7(AntminerModern, L7):
|
class BMMinerL7(AntminerModern, L7):
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import AntminerModern
|
from pyasic.miners.backends import AntminerModern
|
||||||
from pyasic.miners.models import E9Pro
|
from pyasic.miners.device.models import E9Pro
|
||||||
|
|
||||||
|
|
||||||
class BMMinerE9Pro(AntminerModern, E9Pro):
|
class BMMinerE9Pro(AntminerModern, E9Pro):
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import BMMiner
|
from pyasic.miners.backends import BMMiner
|
||||||
from pyasic.miners.models import S9, S9i, S9j
|
from pyasic.miners.device.models import S9, S9i, S9j
|
||||||
|
|
||||||
|
|
||||||
class BMMinerS9(BMMiner, S9):
|
class BMMinerS9(BMMiner, S9):
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import BMMiner
|
from pyasic.miners.backends import BMMiner
|
||||||
from pyasic.miners.models import T9
|
from pyasic.miners.device.models import T9
|
||||||
|
|
||||||
|
|
||||||
class BMMinerT9(BMMiner, T9):
|
class BMMinerT9(BMMiner, T9):
|
||||||
|
|||||||
@@ -18,3 +18,4 @@ from .X7 import *
|
|||||||
from .X9 import *
|
from .X9 import *
|
||||||
from .X17 import *
|
from .X17 import *
|
||||||
from .X19 import *
|
from .X19 import *
|
||||||
|
from .X21 import *
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import BOSMiner
|
from pyasic.miners.backends import BOSMiner
|
||||||
from pyasic.miners.models import S17, S17e, S17Plus, S17Pro
|
from pyasic.miners.device.models import S17, S17e, S17Plus, S17Pro
|
||||||
|
|
||||||
|
|
||||||
class BOSMinerS17(BOSMiner, S17):
|
class BOSMinerS17(BOSMiner, S17):
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import BOSMiner
|
from pyasic.miners.backends import BOSMiner
|
||||||
from pyasic.miners.models import T17, T17e, T17Plus
|
from pyasic.miners.device.models import T17, T17e, T17Plus
|
||||||
|
|
||||||
|
|
||||||
class BOSMinerT17(BOSMiner, T17):
|
class BOSMinerT17(BOSMiner, T17):
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import BOSer
|
from pyasic.miners.backends import BOSer
|
||||||
from pyasic.miners.models import (
|
from pyasic.miners.device.models import (
|
||||||
S19,
|
S19,
|
||||||
S19XP,
|
S19XP,
|
||||||
S19a,
|
S19a,
|
||||||
@@ -23,7 +23,9 @@ from pyasic.miners.models import (
|
|||||||
S19j,
|
S19j,
|
||||||
S19jNoPIC,
|
S19jNoPIC,
|
||||||
S19jPro,
|
S19jPro,
|
||||||
|
S19jProNoPIC,
|
||||||
S19jProPlus,
|
S19jProPlus,
|
||||||
|
S19jProPlusNoPIC,
|
||||||
S19kProNoPIC,
|
S19kProNoPIC,
|
||||||
S19Plus,
|
S19Plus,
|
||||||
S19Pro,
|
S19Pro,
|
||||||
@@ -58,6 +60,10 @@ class BOSMinerS19jPro(BOSer, S19jPro):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class BOSMinerS19jProNoPIC(BOSer, S19jProNoPIC):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class BOSMinerS19kProNoPIC(BOSer, S19kProNoPIC):
|
class BOSMinerS19kProNoPIC(BOSer, S19kProNoPIC):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -70,5 +76,9 @@ class BOSMinerS19jProPlus(BOSer, S19jProPlus):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class BOSMinerS19jProPlusNoPIC(BOSer, S19jProPlusNoPIC):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class BOSMinerS19XP(BOSer, S19XP):
|
class BOSMinerS19XP(BOSer, S19XP):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import BOSer
|
from pyasic.miners.backends import BOSer
|
||||||
from pyasic.miners.models import T19
|
from pyasic.miners.device.models import T19
|
||||||
|
|
||||||
|
|
||||||
class BOSMinerT19(BOSer, T19):
|
class BOSMinerT19(BOSer, T19):
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ from .S19 import (
|
|||||||
BOSMinerS19j,
|
BOSMinerS19j,
|
||||||
BOSMinerS19jNoPIC,
|
BOSMinerS19jNoPIC,
|
||||||
BOSMinerS19jPro,
|
BOSMinerS19jPro,
|
||||||
|
BOSMinerS19jProNoPIC,
|
||||||
BOSMinerS19jProPlus,
|
BOSMinerS19jProPlus,
|
||||||
|
BOSMinerS19jProPlusNoPIC,
|
||||||
BOSMinerS19kProNoPIC,
|
BOSMinerS19kProNoPIC,
|
||||||
BOSMinerS19Plus,
|
BOSMinerS19Plus,
|
||||||
BOSMinerS19Pro,
|
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.device.models import S21
|
||||||
|
|
||||||
|
|
||||||
|
class BOSMinerS21(BOSer, S21):
|
||||||
|
pass
|
||||||
@@ -14,6 +14,4 @@
|
|||||||
# limitations under the License. -
|
# limitations under the License. -
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from .S21 import (
|
from .S21 import BOSMinerS21
|
||||||
S21,
|
|
||||||
)
|
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import BOSMiner
|
from pyasic.miners.backends import BOSMiner
|
||||||
from pyasic.miners.models import S9
|
from pyasic.miners.device.models import S9
|
||||||
|
|
||||||
|
|
||||||
class BOSMinerS9(BOSMiner, S9):
|
class BOSMinerS9(BOSMiner, S9):
|
||||||
|
|||||||
@@ -17,3 +17,4 @@
|
|||||||
from .X9 import *
|
from .X9 import *
|
||||||
from .X17 import *
|
from .X17 import *
|
||||||
from .X19 import *
|
from .X19 import *
|
||||||
|
from .X21 import *
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import AntminerOld
|
from pyasic.miners.backends import AntminerOld
|
||||||
from pyasic.miners.models import Z15
|
from pyasic.miners.device.models import Z15
|
||||||
|
|
||||||
|
|
||||||
class CGMinerZ15(AntminerOld, Z15):
|
class CGMinerZ15(AntminerOld, Z15):
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
# limitations under the License. -
|
# limitations under the License. -
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
from pyasic.miners.backends import AntminerOld
|
from pyasic.miners.backends import AntminerOld
|
||||||
from pyasic.miners.models import D3
|
from pyasic.miners.device.models import D3
|
||||||
|
|
||||||
|
|
||||||
class CGMinerD3(AntminerOld, D3):
|
class CGMinerD3(AntminerOld, D3):
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import AntminerOld
|
from pyasic.miners.backends import AntminerOld
|
||||||
from pyasic.miners.models import DR5
|
from pyasic.miners.device.models import DR5
|
||||||
|
|
||||||
|
|
||||||
class CGMinerDR5(AntminerOld, DR5):
|
class CGMinerDR5(AntminerOld, DR5):
|
||||||
|
|||||||
@@ -15,7 +15,15 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import ePIC
|
from pyasic.miners.backends import ePIC
|
||||||
from pyasic.miners.models import S19, S19XP, S19j, S19jPro, S19jProPlus, S19kPro, S19Pro
|
from pyasic.miners.device.models import (
|
||||||
|
S19,
|
||||||
|
S19XP,
|
||||||
|
S19j,
|
||||||
|
S19jPro,
|
||||||
|
S19jProPlus,
|
||||||
|
S19kPro,
|
||||||
|
S19Pro,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ePICS19(ePIC, S19):
|
class ePICS19(ePIC, S19):
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import ePIC
|
from pyasic.miners.backends import ePIC
|
||||||
from pyasic.miners.models import S21
|
from pyasic.miners.device.models import S21
|
||||||
|
|
||||||
|
|
||||||
class ePICS21(ePIC, S21):
|
class ePICS21(ePIC, S21):
|
||||||
|
|||||||
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.device.models import T21
|
||||||
|
|
||||||
|
|
||||||
|
class ePICT21(ePIC, T21):
|
||||||
|
pass
|
||||||
@@ -17,3 +17,7 @@
|
|||||||
from .S21 import (
|
from .S21 import (
|
||||||
ePICS21,
|
ePICS21,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from .T21 import (
|
||||||
|
ePICT21,
|
||||||
|
)
|
||||||
|
|||||||
@@ -18,11 +18,11 @@ from typing import List, Optional
|
|||||||
|
|
||||||
import asyncssh
|
import asyncssh
|
||||||
|
|
||||||
from pyasic.data import HashBoard
|
from pyasic.data import AlgoHashRate, HashBoard, HashUnit
|
||||||
from pyasic.errors import APIError
|
from pyasic.errors import APIError
|
||||||
from pyasic.miners.backends import Hiveon
|
from pyasic.miners.backends import Hiveon
|
||||||
from pyasic.miners.data import DataFunction, DataLocations, DataOptions, RPCAPICommand
|
from pyasic.miners.data import DataFunction, DataLocations, DataOptions, RPCAPICommand
|
||||||
from pyasic.miners.models import T9
|
from pyasic.miners.device.models import T9
|
||||||
|
|
||||||
HIVEON_T9_DATA_LOC = DataLocations(
|
HIVEON_T9_DATA_LOC = DataLocations(
|
||||||
**{
|
**{
|
||||||
@@ -121,7 +121,9 @@ class HiveonT9(Hiveon, T9):
|
|||||||
chips += rpc_stats["STATS"][1][f"chain_acn{chipset}"]
|
chips += rpc_stats["STATS"][1][f"chain_acn{chipset}"]
|
||||||
except (KeyError, IndexError):
|
except (KeyError, IndexError):
|
||||||
pass
|
pass
|
||||||
hashboards[board].hashrate = round(hashrate / 1000, 2)
|
hashboards[board].hashrate = AlgoHashRate.SHA256(
|
||||||
|
hashrate, HashUnit.SHA256.GH
|
||||||
|
).into(self.algo.unit.default)
|
||||||
hashboards[board].chips = chips
|
hashboards[board].chips = chips
|
||||||
|
|
||||||
return hashboards
|
return hashboards
|
||||||
|
|||||||
@@ -15,7 +15,14 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import LUXMiner
|
from pyasic.miners.backends import LUXMiner
|
||||||
from pyasic.miners.models import S19, S19XP, S19jPro, S19jProPlus, S19kPro, S19Pro
|
from pyasic.miners.device.models import (
|
||||||
|
S19,
|
||||||
|
S19XP,
|
||||||
|
S19jPro,
|
||||||
|
S19jProPlus,
|
||||||
|
S19kPro,
|
||||||
|
S19Pro,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class LUXMinerS19(LUXMiner, S19):
|
class LUXMinerS19(LUXMiner, S19):
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import LUXMiner
|
from pyasic.miners.backends import LUXMiner
|
||||||
from pyasic.miners.models import T19
|
from pyasic.miners.device.models import T19
|
||||||
|
|
||||||
|
|
||||||
class LUXMinerT19(LUXMiner, T19):
|
class LUXMinerT19(LUXMiner, T19):
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import LUXMiner
|
from pyasic.miners.backends import LUXMiner
|
||||||
from pyasic.miners.models import S21
|
from pyasic.miners.device.models import S21
|
||||||
|
|
||||||
|
|
||||||
class LUXMinerS21(LUXMiner, S21):
|
class LUXMinerS21(LUXMiner, S21):
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import LUXMiner
|
from pyasic.miners.backends import LUXMiner
|
||||||
from pyasic.miners.models import S9
|
from pyasic.miners.device.models import S9
|
||||||
|
|
||||||
|
|
||||||
class LUXMinerS9(LUXMiner, S9):
|
class LUXMinerS9(LUXMiner, S9):
|
||||||
|
|||||||
54
pyasic/miners/antminer/marathon/X19/S19.py
Normal file
54
pyasic/miners/antminer/marathon/X19/S19.py
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# 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.device.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.device.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.device.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 *
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
# limitations under the License. -
|
# limitations under the License. -
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
from pyasic.miners.backends import VNish
|
from pyasic.miners.backends import VNish
|
||||||
from pyasic.miners.models import S17Plus, S17Pro
|
from pyasic.miners.device.models import S17Plus, S17Pro
|
||||||
|
|
||||||
|
|
||||||
class VNishS17Plus(VNish, S17Plus):
|
class VNishS17Plus(VNish, S17Plus):
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import VNish
|
from pyasic.miners.backends import VNish
|
||||||
from pyasic.miners.models import (
|
from pyasic.miners.device.models import (
|
||||||
S19,
|
S19,
|
||||||
S19XP,
|
S19XP,
|
||||||
S19a,
|
S19a,
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import VNish
|
from pyasic.miners.backends import VNish
|
||||||
from pyasic.miners.models import T19
|
from pyasic.miners.device.models import T19
|
||||||
|
|
||||||
|
|
||||||
class VNishT19(VNish, T19):
|
class VNishT19(VNish, T19):
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import VNish
|
from pyasic.miners.backends import VNish
|
||||||
from pyasic.miners.models import L3Plus
|
from pyasic.miners.device.models import L3Plus
|
||||||
|
|
||||||
|
|
||||||
class VnishL3Plus(VNish, L3Plus):
|
class VnishL3Plus(VNish, L3Plus):
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import VNish
|
from pyasic.miners.backends import VNish
|
||||||
from pyasic.miners.models import L7
|
from pyasic.miners.device.models import L7
|
||||||
|
|
||||||
|
|
||||||
class VnishL7(VNish, L7):
|
class VnishL7(VNish, L7):
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
from pyasic.miners.backends import Auradine
|
from pyasic.miners.backends import Auradine
|
||||||
from pyasic.miners.models import AuradineAT1500
|
from pyasic.miners.device.models import AuradineAT1500
|
||||||
|
|
||||||
|
|
||||||
class AuradineFluxAT1500(AuradineAT1500, Auradine):
|
class AuradineFluxAT1500(AuradineAT1500, Auradine):
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
from pyasic.miners.backends import Auradine
|
from pyasic.miners.backends import Auradine
|
||||||
from pyasic.miners.models import AuradineAT2860, AuradineAT2880
|
from pyasic.miners.device.models import AuradineAT2860, AuradineAT2880
|
||||||
|
|
||||||
|
|
||||||
class AuradineFluxAT2860(AuradineAT2860, Auradine):
|
class AuradineFluxAT2860(AuradineAT2860, Auradine):
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
from pyasic.miners.backends import Auradine
|
from pyasic.miners.backends import Auradine
|
||||||
from pyasic.miners.models import AuradineAI2500
|
from pyasic.miners.device.models import AuradineAI2500
|
||||||
|
|
||||||
|
|
||||||
class AuradineFluxAI2500(AuradineAI2500, Auradine):
|
class AuradineFluxAI2500(AuradineAI2500, Auradine):
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
from pyasic.miners.backends import Auradine
|
from pyasic.miners.backends import Auradine
|
||||||
from pyasic.miners.models import AuradineAI3680
|
from pyasic.miners.device.models import AuradineAI3680
|
||||||
|
|
||||||
|
|
||||||
class AuradineFluxAI3680(AuradineAI3680, Auradine):
|
class AuradineFluxAI3680(AuradineAI3680, Auradine):
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
from pyasic.miners.backends import Auradine
|
from pyasic.miners.backends import Auradine
|
||||||
from pyasic.miners.models import AuradineAD2500
|
from pyasic.miners.device.models import AuradineAD2500
|
||||||
|
|
||||||
|
|
||||||
class AuradineFluxAD2500(AuradineAD2500, Auradine):
|
class AuradineFluxAD2500(AuradineAD2500, Auradine):
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
from pyasic.miners.backends import Auradine
|
from pyasic.miners.backends import Auradine
|
||||||
from pyasic.miners.models import AuradineAD3500
|
from pyasic.miners.device.models import AuradineAD3500
|
||||||
|
|
||||||
|
|
||||||
class AuradineFluxAD3500(AuradineAD3500, Auradine):
|
class AuradineFluxAD3500(AuradineAD3500, Auradine):
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import AvalonMiner
|
from pyasic.miners.backends import AvalonMiner
|
||||||
from pyasic.miners.models import Avalon1026
|
from pyasic.miners.device.models import Avalon1026
|
||||||
|
|
||||||
|
|
||||||
class CGMinerAvalon1026(AvalonMiner, Avalon1026):
|
class CGMinerAvalon1026(AvalonMiner, Avalon1026):
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import AvalonMiner
|
from pyasic.miners.backends import AvalonMiner
|
||||||
from pyasic.miners.models import Avalon1047
|
from pyasic.miners.device.models import Avalon1047
|
||||||
|
|
||||||
|
|
||||||
class CGMinerAvalon1047(AvalonMiner, Avalon1047):
|
class CGMinerAvalon1047(AvalonMiner, Avalon1047):
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import AvalonMiner
|
from pyasic.miners.backends import AvalonMiner
|
||||||
from pyasic.miners.models import Avalon1066
|
from pyasic.miners.device.models import Avalon1066
|
||||||
|
|
||||||
|
|
||||||
class CGMinerAvalon1066(AvalonMiner, Avalon1066):
|
class CGMinerAvalon1066(AvalonMiner, Avalon1066):
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import AvalonMiner
|
from pyasic.miners.backends import AvalonMiner
|
||||||
from pyasic.miners.models import Avalon1166Pro
|
from pyasic.miners.device.models import Avalon1166Pro
|
||||||
|
|
||||||
|
|
||||||
class CGMinerAvalon1166Pro(AvalonMiner, Avalon1166Pro):
|
class CGMinerAvalon1166Pro(AvalonMiner, Avalon1166Pro):
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import AvalonMiner
|
from pyasic.miners.backends import AvalonMiner
|
||||||
from pyasic.miners.models import Avalon1246
|
from pyasic.miners.device.models import Avalon1246
|
||||||
|
|
||||||
|
|
||||||
class CGMinerAvalon1246(AvalonMiner, Avalon1246):
|
class CGMinerAvalon1246(AvalonMiner, Avalon1246):
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import AvalonMiner
|
from pyasic.miners.backends import AvalonMiner
|
||||||
from pyasic.miners.models import Avalon721
|
from pyasic.miners.device.models import Avalon721
|
||||||
|
|
||||||
|
|
||||||
class CGMinerAvalon721(AvalonMiner, Avalon721):
|
class CGMinerAvalon721(AvalonMiner, Avalon721):
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import AvalonMiner
|
from pyasic.miners.backends import AvalonMiner
|
||||||
from pyasic.miners.models import Avalon741
|
from pyasic.miners.device.models import Avalon741
|
||||||
|
|
||||||
|
|
||||||
class CGMinerAvalon741(AvalonMiner, Avalon741):
|
class CGMinerAvalon741(AvalonMiner, Avalon741):
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import AvalonMiner
|
from pyasic.miners.backends import AvalonMiner
|
||||||
from pyasic.miners.models import Avalon761
|
from pyasic.miners.device.models import Avalon761
|
||||||
|
|
||||||
|
|
||||||
class CGMinerAvalon761(AvalonMiner, Avalon761):
|
class CGMinerAvalon761(AvalonMiner, Avalon761):
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user