Compare commits

..

78 Commits

Author SHA1 Message Date
Upstream Data
bd9fd81b17 version: bump version number 2025-01-20 08:54:14 -07:00
Upstream Data
33803e89e2 feature: add support for Vnish S19i
Fixes: #279
2025-01-20 08:21:24 -07:00
Upstream Data
10a44b9877 bug: fix invlaid import in luxminer.py 2025-01-20 08:21:12 -07:00
pre-commit-ci[bot]
bbd883f639 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2025-01-19 08:18:27 -07:00
Wilfred Allyn
8e2ad478e9 refactor: simplify get_wattage_limit for luxos 2025-01-19 08:18:27 -07:00
Wilfred Allyn
957981a9c6 feature: get active preset from luxos 2025-01-19 08:18:27 -07:00
Wilfred Allyn
13a67dfdd1 feature: add _get_wattage_limit for luxos 2025-01-19 08:18:27 -07:00
Wilfred Allyn
e86f2b62c5 docs: fix issues for docs warnings 2025-01-18 08:03:11 -07:00
Wilfred Allyn
88b4d2cac3 docs: add instructions for building docs locally 2025-01-17 09:31:36 -07:00
Upstream Data
5842ef3d97 version: bump version number 2025-01-16 11:02:57 -07:00
Upstream Data
339a689267 bug: fix possible None value from miner type when parsing hammer miners 2025-01-16 11:02:39 -07:00
Brett Rowan
a0764806c4 version: bump version number 2025-01-15 22:23:41 -07:00
Brett Rowan
6eec0f6d44 bug: fix a few bad type hints in config models 2025-01-15 22:22:53 -07:00
Upstream Data
0854f7833c docs: update supported miners list and generation tool to use unique 2025-01-15 10:56:25 -07:00
Upstream Data
b6edc85679 feature: add support for some weird antminer submodel namings for S21 2025-01-15 09:47:14 -07:00
Upstream Data
ff11ebc304 bug: fix antminer KS5 using iceriver backend 2025-01-15 08:25:02 -07:00
Wilfred Allyn
f3681f1aa5 feature: add support for Vnish S19j Pro A 2025-01-15 07:36:29 -07:00
Wilfred Allyn
1a7411edb3 feature: add support for Vnish T21 and update docs 2025-01-15 07:34:47 -07:00
Upstream Data
f2a4a5d524 version: bump version number 2025-01-08 11:24:08 -07:00
Wilfred Allyn
624a3c5919 feature: revise atmset input params 2025-01-08 11:22:46 -07:00
Wilfred Allyn
2ec8054d24 feature: check if atm enabled before settting power 2025-01-08 11:22:46 -07:00
Wilfred Allyn
d148ccfe5f feature: add atm, atmset commands to luxos rpc 2025-01-08 11:22:46 -07:00
Wilfred Allyn
b6c29d16f9 feature: add set_power_limit for luxos 2025-01-08 11:22:46 -07:00
Wilfred Allyn
53a3bb13af feature: remove deprecated board_n param from profileset 2025-01-08 11:22:46 -07:00
John-Paul Compagnone
16e74e659c add expected_hashrate for bitaxe devices 2025-01-07 09:59:51 -07:00
Upstream Data
730caca23f version: bump version number 2025-01-07 08:57:09 -07:00
Upstream Data
dc126b2953 bug: fix a bug with config on S9 sometimes not having quota set. 2025-01-07 08:56:39 -07:00
Brett Rowan
51abdf0b2d version: bump version number 2025-01-04 11:50:08 -07:00
Brett Rowan
b367b2d293 bug: fix an issue with parsing disabled fan mode on BOS+ 2025-01-04 11:49:49 -07:00
Upstream Data
96f52a4b35 version: bump version number 2025-01-02 16:04:35 -07:00
John-Paul Compagnone
5236e02af2 fix hammer test, enforce default hr unit 2025-01-02 16:04:23 -07:00
Upstream Data
9ee52f77f9 version: bump version number 2025-01-02 15:21:09 -07:00
Upstream Data
26389f8ba0 docs: fix docs 2025-01-02 14:59:36 -07:00
Upstream Data
8a0605bd3b docs: update docs with new wm models 2025-01-02 14:59:36 -07:00
Upstream Data
fe9894919e feature: add support for a lot of whatsminers 2025-01-02 14:59:36 -07:00
Upstream Data
bb399fe362 bug: fix a bug with very new versions of btminer hashboards 2025-01-02 12:30:00 -07:00
Brett Rowan
7ca7fe3e7e version: bump version number 2025-01-01 22:40:20 -07:00
JP Compagnone
748279c25d fix: change sticker hashrate to GH for Hammer and VolcMiner (#264)
* change sticker hashrate to GH

* clean up hashrate for Hammer/Volcminer

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-01-01 22:38:57 -07:00
Brett Rowan
23890fa10a version: bump version number 2024-12-31 13:26:51 -07:00
Brett Rowan
8ab7df516e docs: add checkboxes to indicate support for specific features, and some more updates 2024-12-31 13:26:17 -07:00
Brett Rowan
f7a0188104 feature: add support for M50S++VL30, update docs, fix hammer bug, and handle errors with data on unknown types of miners 2024-12-31 13:05:10 -07:00
wilfredallyn
66a8932ea3 feature: add mining presets for luxos (#262)
* feature: add mining mode preset for luxos

* bug: fix type hint
2024-12-31 12:48:13 -07:00
JP Compagnone
56536fd258 feat: add VolcMiner D1 (#263) 2024-12-31 10:02:48 -07:00
John-Paul Compagnone
1b4e6d4da0 Remove pass 2024-12-26 09:12:45 -07:00
John-Paul Compagnone
2019bdaff2 add sticker_hashrate for D10 2024-12-26 09:12:45 -07:00
pre-commit-ci[bot]
b903cc6e5f [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2024-12-26 09:12:45 -07:00
JP
c1a01b5f7b more D10 updates 2024-12-26 09:12:45 -07:00
JP
3427a8d15a fix D10 board temp 2024-12-26 09:12:45 -07:00
JP
25c08b9bc0 fix to only change the dual version 2024-12-26 09:12:45 -07:00
John-Paul Compagnone
01263da52b add dual rig support to ePIC 2024-12-26 09:12:45 -07:00
Upstream Data
5081319a2f version: bump version number 2024-12-24 08:27:28 -07:00
Upstream Data
ec5be00065 feature: add chip count for S19jXP 2024-12-24 08:27:13 -07:00
Upstream Data
891e28bfe6 version: bump version number 2024-12-24 08:10:26 -07:00
Upstream Data
8e15b00e70 feature: add support for antminer S19j XP and update docs 2024-12-24 08:10:08 -07:00
Upstream Data
df71ab3282 version: bump version number 2024-12-24 08:03:36 -07:00
Upstream Data
1508f7873a bug: fix mining mde being set to an invalid miner_mode in antminer stock and hive 2024-12-24 08:03:19 -07:00
Upstream Data
77058ac692 version: bump version number 2024-12-23 09:26:19 -07:00
Upstream Data
1a4491ca56 feature: add partial support for braiins mini miners 2024-12-23 09:25:28 -07:00
Brett Rowan
d018724aa4 version: bump version number 2024-12-20 17:07:33 -07:00
Brett Rowan
5b97bed704 bug: fix hashrate sum start value in data 2024-12-20 17:07:11 -07:00
Brett Rowan
55786b154d version: bump version number 2024-12-20 10:16:19 -07:00
Brett Rowan
6ab9681dec feature: add auto unit to hashrates and improve model dump for hashrates 2024-12-20 10:16:01 -07:00
Brett Rowan
89641c6316 version: bump version number 2024-12-20 09:26:16 -07:00
Brett Rowan
136ff6a688 feature: add generic hashrate type for doing sums 2024-12-20 09:25:52 -07:00
Brett Rowan
d918d93f4a version: bump version number 2024-12-20 09:21:32 -07:00
Brett Rowan
8046c532a6 bug: fix some issues with adding hashrate types 2024-12-20 09:21:06 -07:00
Upstream Data
92820a362d version: bump version number 2024-12-17 08:15:37 -07:00
aquariuslt
9fd90031a9 fix: update data.env_temp type to float 2024-12-17 08:14:59 -07:00
Brett Rowan
2f2223a112 version: bump version number 2024-12-16 20:06:33 -07:00
Wilfred Allyn
50e6cf9dfd feature: add supports_autotuning to vnish 2024-12-16 07:43:15 -07:00
Wilfred Allyn
1b5e3093e6 feature: set power to highest preset <= wattage 2024-12-16 07:43:15 -07:00
Wilfred Allyn
9e3578b4a2 feature: check vnish presets when set power 2024-12-16 07:43:15 -07:00
Wilfred Allyn
a3087e1a96 set vnish power limit 2024-12-16 07:43:15 -07:00
Brett Rowan
4b16ea2ca2 ci: update publish action 2024-12-10 13:55:30 -07:00
Upstream Data
5dd361c4ef version: bump version number 2024-12-10 13:05:20 -07:00
Upstream Data
098112742c bug: fix vnish config parsing in some overclocking cases 2024-12-10 13:04:58 -07:00
Upstream Data
cd31e0743e docs: update docs 2024-12-10 13:03:07 -07:00
Upstream Data
1a7d0bf7cc feature: add support for vnish S19k pro 2024-12-10 13:02:49 -07:00
255 changed files with 11385 additions and 4410 deletions

View File

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

View File

@@ -1,7 +1,14 @@
ci:
skip:
- unittest
- poetry-lock
- pytest
repos:
- repo: https://github.com/python-poetry/poetry
rev: 2.0.1
hooks:
- id: poetry-check
- id: poetry-lock
- id: poetry-install
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:

View File

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

View File

@@ -55,6 +55,8 @@ def backend_str(backend: MinerTypes) -> str:
return "Stock Firmware IceRiver Miners"
case MinerTypes.HAMMER:
return "Stock Firmware Hammer Miners"
case MinerTypes.VOLCMINER:
return "Stock Firmware Volcminers"
def create_url_str(mtype: str):
@@ -69,11 +71,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 +89,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,17 +121,18 @@ 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):
@@ -138,9 +149,18 @@ async def create_directory_structure(directory, data):
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):

View File

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

View File

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

View File

@@ -2,86 +2,171 @@
## 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 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
## 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
## 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
- [ ] Setpoints
- [x] Presets
::: pyasic.miners.antminer.luxos.X21.S21.LUXMinerS21
handler: python
options:
show_root_heading: false
heading_level: 4
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

View File

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

View File

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

View File

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

View File

@@ -1,73 +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
## S9 (Stock)
::: pyasic.miners.antminer.bmminer.X9.S9.BMMinerS9
## E9Pro (Stock)
- [ ] Shutdowns
- [x] Power Modes
- [ ] Setpoints
- [ ] Presets
::: pyasic.miners.antminer.bmminer.X9.E9.BMMinerE9Pro
handler: python
options:
show_root_heading: false
heading_level: 4
## S9i (Stock)
::: pyasic.miners.antminer.bmminer.X9.S9.BMMinerS9i
handler: python
options:
show_root_heading: false
heading_level: 4
## S9j (Stock)
::: pyasic.miners.antminer.bmminer.X9.S9.BMMinerS9j
handler: python
options:
show_root_heading: false
heading_level: 4
## T9 (Stock)
::: pyasic.miners.antminer.bmminer.X9.T9.BMMinerT9
handler: python
options:
show_root_heading: false
heading_level: 4
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: 4
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: 0
## S9i (Stock)
- [ ] Shutdowns
- [ ] Power Modes
- [ ] Setpoints
- [ ] Presets
::: pyasic.miners.antminer.bmminer.X9.S9.BMMinerS9i
handler: python
options:
show_root_heading: false
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: 0
## T9 (Stock)
- [ ] Shutdowns
- [ ] Power Modes
- [ ] Setpoints
- [ ] Presets
::: pyasic.miners.antminer.bmminer.X9.T9.BMMinerT9
handler: python
options:
show_root_heading: false
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
::: 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
- [ ] Setpoints
- [x] Presets
::: pyasic.miners.antminer.luxos.X9.S9.LUXMinerS9
handler: python
options:
show_root_heading: false
heading_level: 4
heading_level: 0

View File

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

View File

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

View File

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

View File

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

View File

@@ -2,16 +2,28 @@
## 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: 4
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

View File

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

View File

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

View File

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

View File

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

View File

@@ -2,9 +2,15 @@
## nano Models
## 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

View File

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

View File

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

View File

@@ -2,16 +2,28 @@
## 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

View 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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>
@@ -90,12 +93,15 @@ 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>
<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-pro-stock">S21 Pro (Stock)</a></li>
<li><a href="../antminer/X21#t21-stock">T21 (Stock)</a></li>
@@ -109,28 +115,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>
@@ -160,63 +227,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>
@@ -229,45 +268,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>
@@ -276,6 +295,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>
@@ -290,54 +350,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>
@@ -496,6 +655,13 @@ details {
<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>
@@ -530,15 +696,18 @@ details {
<li><a href="../antminer/X19#s19j-vnish">S19j (VNish)</a></li>
<li><a href="../antminer/X19#s19j-pro-vnish">S19j Pro (VNish)</a></li>
<li><a href="../antminer/X19#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>
@@ -557,6 +726,7 @@ 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>
</ul>
</details>
<details>
@@ -717,4 +887,15 @@ details {
</ul>
</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>

View 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

View File

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

View 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

View File

@@ -26,6 +26,8 @@ markdown_extensions:
anchor_linenums: true
line_spans: __span
pygments_lang_class: true
- pymdownx.tasklist:
custom_checkbox: true
- pymdownx.inlinehilite
- pymdownx.snippets
- pymdownx.superfences
@@ -79,6 +81,7 @@ 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"
@@ -90,6 +93,7 @@ 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"
@@ -103,6 +107,7 @@ nav:
- 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"

618
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -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,7 @@ class MinerConfig(BaseModel):
**self.temperature.as_am_modern(),
}
def as_wm(self, user_suffix: str = None) -> dict:
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 +65,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 +74,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 +83,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 +92,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 +101,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 +109,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 +118,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 +126,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 +135,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,7 +143,7 @@ class MinerConfig(BaseModel):
**self.pools.as_mara(user_suffix=user_suffix),
}
def as_bitaxe(self, user_suffix: str = None) -> dict:
def as_bitaxe(self, user_suffix: str | None = None) -> dict:
return {
**self.fan_mode.as_bitaxe(),
**self.temperature.as_bitaxe(),
@@ -151,7 +151,7 @@ class MinerConfig(BaseModel):
**self.pools.as_bitaxe(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 +159,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(),
@@ -286,7 +286,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 +300,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

View File

@@ -308,6 +308,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):

View File

@@ -367,6 +367,29 @@ class MiningModePreset(MinerConfigValue):
available_presets=[MiningPreset.from_vnish(p) for p in web_presets],
)
@classmethod
def from_luxos(
cls, rpc_config: dict, rpc_profiles: list[dict]
) -> "MiningModePreset":
active_preset = cls.get_active_preset_from_luxos(rpc_config, rpc_profiles)
return cls(
active_preset=MiningPreset.from_luxos(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: list[dict]
) -> dict:
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 active_preset
class ManualBoardSettings(MinerConfigValue):
freq: float
@@ -687,6 +710,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",

View File

@@ -6,7 +6,9 @@ class MiningPreset(MinerConfigValue):
power: int | None = None
hashrate: int | None = None
tuned: bool | None = None
modded_psu: bool = False
modded_psu: bool | None = None
frequency: int | None = None
voltage: float | None = None
def as_vnish(self) -> dict:
if self.name is not None:
@@ -22,7 +24,7 @@ class MiningPreset(MinerConfigValue):
hashrate = None
else:
power = hr_power_split[0].replace("watt", "").strip()
hashrate = hr_power_split[1].replace("TH", "").strip()
hashrate = hr_power_split[1].replace("TH", "").replace(" LC", "").strip()
tuned = web_preset["status"] == "tuned"
modded_psu = web_preset["modded_psu_required"]
return cls(
@@ -32,3 +34,14 @@ class MiningPreset(MinerConfigValue):
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"],
)

View File

@@ -22,7 +22,7 @@ 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 +65,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 +81,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 +106,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":

View File

@@ -364,7 +364,7 @@ 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()

View File

@@ -13,19 +13,20 @@
# 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 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
from pyasic.data.pools import PoolMetrics, Scheme
from pyasic.device.algorithm.hashrate import AlgoHashRateType
from pyasic.device.algorithm.hashrate.base import GenericHashrate
from ..device.algorithm.hashrate.unit.base import GenericUnit
from .boards import HashBoard
from .device import DeviceInfo
from .error_codes import BraiinsOSError, InnosiliconError, WhatsminerError, X19Error
@@ -50,6 +51,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 +91,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 +101,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
@@ -135,9 +140,6 @@ class MinerData(BaseModel):
def fields(cls):
return list(cls.model_fields.keys())
def __post_init__(self):
self.raw_datetime = datetime.now(timezone.utc).astimezone()
def get(self, __key: str, default: Any = None):
try:
val = self.__getitem__(__key)
@@ -198,35 +200,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

View File

@@ -51,11 +51,6 @@ 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)
def get(self, __key: str, default: Any = None):
try:
val = self.__getitem__(__key)

View File

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

View File

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

View File

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

View File

@@ -28,6 +28,8 @@ class MinerMake(str, Enum):
BITAXE = "BitAxe"
ICERIVER = "IceRiver"
HAMMER = "Hammer"
VOLCMINER = "VolcMiner"
BRAIINS = "Braiins"
def __str__(self):
return self.value

View File

@@ -13,6 +13,7 @@ class AntminerModels(MinerModelType):
KS3 = "KS3"
DR5 = "DR5"
KS5 = "KS5"
KS5Pro = "KS5Pro"
L7 = "L7"
K7 = "K7"
D7 = "D7"
@@ -54,6 +55,7 @@ class AntminerModels(MinerModelType):
S19KPro = "S19K Pro"
S19kPro = "S19k Pro"
S19kProNoPIC = "S19k Pro No PIC"
S19jXP = "S19j XP"
T19 = "T19"
S21 = "S21"
S21Pro = "S21 Pro"
@@ -64,23 +66,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"
@@ -110,63 +173,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"
@@ -179,49 +214,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"
@@ -236,49 +291,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
@@ -329,6 +478,7 @@ class GoldshellModels(MinerModelType):
class ePICModels(MinerModelType):
BM520i = "BlockMiner 520i"
BM720i = "BlockMiner 720i"
S19jProDual = "S19j Pro Dual"
def __str__(self):
return self.value
@@ -379,6 +529,18 @@ 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 MinerModel:
ANTMINER = AntminerModels
WHATSMINER = WhatsminerModels
@@ -390,3 +552,5 @@ class MinerModel:
BITAXE = BitAxeModels
ICERIVER = IceRiverModels
HAMMER = HammerModels
VOLCMINER = VolcMinerModels
BRAIINS = BraiinsModels

View File

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

View File

@@ -23,6 +23,7 @@ from .S19 import (
BMMinerS19j,
BMMinerS19jNoPIC,
BMMinerS19jPro,
BMMinerS19jXP,
BMMinerS19KPro,
BMMinerS19L,
BMMinerS19Plus,

View File

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

View File

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

View File

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

View File

@@ -18,6 +18,7 @@ from .S19 import (
ePICS19,
ePICS19j,
ePICS19jPro,
ePICS19jProDual,
ePICS19jProPlus,
ePICS19kPro,
ePICS19Pro,

View File

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

View File

@@ -18,8 +18,10 @@ from .S19 import (
VNishS19,
VNishS19a,
VNishS19aPro,
VNishS19i,
VNishS19j,
VNishS19jPro,
VNishS19kPro,
VNishS19NoPIC,
VNishS19Pro,
VNishS19ProHydro,

View 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

View File

@@ -15,3 +15,4 @@
# ------------------------------------------------------------------------------
from .S21 import VNishS21
from .T21 import VNishT21

View File

@@ -32,4 +32,4 @@ from .luxminer import LUXMiner
from .marathon import MaraMiner
from .unknown import UnknownMiner
from .vnish import VNish
from .whatsminer import M2X, M3X, M5X, M6X
from .whatsminer import M2X, M3X, M5X, M6X, M7X

View File

@@ -184,13 +184,13 @@ class AntminerModern(BMMiner):
async def stop_mining(self) -> bool:
cfg = await self.get_config()
cfg.miner_mode = MiningModeConfig.sleep()
cfg.mining_mode = MiningModeConfig.sleep()
await self.send_config(cfg)
return True
async def resume_mining(self) -> bool:
cfg = await self.get_config()
cfg.miner_mode = MiningModeConfig.normal()
cfg.mining_mode = MiningModeConfig.normal()
await self.send_config(cfg)
return True

View File

@@ -14,6 +14,10 @@ BITAXE_DATA_LOC = DataLocations(
"_get_hashrate",
[WebAPICommand("web_system_info", "system/info")],
),
str(DataOptions.EXPECTED_HASHRATE): DataFunction(
"_get_expected_hashrate",
[WebAPICommand("web_system_info", "system/info")],
),
str(DataOptions.WATTAGE): DataFunction(
"_get_wattage",
[WebAPICommand("web_system_info", "system/info")],
@@ -100,6 +104,29 @@ class BitAxe(BaseMiner):
except KeyError:
pass
async def _get_expected_hashrate(
self, web_system_info: dict = None
) -> Optional[AlgoHashRate]:
if web_system_info is None:
try:
web_system_info = await self.web.system_info()
except APIError:
pass
if web_system_info is not None:
try:
expected_hashrate = (
web_system_info.get("smallCoreCount")
* web_system_info.get("asicCount")
* web_system_info.get("frequency")
)
return self.algo.hashrate(
rate=float(expected_hashrate), unit=self.algo.unit.MH
).into(self.algo.unit.default)
except KeyError:
pass
async def _get_uptime(self, web_system_info: dict = None) -> Optional[int]:
if web_system_info is None:
try:

View File

@@ -426,21 +426,22 @@ class BTMiner(StockFirmware):
if rpc_devs is not None:
try:
for board in rpc_devs["DEVS"]:
if len(hashboards) < board["ASC"] + 1:
asc = board.get("ASC")
if asc is None:
asc = board["Slot"]
if len(hashboards) < asc + 1:
hashboards.append(
HashBoard(
slot=board["ASC"], expected_chips=self.expected_chips
)
HashBoard(slot=asc, expected_chips=self.expected_chips)
)
self.expected_hashboards += 1
hashboards[board["ASC"]].chip_temp = round(board["Chip Temp Avg"])
hashboards[board["ASC"]].temp = round(board["Temperature"])
hashboards[board["ASC"]].hashrate = self.algo.hashrate(
hashboards[asc].chip_temp = round(board["Chip Temp Avg"])
hashboards[asc].temp = round(board["Temperature"])
hashboards[asc].hashrate = self.algo.hashrate(
rate=float(board["MHS 1m"]), unit=self.algo.unit.MH
).into(self.algo.unit.default)
hashboards[board["ASC"]].chips = board["Effective Chips"]
hashboards[board["ASC"]].serial_number = board["PCB SN"]
hashboards[board["ASC"]].missing = False
hashboards[asc].chips = board["Effective Chips"]
hashboards[asc].serial_number = board["PCB SN"]
hashboards[asc].missing = False
except LookupError:
pass

View File

@@ -173,8 +173,8 @@ class BlackMiner(StockFirmware):
if rpc_summary is not None:
try:
return self.algo.hashrate(
rate=float(rpc_summary["SUMMARY"][0]["GHS 5s"]),
unit=self.algo.unit.GH,
rate=float(rpc_summary["SUMMARY"][0]["MHS 5s"]),
unit=self.algo.unit.MH,
).into(self.algo.unit.default)
except (LookupError, ValueError, TypeError):
pass
@@ -221,19 +221,15 @@ class BlackMiner(StockFirmware):
hashboard = HashBoard(
slot=i - board_offset, expected_chips=self.expected_chips
)
chip_temp = boards[1].get(f"temp{i}")
if chip_temp:
hashboard.chip_temp = round(chip_temp)
temp = boards[1].get(f"temp2_{i}")
temp = boards[1].get(f"temp{i}")
if temp:
hashboard.chip_temp = round(temp)
hashboard.temp = round(temp)
hashrate = boards[1].get(f"chain_rate{i}")
if hashrate:
hashboard.hashrate = self.algo.hashrate(
rate=float(hashrate), unit=self.algo.unit.GH
rate=float(hashrate), unit=self.algo.unit.MH
).into(self.algo.unit.default)
chips = boards[1].get(f"chain_acn{i}")
@@ -360,11 +356,13 @@ class BlackMiner(StockFirmware):
if rpc_stats is not None:
try:
expected_rate = rpc_stats["STATS"][1]["total_rateideal"]
expected_rate = rpc_stats["STATS"][1].get("total_rateideal")
if expected_rate is None:
return self.sticker_hashrate.into(self.algo.unit.default)
try:
rate_unit = rpc_stats["STATS"][1]["rate_unit"]
except KeyError:
rate_unit = "GH"
rate_unit = "MH"
return self.algo.hashrate(
rate=float(expected_rate), unit=self.algo.unit.from_str(rate_unit)
).into(self.algo.unit.default)

View File

@@ -120,13 +120,13 @@ class HiveonModern(HiveonFirmware, BMMiner):
async def stop_mining(self) -> bool:
cfg = await self.get_config()
cfg.miner_mode = MiningModeConfig.sleep()
cfg.mining_mode = MiningModeConfig.sleep()
await self.send_config(cfg)
return True
async def resume_mining(self) -> bool:
cfg = await self.get_config()
cfg.miner_mode = MiningModeConfig.normal()
cfg.mining_mode = MiningModeConfig.normal()
await self.send_config(cfg)
return True

View File

@@ -17,6 +17,7 @@ import logging
from typing import List, Optional
from pyasic.config import MinerConfig
from pyasic.config.mining import MiningModePreset
from pyasic.data import Fan, HashBoard
from pyasic.data.pools import PoolMetrics, PoolUrl
from pyasic.device.algorithm import AlgoHashRate
@@ -47,6 +48,13 @@ LUXMINER_DATA_LOC = DataLocations(
"_get_wattage",
[RPCAPICommand("rpc_power", "power")],
),
str(DataOptions.WATTAGE_LIMIT): DataFunction(
"_get_wattage_limit",
[
RPCAPICommand("rpc_config", "config"),
RPCAPICommand("rpc_profiles", "profiles"),
],
),
str(DataOptions.FANS): DataFunction(
"_get_fans",
[RPCAPICommand("rpc_fans", "fans")],
@@ -77,6 +85,7 @@ class LUXMiner(LuxOSFirmware):
rpc: LUXMinerRPCAPI
supports_shutdown = True
supports_presets = True
data_locations = LUXMINER_DATA_LOC
@@ -131,12 +140,16 @@ class LUXMiner(LuxOSFirmware):
return False
async def get_config(self) -> MinerConfig:
data = await self.rpc.multicommand("tempctrl", "fans", "pools", "groups")
data = await self.rpc.multicommand(
"tempctrl", "fans", "pools", "groups", "config", "profiles"
)
return MinerConfig.from_luxos(
rpc_tempctrl=data.get("tempctrl", [{}])[0],
rpc_fans=data.get("fans", [{}])[0],
rpc_pools=data.get("pools", [{}])[0],
rpc_groups=data.get("groups", [{}])[0],
rpc_config=data.get("config", [{}])[0],
rpc_profiles=data.get("profiles", [{}])[0],
)
async def upgrade_firmware(self) -> bool:
@@ -146,7 +159,7 @@ class LUXMiner(LuxOSFirmware):
bool: True if the firmware upgrade was successfully initiated, False otherwise.
"""
try:
await self.rpc.upgraderun()
await self.rpc.updaterun()
logging.info(f"{self.ip}: Firmware upgrade initiated successfully.")
return True
@@ -155,6 +168,44 @@ class LUXMiner(LuxOSFirmware):
return False
async def atm_enabled(self) -> Optional[bool]:
try:
result = await self.rpc.atm()
return result["ATM"][0]["Enabled"]
except (APIError, LookupError):
pass
async def set_power_limit(self, wattage: int) -> bool:
config = await self.get_config()
valid_presets = {
preset.name: preset.power
for preset in config.mining_mode.available_presets
if preset.power <= wattage
}
# Set power to highest preset <= wattage
# If ATM enabled, must disable it before setting power limit
new_preset = max(valid_presets, key=valid_presets.get)
re_enable_atm = False
try:
if await self.atm_enabled():
re_enable_atm = True
await self.rpc.atmset("enabled=false")
result = await self.rpc.profileset(new_preset)
if re_enable_atm:
await self.rpc.atmset("enabled=true")
except APIError:
raise
except Exception as e:
logging.warning(f"{self} - Failed to set power limit: {e}")
return False
if result["PROFILE"][0]["Profile"] == new_preset:
return True
else:
return False
##################################################
### DATA GATHERING FUNCTIONS (get_{some_data}) ###
##################################################
@@ -246,6 +297,17 @@ class LUXMiner(LuxOSFirmware):
except (LookupError, ValueError, TypeError):
pass
async def _get_wattage_limit(
self, rpc_config: dict = None, rpc_profiles: list[dict] = None
) -> Optional[int]:
try:
active_preset = MiningModePreset.get_active_preset_from_luxos(
rpc_config, rpc_profiles
)
return active_preset.power
except (LookupError, ValueError, TypeError):
pass
async def _get_fans(self, rpc_fans: dict = None) -> List[Fan]:
if rpc_fans is None:
try:

View File

@@ -14,6 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
import logging
from typing import Optional
from pyasic import MinerConfig
@@ -96,6 +97,7 @@ class VNish(VNishFirmware, BMMiner):
supports_shutdown = True
supports_presets = True
supports_autotuning = True
data_locations = VNISH_DATA_LOC
@@ -272,3 +274,27 @@ class VNish(VNishFirmware, BMMiner):
return self.config
self.config = MinerConfig.from_vnish(web_settings, web_presets)
return self.config
async def set_power_limit(self, wattage: int) -> bool:
config = await self.get_config()
valid_presets = [
preset.power
for preset in config.mining_mode.available_presets
if preset.tuned and preset.power <= wattage
]
new_wattage = max(valid_presets)
# Set power to highest preset <= wattage
try:
await self.web.set_power_limit(new_wattage)
updated_settings = await self.web.settings()
except APIError:
raise
except Exception as e:
logging.warning(f"{self} - Failed to set power limit: {e}")
return False
if int(updated_settings["miner"]["overclock"]["preset"]) == new_wattage:
return True
else:
return False

View File

@@ -16,6 +16,10 @@
from pyasic.miners.backends.btminer import BTMiner
class M7X(BTMiner):
supports_autotuning = True
class M6X(BTMiner):
supports_autotuning = True

View File

@@ -24,6 +24,7 @@ from pyasic.data.device import DeviceInfo
from pyasic.data.error_codes import MinerErrorData
from pyasic.data.pools import PoolMetrics
from pyasic.device.algorithm import MinerAlgoType
from pyasic.device.algorithm.base import GenericAlgo
from pyasic.device.algorithm.hashrate import AlgoHashRate
from pyasic.device.firmware import MinerFirmware
from pyasic.device.makes import MinerMake
@@ -46,7 +47,7 @@ class MinerProtocol(Protocol):
make: MinerMake = None
raw_model: MinerModelType = None
firmware: MinerFirmware = None
algo: type[MinerAlgoType] = None
algo: type[MinerAlgoType] = GenericAlgo
expected_hashboards: int = None
expected_chips: int = None

View 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 .braiins import *

View File

@@ -0,0 +1,26 @@
# ------------------------------------------------------------------------------
# Copyright 2022 Upstream Data Inc -
# -
# Licensed under the Apache License, Version 2.0 (the "License"); -
# you may not use this file except in compliance with the License. -
# You may obtain a copy of the License at -
# -
# http://www.apache.org/licenses/LICENSE-2.0 -
# -
# Unless required by applicable law or agreed to in writing, software -
# distributed under the License is distributed on an "AS IS" BASIS, -
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
# See the License for the specific language governing permissions and -
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners.backends import BOSer
from pyasic.miners.device.models import BMM100, BMM101
class BraiinsBMM100(BOSer, BMM100):
pass
class BraiinsBMM101(BOSer, BMM101):
pass

View 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 .BMM import BraiinsBMM100, BraiinsBMM101

View 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 .BMM import *

View File

@@ -56,3 +56,11 @@ class IceRiverMake(BaseMiner):
class HammerMake(BaseMiner):
make = MinerMake.HAMMER
class VolcMinerMake(BaseMiner):
make = MinerMake.VOLCMINER
class BraiinsMake(BaseMiner):
make = MinerMake.BRAIINS

View File

@@ -17,9 +17,11 @@
from .antminer import *
from .auradine import *
from .avalonminer import *
from .braiins import *
from .epic import *
from .goldshell import *
from .hammer import *
from .iceriver import *
from .innosilicon import *
from .volcminer import *
from .whatsminer import *

View File

@@ -214,3 +214,12 @@ class S19KPro(AntMinerMake):
expected_fans = 4
expected_hashboards = 3
algo = MinerAlgo.SHA256
class S19jXP(AntMinerMake):
raw_model = MinerModel.ANTMINER.S19jXP
expected_chips = 110
expected_fans = 4
expected_hashboards = 3
algo = MinerAlgo.SHA256

View File

@@ -28,6 +28,7 @@ from .S19 import (
S19jProNoPIC,
S19jProPlus,
S19jProPlusNoPIC,
S19jXP,
S19kPro,
S19KPro,
S19kProNoPIC,

View File

@@ -25,3 +25,12 @@ class KS5(AntMinerMake):
expected_hashboards = 3
expected_fans = 4
algo = MinerAlgo.KHEAVYHASH
class KS5Pro(AntMinerMake):
raw_model = MinerModel.ANTMINER.KS5
expected_chips = 92
expected_hashboards = 3
expected_fans = 4
algo = MinerAlgo.KHEAVYHASH

View File

@@ -14,4 +14,4 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from .DR5 import DR5
from .KS5 import KS5
from .KS5 import KS5, KS5Pro

View File

@@ -0,0 +1,19 @@
from pyasic.device.algorithm import MinerAlgo
from pyasic.device.models import MinerModel
from pyasic.miners.device.makes import BraiinsMake
class BMM100(BraiinsMake):
raw_model = MinerModel.BRAIINS.BMM100
expected_hashboards = 1
expected_fans = 1
algo = MinerAlgo.SHA256
class BMM101(BraiinsMake):
raw_model = MinerModel.BRAIINS.BMM101
expected_hashboards = 1
expected_fans = 1
algo = MinerAlgo.SHA256

View File

@@ -0,0 +1 @@
from .BMM1 import *

View File

@@ -0,0 +1 @@
from .BMM import *

View File

@@ -0,0 +1,27 @@
# ------------------------------------------------------------------------------
# Copyright 2024 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.device.algorithm import MinerAlgo
from pyasic.device.models import MinerModel
from pyasic.miners.device.makes import VolcMinerMake
class D1(VolcMinerMake):
raw_model = MinerModel.VOLCMINER.D1
expected_chips = 105
expected_hashboards = 3
expected_fans = 4
algo = MinerAlgo.SCRYPT

View File

@@ -0,0 +1 @@
from .D1 import D1

View File

@@ -0,0 +1 @@
from .DX import *

View File

@@ -1,18 +1,3 @@
# ------------------------------------------------------------------------------
# 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.device.algorithm import MinerAlgo
from pyasic.device.models import MinerModel
from pyasic.miners.device.makes import WhatsMinerMake

View File

@@ -1,18 +1,3 @@
# ------------------------------------------------------------------------------
# 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.device.algorithm import MinerAlgo
from pyasic.device.models import MinerModel
from pyasic.miners.device.makes import WhatsMinerMake

View File

@@ -1,18 +1,3 @@
# ------------------------------------------------------------------------------
# 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.device.algorithm import MinerAlgo
from pyasic.device.models import MinerModel
from pyasic.miners.device.makes import WhatsMinerMake

View File

@@ -1,18 +1,3 @@
# ------------------------------------------------------------------------------
# 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.device.algorithm import MinerAlgo
from pyasic.device.models import MinerModel
from pyasic.miners.device.makes import WhatsMinerMake
@@ -21,6 +6,7 @@ from pyasic.miners.device.makes import WhatsMinerMake
class M20SPlusV30(WhatsMinerMake):
raw_model = MinerModel.WHATSMINER.M20SPlusV30
expected_chips = None
expected_fans = 2
expected_hashboards = 3
algo = MinerAlgo.SHA256

View File

@@ -1,18 +1,3 @@
# ------------------------------------------------------------------------------
# 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.device.algorithm import MinerAlgo
from pyasic.device.models import MinerModel
from pyasic.miners.device.makes import WhatsMinerMake

View File

@@ -1,18 +1,3 @@
# ------------------------------------------------------------------------------
# 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.device.algorithm import MinerAlgo
from pyasic.device.models import MinerModel
from pyasic.miners.device.makes import WhatsMinerMake

View File

@@ -1,18 +1,3 @@
# ------------------------------------------------------------------------------
# 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.device.algorithm import MinerAlgo
from pyasic.device.models import MinerModel
from pyasic.miners.device.makes import WhatsMinerMake
@@ -21,6 +6,7 @@ from pyasic.miners.device.makes import WhatsMinerMake
class M21SPlusV20(WhatsMinerMake):
raw_model = MinerModel.WHATSMINER.M21SPlusV20
expected_chips = None
expected_fans = 2
expected_hashboards = 3
algo = MinerAlgo.SHA256

Some files were not shown because too many files have changed in this diff Show More