Compare commits
209 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
39410424b6 | ||
|
|
7cb871b541 | ||
|
|
a62bea33a7 | ||
|
|
406bcd179c | ||
|
|
aa87ef7d71 | ||
|
|
ec88fbf6aa | ||
|
|
e23c86a944 | ||
|
|
b81276cb19 | ||
|
|
8dcc72b1bb | ||
|
|
540572356f | ||
|
|
83035a869b | ||
|
|
4c104a59ff | ||
|
|
e708ae3728 | ||
|
|
a4352816ee | ||
|
|
336bd9c002 | ||
|
|
e3c917efde | ||
|
|
4d71012ed6 | ||
|
|
1acdba8ae0 | ||
|
|
5567f26c03 | ||
|
|
0027485582 | ||
|
|
c9bcb7bab6 | ||
|
|
0ee261930e | ||
|
|
3cfc8dded9 | ||
|
|
655cf6d0ac | ||
|
|
640dc6d8c2 | ||
|
|
a572fedb4d | ||
|
|
6c46a7cd71 | ||
|
|
49f42172da | ||
|
|
83be80e4bc | ||
|
|
0be9e9d519 | ||
|
|
4694c0f774 | ||
|
|
11012b310b | ||
|
|
8852fab3ee | ||
|
|
ec1b2ca162 | ||
|
|
1f9d4c8c10 | ||
|
|
5bb04b2af4 | ||
|
|
2e192a1536 | ||
|
|
4da8044bc7 | ||
|
|
76078e4d0e | ||
|
|
276a476fab | ||
|
|
e0abed4f93 | ||
|
|
4a67bd5d99 | ||
|
|
eb48d04939 | ||
|
|
c4697728e4 | ||
|
|
de64172073 | ||
|
|
4d7a13433b | ||
|
|
e14a4791b2 | ||
|
|
0e76d4550b | ||
|
|
2d424025e9 | ||
|
|
bf4903ce4b | ||
|
|
4f7f6bf045 | ||
|
|
824890ec97 | ||
|
|
ce9d7ffb0f | ||
|
|
183b4934c1 | ||
|
|
3d2b260b17 | ||
|
|
f88c1734eb | ||
|
|
b897ca8363 | ||
|
|
dba341fdae | ||
|
|
837794bd57 | ||
|
|
36d16c7235 | ||
|
|
7797023689 | ||
|
|
1021f200ec | ||
|
|
197d6568e3 | ||
|
|
71c8905674 | ||
|
|
15c3806fbf | ||
|
|
a5c42c9c2b | ||
|
|
90d8a795e6 | ||
|
|
07cf1b134c | ||
|
|
53e1f33fa6 | ||
|
|
16ab2bd4e3 | ||
|
|
de728f12d2 | ||
|
|
8092e12dfb | ||
|
|
e70c3e9f79 | ||
|
|
39a97f2914 | ||
|
|
35af74ad1a | ||
|
|
15fa91fb98 | ||
|
|
084987a3e1 | ||
|
|
e93cc77a58 | ||
|
|
788d43c51c | ||
|
|
74c22b82ce | ||
|
|
1f46ce1b9a | ||
|
|
7964336a0c | ||
|
|
a24fc07c2a | ||
|
|
4c64481d3b | ||
|
|
66fb5834f0 | ||
|
|
db05cc1d97 | ||
|
|
418e3ce26e | ||
|
|
5a0bb11a44 | ||
|
|
39f9d087db | ||
|
|
067a376f94 | ||
|
|
a5d6e122f9 | ||
|
|
b160fd75ba | ||
|
|
d1007d3ae8 | ||
|
|
33803e89e2 | ||
|
|
10a44b9877 | ||
|
|
bbd883f639 | ||
|
|
8e2ad478e9 | ||
|
|
957981a9c6 | ||
|
|
13a67dfdd1 | ||
|
|
e86f2b62c5 | ||
|
|
88b4d2cac3 | ||
|
|
5842ef3d97 | ||
|
|
339a689267 | ||
|
|
a0764806c4 | ||
|
|
6eec0f6d44 | ||
|
|
0854f7833c | ||
|
|
b6edc85679 | ||
|
|
ff11ebc304 | ||
|
|
f3681f1aa5 | ||
|
|
1a7411edb3 | ||
|
|
f2a4a5d524 | ||
|
|
624a3c5919 | ||
|
|
2ec8054d24 | ||
|
|
d148ccfe5f | ||
|
|
b6c29d16f9 | ||
|
|
53a3bb13af | ||
|
|
16e74e659c | ||
|
|
730caca23f | ||
|
|
dc126b2953 | ||
|
|
51abdf0b2d | ||
|
|
b367b2d293 | ||
|
|
96f52a4b35 | ||
|
|
5236e02af2 | ||
|
|
9ee52f77f9 | ||
|
|
26389f8ba0 | ||
|
|
8a0605bd3b | ||
|
|
fe9894919e | ||
|
|
bb399fe362 | ||
|
|
7ca7fe3e7e | ||
|
|
748279c25d | ||
|
|
23890fa10a | ||
|
|
8ab7df516e | ||
|
|
f7a0188104 | ||
|
|
66a8932ea3 | ||
|
|
56536fd258 | ||
|
|
1b4e6d4da0 | ||
|
|
2019bdaff2 | ||
|
|
b903cc6e5f | ||
|
|
c1a01b5f7b | ||
|
|
3427a8d15a | ||
|
|
25c08b9bc0 | ||
|
|
01263da52b | ||
|
|
5081319a2f | ||
|
|
ec5be00065 | ||
|
|
891e28bfe6 | ||
|
|
8e15b00e70 | ||
|
|
df71ab3282 | ||
|
|
1508f7873a | ||
|
|
77058ac692 | ||
|
|
1a4491ca56 | ||
|
|
d018724aa4 | ||
|
|
5b97bed704 | ||
|
|
55786b154d | ||
|
|
6ab9681dec | ||
|
|
89641c6316 | ||
|
|
136ff6a688 | ||
|
|
d918d93f4a | ||
|
|
8046c532a6 | ||
|
|
92820a362d | ||
|
|
9fd90031a9 | ||
|
|
2f2223a112 | ||
|
|
50e6cf9dfd | ||
|
|
1b5e3093e6 | ||
|
|
9e3578b4a2 | ||
|
|
a3087e1a96 | ||
|
|
4b16ea2ca2 | ||
|
|
5dd361c4ef | ||
|
|
098112742c | ||
|
|
cd31e0743e | ||
|
|
1a7d0bf7cc | ||
|
|
41b5ebf0f0 | ||
|
|
5436bede29 | ||
|
|
c01b3958dc | ||
|
|
c16367285f | ||
|
|
17eae253e6 | ||
|
|
ab30988614 | ||
|
|
9b8e547f86 | ||
|
|
3b8cbb9ff1 | ||
|
|
d39d278296 | ||
|
|
ea8b922367 | ||
|
|
0d1c8d80e0 | ||
|
|
494d25da97 | ||
|
|
0327d93a35 | ||
|
|
680584c468 | ||
|
|
c0dbafb198 | ||
|
|
97d2c4ac34 | ||
|
|
055d633c91 | ||
|
|
68c57f265f | ||
|
|
1ba0f8ed83 | ||
|
|
7f74b083d3 | ||
|
|
97c20dae0a | ||
|
|
09c7aff640 | ||
|
|
7e7cdc9615 | ||
|
|
b6fb0fd2b9 | ||
|
|
46788e7d14 | ||
|
|
5b4f84a241 | ||
|
|
0c56bfdf9e | ||
|
|
4a5d793cd6 | ||
|
|
1894ff1aea | ||
|
|
3ab9294000 | ||
|
|
5e0641634b | ||
|
|
a1975bc9b8 | ||
|
|
6a265f03f7 | ||
|
|
c3658f028f | ||
|
|
ba3c653a29 | ||
|
|
61fbc132ed | ||
|
|
3f9f232990 | ||
|
|
29c2398846 | ||
|
|
ecc161820d |
6
.github/workflows/python-publish.yml
vendored
6
.github/workflows/python-publish.yml
vendored
@@ -13,10 +13,10 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4.2.2
|
||||
- name: Publish GH release
|
||||
uses: softprops/action-gh-release@v0.1.14
|
||||
uses: softprops/action-gh-release@v2.1.0
|
||||
- name: Build using poetry and publish to PyPi
|
||||
uses: JRubics/poetry-publish@v1.11
|
||||
uses: JRubics/poetry-publish@v2.0
|
||||
with:
|
||||
pypi_token: ${{ secrets.PYPI_API_KEY }}
|
||||
|
||||
@@ -1,19 +1,33 @@
|
||||
ci:
|
||||
skip:
|
||||
- poetry-lock
|
||||
- unittest
|
||||
- generate-docs
|
||||
repos:
|
||||
- repo: https://github.com/python-poetry/poetry
|
||||
rev: 2.1.2
|
||||
hooks:
|
||||
- id: poetry-check
|
||||
- id: poetry-lock
|
||||
- id: poetry-install
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v5.0.0
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
- id: check-yaml
|
||||
name: check-yaml for mkdocs.yml
|
||||
files: ^mkdocs\.yml$
|
||||
args: [--unsafe]
|
||||
- id: check-yaml
|
||||
name: check-yaml for other YAML files
|
||||
exclude: ^mkdocs\.yml$
|
||||
- id: check-added-large-files
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 24.10.0
|
||||
rev: 25.1.0
|
||||
hooks:
|
||||
- id: black
|
||||
- repo: https://github.com/pycqa/isort
|
||||
rev: 5.13.2
|
||||
rev: 6.0.1
|
||||
hooks:
|
||||
- id: isort
|
||||
name: isort (python)
|
||||
@@ -24,6 +38,12 @@ repos:
|
||||
name: unittest
|
||||
entry: python -m unittest discover
|
||||
language: system
|
||||
'types': [python]
|
||||
types: [ python ]
|
||||
args: ["-p '*test.py'"] # Probably this option is absolutely not needed.
|
||||
pass_filenames: false
|
||||
- id: generate-docs
|
||||
name: generate-docs
|
||||
entry: python docs/generate_miners.py
|
||||
language: system
|
||||
types: [ python ]
|
||||
pass_filenames: false
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
# .readthedocs.yaml
|
||||
# Read the Docs configuration file
|
||||
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
||||
|
||||
# Required
|
||||
version: 2
|
||||
|
||||
# Set the version of Python and other tools you might need
|
||||
build:
|
||||
os: ubuntu-20.04
|
||||
tools:
|
||||
python: "3.9"
|
||||
tools: { python: "3.11" }
|
||||
jobs:
|
||||
pre_create_environment:
|
||||
- asdf plugin add poetry
|
||||
- asdf install poetry latest
|
||||
- asdf global poetry latest
|
||||
- poetry config virtualenvs.create false
|
||||
post_install:
|
||||
- VIRTUAL_ENV=$READTHEDOCS_VIRTUALENV_PATH poetry install --only docs
|
||||
|
||||
mkdocs:
|
||||
configuration: mkdocs.yml
|
||||
|
||||
# Optionally declare the Python requirements required to build your docs
|
||||
python:
|
||||
install:
|
||||
- requirements: docs/requirements.txt
|
||||
|
||||
@@ -50,6 +50,13 @@ poetry install --with dev
|
||||
pre-commit install
|
||||
```
|
||||
|
||||
##### Building Documentation Locally
|
||||
```
|
||||
poetry install --with docs
|
||||
python docs/generate_miners.py
|
||||
poetry run mkdocs serve
|
||||
```
|
||||
|
||||
---
|
||||
## Getting started
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import asyncio
|
||||
import importlib
|
||||
import os
|
||||
import warnings
|
||||
from pathlib import Path
|
||||
|
||||
from pyasic.miners.factory import MINER_CLASSES, MinerTypes
|
||||
|
||||
@@ -51,10 +52,19 @@ def backend_str(backend: MinerTypes) -> str:
|
||||
return "Mara Firmware Miners"
|
||||
case MinerTypes.BITAXE:
|
||||
return "Stock Firmware BitAxe Miners"
|
||||
case MinerTypes.LUCKYMINER:
|
||||
return "Stock Firmware Lucky Miners"
|
||||
case MinerTypes.ICERIVER:
|
||||
return "Stock Firmware IceRiver Miners"
|
||||
case MinerTypes.HAMMER:
|
||||
return "Stock Firmware Hammer Miners"
|
||||
case MinerTypes.VOLCMINER:
|
||||
return "Stock Firmware Volcminers"
|
||||
case MinerTypes.ELPHAPEX:
|
||||
return "Stock Firmware Elphapex Miners"
|
||||
case MinerTypes.MSKMINER:
|
||||
return "MSKMiner Firmware Miners"
|
||||
raise TypeError("Unknown miner backend, cannot generate docs")
|
||||
|
||||
|
||||
def create_url_str(mtype: str):
|
||||
@@ -69,11 +79,17 @@ def create_url_str(mtype: str):
|
||||
|
||||
HEADER_FORMAT = "# pyasic\n## {} Models\n\n"
|
||||
MINER_HEADER_FORMAT = "## {}\n"
|
||||
DATA_FORMAT = """::: {}
|
||||
DATA_FORMAT = """
|
||||
- [{}] Shutdowns
|
||||
- [{}] Power Modes
|
||||
- [{}] Setpoints
|
||||
- [{}] Presets
|
||||
|
||||
::: {}
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
"""
|
||||
SUPPORTED_TYPES_HEADER = """# pyasic
|
||||
@@ -81,6 +97,8 @@ SUPPORTED_TYPES_HEADER = """# pyasic
|
||||
|
||||
Supported miner types are here on this list. If your miner (or miner version) is not on this list, please feel free to [open an issue on GitHub](https://github.com/UpstreamData/pyasic/issues) to get it added.
|
||||
|
||||
Keep in mind that some functionality is only supported for specific miners or firmwares, please check the page for your miner to make sure the functionality you need is supported.
|
||||
|
||||
##### pyasic currently supports the following miners and subtypes:
|
||||
<style>
|
||||
details {
|
||||
@@ -111,39 +129,49 @@ BACKEND_TYPE_CLOSER = """
|
||||
</details>"""
|
||||
|
||||
m_data = {}
|
||||
|
||||
done = []
|
||||
|
||||
for m in MINER_CLASSES:
|
||||
for t in MINER_CLASSES[m]:
|
||||
if t is not None:
|
||||
for t in sorted(MINER_CLASSES[m], key=lambda x: x or ""):
|
||||
if t is not None and MINER_CLASSES[m][t] not in done:
|
||||
miner = MINER_CLASSES[m][t]
|
||||
if make(miner) not in m_data:
|
||||
m_data[make(miner)] = {}
|
||||
if model_type(miner) not in m_data[make(miner)]:
|
||||
m_data[make(miner)][model_type(miner)] = []
|
||||
m_data[make(miner)][model_type(miner)].append(miner)
|
||||
done.append(miner)
|
||||
|
||||
|
||||
async def create_directory_structure(directory, data):
|
||||
def create_directory_structure(directory, data):
|
||||
if not os.path.exists(directory):
|
||||
os.makedirs(directory)
|
||||
|
||||
for key, value in data.items():
|
||||
subdirectory = os.path.join(directory, key)
|
||||
if isinstance(value, dict):
|
||||
await create_directory_structure(subdirectory, value)
|
||||
create_directory_structure(subdirectory, value)
|
||||
elif isinstance(value, list):
|
||||
file_path = os.path.join(subdirectory + ".md")
|
||||
|
||||
with open(file_path, "w") as file:
|
||||
file.write(HEADER_FORMAT.format(key))
|
||||
for item in value:
|
||||
header = await item("1.1.1.1").get_model()
|
||||
obj = item("1.1.1.1")
|
||||
header = obj.model
|
||||
file.write(MINER_HEADER_FORMAT.format(header))
|
||||
file.write(DATA_FORMAT.format(path(item)))
|
||||
file.write(
|
||||
DATA_FORMAT.format(
|
||||
"x" if obj.supports_shutdown else " ",
|
||||
"x" if obj.supports_power_modes else " ",
|
||||
"x" if obj.supports_autotuning else " ",
|
||||
"x" if obj.supports_presets else " ",
|
||||
path(item),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
async def create_supported_types(directory):
|
||||
def create_supported_types(directory):
|
||||
with open(os.path.join(directory, "supported_types.md"), "w") as file:
|
||||
file.write(SUPPORTED_TYPES_HEADER)
|
||||
for mback in MINER_CLASSES:
|
||||
@@ -160,7 +188,7 @@ async def create_supported_types(directory):
|
||||
for mtype in backend_types:
|
||||
file.write(MINER_TYPE_HEADER.format(mtype))
|
||||
for minstance in backend_types[mtype]:
|
||||
model = await minstance("1.1.1.1").get_model()
|
||||
model = minstance("1.1.1.1").model
|
||||
file.write(
|
||||
MINER_DETAILS.format(
|
||||
make(minstance), mtype, create_url_str(model), model
|
||||
@@ -170,6 +198,7 @@ async def create_supported_types(directory):
|
||||
file.write(BACKEND_TYPE_CLOSER)
|
||||
|
||||
|
||||
root_directory = os.path.join(os.getcwd(), "miners")
|
||||
asyncio.run(create_directory_structure(root_directory, m_data))
|
||||
asyncio.run(create_supported_types(root_directory))
|
||||
if __name__ == "__main__":
|
||||
root_directory = Path(__file__).parent.joinpath("miners")
|
||||
create_directory_structure(root_directory, m_data)
|
||||
create_supported_types(root_directory)
|
||||
|
||||
189
docs/index.md
189
docs/index.md
@@ -11,145 +11,149 @@
|
||||
[](https://pyasic.readthedocs.io/en/latest/)
|
||||
[](https://github.com/UpstreamData/pyasic/blob/master/LICENSE.txt)
|
||||
|
||||
---
|
||||
## Intro
|
||||
---
|
||||
Welcome to `pyasic`! `pyasic` uses an asynchronous method of communicating with ASIC miners on your network, which makes it super fast.
|
||||
|
||||
[Click here to view supported miner types](miners/supported_types.md)
|
||||
|
||||
---
|
||||
## Installation
|
||||
|
||||
It is recommended to install `pyasic` in a [virtual environment](https://realpython.com/python-virtual-environments-a-primer/#what-other-popular-options-exist-aside-from-venv) to isolate it from the rest of your system. Options include:
|
||||
- [pypoetry](https://python-poetry.org/): the reccommended way, since pyasic already uses it by default
|
||||
|
||||
```
|
||||
poetry install
|
||||
```
|
||||
|
||||
- [venv](https://docs.python.org/3/library/venv.html): included in Python standard library but has fewer features than other options
|
||||
- [pyenv-virtualenv](https://github.com/pyenv/pyenv-virtualenv): [pyenv](https://github.com/pyenv/pyenv) plugin for managing virtualenvs
|
||||
|
||||
```
|
||||
pyenv install <python version number>
|
||||
pyenv virtualenv <python version number> <env name>
|
||||
pyenv activate <env name>
|
||||
```
|
||||
|
||||
- [conda](https://docs.conda.io/en/latest/)
|
||||
|
||||
##### Installing `pyasic`
|
||||
|
||||
`python -m pip install pyasic` or `poetry install`
|
||||
|
||||
---
|
||||
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.
|
||||
`pyasic` can be installed directly from pip, either with `pip install pyasic`, or a different command if using a tool like `pypoetry`.
|
||||
|
||||
## Getting started
|
||||
---
|
||||
Getting started with `pyasic` is easy. First, find your miner (or miners) on the network by scanning for them or getting the correct class automatically for them if you know the IP.
|
||||
|
||||
##### Scanning for miners
|
||||
### Scanning for miners
|
||||
To scan for miners in `pyasic`, we use the class [`MinerNetwork`][pyasic.network.MinerNetwork], which abstracts the search, communication, identification, setup, and return of a miner to 1 command.
|
||||
The command [`MinerNetwork.scan()`][pyasic.network.MinerNetwork.scan] returns a list that contains any miners found.
|
||||
```python
|
||||
import asyncio # asyncio for handling the async part
|
||||
from pyasic.network import MinerNetwork # miner network handles the scanning
|
||||
```python3
|
||||
import asyncio# (1)!
|
||||
from pyasic.network import MinerNetwork# (2)!
|
||||
|
||||
|
||||
async def scan_miners(): # define async scan function to allow awaiting
|
||||
# create a miner network
|
||||
# you can pass in any IP and it will use that in a subnet with a /24 mask (255 IPs).
|
||||
network = MinerNetwork.from_subnet("192.168.1.50/24") # this uses the 192.168.1.0-255 network
|
||||
async def scan_miners():# (3)!
|
||||
network = MinerNetwork.from_subnet("192.168.1.50/24")# (4)!
|
||||
|
||||
# scan for miners asynchronously
|
||||
# this will return the correct type of miners if they are supported with all functionality.
|
||||
miners = await network.scan()
|
||||
miners = await network.scan()# (5)!
|
||||
print(miners)
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(scan_miners()) # run the scan asynchronously with asyncio.run()
|
||||
asyncio.run(scan_miners())# (6)!
|
||||
```
|
||||
|
||||
1. `asyncio` for handling the async part.
|
||||
2. `MinerNetwork` handles the scanning.
|
||||
3. Define an async function to allow awaiting.
|
||||
4. Create a miner network.
|
||||
You can pass in any IP and it will use that in a subnet with a /24 mask (255 IPs).
|
||||
This uses the 192.168.1.0-255 network.
|
||||
5. Scan for miners asynchronously.
|
||||
This will return the correct type of miners (if they are supported) with all functionality.
|
||||
6. Run the scan asynchronously with asyncio.run().
|
||||
|
||||
---
|
||||
##### Creating miners based on IP
|
||||
### Creating miners based on IP
|
||||
If you already know the IP address of your miner or miners, you can use the [`MinerFactory`][pyasic.miners.factory.MinerFactory] to communicate and identify the miners, or an abstraction of its functionality, [`get_miner()`][pyasic.miners.get_miner].
|
||||
The function [`get_miner()`][pyasic.miners.get_miner] will return any miner it found at the IP address specified, or an `UnknownMiner` if it cannot identify the miner.
|
||||
```python
|
||||
import asyncio # asyncio for handling the async part
|
||||
from pyasic import get_miner # handles miner creation
|
||||
import asyncio# (1)!
|
||||
from pyasic import get_miner# (2)!
|
||||
|
||||
|
||||
async def get_miners(): # define async scan function to allow awaiting
|
||||
# get the miner with the miner factory
|
||||
# the miner factory is a singleton, and will always use the same object and cache
|
||||
# this means you can always call it as MinerFactory().get_miner(), or just get_miner()
|
||||
miner_1 = await get_miner("192.168.1.75")
|
||||
async def get_miners():# (3)!
|
||||
miner_1 = await get_miner("192.168.1.75")# (4)!
|
||||
miner_2 = await get_miner("192.168.1.76")
|
||||
print(miner_1, miner_2)
|
||||
|
||||
# can also gather these, since they are async
|
||||
# gathering them will get them both at the same time
|
||||
# this makes it much faster to get a lot of miners at a time
|
||||
tasks = [get_miner("192.168.1.75"), get_miner("192.168.1.76")]
|
||||
miners = await asyncio.gather(*tasks)
|
||||
miners = await asyncio.gather(*tasks)# (5)!
|
||||
print(miners)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(get_miners()) # get the miners asynchronously with asyncio.run()
|
||||
asyncio.run(get_miners())# (6)!
|
||||
```
|
||||
|
||||
---
|
||||
1. `asyncio` for handling the async part.
|
||||
2. `get_miner` handles the miner type selection.
|
||||
3. Define an async function to allow awaiting.
|
||||
4. Get the miner.
|
||||
5. Can also gather these, since they are async.
|
||||
Gathering them will get them both at the same time.
|
||||
This makes it much faster to get a lot of miners at a time.
|
||||
6. Get the miners asynchronously with asyncio.run().
|
||||
|
||||
## Data gathering
|
||||
---
|
||||
Once you have your miner(s) identified, you will likely want to get data from the miner(s). You can do this using a built-in function in each miner called `get_data()`.
|
||||
This function will return an instance of the dataclass [`MinerData`][pyasic.data.MinerData] with all data it can gather from the miner.
|
||||
Each piece of data in a [`MinerData`][pyasic.data.MinerData] instance can be referenced by getting it as an attribute, such as [`MinerData().hashrate`][pyasic.data.MinerData].
|
||||
|
||||
##### One miner
|
||||
### One miner
|
||||
```python
|
||||
import asyncio
|
||||
from pyasic import get_miner
|
||||
import asyncio# (1)!
|
||||
from pyasic import get_miner# (2)!
|
||||
|
||||
async def gather_miner_data():
|
||||
miner = await get_miner("192.168.1.75")
|
||||
if miner is not None:
|
||||
miner_data = await miner.get_data()
|
||||
print(miner_data) # all data from the dataclass
|
||||
|
||||
async def gather_miner_data():# (3)!
|
||||
miner = await get_miner("192.168.1.75")# (4)!
|
||||
if miner is not None:# (5)!
|
||||
miner_data = await miner.get_data()# (6)!
|
||||
print(miner_data)# (7)!
|
||||
print(miner_data.hashrate) # hashrate of the miner in TH/s
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(gather_miner_data())
|
||||
asyncio.run(gather_miner_data())# (9)!
|
||||
```
|
||||
---
|
||||
##### Multiple miners
|
||||
|
||||
1. `asyncio` for handling the async part.
|
||||
2. `get_miner` handles the miner type selection.
|
||||
3. Define an async function to allow awaiting.
|
||||
4. Get the miner.
|
||||
5. Make sure the miner exists.
|
||||
If this result is `None`, the miner may be offline.
|
||||
6. Get data from the miner.
|
||||
7. All the data from the dataclass.
|
||||
8. Hashrate of the miner, with unit information.
|
||||
9. Get the miner data asynchronously with asyncio.run().
|
||||
|
||||
### Multiple miners
|
||||
You can do something similar with multiple miners, with only needing to make a small change to get all the data at once.
|
||||
```python
|
||||
import asyncio # asyncio for handling the async part
|
||||
from pyasic.network import MinerNetwork # miner network handles the scanning
|
||||
import asyncio# (1)!
|
||||
from pyasic.network import MinerNetwork# (2)!
|
||||
|
||||
|
||||
async def gather_miner_data(): # define async scan function to allow awaiting
|
||||
network = MinerNetwork.from_subnet("192.168.1.50/24")
|
||||
miners = await network.scan()
|
||||
async def gather_miner_data():# (3)!
|
||||
network = MinerNetwork.from_subnet("192.168.1.50/24")# (4)!
|
||||
miners = await network.scan()# (5)!
|
||||
|
||||
# we need to asyncio.gather() all the miners get_data() functions to make them run together
|
||||
all_miner_data = await asyncio.gather(*[miner.get_data() for miner in miners])
|
||||
|
||||
for miner_data in all_miner_data:
|
||||
print(miner_data) # print out all the data one by one
|
||||
print(miner_data)# (7)!
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(gather_miner_data())
|
||||
asyncio.run(gather_miner_data())# (8)!
|
||||
```
|
||||
|
||||
---
|
||||
1. `asyncio` for handling the async part.
|
||||
2. `MinerNetwork` handles the scanning.
|
||||
3. Define an async function to allow awaiting.
|
||||
4. Create a miner network.
|
||||
5. Scan for miners asynchronously.
|
||||
6. Use `asyncio.gather()` with all the miners' `get_data()` functions to make them run together.
|
||||
7. Print out the data one at a time.
|
||||
8. Get the miner data asynchronously with asyncio.run().
|
||||
|
||||
## Miner control
|
||||
---
|
||||
`pyasic` exposes a standard interface for each miner using control functions.
|
||||
Every miner class in `pyasic` must implement all the control functions defined in [`MinerProtocol`][pyasic.miners.base.MinerProtocol].
|
||||
Every miner class in `pyasic` must implement all the following control functions.
|
||||
|
||||
These functions are
|
||||
[`check_light`][pyasic.miners.base.MinerProtocol.check_light],
|
||||
[`fault_light_off`][pyasic.miners.base.MinerProtocol.fault_light_off],
|
||||
[`fault_light_on`][pyasic.miners.base.MinerProtocol.fault_light_on],
|
||||
@@ -166,35 +170,41 @@ These functions are
|
||||
[`send_config`][pyasic.miners.base.MinerProtocol.send_config], and
|
||||
[`set_power_limit`][pyasic.miners.base.MinerProtocol.set_power_limit].
|
||||
|
||||
##### Usage
|
||||
### Usage
|
||||
```python
|
||||
import asyncio
|
||||
from pyasic import get_miner
|
||||
import asyncio# (1)!
|
||||
from pyasic import get_miner# (2)!
|
||||
|
||||
|
||||
async def set_fault_light():
|
||||
miner = await get_miner("192.168.1.20")
|
||||
async def set_fault_light():# (3)!
|
||||
miner = await get_miner("192.168.1.20")# (4)!
|
||||
|
||||
# call control function
|
||||
await miner.fault_light_on()
|
||||
await miner.fault_light_on()# (5)!
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(set_fault_light())
|
||||
asyncio.run(set_fault_light())# (6)!
|
||||
```
|
||||
|
||||
---
|
||||
1. `asyncio` for handling the async part.
|
||||
2. `get_miner` handles the miner type selection.
|
||||
3. Define an async function to allow awaiting.
|
||||
4. Get the miner.
|
||||
5. Call the miner control function.
|
||||
6. Call the control function asynchronously with asyncio.run().
|
||||
|
||||
|
||||
## Helper dataclasses
|
||||
---
|
||||
|
||||
##### [`MinerConfig`][pyasic.config.MinerConfig] and [`MinerData`][pyasic.data.MinerData]
|
||||
### [`MinerConfig`][pyasic.config.MinerConfig] and [`MinerData`][pyasic.data.MinerData]
|
||||
|
||||
`pyasic` implements a few dataclasses as helpers to make data return types consistent across different miners and miner APIs. The different fields of these dataclasses can all be viewed with the classmethod `cls.fields()`.
|
||||
|
||||
---
|
||||
|
||||
##### [`MinerData`][pyasic.data.MinerData]
|
||||
### [`MinerData`][pyasic.data.MinerData]
|
||||
|
||||
[`MinerData`][pyasic.data.MinerData] is a return from the [`get_data()`](#get-data) function, and is used to have a consistent dataset across all returns.
|
||||
[`MinerData`][pyasic.data.MinerData] is a return from the [`get_data()`][pyasic.miners.base.MinerProtocol.get_data] function, and is used to have a consistent dataset across all returns.
|
||||
|
||||
You can call [`MinerData.as_dict()`][pyasic.data.MinerData.as_dict] to get the dataclass as a dictionary, and there are many other helper functions contained in the class to convert to different data formats.
|
||||
|
||||
@@ -213,13 +223,13 @@ average_data = sum(list_of_miner_data, start=MinerData("0.0.0.0"))/len(list_of_m
|
||||
|
||||
---
|
||||
|
||||
##### [`MinerConfig`][pyasic.config.MinerConfig]
|
||||
### [`MinerConfig`][pyasic.config.MinerConfig]
|
||||
|
||||
[`MinerConfig`][pyasic.config.MinerConfig] is `pyasic`'s way to represent a configuration file from a miner.
|
||||
It is designed to unionize the configuration of all supported miner types, and is the return from [`get_config()`](#get-config).
|
||||
It is designed to unionize the configuration of all supported miner types, and is the return from [`get_config()`][pyasic.miners.base.MinerProtocol.get_config].
|
||||
|
||||
Each miner has a unique way to convert the [`MinerConfig`][pyasic.config.MinerConfig] to their specific type, there are helper functions in the class.
|
||||
In most cases these helper functions should not be used, as [`send_config()`](#send-config) takes a [`MinerConfig`][pyasic.config.MinerConfig] and will do the conversion to the right type for you.
|
||||
In most cases these helper functions should not be used, as [`send_config()`][pyasic.miners.base.MinerProtocol.send_config] takes a [`MinerConfig`][pyasic.config.MinerConfig] and will do the conversion to the right type for you.
|
||||
|
||||
You can use the [`MinerConfig`][pyasic.config.MinerConfig] as follows:
|
||||
```python
|
||||
@@ -241,7 +251,6 @@ if __name__ == "__main__":
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
## Settings
|
||||
---
|
||||
`pyasic` has settings designed to make using large groups of miners easier. You can set the default password for all types of miners using the `pyasic.settings` module, used as follows:
|
||||
@@ -252,7 +261,7 @@ from pyasic import settings
|
||||
settings.update("default_antminer_web_password", "my_pwd")
|
||||
```
|
||||
|
||||
##### Default values:
|
||||
### Default values:
|
||||
```
|
||||
"network_ping_retries": 1,
|
||||
"network_ping_timeout": 3,
|
||||
|
||||
@@ -2,16 +2,28 @@
|
||||
## X15 Models
|
||||
|
||||
## Z15 (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.cgminer.X15.Z15.CGMinerZ15
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## Z15 Pro (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bmminer.X15.Z15.BMMinerZ15Pro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
|
||||
@@ -2,114 +2,210 @@
|
||||
## X17 Models
|
||||
|
||||
## S17 (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bmminer.X17.S17.BMMinerS17
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S17+ (Stock)
|
||||
::: pyasic.miners.antminer.bmminer.X17.S17.BMMinerS17Plus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## S17 Pro (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bmminer.X17.S17.BMMinerS17Pro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## S17+ (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bmminer.X17.S17.BMMinerS17Plus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## S17e (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bmminer.X17.S17.BMMinerS17e
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## T17 (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bmminer.X17.T17.BMMinerT17
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## T17+ (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bmminer.X17.T17.BMMinerT17Plus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## T17e (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bmminer.X17.T17.BMMinerT17e
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## S17 (BOS+)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [x] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bosminer.X17.S17.BOSMinerS17
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S17+ (BOS+)
|
||||
::: pyasic.miners.antminer.bosminer.X17.S17.BOSMinerS17Plus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## S17 Pro (BOS+)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [x] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bosminer.X17.S17.BOSMinerS17Pro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## S17+ (BOS+)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [x] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bosminer.X17.S17.BOSMinerS17Plus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## S17e (BOS+)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [x] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bosminer.X17.S17.BOSMinerS17e
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## T17 (BOS+)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [x] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bosminer.X17.T17.BOSMinerT17
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## T17+ (BOS+)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [x] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bosminer.X17.T17.BOSMinerT17Plus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## T17e (BOS+)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [x] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bosminer.X17.T17.BOSMinerT17e
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S17+ (VNish)
|
||||
::: pyasic.miners.antminer.vnish.X17.S17.VNishS17Plus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## S17 Pro (VNish)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [x] Setpoints
|
||||
- [x] Presets
|
||||
|
||||
::: pyasic.miners.antminer.vnish.X17.S17.VNishS17Pro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## S17+ (VNish)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [x] Setpoints
|
||||
- [x] Presets
|
||||
|
||||
::: pyasic.miners.antminer.vnish.X17.S17.VNishS17Plus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,86 +2,236 @@
|
||||
## X21 Models
|
||||
|
||||
## S21 (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bmminer.X21.S21.BMMinerS21
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## S21 Hydro (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bmminer.X21.S21.BMMinerS21Hydro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## S21 Pro (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bmminer.X21.S21.BMMinerS21Pro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## S21+ (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bmminer.X21.S21.BMMinerS21Plus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## S21+ Hydro (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bmminer.X21.S21.BMMinerS21PlusHydro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## T21 (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bmminer.X21.T21.BMMinerT21
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## S21 (BOS+)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [x] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bosminer.X21.S21.BOSMinerS21
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## S21 Pro (BOS+)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [x] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bosminer.X21.S21.BOSMinerS21Pro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## T21 (BOS+)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [x] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bosminer.X21.T21.BOSMinerT21
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## S21 (VNish)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [x] Setpoints
|
||||
- [x] Presets
|
||||
|
||||
::: pyasic.miners.antminer.vnish.X21.S21.VNishS21
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## T21 (VNish)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [x] Setpoints
|
||||
- [x] Presets
|
||||
|
||||
::: pyasic.miners.antminer.vnish.X21.T21.VNishT21
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## S21 (ePIC)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.epic.X21.S21.ePICS21
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## S21 Pro (ePIC)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.epic.X21.S21.ePICS21Pro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## T21 (ePIC)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.epic.X21.T21.ePICT21
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## S21 (LuxOS)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [x] Setpoints
|
||||
- [x] Presets
|
||||
|
||||
::: pyasic.miners.antminer.luxos.X21.S21.LUXMinerS21
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## T21 (LuxOS)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [x] Setpoints
|
||||
- [x] Presets
|
||||
|
||||
::: pyasic.miners.antminer.luxos.X21.T21.LUXMinerT21
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## S21 (MaraFW)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.marathon.X21.S21.MaraS21
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## T21 (MaraFW)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.marathon.X21.T21.MaraT21
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
|
||||
@@ -2,51 +2,80 @@
|
||||
## X3 Models
|
||||
|
||||
## D3 (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.cgminer.X3.D3.CGMinerD3
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## HS3 (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bmminer.X3.HS3.BMMinerHS3
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## L3+ (Stock)
|
||||
::: pyasic.miners.antminer.bmminer.X3.L3.BMMinerL3Plus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## KA3 (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bmminer.X3.KA3.BMMinerKA3
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## KS3 (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bmminer.X3.KS3.BMMinerKS3
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## L3+ (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bmminer.X3.L3.BMMinerL3Plus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## L3+ (VNish)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [x] Setpoints
|
||||
- [x] Presets
|
||||
|
||||
::: pyasic.miners.antminer.vnish.X3.L3.VnishL3Plus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## L3+ (VNish)
|
||||
::: pyasic.miners.antminer.vnish.X3.L3.VnishL3Plus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
|
||||
@@ -2,16 +2,41 @@
|
||||
## X5 Models
|
||||
|
||||
## DR5 (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.cgminer.X5.DR5.CGMinerDR5
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## KS5 (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bmminer.X5.KS5.BMMinerKS5
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## KS5 (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bmminer.X5.KS5.BMMinerKS5Pro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
|
||||
@@ -1,31 +1,55 @@
|
||||
# pyasic
|
||||
## X7 Models
|
||||
|
||||
## L7 (Stock)
|
||||
::: pyasic.miners.antminer.bmminer.X7.L7.BMMinerL7
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## K7 (Stock)
|
||||
::: pyasic.miners.antminer.bmminer.X7.K7.BMMinerK7
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## D7 (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bmminer.X7.D7.BMMinerD7
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## K7 (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bmminer.X7.K7.BMMinerK7
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## L7 (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bmminer.X7.L7.BMMinerL7
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## L7 (VNish)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [x] Setpoints
|
||||
- [x] Presets
|
||||
|
||||
::: pyasic.miners.antminer.vnish.X7.L7.VnishL7
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
|
||||
@@ -1,66 +1,133 @@
|
||||
# pyasic
|
||||
## X9 Models
|
||||
|
||||
## E9Pro (Stock)
|
||||
::: pyasic.miners.antminer.bmminer.X9.E9.BMMinerE9Pro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## D9 (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bmminer.X9.D9.BMMinerD9
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## E9Pro (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bmminer.X9.E9.BMMinerE9Pro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## L9 (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bmminer.X9.L9.BMMinerL9
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## S9 (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bmminer.X9.S9.BMMinerS9
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## S9i (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bmminer.X9.S9.BMMinerS9i
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## S9j (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bmminer.X9.S9.BMMinerS9j
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## T9 (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bmminer.X9.T9.BMMinerT9
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## S9 (BOS+)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [x] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bosminer.X9.S9.BOSMinerS9
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## T9 (Hive)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
## T9 (Stock)
|
||||
::: pyasic.miners.antminer.hiveon.X9.T9.HiveonT9
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## S9 (LuxOS)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [x] Setpoints
|
||||
- [x] Presets
|
||||
|
||||
::: pyasic.miners.antminer.luxos.X9.S9.LUXMinerS9
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
|
||||
@@ -2,23 +2,41 @@
|
||||
## AD Models
|
||||
|
||||
## AT1500 (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [x] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.auradine.flux.AD.AT1.AuradineFluxAT1500
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## AT2860 (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [x] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.auradine.flux.AD.AT2.AuradineFluxAT2860
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## AT2880 (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [x] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.auradine.flux.AD.AT2.AuradineFluxAT2880
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
|
||||
@@ -2,16 +2,28 @@
|
||||
## AI Models
|
||||
|
||||
## AI2500 (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [x] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.auradine.flux.AI.AI2.AuradineFluxAI2500
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## AI3680 (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [x] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.auradine.flux.AI.AI3.AuradineFluxAI3680
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
|
||||
@@ -2,16 +2,28 @@
|
||||
## AT Models
|
||||
|
||||
## AD2500 (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [x] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.auradine.flux.AT.AD2.AuradineFluxAD2500
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## AD3500 (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [x] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.auradine.flux.AT.AD3.AuradineFluxAD3500
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
|
||||
@@ -2,23 +2,41 @@
|
||||
## A10X Models
|
||||
|
||||
## Avalon 1026 (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.avalonminer.cgminer.A10X.A1026.CGMinerAvalon1026
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## Avalon 1047 (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.avalonminer.cgminer.A10X.A1047.CGMinerAvalon1047
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## Avalon 1066 (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.avalonminer.cgminer.A10X.A1066.CGMinerAvalon1066
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
|
||||
@@ -1,10 +1,29 @@
|
||||
# pyasic
|
||||
## A11X Models
|
||||
|
||||
## Avalon 1126 Pro (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.avalonminer.cgminer.A11X.A1126.CGMinerAvalon1126Pro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## Avalon 1166 Pro (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.avalonminer.cgminer.A11X.A1166.CGMinerAvalon1166Pro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
|
||||
@@ -2,9 +2,15 @@
|
||||
## A12X Models
|
||||
|
||||
## Avalon 1246 (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.avalonminer.cgminer.A12X.A1246.CGMinerAvalon1246
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
|
||||
16
docs/miners/avalonminer/A15X.md
Normal file
16
docs/miners/avalonminer/A15X.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# pyasic
|
||||
## A15X Models
|
||||
|
||||
## Avalon 1566 (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.avalonminer.cgminer.A15X.A1566.CGMinerAvalon1566
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
@@ -2,23 +2,41 @@
|
||||
## A7X Models
|
||||
|
||||
## Avalon 721 (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.avalonminer.cgminer.A7X.A721.CGMinerAvalon721
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## Avalon 741 (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.avalonminer.cgminer.A7X.A741.CGMinerAvalon741
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## Avalon 761 (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.avalonminer.cgminer.A7X.A761.CGMinerAvalon761
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
|
||||
@@ -2,23 +2,41 @@
|
||||
## A8X Models
|
||||
|
||||
## Avalon 821 (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.avalonminer.cgminer.A8X.A821.CGMinerAvalon821
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## Avalon 841 (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.avalonminer.cgminer.A8X.A841.CGMinerAvalon841
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## Avalon 851 (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.avalonminer.cgminer.A8X.A851.CGMinerAvalon851
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
|
||||
@@ -2,9 +2,15 @@
|
||||
## A9X Models
|
||||
|
||||
## Avalon 921 (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.avalonminer.cgminer.A9X.A921.CGMinerAvalon921
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
|
||||
@@ -1,10 +1,29 @@
|
||||
# pyasic
|
||||
## nano Models
|
||||
|
||||
## Avalon Nano 3s (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.avalonminer.cgminer.nano.nano3.CGMinerAvalonNano3s
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## Avalon Nano 3 (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.avalonminer.cgminer.nano.nano3.CGMinerAvalonNano3
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
# pyasic
|
||||
## Hiveon Backend
|
||||
## Modern Hiveon Backend
|
||||
|
||||
::: pyasic.miners.backends.hiveon.Hiveon
|
||||
::: pyasic.miners.backends.hiveon.HiveonModern
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## Old Hiveon Backend
|
||||
::: pyasic.miners.backends.hiveon.HiveonOld
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
|
||||
@@ -10,8 +10,3 @@ You may not instantiate this class on its own, only subclass from it.
|
||||
handler: python
|
||||
options:
|
||||
heading_level: 4
|
||||
|
||||
::: pyasic.miners.base.MinerProtocol
|
||||
handler: python
|
||||
options:
|
||||
heading_level: 4
|
||||
|
||||
@@ -1,31 +1,55 @@
|
||||
# pyasic
|
||||
## BM Models
|
||||
|
||||
## Supra (Stock)
|
||||
::: pyasic.miners.bitaxe.espminer.BM.BM1368.BitAxeSupra
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## Ultra (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.bitaxe.espminer.BM.BM1366.BitAxeUltra
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## Max (Stock)
|
||||
::: pyasic.miners.bitaxe.espminer.BM.BM1397.BitAxeMax
|
||||
## Supra (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.bitaxe.espminer.BM.BM1368.BitAxeSupra
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## Gamma (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.bitaxe.espminer.BM.BM1370.BitAxeGamma
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## Max (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.bitaxe.espminer.BM.BM1397.BitAxeMax
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
|
||||
@@ -2,16 +2,41 @@
|
||||
## blockminer Models
|
||||
|
||||
## BlockMiner 520i (ePIC)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.blockminer.epic.blockminer.blockminer.ePICBlockMiner520i
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## BlockMiner 720i (ePIC)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.blockminer.epic.blockminer.blockminer.ePICBlockMiner720i
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## BlockMiner eLITE 1.0 (ePIC)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.blockminer.epic.blockminer.blockminer.ePICBlockMinerELITE1
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
|
||||
29
docs/miners/braiins/BMM.md
Normal file
29
docs/miners/braiins/BMM.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# pyasic
|
||||
## BMM Models
|
||||
|
||||
## BMM100 (BOS+)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [x] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.braiins.braiins.BMM.BMM.BraiinsBMM100
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## BMM101 (BOS+)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [x] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.braiins.braiins.BMM.BMM.BraiinsBMM101
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
16
docs/miners/elphapex/DGX.md
Normal file
16
docs/miners/elphapex/DGX.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# pyasic
|
||||
## DGX Models
|
||||
|
||||
## DG1+ (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.elphapex.daoge.DGX.DG1.ElphapexDG1Plus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
@@ -1,91 +1,10 @@
|
||||
## Control functionality
|
||||
|
||||
### Check Light
|
||||
::: pyasic.miners.base.MinerProtocol.check_light
|
||||
handler: python
|
||||
options:
|
||||
heading_level: 4
|
||||
All control functionality is outlined by the [`MinerProtocol`][pyasic.miners.base.MinerProtocol] class.
|
||||
|
||||
### Fault Light Off
|
||||
::: pyasic.miners.base.MinerProtocol.fault_light_off
|
||||
handler: python
|
||||
options:
|
||||
heading_level: 4
|
||||
## Miner Protocol
|
||||
|
||||
### Fault Light On
|
||||
::: pyasic.miners.base.MinerProtocol.fault_light_on
|
||||
handler: python
|
||||
options:
|
||||
heading_level: 4
|
||||
|
||||
### Get Config
|
||||
::: pyasic.miners.base.MinerProtocol.get_config
|
||||
handler: python
|
||||
options:
|
||||
heading_level: 4
|
||||
|
||||
### Get Data
|
||||
::: pyasic.miners.base.MinerProtocol.get_data
|
||||
handler: python
|
||||
options:
|
||||
heading_level: 4
|
||||
|
||||
### Get Errors
|
||||
::: pyasic.miners.base.MinerProtocol.get_errors
|
||||
handler: python
|
||||
options:
|
||||
heading_level: 4
|
||||
|
||||
### Get Hostname
|
||||
::: pyasic.miners.base.MinerProtocol.get_hostname
|
||||
handler: python
|
||||
options:
|
||||
heading_level: 4
|
||||
|
||||
### Get Model
|
||||
::: pyasic.miners.base.MinerProtocol.get_model
|
||||
handler: python
|
||||
options:
|
||||
heading_level: 4
|
||||
|
||||
### Reboot
|
||||
::: pyasic.miners.base.MinerProtocol.reboot
|
||||
handler: python
|
||||
options:
|
||||
heading_level: 4
|
||||
|
||||
### Restart Backend
|
||||
::: pyasic.miners.base.MinerProtocol.restart_backend
|
||||
handler: python
|
||||
options:
|
||||
heading_level: 4
|
||||
|
||||
### Stop Mining
|
||||
::: pyasic.miners.base.MinerProtocol.stop_mining
|
||||
handler: python
|
||||
options:
|
||||
heading_level: 4
|
||||
|
||||
### Resume Mining
|
||||
::: pyasic.miners.base.MinerProtocol.resume_mining
|
||||
handler: python
|
||||
options:
|
||||
heading_level: 4
|
||||
|
||||
### Is Mining
|
||||
::: pyasic.miners.base.MinerProtocol.is_mining
|
||||
handler: python
|
||||
options:
|
||||
heading_level: 4
|
||||
|
||||
### Send Config
|
||||
::: pyasic.miners.base.MinerProtocol.send_config
|
||||
handler: python
|
||||
options:
|
||||
heading_level: 4
|
||||
|
||||
### Set Power Limit
|
||||
::: pyasic.miners.base.MinerProtocol.set_power_limit
|
||||
::: pyasic.miners.base.MinerProtocol
|
||||
handler: python
|
||||
options:
|
||||
heading_level: 4
|
||||
|
||||
@@ -2,23 +2,41 @@
|
||||
## X5 Models
|
||||
|
||||
## CK5 (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.goldshell.bfgminer.X5.CK5.GoldshellCK5
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## HS5 (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.goldshell.bfgminer.X5.HS5.GoldshellHS5
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## KD5 (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.goldshell.bfgminer.X5.KD5.GoldshellKD5
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
|
||||
@@ -2,16 +2,28 @@
|
||||
## XBox Models
|
||||
|
||||
## KD Box II (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.goldshell.bfgminer.XBox.KDBox.GoldshellKDBoxII
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## KD Box Pro (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.goldshell.bfgminer.XBox.KDBox.GoldshellKDBoxPro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
|
||||
@@ -2,9 +2,15 @@
|
||||
## XMax Models
|
||||
|
||||
## KD Max (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.goldshell.bfgminer.XMax.KDMax.GoldshellKDMax
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
|
||||
@@ -2,9 +2,15 @@
|
||||
## DX Models
|
||||
|
||||
## D10 (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.hammer.blackminer.DX.D10.HammerD10
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
|
||||
@@ -2,65 +2,119 @@
|
||||
## KSX Models
|
||||
|
||||
## KS0 (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.iceriver.iceminer.KSX.KS0.IceRiverKS0
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## KS1 (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.iceriver.iceminer.KSX.KS1.IceRiverKS1
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## KS2 (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.iceriver.iceminer.KSX.KS2.IceRiverKS2
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## KS3 (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.iceriver.iceminer.KSX.KS3.IceRiverKS3
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## KS3L (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.iceriver.iceminer.KSX.KS3.IceRiverKS3L
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## KS3M (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.iceriver.iceminer.KSX.KS3.IceRiverKS3M
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## KS5 (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.iceriver.iceminer.KSX.KS5.IceRiverKS5
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## KS5L (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.iceriver.iceminer.KSX.KS5.IceRiverKS5L
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## KS5M (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.iceriver.iceminer.KSX.KS5.IceRiverKS5M
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
|
||||
@@ -2,9 +2,15 @@
|
||||
## A10X Models
|
||||
|
||||
## A10X (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.innosilicon.cgminer.A10X.A10X.InnosiliconA10X
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
|
||||
@@ -2,16 +2,28 @@
|
||||
## A11X Models
|
||||
|
||||
## A11 (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.innosilicon.cgminer.A11X.A11.InnosiliconA11
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## A11MX (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.innosilicon.cgminer.A11X.A11M.InnosiliconA11MX
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
|
||||
@@ -2,9 +2,15 @@
|
||||
## T3X Models
|
||||
|
||||
## T3H+ (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.innosilicon.cgminer.T3X.T3H.InnosiliconT3HPlus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
|
||||
29
docs/miners/luckyminer/LV.md
Normal file
29
docs/miners/luckyminer/LV.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# pyasic
|
||||
## LV Models
|
||||
|
||||
## LV07 (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.luckyminer.espminer.LV.LV07.LuckyMinerLV07
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## LV08 (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.luckyminer.espminer.LV.LV08.LuckyMinerLV08
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
Supported miner types are here on this list. If your miner (or miner version) is not on this list, please feel free to [open an issue on GitHub](https://github.com/UpstreamData/pyasic/issues) to get it added.
|
||||
|
||||
Keep in mind that some functionality is only supported for specific miners or firmwares, please check the page for your miner to make sure the functionality you need is supported.
|
||||
|
||||
##### pyasic currently supports the following miners and subtypes:
|
||||
<style>
|
||||
details {
|
||||
@@ -30,6 +32,7 @@ details {
|
||||
<ul>
|
||||
<li><a href="../antminer/X5#dr5-stock">DR5 (Stock)</a></li>
|
||||
<li><a href="../antminer/X5#ks5-stock">KS5 (Stock)</a></li>
|
||||
<li><a href="../antminer/X5#ks5-stock">KS5 (Stock)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
@@ -49,6 +52,7 @@ details {
|
||||
<li><a href="../antminer/X9#s9i-stock">S9i (Stock)</a></li>
|
||||
<li><a href="../antminer/X9#s9j-stock">S9j (Stock)</a></li>
|
||||
<li><a href="../antminer/X9#t9-stock">T9 (Stock)</a></li>
|
||||
<li><a href="../antminer/X9#l9-stock">L9 (Stock)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
@@ -89,6 +93,7 @@ details {
|
||||
<li><a href="../antminer/X19#s19-pro-hydro-stock">S19 Pro Hydro (Stock)</a></li>
|
||||
<li><a href="../antminer/X19#s19-pro_1-hydro-stock">S19 Pro+ Hydro (Stock)</a></li>
|
||||
<li><a href="../antminer/X19#s19k-pro-stock">S19K Pro (Stock)</a></li>
|
||||
<li><a href="../antminer/X19#s19j-xp-stock">S19j XP (Stock)</a></li>
|
||||
<li><a href="../antminer/X19#t19-stock">T19 (Stock)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
@@ -96,8 +101,13 @@ details {
|
||||
<summary>X21 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X21#s21-stock">S21 (Stock)</a></li>
|
||||
<li><a href="../antminer/X21#s21-stock">S21 (Stock)</a></li>
|
||||
<li><a href="../antminer/X21#s21-stock">S21 (Stock)</a></li>
|
||||
<li><a href="../antminer/X21#s21_1-stock">S21+ (Stock)</a></li>
|
||||
<li><a href="../antminer/X21#s21_1-hydro-stock">S21+ Hydro (Stock)</a></li>
|
||||
<li><a href="../antminer/X21#s21-pro-stock">S21 Pro (Stock)</a></li>
|
||||
<li><a href="../antminer/X21#t21-stock">T21 (Stock)</a></li>
|
||||
<li><a href="../antminer/X21#s21-hydro-stock">S21 Hydro (Stock)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
@@ -108,28 +118,89 @@ details {
|
||||
<details>
|
||||
<summary>M2X Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../whatsminer/M2X#m20-v10-stock">M20 V10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M2X#m20s-v10-stock">M20S V10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M2X#m20s-v20-stock">M20S V20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M2X#m20s-v30-stock">M20S V30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M2X#m20p-v10-stock">M20P V10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M2X#m20p-v30-stock">M20P V30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M2X#m20s_1-v30-stock">M20S+ V30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M2X#m21-v10-stock">M21 V10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M2X#m20s-v10-stock">M20S V10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M2X#m20s-v20-stock">M20S V20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M2X#m20s-v30-stock">M20S V30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M2X#m20-v10-stock">M20 V10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M2X#m21s_1-v20-stock">M21S+ V20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M2X#m21s-v20-stock">M21S V20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M2X#m21s-v60-stock">M21S V60 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M2X#m21s-v70-stock">M21S V70 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M2X#m21s_1-v20-stock">M21S+ V20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M2X#m21-v10-stock">M21 V10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M2X#m29-v10-stock">M29 V10 (Stock)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>M3X Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../whatsminer/M3X#m30-v10-stock">M30 V10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30-v20-stock">M30 V20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30k-v10-stock">M30K V10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30l-v10-stock">M30L V10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-v10-stock">M30S++ V10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-v20-stock">M30S++ V20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-ve30-stock">M30S++ VE30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-ve40-stock">M30S++ VE40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-ve50-stock">M30S++ VE50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vf40-stock">M30S++ VF40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vg30-stock">M30S++ VG30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vg40-stock">M30S++ VG40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vg50-stock">M30S++ VG50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vh10-stock">M30S++ VH10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vh100-stock">M30S++ VH100 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vh110-stock">M30S++ VH110 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vh20-stock">M30S++ VH20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vh30-stock">M30S++ VH30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vh40-stock">M30S++ VH40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vh50-stock">M30S++ VH50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vh60-stock">M30S++ VH60 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vh70-stock">M30S++ VH70 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vh80-stock">M30S++ VH80 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vh90-stock">M30S++ VH90 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vi30-stock">M30S++ VI30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vj20-stock">M30S++ VJ20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vj30-stock">M30S++ VJ30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vj50-stock">M30S++ VJ50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vj60-stock">M30S++ VJ60 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vj70-stock">M30S++ VJ70 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vk30-stock">M30S++ VK30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vk40-stock">M30S++ VK40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-v10-stock">M30S+ V10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-v100-stock">M30S+ V100 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-v20-stock">M30S+ V20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-v30-stock">M30S+ V30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-v40-stock">M30S+ V40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-v50-stock">M30S+ V50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-v60-stock">M30S+ V60 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-v70-stock">M30S+ V70 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-v80-stock">M30S+ V80 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-v90-stock">M30S+ V90 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-ve100-stock">M30S+ VE100 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-ve30-stock">M30S+ VE30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-ve40-stock">M30S+ VE40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-ve50-stock">M30S+ VE50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-ve60-stock">M30S+ VE60 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-ve70-stock">M30S+ VE70 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-ve80-stock">M30S+ VE80 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-ve90-stock">M30S+ VE90 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vf20-stock">M30S+ VF20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vf30-stock">M30S+ VF30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vg20-stock">M30S+ VG20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vg30-stock">M30S+ VG30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vg40-stock">M30S+ VG40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vg50-stock">M30S+ VG50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vg60-stock">M30S+ VG60 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vh10-stock">M30S+ VH10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vh20-stock">M30S+ VH20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vh30-stock">M30S+ VH30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vh40-stock">M30S+ VH40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vh50-stock">M30S+ VH50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vh60-stock">M30S+ VH60 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vh70-stock">M30S+ VH70 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vi30-stock">M30S+ VI30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vj30-stock">M30S+ VJ30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vj40-stock">M30S+ VJ40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-v10-stock">M30S V10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-v20-stock">M30S V20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-v30-stock">M30S V30 (Stock)</a></li>
|
||||
@@ -159,63 +230,35 @@ details {
|
||||
<li><a href="../whatsminer/M3X#m30s-vh50-stock">M30S VH50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-vh60-stock">M30S VH60 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-vi20-stock">M30S VI20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-v10-stock">M30S+ V10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-v20-stock">M30S+ V20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-v30-stock">M30S+ V30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-v40-stock">M30S+ V40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-v50-stock">M30S+ V50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-v60-stock">M30S+ V60 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-v70-stock">M30S+ V70 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-v80-stock">M30S+ V80 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-v90-stock">M30S+ V90 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-v100-stock">M30S+ V100 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-ve30-stock">M30S+ VE30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-ve40-stock">M30S+ VE40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-ve50-stock">M30S+ VE50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-ve60-stock">M30S+ VE60 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-ve70-stock">M30S+ VE70 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-ve80-stock">M30S+ VE80 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-ve90-stock">M30S+ VE90 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-ve100-stock">M30S+ VE100 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vf20-stock">M30S+ VF20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vf30-stock">M30S+ VF30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vg20-stock">M30S+ VG20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vg30-stock">M30S+ VG30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vg40-stock">M30S+ VG40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vg50-stock">M30S+ VG50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vg60-stock">M30S+ VG60 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vh10-stock">M30S+ VH10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vh20-stock">M30S+ VH20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vh30-stock">M30S+ VH30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vh40-stock">M30S+ VH40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vh50-stock">M30S+ VH50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1-vh60-stock">M30S+ VH60 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-v10-stock">M30S++ V10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-v20-stock">M30S++ V20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-ve30-stock">M30S++ VE30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-ve40-stock">M30S++ VE40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-ve50-stock">M30S++ VE50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vf40-stock">M30S++ VF40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vg30-stock">M30S++ VG30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vg40-stock">M30S++ VG40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vg50-stock">M30S++ VG50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vh10-stock">M30S++ VH10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vh20-stock">M30S++ VH20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vh30-stock">M30S++ VH30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vh40-stock">M30S++ VH40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vh50-stock">M30S++ VH50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vh60-stock">M30S++ VH60 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vh70-stock">M30S++ VH70 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vh80-stock">M30S++ VH80 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vh90-stock">M30S++ VH90 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vh100-stock">M30S++ VH100 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vj20-stock">M30S++ VJ20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s_1_1-vj30-stock">M30S++ VJ30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31-v10-stock">M31 V10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31-v20-stock">M31 V20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30s-vj30-stock">M30S VJ30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30-v10-stock">M30 V10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30-v20-stock">M30 V20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31h-v10-stock">M31H V10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31h-v40-stock">M31H V40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m30l-v10-stock">M30L V10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31l-v10-stock">M31L V10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-v10-stock">M31S+ V10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-v100-stock">M31S+ V100 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-v20-stock">M31S+ V20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-v30-stock">M31S+ V30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-v40-stock">M31S+ V40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-v50-stock">M31S+ V50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-v60-stock">M31S+ V60 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-v80-stock">M31S+ V80 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-v90-stock">M31S+ V90 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-ve10-stock">M31S+ VE10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-ve20-stock">M31S+ VE20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-ve30-stock">M31S+ VE30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-ve40-stock">M31S+ VE40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-ve50-stock">M31S+ VE50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-ve60-stock">M31S+ VE60 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-ve80-stock">M31S+ VE80 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-vf20-stock">M31S+ VF20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-vf30-stock">M31S+ VF30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-vg20-stock">M31S+ VG20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-vg30-stock">M31S+ VG30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31se-v10-stock">M31SE V10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31se-v20-stock">M31SE V20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31se-v30-stock">M31SE V30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s-v10-stock">M31S V10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s-v20-stock">M31S V20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s-v30-stock">M31S V30 (Stock)</a></li>
|
||||
@@ -228,45 +271,25 @@ details {
|
||||
<li><a href="../whatsminer/M3X#m31s-ve10-stock">M31S VE10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s-ve20-stock">M31S VE20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s-ve30-stock">M31S VE30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31se-v10-stock">M31SE V10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31se-v20-stock">M31SE V20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31se-v30-stock">M31SE V30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-v10-stock">M31S+ V10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-v20-stock">M31S+ V20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-v30-stock">M31S+ V30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-v40-stock">M31S+ V40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-v50-stock">M31S+ V50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-v60-stock">M31S+ V60 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-v80-stock">M31S+ V80 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-v90-stock">M31S+ V90 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-v100-stock">M31S+ V100 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-ve10-stock">M31S+ VE10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-ve20-stock">M31S+ VE20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-ve30-stock">M31S+ VE30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-ve40-stock">M31S+ VE40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-ve50-stock">M31S+ VE50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-ve60-stock">M31S+ VE60 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-ve80-stock">M31S+ VE80 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-vf20-stock">M31S+ VF20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-vf30-stock">M31S+ VF30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-vg20-stock">M31S+ VG20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31s_1-vg30-stock">M31S+ VG30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31-v10-stock">M31 V10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m31-v20-stock">M31 V20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m32-v10-stock">M32 V10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m32-v20-stock">M32 V20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m33s_1_1-vg40-stock">M33S++ VG40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m33s_1_1-vh20-stock">M33S++ VH20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m33s_1_1-vh30-stock">M33S++ VH30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m33s_1-vg20-stock">M33S+ VG20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m33s_1-vg30-stock">M33S+ VG30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m33s_1-vh20-stock">M33S+ VH20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m33s_1-vh30-stock">M33S+ VH30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m33s-vg30-stock">M33S VG30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m33-v10-stock">M33 V10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m33-v20-stock">M33 V20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m33-v30-stock">M33 V30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m33s-vg30-stock">M33S VG30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m33s_1-vg20-stock">M33S+ VG20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m33s_1-vh20-stock">M33S+ VH20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m33s_1-vh30-stock">M33S+ VH30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m33s_1_1-vh20-stock">M33S++ VH20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m33s_1_1-vh30-stock">M33S++ VH30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m33s_1_1-vg40-stock">M33S++ VG40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m34s_1-ve10-stock">M34S+ VE10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m36s-ve10-stock">M36S VE10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m36s_1-vg30-stock">M36S+ VG30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m36s_1_1-vh30-stock">M36S++ VH30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m36s_1-vg30-stock">M36S+ VG30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m36s-ve10-stock">M36S VE10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m39-v10-stock">M39 V10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m39-v20-stock">M39 V20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M3X#m39-v30-stock">M39 V30 (Stock)</a></li>
|
||||
@@ -275,6 +298,47 @@ details {
|
||||
<details>
|
||||
<summary>M5X Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../whatsminer/M5X#m50s_1_1-vk10-stock">M50S++ VK10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1_1-vk20-stock">M50S++ VK20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1_1-vk30-stock">M50S++ VK30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1_1-vk40-stock">M50S++ VK40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1_1-vk50-stock">M50S++ VK50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1_1-vk60-stock">M50S++ VK60 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1_1-vl20-stock">M50S++ VL20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1_1-vl30-stock">M50S++ VL30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1_1-vl40-stock">M50S++ VL40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1_1-vl50-stock">M50S++ VL50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1_1-vl60-stock">M50S++ VL60 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1-vh30-stock">M50S+ VH30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1-vh40-stock">M50S+ VH40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1-vj30-stock">M50S+ VJ30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1-vj40-stock">M50S+ VJ40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1-vj60-stock">M50S+ VJ60 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1-vk10-stock">M50S+ VK10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1-vk20-stock">M50S+ VK20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1-vk30-stock">M50S+ VK30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1-vl10-stock">M50S+ VL10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1-vl20-stock">M50S+ VL20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1-vl30-stock">M50S+ VL30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vh10-stock">M50S VH10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vh20-stock">M50S VH20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vh30-stock">M50S VH30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vh40-stock">M50S VH40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vh50-stock">M50S VH50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vj10-stock">M50S VJ10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vj20-stock">M50S VJ20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vj30-stock">M50S VJ30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vj40-stock">M50S VJ40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vj50-stock">M50S VJ50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vk10-stock">M50S VK10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vk20-stock">M50S VK20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vk30-stock">M50S VK30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vk50-stock">M50S VK50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vk60-stock">M50S VK60 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vk70-stock">M50S VK70 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vk80-stock">M50S VK80 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vl20-stock">M50S VL20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vl30-stock">M50S VL30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50-ve30-stock">M50 VE30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50-vg30-stock">M50 VG30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50-vh10-stock">M50 VH10 (Stock)</a></li>
|
||||
@@ -289,54 +353,153 @@ details {
|
||||
<li><a href="../whatsminer/M5X#m50-vj10-stock">M50 VJ10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50-vj20-stock">M50 VJ20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50-vj30-stock">M50 VJ30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vj10-stock">M50S VJ10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vj20-stock">M50S VJ20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vj30-stock">M50S VJ30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vh10-stock">M50S VH10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vh20-stock">M50S VH20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vh30-stock">M50S VH30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vh40-stock">M50S VH40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s-vh50-stock">M50S VH50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1-vh30-stock">M50S+ VH30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1-vh40-stock">M50S+ VH40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1-vj30-stock">M50S+ VJ30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1-vk20-stock">M50S+ VK20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1_1-vk10-stock">M50S++ VK10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1_1-vk20-stock">M50S++ VK20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50s_1_1-vk30-stock">M50S++ VK30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m53-vh30-stock">M53 VH30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m53s-vh30-stock">M53S VH30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m53s-vj40-stock">M53S VJ40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m53s_1-vj30-stock">M53S+ VJ30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50-vj40-stock">M50 VJ40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50-vj60-stock">M50 VJ60 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50-vk40-stock">M50 VK40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50-vk50-stock">M50 VK50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m52s_1_1-vl10-stock">M52S++ VL10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m52s-vk30-stock">M52S VK30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m53h-vh10-stock">M53H VH10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m53s_1_1-vk10-stock">M53S++ VK10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m56-vh30-stock">M56 VH30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m56s-vh30-stock">M56S VH30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m53s_1_1-vk20-stock">M53S++ VK20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m53s_1_1-vk30-stock">M53S++ VK30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m53s_1_1-vk50-stock">M53S++ VK50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m53s_1_1-vl10-stock">M53S++ VL10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m53s_1_1-vl30-stock">M53S++ VL30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m53s_1-vj30-stock">M53S+ VJ30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m53s_1-vj40-stock">M53S+ VJ40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m53s_1-vj50-stock">M53S+ VJ50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m53s_1-vk30-stock">M53S+ VK30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m53s-vh20-stock">M53S VH20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m53s-vh30-stock">M53S VH30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m53s-vj30-stock">M53S VJ30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m53s-vj40-stock">M53S VJ40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m53s-vk30-stock">M53S VK30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m53-vh30-stock">M53 VH30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m53-vh40-stock">M53 VH40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m53-vh50-stock">M53 VH50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m53-vk30-stock">M53 VK30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m53-vk60-stock">M53 VK60 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m54s_1_1-vk30-stock">M54S++ VK30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m54s_1_1-vl30-stock">M54S++ VL30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m54s_1_1-vl40-stock">M54S++ VL40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m56s_1_1-vk10-stock">M56S++ VK10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m56s_1_1-vk30-stock">M56S++ VK30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m56s_1_1-vk40-stock">M56S++ VK40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m56s_1_1-vk50-stock">M56S++ VK50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m56s_1-vj30-stock">M56S+ VJ30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m56s_1-vk30-stock">M56S+ VK30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m56s_1-vk40-stock">M56S+ VK40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m56s_1-vk50-stock">M56S+ VK50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m56s-vh30-stock">M56S VH30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m56s-vj30-stock">M56S VJ30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m56s-vj40-stock">M56S VJ40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m56-vh30-stock">M56 VH30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m59-vh30-stock">M59 VH30 (Stock)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>M6X Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../whatsminer/M6X#m60-vk10-stock">M60 VK10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60-vk20-stock">M60 VK20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60-vk30-stock">M60 VK30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60-vk40-stock">M60 VK40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60s_1_1-vl30-stock">M60S++ VL30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60s_1_1-vl40-stock">M60S++ VL40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60s_1-vk30-stock">M60S+ VK30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60s_1-vk40-stock">M60S+ VK40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60s_1-vk50-stock">M60S+ VK50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60s_1-vk60-stock">M60S+ VK60 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60s_1-vk70-stock">M60S+ VK70 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60s_1-vl10-stock">M60S+ VL10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60s_1-vl30-stock">M60S+ VL30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60s_1-vl40-stock">M60S+ VL40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60s_1-vl50-stock">M60S+ VL50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60s_1-vl60-stock">M60S+ VL60 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60s-vk10-stock">M60S VK10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60s-vk20-stock">M60S VK20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60s-vk30-stock">M60S VK30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60s-vk40-stock">M60S VK40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m63-vk10-stock">M63 VK10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m63-vk20-stock">M63 VK20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m63-vk30-stock">M63 VK30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60s-vl10-stock">M60S VL10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60s-vl20-stock">M60S VL20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60s-vl30-stock">M60S VL30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60s-vl40-stock">M60S VL40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60s-vl50-stock">M60S VL50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60s-vl60-stock">M60S VL60 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60s-vl70-stock">M60S VL70 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60-vk10-stock">M60 VK10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60-vk20-stock">M60 VK20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60-vk30-stock">M60 VK30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60-vk40-stock">M60 VK40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60-vk6a-stock">M60 VK6A (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60-vl10-stock">M60 VL10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60-vl20-stock">M60 VL20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60-vl30-stock">M60 VL30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60-vl40-stock">M60 VL40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m60-vl50-stock">M60 VL50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m61s_1-vl30-stock">M61S+ VL30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m61s-vl10-stock">M61S VL10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m61s-vl20-stock">M61S VL20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m61s-vl30-stock">M61S VL30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m61-vk10-stock">M61 VK10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m61-vk20-stock">M61 VK20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m61-vk30-stock">M61 VK30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m61-vk40-stock">M61 VK40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m61-vl10-stock">M61 VL10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m61-vl30-stock">M61 VL30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m61-vl40-stock">M61 VL40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m61-vl50-stock">M61 VL50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m61-vl60-stock">M61 VL60 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m62s_1-vk30-stock">M62S+ VK30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m63s_1_1-vl20-stock">M63S++ VL20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m63s_1-vk30-stock">M63S+ VK30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m63s_1-vl10-stock">M63S+ VL10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m63s_1-vl20-stock">M63S+ VL20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m63s_1-vl30-stock">M63S+ VL30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m63s_1-vl50-stock">M63S+ VL50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m63s-vk10-stock">M63S VK10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m63s-vk20-stock">M63S VK20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m63s-vk30-stock">M63S VK30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m66-vk20-stock">M66 VK20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m66-vk30-stock">M66 VK30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m63s-vk60-stock">M63S VK60 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m63s-vl10-stock">M63S VL10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m63s-vl50-stock">M63S VL50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m63s-vl60-stock">M63S VL60 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m63-vk10-stock">M63 VK10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m63-vk20-stock">M63 VK20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m63-vk30-stock">M63 VK30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m63-vl10-stock">M63 VL10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m63-vl30-stock">M63 VL30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m64s-vl30-stock">M64S VL30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m64-vl30-stock">M64 VL30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m64-vl40-stock">M64 VL40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m65s_1-vk30-stock">M65S+ VK30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m65s-vk20-stock">M65S VK20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m65s-vl60-stock">M65S VL60 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m66s_1_1-vl20-stock">M66S++ VL20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m66s_1-vk30-stock">M66S+ VK30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m66s_1-vl10-stock">M66S+ VL10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m66s_1-vl20-stock">M66S+ VL20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m66s_1-vl30-stock">M66S+ VL30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m66s_1-vl40-stock">M66S+ VL40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m66s_1-vl60-stock">M66S+ VL60 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m66s-vk20-stock">M66S VK20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m66s-vk30-stock">M66S VK30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m66s-vk40-stock">M66S VK40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m66s-vk50-stock">M66S VK50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m66s-vk60-stock">M66S VK60 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m66s-vl10-stock">M66S VL10 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m66s-vl20-stock">M66S VL20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m66s-vl30-stock">M66S VL30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m66s-vl40-stock">M66S VL40 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m66s-vl50-stock">M66S VL50 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m66-vk20-stock">M66 VK20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m66-vk30-stock">M66 VK30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m66-vl20-stock">M66 VL20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m66-vl30-stock">M66 VL30 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M6X#m67s-vk30-stock">M67S VK30 (Stock)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>M7X Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../whatsminer/M7X#m70-vm30-stock">M70 VM30 (Stock)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
@@ -377,6 +540,7 @@ details {
|
||||
<details>
|
||||
<summary>A11X Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../avalonminer/A11X#avalon-1126-pro-stock">Avalon 1126 Pro (Stock)</a></li>
|
||||
<li><a href="../avalonminer/A11X#avalon-1166-pro-stock">Avalon 1166 Pro (Stock)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
@@ -390,6 +554,13 @@ details {
|
||||
<summary>nano Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../avalonminer/nano#avalon-nano-3-stock">Avalon Nano 3 (Stock)</a></li>
|
||||
<li><a href="../avalonminer/nano#avalon-nano-3s-stock">Avalon Nano 3s (Stock)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>A15X Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../avalonminer/A15X#avalon-1566-stock">Avalon 1566 (Stock)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
@@ -491,9 +662,17 @@ details {
|
||||
<summary>X21 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X21#s21-bos_1">S21 (BOS+)</a></li>
|
||||
<li><a href="../antminer/X21#s21-pro-bos_1">S21 Pro (BOS+)</a></li>
|
||||
<li><a href="../antminer/X21#t21-bos_1">T21 (BOS+)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>BMM Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../braiins/BMM#bmm100-bos_1">BMM100 (BOS+)</a></li>
|
||||
<li><a href="../braiins/BMM#bmm101-bos_1">BMM101 (BOS+)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
@@ -526,17 +705,21 @@ details {
|
||||
<li><a href="../antminer/X19#s19-no-pic-vnish">S19 No PIC (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#s19-pro-vnish">S19 Pro (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#s19j-vnish">S19j (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#s19i-vnish">S19i (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#s19j-pro-vnish">S19j Pro (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#s19j-pro-vnish">S19j Pro (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#s19j-pro-vnish">S19j Pro (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#s19a-vnish">S19a (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#s19a-pro-vnish">S19a Pro (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#s19-pro-hydro-vnish">S19 Pro Hydro (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#s19k-pro-vnish">S19k Pro (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#t19-vnish">T19 (VNish)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>X21 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X21#t21-vnish">T21 (VNish)</a></li>
|
||||
<li><a href="../antminer/X21#s21-vnish">S21 (VNish)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
@@ -555,6 +738,8 @@ details {
|
||||
<li><a href="../antminer/X19#s19j-pro_1-epic">S19j Pro+ (ePIC)</a></li>
|
||||
<li><a href="../antminer/X19#s19k-pro-epic">S19k Pro (ePIC)</a></li>
|
||||
<li><a href="../antminer/X19#s19-xp-epic">S19 XP (ePIC)</a></li>
|
||||
<li><a href="../antminer/X19#s19j-pro-dual-epic">S19j Pro Dual (ePIC)</a></li>
|
||||
<li><a href="../antminer/X19#s19k-pro-dual-epic">S19k Pro Dual (ePIC)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
@@ -570,6 +755,7 @@ details {
|
||||
<ul>
|
||||
<li><a href="../blockminer/blockminer#blockminer-520i-epic">BlockMiner 520i (ePIC)</a></li>
|
||||
<li><a href="../blockminer/blockminer#blockminer-720i-epic">BlockMiner 720i (ePIC)</a></li>
|
||||
<li><a href="../blockminer/blockminer#blockminer-elite-1.0-epic">BlockMiner eLITE 1.0 (ePIC)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
@@ -580,13 +766,27 @@ details {
|
||||
<details>
|
||||
<summary>X9 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X9#t9-stock">T9 (Stock)</a></li>
|
||||
<li><a href="../antminer/X9#t9-hive">T9 (Hive)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>X19 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X19#s19j-pro-stock">S19j Pro (Stock)</a></li>
|
||||
<li><a href="../antminer/X19#s19j-pro-hive">S19j Pro (Hive)</a></li>
|
||||
<li><a href="../antminer/X19#s19-hive">S19 (Hive)</a></li>
|
||||
<li><a href="../antminer/X19#s19k-pro-hive">S19K Pro (Hive)</a></li>
|
||||
<li><a href="../antminer/X19#s19-no-pic-hive">S19 No PIC (Hive)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>MSKMiner Firmware Miners:</summary>
|
||||
<ul>
|
||||
<details>
|
||||
<summary>X19 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X19#s19-no-pic-stock">S19 No PIC (Stock)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
@@ -616,6 +816,7 @@ details {
|
||||
<summary>X21 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X21#s21-luxos">S21 (LuxOS)</a></li>
|
||||
<li><a href="../antminer/X21#t21-luxos">T21 (LuxOS)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
@@ -686,6 +887,18 @@ details {
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>Stock Firmware Lucky Miners:</summary>
|
||||
<ul>
|
||||
<details>
|
||||
<summary>LV Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../luckyminer/LV#lv08-stock">LV08 (Stock)</a></li>
|
||||
<li><a href="../luckyminer/LV#lv07-stock">LV07 (Stock)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>Stock Firmware IceRiver Miners:</summary>
|
||||
<ul>
|
||||
<details>
|
||||
@@ -715,3 +928,25 @@ details {
|
||||
</details>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>Stock Firmware Volcminers:</summary>
|
||||
<ul>
|
||||
<details>
|
||||
<summary>DX Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../volcminer/DX#d1-stock">D1 (Stock)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>Stock Firmware Elphapex Miners:</summary>
|
||||
<ul>
|
||||
<details>
|
||||
<summary>DGX Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../elphapex/DGX#dg1_1-stock">DG1+ (Stock)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
</details>
|
||||
16
docs/miners/volcminer/DX.md
Normal file
16
docs/miners/volcminer/DX.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# pyasic
|
||||
## DX Models
|
||||
|
||||
## D1 (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.volcminer.blackminer.DX.D1.VolcMinerD1
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
@@ -1,94 +1,172 @@
|
||||
# pyasic
|
||||
## M2X Models
|
||||
|
||||
## M20 V10 (Stock)
|
||||
::: pyasic.miners.whatsminer.btminer.M2X.M20.BTMinerM20V10
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M20S V10 (Stock)
|
||||
::: pyasic.miners.whatsminer.btminer.M2X.M20S.BTMinerM20SV10
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M20S V20 (Stock)
|
||||
::: pyasic.miners.whatsminer.btminer.M2X.M20S.BTMinerM20SV20
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M20S V30 (Stock)
|
||||
::: pyasic.miners.whatsminer.btminer.M2X.M20S.BTMinerM20SV30
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M20P V10 (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.whatsminer.btminer.M2X.M20P.BTMinerM20PV10
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## M20P V30 (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.whatsminer.btminer.M2X.M20P.BTMinerM20PV30
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## M20S+ V30 (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.whatsminer.btminer.M2X.M20S_Plus.BTMinerM20SPlusV30
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## M21 V10 (Stock)
|
||||
::: pyasic.miners.whatsminer.btminer.M2X.M21.BTMinerM21V10
|
||||
## M20S V10 (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.whatsminer.btminer.M2X.M20S.BTMinerM20SV10
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## M21S V20 (Stock)
|
||||
::: pyasic.miners.whatsminer.btminer.M2X.M21S.BTMinerM21SV20
|
||||
## M20S V20 (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.whatsminer.btminer.M2X.M20S.BTMinerM20SV20
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## M21S V60 (Stock)
|
||||
::: pyasic.miners.whatsminer.btminer.M2X.M21S.BTMinerM21SV60
|
||||
## M20S V30 (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.whatsminer.btminer.M2X.M20S.BTMinerM20SV30
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## M21S V70 (Stock)
|
||||
::: pyasic.miners.whatsminer.btminer.M2X.M21S.BTMinerM21SV70
|
||||
## M20 V10 (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.whatsminer.btminer.M2X.M20.BTMinerM20V10
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## M21S+ V20 (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.whatsminer.btminer.M2X.M21S_Plus.BTMinerM21SPlusV20
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
## M21S V20 (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.whatsminer.btminer.M2X.M21S.BTMinerM21SV20
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## M21S V60 (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.whatsminer.btminer.M2X.M21S.BTMinerM21SV60
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## M21S V70 (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.whatsminer.btminer.M2X.M21S.BTMinerM21SV70
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## M21 V10 (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.whatsminer.btminer.M2X.M21.BTMinerM21V10
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## M29 V10 (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.whatsminer.btminer.M2X.M29.BTMinerM29V10
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
heading_level: 0
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
16
docs/miners/whatsminer/M7X.md
Normal file
16
docs/miners/whatsminer/M7X.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# pyasic
|
||||
## M7X Models
|
||||
|
||||
## M70 VM30 (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [x] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.whatsminer.btminer.M7X.M70.BTMinerM70VM30
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
jinja2<3.1.4
|
||||
mkdocs
|
||||
mkdocstrings[python]
|
||||
zipp>=3.19.1 # not directly required, pinned by Snyk to avoid a vulnerability
|
||||
38
mkdocs.yml
38
mkdocs.yml
@@ -1,5 +1,36 @@
|
||||
site_name: pyasic
|
||||
repo_url: https://github.com/UpstreamData/pyasic
|
||||
site_url: !ENV SITE_URL
|
||||
theme:
|
||||
name: material
|
||||
features:
|
||||
- content.code.copy
|
||||
- content.code.annotate
|
||||
palette:
|
||||
- media: "(prefers-color-scheme)"
|
||||
toggle:
|
||||
icon: material/brightness-auto
|
||||
name: Switch to light mode
|
||||
- media: "(prefers-color-scheme: light)"
|
||||
scheme: default
|
||||
toggle:
|
||||
icon: material/weather-night
|
||||
name: Switch to dark mode
|
||||
- media: "(prefers-color-scheme: dark)"
|
||||
scheme: slate
|
||||
toggle:
|
||||
icon: material/weather-sunny
|
||||
name: Switch to auto mode
|
||||
markdown_extensions:
|
||||
- pymdownx.highlight:
|
||||
anchor_linenums: true
|
||||
line_spans: __span
|
||||
pygments_lang_class: true
|
||||
- pymdownx.tasklist:
|
||||
custom_checkbox: true
|
||||
- pymdownx.inlinehilite
|
||||
- pymdownx.snippets
|
||||
- pymdownx.superfences
|
||||
nav:
|
||||
- Introduction: "index.md"
|
||||
- Miners:
|
||||
@@ -50,6 +81,8 @@ nav:
|
||||
- Antminer X17: "miners/antminer/X17.md"
|
||||
- Antminer X19: "miners/antminer/X19.md"
|
||||
- Antminer X21: "miners/antminer/X21.md"
|
||||
- Braiins Mini Miners: "miners/braiins/BMM.md"
|
||||
- Avalon Nano: "miners/avalonminer/nano.md"
|
||||
- Avalon 7X: "miners/avalonminer/A7X.md"
|
||||
- Avalon 8X: "miners/avalonminer/A8X.md"
|
||||
- Avalon 9X: "miners/avalonminer/A9X.md"
|
||||
@@ -60,8 +93,10 @@ nav:
|
||||
- Whatsminer M3X: "miners/whatsminer/M3X.md"
|
||||
- Whatsminer M5X: "miners/whatsminer/M5X.md"
|
||||
- Whatsminer M6X: "miners/whatsminer/M6X.md"
|
||||
- Whatsminer M7X: "miners/whatsminer/M7X.md"
|
||||
- Innosilicon T3X: "miners/innosilicon/T3X.md"
|
||||
- Innosilicon A10X: "miners/innosilicon/A10X.md"
|
||||
- Innosilicon A11X: "miners/innosilicon/A11X.md"
|
||||
- Goldshell X5: "miners/goldshell/X5.md"
|
||||
- Goldshell XMax: "miners/goldshell/XMax.md"
|
||||
- Goldshell XBox: "miners/goldshell/XBox.md"
|
||||
@@ -70,6 +105,9 @@ nav:
|
||||
- Auradine AT: "miners/auradine/AT.md"
|
||||
- Blockminer: "miners/blockminer/blockminer.md"
|
||||
- BitAxe BM: "miners/bitaxe/BM.md"
|
||||
- Hammer DX: "miners/hammer/DX.md"
|
||||
- Iceriver KSX: "miners/iceriver/KSX.md"
|
||||
- Volcminer DX: "miners/volcminer/DX.md"
|
||||
- Base Miner: "miners/base_miner.md"
|
||||
- Settings:
|
||||
- Settings: "settings/settings.md"
|
||||
|
||||
1046
poetry.lock
generated
1046
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -13,6 +13,8 @@
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
import importlib.metadata
|
||||
|
||||
from pyasic import settings
|
||||
from pyasic.config import MinerConfig
|
||||
from pyasic.data import MinerData
|
||||
@@ -22,3 +24,5 @@ from pyasic.network import MinerNetwork
|
||||
from pyasic.rpc import *
|
||||
from pyasic.ssh import *
|
||||
from pyasic.web import *
|
||||
|
||||
__version__ = importlib.metadata.version("pyasic")
|
||||
|
||||
@@ -46,7 +46,7 @@ class MinerConfig(BaseModel):
|
||||
"""Converts the MinerConfig object to a dictionary."""
|
||||
return self.model_dump()
|
||||
|
||||
def as_am_modern(self, user_suffix: str = None) -> dict:
|
||||
def as_am_modern(self, user_suffix: str | None = None) -> dict:
|
||||
"""Generates the configuration in the format suitable for modern Antminers."""
|
||||
return {
|
||||
**self.fan_mode.as_am_modern(),
|
||||
@@ -56,7 +56,27 @@ class MinerConfig(BaseModel):
|
||||
**self.temperature.as_am_modern(),
|
||||
}
|
||||
|
||||
def as_wm(self, user_suffix: str = None) -> dict:
|
||||
def as_hiveon_modern(self, user_suffix: str | None = None) -> dict:
|
||||
"""Generates the configuration in the format suitable for modern Hiveon."""
|
||||
return {
|
||||
**self.fan_mode.as_hiveon_modern(),
|
||||
"freq-level": "100",
|
||||
**self.mining_mode.as_hiveon_modern(),
|
||||
**self.pools.as_hiveon_modern(user_suffix=user_suffix),
|
||||
**self.temperature.as_hiveon_modern(),
|
||||
}
|
||||
|
||||
def as_elphapex(self, user_suffix: str | None = None) -> dict:
|
||||
"""Generates the configuration in the format suitable for modern Elphapex."""
|
||||
return {
|
||||
**self.fan_mode.as_elphapex(),
|
||||
"fc-freq-level": "100",
|
||||
**self.mining_mode.as_elphapex(),
|
||||
**self.pools.as_elphapex(user_suffix=user_suffix),
|
||||
**self.temperature.as_elphapex(),
|
||||
}
|
||||
|
||||
def as_wm(self, user_suffix: str | None = None) -> dict:
|
||||
"""Generates the configuration in the format suitable for Whatsminers."""
|
||||
return {
|
||||
**self.fan_mode.as_wm(),
|
||||
@@ -65,7 +85,7 @@ class MinerConfig(BaseModel):
|
||||
**self.temperature.as_wm(),
|
||||
}
|
||||
|
||||
def as_am_old(self, user_suffix: str = None) -> dict:
|
||||
def as_am_old(self, user_suffix: str | None = None) -> dict:
|
||||
"""Generates the configuration in the format suitable for old versions of Antminers."""
|
||||
return {
|
||||
**self.fan_mode.as_am_old(),
|
||||
@@ -74,7 +94,7 @@ class MinerConfig(BaseModel):
|
||||
**self.temperature.as_am_old(),
|
||||
}
|
||||
|
||||
def as_goldshell(self, user_suffix: str = None) -> dict:
|
||||
def as_goldshell(self, user_suffix: str | None = None) -> dict:
|
||||
"""Generates the configuration in the format suitable for Goldshell miners."""
|
||||
return {
|
||||
**self.fan_mode.as_goldshell(),
|
||||
@@ -83,7 +103,7 @@ class MinerConfig(BaseModel):
|
||||
**self.temperature.as_goldshell(),
|
||||
}
|
||||
|
||||
def as_avalon(self, user_suffix: str = None) -> dict:
|
||||
def as_avalon(self, user_suffix: str | None = None) -> dict:
|
||||
"""Generates the configuration in the format suitable for Avalonminers."""
|
||||
return {
|
||||
**self.fan_mode.as_avalon(),
|
||||
@@ -92,7 +112,7 @@ class MinerConfig(BaseModel):
|
||||
**self.temperature.as_avalon(),
|
||||
}
|
||||
|
||||
def as_inno(self, user_suffix: str = None) -> dict:
|
||||
def as_inno(self, user_suffix: str | None = None) -> dict:
|
||||
"""Generates the configuration in the format suitable for Innosilicon miners."""
|
||||
return {
|
||||
**self.fan_mode.as_inno(),
|
||||
@@ -101,7 +121,7 @@ class MinerConfig(BaseModel):
|
||||
**self.temperature.as_inno(),
|
||||
}
|
||||
|
||||
def as_bosminer(self, user_suffix: str = None) -> dict:
|
||||
def as_bosminer(self, user_suffix: str | None = None) -> dict:
|
||||
"""Generates the configuration in the bosminer.toml format."""
|
||||
return {
|
||||
**merge_dicts(self.fan_mode.as_bosminer(), self.temperature.as_bosminer()),
|
||||
@@ -109,7 +129,7 @@ class MinerConfig(BaseModel):
|
||||
**self.pools.as_bosminer(user_suffix=user_suffix),
|
||||
}
|
||||
|
||||
def as_boser(self, user_suffix: str = None) -> dict:
|
||||
def as_boser(self, user_suffix: str | None = None) -> dict:
|
||||
"""Generates the configuration in the format suitable for BOSer."""
|
||||
return {
|
||||
**self.fan_mode.as_boser(),
|
||||
@@ -118,7 +138,7 @@ class MinerConfig(BaseModel):
|
||||
**self.pools.as_boser(user_suffix=user_suffix),
|
||||
}
|
||||
|
||||
def as_epic(self, user_suffix: str = None) -> dict:
|
||||
def as_epic(self, user_suffix: str | None = None) -> dict:
|
||||
"""Generates the configuration in the format suitable for ePIC miners."""
|
||||
return {
|
||||
**merge_dicts(self.fan_mode.as_epic(), self.temperature.as_epic()),
|
||||
@@ -126,7 +146,7 @@ class MinerConfig(BaseModel):
|
||||
**self.pools.as_epic(user_suffix=user_suffix),
|
||||
}
|
||||
|
||||
def as_auradine(self, user_suffix: str = None) -> dict:
|
||||
def as_auradine(self, user_suffix: str | None = None) -> dict:
|
||||
"""Generates the configuration in the format suitable for Auradine miners."""
|
||||
return {
|
||||
**self.fan_mode.as_auradine(),
|
||||
@@ -135,7 +155,7 @@ class MinerConfig(BaseModel):
|
||||
**self.pools.as_auradine(user_suffix=user_suffix),
|
||||
}
|
||||
|
||||
def as_mara(self, user_suffix: str = None) -> dict:
|
||||
def as_mara(self, user_suffix: str | None = None) -> dict:
|
||||
return {
|
||||
**self.fan_mode.as_mara(),
|
||||
**self.temperature.as_mara(),
|
||||
@@ -143,15 +163,15 @@ class MinerConfig(BaseModel):
|
||||
**self.pools.as_mara(user_suffix=user_suffix),
|
||||
}
|
||||
|
||||
def as_bitaxe(self, user_suffix: str = None) -> dict:
|
||||
def as_espminer(self, user_suffix: str | None = None) -> dict:
|
||||
return {
|
||||
**self.fan_mode.as_bitaxe(),
|
||||
**self.temperature.as_bitaxe(),
|
||||
**self.mining_mode.as_bitaxe(),
|
||||
**self.pools.as_bitaxe(user_suffix=user_suffix),
|
||||
**self.fan_mode.as_espminer(),
|
||||
**self.temperature.as_espminer(),
|
||||
**self.mining_mode.as_espminer(),
|
||||
**self.pools.as_espminer(user_suffix=user_suffix),
|
||||
}
|
||||
|
||||
def as_luxos(self, user_suffix: str = None) -> dict:
|
||||
def as_luxos(self, user_suffix: str | None = None) -> dict:
|
||||
return {
|
||||
**self.fan_mode.as_luxos(),
|
||||
**self.temperature.as_luxos(),
|
||||
@@ -159,7 +179,7 @@ class MinerConfig(BaseModel):
|
||||
**self.pools.as_luxos(user_suffix=user_suffix),
|
||||
}
|
||||
|
||||
def as_vnish(self, user_suffix: str = None) -> dict:
|
||||
def as_vnish(self, user_suffix: str | None = None) -> dict:
|
||||
main_cfg = {
|
||||
"miner": {
|
||||
**self.fan_mode.as_vnish(),
|
||||
@@ -199,6 +219,24 @@ class MinerConfig(BaseModel):
|
||||
fan_mode=FanModeConfig.from_am_modern(web_conf),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_hiveon_modern(cls, web_conf: dict) -> "MinerConfig":
|
||||
"""Constructs a MinerConfig object from web configuration for Hiveon."""
|
||||
return cls(
|
||||
pools=PoolConfig.from_hiveon_modern(web_conf),
|
||||
mining_mode=MiningModeConfig.from_hiveon_modern(web_conf),
|
||||
fan_mode=FanModeConfig.from_hiveon_modern(web_conf),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_elphapex(cls, web_conf: dict) -> "MinerConfig":
|
||||
"""Constructs a MinerConfig object from web configuration for modern Antminers."""
|
||||
return cls(
|
||||
pools=PoolConfig.from_elphapex(web_conf),
|
||||
mining_mode=MiningModeConfig.from_elphapex(web_conf),
|
||||
fan_mode=FanModeConfig.from_elphapex(web_conf),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_am_old(cls, web_conf: dict) -> "MinerConfig":
|
||||
"""Constructs a MinerConfig object from web configuration for old versions of Antminers."""
|
||||
@@ -245,13 +283,13 @@ class MinerConfig(BaseModel):
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_vnish(cls, web_settings: dict) -> "MinerConfig":
|
||||
def from_vnish(cls, web_settings: dict, web_presets: list[dict]) -> "MinerConfig":
|
||||
"""Constructs a MinerConfig object from web settings for VNish miners."""
|
||||
return cls(
|
||||
pools=PoolConfig.from_vnish(web_settings),
|
||||
fan_mode=FanModeConfig.from_vnish(web_settings),
|
||||
temperature=TemperatureConfig.from_vnish(web_settings),
|
||||
mining_mode=MiningModeConfig.from_vnish(web_settings),
|
||||
mining_mode=MiningModeConfig.from_vnish(web_settings, web_presets),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@@ -272,10 +310,10 @@ class MinerConfig(BaseModel):
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_bitaxe(cls, web_system_info: dict) -> "MinerConfig":
|
||||
def from_espminer(cls, web_system_info: dict) -> "MinerConfig":
|
||||
return cls(
|
||||
pools=PoolConfig.from_bitaxe(web_system_info),
|
||||
fan_mode=FanModeConfig.from_bitaxe(web_system_info),
|
||||
pools=PoolConfig.from_espminer(web_system_info),
|
||||
fan_mode=FanModeConfig.from_espminer(web_system_info),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@@ -286,7 +324,13 @@ class MinerConfig(BaseModel):
|
||||
|
||||
@classmethod
|
||||
def from_luxos(
|
||||
cls, rpc_tempctrl: dict, rpc_fans: dict, rpc_pools: dict, rpc_groups: dict
|
||||
cls,
|
||||
rpc_tempctrl: dict,
|
||||
rpc_fans: dict,
|
||||
rpc_pools: dict,
|
||||
rpc_groups: dict,
|
||||
rpc_config: dict,
|
||||
rpc_profiles: dict,
|
||||
) -> "MinerConfig":
|
||||
return cls(
|
||||
temperature=TemperatureConfig.from_luxos(rpc_tempctrl=rpc_tempctrl),
|
||||
@@ -294,6 +338,9 @@ class MinerConfig(BaseModel):
|
||||
rpc_tempctrl=rpc_tempctrl, rpc_fans=rpc_fans
|
||||
),
|
||||
pools=PoolConfig.from_luxos(rpc_pools=rpc_pools, rpc_groups=rpc_groups),
|
||||
mining_mode=MiningModeConfig.from_luxos(
|
||||
rpc_config=rpc_config, rpc_profiles=rpc_profiles
|
||||
),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -28,6 +28,9 @@ class MinerConfigOption(Enum):
|
||||
def as_am_modern(self) -> dict:
|
||||
return self.value.as_am_modern()
|
||||
|
||||
def as_hiveon_modern(self) -> dict:
|
||||
return self.value.as_hiveon_modern()
|
||||
|
||||
def as_am_old(self) -> dict:
|
||||
return self.value.as_am_old()
|
||||
|
||||
@@ -61,12 +64,15 @@ class MinerConfigOption(Enum):
|
||||
def as_mara(self) -> dict:
|
||||
return self.value.as_mara()
|
||||
|
||||
def as_bitaxe(self) -> dict:
|
||||
return self.value.as_bitaxe()
|
||||
def as_espminer(self) -> dict:
|
||||
return self.value.as_espminer()
|
||||
|
||||
def as_luxos(self) -> dict:
|
||||
return self.value.as_luxos()
|
||||
|
||||
def as_elphapex(self) -> dict:
|
||||
return self.value.as_elphapex()
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
return self.value(*args, **kwargs)
|
||||
|
||||
@@ -92,6 +98,9 @@ class MinerConfigValue(BaseModel):
|
||||
def as_am_modern(self) -> dict:
|
||||
return {}
|
||||
|
||||
def as_hiveon_modern(self) -> dict:
|
||||
return {}
|
||||
|
||||
def as_am_old(self) -> dict:
|
||||
return {}
|
||||
|
||||
@@ -125,12 +134,15 @@ class MinerConfigValue(BaseModel):
|
||||
def as_mara(self) -> dict:
|
||||
return {}
|
||||
|
||||
def as_bitaxe(self) -> dict:
|
||||
def as_espminer(self) -> dict:
|
||||
return {}
|
||||
|
||||
def as_luxos(self) -> dict:
|
||||
return {}
|
||||
|
||||
def as_elphapex(self) -> dict:
|
||||
return {}
|
||||
|
||||
def __getitem__(self, item):
|
||||
try:
|
||||
return getattr(self, item)
|
||||
|
||||
@@ -55,6 +55,12 @@ class FanModeNormal(MinerConfigValue):
|
||||
def as_am_modern(self) -> dict:
|
||||
return {"bitmain-fan-ctrl": False, "bitmain-fan-pwn": "100"}
|
||||
|
||||
def as_hiveon_modern(self) -> dict:
|
||||
return {"bitmain-fan-ctrl": False, "bitmain-fan-pwn": "100"}
|
||||
|
||||
def as_elphapex(self) -> dict:
|
||||
return {"fc-fan-ctrl": False, "fc-fan-pwn": "100"}
|
||||
|
||||
def as_bosminer(self) -> dict:
|
||||
return {
|
||||
"temp_control": {"mode": "auto"},
|
||||
@@ -81,7 +87,7 @@ class FanModeNormal(MinerConfigValue):
|
||||
},
|
||||
}
|
||||
|
||||
def as_bitaxe(self) -> dict:
|
||||
def as_espminer(self) -> dict:
|
||||
return {"autoFanspeed": 1}
|
||||
|
||||
def as_luxos(self) -> dict:
|
||||
@@ -135,6 +141,12 @@ class FanModeManual(MinerConfigValue):
|
||||
def as_am_modern(self) -> dict:
|
||||
return {"bitmain-fan-ctrl": True, "bitmain-fan-pwm": str(self.speed)}
|
||||
|
||||
def as_hiveon_modern(self) -> dict:
|
||||
return {"bitmain-fan-ctrl": True, "bitmain-fan-pwm": str(self.speed)}
|
||||
|
||||
def as_elphapex(self) -> dict:
|
||||
return {"fc-fan-ctrl": True, "fc-fan-pwm": str(self.speed)}
|
||||
|
||||
def as_bosminer(self) -> dict:
|
||||
return {
|
||||
"temp_control": {"mode": "manual"},
|
||||
@@ -156,7 +168,7 @@ class FanModeManual(MinerConfigValue):
|
||||
},
|
||||
}
|
||||
|
||||
def as_bitaxe(self) -> dict:
|
||||
def as_espminer(self) -> dict:
|
||||
return {"autoFanspeed": 0, "fanspeed": self.speed}
|
||||
|
||||
def as_luxos(self) -> dict:
|
||||
@@ -185,6 +197,12 @@ class FanModeImmersion(MinerConfigValue):
|
||||
def as_am_modern(self) -> dict:
|
||||
return {"bitmain-fan-ctrl": True, "bitmain-fan-pwm": "0"}
|
||||
|
||||
def as_hiveon_modern(self) -> dict:
|
||||
return {"bitmain-fan-ctrl": True, "bitmain-fan-pwm": "0"}
|
||||
|
||||
def as_elphapex(self) -> dict:
|
||||
return {"fc-fan-ctrl": True, "fc-fan-pwm": "0"}
|
||||
|
||||
def as_bosminer(self) -> dict:
|
||||
return {
|
||||
"fan_control": {"min_fans": 0},
|
||||
@@ -239,6 +257,34 @@ class FanModeConfig(MinerConfigOption):
|
||||
else:
|
||||
return cls.default()
|
||||
|
||||
@classmethod
|
||||
def from_hiveon_modern(cls, web_conf: dict):
|
||||
if web_conf.get("bitmain-fan-ctrl") is not None:
|
||||
fan_manual = web_conf["bitmain-fan-ctrl"]
|
||||
if fan_manual:
|
||||
speed = int(web_conf["bitmain-fan-pwm"])
|
||||
if speed == 0:
|
||||
return cls.immersion()
|
||||
return cls.manual(speed=speed)
|
||||
else:
|
||||
return cls.normal()
|
||||
else:
|
||||
return cls.default()
|
||||
|
||||
@classmethod
|
||||
def from_elphapex(cls, web_conf: dict):
|
||||
if web_conf.get("fc-fan-ctrl") is not None:
|
||||
fan_manual = web_conf["fc-fan-ctrl"]
|
||||
if fan_manual:
|
||||
speed = int(web_conf["fc-fan-pwm"])
|
||||
if speed == 0:
|
||||
return cls.immersion()
|
||||
return cls.manual(speed=speed)
|
||||
else:
|
||||
return cls.normal()
|
||||
else:
|
||||
return cls.default()
|
||||
|
||||
@classmethod
|
||||
def from_epic(cls, web_conf: dict):
|
||||
try:
|
||||
@@ -308,6 +354,12 @@ class FanModeConfig(MinerConfigOption):
|
||||
if "minimumRequiredFans" in keys:
|
||||
conf["minimum_fans"] = int(temperature_conf["minimumRequiredFans"])
|
||||
return cls.manual(**conf)
|
||||
if "disabled" in keys:
|
||||
conf = {}
|
||||
if "fanSpeedRatio" in temperature_conf["disabled"].keys():
|
||||
conf["speed"] = int(temperature_conf["disabled"]["fanSpeedRatio"])
|
||||
return cls.manual(**conf)
|
||||
return cls.default()
|
||||
|
||||
@classmethod
|
||||
def from_auradine(cls, web_fan: dict):
|
||||
@@ -336,7 +388,7 @@ class FanModeConfig(MinerConfigOption):
|
||||
return cls.default()
|
||||
|
||||
@classmethod
|
||||
def from_bitaxe(cls, web_system_info: dict):
|
||||
def from_espminer(cls, web_system_info: dict):
|
||||
if web_system_info["autofanspeed"] == 1:
|
||||
return cls.normal()
|
||||
else:
|
||||
|
||||
@@ -36,6 +36,7 @@ from pyasic.web.braiins_os.proto.braiins.bos.v1 import (
|
||||
)
|
||||
|
||||
from .algo import TunerAlgo, TunerAlgoType
|
||||
from .presets import MiningPreset
|
||||
from .scaling import ScalingConfig
|
||||
|
||||
|
||||
@@ -51,6 +52,14 @@ class MiningModeNormal(MinerConfigValue):
|
||||
return {"miner-mode": "0"}
|
||||
return {"miner-mode": 0}
|
||||
|
||||
def as_hiveon_modern(self) -> dict:
|
||||
if settings.get("antminer_mining_mode_as_str", False):
|
||||
return {"miner-mode": "0"}
|
||||
return {"miner-mode": 0}
|
||||
|
||||
def as_elphapex(self) -> dict:
|
||||
return {"miner-mode": 0}
|
||||
|
||||
def as_wm(self) -> dict:
|
||||
return {"mode": self.mode}
|
||||
|
||||
@@ -73,6 +82,9 @@ class MiningModeNormal(MinerConfigValue):
|
||||
def as_luxos(self) -> dict:
|
||||
return {"autotunerset": {"enabled": False}}
|
||||
|
||||
def as_bosminer(self) -> dict:
|
||||
return {"autotuning": {"enabled": True}}
|
||||
|
||||
|
||||
class MiningModeSleep(MinerConfigValue):
|
||||
mode: str = field(init=False, default="sleep")
|
||||
@@ -86,6 +98,14 @@ class MiningModeSleep(MinerConfigValue):
|
||||
return {"miner-mode": "1"}
|
||||
return {"miner-mode": 1}
|
||||
|
||||
def as_hiveon_modern(self) -> dict:
|
||||
if settings.get("antminer_mining_mode_as_str", False):
|
||||
return {"miner-mode": "1"}
|
||||
return {"miner-mode": 1}
|
||||
|
||||
def as_elphapex(self) -> dict:
|
||||
return {"miner-mode": 1}
|
||||
|
||||
def as_wm(self) -> dict:
|
||||
return {"mode": self.mode}
|
||||
|
||||
@@ -118,6 +138,14 @@ class MiningModeLPM(MinerConfigValue):
|
||||
return {"miner-mode": "3"}
|
||||
return {"miner-mode": 3}
|
||||
|
||||
def as_hiveon_modern(self) -> dict:
|
||||
if settings.get("antminer_mining_mode_as_str", False):
|
||||
return {"miner-mode": "3"}
|
||||
return {"miner-mode": 3}
|
||||
|
||||
def as_elphapex(self) -> dict:
|
||||
return {"miner-mode": 3}
|
||||
|
||||
def as_wm(self) -> dict:
|
||||
return {"mode": self.mode}
|
||||
|
||||
@@ -140,6 +168,14 @@ class MiningModeHPM(MinerConfigValue):
|
||||
return {"miner-mode": "0"}
|
||||
return {"miner-mode": 0}
|
||||
|
||||
def as_hiveon_modern(self) -> dict:
|
||||
if settings.get("antminer_mining_mode_as_str", False):
|
||||
return {"miner-mode": "0"}
|
||||
return {"miner-mode": 0}
|
||||
|
||||
def as_elphapex(self) -> dict:
|
||||
return {"miner-mode": 0}
|
||||
|
||||
def as_wm(self) -> dict:
|
||||
return {"mode": self.mode}
|
||||
|
||||
@@ -173,6 +209,14 @@ class MiningModePowerTune(MinerConfigValue):
|
||||
return {"miner-mode": "0"}
|
||||
return {"miner-mode": 0}
|
||||
|
||||
def as_hiveon_modern(self) -> dict:
|
||||
if settings.get("antminer_mining_mode_as_str", False):
|
||||
return {"miner-mode": "0"}
|
||||
return {"miner-mode": 0}
|
||||
|
||||
def as_elphapex(self) -> dict:
|
||||
return {"miner-mode": 0}
|
||||
|
||||
def as_wm(self) -> dict:
|
||||
if self.power is not None:
|
||||
return {"mode": self.mode, self.mode: {"wattage": self.power}}
|
||||
@@ -214,18 +258,18 @@ class MiningModePowerTune(MinerConfigValue):
|
||||
sd_cfg = {}
|
||||
if self.scaling.shutdown is not None:
|
||||
sd_cfg = self.scaling.shutdown.as_boser()
|
||||
cfg["set_dps"] = (
|
||||
SetDpsRequest(
|
||||
enable=True,
|
||||
**sd_cfg,
|
||||
target=DpsTarget(
|
||||
power_target=DpsPowerTarget(
|
||||
power_step=Power(self.scaling.step),
|
||||
min_power_target=Power(self.scaling.minimum),
|
||||
)
|
||||
),
|
||||
),
|
||||
power_target_kwargs = {}
|
||||
if self.scaling.step is not None:
|
||||
power_target_kwargs["power_step"] = Power(self.scaling.step)
|
||||
if self.scaling.minimum is not None:
|
||||
power_target_kwargs["min_power_target"] = Power(self.scaling.minimum)
|
||||
cfg["set_dps"] = SetDpsRequest(
|
||||
save_action=SaveAction.SAVE_AND_APPLY,
|
||||
enable=True,
|
||||
**sd_cfg,
|
||||
target=DpsTarget(power_target=DpsPowerTarget(**power_target_kwargs)),
|
||||
)
|
||||
|
||||
return cfg
|
||||
|
||||
def as_auradine(self) -> dict:
|
||||
@@ -251,9 +295,9 @@ class MiningModeHashrateTune(MinerConfigValue):
|
||||
arbitrary_types_allowed = True
|
||||
|
||||
mode: str = field(init=False, default="hashrate_tuning")
|
||||
hashrate: int = None
|
||||
hashrate: int | None = None
|
||||
algo: TunerAlgoType = field(default_factory=TunerAlgo.default)
|
||||
scaling: ScalingConfig = None
|
||||
scaling: ScalingConfig | None = None
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, dict_conf: dict | None) -> "MiningModeHashrateTune":
|
||||
@@ -272,13 +316,20 @@ class MiningModeHashrateTune(MinerConfigValue):
|
||||
return {"miner-mode": "0"}
|
||||
return {"miner-mode": 0}
|
||||
|
||||
def as_hiveon_modern(self) -> dict:
|
||||
if settings.get("antminer_mining_mode_as_str", False):
|
||||
return {"miner-mode": "0"}
|
||||
return {"miner-mode": 0}
|
||||
|
||||
def as_elphapex(self) -> dict:
|
||||
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}
|
||||
|
||||
@property
|
||||
def as_boser(self) -> dict:
|
||||
cfg = {
|
||||
"set_performance_mode": SetPerformanceModeRequest(
|
||||
@@ -298,18 +349,24 @@ class MiningModeHashrateTune(MinerConfigValue):
|
||||
sd_cfg = {}
|
||||
if self.scaling.shutdown is not None:
|
||||
sd_cfg = self.scaling.shutdown.as_boser()
|
||||
cfg["set_dps"] = (
|
||||
SetDpsRequest(
|
||||
enable=True,
|
||||
**sd_cfg,
|
||||
target=DpsTarget(
|
||||
hashrate_target=DpsHashrateTarget(
|
||||
hashrate_step=TeraHashrate(self.scaling.step),
|
||||
min_hashrate_target=TeraHashrate(self.scaling.minimum),
|
||||
)
|
||||
),
|
||||
hashrate_target_kwargs = {}
|
||||
if self.scaling.step is not None:
|
||||
hashrate_target_kwargs["hashrate_step"] = TeraHashrate(
|
||||
self.scaling.step
|
||||
)
|
||||
if self.scaling.minimum is not None:
|
||||
hashrate_target_kwargs["min_hashrate_target"] = TeraHashrate(
|
||||
self.scaling.minimum
|
||||
)
|
||||
cfg["set_dps"] = SetDpsRequest(
|
||||
save_action=SaveAction.SAVE_AND_APPLY,
|
||||
enable=True,
|
||||
**sd_cfg,
|
||||
target=DpsTarget(
|
||||
hashrate_target=DpsHashrateTarget(**hashrate_target_kwargs)
|
||||
),
|
||||
)
|
||||
|
||||
return cfg
|
||||
|
||||
def as_auradine(self) -> dict:
|
||||
@@ -344,6 +401,50 @@ class MiningModeHashrateTune(MinerConfigValue):
|
||||
return {"autotunerset": {"enabled": True}}
|
||||
|
||||
|
||||
class MiningModePreset(MinerConfigValue):
|
||||
mode: str = field(init=False, default="preset")
|
||||
|
||||
active_preset: MiningPreset
|
||||
available_presets: list[MiningPreset] = field(default_factory=list)
|
||||
|
||||
def as_vnish(self) -> dict:
|
||||
return {"overclock": {**self.active_preset.as_vnish()}}
|
||||
|
||||
@classmethod
|
||||
def from_vnish(
|
||||
cls, web_overclock_settings: dict, web_presets: list[dict]
|
||||
) -> "MiningModePreset":
|
||||
active_preset = None
|
||||
for preset in web_presets:
|
||||
if preset["name"] == web_overclock_settings["preset"]:
|
||||
active_preset = preset
|
||||
return cls(
|
||||
active_preset=MiningPreset.from_vnish(active_preset),
|
||||
available_presets=[MiningPreset.from_vnish(p) for p in web_presets],
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_luxos(cls, rpc_config: dict, rpc_profiles: dict) -> "MiningModePreset":
|
||||
active_preset = cls.get_active_preset_from_luxos(rpc_config, rpc_profiles)
|
||||
return cls(
|
||||
active_preset=active_preset,
|
||||
available_presets=[
|
||||
MiningPreset.from_luxos(p) for p in rpc_profiles["PROFILES"]
|
||||
],
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_active_preset_from_luxos(
|
||||
cls, rpc_config: dict, rpc_profiles: dict
|
||||
) -> MiningPreset:
|
||||
active_preset = None
|
||||
active_profile = rpc_config["CONFIG"][0]["Profile"]
|
||||
for profile in rpc_profiles["PROFILES"]:
|
||||
if profile["Profile Name"] == active_profile:
|
||||
active_preset = profile
|
||||
return MiningPreset.from_luxos(active_preset)
|
||||
|
||||
|
||||
class ManualBoardSettings(MinerConfigValue):
|
||||
freq: float
|
||||
volt: float
|
||||
@@ -357,6 +458,14 @@ class ManualBoardSettings(MinerConfigValue):
|
||||
return {"miner-mode": "0"}
|
||||
return {"miner-mode": 0}
|
||||
|
||||
def as_hiveon_modern(self) -> dict:
|
||||
if settings.get("antminer_mining_mode_as_str", False):
|
||||
return {"miner-mode": "0"}
|
||||
return {"miner-mode": 0}
|
||||
|
||||
def as_elphapex(self) -> dict:
|
||||
return {"miner-mode": 0}
|
||||
|
||||
def as_vnish(self) -> dict:
|
||||
return {"freq": self.freq}
|
||||
|
||||
@@ -381,10 +490,19 @@ class MiningModeManual(MinerConfigValue):
|
||||
return {"miner-mode": "0"}
|
||||
return {"miner-mode": 0}
|
||||
|
||||
def as_elphapex(self) -> dict:
|
||||
return {"miner-mode": 0}
|
||||
|
||||
def as_vnish(self) -> dict:
|
||||
chains = [b.as_vnish() for b in self.boards.values() if b.freq != 0]
|
||||
return {
|
||||
"chains": [b.as_vnish() for b in self.boards.values() if b.freq != 0],
|
||||
"globals": {"freq": int(self.global_freq), "volt": int(self.global_volt)},
|
||||
"overclock": {
|
||||
"chains": chains if chains != [] else None,
|
||||
"globals": {
|
||||
"freq": int(self.global_freq),
|
||||
"volt": int(self.global_volt),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@classmethod
|
||||
@@ -438,6 +556,7 @@ class MiningModeConfig(MinerConfigOption):
|
||||
sleep = MiningModeSleep
|
||||
power_tuning = MiningModePowerTune
|
||||
hashrate_tuning = MiningModeHashrateTune
|
||||
preset = MiningModePreset
|
||||
manual = MiningModeManual
|
||||
|
||||
@classmethod
|
||||
@@ -471,6 +590,34 @@ class MiningModeConfig(MinerConfigOption):
|
||||
return cls.low()
|
||||
return cls.default()
|
||||
|
||||
@classmethod
|
||||
def from_hiveon_modern(cls, web_conf: dict):
|
||||
if web_conf.get("bitmain-work-mode") is not None:
|
||||
work_mode = web_conf["bitmain-work-mode"]
|
||||
if work_mode == "":
|
||||
return cls.default()
|
||||
if int(work_mode) == 0:
|
||||
return cls.normal()
|
||||
elif int(work_mode) == 1:
|
||||
return cls.sleep()
|
||||
elif int(work_mode) == 3:
|
||||
return cls.low()
|
||||
return cls.default()
|
||||
|
||||
@classmethod
|
||||
def from_elphapex(cls, web_conf: dict):
|
||||
if web_conf.get("fc-work-mode") is not None:
|
||||
work_mode = web_conf["fc-work-mode"]
|
||||
if work_mode == "":
|
||||
return cls.default()
|
||||
if int(work_mode) == 0:
|
||||
return cls.normal()
|
||||
elif int(work_mode) == 1:
|
||||
return cls.sleep()
|
||||
elif int(work_mode) == 3:
|
||||
return cls.low()
|
||||
return cls.default()
|
||||
|
||||
@classmethod
|
||||
def from_epic(cls, web_conf: dict):
|
||||
try:
|
||||
@@ -553,9 +700,10 @@ class MiningModeConfig(MinerConfigOption):
|
||||
return cls.hashrate_tuning(
|
||||
scaling=ScalingConfig.from_bosminer(toml_conf, mode="hashrate"),
|
||||
)
|
||||
return cls.default()
|
||||
|
||||
@classmethod
|
||||
def from_vnish(cls, web_settings: dict):
|
||||
def from_vnish(cls, web_settings: dict, web_presets: list[dict]):
|
||||
try:
|
||||
mode_settings = web_settings["miner"]["overclock"]
|
||||
except KeyError:
|
||||
@@ -564,7 +712,7 @@ class MiningModeConfig(MinerConfigOption):
|
||||
if mode_settings["preset"] == "disabled":
|
||||
return MiningModeManual.from_vnish(mode_settings)
|
||||
else:
|
||||
return cls.power_tuning(power=int(mode_settings["preset"]))
|
||||
return MiningModePreset.from_vnish(mode_settings, web_presets)
|
||||
|
||||
@classmethod
|
||||
def from_boser(cls, grpc_miner_conf: dict):
|
||||
@@ -656,6 +804,14 @@ class MiningModeConfig(MinerConfigOption):
|
||||
pass
|
||||
return cls.default()
|
||||
|
||||
@classmethod
|
||||
def from_luxos(cls, rpc_config: dict, rpc_profiles: dict):
|
||||
preset_info = MiningModePreset.from_luxos(rpc_config, rpc_profiles)
|
||||
return cls.preset(
|
||||
active_preset=preset_info.active_preset,
|
||||
available_presets=preset_info.available_presets,
|
||||
)
|
||||
|
||||
|
||||
MiningMode = TypeVar(
|
||||
"MiningMode",
|
||||
@@ -667,5 +823,6 @@ MiningMode = TypeVar(
|
||||
MiningModeManual,
|
||||
MiningModePowerTune,
|
||||
MiningModeHashrateTune,
|
||||
MiningModePreset,
|
||||
],
|
||||
)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from dataclasses import field
|
||||
from typing import TypeVar, Union
|
||||
|
||||
from pyasic.config.base import MinerConfigOption, MinerConfigValue
|
||||
|
||||
54
pyasic/config/mining/presets.py
Normal file
54
pyasic/config/mining/presets.py
Normal file
@@ -0,0 +1,54 @@
|
||||
from pyasic.config.base import MinerConfigValue
|
||||
|
||||
|
||||
class MiningPreset(MinerConfigValue):
|
||||
name: str | None = None
|
||||
power: int | None = None
|
||||
hashrate: int | None = None
|
||||
tuned: bool | None = None
|
||||
modded_psu: bool | None = None
|
||||
frequency: int | None = None
|
||||
voltage: float | None = None
|
||||
|
||||
def as_vnish(self) -> dict:
|
||||
if self.name is not None:
|
||||
return {"preset": self.name}
|
||||
return {}
|
||||
|
||||
@classmethod
|
||||
def from_vnish(cls, web_preset: dict):
|
||||
name = web_preset["name"]
|
||||
hr_power_split = web_preset["pretty"].split("~")
|
||||
if len(hr_power_split) == 1:
|
||||
power = None
|
||||
hashrate = None
|
||||
else:
|
||||
power = hr_power_split[0].replace("watt", "").strip()
|
||||
hashrate = (
|
||||
hr_power_split[1]
|
||||
.replace("TH", "")
|
||||
.replace("GH", "")
|
||||
.replace("MH", "")
|
||||
.replace(" LC", "")
|
||||
.strip()
|
||||
)
|
||||
tuned = web_preset["status"] == "tuned"
|
||||
modded_psu = web_preset["modded_psu_required"]
|
||||
return cls(
|
||||
name=name,
|
||||
power=power,
|
||||
hashrate=hashrate,
|
||||
tuned=tuned,
|
||||
modded_psu=modded_psu,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_luxos(cls, profile: dict):
|
||||
return cls(
|
||||
name=profile["Profile Name"],
|
||||
power=profile["Watts"],
|
||||
hashrate=round(profile["Hashrate"]),
|
||||
tuned=profile["IsTuned"],
|
||||
frequency=profile["Frequency"],
|
||||
voltage=profile["Voltage"],
|
||||
)
|
||||
@@ -15,14 +15,12 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
from pyasic.config.base import MinerConfigValue
|
||||
|
||||
|
||||
class ScalingShutdown(MinerConfigValue):
|
||||
enabled: bool = False
|
||||
duration: int = None
|
||||
duration: int | None = None
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, dict_conf: dict | None) -> "ScalingShutdown":
|
||||
@@ -65,9 +63,9 @@ class ScalingShutdown(MinerConfigValue):
|
||||
|
||||
|
||||
class ScalingConfig(MinerConfigValue):
|
||||
step: int = None
|
||||
minimum: int = None
|
||||
shutdown: ScalingShutdown = None
|
||||
step: int | None = None
|
||||
minimum: int | None = None
|
||||
shutdown: ScalingShutdown | None = None
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, dict_conf: dict | None) -> "ScalingConfig":
|
||||
@@ -81,7 +79,7 @@ class ScalingConfig(MinerConfigValue):
|
||||
return cls(**cls_conf)
|
||||
|
||||
@classmethod
|
||||
def from_bosminer(cls, toml_conf: dict, mode: str = None):
|
||||
def from_bosminer(cls, toml_conf: dict, mode: str | None = None):
|
||||
if mode == "power":
|
||||
return cls._from_bosminer_power(toml_conf)
|
||||
if mode == "hashrate":
|
||||
@@ -106,7 +104,7 @@ class ScalingConfig(MinerConfigValue):
|
||||
return cls(step=power_step, minimum=min_power, shutdown=sd_mode)
|
||||
|
||||
@classmethod
|
||||
def from_boser(cls, grpc_miner_conf: dict, mode: str = None):
|
||||
def from_boser(cls, grpc_miner_conf: dict, mode: str | None = None):
|
||||
if mode == "power":
|
||||
return cls._from_boser_power(grpc_miner_conf)
|
||||
if mode == "hashrate":
|
||||
|
||||
@@ -36,124 +36,107 @@ class Pool(MinerConfigValue):
|
||||
user: str
|
||||
password: str
|
||||
|
||||
def as_am_modern(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}
|
||||
def as_am_modern(self, user_suffix: str | None = None) -> dict:
|
||||
return {
|
||||
"url": self.url,
|
||||
"user": f"{self.user}{user_suffix or ''}",
|
||||
"pass": self.password,
|
||||
}
|
||||
|
||||
def as_wm(self, idx: int = 1, user_suffix: str = None) -> dict:
|
||||
if user_suffix is not None:
|
||||
return {
|
||||
f"pool_{idx}": self.url,
|
||||
f"worker_{idx}": f"{self.user}{user_suffix}",
|
||||
f"passwd_{idx}": self.password,
|
||||
}
|
||||
def as_hiveon_modern(self, user_suffix: str | None = None) -> dict:
|
||||
return {
|
||||
"url": self.url,
|
||||
"user": f"{self.user}{user_suffix or ''}",
|
||||
"pass": self.password,
|
||||
}
|
||||
|
||||
def as_elphapex(self, user_suffix: str | None = None) -> dict:
|
||||
return {
|
||||
"url": self.url,
|
||||
"user": f"{self.user}{user_suffix or ''}",
|
||||
"pass": self.password,
|
||||
}
|
||||
|
||||
def as_wm(self, idx: int = 1, user_suffix: str | None = None) -> dict:
|
||||
return {
|
||||
f"pool_{idx}": self.url,
|
||||
f"worker_{idx}": self.user,
|
||||
f"worker_{idx}": f"{self.user}{user_suffix or ''}",
|
||||
f"passwd_{idx}": self.password,
|
||||
}
|
||||
|
||||
def as_am_old(self, idx: int = 1, user_suffix: str = None) -> dict:
|
||||
if user_suffix is not None:
|
||||
return {
|
||||
f"_ant_pool{idx}url": self.url,
|
||||
f"_ant_pool{idx}user": f"{self.user}{user_suffix}",
|
||||
f"_ant_pool{idx}pw": self.password,
|
||||
}
|
||||
def as_am_old(self, idx: int = 1, user_suffix: str | None = None) -> dict:
|
||||
return {
|
||||
f"_ant_pool{idx}url": self.url,
|
||||
f"_ant_pool{idx}user": self.user,
|
||||
f"_ant_pool{idx}user": f"{self.user}{user_suffix or ''}",
|
||||
f"_ant_pool{idx}pw": self.password,
|
||||
}
|
||||
|
||||
def as_goldshell(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}
|
||||
def as_goldshell(self, user_suffix: str | None = None) -> dict:
|
||||
return {
|
||||
"url": self.url,
|
||||
"user": f"{self.user}{user_suffix or ''}",
|
||||
"pass": self.password,
|
||||
}
|
||||
|
||||
def as_avalon(self, user_suffix: str = None) -> str:
|
||||
if user_suffix is not None:
|
||||
return ",".join([self.url, f"{self.user}{user_suffix}", self.password])
|
||||
return ",".join([self.url, self.user, self.password])
|
||||
def as_avalon(self, user_suffix: str | None = None) -> str:
|
||||
return ",".join([self.url, f"{self.user}{user_suffix or ''}", self.password])
|
||||
|
||||
def as_inno(self, idx: int = 1, user_suffix: str = None) -> dict:
|
||||
if user_suffix is not None:
|
||||
return {
|
||||
f"Pool{idx}": self.url,
|
||||
f"UserName{idx}": f"{self.user}{user_suffix}",
|
||||
f"Password{idx}": self.password,
|
||||
}
|
||||
def as_inno(self, idx: int = 1, user_suffix: str | None = None) -> dict:
|
||||
return {
|
||||
f"Pool{idx}": self.url,
|
||||
f"UserName{idx}": self.user,
|
||||
f"UserName{idx}": f"{self.user}{user_suffix or ''}",
|
||||
f"Password{idx}": self.password,
|
||||
}
|
||||
|
||||
def as_bosminer(self, user_suffix: str = None) -> dict:
|
||||
if user_suffix is not None:
|
||||
return {
|
||||
"url": self.url,
|
||||
"user": f"{self.user}{user_suffix}",
|
||||
"password": self.password,
|
||||
}
|
||||
return {"url": self.url, "user": self.user, "password": self.password}
|
||||
def as_bosminer(self, user_suffix: str | None = None) -> dict:
|
||||
return {
|
||||
"url": self.url,
|
||||
"user": f"{self.user}{user_suffix or ''}",
|
||||
"password": self.password,
|
||||
}
|
||||
|
||||
def as_auradine(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}
|
||||
def as_auradine(self, user_suffix: str | None = None) -> dict:
|
||||
return {
|
||||
"url": self.url,
|
||||
"user": f"{self.user}{user_suffix or ''}",
|
||||
"pass": self.password,
|
||||
}
|
||||
|
||||
def as_epic(self, user_suffix: str = None):
|
||||
if user_suffix is not None:
|
||||
return {
|
||||
"pool": self.url,
|
||||
"login": f"{self.user}{user_suffix}",
|
||||
"password": self.password,
|
||||
}
|
||||
return {"pool": self.url, "login": self.user, "password": self.password}
|
||||
def as_epic(self, user_suffix: str | None = None):
|
||||
return {
|
||||
"pool": self.url,
|
||||
"login": f"{self.user}{user_suffix or ''}",
|
||||
"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}
|
||||
def as_mara(self, user_suffix: str | None = None) -> dict:
|
||||
return {
|
||||
"url": self.url,
|
||||
"user": f"{self.user}{user_suffix or ''}",
|
||||
"pass": self.password,
|
||||
}
|
||||
|
||||
def as_bitaxe(self, user_suffix: str = None) -> dict:
|
||||
def as_espminer(self, user_suffix: str | None = None) -> dict:
|
||||
return {
|
||||
"stratumURL": self.url,
|
||||
"stratumUser": f"{self.user}{user_suffix}",
|
||||
"stratumUser": f"{self.user}{user_suffix or ''}",
|
||||
"stratumPassword": self.password,
|
||||
}
|
||||
|
||||
def as_boser(self) -> PoolConfiguration:
|
||||
def as_boser(self, user_suffix: str | None = None) -> PoolConfiguration:
|
||||
return PoolConfiguration(
|
||||
url=self.url, user=self.user, password=self.password, enabled=True
|
||||
url=self.url,
|
||||
user=f"{self.user}{user_suffix or ''}",
|
||||
password=self.password,
|
||||
enabled=True,
|
||||
)
|
||||
|
||||
def as_vnish(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}
|
||||
def as_vnish(self, user_suffix: str | None = None) -> dict:
|
||||
return {
|
||||
"url": self.url,
|
||||
"user": f"{self.user}{user_suffix or ''}",
|
||||
"pass": self.password,
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, dict_conf: dict | None) -> "Pool":
|
||||
@@ -177,6 +160,18 @@ class Pool(MinerConfigValue):
|
||||
url=web_pool["url"], user=web_pool["user"], password=web_pool["pass"]
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_hiveon_modern(cls, web_pool: dict) -> "Pool":
|
||||
return cls(
|
||||
url=web_pool["url"], user=web_pool["user"], password=web_pool["pass"]
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_elphapex(cls, web_pool: dict) -> "Pool":
|
||||
return cls(
|
||||
url=web_pool["url"], user=web_pool["user"], password=web_pool["pass"]
|
||||
)
|
||||
|
||||
# TODO: check if this is accurate, user/username, pass/password
|
||||
@classmethod
|
||||
def from_goldshell(cls, web_pool: dict) -> "Pool":
|
||||
@@ -195,13 +190,13 @@ class Pool(MinerConfigValue):
|
||||
return cls(
|
||||
url=toml_pool_conf["url"],
|
||||
user=toml_pool_conf["user"],
|
||||
password=toml_pool_conf["password"],
|
||||
password=toml_pool_conf.get("password", ""),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_vnish(cls, web_pool: dict) -> "Pool":
|
||||
return cls(
|
||||
url=web_pool["url"],
|
||||
url="stratum+tcp://" + web_pool["url"],
|
||||
user=web_pool["user"],
|
||||
password=web_pool["pass"],
|
||||
)
|
||||
@@ -223,7 +218,7 @@ class Pool(MinerConfigValue):
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_bitaxe(cls, web_system_info: dict) -> "Pool":
|
||||
def from_espminer(cls, web_system_info: dict) -> "Pool":
|
||||
url = f"stratum+tcp://{web_system_info['stratumURL']}:{web_system_info['stratumPort']}"
|
||||
return cls(
|
||||
url=url,
|
||||
@@ -255,7 +250,7 @@ class PoolGroup(MinerConfigValue):
|
||||
random.choice(string.ascii_uppercase + string.digits) for _ in range(6)
|
||||
) # generate random pool group name in case it isn't set
|
||||
|
||||
def as_am_modern(self, user_suffix: str = None) -> list:
|
||||
def as_am_modern(self, user_suffix: str | None = None) -> list:
|
||||
pools = []
|
||||
idx = 0
|
||||
while idx < 3:
|
||||
@@ -266,7 +261,29 @@ class PoolGroup(MinerConfigValue):
|
||||
idx += 1
|
||||
return pools
|
||||
|
||||
def as_wm(self, user_suffix: str = None) -> dict:
|
||||
def as_hiveon_modern(self, user_suffix: str | None = None) -> list:
|
||||
pools = []
|
||||
idx = 0
|
||||
while idx < 3:
|
||||
if len(self.pools) > idx:
|
||||
pools.append(self.pools[idx].as_hiveon_modern(user_suffix=user_suffix))
|
||||
else:
|
||||
pools.append(Pool(url="", user="", password="").as_hiveon_modern())
|
||||
idx += 1
|
||||
return pools
|
||||
|
||||
def as_elphapex(self, user_suffix: str | None = None) -> list:
|
||||
pools = []
|
||||
idx = 0
|
||||
while idx < 3:
|
||||
if len(self.pools) > idx:
|
||||
pools.append(self.pools[idx].as_elphapex(user_suffix=user_suffix))
|
||||
else:
|
||||
pools.append(Pool(url="", user="", password="").as_elphapex())
|
||||
idx += 1
|
||||
return pools
|
||||
|
||||
def as_wm(self, user_suffix: str | None = None) -> dict:
|
||||
pools = {}
|
||||
idx = 0
|
||||
while idx < 3:
|
||||
@@ -279,7 +296,7 @@ class PoolGroup(MinerConfigValue):
|
||||
idx += 1
|
||||
return pools
|
||||
|
||||
def as_am_old(self, user_suffix: str = None) -> dict:
|
||||
def as_am_old(self, user_suffix: str | None = None) -> dict:
|
||||
pools = {}
|
||||
idx = 0
|
||||
while idx < 3:
|
||||
@@ -294,15 +311,15 @@ class PoolGroup(MinerConfigValue):
|
||||
idx += 1
|
||||
return pools
|
||||
|
||||
def as_goldshell(self, user_suffix: str = None) -> list:
|
||||
def as_goldshell(self, user_suffix: str | None = None) -> list:
|
||||
return [pool.as_goldshell(user_suffix) for pool in self.pools]
|
||||
|
||||
def as_avalon(self, user_suffix: str = None) -> str:
|
||||
def as_avalon(self, user_suffix: str | None = None) -> str:
|
||||
if len(self.pools) > 0:
|
||||
return self.pools[0].as_avalon(user_suffix=user_suffix)
|
||||
return Pool(url="", user="", password="").as_avalon()
|
||||
|
||||
def as_inno(self, user_suffix: str = None) -> dict:
|
||||
def as_inno(self, user_suffix: str | None = None) -> dict:
|
||||
pools = {}
|
||||
idx = 0
|
||||
while idx < 3:
|
||||
@@ -315,7 +332,7 @@ class PoolGroup(MinerConfigValue):
|
||||
idx += 1
|
||||
return pools
|
||||
|
||||
def as_bosminer(self, user_suffix: str = None) -> dict:
|
||||
def as_bosminer(self, user_suffix: str | None = None) -> dict:
|
||||
if len(self.pools) > 0:
|
||||
conf = {
|
||||
"name": self.name,
|
||||
@@ -328,26 +345,26 @@ class PoolGroup(MinerConfigValue):
|
||||
return conf
|
||||
return {"name": "Group", "pool": []}
|
||||
|
||||
def as_auradine(self, user_suffix: str = None) -> list:
|
||||
def as_auradine(self, user_suffix: str | None = None) -> list:
|
||||
return [p.as_auradine(user_suffix=user_suffix) for p in self.pools]
|
||||
|
||||
def as_epic(self, user_suffix: str = None) -> list:
|
||||
def as_epic(self, user_suffix: str | None = None) -> list:
|
||||
return [p.as_epic(user_suffix=user_suffix) for p in self.pools]
|
||||
|
||||
def as_mara(self, user_suffix: str = None) -> list:
|
||||
def as_mara(self, user_suffix: str | None = None) -> list:
|
||||
return [p.as_mara(user_suffix=user_suffix) for p in self.pools]
|
||||
|
||||
def as_bitaxe(self, user_suffix: str = None) -> dict:
|
||||
return self.pools[0].as_bitaxe(user_suffix=user_suffix)
|
||||
def as_espminer(self, user_suffix: str | None = None) -> dict:
|
||||
return self.pools[0].as_espminer(user_suffix=user_suffix)
|
||||
|
||||
def as_boser(self, user_suffix: str = None) -> PoolGroupConfiguration:
|
||||
def as_boser(self, user_suffix: str | None = None) -> PoolGroupConfiguration:
|
||||
return PoolGroupConfiguration(
|
||||
name=self.name,
|
||||
quota=Quota(value=self.quota),
|
||||
pools=[p.as_boser() for p in self.pools],
|
||||
)
|
||||
|
||||
def as_vnish(self, user_suffix: str = None) -> dict:
|
||||
def as_vnish(self, user_suffix: str | None = None) -> dict:
|
||||
return {"pools": [p.as_vnish(user_suffix=user_suffix) for p in self.pools]}
|
||||
|
||||
@classmethod
|
||||
@@ -382,6 +399,20 @@ class PoolGroup(MinerConfigValue):
|
||||
pools.append(Pool.from_am_modern(pool))
|
||||
return cls(pools=pools)
|
||||
|
||||
@classmethod
|
||||
def from_hiveon_modern(cls, web_pool_list: list) -> "PoolGroup":
|
||||
pools = []
|
||||
for pool in web_pool_list:
|
||||
pools.append(Pool.from_hiveon_modern(pool))
|
||||
return cls(pools=pools)
|
||||
|
||||
@classmethod
|
||||
def from_elphapex(cls, web_pool_list: list) -> "PoolGroup":
|
||||
pools = []
|
||||
for pool in web_pool_list:
|
||||
pools.append(Pool.from_elphapex(pool))
|
||||
return cls(pools=pools)
|
||||
|
||||
@classmethod
|
||||
def from_goldshell(cls, web_pools: list) -> "PoolGroup":
|
||||
return cls(pools=[Pool.from_goldshell(p) for p in web_pools])
|
||||
@@ -395,14 +426,16 @@ class PoolGroup(MinerConfigValue):
|
||||
if toml_group_conf.get("pool") is not None:
|
||||
return cls(
|
||||
name=toml_group_conf["name"],
|
||||
quota=toml_group_conf.get("quota"),
|
||||
quota=toml_group_conf.get("quota", 1),
|
||||
pools=[Pool.from_bosminer(p) for p in toml_group_conf["pool"]],
|
||||
)
|
||||
return cls()
|
||||
|
||||
@classmethod
|
||||
def from_vnish(cls, web_settings_pools: dict) -> "PoolGroup":
|
||||
return cls(pools=[Pool.from_vnish(p) for p in web_settings_pools])
|
||||
return cls(
|
||||
pools=[Pool.from_vnish(p) for p in web_settings_pools if p["url"] != ""]
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_boser(cls, grpc_pool_group: dict) -> "PoolGroup":
|
||||
@@ -424,8 +457,8 @@ class PoolGroup(MinerConfigValue):
|
||||
return cls(pools=[Pool.from_mara(pool_conf) for pool_conf in web_config_pools])
|
||||
|
||||
@classmethod
|
||||
def from_bitaxe(cls, web_system_info: dict) -> "PoolGroup":
|
||||
return cls(pools=[Pool.from_bitaxe(web_system_info)])
|
||||
def from_espminer(cls, web_system_info: dict) -> "PoolGroup":
|
||||
return cls(pools=[Pool.from_espminer(web_system_info)])
|
||||
|
||||
@classmethod
|
||||
def from_iceriver(cls, web_userpanel: dict) -> "PoolGroup":
|
||||
@@ -460,44 +493,54 @@ class PoolConfig(MinerConfigValue):
|
||||
group_pools.append(pool)
|
||||
return cls(groups=[PoolGroup(pools=group_pools)])
|
||||
|
||||
def as_am_modern(self, user_suffix: str = None) -> dict:
|
||||
def as_am_modern(self, user_suffix: str | None = None) -> dict:
|
||||
if len(self.groups) > 0:
|
||||
return {"pools": self.groups[0].as_am_modern(user_suffix=user_suffix)}
|
||||
return {"pools": PoolGroup().as_am_modern()}
|
||||
|
||||
def as_wm(self, user_suffix: str = None) -> dict:
|
||||
def as_hiveon_modern(self, user_suffix: str | None = None) -> dict:
|
||||
if len(self.groups) > 0:
|
||||
return {"pools": self.groups[0].as_hiveon_modern(user_suffix=user_suffix)}
|
||||
return {"pools": PoolGroup().as_hiveon_modern()}
|
||||
|
||||
def as_elphapex(self, user_suffix: str | None = None) -> dict:
|
||||
if len(self.groups) > 0:
|
||||
return {"pools": self.groups[0].as_elphapex(user_suffix=user_suffix)}
|
||||
return {"pools": PoolGroup().as_elphapex()}
|
||||
|
||||
def as_wm(self, user_suffix: str | None = None) -> dict:
|
||||
if len(self.groups) > 0:
|
||||
return {"pools": self.groups[0].as_wm(user_suffix=user_suffix)}
|
||||
return {"pools": PoolGroup().as_wm()}
|
||||
|
||||
def as_am_old(self, user_suffix: str = None) -> dict:
|
||||
def as_am_old(self, user_suffix: str | None = None) -> dict:
|
||||
if len(self.groups) > 0:
|
||||
return self.groups[0].as_am_old(user_suffix=user_suffix)
|
||||
return PoolGroup().as_am_old()
|
||||
|
||||
def as_goldshell(self, user_suffix: str = None) -> dict:
|
||||
def as_goldshell(self, user_suffix: str | None = None) -> dict:
|
||||
if len(self.groups) > 0:
|
||||
return {"pools": self.groups[0].as_goldshell(user_suffix=user_suffix)}
|
||||
return {"pools": PoolGroup().as_goldshell()}
|
||||
|
||||
def as_avalon(self, user_suffix: str = None) -> dict:
|
||||
def as_avalon(self, user_suffix: str | None = None) -> dict:
|
||||
if len(self.groups) > 0:
|
||||
return {"pools": self.groups[0].as_avalon(user_suffix=user_suffix)}
|
||||
return {"pools": PoolGroup().as_avalon()}
|
||||
|
||||
def as_inno(self, user_suffix: str = None) -> dict:
|
||||
def as_inno(self, user_suffix: str | None = None) -> dict:
|
||||
if len(self.groups) > 0:
|
||||
return self.groups[0].as_inno(user_suffix=user_suffix)
|
||||
return PoolGroup().as_inno()
|
||||
|
||||
def as_bosminer(self, user_suffix: str = None) -> dict:
|
||||
def as_bosminer(self, user_suffix: str | None = None) -> dict:
|
||||
if len(self.groups) > 0:
|
||||
return {
|
||||
"group": [g.as_bosminer(user_suffix=user_suffix) for g in self.groups]
|
||||
}
|
||||
return {"group": [PoolGroup().as_bosminer()]}
|
||||
|
||||
def as_boser(self, user_suffix: str = None) -> dict:
|
||||
def as_boser(self, user_suffix: str | None = None) -> dict:
|
||||
return {
|
||||
"set_pool_groups": SetPoolGroupsRequest(
|
||||
save_action=SaveAction.SAVE_AND_APPLY,
|
||||
@@ -505,7 +548,7 @@ class PoolConfig(MinerConfigValue):
|
||||
)
|
||||
}
|
||||
|
||||
def as_auradine(self, user_suffix: str = None) -> dict:
|
||||
def as_auradine(self, user_suffix: str | None = None) -> dict:
|
||||
if len(self.groups) > 0:
|
||||
return {
|
||||
"updatepools": {
|
||||
@@ -514,7 +557,7 @@ class PoolConfig(MinerConfigValue):
|
||||
}
|
||||
return {"updatepools": {"pools": PoolGroup().as_auradine()}}
|
||||
|
||||
def as_epic(self, user_suffix: str = None) -> dict:
|
||||
def as_epic(self, user_suffix: str | None = None) -> dict:
|
||||
if len(self.groups) > 0:
|
||||
return {
|
||||
"pools": {
|
||||
@@ -531,18 +574,18 @@ class PoolConfig(MinerConfigValue):
|
||||
}
|
||||
}
|
||||
|
||||
def as_mara(self, user_suffix: str = None) -> dict:
|
||||
def as_mara(self, user_suffix: str | None = None) -> dict:
|
||||
if len(self.groups) > 0:
|
||||
return {"pools": self.groups[0].as_mara(user_suffix=user_suffix)}
|
||||
return {"pools": []}
|
||||
|
||||
def as_bitaxe(self, user_suffix: str = None) -> dict:
|
||||
return self.groups[0].as_bitaxe(user_suffix=user_suffix)
|
||||
def as_espminer(self, user_suffix: str | None = None) -> dict:
|
||||
return self.groups[0].as_espminer(user_suffix=user_suffix)
|
||||
|
||||
def as_luxos(self, user_suffix: str = None) -> dict:
|
||||
def as_luxos(self, user_suffix: str | None = None) -> dict:
|
||||
return {}
|
||||
|
||||
def as_vnish(self, user_suffix: str = None) -> dict:
|
||||
def as_vnish(self, user_suffix: str | None = None) -> dict:
|
||||
return self.groups[0].as_vnish(user_suffix=user_suffix)
|
||||
|
||||
@classmethod
|
||||
@@ -562,10 +605,28 @@ class PoolConfig(MinerConfigValue):
|
||||
|
||||
@classmethod
|
||||
def from_am_modern(cls, web_conf: dict) -> "PoolConfig":
|
||||
pool_data = web_conf["pools"]
|
||||
try:
|
||||
pool_data = web_conf["pools"]
|
||||
except KeyError:
|
||||
return cls(groups=[])
|
||||
|
||||
return cls(groups=[PoolGroup.from_am_modern(pool_data)])
|
||||
|
||||
@classmethod
|
||||
def from_hiveon_modern(cls, web_conf: dict) -> "PoolConfig":
|
||||
try:
|
||||
pool_data = web_conf["pools"]
|
||||
except KeyError:
|
||||
return cls(groups=[])
|
||||
|
||||
return cls(groups=[PoolGroup.from_hiveon_modern(pool_data)])
|
||||
|
||||
@classmethod
|
||||
def from_elphapex(cls, web_conf: dict) -> "PoolConfig":
|
||||
pool_data = web_conf["pools"]
|
||||
|
||||
return cls(groups=[PoolGroup.from_elphapex(pool_data)])
|
||||
|
||||
@classmethod
|
||||
def from_goldshell(cls, web_pools: list) -> "PoolConfig":
|
||||
return cls(groups=[PoolGroup.from_goldshell(web_pools)])
|
||||
@@ -605,8 +666,8 @@ class PoolConfig(MinerConfigValue):
|
||||
return cls(groups=[PoolGroup.from_mara(web_config["pools"])])
|
||||
|
||||
@classmethod
|
||||
def from_bitaxe(cls, web_system_info: dict) -> "PoolConfig":
|
||||
return cls(groups=[PoolGroup.from_bitaxe(web_system_info)])
|
||||
def from_espminer(cls, web_system_info: dict) -> "PoolConfig":
|
||||
return cls(groups=[PoolGroup.from_espminer(web_system_info)])
|
||||
|
||||
@classmethod
|
||||
def from_iceriver(cls, web_userpanel: dict) -> "PoolConfig":
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
from pyasic.config.base import MinerConfigValue
|
||||
|
||||
|
||||
|
||||
@@ -13,13 +13,12 @@
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
import copy
|
||||
import time
|
||||
from datetime import datetime, timezone
|
||||
from typing import Any, List, Union
|
||||
from typing import Any
|
||||
|
||||
from pydantic import BaseModel, Field, computed_field, field_serializer
|
||||
from pydantic import BaseModel, Field, computed_field
|
||||
|
||||
from pyasic.config import MinerConfig
|
||||
from pyasic.config.mining import MiningModePowerTune
|
||||
@@ -29,6 +28,7 @@ from pyasic.device.algorithm.hashrate import AlgoHashRateType
|
||||
from .boards import HashBoard
|
||||
from .device import DeviceInfo
|
||||
from .error_codes import BraiinsOSError, InnosiliconError, WhatsminerError, X19Error
|
||||
from .error_codes.base import BaseMinerError
|
||||
from .fans import Fan
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@ class MinerData(BaseModel):
|
||||
hostname: The network hostname of the miner as a str.
|
||||
hashrate: The hashrate of the miner in TH/s as a float. Calculated automatically.
|
||||
expected_hashrate: The factory nominal hashrate of the miner in TH/s as a float.
|
||||
sticker_hashrate: The factory sticker hashrate of the miner as a float.
|
||||
hashboards: A list of [`HashBoard`][pyasic.data.HashBoard]s on the miner with their statistics.
|
||||
temperature_avg: The average temperature across the boards. Calculated automatically.
|
||||
env_temp: The environment temps as a float.
|
||||
@@ -89,6 +90,9 @@ class MinerData(BaseModel):
|
||||
# hashrate
|
||||
raw_hashrate: AlgoHashRateType = Field(exclude=True, default=None, repr=False)
|
||||
|
||||
# sticker
|
||||
sticker_hashrate: AlgoHashRateType | None = None
|
||||
|
||||
# expected
|
||||
expected_hashrate: AlgoHashRateType | None = None
|
||||
expected_hashboards: int | None = None
|
||||
@@ -96,7 +100,7 @@ class MinerData(BaseModel):
|
||||
expected_fans: int | None = None
|
||||
|
||||
# temperature
|
||||
env_temp: int | None = None
|
||||
env_temp: float | None = None
|
||||
|
||||
# power
|
||||
wattage: int | None = None
|
||||
@@ -104,25 +108,18 @@ class MinerData(BaseModel):
|
||||
raw_wattage_limit: int | None = Field(exclude=True, default=None, repr=False)
|
||||
|
||||
# fans
|
||||
fans: List[Fan] = Field(default_factory=list)
|
||||
fans: list[Fan] = Field(default_factory=list)
|
||||
fan_psu: int | None = None
|
||||
|
||||
# boards
|
||||
hashboards: List[HashBoard] = Field(default_factory=list)
|
||||
hashboards: list[HashBoard] = Field(default_factory=list)
|
||||
|
||||
# config
|
||||
config: MinerConfig | None = None
|
||||
fault_light: bool | None = None
|
||||
|
||||
# errors
|
||||
errors: List[
|
||||
Union[
|
||||
WhatsminerError,
|
||||
BraiinsOSError,
|
||||
X19Error,
|
||||
InnosiliconError,
|
||||
]
|
||||
] = Field(default_factory=list)
|
||||
errors: list[BaseMinerError] = Field(default_factory=list)
|
||||
|
||||
# mining state
|
||||
is_mining: bool = True
|
||||
@@ -132,11 +129,10 @@ class MinerData(BaseModel):
|
||||
pools: list[PoolMetrics] = Field(default_factory=list)
|
||||
|
||||
@classmethod
|
||||
def fields(cls):
|
||||
return list(cls.model_fields.keys())
|
||||
|
||||
def __post_init__(self):
|
||||
self.raw_datetime = datetime.now(timezone.utc).astimezone()
|
||||
def fields(cls) -> set:
|
||||
all_fields = set(cls.model_fields.keys())
|
||||
all_fields.update(set(cls.model_computed_fields.keys()))
|
||||
return all_fields
|
||||
|
||||
def get(self, __key: str, default: Any = None):
|
||||
try:
|
||||
@@ -198,35 +194,23 @@ class MinerData(BaseModel):
|
||||
|
||||
@computed_field # type: ignore[misc]
|
||||
@property
|
||||
def hashrate(self) -> AlgoHashRateType:
|
||||
def hashrate(self) -> AlgoHashRateType | None:
|
||||
if len(self.hashboards) > 0:
|
||||
hr_data = []
|
||||
for item in self.hashboards:
|
||||
if item.hashrate is not None:
|
||||
hr_data.append(item.hashrate)
|
||||
if len(hr_data) > 0:
|
||||
return sum(hr_data, start=type(hr_data[0])(rate=0))
|
||||
return sum(hr_data, start=self.device_info.algo.hashrate(rate=0))
|
||||
return self.raw_hashrate
|
||||
|
||||
@field_serializer("hashrate")
|
||||
def serialize_hashrate(self, hashrate: AlgoHashRateType | None) -> float:
|
||||
if hashrate is not None:
|
||||
return float(hashrate)
|
||||
|
||||
@field_serializer("expected_hashrate")
|
||||
def serialize_expected_hashrate(
|
||||
self, expected_hashrate: AlgoHashRateType | None, _info
|
||||
) -> float:
|
||||
if expected_hashrate is not None:
|
||||
return float(expected_hashrate)
|
||||
|
||||
@hashrate.setter
|
||||
def hashrate(self, val):
|
||||
self.raw_hashrate = val
|
||||
|
||||
@computed_field # type: ignore[misc]
|
||||
@property
|
||||
def wattage_limit(self) -> int:
|
||||
def wattage_limit(self) -> int | None:
|
||||
if self.config is not None:
|
||||
if isinstance(self.config.mining_mode, MiningModePowerTune):
|
||||
return self.config.mining_mode.power
|
||||
@@ -300,10 +284,22 @@ class MinerData(BaseModel):
|
||||
@computed_field # type: ignore[misc]
|
||||
@property
|
||||
def efficiency(self) -> int | None:
|
||||
efficiency = self._efficiency(0)
|
||||
if efficiency is None:
|
||||
return None
|
||||
else:
|
||||
return int(efficiency)
|
||||
|
||||
@computed_field # type: ignore[misc]
|
||||
@property
|
||||
def efficiency_fract(self) -> float | None:
|
||||
self._efficiency(2)
|
||||
|
||||
def _efficiency(self, ndigits: int) -> float | None:
|
||||
if self.hashrate is None or self.wattage is None:
|
||||
return None
|
||||
try:
|
||||
return round(self.wattage / float(self.hashrate))
|
||||
return round(self.wattage / float(self.hashrate), ndigits)
|
||||
except ZeroDivisionError:
|
||||
return 0
|
||||
|
||||
@@ -319,25 +315,25 @@ class MinerData(BaseModel):
|
||||
|
||||
@computed_field # type: ignore[misc]
|
||||
@property
|
||||
def make(self) -> str:
|
||||
def make(self) -> str | None:
|
||||
if self.device_info.make is not None:
|
||||
return str(self.device_info.make)
|
||||
|
||||
@computed_field # type: ignore[misc]
|
||||
@property
|
||||
def model(self) -> str:
|
||||
def model(self) -> str | None:
|
||||
if self.device_info.model is not None:
|
||||
return str(self.device_info.model)
|
||||
|
||||
@computed_field # type: ignore[misc]
|
||||
@property
|
||||
def firmware(self) -> str:
|
||||
def firmware(self) -> str | None:
|
||||
if self.device_info.firmware is not None:
|
||||
return str(self.device_info.firmware)
|
||||
|
||||
@computed_field # type: ignore[misc]
|
||||
@property
|
||||
def algo(self) -> str:
|
||||
def algo(self) -> str | None:
|
||||
if self.device_info.algo is not None:
|
||||
return str(self.device_info.algo)
|
||||
|
||||
@@ -377,7 +373,9 @@ class MinerData(BaseModel):
|
||||
data_list = [str(data[item]) for item in data]
|
||||
return ",".join(data_list)
|
||||
|
||||
def as_influxdb(self, measurement_name: str = "miner_data") -> str:
|
||||
def as_influxdb(
|
||||
self, measurement_name: str = "miner_data", level_delimiter: str = "."
|
||||
) -> str:
|
||||
"""Get this dataclass as [influxdb line protocol](https://docs.influxdata.com/influxdb/v2.4/reference/syntax/line-protocol/).
|
||||
|
||||
Parameters:
|
||||
@@ -386,54 +384,127 @@ class MinerData(BaseModel):
|
||||
Returns:
|
||||
A influxdb line protocol version of this class.
|
||||
"""
|
||||
tag_data = [measurement_name]
|
||||
|
||||
def serialize_int(key: str, value: int) -> str:
|
||||
return f"{key}={value}"
|
||||
|
||||
def serialize_float(key: str, value: float) -> str:
|
||||
return f"{key}={value}"
|
||||
|
||||
def serialize_str(key: str, value: str) -> str:
|
||||
return f'{key}="{value}"'
|
||||
|
||||
def serialize_algo_hash_rate(key: str, value: AlgoHashRateType) -> str:
|
||||
return f"{key}={round(float(value), 2)}"
|
||||
|
||||
def serialize_list(key: str, value: list[Any]) -> str | None:
|
||||
if len(value) == 0:
|
||||
return None
|
||||
|
||||
list_field_data = []
|
||||
for idx, list_field_val in enumerate(value):
|
||||
item_serialization_func = serialization_map.get(
|
||||
type(list_field_val), lambda _k, _v: None
|
||||
)
|
||||
item_serialized = item_serialization_func(
|
||||
f"{key}{level_delimiter}{idx}", list_field_val
|
||||
)
|
||||
if item_serialized is not None:
|
||||
list_field_data.append(item_serialized)
|
||||
continue
|
||||
for dt in serialization_map_instance:
|
||||
if item_serialized is None:
|
||||
if isinstance(list_field_val, dt):
|
||||
item_serialized = serialization_map_instance[dt](
|
||||
f"{key}{level_delimiter}{idx}", list_field_val
|
||||
)
|
||||
if item_serialized is not None:
|
||||
list_field_data.append(item_serialized)
|
||||
return ",".join(list_field_data)
|
||||
|
||||
def serialize_miner_error(key: str, value: BaseMinerError):
|
||||
return value.as_influxdb(key, level_delimiter=level_delimiter)
|
||||
|
||||
def serialize_fan(key: str, value: Fan) -> str:
|
||||
return f"{key}{level_delimiter}speed={value.speed}"
|
||||
|
||||
def serialize_hashboard(key: str, value: HashBoard) -> str:
|
||||
return value.as_influxdb(key, level_delimiter=level_delimiter)
|
||||
|
||||
def serialize_bool(key: str, value: bool):
|
||||
return f"{key}={str(value).lower()}"
|
||||
|
||||
def serialize_pool_metrics(key: str, value: PoolMetrics):
|
||||
return value.as_influxdb(key, level_delimiter=level_delimiter)
|
||||
|
||||
include = [
|
||||
"uptime",
|
||||
"expected_hashrate",
|
||||
"hashrate",
|
||||
"hashboards",
|
||||
"temperature_avg",
|
||||
"env_temp",
|
||||
"wattage",
|
||||
"wattage_limit",
|
||||
"voltage",
|
||||
"fans",
|
||||
"expected_fans",
|
||||
"fan_psu",
|
||||
"total_chips",
|
||||
"expected_chips",
|
||||
"efficiency",
|
||||
"fault_light",
|
||||
"is_mining",
|
||||
"errors",
|
||||
"pools",
|
||||
]
|
||||
|
||||
serialization_map_instance = {
|
||||
AlgoHashRateType: serialize_algo_hash_rate,
|
||||
BaseMinerError: serialize_miner_error,
|
||||
}
|
||||
serialization_map = {
|
||||
int: serialize_int,
|
||||
float: serialize_float,
|
||||
str: serialize_str,
|
||||
bool: serialize_bool,
|
||||
list: serialize_list,
|
||||
Fan: serialize_fan,
|
||||
HashBoard: serialize_hashboard,
|
||||
PoolMetrics: serialize_pool_metrics,
|
||||
}
|
||||
|
||||
tag_data = [
|
||||
measurement_name,
|
||||
f"ip={str(self.ip)}",
|
||||
f"mac={str(self.mac)}",
|
||||
f"make={str(self.make)}",
|
||||
f"model={str(self.model)}",
|
||||
f"firmware={str(self.firmware)}",
|
||||
f"algo={str(self.algo)}",
|
||||
]
|
||||
field_data = []
|
||||
|
||||
tags = ["ip", "mac", "model", "hostname"]
|
||||
for attribute in self.fields():
|
||||
if attribute in tags:
|
||||
escaped_data = self.get(attribute, "Unknown").replace(" ", "\\ ")
|
||||
tag_data.append(f"{attribute}={escaped_data}")
|
||||
for field in include:
|
||||
field_val = getattr(self, field)
|
||||
serialization_func = serialization_map.get(
|
||||
type(field_val), lambda _k, _v: None
|
||||
)
|
||||
serialized = serialization_func(field, field_val)
|
||||
if serialized is not None:
|
||||
field_data.append(serialized)
|
||||
continue
|
||||
elif str(attribute).startswith("_"):
|
||||
continue
|
||||
elif isinstance(self[attribute], str):
|
||||
field_data.append(f'{attribute}="{self[attribute]}"')
|
||||
continue
|
||||
elif isinstance(self[attribute], bool):
|
||||
field_data.append(f"{attribute}={str(self[attribute]).lower()}")
|
||||
continue
|
||||
elif isinstance(self[attribute], int):
|
||||
field_data.append(f"{attribute}={self[attribute]}")
|
||||
continue
|
||||
elif isinstance(self[attribute], float):
|
||||
field_data.append(f"{attribute}={self[attribute]}")
|
||||
continue
|
||||
elif attribute == "errors":
|
||||
for idx, item in enumerate(self[attribute]):
|
||||
field_data.append(f'error_{idx+1}="{item.error_message}"')
|
||||
elif attribute == "hashboards":
|
||||
for idx, item in enumerate(self[attribute]):
|
||||
field_data.append(
|
||||
f"hashboard_{idx+1}_hashrate={item.get('hashrate', 0.0)}"
|
||||
)
|
||||
field_data.append(
|
||||
f"hashboard_{idx+1}_temperature={item.get('temp', 0)}"
|
||||
)
|
||||
field_data.append(
|
||||
f"hashboard_{idx+1}_chip_temperature={item.get('chip_temp', 0)}"
|
||||
)
|
||||
field_data.append(f"hashboard_{idx+1}_chips={item.get('chips', 0)}")
|
||||
field_data.append(
|
||||
f"hashboard_{idx+1}_expected_chips={item.get('expected_chips', 0)}"
|
||||
)
|
||||
elif attribute == "fans":
|
||||
for idx, item in enumerate(self[attribute]):
|
||||
if item.speed is not None:
|
||||
field_data.append(f"fan_{idx+1}={item.speed}")
|
||||
for datatype in serialization_map_instance:
|
||||
if serialized is None:
|
||||
if isinstance(field_val, datatype):
|
||||
serialized = serialization_map_instance[datatype](
|
||||
field, field_val
|
||||
)
|
||||
if serialized is not None:
|
||||
field_data.append(serialized)
|
||||
|
||||
tags_str = ",".join(tag_data)
|
||||
field_str = ",".join(field_data)
|
||||
timestamp = str(self.timestamp * 1e9)
|
||||
tags_str = ",".join(tag_data).replace(" ", "\\ ")
|
||||
field_str = ",".join(field_data).replace(" ", "\\ ")
|
||||
timestamp = str(self.timestamp * 10**9)
|
||||
|
||||
return " ".join([tags_str, field_str, timestamp])
|
||||
|
||||
@@ -17,7 +17,7 @@ from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from pydantic import BaseModel, field_serializer
|
||||
from pydantic import BaseModel
|
||||
|
||||
from pyasic.device.algorithm.hashrate import AlgoHashRateType
|
||||
|
||||
@@ -28,6 +28,8 @@ class HashBoard(BaseModel):
|
||||
Attributes:
|
||||
slot: The slot of the board as an int.
|
||||
hashrate: The hashrate of the board in TH/s as a float.
|
||||
inlet_temp: Inlet temperature for hydro asics as an int
|
||||
outlet_temp: Outlet temperature for hydro asics as an int
|
||||
temp: The temperature of the PCB as an int.
|
||||
chip_temp: The temperature of the chips as an int.
|
||||
chips: The chip count of the board as an int.
|
||||
@@ -41,6 +43,8 @@ class HashBoard(BaseModel):
|
||||
|
||||
slot: int = 0
|
||||
hashrate: AlgoHashRateType | None = None
|
||||
inlet_temp: float | None = None
|
||||
outlet_temp: float | None = None
|
||||
temp: float | None = None
|
||||
chip_temp: float | None = None
|
||||
chips: int | None = None
|
||||
@@ -51,10 +55,11 @@ class HashBoard(BaseModel):
|
||||
active: bool | None = None
|
||||
voltage: float | None = None
|
||||
|
||||
@field_serializer("hashrate")
|
||||
def serialize_hashrate(self, hashrate: AlgoHashRateType | None) -> float:
|
||||
if hashrate is not None:
|
||||
return float(hashrate)
|
||||
@classmethod
|
||||
def fields(cls) -> set:
|
||||
all_fields = set(cls.model_fields.keys())
|
||||
all_fields.update(set(cls.model_computed_fields.keys()))
|
||||
return all_fields
|
||||
|
||||
def get(self, __key: str, default: Any = None):
|
||||
try:
|
||||
@@ -70,3 +75,63 @@ class HashBoard(BaseModel):
|
||||
return getattr(self, item)
|
||||
except AttributeError:
|
||||
raise KeyError(f"{item}")
|
||||
|
||||
def as_influxdb(self, key_root: str, level_delimiter: str = ".") -> str:
|
||||
|
||||
def serialize_int(key: str, value: int) -> str:
|
||||
return f"{key}={value}"
|
||||
|
||||
def serialize_float(key: str, value: float) -> str:
|
||||
return f"{key}={value}"
|
||||
|
||||
def serialize_str(key: str, value: str) -> str:
|
||||
return f'{key}="{value}"'
|
||||
|
||||
def serialize_algo_hash_rate(key: str, value: AlgoHashRateType) -> str:
|
||||
return f"{key}={round(float(value), 2)}"
|
||||
|
||||
def serialize_bool(key: str, value: bool):
|
||||
return f"{key}={str(value).lower()}"
|
||||
|
||||
serialization_map_instance = {
|
||||
AlgoHashRateType: serialize_algo_hash_rate,
|
||||
}
|
||||
serialization_map = {
|
||||
int: serialize_int,
|
||||
float: serialize_float,
|
||||
str: serialize_str,
|
||||
bool: serialize_bool,
|
||||
}
|
||||
|
||||
include = [
|
||||
"hashrate",
|
||||
"temp",
|
||||
"chip_temp",
|
||||
"chips",
|
||||
"expected_chips",
|
||||
"tuned",
|
||||
"active",
|
||||
"voltage",
|
||||
]
|
||||
|
||||
field_data = []
|
||||
for field in include:
|
||||
field_val = getattr(self, field)
|
||||
serialization_func = serialization_map.get(
|
||||
type(field_val), lambda _k, _v: None
|
||||
)
|
||||
serialized = serialization_func(
|
||||
f"{key_root}{level_delimiter}{field}", field_val
|
||||
)
|
||||
if serialized is not None:
|
||||
field_data.append(serialized)
|
||||
continue
|
||||
for datatype in serialization_map_instance:
|
||||
if serialized is None:
|
||||
if isinstance(field_val, datatype):
|
||||
serialized = serialization_map_instance[datatype](
|
||||
f"{key_root}{level_delimiter}{field}", field_val
|
||||
)
|
||||
if serialized is not None:
|
||||
field_data.append(serialized)
|
||||
return ",".join(field_data)
|
||||
|
||||
@@ -18,9 +18,15 @@ from typing import TypeVar
|
||||
|
||||
from .bos import BraiinsOSError
|
||||
from .innosilicon import InnosiliconError
|
||||
from .vnish import VnishError
|
||||
from .whatsminer import WhatsminerError
|
||||
from .X19 import X19Error
|
||||
|
||||
MinerErrorData = TypeVar(
|
||||
"MinerErrorData", WhatsminerError, BraiinsOSError, X19Error, InnosiliconError
|
||||
"MinerErrorData",
|
||||
WhatsminerError,
|
||||
BraiinsOSError,
|
||||
X19Error,
|
||||
InnosiliconError,
|
||||
VnishError,
|
||||
)
|
||||
|
||||
@@ -16,3 +16,17 @@ class BaseMinerError(BaseModel):
|
||||
A dictionary version of this class.
|
||||
"""
|
||||
return self.asdict()
|
||||
|
||||
def as_influxdb(self, root_key: str, level_delimiter: str = ".") -> str:
|
||||
field_data = []
|
||||
|
||||
if self.error_code is not None:
|
||||
field_data.append(
|
||||
f"{root_key}{level_delimiter}error_code={self.error_code}"
|
||||
)
|
||||
if self.error_message is not None:
|
||||
field_data.append(
|
||||
f'{root_key}{level_delimiter}error_message="{self.error_message}"'
|
||||
)
|
||||
|
||||
return ",".join(field_data)
|
||||
|
||||
28
pyasic/data/error_codes/vnish.py
Normal file
28
pyasic/data/error_codes/vnish.py
Normal file
@@ -0,0 +1,28 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# 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.data.error_codes.base import BaseMinerError
|
||||
|
||||
|
||||
class VnishError(BaseMinerError):
|
||||
"""A Dataclass to handle error codes of Vnish miners.
|
||||
|
||||
Attributes:
|
||||
error_message: The error message as a string.
|
||||
error_code: The error code as an int. 0 if the message is not assigned a code.
|
||||
"""
|
||||
|
||||
error_message: str
|
||||
error_code: int = 0
|
||||
@@ -92,3 +92,51 @@ class PoolMetrics(BaseModel):
|
||||
if total == 0:
|
||||
return 0
|
||||
return (value / total) * 100
|
||||
|
||||
def as_influxdb(self, key_root: str, level_delimiter: str = ".") -> str:
|
||||
|
||||
def serialize_int(key: str, value: int) -> str:
|
||||
return f"{key}={value}"
|
||||
|
||||
def serialize_float(key: str, value: float) -> str:
|
||||
return f"{key}={value}"
|
||||
|
||||
def serialize_str(key: str, value: str) -> str:
|
||||
return f'{key}="{value}"'
|
||||
|
||||
def serialize_pool_url(key: str, value: str) -> str:
|
||||
return f'{key}="{str(value)}"'
|
||||
|
||||
def serialize_bool(key: str, value: bool):
|
||||
return f"{key}={str(value).lower()}"
|
||||
|
||||
serialization_map = {
|
||||
int: serialize_int,
|
||||
float: serialize_float,
|
||||
str: serialize_str,
|
||||
bool: serialize_bool,
|
||||
PoolUrl: serialize_pool_url,
|
||||
}
|
||||
|
||||
include = [
|
||||
"url",
|
||||
"accepted",
|
||||
"rejected",
|
||||
"active",
|
||||
"alive",
|
||||
"user",
|
||||
]
|
||||
|
||||
field_data = []
|
||||
for field in include:
|
||||
field_val = getattr(self, field)
|
||||
serialization_func = serialization_map.get(
|
||||
type(field_val), lambda _k, _v: None
|
||||
)
|
||||
serialized = serialization_func(
|
||||
f"{key_root}{level_delimiter}{field}", field_val
|
||||
)
|
||||
if serialized is not None:
|
||||
field_data.append(serialized)
|
||||
|
||||
return ",".join(field_data)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from .hashrate.base import AlgoHashRateType
|
||||
from .hashrate.unit.base import AlgoHashRateUnitType
|
||||
from .hashrate.base import AlgoHashRateType, GenericHashrate
|
||||
from .hashrate.unit.base import AlgoHashRateUnitType, GenericUnit
|
||||
|
||||
|
||||
class MinerAlgoMeta(type):
|
||||
@@ -14,3 +14,10 @@ class MinerAlgoMeta(type):
|
||||
class MinerAlgoType(metaclass=MinerAlgoMeta):
|
||||
hashrate: type[AlgoHashRateType]
|
||||
unit: type[AlgoHashRateUnitType]
|
||||
|
||||
|
||||
class GenericAlgo(MinerAlgoType):
|
||||
hashrate: type[GenericHashrate] = GenericHashrate
|
||||
unit: type[GenericUnit] = GenericUnit
|
||||
|
||||
name = "Generic (Unknown)"
|
||||
|
||||
@@ -1,19 +1,42 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
from pydantic import BaseModel
|
||||
from pydantic import BaseModel, field_serializer
|
||||
from typing_extensions import Self
|
||||
|
||||
from .unit.base import AlgoHashRateUnitType
|
||||
from .unit.base import AlgoHashRateUnitType, GenericUnit
|
||||
|
||||
|
||||
class AlgoHashRateType(BaseModel, ABC):
|
||||
unit: AlgoHashRateUnitType
|
||||
rate: float
|
||||
|
||||
@field_serializer("unit")
|
||||
def serialize_unit(self, unit: AlgoHashRateUnitType):
|
||||
return unit.model_dump()
|
||||
|
||||
@abstractmethod
|
||||
def into(self, other: "AlgoHashRateUnitType"):
|
||||
pass
|
||||
|
||||
def auto_unit(self):
|
||||
if 1 < self.rate // int(self.unit.H) < 1000:
|
||||
return self.into(self.unit.H)
|
||||
if 1 < self.rate // int(self.unit.MH) < 1000:
|
||||
return self.into(self.unit.MH)
|
||||
if 1 < self.rate // int(self.unit.GH) < 1000:
|
||||
return self.into(self.unit.GH)
|
||||
if 1 < self.rate // int(self.unit.TH) < 1000:
|
||||
return self.into(self.unit.TH)
|
||||
if 1 < self.rate // int(self.unit.PH) < 1000:
|
||||
return self.into(self.unit.PH)
|
||||
if 1 < self.rate // int(self.unit.EH) < 1000:
|
||||
return self.into(self.unit.EH)
|
||||
if 1 < self.rate // int(self.unit.ZH) < 1000:
|
||||
return self.into(self.unit.ZH)
|
||||
return self
|
||||
|
||||
def __float__(self):
|
||||
return float(self.rate)
|
||||
|
||||
@@ -27,36 +50,46 @@ class AlgoHashRateType(BaseModel, ABC):
|
||||
return round(self.rate, n)
|
||||
|
||||
def __add__(self, other: Self | int | float) -> Self:
|
||||
if isinstance(other, self.__class__):
|
||||
if isinstance(other, AlgoHashRateType):
|
||||
return self.__class__(
|
||||
rate=self.rate + other.into(self.unit).rate, unit=self.unit
|
||||
)
|
||||
return self.__class__(rate=self.rate + other, unit=self.unit)
|
||||
|
||||
def __sub__(self, other: Self | int | float) -> Self:
|
||||
if isinstance(other, self.__class__):
|
||||
if isinstance(other, AlgoHashRateType):
|
||||
return self.__class__(
|
||||
rate=self.rate - other.into(self.unit).rate, unit=self.unit
|
||||
)
|
||||
return self.__class__(rate=self.rate - other, unit=self.unit)
|
||||
|
||||
def __truediv__(self, other: Self | int | float) -> Self:
|
||||
if isinstance(other, self.__class__):
|
||||
if isinstance(other, AlgoHashRateType):
|
||||
return self.__class__(
|
||||
rate=self.rate / other.into(self.unit).rate, unit=self.unit
|
||||
)
|
||||
return self.__class__(rate=self.rate / other, unit=self.unit)
|
||||
|
||||
def __floordiv__(self, other: Self | int | float) -> Self:
|
||||
if isinstance(other, self.__class__):
|
||||
if isinstance(other, AlgoHashRateType):
|
||||
return self.__class__(
|
||||
rate=self.rate // other.into(self.unit).rate, unit=self.unit
|
||||
)
|
||||
return self.__class__(rate=self.rate // other, unit=self.unit)
|
||||
|
||||
def __mul__(self, other: Self | int | float) -> Self:
|
||||
if isinstance(other, self.__class__):
|
||||
if isinstance(other, AlgoHashRateType):
|
||||
return self.__class__(
|
||||
rate=self.rate * other.into(self.unit).rate, unit=self.unit
|
||||
)
|
||||
return self.__class__(rate=self.rate * other, unit=self.unit)
|
||||
|
||||
|
||||
class GenericHashrate(AlgoHashRateType):
|
||||
rate: float = 0
|
||||
unit: GenericUnit = GenericUnit.H
|
||||
|
||||
def into(self, other: GenericUnit):
|
||||
return self.__class__(
|
||||
rate=self.rate / (other.value / self.unit.value), unit=other
|
||||
)
|
||||
|
||||
@@ -53,3 +53,19 @@ class AlgoHashRateUnitType(IntEnum):
|
||||
|
||||
def __repr__(self):
|
||||
return str(self)
|
||||
|
||||
def model_dump(self):
|
||||
return {"value": self.value, "suffix": str(self)}
|
||||
|
||||
|
||||
class GenericUnit(AlgoHashRateUnitType):
|
||||
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 = H
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from enum import IntEnum
|
||||
from .base import AlgoHashRateUnitType
|
||||
|
||||
|
||||
class ScryptUnit(IntEnum):
|
||||
class ScryptUnit(AlgoHashRateUnitType):
|
||||
H = 1
|
||||
KH = int(H) * 1000
|
||||
MH = int(KH) * 1000
|
||||
|
||||
@@ -26,8 +26,12 @@ class MinerMake(str, Enum):
|
||||
AURADINE = "Auradine"
|
||||
EPIC = "ePIC"
|
||||
BITAXE = "BitAxe"
|
||||
LUCKYMINER = "LuckyMiner"
|
||||
ICERIVER = "IceRiver"
|
||||
HAMMER = "Hammer"
|
||||
VOLCMINER = "VolcMiner"
|
||||
ELPHAPEX = "Elphapex"
|
||||
BRAIINS = "Braiins"
|
||||
|
||||
def __str__(self):
|
||||
return self.value
|
||||
|
||||
@@ -13,6 +13,7 @@ class AntminerModels(MinerModelType):
|
||||
KS3 = "KS3"
|
||||
DR5 = "DR5"
|
||||
KS5 = "KS5"
|
||||
KS5Pro = "KS5Pro"
|
||||
L7 = "L7"
|
||||
K7 = "K7"
|
||||
D7 = "D7"
|
||||
@@ -22,6 +23,7 @@ class AntminerModels(MinerModelType):
|
||||
S9j = "S9j"
|
||||
T9 = "T9"
|
||||
D9 = "D9"
|
||||
L9 = "L9"
|
||||
Z15 = "Z15"
|
||||
Z15Pro = "Z15 Pro"
|
||||
S17 = "S17"
|
||||
@@ -53,9 +55,13 @@ class AntminerModels(MinerModelType):
|
||||
S19KPro = "S19K Pro"
|
||||
S19kPro = "S19k Pro"
|
||||
S19kProNoPIC = "S19k Pro No PIC"
|
||||
S19jXP = "S19j XP"
|
||||
T19 = "T19"
|
||||
S21 = "S21"
|
||||
S21Plus = "S21+"
|
||||
S21PlusHydro = "S21+ Hydro"
|
||||
S21Pro = "S21 Pro"
|
||||
S21Hydro = "S21 Hydro"
|
||||
T21 = "T21"
|
||||
|
||||
def __str__(self):
|
||||
@@ -63,23 +69,84 @@ class AntminerModels(MinerModelType):
|
||||
|
||||
|
||||
class WhatsminerModels(MinerModelType):
|
||||
M20V10 = "M20 V10"
|
||||
M20SV10 = "M20S V10"
|
||||
M20SV20 = "M20S V20"
|
||||
M20SV30 = "M20S V30"
|
||||
M20PV10 = "M20P V10"
|
||||
M20PV30 = "M20P V30"
|
||||
M20SPlusV30 = "M20S+ V30"
|
||||
M21V10 = "M21 V10"
|
||||
M20SV10 = "M20S V10"
|
||||
M20SV20 = "M20S V20"
|
||||
M20SV30 = "M20S V30"
|
||||
M20V10 = "M20 V10"
|
||||
M21SPlusV20 = "M21S+ V20"
|
||||
M21SV20 = "M21S V20"
|
||||
M21SV60 = "M21S V60"
|
||||
M21SV70 = "M21S V70"
|
||||
M21SPlusV20 = "M21S+ V20"
|
||||
M21V10 = "M21 V10"
|
||||
M29V10 = "M29 V10"
|
||||
M30V10 = "M30 V10"
|
||||
M30V20 = "M30 V20"
|
||||
M30KV10 = "M30K V10"
|
||||
M30LV10 = "M30L V10"
|
||||
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"
|
||||
M30SPlusPlusVH100 = "M30S++ VH100"
|
||||
M30SPlusPlusVH110 = "M30S++ VH110"
|
||||
M30SPlusPlusVH20 = "M30S++ VH20"
|
||||
M30SPlusPlusVH30 = "M30S++ VH30"
|
||||
M30SPlusPlusVH40 = "M30S++ VH40"
|
||||
M30SPlusPlusVH50 = "M30S++ VH50"
|
||||
M30SPlusPlusVH60 = "M30S++ VH60"
|
||||
M30SPlusPlusVH70 = "M30S++ VH70"
|
||||
M30SPlusPlusVH80 = "M30S++ VH80"
|
||||
M30SPlusPlusVH90 = "M30S++ VH90"
|
||||
M30SPlusPlusVI30 = "M30S++ VI30"
|
||||
M30SPlusPlusVJ20 = "M30S++ VJ20"
|
||||
M30SPlusPlusVJ30 = "M30S++ VJ30"
|
||||
M30SPlusPlusVJ50 = "M30S++ VJ50"
|
||||
M30SPlusPlusVJ60 = "M30S++ VJ60"
|
||||
M30SPlusPlusVJ70 = "M30S++ VJ70"
|
||||
M30SPlusPlusVK30 = "M30S++ VK30"
|
||||
M30SPlusPlusVK40 = "M30S++ VK40"
|
||||
M30SPlusV10 = "M30S+ V10"
|
||||
M30SPlusV100 = "M30S+ V100"
|
||||
M30SPlusV20 = "M30S+ V20"
|
||||
M30SPlusV30 = "M30S+ V30"
|
||||
M30SPlusV40 = "M30S+ V40"
|
||||
M30SPlusV50 = "M30S+ V50"
|
||||
M30SPlusV60 = "M30S+ V60"
|
||||
M30SPlusV70 = "M30S+ V70"
|
||||
M30SPlusV80 = "M30S+ V80"
|
||||
M30SPlusV90 = "M30S+ V90"
|
||||
M30SPlusVE100 = "M30S+ VE100"
|
||||
M30SPlusVE30 = "M30S+ VE30"
|
||||
M30SPlusVE40 = "M30S+ VE40"
|
||||
M30SPlusVE50 = "M30S+ VE50"
|
||||
M30SPlusVE60 = "M30S+ VE60"
|
||||
M30SPlusVE70 = "M30S+ VE70"
|
||||
M30SPlusVE80 = "M30S+ VE80"
|
||||
M30SPlusVE90 = "M30S+ VE90"
|
||||
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"
|
||||
M30SPlusVH70 = "M30S+ VH70"
|
||||
M30SPlusVI30 = "M30S+ VI30"
|
||||
M30SPlusVJ30 = "M30S+ VJ30"
|
||||
M30SPlusVJ40 = "M30S+ VJ40"
|
||||
M30SV10 = "M30S V10"
|
||||
M30SV20 = "M30S V20"
|
||||
M30SV30 = "M30S V30"
|
||||
@@ -109,63 +176,35 @@ class WhatsminerModels(MinerModelType):
|
||||
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"
|
||||
M30SVJ30 = "M30S VJ30"
|
||||
M30V10 = "M30 V10"
|
||||
M30V20 = "M30 V20"
|
||||
M31HV10 = "M31H V10"
|
||||
M31HV40 = "M31H V40"
|
||||
M31LV10 = "M30L V10"
|
||||
M31LV10 = "M31L V10"
|
||||
M31SPlusV10 = "M31S+ V10"
|
||||
M31SPlusV100 = "M31S+ V100"
|
||||
M31SPlusV20 = "M31S+ V20"
|
||||
M31SPlusV30 = "M31S+ V30"
|
||||
M31SPlusV40 = "M31S+ V40"
|
||||
M31SPlusV50 = "M31S+ V50"
|
||||
M31SPlusV60 = "M31S+ V60"
|
||||
M31SPlusV80 = "M31S+ V80"
|
||||
M31SPlusV90 = "M31S+ V90"
|
||||
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"
|
||||
M31SEV10 = "M31SE V10"
|
||||
M31SEV20 = "M31SE V20"
|
||||
M31SEV30 = "M31SE V30"
|
||||
M31SV10 = "M31S V10"
|
||||
M31SV20 = "M31S V20"
|
||||
M31SV30 = "M31S V30"
|
||||
@@ -178,49 +217,69 @@ class WhatsminerModels(MinerModelType):
|
||||
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"
|
||||
M31V10 = "M31 V10"
|
||||
M31V20 = "M31 V20"
|
||||
M32V10 = "M32 V10"
|
||||
M32V20 = "M32 V20"
|
||||
M32S = "M32S"
|
||||
M33SPlusPlusVG40 = "M33S++ VG40"
|
||||
M33SPlusPlusVH20 = "M33S++ VH20"
|
||||
M33SPlusPlusVH30 = "M33S++ VH30"
|
||||
M33SPlusVG20 = "M33S+ VG20"
|
||||
M33SPlusVG30 = "M33S+ VG30"
|
||||
M33SPlusVH20 = "M33S+ VH20"
|
||||
M33SPlusVH30 = "M33S+ VH30"
|
||||
M33SVG30 = "M33S VG30"
|
||||
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"
|
||||
M36SPlusVG30 = "M36S+ VG30"
|
||||
M36SVE10 = "M36S VE10"
|
||||
M39V10 = "M39 V10"
|
||||
M39V20 = "M39 V20"
|
||||
M39V30 = "M39 V30"
|
||||
M50SPlusPlusVK10 = "M50S++ VK10"
|
||||
M50SPlusPlusVK20 = "M50S++ VK20"
|
||||
M50SPlusPlusVK30 = "M50S++ VK30"
|
||||
M50SPlusPlusVK40 = "M50S++ VK40"
|
||||
M50SPlusPlusVK50 = "M50S++ VK50"
|
||||
M50SPlusPlusVK60 = "M50S++ VK60"
|
||||
M50SPlusPlusVL20 = "M50S++ VL20"
|
||||
M50SPlusPlusVL30 = "M50S++ VL30"
|
||||
M50SPlusPlusVL40 = "M50S++ VL40"
|
||||
M50SPlusPlusVL50 = "M50S++ VL50"
|
||||
M50SPlusPlusVL60 = "M50S++ VL60"
|
||||
M50SPlusVH30 = "M50S+ VH30"
|
||||
M50SPlusVH40 = "M50S+ VH40"
|
||||
M50SPlusVJ30 = "M50S+ VJ30"
|
||||
M50SPlusVJ40 = "M50S+ VJ40"
|
||||
M50SPlusVJ60 = "M50S+ VJ60"
|
||||
M50SPlusVK10 = "M50S+ VK10"
|
||||
M50SPlusVK20 = "M50S+ VK20"
|
||||
M50SPlusVK30 = "M50S+ VK30"
|
||||
M50SPlusVL10 = "M50S+ VL10"
|
||||
M50SPlusVL20 = "M50S+ VL20"
|
||||
M50SPlusVL30 = "M50S+ VL30"
|
||||
M50SVH10 = "M50S VH10"
|
||||
M50SVH20 = "M50S VH20"
|
||||
M50SVH30 = "M50S VH30"
|
||||
M50SVH40 = "M50S VH40"
|
||||
M50SVH50 = "M50S VH50"
|
||||
M50SVJ10 = "M50S VJ10"
|
||||
M50SVJ20 = "M50S VJ20"
|
||||
M50SVJ30 = "M50S VJ30"
|
||||
M50SVJ40 = "M50S VJ40"
|
||||
M50SVJ50 = "M50S VJ50"
|
||||
M50SVK10 = "M50S VK10"
|
||||
M50SVK20 = "M50S VK20"
|
||||
M50SVK30 = "M50S VK30"
|
||||
M50SVK50 = "M50S VK50"
|
||||
M50SVK60 = "M50S VK60"
|
||||
M50SVK70 = "M50S VK70"
|
||||
M50SVK80 = "M50S VK80"
|
||||
M50SVL20 = "M50S VL20"
|
||||
M50SVL30 = "M50S VL30"
|
||||
M50VE30 = "M50 VE30"
|
||||
M50VG30 = "M50 VG30"
|
||||
M50VH10 = "M50 VH10"
|
||||
@@ -235,49 +294,143 @@ class WhatsminerModels(MinerModelType):
|
||||
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"
|
||||
M50VJ40 = "M50 VJ40"
|
||||
M50VJ60 = "M50 VJ60"
|
||||
M50VK40 = "M50 VK40"
|
||||
M50VK50 = "M50 VK50"
|
||||
M52SPlusPlusVL10 = "M52S++ VL10"
|
||||
M52SVK30 = "M52S VK30"
|
||||
M53HVH10 = "M53H VH10"
|
||||
M53SPlusPlusVK10 = "M53S++ VK10"
|
||||
M56VH30 = "M56 VH30"
|
||||
M56SVH30 = "M56S VH30"
|
||||
M53SPlusPlusVK20 = "M53S++ VK20"
|
||||
M53SPlusPlusVK30 = "M53S++ VK30"
|
||||
M53SPlusPlusVK50 = "M53S++ VK50"
|
||||
M53SPlusPlusVL10 = "M53S++ VL10"
|
||||
M53SPlusPlusVL30 = "M53S++ VL30"
|
||||
M53SPlusVJ30 = "M53S+ VJ30"
|
||||
M53SPlusVJ40 = "M53S+ VJ40"
|
||||
M53SPlusVJ50 = "M53S+ VJ50"
|
||||
M53SPlusVK30 = "M53S+ VK30"
|
||||
M53SVH20 = "M53S VH20"
|
||||
M53SVH30 = "M53S VH30"
|
||||
M53SVJ30 = "M53S VJ30"
|
||||
M53SVJ40 = "M53S VJ40"
|
||||
M53SVK30 = "M53S VK30"
|
||||
M53VH30 = "M53 VH30"
|
||||
M53VH40 = "M53 VH40"
|
||||
M53VH50 = "M53 VH50"
|
||||
M53VK30 = "M53 VK30"
|
||||
M53VK60 = "M53 VK60"
|
||||
M54SPlusPlusVK30 = "M54S++ VK30"
|
||||
M54SPlusPlusVL30 = "M54S++ VL30"
|
||||
M54SPlusPlusVL40 = "M54S++ VL40"
|
||||
M56SPlusPlusVK10 = "M56S++ VK10"
|
||||
M56SPlusPlusVK30 = "M56S++ VK30"
|
||||
M56SPlusPlusVK40 = "M56S++ VK40"
|
||||
M56SPlusPlusVK50 = "M56S++ VK50"
|
||||
M56SPlusVJ30 = "M56S+ VJ30"
|
||||
M56SPlusVK30 = "M56S+ VK30"
|
||||
M56SPlusVK40 = "M56S+ VK40"
|
||||
M56SPlusVK50 = "M56S+ VK50"
|
||||
M56SVH30 = "M56S VH30"
|
||||
M56SVJ30 = "M56S VJ30"
|
||||
M56SVJ40 = "M56S VJ40"
|
||||
M56VH30 = "M56 VH30"
|
||||
M59VH30 = "M59 VH30"
|
||||
M60VK10 = "M60 VK10"
|
||||
M60VK20 = "M60 VK20"
|
||||
M60VK30 = "M60 VK30"
|
||||
M60VK40 = "M60 VK40"
|
||||
M60SPlusPlusVL30 = "M60S++ VL30"
|
||||
M60SPlusPlusVL40 = "M60S++ VL40"
|
||||
M60SPlusVK30 = "M60S+ VK30"
|
||||
M60SPlusVK40 = "M60S+ VK40"
|
||||
M60SPlusVK50 = "M60S+ VK50"
|
||||
M60SPlusVK60 = "M60S+ VK60"
|
||||
M60SPlusVK70 = "M60S+ VK70"
|
||||
M60SPlusVL10 = "M60S+ VL10"
|
||||
M60SPlusVL30 = "M60S+ VL30"
|
||||
M60SPlusVL40 = "M60S+ VL40"
|
||||
M60SPlusVL50 = "M60S+ VL50"
|
||||
M60SPlusVL60 = "M60S+ VL60"
|
||||
M60SVK10 = "M60S VK10"
|
||||
M60SVK20 = "M60S VK20"
|
||||
M60SVK30 = "M60S VK30"
|
||||
M60SVK40 = "M60S VK40"
|
||||
M63VK10 = "M63 VK10"
|
||||
M63VK20 = "M63 VK20"
|
||||
M63VK30 = "M63 VK30"
|
||||
M60SVL10 = "M60S VL10"
|
||||
M60SVL20 = "M60S VL20"
|
||||
M60SVL30 = "M60S VL30"
|
||||
M60SVL40 = "M60S VL40"
|
||||
M60SVL50 = "M60S VL50"
|
||||
M60SVL60 = "M60S VL60"
|
||||
M60SVL70 = "M60S VL70"
|
||||
M60VK10 = "M60 VK10"
|
||||
M60VK20 = "M60 VK20"
|
||||
M60VK30 = "M60 VK30"
|
||||
M60VK40 = "M60 VK40"
|
||||
M60VK6A = "M60 VK6A"
|
||||
M60VL10 = "M60 VL10"
|
||||
M60VL20 = "M60 VL20"
|
||||
M60VL30 = "M60 VL30"
|
||||
M60VL40 = "M60 VL40"
|
||||
M60VL50 = "M60 VL50"
|
||||
M61SPlusVL30 = "M61S+ VL30"
|
||||
M61SVL10 = "M61S VL10"
|
||||
M61SVL20 = "M61S VL20"
|
||||
M61SVL30 = "M61S VL30"
|
||||
M61VK10 = "M61 VK10"
|
||||
M61VK20 = "M61 VK20"
|
||||
M61VK30 = "M61 VK30"
|
||||
M61VK40 = "M61 VK40"
|
||||
M61VL10 = "M61 VL10"
|
||||
M61VL30 = "M61 VL30"
|
||||
M61VL40 = "M61 VL40"
|
||||
M61VL50 = "M61 VL50"
|
||||
M61VL60 = "M61 VL60"
|
||||
M62SPlusVK30 = "M62S+ VK30"
|
||||
M63SPlusPlusVL20 = "M63S++ VL20"
|
||||
M63SPlusVK30 = "M63S+ VK30"
|
||||
M63SPlusVL10 = "M63S+ VL10"
|
||||
M63SPlusVL20 = "M63S+ VL20"
|
||||
M63SPlusVL30 = "M63S+ VL30"
|
||||
M63SPlusVL50 = "M63S+ VL50"
|
||||
M63SVK10 = "M63S VK10"
|
||||
M63SVK20 = "M63S VK20"
|
||||
M63SVK30 = "M63S VK30"
|
||||
M66VK20 = "M66 VK20"
|
||||
M66VK30 = "M66 VK30"
|
||||
M63SVK60 = "M63S VK60"
|
||||
M63SVL10 = "M63S VL10"
|
||||
M63SVL50 = "M63S VL50"
|
||||
M63SVL60 = "M63S VL60"
|
||||
M63VK10 = "M63 VK10"
|
||||
M63VK20 = "M63 VK20"
|
||||
M63VK30 = "M63 VK30"
|
||||
M63VL10 = "M63 VL10"
|
||||
M63VL30 = "M63 VL30"
|
||||
M64SVL30 = "M64S VL30"
|
||||
M64VL30 = "M64 VL30"
|
||||
M64VL40 = "M64 VL40"
|
||||
M65SPlusVK30 = "M65S+ VK30"
|
||||
M65SVK20 = "M65S VK20"
|
||||
M65SVL60 = "M65S VL60"
|
||||
M66SPlusPlusVL20 = "M66S++ VL20"
|
||||
M66SPlusVK30 = "M66S+ VK30"
|
||||
M66SPlusVL10 = "M66S+ VL10"
|
||||
M66SPlusVL20 = "M66S+ VL20"
|
||||
M66SPlusVL30 = "M66S+ VL30"
|
||||
M66SPlusVL40 = "M66S+ VL40"
|
||||
M66SPlusVL60 = "M66S+ VL60"
|
||||
M66SVK20 = "M66S VK20"
|
||||
M66SVK30 = "M66S VK30"
|
||||
M66SVK40 = "M66S VK40"
|
||||
M66SVK50 = "M66S VK50"
|
||||
M66SVK60 = "M66S VK60"
|
||||
M66SVL10 = "M66S VL10"
|
||||
M66SVL20 = "M66S VL20"
|
||||
M66SVL30 = "M66S VL30"
|
||||
M66SVL40 = "M66S VL40"
|
||||
M66SVL50 = "M66S VL50"
|
||||
M66VK20 = "M66 VK20"
|
||||
M66VK30 = "M66 VK30"
|
||||
M66VL20 = "M66 VL20"
|
||||
M66VL30 = "M66 VL30"
|
||||
M67SVK30 = "M67S VK30"
|
||||
M70VM30 = "M70 VM30"
|
||||
|
||||
def __str__(self):
|
||||
return self.value
|
||||
@@ -295,8 +448,11 @@ class AvalonminerModels(MinerModelType):
|
||||
Avalon1047 = "Avalon 1047"
|
||||
Avalon1066 = "Avalon 1066"
|
||||
Avalon1166Pro = "Avalon 1166 Pro"
|
||||
Avalon1126Pro = "Avalon 1126 Pro"
|
||||
Avalon1246 = "Avalon 1246"
|
||||
Avalon1566 = "Avalon 1566"
|
||||
AvalonNano3 = "Avalon Nano 3"
|
||||
AvalonNano3s = "Avalon Nano 3s"
|
||||
|
||||
def __str__(self):
|
||||
return self.value
|
||||
@@ -327,6 +483,9 @@ class GoldshellModels(MinerModelType):
|
||||
class ePICModels(MinerModelType):
|
||||
BM520i = "BlockMiner 520i"
|
||||
BM720i = "BlockMiner 720i"
|
||||
eLITE1 = "BlockMiner eLITE 1.0"
|
||||
S19jProDual = "S19j Pro Dual"
|
||||
S19kProDual = "S19k Pro Dual"
|
||||
|
||||
def __str__(self):
|
||||
return self.value
|
||||
@@ -355,6 +514,14 @@ class BitAxeModels(MinerModelType):
|
||||
return self.value
|
||||
|
||||
|
||||
class LuckyMinerModels(MinerModelType):
|
||||
LV07 = "LV07"
|
||||
LV08 = "LV08"
|
||||
|
||||
def __str__(self):
|
||||
return self.value
|
||||
|
||||
|
||||
class IceRiverModels(MinerModelType):
|
||||
KS0 = "KS0"
|
||||
KS1 = "KS1"
|
||||
@@ -377,6 +544,22 @@ class HammerModels(MinerModelType):
|
||||
return self.value
|
||||
|
||||
|
||||
class VolcMinerModels(MinerModelType):
|
||||
D1 = "D1"
|
||||
|
||||
def __str__(self):
|
||||
return self.value
|
||||
|
||||
|
||||
class BraiinsModels(MinerModelType):
|
||||
BMM100 = "BMM100"
|
||||
BMM101 = "BMM101"
|
||||
|
||||
|
||||
class ElphapexModels(MinerModelType):
|
||||
DG1Plus = "DG1+"
|
||||
|
||||
|
||||
class MinerModel:
|
||||
ANTMINER = AntminerModels
|
||||
WHATSMINER = WhatsminerModels
|
||||
@@ -386,5 +569,9 @@ class MinerModel:
|
||||
AURADINE = AuradineModels
|
||||
EPIC = ePICModels
|
||||
BITAXE = BitAxeModels
|
||||
LUCKYMINER = LuckyMinerModels
|
||||
ICERIVER = IceRiverModels
|
||||
HAMMER = HammerModels
|
||||
VOLCMINER = VolcMinerModels
|
||||
ELPHAPEX = ElphapexModels
|
||||
BRAIINS = BraiinsModels
|
||||
|
||||
@@ -21,4 +21,5 @@ from .epic import *
|
||||
from .hiveon import *
|
||||
from .luxos import *
|
||||
from .marathon import *
|
||||
from .mskminer import *
|
||||
from .vnish import *
|
||||
|
||||
@@ -26,6 +26,7 @@ from pyasic.miners.device.models import (
|
||||
S19j,
|
||||
S19jNoPIC,
|
||||
S19jPro,
|
||||
S19jXP,
|
||||
S19KPro,
|
||||
S19Plus,
|
||||
S19Pro,
|
||||
@@ -97,3 +98,7 @@ class BMMinerS19ProPlusHydro(AntminerModern, S19ProPlusHydro):
|
||||
|
||||
class BMMinerS19KPro(AntminerModern, S19KPro):
|
||||
pass
|
||||
|
||||
|
||||
class BMMinerS19jXP(AntminerModern, S19jXP):
|
||||
pass
|
||||
|
||||
@@ -23,6 +23,7 @@ from .S19 import (
|
||||
BMMinerS19j,
|
||||
BMMinerS19jNoPIC,
|
||||
BMMinerS19jPro,
|
||||
BMMinerS19jXP,
|
||||
BMMinerS19KPro,
|
||||
BMMinerS19L,
|
||||
BMMinerS19Plus,
|
||||
|
||||
@@ -15,12 +15,24 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.backends import AntminerModern
|
||||
from pyasic.miners.device.models import S21, S21Pro
|
||||
from pyasic.miners.device.models import S21, S21Hydro, S21Plus, S21PlusHydro, S21Pro
|
||||
|
||||
|
||||
class BMMinerS21(AntminerModern, S21):
|
||||
pass
|
||||
|
||||
|
||||
class BMMinerS21Plus(AntminerModern, S21Plus):
|
||||
pass
|
||||
|
||||
|
||||
class BMMinerS21PlusHydro(AntminerModern, S21PlusHydro):
|
||||
pass
|
||||
|
||||
|
||||
class BMMinerS21Pro(AntminerModern, S21Pro):
|
||||
pass
|
||||
|
||||
|
||||
class BMMinerS21Hydro(AntminerModern, S21Hydro):
|
||||
pass
|
||||
|
||||
@@ -13,5 +13,11 @@
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
from .S21 import BMMinerS21, BMMinerS21Pro
|
||||
from .S21 import (
|
||||
BMMinerS21,
|
||||
BMMinerS21Hydro,
|
||||
BMMinerS21Plus,
|
||||
BMMinerS21PlusHydro,
|
||||
BMMinerS21Pro,
|
||||
)
|
||||
from .T21 import BMMinerT21
|
||||
|
||||
@@ -14,8 +14,12 @@
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
from pyasic.miners.backends import AntminerModern
|
||||
from pyasic.miners.device.models import KS5
|
||||
from pyasic.miners.device.models.antminer import KS5, KS5Pro
|
||||
|
||||
|
||||
class BMMinerKS5(AntminerModern, KS5):
|
||||
supports_shutdown = False
|
||||
|
||||
|
||||
class BMMinerKS5Pro(AntminerModern, KS5Pro):
|
||||
supports_shutdown = False
|
||||
|
||||
@@ -13,4 +13,4 @@
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
from .KS5 import BMMinerKS5
|
||||
from .KS5 import BMMinerKS5, BMMinerKS5Pro
|
||||
|
||||
22
pyasic/miners/antminer/bmminer/X9/L9.py
Normal file
22
pyasic/miners/antminer/bmminer/X9/L9.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 L9
|
||||
|
||||
|
||||
class BMMinerL9(AntminerModern, L9):
|
||||
pass
|
||||
@@ -16,5 +16,6 @@
|
||||
|
||||
from .D9 import BMMinerD9
|
||||
from .E9 import BMMinerE9Pro
|
||||
from .L9 import BMMinerL9
|
||||
from .S9 import BMMinerS9, BMMinerS9i, BMMinerS9j
|
||||
from .T9 import BMMinerT9
|
||||
|
||||
@@ -15,8 +15,12 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.backends import BOSer
|
||||
from pyasic.miners.device.models import S21
|
||||
from pyasic.miners.device.models import S21, S21Pro
|
||||
|
||||
|
||||
class BOSMinerS21(BOSer, S21):
|
||||
pass
|
||||
|
||||
|
||||
class BOSMinerS21Pro(BOSer, S21Pro):
|
||||
pass
|
||||
|
||||
@@ -14,5 +14,5 @@
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from .S21 import BOSMinerS21
|
||||
from .S21 import BOSMinerS21, BOSMinerS21Pro
|
||||
from .T21 import BOSMinerT21
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.device.models import MinerModel
|
||||
from pyasic.miners.backends import ePIC
|
||||
from pyasic.miners.device.models import (
|
||||
S19,
|
||||
@@ -52,3 +53,15 @@ class ePICS19kPro(ePIC, S19kPro):
|
||||
|
||||
class ePICS19XP(ePIC, S19XP):
|
||||
pass
|
||||
|
||||
|
||||
class ePICS19jProDual(ePIC, S19jPro):
|
||||
raw_model = MinerModel.EPIC.S19jProDual
|
||||
expected_fans = S19jPro.expected_fans * 2
|
||||
expected_hashboards = S19jPro.expected_hashboards * 2
|
||||
|
||||
|
||||
class ePICS19kProDual(ePIC, S19kPro):
|
||||
raw_model = MinerModel.EPIC.S19kProDual
|
||||
expected_fans = S19kPro.expected_fans * 2
|
||||
expected_hashboards = S19kPro.expected_hashboards * 2
|
||||
|
||||
@@ -18,8 +18,10 @@ from .S19 import (
|
||||
ePICS19,
|
||||
ePICS19j,
|
||||
ePICS19jPro,
|
||||
ePICS19jProDual,
|
||||
ePICS19jProPlus,
|
||||
ePICS19kPro,
|
||||
ePICS19kProDual,
|
||||
ePICS19Pro,
|
||||
ePICS19XP,
|
||||
)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.backends import Hiveon
|
||||
from pyasic.miners.backends import HiveonModern
|
||||
from pyasic.miners.device.models import (
|
||||
S19,
|
||||
S19L,
|
||||
@@ -27,6 +27,7 @@ from pyasic.miners.device.models import (
|
||||
S19jNoPIC,
|
||||
S19jPro,
|
||||
S19KPro,
|
||||
S19NoPIC,
|
||||
S19Plus,
|
||||
S19Pro,
|
||||
S19ProHydro,
|
||||
@@ -35,65 +36,69 @@ from pyasic.miners.device.models import (
|
||||
)
|
||||
|
||||
|
||||
class HiveonS19(Hiveon, S19):
|
||||
class HiveonS19(HiveonModern, S19):
|
||||
pass
|
||||
|
||||
|
||||
class HiveonS19Plus(Hiveon, S19Plus):
|
||||
class HiveonS19NoPIC(HiveonModern, S19NoPIC):
|
||||
pass
|
||||
|
||||
|
||||
class HiveonS19i(Hiveon, S19i):
|
||||
class HiveonS19Plus(HiveonModern, S19Plus):
|
||||
pass
|
||||
|
||||
|
||||
class HiveonS19Pro(Hiveon, S19Pro):
|
||||
class HiveonS19i(HiveonModern, S19i):
|
||||
pass
|
||||
|
||||
|
||||
class HiveonS19ProPlus(Hiveon, S19ProPlus):
|
||||
class HiveonS19Pro(HiveonModern, S19Pro):
|
||||
pass
|
||||
|
||||
|
||||
class HiveonS19XP(Hiveon, S19XP):
|
||||
class HiveonS19ProPlus(HiveonModern, S19ProPlus):
|
||||
pass
|
||||
|
||||
|
||||
class HiveonS19a(Hiveon, S19a):
|
||||
class HiveonS19XP(HiveonModern, S19XP):
|
||||
pass
|
||||
|
||||
|
||||
class HiveonS19aPro(Hiveon, S19aPro):
|
||||
class HiveonS19a(HiveonModern, S19a):
|
||||
pass
|
||||
|
||||
|
||||
class HiveonS19j(Hiveon, S19j):
|
||||
class HiveonS19aPro(HiveonModern, S19aPro):
|
||||
pass
|
||||
|
||||
|
||||
class HiveonS19jNoPIC(Hiveon, S19jNoPIC):
|
||||
class HiveonS19j(HiveonModern, S19j):
|
||||
pass
|
||||
|
||||
|
||||
class HiveonS19jPro(Hiveon, S19jPro):
|
||||
class HiveonS19jNoPIC(HiveonModern, S19jNoPIC):
|
||||
pass
|
||||
|
||||
|
||||
class HiveonS19L(Hiveon, S19L):
|
||||
class HiveonS19jPro(HiveonModern, S19jPro):
|
||||
pass
|
||||
|
||||
|
||||
class HiveonS19ProHydro(Hiveon, S19ProHydro):
|
||||
class HiveonS19L(HiveonModern, S19L):
|
||||
pass
|
||||
|
||||
|
||||
class HiveonS19Hydro(Hiveon, S19Hydro):
|
||||
class HiveonS19ProHydro(HiveonModern, S19ProHydro):
|
||||
pass
|
||||
|
||||
|
||||
class HiveonS19ProPlusHydro(Hiveon, S19ProPlusHydro):
|
||||
class HiveonS19Hydro(HiveonModern, S19Hydro):
|
||||
pass
|
||||
|
||||
|
||||
class HiveonS19KPro(Hiveon, S19KPro):
|
||||
class HiveonS19ProPlusHydro(HiveonModern, S19ProPlusHydro):
|
||||
pass
|
||||
|
||||
|
||||
class HiveonS19kPro(HiveonModern, S19KPro):
|
||||
pass
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.backends import Hiveon
|
||||
from pyasic.miners.backends import HiveonModern
|
||||
from pyasic.miners.device.models import T19
|
||||
|
||||
|
||||
class HiveonT19(Hiveon, T19):
|
||||
class HiveonT19(HiveonModern, T19):
|
||||
pass
|
||||
|
||||
@@ -23,8 +23,9 @@ from .S19 import (
|
||||
HiveonS19j,
|
||||
HiveonS19jNoPIC,
|
||||
HiveonS19jPro,
|
||||
HiveonS19KPro,
|
||||
HiveonS19kPro,
|
||||
HiveonS19L,
|
||||
HiveonS19NoPIC,
|
||||
HiveonS19Plus,
|
||||
HiveonS19Pro,
|
||||
HiveonS19ProHydro,
|
||||
|
||||
@@ -16,12 +16,10 @@
|
||||
|
||||
from typing import List, Optional
|
||||
|
||||
import asyncssh
|
||||
|
||||
from pyasic.data import HashBoard
|
||||
from pyasic.device.algorithm import AlgoHashRate, HashUnit
|
||||
from pyasic.errors import APIError
|
||||
from pyasic.miners.backends import Hiveon
|
||||
from pyasic.miners.backends import HiveonOld
|
||||
from pyasic.miners.data import DataFunction, DataLocations, DataOptions, RPCAPICommand
|
||||
from pyasic.miners.device.models import T9
|
||||
|
||||
@@ -71,7 +69,7 @@ HIVEON_T9_DATA_LOC = DataLocations(
|
||||
)
|
||||
|
||||
|
||||
class HiveonT9(Hiveon, T9):
|
||||
class HiveonT9(HiveonOld, T9):
|
||||
data_locations = HIVEON_T9_DATA_LOC
|
||||
|
||||
##################################################
|
||||
|
||||
22
pyasic/miners/antminer/luxos/X21/T21.py
Normal file
22
pyasic/miners/antminer/luxos/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 LUXMiner
|
||||
from pyasic.miners.device.models import S21, T21
|
||||
|
||||
|
||||
class LUXMinerT21(LUXMiner, T21):
|
||||
pass
|
||||
@@ -15,3 +15,4 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from .S21 import LUXMinerS21
|
||||
from .T21 import LUXMinerT21
|
||||
|
||||
24
pyasic/miners/antminer/mskminer/X19/S19.py
Normal file
24
pyasic/miners/antminer/mskminer/X19/S19.py
Normal file
@@ -0,0 +1,24 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Copyright 2022 Upstream Data Inc -
|
||||
# -
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||
# you may not use this file except in compliance with the License. -
|
||||
# You may obtain a copy of the License at -
|
||||
# -
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||
# -
|
||||
# Unless required by applicable law or agreed to in writing, software -
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.backends.mskminer import MSKMiner
|
||||
from pyasic.miners.device.models import (
|
||||
S19NoPIC,
|
||||
)
|
||||
|
||||
|
||||
class MSKMinerS19NoPIC(MSKMiner, S19NoPIC):
|
||||
pass
|
||||
17
pyasic/miners/antminer/mskminer/X19/__init__.py
Normal file
17
pyasic/miners/antminer/mskminer/X19/__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 .S19 import MSKMinerS19NoPIC
|
||||
17
pyasic/miners/antminer/mskminer/__init__.py
Normal file
17
pyasic/miners/antminer/mskminer/__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 .X19 import *
|
||||
@@ -20,8 +20,10 @@ from pyasic.miners.device.models import (
|
||||
S19XP,
|
||||
S19a,
|
||||
S19aPro,
|
||||
S19i,
|
||||
S19j,
|
||||
S19jPro,
|
||||
S19kPro,
|
||||
S19NoPIC,
|
||||
S19Pro,
|
||||
S19ProHydro,
|
||||
@@ -52,6 +54,10 @@ class VNishS19aPro(VNish, S19aPro):
|
||||
pass
|
||||
|
||||
|
||||
class VNishS19i(VNish, S19i):
|
||||
pass
|
||||
|
||||
|
||||
class VNishS19j(VNish, S19j):
|
||||
pass
|
||||
|
||||
@@ -62,3 +68,7 @@ class VNishS19jPro(VNish, S19jPro):
|
||||
|
||||
class VNishS19ProHydro(VNish, S19ProHydro):
|
||||
pass
|
||||
|
||||
|
||||
class VNishS19kPro(VNish, S19kPro):
|
||||
pass
|
||||
|
||||
@@ -18,8 +18,10 @@ from .S19 import (
|
||||
VNishS19,
|
||||
VNishS19a,
|
||||
VNishS19aPro,
|
||||
VNishS19i,
|
||||
VNishS19j,
|
||||
VNishS19jPro,
|
||||
VNishS19kPro,
|
||||
VNishS19NoPIC,
|
||||
VNishS19Pro,
|
||||
VNishS19ProHydro,
|
||||
|
||||
22
pyasic/miners/antminer/vnish/X21/T21.py
Normal file
22
pyasic/miners/antminer/vnish/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 VNish
|
||||
from pyasic.miners.device.models import T21
|
||||
|
||||
|
||||
class VNishT21(VNish, T21):
|
||||
pass
|
||||
@@ -15,3 +15,4 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from .S21 import VNishS21
|
||||
from .T21 import VNishT21
|
||||
|
||||
22
pyasic/miners/avalonminer/cgminer/A11X/A1126.py
Normal file
22
pyasic/miners/avalonminer/cgminer/A11X/A1126.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 AvalonMiner
|
||||
from pyasic.miners.device.models import Avalon1126Pro
|
||||
|
||||
|
||||
class CGMinerAvalon1126Pro(AvalonMiner, Avalon1126Pro):
|
||||
pass
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user