Compare commits

..

54 Commits

Author SHA1 Message Date
Upstream Data
74c457a694 version: bump version number. 2024-04-11 09:23:55 -06:00
Upstream Data
4a1c53dfd7 bug: fix some issues with config on bosminer. 2024-04-11 09:23:33 -06:00
Upstream Data
2815d2ba11 version: bump version number. 2024-04-08 12:15:38 -06:00
Upstream Data
1ff20fc6f0 feature: add bosminer S21 support. 2024-04-08 12:15:18 -06:00
Brett Rowan
797c847055 version: bump version number. 2024-04-07 17:17:17 -06:00
Brett Rowan
65c7f2f66f bug: fix vnish shutting-down handling. 2024-04-07 17:16:37 -06:00
Brett Rowan
445d621590 version: bump version number. 2024-04-07 17:04:10 -06:00
Brett Rowan
d39ecfd6b4 feature: add is_mining for vnish. 2024-04-07 17:03:28 -06:00
Brett Rowan
36663471fb version: bump version number. 2024-04-06 12:34:43 -06:00
Brett Rowan
80293ac52f bug: fix incorrect model for XP. 2024-04-06 12:34:14 -06:00
UpstreamData
70b45f40f5 docs: update dev setup. 2024-03-29 11:19:17 -06:00
UpstreamData
a511fabd9c Update README.md with dev docs. 2024-03-29 11:17:39 -06:00
Jim Burtoft
8bc8f6f178 Comment on some code I didn't understand initially (#118) 2024-03-28 21:31:37 -06:00
Brett Rowan
b790ad58a7 version: bump version number. 2024-03-23 20:27:42 -06:00
Brett Rowan
354ab793a2 bug: fix vnish MAC not working on some versions. 2024-03-23 20:25:26 -06:00
Upstream Data
59346d641f version: bump version number. 2024-03-22 15:12:35 -06:00
Upstream Data
11d770771b feature: fix vnish not having the shutdown flag. 2024-03-22 15:12:20 -06:00
Upstream Data
1b6db7ed45 feature: add antminer new API. 2024-03-22 13:42:10 -06:00
Upstream Data
55c4e10fae tests: Update tests, and fix some bugs. 2024-03-22 13:19:44 -06:00
Upstream Data
77c06dad61 version: bump version number. 2024-03-19 14:24:54 -06:00
Upstream Data
68d250d2f2 bug: fix K pro naming. 2024-03-19 14:24:31 -06:00
Upstream Data
094a17ac68 version: bump version number. 2024-03-19 14:17:21 -06:00
Upstream Data
dbcdeaa3de feature: add support for S19K Pro. 2024-03-19 14:16:57 -06:00
Upstream Data
872cac811a version: bump version number. 2024-03-19 12:41:57 -06:00
Upstream Data
d324c2fee9 feature: add stock S21 support. 2024-03-19 12:41:37 -06:00
Upstream Data
4b54cf67ba version: bump version number. 2024-03-12 16:16:40 -06:00
Upstream Data
0e00fe3114 feature: add antminer mode as str setting. 2024-03-12 16:16:15 -06:00
wilfredallyn
15d1dc5bb6 feature: add install docs (#117) 2024-03-10 09:09:06 -06:00
Brett Rowan
2af0003843 version: bump version number. 2024-03-06 21:56:10 -07:00
Brett Rowan
3c227be170 bug: update httpx to use compatible versioning. 2024-03-06 21:53:14 -07:00
Brett Rowan
e889780bad version: bump version number. 2024-03-03 11:16:16 -07:00
Brett Rowan
cc3d4fa805 feature: add S19 Hydro and S19 Pro+ Hydro. 2024-03-03 11:15:44 -07:00
Brett Rowan
227e1e2d2d version: bump version number. 2024-02-25 13:10:11 -07:00
Brett Rowan
d6c8ff0910 feature: add support for more S21 LUXOS. 2024-02-25 13:08:25 -07:00
Brett Rowan
bd20e051b0 feature: add support for more LuxOS models. 2024-02-25 13:02:52 -07:00
UpstreamData
2eb6697e9a version: bump version number 2024-02-21 13:23:38 -07:00
UpstreamData
c5817fcc36 docs: Update docs. 2024-02-21 13:22:40 -07:00
Brett Rowan
f2391bcb2d Merge pull request #110 from jpcomps/add_blockminer_support
ePIC: Add Blockminer support
2024-02-21 13:21:45 -07:00
Brett Rowan
bc3bd9e5da Fix issue with possible type hint incompatability. 2024-02-21 13:20:41 -07:00
UpstreamData
3f0959d75e docs: Update docs. 2024-02-21 12:43:46 -07:00
UpstreamData
31f7b56724 docs: Update docs. 2024-02-21 12:39:40 -07:00
UpstreamData
072954d755 docs: Update docs. 2024-02-21 12:39:08 -07:00
UpstreamData
d271e0f9c8 version: bump version number. 2024-02-21 12:33:21 -07:00
UpstreamData
8f1408ce17 bug: fix sending privileged commands on BTMiner using timeout as the port, and capture positional arguments in _send_bytes to prevent this. 2024-02-21 12:32:56 -07:00
John-Paul Compagnone
825d1f4cfb fix checks 2024-02-20 20:39:22 -05:00
John-Paul Compagnone
c6bcd7e05a fix capitalization 2024-02-20 20:33:30 -05:00
John-Paul Compagnone
5d80051f3b more missing i 2024-02-20 18:15:40 -05:00
John-Paul Compagnone
b71c448199 add missing i 2024-02-20 18:12:19 -05:00
JP Compagnone
c82148412c Merge branch 'UpstreamData:master' into add_blockminer_support 2024-02-20 18:01:16 -05:00
UpstreamData
a582ee63a0 bug: use force apply to fix DPS bug with setting wattage. 2024-02-20 10:11:57 -07:00
UpstreamData
db7c19c486 feature: add some miner support. 2024-02-20 09:47:28 -07:00
JP Compagnone
599f71da19 Merge branch 'UpstreamData:master' into add_blockminer_support 2024-02-19 19:04:32 -05:00
John-Paul Compagnone
c25ff6fcef add ePIC Blockminer 520i support 2024-02-11 10:55:49 -05:00
John-Paul Compagnone
ab0dcd607b make ePIC api calls more reliable 2024-02-10 21:59:08 -05:00
68 changed files with 1239 additions and 117 deletions

View File

@@ -1,16 +1,16 @@
repos: repos:
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0 rev: v4.5.0
hooks: hooks:
- id: trailing-whitespace - id: trailing-whitespace
- id: check-yaml - id: check-yaml
- id: check-added-large-files - id: check-added-large-files
- repo: https://github.com/psf/black - repo: https://github.com/psf/black
rev: 22.6.0 rev: 24.3.0
hooks: hooks:
- id: black - id: black
- repo: https://github.com/pycqa/isort - repo: https://github.com/pycqa/isort
rev: 5.10.1 rev: 5.13.2
hooks: hooks:
- id: isort - id: isort
name: isort (python) name: isort (python)

View File

@@ -19,6 +19,33 @@ Welcome to `pyasic`! `pyasic` uses an asynchronous method of communicating with
[Click here to view supported miner types](https://docs.pyasic.org/en/latest/miners/supported_types/) [Click here to view supported miner types](https://docs.pyasic.org/en/latest/miners/supported_types/)
---
## Installation
It is recommended to install `pyasic` in a [virtual environment](https://realpython.com/python-virtual-environments-a-primer/#what-other-popular-options-exist-aside-from-venv) to isolate it from the rest of your system. Options include:
- [pypoetry](https://python-poetry.org/): the reccommended way, since pyasic already uses it by default
```
poetry install
```
- [venv](https://docs.python.org/3/library/venv.html): included in Python standard library but has fewer features than other options
- [pyenv-virtualenv](https://github.com/pyenv/pyenv-virtualenv): [pyenv](https://github.com/pyenv/pyenv) plugin for managing virtualenvs
```
pyenv install <python version number>
pyenv virtualenv <python version number> <env name>
pyenv activate <env name>
```
- [conda](https://docs.conda.io/en/latest/)
##### Installing `pyasic`
`python -m pip install .` or `poetry install`
##### Additional Developer Setup
```
poetry install --with dev
pre-commit install
```
--- ---
## Getting started ## Getting started

View File

@@ -27,6 +27,8 @@ def backend_str(backend: MinerTypes) -> str:
match backend: match backend:
case MinerTypes.ANTMINER: case MinerTypes.ANTMINER:
return "Stock Firmware Antminers" return "Stock Firmware Antminers"
case MinerTypes.AURADINE:
return "Stock Firmware Auradine Miners"
case MinerTypes.AVALONMINER: case MinerTypes.AVALONMINER:
return "Stock Firmware Avalonminers" return "Stock Firmware Avalonminers"
case MinerTypes.VNISH: case MinerTypes.VNISH:
@@ -45,6 +47,8 @@ def backend_str(backend: MinerTypes) -> str:
return "Stock Firmware Goldshells" return "Stock Firmware Goldshells"
case MinerTypes.LUX_OS: case MinerTypes.LUX_OS:
return "LuxOS Firmware Miners" return "LuxOS Firmware Miners"
case MinerTypes.EPIC:
return "ePIC Firmware Miners"
def create_url_str(mtype: str): def create_url_str(mtype: str):

View File

@@ -18,6 +18,23 @@ Welcome to `pyasic`! `pyasic` uses an asynchronous method of communicating with
[Click here to view supported miner types](miners/supported_types.md) [Click here to view supported miner types](miners/supported_types.md)
---
## Installation
It is recommended to install `pyasic` in a [virtual environment](https://realpython.com/python-virtual-environments-a-primer/#what-other-popular-options-exist-aside-from-venv) to isolate it from the rest of your system. Options include:
- [venv](https://docs.python.org/3/library/venv.html): included in Python standard library but has fewer features than other options
- [pyenv-virtualenv](https://github.com/pyenv/pyenv-virtualenv): [pyenv](https://github.com/pyenv/pyenv) plugin for managing virtualenvs
```
pyenv install <python version number>
pyenv virtualenv <python version number> <env name>
pyenv activate <env name>
```
- [conda](https://docs.conda.io/en/latest/)
##### Installing `pyasic`
`python -m pip install .` or `poetry install`
--- ---
## Getting started ## Getting started
--- ---
@@ -236,6 +253,7 @@ settings.update("default_antminer_password", "my_pwd")
"factory_get_timeout": 3, "factory_get_timeout": 3,
"get_data_retries": 1, "get_data_retries": 1,
"api_function_timeout": 5, "api_function_timeout": 5,
"antminer_mining_mode_as_str": False,
"default_whatsminer_password": "admin", "default_whatsminer_password": "admin",
"default_innosilicon_password": "admin", "default_innosilicon_password": "admin",
"default_antminer_password": "root", "default_antminer_password": "root",

View File

@@ -50,49 +50,49 @@
show_root_heading: false show_root_heading: false
heading_level: 4 heading_level: 4
## S17 (BOS) ## S17 (BOS+)
::: pyasic.miners.antminer.bosminer.X17.S17.BOSMinerS17 ::: pyasic.miners.antminer.bosminer.X17.S17.BOSMinerS17
handler: python handler: python
options: options:
show_root_heading: false show_root_heading: false
heading_level: 4 heading_level: 4
## S17+ (BOS) ## S17+ (BOS+)
::: pyasic.miners.antminer.bosminer.X17.S17.BOSMinerS17Plus ::: pyasic.miners.antminer.bosminer.X17.S17.BOSMinerS17Plus
handler: python handler: python
options: options:
show_root_heading: false show_root_heading: false
heading_level: 4 heading_level: 4
## S17 Pro (BOS) ## S17 Pro (BOS+)
::: pyasic.miners.antminer.bosminer.X17.S17.BOSMinerS17Pro ::: pyasic.miners.antminer.bosminer.X17.S17.BOSMinerS17Pro
handler: python handler: python
options: options:
show_root_heading: false show_root_heading: false
heading_level: 4 heading_level: 4
## S17e (BOS) ## S17e (BOS+)
::: pyasic.miners.antminer.bosminer.X17.S17.BOSMinerS17e ::: pyasic.miners.antminer.bosminer.X17.S17.BOSMinerS17e
handler: python handler: python
options: options:
show_root_heading: false show_root_heading: false
heading_level: 4 heading_level: 4
## T17 (BOS) ## T17 (BOS+)
::: pyasic.miners.antminer.bosminer.X17.T17.BOSMinerT17 ::: pyasic.miners.antminer.bosminer.X17.T17.BOSMinerT17
handler: python handler: python
options: options:
show_root_heading: false show_root_heading: false
heading_level: 4 heading_level: 4
## T17+ (BOS) ## T17+ (BOS+)
::: pyasic.miners.antminer.bosminer.X17.T17.BOSMinerT17Plus ::: pyasic.miners.antminer.bosminer.X17.T17.BOSMinerT17Plus
handler: python handler: python
options: options:
show_root_heading: false show_root_heading: false
heading_level: 4 heading_level: 4
## T17e (BOS) ## T17e (BOS+)
::: pyasic.miners.antminer.bosminer.X17.T17.BOSMinerT17e ::: pyasic.miners.antminer.bosminer.X17.T17.BOSMinerT17e
handler: python handler: python
options: options:

View File

@@ -85,6 +85,34 @@
show_root_heading: false show_root_heading: false
heading_level: 4 heading_level: 4
## S19 Hydro
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19Hydro
handler: python
options:
show_root_heading: false
heading_level: 4
## S19 Pro Hydro
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19ProHydro
handler: python
options:
show_root_heading: false
heading_level: 4
## S19 Pro+ Hydro
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19ProPlusHydro
handler: python
options:
show_root_heading: false
heading_level: 4
## S19K Pro
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19KPro
handler: python
options:
show_root_heading: false
heading_level: 4
## T19 ## T19
::: pyasic.miners.antminer.bmminer.X19.T19.BMMinerT19 ::: pyasic.miners.antminer.bmminer.X19.T19.BMMinerT19
handler: python handler: python
@@ -92,49 +120,91 @@
show_root_heading: false show_root_heading: false
heading_level: 4 heading_level: 4
## S19 (BOS) ## S19
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19 ::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19
handler: python handler: python
options: options:
show_root_heading: false show_root_heading: false
heading_level: 4 heading_level: 4
## S19 Pro (BOS) ## S19+
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19Plus
handler: python
options:
show_root_heading: false
heading_level: 4
## S19 Pro
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19Pro ::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19Pro
handler: python handler: python
options: options:
show_root_heading: false show_root_heading: false
heading_level: 4 heading_level: 4
## S19j (BOS) ## S19a
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19a
handler: python
options:
show_root_heading: false
heading_level: 4
## S19a Pro
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19aPro
handler: python
options:
show_root_heading: false
heading_level: 4
## S19j
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19j ::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19j
handler: python handler: python
options: options:
show_root_heading: false show_root_heading: false
heading_level: 4 heading_level: 4
## S19j No PIC (BOS) ## S19j No PIC
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19jNoPIC ::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19jNoPIC
handler: python handler: python
options: options:
show_root_heading: false show_root_heading: false
heading_level: 4 heading_level: 4
## S19j Pro (BOS) ## S19j Pro
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19jPro ::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19jPro
handler: python handler: python
options: options:
show_root_heading: false show_root_heading: false
heading_level: 4 heading_level: 4
## S19j Pro (BOS) ## S19j Pro
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19jPro ::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19jPro
handler: python handler: python
options: options:
show_root_heading: false show_root_heading: false
heading_level: 4 heading_level: 4
## T19 (BOS) ## S19j Pro+
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19jProPlus
handler: python
options:
show_root_heading: false
heading_level: 4
## S19k Pro No PIC
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19kProNoPIC
handler: python
options:
show_root_heading: false
heading_level: 4
## S19 XP
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19XP
handler: python
options:
show_root_heading: false
heading_level: 4
## T19
::: pyasic.miners.antminer.bosminer.X19.T19.BOSMinerT19 ::: pyasic.miners.antminer.bosminer.X19.T19.BOSMinerT19
handler: python handler: python
options: options:
@@ -225,6 +295,20 @@
show_root_heading: false show_root_heading: false
heading_level: 4 heading_level: 4
## S19j Pro+ (ePIC)
::: pyasic.miners.antminer.epic.X19.S19.ePICS19jProPlus
handler: python
options:
show_root_heading: false
heading_level: 4
## S19k Pro (ePIC)
::: pyasic.miners.antminer.epic.X19.S19.ePICS19kPro
handler: python
options:
show_root_heading: false
heading_level: 4
## S19 XP (ePIC) ## S19 XP (ePIC)
::: pyasic.miners.antminer.epic.X19.S19.ePICS19XP ::: pyasic.miners.antminer.epic.X19.S19.ePICS19XP
handler: python handler: python
@@ -232,3 +316,52 @@
show_root_heading: false show_root_heading: false
heading_level: 4 heading_level: 4
## S19 (LuxOS)
::: pyasic.miners.antminer.luxos.X19.S19.LUXMinerS19
handler: python
options:
show_root_heading: false
heading_level: 4
## S19 Pro (LuxOS)
::: pyasic.miners.antminer.luxos.X19.S19.LUXMinerS19Pro
handler: python
options:
show_root_heading: false
heading_level: 4
## S19j Pro (LuxOS)
::: pyasic.miners.antminer.luxos.X19.S19.LUXMinerS19jPro
handler: python
options:
show_root_heading: false
heading_level: 4
## S19j Pro+ (LuxOS)
::: pyasic.miners.antminer.luxos.X19.S19.LUXMinerS19jProPlus
handler: python
options:
show_root_heading: false
heading_level: 4
## S19k Pro (LuxOS)
::: pyasic.miners.antminer.luxos.X19.S19.LUXMinerS19kPro
handler: python
options:
show_root_heading: false
heading_level: 4
## S19 XP (LuxOS)
::: pyasic.miners.antminer.luxos.X19.S19.LUXMinerS19XP
handler: python
options:
show_root_heading: false
heading_level: 4
## T19 (LuxOS)
::: pyasic.miners.antminer.luxos.X19.T19.LUXMinerT19
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -0,0 +1,31 @@
# pyasic
## X21 Models
## S21
::: pyasic.miners.antminer.bmminer.X21.S21.BMMinerS21
handler: python
options:
show_root_heading: false
heading_level: 4
## S21
::: pyasic.miners.antminer.bosminer.X21.S21.BOSMinerS21
handler: python
options:
show_root_heading: false
heading_level: 4
## S21 (ePIC)
::: pyasic.miners.antminer.epic.X21.S21.ePICS21
handler: python
options:
show_root_heading: false
heading_level: 4
## S21 (LuxOS)
::: pyasic.miners.antminer.luxos.X21.S21.LUXMinerS21
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -29,3 +29,10 @@
show_root_heading: false show_root_heading: false
heading_level: 4 heading_level: 4
## L3+ (VNish)
::: pyasic.miners.antminer.vnish.X3.L3.VnishL3Plus
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -8,3 +8,10 @@
show_root_heading: false show_root_heading: false
heading_level: 4 heading_level: 4
## L7 (VNish)
::: pyasic.miners.antminer.vnish.X7.L7.VnishL7
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -36,14 +36,14 @@
show_root_heading: false show_root_heading: false
heading_level: 4 heading_level: 4
## S9 (BOS) ## S9 (BOS+)
::: pyasic.miners.antminer.bosminer.X9.S9.BOSMinerS9 ::: pyasic.miners.antminer.bosminer.X9.S9.BOSMinerS9
handler: python handler: python
options: options:
show_root_heading: false show_root_heading: false
heading_level: 4 heading_level: 4
## T9 (Hiveon) ## T9 (Hive)
::: pyasic.miners.antminer.hiveon.X9.T9.HiveonT9 ::: pyasic.miners.antminer.hiveon.X9.T9.HiveonT9
handler: python handler: python
options: options:

View File

@@ -0,0 +1,24 @@
# pyasic
## AD Models
## AT1500
::: pyasic.miners.auradine.flux.AD.AT1.AuradineFluxAT1500
handler: python
options:
show_root_heading: false
heading_level: 4
## AT2860
::: pyasic.miners.auradine.flux.AD.AT2.AuradineFluxAT2860
handler: python
options:
show_root_heading: false
heading_level: 4
## AT2880
::: pyasic.miners.auradine.flux.AD.AT2.AuradineFluxAT2880
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -0,0 +1,17 @@
# pyasic
## AI Models
## AI2500
::: pyasic.miners.auradine.flux.AI.AI2.AuradineFluxAI2500
handler: python
options:
show_root_heading: false
heading_level: 4
## AI3680
::: pyasic.miners.auradine.flux.AI.AI3.AuradineFluxAI3680
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -0,0 +1,17 @@
# pyasic
## AT Models
## AD2500
::: pyasic.miners.auradine.flux.AT.AD2.AuradineFluxAD2500
handler: python
options:
show_root_heading: false
heading_level: 4
## AD3500
::: pyasic.miners.auradine.flux.AT.AD3.AuradineFluxAD3500
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -21,3 +21,4 @@
options: options:
show_root_heading: false show_root_heading: false
heading_level: 4 heading_level: 4

View File

@@ -0,0 +1,17 @@
# pyasic
## XBox Models
## KD Box II
::: pyasic.miners.goldshell.bfgminer.XBox.KDBox.GoldshellKDBoxII
handler: python
options:
show_root_heading: false
heading_level: 4
## KD Box Pro
::: pyasic.miners.goldshell.bfgminer.XBox.KDBox.GoldshellKDBoxPro
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -2,8 +2,9 @@
## XMax Models ## XMax Models
## KD Max ## KD Max
::: pyasic.miners.goldshell.bfgminer.XMax.KDMax.KDMax ::: pyasic.miners.goldshell.bfgminer.XMax.KDMax.GoldshellKDMax
handler: python handler: python
options: options:
show_root_heading: false show_root_heading: false
heading_level: 4 heading_level: 4

View File

@@ -7,3 +7,4 @@
options: options:
show_root_heading: false show_root_heading: false
heading_level: 4 heading_level: 4

View File

@@ -7,3 +7,4 @@
options: options:
show_root_heading: false show_root_heading: false
heading_level: 4 heading_level: 4

View File

@@ -78,9 +78,19 @@ details {
<li><a href="../antminer/X19#s19-xp">S19 XP</a></li> <li><a href="../antminer/X19#s19-xp">S19 XP</a></li>
<li><a href="../antminer/X19#s19a">S19a</a></li> <li><a href="../antminer/X19#s19a">S19a</a></li>
<li><a href="../antminer/X19#s19a-pro">S19a Pro</a></li> <li><a href="../antminer/X19#s19a-pro">S19a Pro</a></li>
<li><a href="../antminer/X19#s19-hydro">S19 Hydro</a></li>
<li><a href="../antminer/X19#s19-pro-hydro">S19 Pro Hydro</a></li>
<li><a href="../antminer/X19#s19-pro_1-hydro">S19 Pro+ Hydro</a></li>
<li><a href="../antminer/X19#s19k-pro">S19K Pro</a></li>
<li><a href="../antminer/X19#t19">T19</a></li> <li><a href="../antminer/X19#t19">T19</a></li>
</ul> </ul>
</details> </details>
<details>
<summary>X21 Series:</summary>
<ul>
<li><a href="../antminer/X21#s21">S21</a></li>
</ul>
</details>
</ul> </ul>
</details> </details>
<details> <details>
@@ -286,13 +296,39 @@ details {
<li><a href="../whatsminer/M5X#m50s_1_1-vk30">M50S++ VK30</a></li> <li><a href="../whatsminer/M5X#m50s_1_1-vk30">M50S++ VK30</a></li>
<li><a href="../whatsminer/M5X#m53-vh30">M53 VH30</a></li> <li><a href="../whatsminer/M5X#m53-vh30">M53 VH30</a></li>
<li><a href="../whatsminer/M5X#m53s-vh30">M53S VH30</a></li> <li><a href="../whatsminer/M5X#m53s-vh30">M53S VH30</a></li>
<li><a href="../whatsminer/M5X#m53s-vj40">M53S VJ40</a></li>
<li><a href="../whatsminer/M5X#m53s_1-vj30">M53S+ VJ30</a></li> <li><a href="../whatsminer/M5X#m53s_1-vj30">M53S+ VJ30</a></li>
<li><a href="../whatsminer/M5X#m53s_1_1-vk10">M53S++ VK10</a></li>
<li><a href="../whatsminer/M5X#m56-vh30">M56 VH30</a></li> <li><a href="../whatsminer/M5X#m56-vh30">M56 VH30</a></li>
<li><a href="../whatsminer/M5X#m56s-vh30">M56S VH30</a></li> <li><a href="../whatsminer/M5X#m56s-vh30">M56S VH30</a></li>
<li><a href="../whatsminer/M5X#m56s_1-vj30">M56S+ VJ30</a></li> <li><a href="../whatsminer/M5X#m56s_1-vj30">M56S+ VJ30</a></li>
<li><a href="../whatsminer/M5X#m59-vh30">M59 VH30</a></li> <li><a href="../whatsminer/M5X#m59-vh30">M59 VH30</a></li>
</ul> </ul>
</details> </details>
<details>
<summary>M6X Series:</summary>
<ul>
<li><a href="../whatsminer/M6X#m60-vk10">M60 VK10</a></li>
<li><a href="../whatsminer/M6X#m60-vk20">M60 VK20</a></li>
<li><a href="../whatsminer/M6X#m60-vk30">M60 VK30</a></li>
<li><a href="../whatsminer/M6X#m60-vk40">M60 VK40</a></li>
<li><a href="../whatsminer/M6X#m60s-vk10">M60S VK10</a></li>
<li><a href="../whatsminer/M6X#m60s-vk20">M60S VK20</a></li>
<li><a href="../whatsminer/M6X#m60s-vk30">M60S VK30</a></li>
<li><a href="../whatsminer/M6X#m60s-vk40">M60S VK40</a></li>
<li><a href="../whatsminer/M6X#m63-vk10">M63 VK10</a></li>
<li><a href="../whatsminer/M6X#m63-vk20">M63 VK20</a></li>
<li><a href="../whatsminer/M6X#m63-vk30">M63 VK30</a></li>
<li><a href="../whatsminer/M6X#m63s-vk10">M63S VK10</a></li>
<li><a href="../whatsminer/M6X#m63s-vk20">M63S VK20</a></li>
<li><a href="../whatsminer/M6X#m63s-vk30">M63S VK30</a></li>
<li><a href="../whatsminer/M6X#m66-vk20">M66 VK20</a></li>
<li><a href="../whatsminer/M6X#m66-vk30">M66 VK30</a></li>
<li><a href="../whatsminer/M6X#m66s-vk20">M66S VK20</a></li>
<li><a href="../whatsminer/M6X#m66s-vk30">M66S VK30</a></li>
<li><a href="../whatsminer/M6X#m66s-vk40">M66S VK40</a></li>
</ul>
</details>
</ul> </ul>
</details> </details>
<details> <details>
@@ -376,6 +412,13 @@ details {
<li><a href="../goldshell/XMax#kd-max">KD Max</a></li> <li><a href="../goldshell/XMax#kd-max">KD Max</a></li>
</ul> </ul>
</details> </details>
<details>
<summary>XBox Series:</summary>
<ul>
<li><a href="../goldshell/XBox#kd-box-ii">KD Box II</a></li>
<li><a href="../goldshell/XBox#kd-box-pro">KD Box Pro</a></li>
</ul>
</details>
</ul> </ul>
</details> </details>
<details> <details>
@@ -384,31 +427,43 @@ details {
<details> <details>
<summary>X9 Series:</summary> <summary>X9 Series:</summary>
<ul> <ul>
<li><a href="../antminer/X9#s9-bos">S9 (BOS)</a></li> <li><a href="../antminer/X9#s9-bos_1">S9 (BOS+)</a></li>
</ul> </ul>
</details> </details>
<details> <details>
<summary>X17 Series:</summary> <summary>X17 Series:</summary>
<ul> <ul>
<li><a href="../antminer/X17#s17-bos">S17 (BOS)</a></li> <li><a href="../antminer/X17#s17-bos_1">S17 (BOS+)</a></li>
<li><a href="../antminer/X17#s17_1-bos">S17+ (BOS)</a></li> <li><a href="../antminer/X17#s17_1-bos_1">S17+ (BOS+)</a></li>
<li><a href="../antminer/X17#s17-pro-bos">S17 Pro (BOS)</a></li> <li><a href="../antminer/X17#s17-pro-bos_1">S17 Pro (BOS+)</a></li>
<li><a href="../antminer/X17#s17e-bos">S17e (BOS)</a></li> <li><a href="../antminer/X17#s17e-bos_1">S17e (BOS+)</a></li>
<li><a href="../antminer/X17#t17-bos">T17 (BOS)</a></li> <li><a href="../antminer/X17#t17-bos_1">T17 (BOS+)</a></li>
<li><a href="../antminer/X17#t17_1-bos">T17+ (BOS)</a></li> <li><a href="../antminer/X17#t17_1-bos_1">T17+ (BOS+)</a></li>
<li><a href="../antminer/X17#t17e-bos">T17e (BOS)</a></li> <li><a href="../antminer/X17#t17e-bos_1">T17e (BOS+)</a></li>
</ul> </ul>
</details> </details>
<details> <details>
<summary>X19 Series:</summary> <summary>X19 Series:</summary>
<ul> <ul>
<li><a href="../antminer/X19#s19-bos">S19 (BOS)</a></li> <li><a href="../antminer/X19#s19">S19</a></li>
<li><a href="../antminer/X19#s19-pro-bos">S19 Pro (BOS)</a></li> <li><a href="../antminer/X19#s19_1">S19+</a></li>
<li><a href="../antminer/X19#s19j-bos">S19j (BOS)</a></li> <li><a href="../antminer/X19#s19-pro">S19 Pro</a></li>
<li><a href="../antminer/X19#s19j-no-pic-bos">S19j No PIC (BOS)</a></li> <li><a href="../antminer/X19#s19a">S19a</a></li>
<li><a href="../antminer/X19#s19j-pro-bos">S19j Pro (BOS)</a></li> <li><a href="../antminer/X19#s19a-pro">S19a Pro</a></li>
<li><a href="../antminer/X19#s19j-pro-bos">S19j Pro (BOS)</a></li> <li><a href="../antminer/X19#s19j">S19j</a></li>
<li><a href="../antminer/X19#t19-bos">T19 (BOS)</a></li> <li><a href="../antminer/X19#s19j-no-pic">S19j No PIC</a></li>
<li><a href="../antminer/X19#s19j-pro">S19j Pro</a></li>
<li><a href="../antminer/X19#s19j-pro">S19j Pro</a></li>
<li><a href="../antminer/X19#s19j-pro_1">S19j Pro+</a></li>
<li><a href="../antminer/X19#s19k-pro-no-pic">S19k Pro No PIC</a></li>
<li><a href="../antminer/X19#s19-xp">S19 XP</a></li>
<li><a href="../antminer/X19#t19">T19</a></li>
</ul>
</details>
<details>
<summary>X21 Series:</summary>
<ul>
<li><a href="../antminer/X21#s21">S21</a></li>
</ul> </ul>
</details> </details>
</ul> </ul>
@@ -420,6 +475,13 @@ details {
<summary>X3 Series:</summary> <summary>X3 Series:</summary>
<ul> <ul>
<li><a href="../antminer/X3#l3_1-vnish">L3+ (VNish)</a></li> <li><a href="../antminer/X3#l3_1-vnish">L3+ (VNish)</a></li>
<li><a href="../antminer/X3#l3_1-vnish">L3+ (VNish)</a></li>
</ul>
</details>
<details>
<summary>X7 Series:</summary>
<ul>
<li><a href="../antminer/X7#l7-vnish">L7 (VNish)</a></li>
</ul> </ul>
</details> </details>
<details> <details>
@@ -454,9 +516,23 @@ details {
<li><a href="../antminer/X19#s19-pro-epic">S19 Pro (ePIC)</a></li> <li><a href="../antminer/X19#s19-pro-epic">S19 Pro (ePIC)</a></li>
<li><a href="../antminer/X19#s19j-epic">S19j (ePIC)</a></li> <li><a href="../antminer/X19#s19j-epic">S19j (ePIC)</a></li>
<li><a href="../antminer/X19#s19j-pro-epic">S19j Pro (ePIC)</a></li> <li><a href="../antminer/X19#s19j-pro-epic">S19j Pro (ePIC)</a></li>
<li><a href="../antminer/X19#s19j-pro_1-epic">S19j Pro+ (ePIC)</a></li>
<li><a href="../antminer/X19#s19k-pro-epic">S19k Pro (ePIC)</a></li>
<li><a href="../antminer/X19#s19-xp-epic">S19 XP (ePIC)</a></li> <li><a href="../antminer/X19#s19-xp-epic">S19 XP (ePIC)</a></li>
</ul> </ul>
</details> </details>
<details>
<summary>X21 Series:</summary>
<ul>
<li><a href="../antminer/X21#s21-epic">S21 (ePIC)</a></li>
</ul>
</details>
<details>
<summary>blockminer Series:</summary>
<ul>
<li><a href="../blockminer/blockminer#blockminer-520i-epic">BlockMiner 520i (ePIC)</a></li>
</ul>
</details>
</ul> </ul>
</details> </details>
<details> <details>
@@ -465,7 +541,7 @@ details {
<details> <details>
<summary>X9 Series:</summary> <summary>X9 Series:</summary>
<ul> <ul>
<li><a href="../antminer/X9#t9-hiveon">T9 (Hiveon)</a></li> <li><a href="../antminer/X9#t9-hive">T9 (Hive)</a></li>
</ul> </ul>
</details> </details>
</ul> </ul>
@@ -479,5 +555,50 @@ details {
<li><a href="../antminer/X9#s9-luxos">S9 (LuxOS)</a></li> <li><a href="../antminer/X9#s9-luxos">S9 (LuxOS)</a></li>
</ul> </ul>
</details> </details>
<details>
<summary>X19 Series:</summary>
<ul>
<li><a href="../antminer/X19#s19-luxos">S19 (LuxOS)</a></li>
<li><a href="../antminer/X19#s19-pro-luxos">S19 Pro (LuxOS)</a></li>
<li><a href="../antminer/X19#s19j-pro-luxos">S19j Pro (LuxOS)</a></li>
<li><a href="../antminer/X19#s19j-pro_1-luxos">S19j Pro+ (LuxOS)</a></li>
<li><a href="../antminer/X19#s19k-pro-luxos">S19k Pro (LuxOS)</a></li>
<li><a href="../antminer/X19#s19-xp-luxos">S19 XP (LuxOS)</a></li>
<li><a href="../antminer/X19#t19-luxos">T19 (LuxOS)</a></li>
</ul>
</details>
<details>
<summary>X21 Series:</summary>
<ul>
<li><a href="../antminer/X21#s21-luxos">S21 (LuxOS)</a></li>
</ul>
</details>
</ul>
</details>
<details>
<summary>Stock Firmware Auradine Miners:</summary>
<ul>
<details>
<summary>AD Series:</summary>
<ul>
<li><a href="../auradine/AD#at1500">AT1500</a></li>
<li><a href="../auradine/AD#at2860">AT2860</a></li>
<li><a href="../auradine/AD#at2880">AT2880</a></li>
</ul>
</details>
<details>
<summary>AI Series:</summary>
<ul>
<li><a href="../auradine/AI#ai2500">AI2500</a></li>
<li><a href="../auradine/AI#ai3680">AI3680</a></li>
</ul>
</details>
<details>
<summary>AT Series:</summary>
<ul>
<li><a href="../auradine/AT#ad2500">AD2500</a></li>
<li><a href="../auradine/AT#ad3500">AD3500</a></li>
</ul>
</details>
</ul> </ul>
</details> </details>

View File

@@ -211,6 +211,13 @@
show_root_heading: false show_root_heading: false
heading_level: 4 heading_level: 4
## M53S VJ40
::: pyasic.miners.whatsminer.btminer.M5X.M53S.BTMinerM53SVJ40
handler: python
options:
show_root_heading: false
heading_level: 4
## M53S+ VJ30 ## M53S+ VJ30
::: pyasic.miners.whatsminer.btminer.M5X.M53S_Plus.BTMinerM53SPlusVJ30 ::: pyasic.miners.whatsminer.btminer.M5X.M53S_Plus.BTMinerM53SPlusVJ30
handler: python handler: python
@@ -218,6 +225,13 @@
show_root_heading: false show_root_heading: false
heading_level: 4 heading_level: 4
## M53S++ VK10
::: pyasic.miners.whatsminer.btminer.M5X.M53S_Plus_Plus.BTMinerM53SPlusPlusVK10
handler: python
options:
show_root_heading: false
heading_level: 4
## M56 VH30 ## M56 VH30
::: pyasic.miners.whatsminer.btminer.M5X.M56.BTMinerM56VH30 ::: pyasic.miners.whatsminer.btminer.M5X.M56.BTMinerM56VH30
handler: python handler: python

View File

@@ -0,0 +1,136 @@
# pyasic
## M6X Models
## M60 VK10
::: pyasic.miners.whatsminer.btminer.M6X.M60.BTMinerM60VK10
handler: python
options:
show_root_heading: false
heading_level: 4
## M60 VK20
::: pyasic.miners.whatsminer.btminer.M6X.M60.BTMinerM60VK20
handler: python
options:
show_root_heading: false
heading_level: 4
## M60 VK30
::: pyasic.miners.whatsminer.btminer.M6X.M60.BTMinerM60VK30
handler: python
options:
show_root_heading: false
heading_level: 4
## M60 VK40
::: pyasic.miners.whatsminer.btminer.M6X.M60.BTMinerM60VK40
handler: python
options:
show_root_heading: false
heading_level: 4
## M60S VK10
::: pyasic.miners.whatsminer.btminer.M6X.M60S.BTMinerM60SVK10
handler: python
options:
show_root_heading: false
heading_level: 4
## M60S VK20
::: pyasic.miners.whatsminer.btminer.M6X.M60S.BTMinerM60SVK20
handler: python
options:
show_root_heading: false
heading_level: 4
## M60S VK30
::: pyasic.miners.whatsminer.btminer.M6X.M60S.BTMinerM60SVK30
handler: python
options:
show_root_heading: false
heading_level: 4
## M60S VK40
::: pyasic.miners.whatsminer.btminer.M6X.M60S.BTMinerM60SVK40
handler: python
options:
show_root_heading: false
heading_level: 4
## M63 VK10
::: pyasic.miners.whatsminer.btminer.M6X.M63.BTMinerM63VK10
handler: python
options:
show_root_heading: false
heading_level: 4
## M63 VK20
::: pyasic.miners.whatsminer.btminer.M6X.M63.BTMinerM63VK20
handler: python
options:
show_root_heading: false
heading_level: 4
## M63 VK30
::: pyasic.miners.whatsminer.btminer.M6X.M63.BTMinerM63VK30
handler: python
options:
show_root_heading: false
heading_level: 4
## M63S VK10
::: pyasic.miners.whatsminer.btminer.M6X.M63S.BTMinerM63SVK10
handler: python
options:
show_root_heading: false
heading_level: 4
## M63S VK20
::: pyasic.miners.whatsminer.btminer.M6X.M63S.BTMinerM63SVK20
handler: python
options:
show_root_heading: false
heading_level: 4
## M63S VK30
::: pyasic.miners.whatsminer.btminer.M6X.M63S.BTMinerM63SVK30
handler: python
options:
show_root_heading: false
heading_level: 4
## M66 VK20
::: pyasic.miners.whatsminer.btminer.M6X.M66.BTMinerM66VK20
handler: python
options:
show_root_heading: false
heading_level: 4
## M66 VK30
::: pyasic.miners.whatsminer.btminer.M6X.M66.BTMinerM66VK30
handler: python
options:
show_root_heading: false
heading_level: 4
## M66S VK20
::: pyasic.miners.whatsminer.btminer.M6X.M66S.BTMinerM66SVK20
handler: python
options:
show_root_heading: false
heading_level: 4
## M66S VK30
::: pyasic.miners.whatsminer.btminer.M6X.M66S.BTMinerM66SVK30
handler: python
options:
show_root_heading: false
heading_level: 4
## M66S VK40
::: pyasic.miners.whatsminer.btminer.M6X.M66S.BTMinerM66SVK40
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -12,6 +12,7 @@ Settings options:
- `factory_get_timeout` - `factory_get_timeout`
- `get_data_retries` - `get_data_retries`
- `api_function_timeout` - `api_function_timeout`
- `antminer_mining_mode_as_str`
- `default_whatsminer_password` - `default_whatsminer_password`
- `default_innosilicon_password` - `default_innosilicon_password`
- `default_antminer_password` - `default_antminer_password`

View File

@@ -96,7 +96,7 @@ class FanModeManual(MinerConfigValue):
return cls(**cls_conf) return cls(**cls_conf)
def as_am_modern(self) -> dict: def as_am_modern(self) -> dict:
return {"bitmain-fan-ctrl": True, "bitmain-fan-pwn": str(self.speed)} return {"bitmain-fan-ctrl": True, "bitmain-fan-pwm": str(self.speed)}
def as_bosminer(self) -> dict: def as_bosminer(self) -> dict:
return { return {
@@ -120,7 +120,7 @@ class FanModeImmersion(MinerConfigValue):
return cls() return cls()
def as_am_modern(self) -> dict: def as_am_modern(self) -> dict:
return {"bitmain-fan-ctrl": True, "bitmain-fan-pwn": "0"} return {"bitmain-fan-ctrl": True, "bitmain-fan-pwm": "0"}
def as_bosminer(self) -> dict: def as_bosminer(self) -> dict:
return {"temp_control": {"mode": "disabled"}} return {"temp_control": {"mode": "disabled"}}
@@ -156,7 +156,10 @@ class FanModeConfig(MinerConfigOption):
if web_conf.get("bitmain-fan-ctrl") is not None: if web_conf.get("bitmain-fan-ctrl") is not None:
fan_manual = web_conf["bitmain-fan-ctrl"] fan_manual = web_conf["bitmain-fan-ctrl"]
if fan_manual: if fan_manual:
return cls.manual(speed=web_conf["bitmain-fan-pwm"]) speed = int(web_conf["bitmain-fan-pwm"])
if speed == 0:
return cls.immersion()
return cls.manual(speed=speed)
else: else:
return cls.normal() return cls.normal()
else: else:

View File

@@ -17,6 +17,7 @@ from __future__ import annotations
from dataclasses import dataclass, field from dataclasses import dataclass, field
from pyasic import settings
from pyasic.config.base import MinerConfigOption, MinerConfigValue from pyasic.config.base import MinerConfigOption, MinerConfigValue
from pyasic.web.braiins_os.proto.braiins.bos.v1 import ( from pyasic.web.braiins_os.proto.braiins.bos.v1 import (
HashrateTargetMode, HashrateTargetMode,
@@ -39,7 +40,9 @@ class MiningModeNormal(MinerConfigValue):
return cls() return cls()
def as_am_modern(self) -> dict: def as_am_modern(self) -> dict:
return {"miner-mode": "0"} if settings.get("antminer_mining_mode_as_str", False):
return {"miner-mode": "0"}
return {"miner-mode": 0}
def as_wm(self) -> dict: def as_wm(self) -> dict:
return {"mode": self.mode} return {"mode": self.mode}
@@ -63,7 +66,9 @@ class MiningModeSleep(MinerConfigValue):
return cls() return cls()
def as_am_modern(self) -> dict: def as_am_modern(self) -> dict:
return {"miner-mode": "1"} if settings.get("antminer_mining_mode_as_str", False):
return {"miner-mode": "1"}
return {"miner-mode": 1}
def as_wm(self) -> dict: def as_wm(self) -> dict:
return {"mode": self.mode} return {"mode": self.mode}
@@ -87,7 +92,9 @@ class MiningModeLPM(MinerConfigValue):
return cls() return cls()
def as_am_modern(self) -> dict: def as_am_modern(self) -> dict:
return {"miner-mode": "3"} if settings.get("antminer_mining_mode_as_str", False):
return {"miner-mode": "3"}
return {"miner-mode": 3}
def as_wm(self) -> dict: def as_wm(self) -> dict:
return {"mode": self.mode} return {"mode": self.mode}
@@ -108,7 +115,9 @@ class MiningModeHPM(MinerConfigValue):
return cls() return cls()
def as_am_modern(self) -> dict: def as_am_modern(self) -> dict:
return {"miner-mode": "0"} if settings.get("antminer_mining_mode_as_str", False):
return {"miner-mode": "0"}
return {"miner-mode": 0}
def as_wm(self) -> dict: def as_wm(self) -> dict:
return {"mode": self.mode} return {"mode": self.mode}
@@ -165,7 +174,9 @@ class MiningModePowerTune(MinerConfigValue):
return cls(**cls_conf) return cls(**cls_conf)
def as_am_modern(self) -> dict: def as_am_modern(self) -> dict:
return {"miner-mode": "0"} if settings.get("antminer_mining_mode_as_str", False):
return {"miner-mode": "0"}
return {"miner-mode": 0}
def as_wm(self) -> dict: def as_wm(self) -> dict:
if self.power is not None: if self.power is not None:
@@ -173,7 +184,10 @@ class MiningModePowerTune(MinerConfigValue):
return {} return {}
def as_bosminer(self) -> dict: def as_bosminer(self) -> dict:
return {"autotuning": {"enabled": True, "psu_power_limit": self.power}} conf = {"enabled": True, "mode": "power_target"}
if self.power is not None:
conf["power_target"] = self.power
return {"autotuning": conf}
def as_boser(self) -> dict: def as_boser(self) -> dict:
return { return {
@@ -204,7 +218,15 @@ class MiningModeHashrateTune(MinerConfigValue):
return cls(dict_conf.get("hashrate")) return cls(dict_conf.get("hashrate"))
def as_am_modern(self) -> dict: def as_am_modern(self) -> dict:
return {"miner-mode": "0"} if settings.get("antminer_mining_mode_as_str", False):
return {"miner-mode": "0"}
return {"miner-mode": 0}
def as_bosminer(self) -> dict:
conf = {"enabled": True, "mode": "hashrate_target"}
if self.hashrate is not None:
conf["hashrate_target"] = self.hashrate
return {"autotuning": conf}
def as_boser(self) -> dict: def as_boser(self) -> dict:
return { return {
@@ -239,7 +261,9 @@ class ManualBoardSettings(MinerConfigValue):
return cls(freq=dict_conf["freq"], volt=dict_conf["volt"]) return cls(freq=dict_conf["freq"], volt=dict_conf["volt"])
def as_am_modern(self) -> dict: def as_am_modern(self) -> dict:
return {"miner-mode": "0"} if settings.get("antminer_mining_mode_as_str", False):
return {"miner-mode": "0"}
return {"miner-mode": 0}
@dataclass @dataclass
@@ -259,7 +283,9 @@ class MiningModeManual(MinerConfigValue):
) )
def as_am_modern(self) -> dict: def as_am_modern(self) -> dict:
return {"miner-mode": "0"} if settings.get("antminer_mining_mode_as_str", False):
return {"miner-mode": "0"}
return {"miner-mode": 0}
@classmethod @classmethod
def from_vnish(cls, web_overclock_settings: dict) -> "MiningModeManual": def from_vnish(cls, web_overclock_settings: dict) -> "MiningModeManual":

View File

@@ -114,6 +114,8 @@ class PowerScalingEnabled(MinerConfigValue):
def from_bosminer(cls, power_scaling_conf: dict) -> "PowerScalingEnabled": def from_bosminer(cls, power_scaling_conf: dict) -> "PowerScalingEnabled":
power_step = power_scaling_conf.get("power_step") power_step = power_scaling_conf.get("power_step")
min_power = power_scaling_conf.get("min_psu_power_limit") min_power = power_scaling_conf.get("min_psu_power_limit")
if min_power is None:
min_power = power_scaling_conf.get("min_power_target")
sd_mode = PowerScalingShutdown.from_bosminer(power_scaling_conf) sd_mode = PowerScalingShutdown.from_bosminer(power_scaling_conf)
return cls( return cls(
@@ -138,12 +140,12 @@ class PowerScalingEnabled(MinerConfigValue):
if self.power_step is not None: if self.power_step is not None:
cfg["power_step"] = self.power_step cfg["power_step"] = self.power_step
if self.minimum_power is not None: if self.minimum_power is not None:
cfg["min_psu_power_limit"] = self.minimum_power cfg["min_power_target"] = self.minimum_power
if self.shutdown_enabled is not None: if self.shutdown_enabled is not None:
cfg = {**cfg, **self.shutdown_enabled.as_bosminer()} cfg = {**cfg, **self.shutdown_enabled.as_bosminer()}
return {"power_scaling": cfg} return {"performance_scaling": cfg}
def as_boser(self) -> dict: def as_boser(self) -> dict:
return { return {
@@ -189,6 +191,8 @@ class PowerScalingConfig(MinerConfigOption):
@classmethod @classmethod
def from_bosminer(cls, toml_conf: dict): def from_bosminer(cls, toml_conf: dict):
power_scaling = toml_conf.get("power_scaling") power_scaling = toml_conf.get("power_scaling")
if power_scaling is None:
power_scaling = toml_conf.get("performance_scaling")
if power_scaling is not None: if power_scaling is not None:
enabled = power_scaling.get("enabled") enabled = power_scaling.get("enabled")
if enabled is not None: if enabled is not None:

View File

@@ -94,9 +94,7 @@ class MinerData:
percent_expected_wattage: float = field(init=False) percent_expected_wattage: float = field(init=False)
nominal: bool = field(init=False) nominal: bool = field(init=False)
config: MinerConfig = None config: MinerConfig = None
errors: List[ errors: List[Union[WhatsminerError, BraiinsOSError, X19Error, InnosiliconError]] = field(default_factory=list)
Union[WhatsminerError, BraiinsOSError, X19Error, InnosiliconError]
] = field(default_factory=list)
fault_light: Union[bool, None] = None fault_light: Union[bool, None] = None
efficiency: int = field(init=False) efficiency: int = field(init=False)
is_mining: bool = True is_mining: bool = True

View File

@@ -21,6 +21,7 @@ from pyasic.miners.models import (
S19XP, S19XP,
S19a, S19a,
S19aPro, S19aPro,
S19Hydro,
S19i, S19i,
S19j, S19j,
S19jNoPIC, S19jNoPIC,
@@ -29,6 +30,8 @@ from pyasic.miners.models import (
S19Pro, S19Pro,
S19ProHydro, S19ProHydro,
S19ProPlus, S19ProPlus,
S19ProPlusHydro,
S19KPro,
) )
@@ -82,3 +85,15 @@ class BMMinerS19L(AntminerModern, S19L):
class BMMinerS19ProHydro(AntminerModern, S19ProHydro): class BMMinerS19ProHydro(AntminerModern, S19ProHydro):
pass pass
class BMMinerS19Hydro(AntminerModern, S19Hydro):
pass
class BMMinerS19ProPlusHydro(AntminerModern, S19ProPlusHydro):
pass
class BMMinerS19KPro(AntminerModern, S19KPro):
pass

View File

@@ -18,6 +18,7 @@ from .S19 import (
BMMinerS19, BMMinerS19,
BMMinerS19a, BMMinerS19a,
BMMinerS19aPro, BMMinerS19aPro,
BMMinerS19Hydro,
BMMinerS19i, BMMinerS19i,
BMMinerS19j, BMMinerS19j,
BMMinerS19jNoPIC, BMMinerS19jNoPIC,
@@ -27,6 +28,8 @@ from .S19 import (
BMMinerS19Pro, BMMinerS19Pro,
BMMinerS19ProHydro, BMMinerS19ProHydro,
BMMinerS19ProPlus, BMMinerS19ProPlus,
BMMinerS19ProPlusHydro,
BMMinerS19XP, BMMinerS19XP,
BMMinerS19KPro,
) )
from .T19 import BMMinerT19 from .T19 import BMMinerT19

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 AntminerModern
from pyasic.miners.models import S21
class BMMinerS21(AntminerModern, S21):
pass

View File

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

View File

@@ -18,3 +18,4 @@ from .X7 import *
from .X9 import * from .X9 import *
from .X17 import * from .X17 import *
from .X19 import * from .X19 import *
from .X21 import *

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 BOSer
from pyasic.miners.models import S21
class BOSMinerS21(BOSer, S21):
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 .S21 import BOSMinerS21

View File

@@ -17,3 +17,4 @@
from .X9 import * from .X9 import *
from .X17 import * from .X17 import *
from .X19 import * from .X19 import *
from .X21 import *

View File

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

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 LUXMiner
from pyasic.miners.models import T19
class LUXMinerT19(LUXMiner, T19):
pass

View File

@@ -0,0 +1,25 @@
# ------------------------------------------------------------------------------
# Copyright 2022 Upstream Data Inc -
# -
# Licensed under the Apache License, Version 2.0 (the "License"); -
# you may not use this file except in compliance with the License. -
# You may obtain a copy of the License at -
# -
# http://www.apache.org/licenses/LICENSE-2.0 -
# -
# Unless required by applicable law or agreed to in writing, software -
# distributed under the License is distributed on an "AS IS" BASIS, -
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
# See the License for the specific language governing permissions and -
# limitations under the License. -
# ------------------------------------------------------------------------------
from .S19 import (
LUXMinerS19,
LUXMinerS19jPro,
LUXMinerS19jProPlus,
LUXMinerS19kPro,
LUXMinerS19Pro,
LUXMinerS19XP,
)
from .T19 import LUXMinerT19

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 LUXMiner
from pyasic.miners.models import S21
class LUXMinerS21(LUXMiner, S21):
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 .S21 import LUXMinerS21

View File

@@ -15,3 +15,5 @@
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
from .X9 import * from .X9 import *
from .X19 import *
from .X21 import *

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.models import L7
class VnishL7(VNish, L7):
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 .L7 import VnishL7

View File

@@ -15,5 +15,6 @@
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
from .X3 import * from .X3 import *
from .X7 import *
from .X17 import * from .X17 import *
from .X19 import * from .X19 import *

View File

@@ -22,6 +22,7 @@ from pyasic.data.error_codes import MinerErrorData, X19Error
from pyasic.errors import APIError from pyasic.errors import APIError
from pyasic.miners.backends.bmminer import BMMiner from pyasic.miners.backends.bmminer import BMMiner
from pyasic.miners.backends.cgminer import CGMiner from pyasic.miners.backends.cgminer import CGMiner
from pyasic.miners.base import BaseMiner
from pyasic.miners.data import ( from pyasic.miners.data import (
DataFunction, DataFunction,
DataLocations, DataLocations,
@@ -29,6 +30,7 @@ from pyasic.miners.data import (
RPCAPICommand, RPCAPICommand,
WebAPICommand, WebAPICommand,
) )
from pyasic.rpc.antminer import AntminerRPCAPI
from pyasic.ssh.antminer import AntminerModernSSH from pyasic.ssh.antminer import AntminerModernSSH
from pyasic.web.antminer import AntminerModernWebAPI, AntminerOldWebAPI from pyasic.web.antminer import AntminerModernWebAPI, AntminerOldWebAPI
@@ -88,6 +90,9 @@ class AntminerModern(BMMiner):
_web_cls = AntminerModernWebAPI _web_cls = AntminerModernWebAPI
web: AntminerModernWebAPI web: AntminerModernWebAPI
_rpc_cls = AntminerRPCAPI
web: AntminerRPCAPI
_ssh_cls = AntminerModernSSH _ssh_cls = AntminerModernSSH
ssh: AntminerModernSSH ssh: AntminerModernSSH
@@ -207,7 +212,7 @@ class AntminerModern(BMMiner):
] ]
try: try:
rpc_stats = await self.rpc.send_command("stats", new_api=True) rpc_stats = await self.rpc.stats(new_api=True)
except APIError: except APIError:
return hashboards return hashboards

View File

@@ -35,6 +35,7 @@ from pyasic.miners.data import (
from pyasic.rpc.bosminer import BOSMinerRPCAPI from pyasic.rpc.bosminer import BOSMinerRPCAPI
from pyasic.ssh.braiins_os import BOSMinerSSH from pyasic.ssh.braiins_os import BOSMinerSSH
from pyasic.web.braiins_os import BOSerWebAPI, BOSMinerWebAPI from pyasic.web.braiins_os import BOSerWebAPI, BOSMinerWebAPI
from pyasic.web.braiins_os.proto.braiins.bos.v1 import SaveAction
BOSMINER_DATA_LOC = DataLocations( BOSMINER_DATA_LOC = DataLocations(
**{ **{
@@ -180,16 +181,17 @@ class BOSMiner(BaseMiner):
async def send_config(self, config: MinerConfig, user_suffix: str = None) -> None: async def send_config(self, config: MinerConfig, user_suffix: str = None) -> None:
self.config = config self.config = config
parsed_cfg = config.as_bosminer(user_suffix=user_suffix)
toml_conf = toml.dumps( toml_conf = toml.dumps(
{ {
"format": { "format": {
"version": "1.2+", "version": "2.0",
"generator": "pyasic", "generator": "pyasic",
"model": f"{self.make.replace('Miner', 'miner')} {self.raw_model.replace('j', 'J')}", "model": f"{self.make.replace('Miner', 'miner')} {self.raw_model.replace('j', 'J')}",
"timestamp": int(time.time()), "timestamp": int(time.time()),
}, },
**config.as_bosminer(user_suffix=user_suffix), **parsed_cfg,
} }
) )
try: try:
@@ -691,7 +693,9 @@ class BOSer(BaseMiner):
async def set_power_limit(self, wattage: int) -> bool: async def set_power_limit(self, wattage: int) -> bool:
try: try:
result = await self.web.set_power_target(wattage) result = await self.web.set_power_target(
wattage, save_action=SaveAction.SAVE_ACTION_SAVE_AND_FORCE_APPLY
)
except APIError: except APIError:
return False return False

View File

@@ -74,6 +74,10 @@ VNISH_DATA_LOC = DataLocations(
"_get_uptime", "_get_uptime",
[RPCAPICommand("rpc_stats", "stats")], [RPCAPICommand("rpc_stats", "stats")],
), ),
str(DataOptions.IS_MINING): DataFunction(
"_is_mining",
[WebAPICommand("web_summary", "summary")],
),
} }
) )
@@ -84,6 +88,8 @@ class VNish(BMMiner):
_web_cls = VNishWebAPI _web_cls = VNishWebAPI
web: VNishWebAPI web: VNishWebAPI
supports_shutdown = True
firmware = "VNish" firmware = "VNish"
data_locations = VNISH_DATA_LOC data_locations = VNISH_DATA_LOC
@@ -125,16 +131,6 @@ class VNish(BMMiner):
return False return False
async def _get_mac(self, web_summary: dict = None) -> str: async def _get_mac(self, web_summary: dict = None) -> str:
if web_summary is None:
web_info = await self.web.info()
if web_info is not None:
try:
mac = web_info["system"]["network_status"]["mac"]
return mac
except KeyError:
pass
if web_summary is not None: if web_summary is not None:
try: try:
mac = web_summary["system"]["network_status"]["mac"] mac = web_summary["system"]["network_status"]["mac"]
@@ -142,6 +138,15 @@ class VNish(BMMiner):
except KeyError: except KeyError:
pass pass
web_info = await self.web.info()
if web_info is not None:
try:
mac = web_info["system"]["network_status"]["mac"]
return mac
except KeyError:
pass
async def _get_hostname(self, web_summary: dict = None) -> str: async def _get_hostname(self, web_summary: dict = None) -> str:
if web_summary is None: if web_summary is None:
web_info = await self.web.info() web_info = await self.web.info()
@@ -214,6 +219,20 @@ class VNish(BMMiner):
except LookupError: except LookupError:
return fw_ver return fw_ver
async def _is_mining(self, web_summary: dict = None) -> Optional[bool]:
if web_summary is None:
web_summary = await self.web.summary()
if web_summary is not None:
try:
is_mining = not web_summary["miner"]["miner_status"]["miner_state"] in [
"stopped",
"shutting-down",
]
return is_mining
except LookupError:
pass
async def get_config(self) -> MinerConfig: async def get_config(self) -> MinerConfig:
try: try:
web_settings = await self.web.settings() web_settings = await self.web.settings()

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 .epic import *

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 .blockminer import *

View File

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

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 ePIC
from pyasic.miners.models import BlockMiner520i
class ePICBlockMiner520i(ePIC, BlockMiner520i):
pass

View File

@@ -45,6 +45,7 @@ from pyasic.miners.backends import (
) )
from pyasic.miners.backends.unknown import UnknownMiner from pyasic.miners.backends.unknown import UnknownMiner
from pyasic.miners.base import AnyMiner from pyasic.miners.base import AnyMiner
from pyasic.miners.blockminer import *
from pyasic.miners.goldshell import * from pyasic.miners.goldshell import *
from pyasic.miners.innosilicon import * from pyasic.miners.innosilicon import *
from pyasic.miners.makes import * from pyasic.miners.makes import *
@@ -98,8 +99,12 @@ MINER_CLASSES = {
"ANTMINER S19 XP": BMMinerS19XP, "ANTMINER S19 XP": BMMinerS19XP,
"ANTMINER S19A": BMMinerS19a, "ANTMINER S19A": BMMinerS19a,
"ANTMINER S19A PRO": BMMinerS19aPro, "ANTMINER S19A PRO": BMMinerS19aPro,
"ANTMINER S19 HYDRO": BMMinerS19Hydro,
"ANTMINER S19 PRO HYD.": BMMinerS19ProHydro, "ANTMINER S19 PRO HYD.": BMMinerS19ProHydro,
"ANTMINER S19 PRO+ HYD.": BMMinerS19ProPlusHydro,
"ANTMINER S19K PRO": BMMinerS19KPro,
"ANTMINER T19": BMMinerT19, "ANTMINER T19": BMMinerT19,
"ANTMINER S21": BMMinerS21,
}, },
MinerTypes.WHATSMINER: { MinerTypes.WHATSMINER: {
None: type("WhatsminerUnknown", (BTMiner, WhatsMinerMake), {}), None: type("WhatsminerUnknown", (BTMiner, WhatsMinerMake), {}),
@@ -367,12 +372,15 @@ MINER_CLASSES = {
"ANTMINER S19J PRO NOPIC": BOSMinerS19jPro, "ANTMINER S19J PRO NOPIC": BOSMinerS19jPro,
"ANTMINER S19J PRO+": BOSMinerS19jProPlus, "ANTMINER S19J PRO+": BOSMinerS19jProPlus,
"ANTMINER S19K PRO NOPIC": BOSMinerS19kProNoPIC, "ANTMINER S19K PRO NOPIC": BOSMinerS19kProNoPIC,
"ANTMINER S19XP": BOSMinerS19XP, "ANTMINER S19 XP": BOSMinerS19XP,
"ANTMINER T19": BOSMinerT19, "ANTMINER T19": BOSMinerT19,
"ANTMINER S21": BOSMinerS21,
}, },
MinerTypes.VNISH: { MinerTypes.VNISH: {
None: VNish, None: VNish,
"L3+": VnishL3Plus,
"ANTMINER L3+": VnishL3Plus, "ANTMINER L3+": VnishL3Plus,
"ANTMINER L7": VnishL7,
"ANTMINER S17+": VNishS17Plus, "ANTMINER S17+": VNishS17Plus,
"ANTMINER S17 PRO": VNishS17Pro, "ANTMINER S17 PRO": VNishS17Pro,
"ANTMINER S19": VNishS19, "ANTMINER S19": VNishS19,
@@ -394,6 +402,7 @@ MINER_CLASSES = {
"ANTMINER S19K PRO": ePICS19kPro, "ANTMINER S19K PRO": ePICS19kPro,
"ANTMINER S19 XP": ePICS19XP, "ANTMINER S19 XP": ePICS19XP,
"ANTMINER S21": ePICS21, "ANTMINER S21": ePICS21,
"BLOCKMINER 520I": ePICBlockMiner520i,
}, },
MinerTypes.HIVEON: { MinerTypes.HIVEON: {
None: Hiveon, None: Hiveon,
@@ -402,6 +411,14 @@ MINER_CLASSES = {
MinerTypes.LUX_OS: { MinerTypes.LUX_OS: {
None: LUXMiner, None: LUXMiner,
"ANTMINER S9": LUXMinerS9, "ANTMINER S9": LUXMinerS9,
"ANTMINER S19": LUXMinerS19,
"ANTMINER S19 PRO": LUXMinerS19Pro,
"ANTMINER S19J PRO": LUXMinerS19jPro,
"ANTMINER S19J PRO+": LUXMinerS19jProPlus,
"ANTMINER S19K PRO": LUXMinerS19kPro,
"ANTMINER S19 XP": LUXMinerS19XP,
"ANTMINER T19": LUXMinerT19,
"ANTMINER S21": LUXMinerS21,
}, },
MinerTypes.AURADINE: { MinerTypes.AURADINE: {
None: type("GoldshellUnknown", (Auradine, AuradineMake), {}), None: type("GoldshellUnknown", (Auradine, AuradineMake), {}),
@@ -899,10 +916,11 @@ class MinerFactory:
async def get_miner_model_braiins_os(self, ip: str) -> str | None: async def get_miner_model_braiins_os(self, ip: str) -> str | None:
sock_json_data = await self.send_api_command(ip, "devdetails") sock_json_data = await self.send_api_command(ip, "devdetails")
try: try:
miner_model = sock_json_data["DEVDETAILS"][0]["Model"].replace( miner_model = (
"Bitmain ", "" sock_json_data["DEVDETAILS"][0]["Model"]
.replace("Bitmain ", "")
.replace("S19XP", "S19 XP")
) )
return miner_model return miner_model
except (TypeError, LookupError): except (TypeError, LookupError):
pass pass
@@ -915,7 +933,9 @@ class MinerFactory:
) )
if d.status_code == 200: if d.status_code == 200:
json_data = d.json() json_data = d.json()
miner_model = json_data["data"]["bosminer"]["info"]["modelName"] miner_model = json_data["data"]["bosminer"]["info"][
"modelName"
].replace("S19XP", "S19 XP")
return miner_model return miner_model
except (httpx.HTTPError, LookupError): except (httpx.HTTPError, LookupError):
pass pass
@@ -939,12 +959,16 @@ class MinerFactory:
pass pass
async def get_miner_model_epic(self, ip: str) -> str | None: async def get_miner_model_epic(self, ip: str) -> str | None:
sock_json_data = await self.send_web_command(ip, ":4028/capabilities") for retry_cnt in range(settings.get("get_data_retries", 1)):
try: sock_json_data = await self.send_web_command(ip, ":4028/capabilities")
miner_model = sock_json_data["Model"] try:
return miner_model miner_model = sock_json_data["Model"]
except (TypeError, LookupError): return miner_model
pass except (TypeError, LookupError):
if retry_cnt < settings.get("get_data_retries", 1) - 1:
continue
else:
pass
async def get_miner_model_hiveon(self, ip: str) -> str | None: async def get_miner_model_hiveon(self, ip: str) -> str | None:
sock_json_data = await self.send_api_command(ip, "version") sock_json_data = await self.send_api_command(ip, "version")

View File

@@ -39,3 +39,7 @@ class GoldshellMake(BaseMiner):
class AuradineMake(BaseMiner): class AuradineMake(BaseMiner):
make = "Auradine" make = "Auradine"
class ePICMake(BaseMiner):
make = "ePIC"

View File

@@ -20,3 +20,4 @@ from .avalonminer import *
from .goldshell import * from .goldshell import *
from .innosilicon import * from .innosilicon import *
from .whatsminer import * from .whatsminer import *
from .epic import *

View File

@@ -113,8 +113,28 @@ class S19kProNoPIC(AntMinerMake):
expected_fans = 4 expected_fans = 4
class S19Hydro(AntMinerMake):
raw_model = "S19 Hydro"
expected_chips = 104
expected_hashboards = 4
expected_fans = 0
class S19ProHydro(AntMinerMake): class S19ProHydro(AntMinerMake):
raw_model = "S19 Pro Hydro" raw_model = "S19 Pro Hydro"
expected_chips = 180 expected_chips = 180
expected_hashboards = 4 expected_hashboards = 4
expected_fans = 0 expected_fans = 0
class S19ProPlusHydro(AntMinerMake):
raw_model = "S19 Pro+ Hydro"
expected_chips = 180
expected_hashboards = 4
expected_fans = 0
class S19KPro(AntMinerMake):
raw_model = "S19K Pro"
expected_chips = 77
expected_fans = 4

View File

@@ -20,6 +20,7 @@ from .S19 import (
S19XP, S19XP,
S19a, S19a,
S19aPro, S19aPro,
S19Hydro,
S19i, S19i,
S19j, S19j,
S19jNoPIC, S19jNoPIC,
@@ -32,5 +33,7 @@ from .S19 import (
S19Pro, S19Pro,
S19ProHydro, S19ProHydro,
S19ProPlus, S19ProPlus,
S19ProPlusHydro,
S19KPro,
) )
from .T19 import T19 from .T19 import T19

View File

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

View File

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

View File

@@ -0,0 +1,7 @@
from pyasic.miners.makes import ePICMake
class BlockMiner520i(ePICMake):
raw_model = "BlockMiner 520i"
expected_chips = 124
expected_fans = 4

36
pyasic/rpc/antminer.py Normal file
View File

@@ -0,0 +1,36 @@
from pyasic.rpc.bmminer import BMMinerRPCAPI
class AntminerRPCAPI(BMMinerRPCAPI):
async def stats(self, new_api: bool = False) -> dict:
if new_api:
return await self.send_command("stats", new_api=True)
return await super().stats()
async def rate(self):
return await self.send_command("rate", new_api=True)
async def pools(self, new_api: bool = False):
if new_api:
return await self.send_command("pools", new_api=True)
return await self.send_command("pools")
async def reload(self):
return await self.send_command("reload", new_api=True)
async def summary(self, new_api: bool = False):
if new_api:
return await self.send_command("summary", new_api=True)
return await self.send_command("summary")
async def warning(self):
return await self.send_command("warning", new_api=True)
async def new_api_pools(self):
return await self.pools(new_api=True)
async def new_api_stats(self):
return await self.stats(new_api=True)
async def new_api_summary(self):
return await self.summary(new_api=True)

View File

@@ -196,6 +196,7 @@ If you are sure you want to use this command please use API.send_command("{comma
async def _send_bytes( async def _send_bytes(
self, self,
data: bytes, data: bytes,
*,
port: int = None, port: int = None,
timeout: int = 100, timeout: int = 100,
) -> bytes: ) -> bytes:

View File

@@ -276,7 +276,7 @@ class BTMinerRPCAPI(BaseMinerRPCAPI):
logging.debug(f"{self} - (Send Privileged Command) - Sending") logging.debug(f"{self} - (Send Privileged Command) - Sending")
try: try:
data = await self._send_bytes(enc_command, timeout) data = await self._send_bytes(enc_command, timeout=timeout)
except (asyncio.CancelledError, asyncio.TimeoutError): except (asyncio.CancelledError, asyncio.TimeoutError):
if ignore_errors: if ignore_errors:
return {} return {}

View File

@@ -28,6 +28,7 @@ _settings = { # defaults
"factory_get_timeout": 3, "factory_get_timeout": 3,
"get_data_retries": 1, "get_data_retries": 1,
"api_function_timeout": 5, "api_function_timeout": 5,
"antminer_mining_mode_as_str": False,
"default_whatsminer_rpc_password": "admin", "default_whatsminer_rpc_password": "admin",
"default_innosilicon_web_password": "admin", "default_innosilicon_web_password": "admin",
"default_antminer_web_password": "root", "default_antminer_web_password": "root",
@@ -45,7 +46,9 @@ _settings = { # defaults
ssl_cxt = httpx.create_ssl_context() ssl_cxt = httpx.create_ssl_context()
#this function configures socket options like SO_LINGER and returns an AsyncHTTPTransport instance to perform asynchronous HTTP requests
#using those options.
#SO_LINGER controls what happens when you close a socket with unsent data - it allows specifying linger time for the data to be sent.
def transport(verify: Union[str, bool, SSLContext] = ssl_cxt): def transport(verify: Union[str, bool, SSLContext] = ssl_cxt):
l_onoff = 1 l_onoff = 1
l_linger = get("so_linger_time", 1000) l_linger = get("so_linger_time", 1000)

View File

@@ -44,37 +44,40 @@ class ePICWebAPI(BaseWebAPI):
post = privileged or not parameters == {} post = privileged or not parameters == {}
async with httpx.AsyncClient(transport=settings.transport()) as client: async with httpx.AsyncClient(transport=settings.transport()) as client:
try: for retry_cnt in range(settings.get("get_data_retries", 1)):
if post: try:
response = await client.post( if post:
f"http://{self.ip}:{self.port}/{command}", response = await client.post(
timeout=5, f"http://{self.ip}:{self.port}/{command}",
json={ timeout=5,
**parameters, json={
"password": self.pwd, **parameters,
}, "password": self.pwd,
) },
else:
response = await client.get(
f"http://{self.ip}:{self.port}/{command}",
timeout=5,
)
if not response.status_code == 200:
if not ignore_errors:
raise APIError(
f"Web command {command} failed with status code {response.status_code}"
) )
return {} else:
json_data = response.json() response = await client.get(
if json_data: f"http://{self.ip}:{self.port}/{command}",
# The API can return a fail status if the miner cannot return the requested data. Catch this and pass timeout=5,
if not json_data.get("result", True) and not post: )
if not response.status_code == 200:
if not ignore_errors: if not ignore_errors:
raise APIError(json_data["error"]) raise APIError(
return json_data f"Web command {command} failed with status code {response.status_code}"
return {"success": True} )
except (httpx.HTTPError, json.JSONDecodeError, AttributeError): return {}
pass json_data = response.json()
if json_data:
# The API can return a fail status if the miner cannot return the requested data. Catch this and pass
if not json_data.get("result", True) and not post:
if retry_cnt < settings.get("get_data_retries", 1) - 1:
continue
if not ignore_errors:
raise APIError(json_data["error"])
return json_data
return {"success": True}
except (httpx.HTTPError, json.JSONDecodeError, AttributeError):
pass
async def multicommand( async def multicommand(
self, *commands: str, ignore_errors: bool = False, allow_warning: bool = True self, *commands: str, ignore_errors: bool = False, allow_warning: bool = True

View File

@@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "pyasic" name = "pyasic"
version = "0.53.1" version = "0.54.14"
description = "A simplified and standardized interface for Bitcoin ASICs." description = "A simplified and standardized interface for Bitcoin ASICs."
authors = ["UpstreamData <brett@upstreamdata.ca>"] authors = ["UpstreamData <brett@upstreamdata.ca>"]
repository = "https://github.com/UpstreamData/pyasic" repository = "https://github.com/UpstreamData/pyasic"
@@ -9,7 +9,7 @@ readme = "README.md"
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = "^3.8" python = "^3.8"
httpx = "^0.26.0" httpx = ">=0.26.0"
asyncssh = "^2.14.2" asyncssh = "^2.14.2"
passlib = "^1.7.4" passlib = "^1.7.4"
pyaml = "^23.12.0" pyaml = "^23.12.0"

View File

@@ -14,7 +14,7 @@
# limitations under the License. - # limitations under the License. -
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
from tests.api_tests import * from tests.rpc_tests import *
from tests.config_tests import TestConfig from tests.config_tests import TestConfig
from tests.miners_tests import MinersTest from tests.miners_tests import MinersTest
from tests.network_tests import NetworkTest from tests.network_tests import NetworkTest

View File

@@ -98,7 +98,11 @@ class TestConfig(unittest.TestCase):
"dangerous_temp": 120, "dangerous_temp": 120,
}, },
"fan_control": {"min_fans": 2, "speed": 90}, "fan_control": {"min_fans": 2, "speed": 90},
"autotuning": {"enabled": True, "psu_power_limit": 3000}, "autotuning": {
"enabled": True,
"mode": "power_target",
"power_target": 3000,
},
"group": [ "group": [
{ {
"name": "W91Q1L", "name": "W91Q1L",
@@ -112,10 +116,10 @@ class TestConfig(unittest.TestCase):
"quota": 1, "quota": 1,
} }
], ],
"power_scaling": { "performance_scaling": {
"enabled": True, "enabled": True,
"power_step": 100, "power_step": 100,
"min_psu_power_limit": 2000, "min_power_target": 2000,
"shutdown_enabled": True, "shutdown_enabled": True,
"shutdown_duration": 3, "shutdown_duration": 3,
}, },
@@ -128,9 +132,9 @@ class TestConfig(unittest.TestCase):
def test_am_modern_serialize(self): def test_am_modern_serialize(self):
correct_config = { correct_config = {
"bitmain-fan-ctrl": True, "bitmain-fan-ctrl": True,
"bitmain-fan-pwn": "90", "bitmain-fan-pwm": "90",
"freq-level": "100", "freq-level": "100",
"miner-mode": "0", "miner-mode": 0,
"pools": [ "pools": [
{ {
"url": "stratum+tcp://stratum.test.io:3333", "url": "stratum+tcp://stratum.test.io:3333",

View File

@@ -0,0 +1,35 @@
import unittest
from pyasic.config import FanModeConfig
class TestFanConfig(unittest.TestCase):
def test_serialize_and_deserialize(self):
for fan_mode in FanModeConfig:
with self.subTest(
msg=f"Test serialization and deserialization of fan config",
fan_mode=fan_mode,
):
conf = fan_mode()
dict_conf = conf.as_dict()
self.assertEqual(conf, FanModeConfig.from_dict(dict_conf))
def test_bosminer_deserialize_and_serialize(self):
for fan_mode in FanModeConfig:
with self.subTest(
msg=f"Test serialization and deserialization of bosminer fan config",
fan_mode=fan_mode,
):
conf = fan_mode()
bos_conf = conf.as_bosminer()
self.assertEqual(conf, FanModeConfig.from_bosminer(bos_conf))
def test_am_modern_deserialize_and_serialize(self):
for fan_mode in FanModeConfig:
with self.subTest(
msg=f"Test serialization and deserialization of antminer modern fan config",
fan_mode=fan_mode,
):
conf = fan_mode()
am_conf = conf.as_am_modern()
self.assertEqual(conf, FanModeConfig.from_am_modern(am_conf))