Compare commits
65 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2eb6697e9a | ||
|
|
c5817fcc36 | ||
|
|
f2391bcb2d | ||
|
|
bc3bd9e5da | ||
|
|
3f0959d75e | ||
|
|
31f7b56724 | ||
|
|
072954d755 | ||
|
|
d271e0f9c8 | ||
|
|
8f1408ce17 | ||
|
|
825d1f4cfb | ||
|
|
c6bcd7e05a | ||
|
|
5d80051f3b | ||
|
|
b71c448199 | ||
|
|
c82148412c | ||
|
|
a582ee63a0 | ||
|
|
db7c19c486 | ||
|
|
599f71da19 | ||
|
|
0995744d90 | ||
|
|
4073a27aba | ||
|
|
bec9c31c97 | ||
|
|
acdd615c53 | ||
|
|
8091617ee2 | ||
|
|
c25ff6fcef | ||
|
|
ab0dcd607b | ||
|
|
ce288e472f | ||
|
|
02d8f25daf | ||
|
|
a76d1c6149 | ||
|
|
17f5eade19 | ||
|
|
b6a2a5054b | ||
|
|
5984338c64 | ||
|
|
07d1c48e33 | ||
|
|
d2abae947c | ||
|
|
e4a0f2451a | ||
|
|
880c598b1a | ||
|
|
3632c2c4d8 | ||
|
|
09bc9686ae | ||
|
|
34584ab098 | ||
|
|
554d99ca08 | ||
|
|
5c5d688ffa | ||
|
|
c50d55e87c | ||
|
|
5e5516bfb3 | ||
|
|
4b068c57c5 | ||
|
|
203f199aec | ||
|
|
895f17aaf9 | ||
|
|
8a64ff3559 | ||
|
|
4c45d356c4 | ||
|
|
4dec329f11 | ||
|
|
b563ed118e | ||
|
|
75b2ec40b1 | ||
|
|
d9adaf6667 | ||
|
|
9343308f41 | ||
|
|
88769e40ae | ||
|
|
be45eb7400 | ||
|
|
2f719a03a4 | ||
|
|
64196f9754 | ||
|
|
49a77f1b79 | ||
|
|
3838c4f2f9 | ||
|
|
80d89c95b5 | ||
|
|
30cd8b5cfe | ||
|
|
c443170f78 | ||
|
|
a2c2aa2377 | ||
|
|
4f0eb49a02 | ||
|
|
a821357b4f | ||
|
|
3c7679a22d | ||
|
|
a52737e236 |
@@ -9,7 +9,7 @@
|
|||||||
[](https://github.com/UpstreamData/pyasic/commits/master/)
|
[](https://github.com/UpstreamData/pyasic/commits/master/)
|
||||||
|
|
||||||
[](https://github.com/psf/black)
|
[](https://github.com/psf/black)
|
||||||
[](https://pyasic.readthedocs.io/en/latest/)
|
[](https://docs.pyasic.org)
|
||||||
[](https://github.com/UpstreamData/pyasic/blob/master/LICENSE.txt)
|
[](https://github.com/UpstreamData/pyasic/blob/master/LICENSE.txt)
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
Welcome to `pyasic`! `pyasic` uses an asynchronous method of communicating with ASIC miners on your network, which makes it super fast.
|
Welcome to `pyasic`! `pyasic` uses an asynchronous method of communicating with ASIC miners on your network, which makes it super fast.
|
||||||
|
|
||||||
[Click here to view supported miner types](miners/supported_types.md)
|
[Click here to view supported miner types](https://docs.pyasic.org/en/latest/miners/supported_types/)
|
||||||
|
|
||||||
---
|
---
|
||||||
## Getting started
|
## Getting started
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -85,6 +85,13 @@
|
|||||||
show_root_heading: false
|
show_root_heading: false
|
||||||
heading_level: 4
|
heading_level: 4
|
||||||
|
|
||||||
|
## S19 Pro Hydro
|
||||||
|
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19ProHydro
|
||||||
|
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 +99,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 +274,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 +295,10 @@
|
|||||||
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
|
||||||
|
|
||||||
|
|||||||
10
docs/miners/antminer/X21.md
Normal file
10
docs/miners/antminer/X21.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# pyasic
|
||||||
|
## X21 Models
|
||||||
|
|
||||||
|
## S21 (ePIC)
|
||||||
|
::: pyasic.miners.antminer.epic.X21.S21.ePICS21
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
24
docs/miners/auradine/AD.md
Normal file
24
docs/miners/auradine/AD.md
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# pyasic
|
||||||
|
## AD Models
|
||||||
|
|
||||||
|
## AT1500
|
||||||
|
::: pyasic.miners.auradine.flux.AD.AT1.AuradineFluxAT1500
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
## AT2860
|
||||||
|
::: pyasic.miners.auradine.flux.AD.AT2.AuradineFluxAT2860
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
## AT2880
|
||||||
|
::: pyasic.miners.auradine.flux.AD.AT2.AuradineFluxAT2880
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
17
docs/miners/auradine/AI.md
Normal file
17
docs/miners/auradine/AI.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# pyasic
|
||||||
|
## AI Models
|
||||||
|
|
||||||
|
## AI2500
|
||||||
|
::: pyasic.miners.auradine.flux.AI.AI2.AuradineFluxAI2500
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
## AI3680
|
||||||
|
::: pyasic.miners.auradine.flux.AI.AI3.AuradineFluxAI3680
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
17
docs/miners/auradine/AT.md
Normal file
17
docs/miners/auradine/AT.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# pyasic
|
||||||
|
## AT Models
|
||||||
|
|
||||||
|
## AD2500
|
||||||
|
::: pyasic.miners.auradine.flux.AT.AD2.AuradineFluxAD2500
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
## AD3500
|
||||||
|
::: pyasic.miners.auradine.flux.AT.AD3.AuradineFluxAD3500
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
@@ -21,3 +21,4 @@
|
|||||||
options:
|
options:
|
||||||
show_root_heading: false
|
show_root_heading: false
|
||||||
heading_level: 4
|
heading_level: 4
|
||||||
|
|
||||||
|
|||||||
17
docs/miners/goldshell/XBox.md
Normal file
17
docs/miners/goldshell/XBox.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# pyasic
|
||||||
|
## XBox Models
|
||||||
|
|
||||||
|
## KD Box II
|
||||||
|
::: pyasic.miners.goldshell.bfgminer.XBox.KDBox.GoldshellKDBoxII
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
## KD Box Pro
|
||||||
|
::: pyasic.miners.goldshell.bfgminer.XBox.KDBox.GoldshellKDBoxPro
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
@@ -2,8 +2,9 @@
|
|||||||
## XMax Models
|
## 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
|
||||||
|
|
||||||
|
|||||||
@@ -7,3 +7,4 @@
|
|||||||
options:
|
options:
|
||||||
show_root_heading: false
|
show_root_heading: false
|
||||||
heading_level: 4
|
heading_level: 4
|
||||||
|
|
||||||
|
|||||||
@@ -7,3 +7,4 @@
|
|||||||
options:
|
options:
|
||||||
show_root_heading: false
|
show_root_heading: false
|
||||||
heading_level: 4
|
heading_level: 4
|
||||||
|
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ 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-pro-hydro">S19 Pro Hydro</a></li>
|
||||||
<li><a href="../antminer/X19#t19">T19</a></li>
|
<li><a href="../antminer/X19#t19">T19</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</details>
|
</details>
|
||||||
@@ -286,13 +287,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 +403,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 +418,37 @@ 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>
|
</ul>
|
||||||
</details>
|
</details>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -420,6 +460,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 +501,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 +526,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 +540,38 @@ 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>
|
||||||
|
</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>
|
||||||
@@ -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
|
||||||
|
|||||||
136
docs/miners/whatsminer/M6X.md
Normal file
136
docs/miners/whatsminer/M6X.md
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
# pyasic
|
||||||
|
## M6X Models
|
||||||
|
|
||||||
|
## M60 VK10
|
||||||
|
::: pyasic.miners.whatsminer.btminer.M6X.M60.BTMinerM60VK10
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
## M60 VK20
|
||||||
|
::: pyasic.miners.whatsminer.btminer.M6X.M60.BTMinerM60VK20
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
## M60 VK30
|
||||||
|
::: pyasic.miners.whatsminer.btminer.M6X.M60.BTMinerM60VK30
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
## M60 VK40
|
||||||
|
::: pyasic.miners.whatsminer.btminer.M6X.M60.BTMinerM60VK40
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
## M60S VK10
|
||||||
|
::: pyasic.miners.whatsminer.btminer.M6X.M60S.BTMinerM60SVK10
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
## M60S VK20
|
||||||
|
::: pyasic.miners.whatsminer.btminer.M6X.M60S.BTMinerM60SVK20
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
## M60S VK30
|
||||||
|
::: pyasic.miners.whatsminer.btminer.M6X.M60S.BTMinerM60SVK30
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
## M60S VK40
|
||||||
|
::: pyasic.miners.whatsminer.btminer.M6X.M60S.BTMinerM60SVK40
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
## M63 VK10
|
||||||
|
::: pyasic.miners.whatsminer.btminer.M6X.M63.BTMinerM63VK10
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
## M63 VK20
|
||||||
|
::: pyasic.miners.whatsminer.btminer.M6X.M63.BTMinerM63VK20
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
## M63 VK30
|
||||||
|
::: pyasic.miners.whatsminer.btminer.M6X.M63.BTMinerM63VK30
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
## M63S VK10
|
||||||
|
::: pyasic.miners.whatsminer.btminer.M6X.M63S.BTMinerM63SVK10
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
## M63S VK20
|
||||||
|
::: pyasic.miners.whatsminer.btminer.M6X.M63S.BTMinerM63SVK20
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
## M63S VK30
|
||||||
|
::: pyasic.miners.whatsminer.btminer.M6X.M63S.BTMinerM63SVK30
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
## M66 VK20
|
||||||
|
::: pyasic.miners.whatsminer.btminer.M6X.M66.BTMinerM66VK20
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
## M66 VK30
|
||||||
|
::: pyasic.miners.whatsminer.btminer.M6X.M66.BTMinerM66VK30
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
## M66S VK20
|
||||||
|
::: pyasic.miners.whatsminer.btminer.M6X.M66S.BTMinerM66SVK20
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
## M66S VK30
|
||||||
|
::: pyasic.miners.whatsminer.btminer.M6X.M66S.BTMinerM66SVK30
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
## M66S VK40
|
||||||
|
::: pyasic.miners.whatsminer.btminer.M6X.M66S.BTMinerM66SVK40
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
@@ -40,6 +40,7 @@ nav:
|
|||||||
- Antminer X15: "miners/antminer/X15.md"
|
- Antminer X15: "miners/antminer/X15.md"
|
||||||
- Antminer X17: "miners/antminer/X17.md"
|
- Antminer X17: "miners/antminer/X17.md"
|
||||||
- Antminer X19: "miners/antminer/X19.md"
|
- Antminer X19: "miners/antminer/X19.md"
|
||||||
|
- Antminer X21: "miners/antminer/X21.md"
|
||||||
- Avalon 7X: "miners/avalonminer/A7X.md"
|
- Avalon 7X: "miners/avalonminer/A7X.md"
|
||||||
- Avalon 8X: "miners/avalonminer/A8X.md"
|
- Avalon 8X: "miners/avalonminer/A8X.md"
|
||||||
- Avalon 9X: "miners/avalonminer/A9X.md"
|
- Avalon 9X: "miners/avalonminer/A9X.md"
|
||||||
|
|||||||
@@ -54,9 +54,9 @@ class FanModeNormal(MinerConfigValue):
|
|||||||
return {
|
return {
|
||||||
"fans": {
|
"fans": {
|
||||||
"Auto": {
|
"Auto": {
|
||||||
"Idle Speed": self.minimum_speed
|
"Idle Speed": (
|
||||||
if not self.minimum_speed == 0
|
self.minimum_speed if not self.minimum_speed == 0 else 100
|
||||||
else 100
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,9 @@ class MiningModeNormal(MinerConfigValue):
|
|||||||
def as_epic(self) -> dict:
|
def as_epic(self) -> dict:
|
||||||
return {"ptune": {"enabled": False}}
|
return {"ptune": {"enabled": False}}
|
||||||
|
|
||||||
|
def as_goldshell(self) -> dict:
|
||||||
|
return {"settings": {"level": 0}}
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class MiningModeSleep(MinerConfigValue):
|
class MiningModeSleep(MinerConfigValue):
|
||||||
@@ -71,6 +74,9 @@ class MiningModeSleep(MinerConfigValue):
|
|||||||
def as_epic(self) -> dict:
|
def as_epic(self) -> dict:
|
||||||
return {"ptune": {"algo": "Sleep", "target": 0}}
|
return {"ptune": {"algo": "Sleep", "target": 0}}
|
||||||
|
|
||||||
|
def as_goldshell(self) -> dict:
|
||||||
|
return {"settings": {"level": 3}}
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class MiningModeLPM(MinerConfigValue):
|
class MiningModeLPM(MinerConfigValue):
|
||||||
@@ -89,6 +95,9 @@ class MiningModeLPM(MinerConfigValue):
|
|||||||
def as_auradine(self) -> dict:
|
def as_auradine(self) -> dict:
|
||||||
return {"mode": {"mode": "eco"}}
|
return {"mode": {"mode": "eco"}}
|
||||||
|
|
||||||
|
def as_goldshell(self) -> dict:
|
||||||
|
return {"settings": {"level": 1}}
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class MiningModeHPM(MinerConfigValue):
|
class MiningModeHPM(MinerConfigValue):
|
||||||
@@ -108,31 +117,31 @@ class MiningModeHPM(MinerConfigValue):
|
|||||||
return {"mode": {"mode": "turbo"}}
|
return {"mode": {"mode": "turbo"}}
|
||||||
|
|
||||||
|
|
||||||
class StandardPowerTuneAlgo(MinerConfigValue):
|
class StandardTuneAlgo(MinerConfigValue):
|
||||||
mode: str = field(init=False, default="standard")
|
mode: str = field(init=False, default="standard")
|
||||||
|
|
||||||
def as_epic(self):
|
def as_epic(self) -> str:
|
||||||
return VOptPowerTuneAlgo().as_epic()
|
return VOptAlgo().as_epic()
|
||||||
|
|
||||||
|
|
||||||
class VOptPowerTuneAlgo(MinerConfigValue):
|
class VOptAlgo(MinerConfigValue):
|
||||||
mode: str = field(init=False, default="standard")
|
mode: str = field(init=False, default="standard")
|
||||||
|
|
||||||
def as_epic(self):
|
def as_epic(self) -> str:
|
||||||
return "VoltageOptimizer"
|
return "VoltageOptimizer"
|
||||||
|
|
||||||
|
|
||||||
class ChipTunePowerTuneAlgo(MinerConfigValue):
|
class ChipTuneAlgo(MinerConfigValue):
|
||||||
mode: str = field(init=False, default="standard")
|
mode: str = field(init=False, default="standard")
|
||||||
|
|
||||||
def as_epic(self):
|
def as_epic(self) -> str:
|
||||||
return "ChipTune"
|
return "ChipTune"
|
||||||
|
|
||||||
|
|
||||||
class PowerTunerAlgo(MinerConfigOption):
|
class TunerAlgo(MinerConfigOption):
|
||||||
standard = StandardPowerTuneAlgo
|
standard = StandardTuneAlgo
|
||||||
voltage_optimizer = VOptPowerTuneAlgo
|
voltage_optimizer = VOptAlgo
|
||||||
chip_tune = ChipTunePowerTuneAlgo
|
chip_tune = ChipTuneAlgo
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def default(cls):
|
def default(cls):
|
||||||
@@ -143,7 +152,7 @@ class PowerTunerAlgo(MinerConfigOption):
|
|||||||
class MiningModePowerTune(MinerConfigValue):
|
class MiningModePowerTune(MinerConfigValue):
|
||||||
mode: str = field(init=False, default="power_tuning")
|
mode: str = field(init=False, default="power_tuning")
|
||||||
power: int = None
|
power: int = None
|
||||||
algo: PowerTunerAlgo = field(default_factory=PowerTunerAlgo.default)
|
algo: TunerAlgo = field(default_factory=TunerAlgo.default)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_dict(cls, dict_conf: dict | None) -> "MiningModePowerTune":
|
def from_dict(cls, dict_conf: dict | None) -> "MiningModePowerTune":
|
||||||
@@ -183,14 +192,12 @@ class MiningModePowerTune(MinerConfigValue):
|
|||||||
def as_auradine(self) -> dict:
|
def as_auradine(self) -> dict:
|
||||||
return {"mode": {"mode": "custom", "tune": "power", "power": self.power}}
|
return {"mode": {"mode": "custom", "tune": "power", "power": self.power}}
|
||||||
|
|
||||||
def as_epic(self) -> dict:
|
|
||||||
return {"ptune": {**self.algo.as_epic(), "target": self.power}}
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class MiningModeHashrateTune(MinerConfigValue):
|
class MiningModeHashrateTune(MinerConfigValue):
|
||||||
mode: str = field(init=False, default="hashrate_tuning")
|
mode: str = field(init=False, default="hashrate_tuning")
|
||||||
hashrate: int = None
|
hashrate: int = None
|
||||||
|
algo: TunerAlgo = field(default_factory=TunerAlgo.default)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_dict(cls, dict_conf: dict | None) -> "MiningModeHashrateTune":
|
def from_dict(cls, dict_conf: dict | None) -> "MiningModeHashrateTune":
|
||||||
@@ -218,6 +225,9 @@ class MiningModeHashrateTune(MinerConfigValue):
|
|||||||
def as_auradine(self) -> dict:
|
def as_auradine(self) -> dict:
|
||||||
return {"mode": {"mode": "custom", "tune": "ths", "ths": self.hashrate}}
|
return {"mode": {"mode": "custom", "tune": "ths", "ths": self.hashrate}}
|
||||||
|
|
||||||
|
def as_epic(self) -> dict:
|
||||||
|
return {"ptune": {"algo": self.algo.as_epic(), "target": self.hashrate}}
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class ManualBoardSettings(MinerConfigValue):
|
class ManualBoardSettings(MinerConfigValue):
|
||||||
@@ -313,14 +323,14 @@ class MiningModeConfig(MinerConfigOption):
|
|||||||
if tuner_running:
|
if tuner_running:
|
||||||
algo_info = web_conf["PerpetualTune"]["Algorithm"]
|
algo_info = web_conf["PerpetualTune"]["Algorithm"]
|
||||||
if algo_info.get("VoltageOptimizer") is not None:
|
if algo_info.get("VoltageOptimizer") is not None:
|
||||||
return cls.power_tuning(
|
return cls.hashrate_tuning(
|
||||||
power=algo_info["VoltageOptimizer"]["Target"],
|
hashrate=algo_info["VoltageOptimizer"]["Target"],
|
||||||
algo=PowerTunerAlgo.voltage_optimizer,
|
algo=TunerAlgo.voltage_optimizer,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
return cls.power_tuning(
|
return cls.hashrate_tuning(
|
||||||
power=algo_info["ChipTune"]["Target"],
|
hashrate=algo_info["ChipTune"]["Target"],
|
||||||
algo=PowerTunerAlgo.chip_tune,
|
algo=TunerAlgo.chip_tune,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
return cls.normal()
|
return cls.normal()
|
||||||
|
|||||||
@@ -265,15 +265,7 @@ class PoolGroup(MinerConfigValue):
|
|||||||
return [p.as_auradine(user_suffix=user_suffix) for p in self.pools]
|
return [p.as_auradine(user_suffix=user_suffix) for p in self.pools]
|
||||||
|
|
||||||
def as_epic(self, user_suffix: str = None) -> dict:
|
def as_epic(self, user_suffix: str = None) -> dict:
|
||||||
if len(self.pools) > 0:
|
return [p.as_epic(user_suffix=user_suffix) for p in self.pools]
|
||||||
conf = {
|
|
||||||
"name": self.name,
|
|
||||||
"pool": [pool.as_epic(user_suffix=user_suffix) for pool in self.pools],
|
|
||||||
}
|
|
||||||
if self.quota is not None:
|
|
||||||
conf["quota"] = self.quota
|
|
||||||
return conf
|
|
||||||
return {"name": self.name, "pool": []}
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_dict(cls, dict_conf: dict | None) -> "PoolGroup":
|
def from_dict(cls, dict_conf: dict | None) -> "PoolGroup":
|
||||||
@@ -335,9 +327,11 @@ class PoolGroup(MinerConfigValue):
|
|||||||
return cls(
|
return cls(
|
||||||
pools=[Pool.from_boser(p) for p in grpc_pool_group["pools"]],
|
pools=[Pool.from_boser(p) for p in grpc_pool_group["pools"]],
|
||||||
name=grpc_pool_group["name"],
|
name=grpc_pool_group["name"],
|
||||||
quota=grpc_pool_group["quota"]["value"]
|
quota=(
|
||||||
if grpc_pool_group.get("quota") is not None
|
grpc_pool_group["quota"]["value"]
|
||||||
else 1,
|
if grpc_pool_group.get("quota") is not None
|
||||||
|
else 1
|
||||||
|
),
|
||||||
)
|
)
|
||||||
except LookupError:
|
except LookupError:
|
||||||
return cls()
|
return cls()
|
||||||
@@ -421,9 +415,7 @@ class PoolConfig(MinerConfigValue):
|
|||||||
return {
|
return {
|
||||||
"pools": {
|
"pools": {
|
||||||
"coin": "Btc",
|
"coin": "Btc",
|
||||||
"stratum_configs": [
|
"stratum_configs": self.groups[0].as_epic(user_suffix=user_suffix),
|
||||||
g.as_epic(user_suffix=user_suffix) for g in self.groups
|
|
||||||
],
|
|
||||||
"unique_id": False,
|
"unique_id": False,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,9 +43,9 @@ class TemperatureConfig(MinerConfigValue):
|
|||||||
def as_epic(self) -> dict:
|
def as_epic(self) -> dict:
|
||||||
temps_config = {"temps": {}, "fans": {"Auto": {}}}
|
temps_config = {"temps": {}, "fans": {"Auto": {}}}
|
||||||
if self.target is not None:
|
if self.target is not None:
|
||||||
temps_config["fans"]["Target Temperature"] = self.target
|
temps_config["fans"]["Auto"]["Target Temperature"] = self.target
|
||||||
else:
|
else:
|
||||||
temps_config["fans"]["Target Temperature"] = 60
|
temps_config["fans"]["Auto"]["Target Temperature"] = 60
|
||||||
if self.danger is not None:
|
if self.danger is not None:
|
||||||
temps_config["temps"]["shutdown"] = self.danger
|
temps_config["temps"]["shutdown"] = self.danger
|
||||||
return temps_config
|
return temps_config
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -14,21 +14,21 @@
|
|||||||
# limitations under the License. -
|
# limitations under the License. -
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import BOSer
|
from pyasic.miners.backends import BOSMiner
|
||||||
from pyasic.miners.models import S17, S17e, S17Plus, S17Pro
|
from pyasic.miners.models import S17, S17e, S17Plus, S17Pro
|
||||||
|
|
||||||
|
|
||||||
class BOSMinerS17(BOSer, S17):
|
class BOSMinerS17(BOSMiner, S17):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class BOSMinerS17Plus(BOSer, S17Plus):
|
class BOSMinerS17Plus(BOSMiner, S17Plus):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class BOSMinerS17Pro(BOSer, S17Pro):
|
class BOSMinerS17Pro(BOSMiner, S17Pro):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class BOSMinerS17e(BOSer, S17e):
|
class BOSMinerS17e(BOSMiner, S17e):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -14,17 +14,17 @@
|
|||||||
# limitations under the License. -
|
# limitations under the License. -
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import BOSer
|
from pyasic.miners.backends import BOSMiner
|
||||||
from pyasic.miners.models import T17, T17e, T17Plus
|
from pyasic.miners.models import T17, T17e, T17Plus
|
||||||
|
|
||||||
|
|
||||||
class BOSMinerT17(BOSer, T17):
|
class BOSMinerT17(BOSMiner, T17):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class BOSMinerT17Plus(BOSer, T17Plus):
|
class BOSMinerT17Plus(BOSMiner, T17Plus):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class BOSMinerT17e(BOSer, T17e):
|
class BOSMinerT17e(BOSMiner, T17e):
|
||||||
pass
|
pass
|
||||||
|
|||||||
22
pyasic/miners/antminer/epic/X21/S21.py
Normal file
22
pyasic/miners/antminer/epic/X21/S21.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Copyright 2022 Upstream Data Inc -
|
||||||
|
# -
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||||
|
# you may not use this file except in compliance with the License. -
|
||||||
|
# You may obtain a copy of the License at -
|
||||||
|
# -
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||||
|
# -
|
||||||
|
# Unless required by applicable law or agreed to in writing, software -
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||||
|
# See the License for the specific language governing permissions and -
|
||||||
|
# limitations under the License. -
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
from pyasic.miners.backends import ePIC
|
||||||
|
from pyasic.miners.models import S21
|
||||||
|
|
||||||
|
|
||||||
|
class ePICS21(ePIC, S21):
|
||||||
|
pass
|
||||||
19
pyasic/miners/antminer/epic/X21/__init__.py
Normal file
19
pyasic/miners/antminer/epic/X21/__init__.py
Normal 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 .S21 import (
|
||||||
|
ePICS21,
|
||||||
|
)
|
||||||
@@ -15,3 +15,4 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from .X19 import *
|
from .X19 import *
|
||||||
|
from .X21 import *
|
||||||
|
|||||||
22
pyasic/miners/antminer/luxos/X19/S19.py
Normal file
22
pyasic/miners/antminer/luxos/X19/S19.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Copyright 2022 Upstream Data Inc -
|
||||||
|
# -
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||||
|
# you may not use this file except in compliance with the License. -
|
||||||
|
# You may obtain a copy of the License at -
|
||||||
|
# -
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||||
|
# -
|
||||||
|
# Unless required by applicable law or agreed to in writing, software -
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||||
|
# See the License for the specific language governing permissions and -
|
||||||
|
# limitations under the License. -
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
from pyasic.miners.backends import LUXMiner
|
||||||
|
from pyasic.miners.models import S19
|
||||||
|
|
||||||
|
|
||||||
|
class LUXMinerS19(LUXMiner, S19):
|
||||||
|
pass
|
||||||
17
pyasic/miners/antminer/luxos/X19/__init__.py
Normal file
17
pyasic/miners/antminer/luxos/X19/__init__.py
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Copyright 2022 Upstream Data Inc -
|
||||||
|
# -
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||||
|
# you may not use this file except in compliance with the License. -
|
||||||
|
# You may obtain a copy of the License at -
|
||||||
|
# -
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||||
|
# -
|
||||||
|
# Unless required by applicable law or agreed to in writing, software -
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||||
|
# See the License for the specific language governing permissions and -
|
||||||
|
# limitations under the License. -
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
from .S19 import LUXMinerS19
|
||||||
@@ -15,3 +15,4 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from .X9 import *
|
from .X9 import *
|
||||||
|
from .X19 import *
|
||||||
|
|||||||
22
pyasic/miners/antminer/vnish/X7/L7.py
Normal file
22
pyasic/miners/antminer/vnish/X7/L7.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Copyright 2022 Upstream Data Inc -
|
||||||
|
# -
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||||
|
# you may not use this file except in compliance with the License. -
|
||||||
|
# You may obtain a copy of the License at -
|
||||||
|
# -
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||||
|
# -
|
||||||
|
# Unless required by applicable law or agreed to in writing, software -
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||||
|
# See the License for the specific language governing permissions and -
|
||||||
|
# limitations under the License. -
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
from pyasic.miners.backends import VNish
|
||||||
|
from pyasic.miners.models import L7
|
||||||
|
|
||||||
|
|
||||||
|
class VnishL7(VNish, L7):
|
||||||
|
pass
|
||||||
17
pyasic/miners/antminer/vnish/X7/__init__.py
Normal file
17
pyasic/miners/antminer/vnish/X7/__init__.py
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Copyright 2022 Upstream Data Inc -
|
||||||
|
# -
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||||
|
# you may not use this file except in compliance with the License. -
|
||||||
|
# You may obtain a copy of the License at -
|
||||||
|
# -
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||||
|
# -
|
||||||
|
# Unless required by applicable law or agreed to in writing, software -
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||||
|
# See the License for the specific language governing permissions and -
|
||||||
|
# limitations under the License. -
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
from .L7 import VnishL7
|
||||||
@@ -15,5 +15,6 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from .X3 import *
|
from .X3 import *
|
||||||
|
from .X7 import *
|
||||||
from .X17 import *
|
from .X17 import *
|
||||||
from .X19 import *
|
from .X19 import *
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ class AntminerModern(BMMiner):
|
|||||||
data_locations = ANTMINER_MODERN_DATA_LOC
|
data_locations = ANTMINER_MODERN_DATA_LOC
|
||||||
|
|
||||||
supports_shutdown = True
|
supports_shutdown = True
|
||||||
|
supports_power_modes = True
|
||||||
|
|
||||||
async def get_config(self) -> MinerConfig:
|
async def get_config(self) -> MinerConfig:
|
||||||
data = await self.web.get_miner_conf()
|
data = await self.web.get_miner_conf()
|
||||||
@@ -206,7 +207,7 @@ class AntminerModern(BMMiner):
|
|||||||
]
|
]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
rpc_stats = await self.rpc.send_command("stats", new_rpc=True)
|
rpc_stats = await self.rpc.send_command("stats", new_api=True)
|
||||||
except APIError:
|
except APIError:
|
||||||
return hashboards
|
return hashboards
|
||||||
|
|
||||||
|
|||||||
@@ -124,6 +124,7 @@ class Auradine(BaseMiner):
|
|||||||
data_locations = AURADINE_DATA_LOC
|
data_locations = AURADINE_DATA_LOC
|
||||||
|
|
||||||
supports_shutdown = True
|
supports_shutdown = True
|
||||||
|
supports_power_modes = True
|
||||||
supports_autotuning = True
|
supports_autotuning = True
|
||||||
|
|
||||||
async def fault_light_on(self) -> bool:
|
async def fault_light_on(self) -> bool:
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ class BFGMiner(BaseMiner):
|
|||||||
except APIError:
|
except APIError:
|
||||||
return self.config
|
return self.config
|
||||||
|
|
||||||
self.config = MinerConfig.from_rpc(pools)
|
self.config = MinerConfig.from_api(pools)
|
||||||
return self.config
|
return self.config
|
||||||
|
|
||||||
##################################################
|
##################################################
|
||||||
@@ -84,11 +84,11 @@ class BFGMiner(BaseMiner):
|
|||||||
|
|
||||||
if rpc_version is not None:
|
if rpc_version is not None:
|
||||||
try:
|
try:
|
||||||
self.rpc_ver = rpc_version["VERSION"][0]["API"]
|
self.api_ver = rpc_version["VERSION"][0]["API"]
|
||||||
except LookupError:
|
except LookupError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return self.rpc_ver
|
return self.api_ver
|
||||||
|
|
||||||
async def _get_fw_ver(self, rpc_version: dict = None) -> Optional[str]:
|
async def _get_fw_ver(self, rpc_version: dict = None) -> Optional[str]:
|
||||||
if rpc_version is None:
|
if rpc_version is None:
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ class BMMiner(BaseMiner):
|
|||||||
except APIError:
|
except APIError:
|
||||||
return self.config
|
return self.config
|
||||||
|
|
||||||
self.config = MinerConfig.from_rpc(pools)
|
self.config = MinerConfig.from_api(pools)
|
||||||
return self.config
|
return self.config
|
||||||
|
|
||||||
##################################################
|
##################################################
|
||||||
@@ -88,11 +88,11 @@ class BMMiner(BaseMiner):
|
|||||||
|
|
||||||
if rpc_version is not None:
|
if rpc_version is not None:
|
||||||
try:
|
try:
|
||||||
self.rpc_ver = rpc_version["VERSION"][0]["API"]
|
self.api_ver = rpc_version["VERSION"][0]["API"]
|
||||||
except LookupError:
|
except LookupError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return self.rpc_ver
|
return self.api_ver
|
||||||
|
|
||||||
async def _get_fw_ver(self, rpc_version: dict = None) -> Optional[str]:
|
async def _get_fw_ver(self, rpc_version: dict = None) -> Optional[str]:
|
||||||
if rpc_version is None:
|
if rpc_version is None:
|
||||||
|
|||||||
@@ -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(
|
||||||
**{
|
**{
|
||||||
@@ -305,10 +306,10 @@ class BOSMiner(BaseMiner):
|
|||||||
rpc_ver = rpc_version["VERSION"][0]["API"]
|
rpc_ver = rpc_version["VERSION"][0]["API"]
|
||||||
except LookupError:
|
except LookupError:
|
||||||
rpc_ver = None
|
rpc_ver = None
|
||||||
self.rpc_ver = rpc_ver
|
self.api_ver = rpc_ver
|
||||||
self.rpc.rpc_ver = self.rpc_ver
|
self.rpc.rpc_ver = self.api_ver
|
||||||
|
|
||||||
return self.rpc_ver
|
return self.api_ver
|
||||||
|
|
||||||
async def _get_fw_ver(self, web_bos_info: dict = None) -> Optional[str]:
|
async def _get_fw_ver(self, web_bos_info: dict = None) -> Optional[str]:
|
||||||
if web_bos_info is None:
|
if web_bos_info is None:
|
||||||
@@ -691,7 +692,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
|
||||||
|
|
||||||
@@ -731,10 +734,10 @@ class BOSer(BaseMiner):
|
|||||||
rpc_ver = rpc_version["VERSION"][0]["API"]
|
rpc_ver = rpc_version["VERSION"][0]["API"]
|
||||||
except LookupError:
|
except LookupError:
|
||||||
rpc_ver = None
|
rpc_ver = None
|
||||||
self.rpc_ver = rpc_ver
|
self.api_ver = rpc_ver
|
||||||
self.rpc.rpc_ver = self.rpc_ver
|
self.rpc.rpc_ver = self.api_ver
|
||||||
|
|
||||||
return self.rpc_ver
|
return self.api_ver
|
||||||
|
|
||||||
async def _get_fw_ver(self, grpc_miner_details: dict = None) -> Optional[str]:
|
async def _get_fw_ver(self, grpc_miner_details: dict = None) -> Optional[str]:
|
||||||
if grpc_miner_details is None:
|
if grpc_miner_details is None:
|
||||||
|
|||||||
@@ -119,6 +119,7 @@ class BTMiner(BaseMiner):
|
|||||||
data_locations = BTMINER_DATA_LOC
|
data_locations = BTMINER_DATA_LOC
|
||||||
|
|
||||||
supports_shutdown = True
|
supports_shutdown = True
|
||||||
|
supports_power_modes = True
|
||||||
|
|
||||||
async def _reset_rpc_pwd_to_admin(self, pwd: str):
|
async def _reset_rpc_pwd_to_admin(self, pwd: str):
|
||||||
try:
|
try:
|
||||||
@@ -234,7 +235,7 @@ class BTMiner(BaseMiner):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
if pools is not None:
|
if pools is not None:
|
||||||
cfg = MinerConfig.from_rpc(pools)
|
cfg = MinerConfig.from_api(pools)
|
||||||
else:
|
else:
|
||||||
cfg = MinerConfig()
|
cfg = MinerConfig()
|
||||||
|
|
||||||
@@ -325,14 +326,14 @@ class BTMiner(BaseMiner):
|
|||||||
rpc_ver = rpc_get_version["Msg"]
|
rpc_ver = rpc_get_version["Msg"]
|
||||||
if not isinstance(rpc_ver, str):
|
if not isinstance(rpc_ver, str):
|
||||||
rpc_ver = rpc_ver["rpc_ver"]
|
rpc_ver = rpc_ver["rpc_ver"]
|
||||||
self.rpc_ver = rpc_ver.replace("whatsminer v", "")
|
self.api_ver = rpc_ver.replace("whatsminer v", "")
|
||||||
except (KeyError, TypeError):
|
except (KeyError, TypeError):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
self.rpc.rpc_ver = self.rpc_ver
|
self.rpc.rpc_ver = self.api_ver
|
||||||
return self.rpc_ver
|
return self.api_ver
|
||||||
|
|
||||||
return self.rpc_ver
|
return self.api_ver
|
||||||
|
|
||||||
async def _get_fw_ver(
|
async def _get_fw_ver(
|
||||||
self, rpc_get_version: dict = None, rpc_summary: dict = None
|
self, rpc_get_version: dict = None, rpc_summary: dict = None
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ class CGMiner(BaseMiner):
|
|||||||
except APIError:
|
except APIError:
|
||||||
return self.config
|
return self.config
|
||||||
|
|
||||||
self.config = MinerConfig.from_rpc(pools)
|
self.config = MinerConfig.from_api(pools)
|
||||||
return self.config
|
return self.config
|
||||||
|
|
||||||
##################################################
|
##################################################
|
||||||
@@ -87,11 +87,11 @@ class CGMiner(BaseMiner):
|
|||||||
|
|
||||||
if rpc_version is not None:
|
if rpc_version is not None:
|
||||||
try:
|
try:
|
||||||
self.rpc_ver = rpc_version["VERSION"][0]["API"]
|
self.api_ver = rpc_version["VERSION"][0]["API"]
|
||||||
except LookupError:
|
except LookupError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return self.rpc_ver
|
return self.api_ver
|
||||||
|
|
||||||
async def _get_fw_ver(self, rpc_version: dict = None) -> Optional[str]:
|
async def _get_fw_ver(self, rpc_version: dict = None) -> Optional[str]:
|
||||||
if rpc_version is None:
|
if rpc_version is None:
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ EPIC_DATA_LOC = DataLocations(
|
|||||||
"_get_hashboards",
|
"_get_hashboards",
|
||||||
[
|
[
|
||||||
WebAPICommand("web_summary", "summary"),
|
WebAPICommand("web_summary", "summary"),
|
||||||
WebAPICommand("web_hashrate", "hashrate"),
|
WebAPICommand("web_capabilities", "capabilities"),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
str(DataOptions.WATTAGE): DataFunction(
|
str(DataOptions.WATTAGE): DataFunction(
|
||||||
@@ -116,6 +116,7 @@ class ePIC(BaseMiner):
|
|||||||
if not conf.get("temps", {}) == {}:
|
if not conf.get("temps", {}) == {}:
|
||||||
await self.web.set_shutdown_temp(conf["temps"]["shutdown"])
|
await self.web.set_shutdown_temp(conf["temps"]["shutdown"])
|
||||||
# Fans
|
# Fans
|
||||||
|
# set with sub-keys instead of conf["fans"] because sometimes both can be set
|
||||||
if not conf["fans"].get("Manual", {}) == {}:
|
if not conf["fans"].get("Manual", {}) == {}:
|
||||||
await self.web.set_fan({"Manual": conf["fans"]["Manual"]})
|
await self.web.set_fan({"Manual": conf["fans"]["Manual"]})
|
||||||
elif not conf["fans"].get("Auto", {}) == {}:
|
elif not conf["fans"].get("Auto", {}) == {}:
|
||||||
@@ -283,7 +284,7 @@ class ePIC(BaseMiner):
|
|||||||
return fans
|
return fans
|
||||||
|
|
||||||
async def _get_hashboards(
|
async def _get_hashboards(
|
||||||
self, web_summary: dict = None, web_hashrate: dict = None
|
self, web_summary: dict = None, web_capabilities: dict = None
|
||||||
) -> List[HashBoard]:
|
) -> List[HashBoard]:
|
||||||
if web_summary is None:
|
if web_summary is None:
|
||||||
try:
|
try:
|
||||||
@@ -291,28 +292,25 @@ class ePIC(BaseMiner):
|
|||||||
except APIError:
|
except APIError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if web_hashrate is not None:
|
if web_capabilities is not None:
|
||||||
try:
|
try:
|
||||||
web_hashrate = await self.web.hashrate()
|
web_capabilities = await self.web.capabilities()
|
||||||
except APIError:
|
except APIError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
hb_list = [
|
hb_list = [
|
||||||
HashBoard(slot=i, expected_chips=self.expected_chips)
|
HashBoard(slot=i, expected_chips=self.expected_chips)
|
||||||
for i in range(self.expected_hashboards)
|
for i in range(self.expected_hashboards)
|
||||||
]
|
]
|
||||||
|
|
||||||
if web_summary.get("HBs") is not None:
|
if web_summary.get("HBs") is not None:
|
||||||
for hb in web_summary["HBs"]:
|
for hb in web_summary["HBs"]:
|
||||||
for hr in web_hashrate:
|
num_of_chips = web_capabilities["Performance Estimator"]["Chip Count"]
|
||||||
if hr["Index"] == hb["Index"]:
|
hashrate = hb["Hashrate"][0]
|
||||||
num_of_chips = len(hr["Data"])
|
# Update the Hashboard object
|
||||||
hashrate = hb["Hashrate"][0]
|
hb_list[hb["Index"]].missing = False
|
||||||
# Update the Hashboard object
|
hb_list[hb["Index"]].hashrate = round(hashrate / 1000000, 2)
|
||||||
hb_list[hr["Index"]].expected_chips = num_of_chips
|
hb_list[hb["Index"]].chips = num_of_chips
|
||||||
hb_list[hr["Index"]].missing = False
|
hb_list[hb["Index"]].temp = hb["Temperature"]
|
||||||
hb_list[hr["Index"]].hashrate = round(hashrate / 1000000, 2)
|
|
||||||
hb_list[hr["Index"]].chips = num_of_chips
|
|
||||||
hb_list[hr["Index"]].temp = hb["Temperature"]
|
|
||||||
return hb_list
|
return hb_list
|
||||||
|
|
||||||
async def _is_mining(self, *args, **kwargs) -> Optional[bool]:
|
async def _is_mining(self, *args, **kwargs) -> Optional[bool]:
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from pyasic.config import MinerConfig
|
from pyasic.config import MinerConfig, MiningModeConfig
|
||||||
from pyasic.data import HashBoard
|
from pyasic.data import HashBoard
|
||||||
from pyasic.errors import APIError
|
from pyasic.errors import APIError
|
||||||
from pyasic.logger import logger
|
from pyasic.logger import logger
|
||||||
@@ -74,6 +74,9 @@ class GoldshellMiner(BFGMiner):
|
|||||||
|
|
||||||
data_locations = GOLDSHELL_DATA_LOC
|
data_locations = GOLDSHELL_DATA_LOC
|
||||||
|
|
||||||
|
supports_shutdown = True
|
||||||
|
supports_power_modes = True
|
||||||
|
|
||||||
async def get_config(self) -> MinerConfig:
|
async def get_config(self) -> MinerConfig:
|
||||||
# get pool data
|
# get pool data
|
||||||
try:
|
try:
|
||||||
@@ -96,13 +99,19 @@ class GoldshellMiner(BFGMiner):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.config = config
|
self.config = config
|
||||||
|
cfg = config.as_goldshell(user_suffix=user_suffix)
|
||||||
# send them back 1 at a time
|
# send them back 1 at a time
|
||||||
for pool in config.as_goldshell(user_suffix=user_suffix)["pools"]:
|
for pool in cfg["pools"]:
|
||||||
await self.web.newpool(
|
await self.web.newpool(
|
||||||
url=pool["url"], user=pool["user"], password=pool["pass"]
|
url=pool["url"], user=pool["user"], password=pool["pass"]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
settings = await self.web.setting()
|
||||||
|
for idx, plan in enumerate(settings["powerplans"]):
|
||||||
|
if plan["level"] == cfg["settings"]["level"]:
|
||||||
|
settings["select"] = idx
|
||||||
|
await self.web.set_setting(settings)
|
||||||
|
|
||||||
async def _get_mac(self, web_setting: dict = None) -> str:
|
async def _get_mac(self, web_setting: dict = None) -> str:
|
||||||
if web_setting is None:
|
if web_setting is None:
|
||||||
try:
|
try:
|
||||||
@@ -178,3 +187,25 @@ class GoldshellMiner(BFGMiner):
|
|||||||
logger.error(self, rpc_devdetails)
|
logger.error(self, rpc_devdetails)
|
||||||
|
|
||||||
return hashboards
|
return hashboards
|
||||||
|
|
||||||
|
async def stop_mining(self) -> bool:
|
||||||
|
settings = await self.web.setting()
|
||||||
|
mode = MiningModeConfig.sleep()
|
||||||
|
cfg = mode.as_goldshell()
|
||||||
|
level = cfg["settings"]["level"]
|
||||||
|
for idx, plan in enumerate(settings["powerplans"]):
|
||||||
|
if plan["level"] == level:
|
||||||
|
settings["select"] = idx
|
||||||
|
await self.web.set_setting(settings)
|
||||||
|
return True
|
||||||
|
|
||||||
|
async def resume_mining(self) -> bool:
|
||||||
|
settings = await self.web.setting()
|
||||||
|
mode = MiningModeConfig.normal()
|
||||||
|
cfg = mode.as_goldshell()
|
||||||
|
level = cfg["settings"]["level"]
|
||||||
|
for idx, plan in enumerate(settings["powerplans"]):
|
||||||
|
if plan["level"] == level:
|
||||||
|
settings["select"] = idx
|
||||||
|
await self.web.set_setting(settings)
|
||||||
|
return True
|
||||||
|
|||||||
@@ -205,13 +205,14 @@ class VNish(BMMiner):
|
|||||||
if web_summary is None:
|
if web_summary is None:
|
||||||
web_summary = await self.web.summary()
|
web_summary = await self.web.summary()
|
||||||
|
|
||||||
|
fw_ver = None
|
||||||
if web_summary is not None:
|
if web_summary is not None:
|
||||||
try:
|
try:
|
||||||
fw_ver = web_summary["miner"]["miner_type"]
|
fw_ver = web_summary["miner"]["miner_type"]
|
||||||
fw_ver = fw_ver.split("(Vnish ")[1].replace(")", "")
|
fw_ver = fw_ver.split("(Vnish ")[1].replace(")", "")
|
||||||
return fw_ver
|
return fw_ver
|
||||||
except KeyError:
|
except LookupError:
|
||||||
pass
|
return fw_ver
|
||||||
|
|
||||||
async def get_config(self) -> MinerConfig:
|
async def get_config(self) -> MinerConfig:
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ class MinerProtocol(Protocol):
|
|||||||
data_locations: DataLocations = None
|
data_locations: DataLocations = None
|
||||||
|
|
||||||
supports_shutdown: bool = False
|
supports_shutdown: bool = False
|
||||||
|
supports_power_modes: bool = False
|
||||||
supports_autotuning: bool = False
|
supports_autotuning: bool = False
|
||||||
|
|
||||||
api_ver: str = None
|
api_ver: str = None
|
||||||
@@ -68,7 +69,12 @@ class MinerProtocol(Protocol):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def model(self) -> str:
|
def model(self) -> str:
|
||||||
model_data = [self.raw_model if self.raw_model is not None else "Unknown"]
|
if self.raw_model is not None:
|
||||||
|
model_data = [self.raw_model]
|
||||||
|
elif self.make is not None:
|
||||||
|
model_data = [self.make]
|
||||||
|
else:
|
||||||
|
model_data = ["Unknown"]
|
||||||
if self.firmware is not None:
|
if self.firmware is not None:
|
||||||
model_data.append(f"({self.firmware})")
|
model_data.append(f"({self.firmware})")
|
||||||
return " ".join(model_data)
|
return " ".join(model_data)
|
||||||
@@ -461,9 +467,11 @@ class MinerProtocol(Protocol):
|
|||||||
ip=str(self.ip),
|
ip=str(self.ip),
|
||||||
make=self.make,
|
make=self.make,
|
||||||
model=self.model,
|
model=self.model,
|
||||||
expected_chips=self.expected_chips * self.expected_hashboards
|
expected_chips=(
|
||||||
if self.expected_chips is not None
|
self.expected_chips * self.expected_hashboards
|
||||||
else 0,
|
if self.expected_chips is not None
|
||||||
|
else 0
|
||||||
|
),
|
||||||
expected_hashboards=self.expected_hashboards,
|
expected_hashboards=self.expected_hashboards,
|
||||||
hashboards=[
|
hashboards=[
|
||||||
HashBoard(slot=i, expected_chips=self.expected_chips)
|
HashBoard(slot=i, expected_chips=self.expected_chips)
|
||||||
|
|||||||
17
pyasic/miners/blockminer/__init__.py
Normal file
17
pyasic/miners/blockminer/__init__.py
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Copyright 2022 Upstream Data Inc -
|
||||||
|
# -
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||||
|
# you may not use this file except in compliance with the License. -
|
||||||
|
# You may obtain a copy of the License at -
|
||||||
|
# -
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||||
|
# -
|
||||||
|
# Unless required by applicable law or agreed to in writing, software -
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||||
|
# See the License for the specific language governing permissions and -
|
||||||
|
# limitations under the License. -
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
from .epic import *
|
||||||
17
pyasic/miners/blockminer/epic/__init__.py
Normal file
17
pyasic/miners/blockminer/epic/__init__.py
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Copyright 2022 Upstream Data Inc -
|
||||||
|
# -
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||||
|
# you may not use this file except in compliance with the License. -
|
||||||
|
# You may obtain a copy of the License at -
|
||||||
|
# -
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||||
|
# -
|
||||||
|
# Unless required by applicable law or agreed to in writing, software -
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||||
|
# See the License for the specific language governing permissions and -
|
||||||
|
# limitations under the License. -
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
from .blockminer import *
|
||||||
19
pyasic/miners/blockminer/epic/blockminer/__init__.py
Normal file
19
pyasic/miners/blockminer/epic/blockminer/__init__.py
Normal 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,
|
||||||
|
)
|
||||||
22
pyasic/miners/blockminer/epic/blockminer/blockminer.py
Normal file
22
pyasic/miners/blockminer/epic/blockminer/blockminer.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Copyright 2022 Upstream Data Inc -
|
||||||
|
# -
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||||
|
# you may not use this file except in compliance with the License. -
|
||||||
|
# You may obtain a copy of the License at -
|
||||||
|
# -
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||||
|
# -
|
||||||
|
# Unless required by applicable law or agreed to in writing, software -
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||||
|
# See the License for the specific language governing permissions and -
|
||||||
|
# limitations under the License. -
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
from pyasic.miners.backends import ePIC
|
||||||
|
from pyasic.miners.models import BlockMiner520i
|
||||||
|
|
||||||
|
|
||||||
|
class ePICBlockMiner520i(ePIC, BlockMiner520i):
|
||||||
|
pass
|
||||||
@@ -29,6 +29,7 @@ from pyasic import settings
|
|||||||
from pyasic.logger import logger
|
from pyasic.logger import logger
|
||||||
from pyasic.miners.antminer import *
|
from pyasic.miners.antminer import *
|
||||||
from pyasic.miners.auradine import *
|
from pyasic.miners.auradine import *
|
||||||
|
from pyasic.miners.blockminer import *
|
||||||
from pyasic.miners.avalonminer import *
|
from pyasic.miners.avalonminer import *
|
||||||
from pyasic.miners.backends import (
|
from pyasic.miners.backends import (
|
||||||
Auradine,
|
Auradine,
|
||||||
@@ -47,6 +48,7 @@ from pyasic.miners.backends.unknown import UnknownMiner
|
|||||||
from pyasic.miners.base import AnyMiner
|
from pyasic.miners.base import AnyMiner
|
||||||
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.whatsminer import *
|
from pyasic.miners.whatsminer import *
|
||||||
|
|
||||||
|
|
||||||
@@ -66,7 +68,7 @@ class MinerTypes(enum.Enum):
|
|||||||
|
|
||||||
MINER_CLASSES = {
|
MINER_CLASSES = {
|
||||||
MinerTypes.ANTMINER: {
|
MinerTypes.ANTMINER: {
|
||||||
None: BMMiner,
|
None: type("AntminerUnknown", (BMMiner, AntMinerMake), {}),
|
||||||
"ANTMINER D3": CGMinerD3,
|
"ANTMINER D3": CGMinerD3,
|
||||||
"ANTMINER HS3": BMMinerHS3,
|
"ANTMINER HS3": BMMinerHS3,
|
||||||
"ANTMINER L3+": BMMinerL3Plus,
|
"ANTMINER L3+": BMMinerL3Plus,
|
||||||
@@ -101,7 +103,7 @@ MINER_CLASSES = {
|
|||||||
"ANTMINER T19": BMMinerT19,
|
"ANTMINER T19": BMMinerT19,
|
||||||
},
|
},
|
||||||
MinerTypes.WHATSMINER: {
|
MinerTypes.WHATSMINER: {
|
||||||
None: BTMiner,
|
None: type("WhatsminerUnknown", (BTMiner, WhatsMinerMake), {}),
|
||||||
"M20V10": BTMinerM20V10,
|
"M20V10": BTMinerM20V10,
|
||||||
"M20SV10": BTMinerM20SV10,
|
"M20SV10": BTMinerM20SV10,
|
||||||
"M20SV20": BTMinerM20SV20,
|
"M20SV20": BTMinerM20SV20,
|
||||||
@@ -289,7 +291,9 @@ MINER_CLASSES = {
|
|||||||
"M50S++VK30": BTMinerM50SPlusPlusVK30,
|
"M50S++VK30": BTMinerM50SPlusPlusVK30,
|
||||||
"M53VH30": BTMinerM53VH30,
|
"M53VH30": BTMinerM53VH30,
|
||||||
"M53SVH30": BTMinerM53SVH30,
|
"M53SVH30": BTMinerM53SVH30,
|
||||||
|
"M53SVJ40": BTMinerM53SVJ40,
|
||||||
"M53S+VJ30": BTMinerM53SPlusVJ30,
|
"M53S+VJ30": BTMinerM53SPlusVJ30,
|
||||||
|
"M53S++VK10": BTMinerM53SPlusPlusVK10,
|
||||||
"M56VH30": BTMinerM56VH30,
|
"M56VH30": BTMinerM56VH30,
|
||||||
"M56SVH30": BTMinerM56SVH30,
|
"M56SVH30": BTMinerM56SVH30,
|
||||||
"M56S+VJ30": BTMinerM56SPlusVJ30,
|
"M56S+VJ30": BTMinerM56SPlusVJ30,
|
||||||
@@ -315,7 +319,7 @@ MINER_CLASSES = {
|
|||||||
"M66SVK40": BTMinerM66SVK40,
|
"M66SVK40": BTMinerM66SVK40,
|
||||||
},
|
},
|
||||||
MinerTypes.AVALONMINER: {
|
MinerTypes.AVALONMINER: {
|
||||||
None: AvalonMiner,
|
None: type("AvalonUnknown", (AvalonMiner, AvalonMinerMake), {}),
|
||||||
"AVALONMINER 721": CGMinerAvalon721,
|
"AVALONMINER 721": CGMinerAvalon721,
|
||||||
"AVALONMINER 741": CGMinerAvalon741,
|
"AVALONMINER 741": CGMinerAvalon741,
|
||||||
"AVALONMINER 761": CGMinerAvalon761,
|
"AVALONMINER 761": CGMinerAvalon761,
|
||||||
@@ -330,16 +334,18 @@ MINER_CLASSES = {
|
|||||||
"AVALONMINER 1246": CGMinerAvalon1246,
|
"AVALONMINER 1246": CGMinerAvalon1246,
|
||||||
},
|
},
|
||||||
MinerTypes.INNOSILICON: {
|
MinerTypes.INNOSILICON: {
|
||||||
None: Innosilicon,
|
None: type("InnosiliconUnknown", (Innosilicon, InnosiliconMake), {}),
|
||||||
"T3H+": InnosiliconT3HPlus,
|
"T3H+": InnosiliconT3HPlus,
|
||||||
"A10X": InnosiliconA10X,
|
"A10X": InnosiliconA10X,
|
||||||
},
|
},
|
||||||
MinerTypes.GOLDSHELL: {
|
MinerTypes.GOLDSHELL: {
|
||||||
None: GoldshellMiner,
|
None: type("GoldshellUnknown", (GoldshellMiner, GoldshellMake), {}),
|
||||||
"GOLDSHELL CK5": GoldshellCK5,
|
"GOLDSHELL CK5": GoldshellCK5,
|
||||||
"GOLDSHELL HS5": GoldshellHS5,
|
"GOLDSHELL HS5": GoldshellHS5,
|
||||||
"GOLDSHELL KD5": GoldshellKD5,
|
"GOLDSHELL KD5": GoldshellKD5,
|
||||||
"GOLDSHELL KDMAX": GoldshellKDMax,
|
"GOLDSHELL KDMAX": GoldshellKDMax,
|
||||||
|
"GOLDSHELL KDBOXII": GoldshellKDBoxII,
|
||||||
|
"GOLDSHELL KDBOXPRO": GoldshellKDBoxPro,
|
||||||
},
|
},
|
||||||
MinerTypes.BRAIINS_OS: {
|
MinerTypes.BRAIINS_OS: {
|
||||||
None: BOSMiner,
|
None: BOSMiner,
|
||||||
@@ -367,7 +373,9 @@ MINER_CLASSES = {
|
|||||||
},
|
},
|
||||||
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,
|
||||||
@@ -388,6 +396,8 @@ MINER_CLASSES = {
|
|||||||
"ANTMINER S19J PRO+": ePICS19jProPlus,
|
"ANTMINER S19J PRO+": ePICS19jProPlus,
|
||||||
"ANTMINER S19K PRO": ePICS19kPro,
|
"ANTMINER S19K PRO": ePICS19kPro,
|
||||||
"ANTMINER S19 XP": ePICS19XP,
|
"ANTMINER S19 XP": ePICS19XP,
|
||||||
|
"ANTMINER S21": ePICS21,
|
||||||
|
"BLOCKMINER 520I": ePICBlockMiner520i,
|
||||||
},
|
},
|
||||||
MinerTypes.HIVEON: {
|
MinerTypes.HIVEON: {
|
||||||
None: Hiveon,
|
None: Hiveon,
|
||||||
@@ -396,9 +406,10 @@ MINER_CLASSES = {
|
|||||||
MinerTypes.LUX_OS: {
|
MinerTypes.LUX_OS: {
|
||||||
None: LUXMiner,
|
None: LUXMiner,
|
||||||
"ANTMINER S9": LUXMinerS9,
|
"ANTMINER S9": LUXMinerS9,
|
||||||
|
"ANTMINER S19": LUXMinerS19,
|
||||||
},
|
},
|
||||||
MinerTypes.AURADINE: {
|
MinerTypes.AURADINE: {
|
||||||
None: Auradine,
|
None: type("GoldshellUnknown", (Auradine, AuradineMake), {}),
|
||||||
"AT1500": AuradineFluxAT1500,
|
"AT1500": AuradineFluxAT1500,
|
||||||
"AT2860": AuradineFluxAT2860,
|
"AT2860": AuradineFluxAT2860,
|
||||||
"AT2880": AuradineFluxAT2880,
|
"AT2880": AuradineFluxAT2880,
|
||||||
@@ -494,7 +505,6 @@ class MinerFactory:
|
|||||||
)
|
)
|
||||||
except asyncio.TimeoutError:
|
except asyncio.TimeoutError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
miner = self._select_miner_from_classes(
|
miner = self._select_miner_from_classes(
|
||||||
ip,
|
ip,
|
||||||
miner_type=miner_type,
|
miner_type=miner_type,
|
||||||
@@ -666,7 +676,11 @@ class MinerFactory:
|
|||||||
return MinerTypes.LUX_OS
|
return MinerTypes.LUX_OS
|
||||||
if "ANTMINER" in upper_data and "DEVDETAILS" not in upper_data:
|
if "ANTMINER" in upper_data and "DEVDETAILS" not in upper_data:
|
||||||
return MinerTypes.ANTMINER
|
return MinerTypes.ANTMINER
|
||||||
if "INTCHAINS_QOMO" in upper_data:
|
if (
|
||||||
|
"INTCHAINS_QOMO" in upper_data
|
||||||
|
or "KDAMINER" in upper_data
|
||||||
|
or "BFGMINER" in upper_data
|
||||||
|
):
|
||||||
return MinerTypes.GOLDSHELL
|
return MinerTypes.GOLDSHELL
|
||||||
if "AVALON" in upper_data:
|
if "AVALON" in upper_data:
|
||||||
return MinerTypes.AVALONMINER
|
return MinerTypes.AVALONMINER
|
||||||
@@ -930,12 +944,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")
|
||||||
@@ -968,6 +986,7 @@ class MinerFactory:
|
|||||||
|
|
||||||
miner_factory = MinerFactory()
|
miner_factory = MinerFactory()
|
||||||
|
|
||||||
|
|
||||||
# abstracted version of get miner that is easier to access
|
# abstracted version of get miner that is easier to access
|
||||||
async def get_miner(ip: ipaddress.ip_address | str) -> AnyMiner:
|
async def get_miner(ip: ipaddress.ip_address | str) -> AnyMiner:
|
||||||
return await miner_factory.get_miner(ip)
|
return await miner_factory.get_miner(ip)
|
||||||
|
|||||||
25
pyasic/miners/goldshell/bfgminer/XBox/KDBox.py
Normal file
25
pyasic/miners/goldshell/bfgminer/XBox/KDBox.py
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Copyright 2022 Upstream Data Inc -
|
||||||
|
# -
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||||
|
# you may not use this file except in compliance with the License. -
|
||||||
|
# You may obtain a copy of the License at -
|
||||||
|
# -
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||||
|
# -
|
||||||
|
# Unless required by applicable law or agreed to in writing, software -
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||||
|
# See the License for the specific language governing permissions and -
|
||||||
|
# limitations under the License. -
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
from pyasic.miners.backends import GoldshellMiner
|
||||||
|
from pyasic.miners.models import KDBoxII, KDBoxPro
|
||||||
|
|
||||||
|
|
||||||
|
class GoldshellKDBoxII(GoldshellMiner, KDBoxII):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class GoldshellKDBoxPro(GoldshellMiner, KDBoxPro):
|
||||||
|
pass
|
||||||
16
pyasic/miners/goldshell/bfgminer/XBox/__init__.py
Normal file
16
pyasic/miners/goldshell/bfgminer/XBox/__init__.py
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Copyright 2022 Upstream Data Inc -
|
||||||
|
# -
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||||
|
# you may not use this file except in compliance with the License. -
|
||||||
|
# You may obtain a copy of the License at -
|
||||||
|
# -
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||||
|
# -
|
||||||
|
# Unless required by applicable law or agreed to in writing, software -
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||||
|
# See the License for the specific language governing permissions and -
|
||||||
|
# limitations under the License. -
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
from .KDBox import GoldshellKDBoxII, GoldshellKDBoxPro
|
||||||
@@ -14,4 +14,5 @@
|
|||||||
# limitations under the License. -
|
# limitations under the License. -
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
from .X5 import *
|
from .X5 import *
|
||||||
|
from .XBox import *
|
||||||
from .XMax import *
|
from .XMax import *
|
||||||
|
|||||||
@@ -39,3 +39,7 @@ class GoldshellMake(BaseMiner):
|
|||||||
|
|
||||||
class AuradineMake(BaseMiner):
|
class AuradineMake(BaseMiner):
|
||||||
make = "Auradine"
|
make = "Auradine"
|
||||||
|
|
||||||
|
|
||||||
|
class ePICMake(BaseMiner):
|
||||||
|
make = "ePIC"
|
||||||
|
|||||||
@@ -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 *
|
||||||
|
|||||||
23
pyasic/miners/models/antminer/X21/S21.py
Normal file
23
pyasic/miners/models/antminer/X21/S21.py
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Copyright 2022 Upstream Data Inc -
|
||||||
|
# -
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||||
|
# you may not use this file except in compliance with the License. -
|
||||||
|
# You may obtain a copy of the License at -
|
||||||
|
# -
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||||
|
# -
|
||||||
|
# Unless required by applicable law or agreed to in writing, software -
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||||
|
# See the License for the specific language governing permissions and -
|
||||||
|
# limitations under the License. -
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
from pyasic.miners.makes import AntMinerMake
|
||||||
|
|
||||||
|
|
||||||
|
class S21(AntMinerMake):
|
||||||
|
raw_model = "S21"
|
||||||
|
expected_chips = 108
|
||||||
|
expected_fans = 4
|
||||||
19
pyasic/miners/models/antminer/X21/__init__.py
Normal file
19
pyasic/miners/models/antminer/X21/__init__.py
Normal 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 .S21 import (
|
||||||
|
S21,
|
||||||
|
)
|
||||||
@@ -20,3 +20,4 @@ from .X9 import *
|
|||||||
from .X15 import *
|
from .X15 import *
|
||||||
from .X17 import *
|
from .X17 import *
|
||||||
from .X19 import *
|
from .X19 import *
|
||||||
|
from .X21 import *
|
||||||
|
|||||||
1
pyasic/miners/models/epic/__init__.py
Normal file
1
pyasic/miners/models/epic/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
from .blockminer import *
|
||||||
1
pyasic/miners/models/epic/blockminer/__init__.py
Normal file
1
pyasic/miners/models/epic/blockminer/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
from .blockminer import *
|
||||||
7
pyasic/miners/models/epic/blockminer/blockminer.py
Normal file
7
pyasic/miners/models/epic/blockminer/blockminer.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
from pyasic.miners.makes import ePICMake
|
||||||
|
|
||||||
|
|
||||||
|
class BlockMiner520i(ePICMake):
|
||||||
|
raw_model = "BlockMiner 520i"
|
||||||
|
expected_chips = 124
|
||||||
|
expected_fans = 4
|
||||||
30
pyasic/miners/models/goldshell/XBox/KDBox.py
Normal file
30
pyasic/miners/models/goldshell/XBox/KDBox.py
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Copyright 2022 Upstream Data Inc -
|
||||||
|
# -
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||||
|
# you may not use this file except in compliance with the License. -
|
||||||
|
# You may obtain a copy of the License at -
|
||||||
|
# -
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||||
|
# -
|
||||||
|
# Unless required by applicable law or agreed to in writing, software -
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||||
|
# See the License for the specific language governing permissions and -
|
||||||
|
# limitations under the License. -
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
from pyasic.miners.makes import GoldshellMake
|
||||||
|
|
||||||
|
|
||||||
|
class KDBoxII(GoldshellMake):
|
||||||
|
raw_model = "KD Box II"
|
||||||
|
expected_chips = 36
|
||||||
|
expected_fans = 2
|
||||||
|
expected_hashboards = 1
|
||||||
|
|
||||||
|
|
||||||
|
class KDBoxPro(GoldshellMake):
|
||||||
|
raw_model = "KD Box Pro"
|
||||||
|
expected_chips = 16
|
||||||
|
expected_fans = 2
|
||||||
|
expected_hashboards = 1
|
||||||
1
pyasic/miners/models/goldshell/XBox/__init__.py
Normal file
1
pyasic/miners/models/goldshell/XBox/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
from .KDBox import KDBoxII, KDBoxPro
|
||||||
@@ -14,4 +14,5 @@
|
|||||||
# limitations under the License. -
|
# limitations under the License. -
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
from .X5 import *
|
from .X5 import *
|
||||||
|
from .XBox import *
|
||||||
from .XMax import *
|
from .XMax import *
|
||||||
|
|||||||
@@ -20,3 +20,8 @@ from pyasic.miners.makes import WhatsMinerMake
|
|||||||
class M53SVH30(WhatsMinerMake):
|
class M53SVH30(WhatsMinerMake):
|
||||||
raw_model = "M53S VH30"
|
raw_model = "M53S VH30"
|
||||||
expected_fans = 0
|
expected_fans = 0
|
||||||
|
|
||||||
|
|
||||||
|
class M53SVJ40(WhatsMinerMake):
|
||||||
|
raw_model = "M53S VJ40"
|
||||||
|
expected_fans = 0
|
||||||
|
|||||||
22
pyasic/miners/models/whatsminer/M5X/M53S_Plus_Plus.py
Normal file
22
pyasic/miners/models/whatsminer/M5X/M53S_Plus_Plus.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Copyright 2022 Upstream Data Inc -
|
||||||
|
# -
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||||
|
# you may not use this file except in compliance with the License. -
|
||||||
|
# You may obtain a copy of the License at -
|
||||||
|
# -
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||||
|
# -
|
||||||
|
# Unless required by applicable law or agreed to in writing, software -
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||||
|
# See the License for the specific language governing permissions and -
|
||||||
|
# limitations under the License. -
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
from pyasic.miners.makes import WhatsMinerMake
|
||||||
|
|
||||||
|
|
||||||
|
class M53SPlusPlusVK10(WhatsMinerMake):
|
||||||
|
raw_model = "M53S++ VK10"
|
||||||
|
expected_fans = 0
|
||||||
@@ -42,8 +42,9 @@ from .M50S import (
|
|||||||
from .M50S_Plus import M50SPlusVH30, M50SPlusVH40, M50SPlusVJ30, M50SPlusVK20
|
from .M50S_Plus import M50SPlusVH30, M50SPlusVH40, M50SPlusVJ30, M50SPlusVK20
|
||||||
from .M50S_Plus_Plus import M50SPlusPlusVK10, M50SPlusPlusVK20, M50SPlusPlusVK30
|
from .M50S_Plus_Plus import M50SPlusPlusVK10, M50SPlusPlusVK20, M50SPlusPlusVK30
|
||||||
from .M53 import M53VH30
|
from .M53 import M53VH30
|
||||||
from .M53S import M53SVH30
|
from .M53S import M53SVH30, M53SVJ40
|
||||||
from .M53S_Plus import M53SPlusVJ30
|
from .M53S_Plus import M53SPlusVJ30
|
||||||
|
from .M53S_Plus_Plus import M53SPlusPlusVK10
|
||||||
from .M56 import M56VH30
|
from .M56 import M56VH30
|
||||||
from .M56S import M56SVH30
|
from .M56S import M56SVH30
|
||||||
from .M56S_Plus import M56SPlusVJ30
|
from .M56S_Plus import M56SPlusVJ30
|
||||||
|
|||||||
@@ -15,8 +15,12 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import M5X
|
from pyasic.miners.backends import M5X
|
||||||
from pyasic.miners.models import M53SVH30
|
from pyasic.miners.models import M53SVH30, M53SVJ40
|
||||||
|
|
||||||
|
|
||||||
class BTMinerM53SVH30(M5X, M53SVH30):
|
class BTMinerM53SVH30(M5X, M53SVH30):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class BTMinerM53SVJ40(M5X, M53SVJ40):
|
||||||
|
pass
|
||||||
|
|||||||
22
pyasic/miners/whatsminer/btminer/M5X/M53S_Plus_Plus.py
Normal file
22
pyasic/miners/whatsminer/btminer/M5X/M53S_Plus_Plus.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Copyright 2022 Upstream Data Inc -
|
||||||
|
# -
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||||
|
# you may not use this file except in compliance with the License. -
|
||||||
|
# You may obtain a copy of the License at -
|
||||||
|
# -
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||||
|
# -
|
||||||
|
# Unless required by applicable law or agreed to in writing, software -
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||||
|
# See the License for the specific language governing permissions and -
|
||||||
|
# limitations under the License. -
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
from pyasic.miners.backends import M5X
|
||||||
|
from pyasic.miners.models import M53SPlusPlusVK10
|
||||||
|
|
||||||
|
|
||||||
|
class BTMinerM53SPlusPlusVK10(M5X, M53SPlusPlusVK10):
|
||||||
|
pass
|
||||||
@@ -51,8 +51,9 @@ from .M50S_Plus_Plus import (
|
|||||||
BTMinerM50SPlusPlusVK30,
|
BTMinerM50SPlusPlusVK30,
|
||||||
)
|
)
|
||||||
from .M53 import BTMinerM53VH30
|
from .M53 import BTMinerM53VH30
|
||||||
from .M53S import BTMinerM53SVH30
|
from .M53S import BTMinerM53SVH30, BTMinerM53SVJ40
|
||||||
from .M53S_Plus import BTMinerM53SPlusVJ30
|
from .M53S_Plus import BTMinerM53SPlusVJ30
|
||||||
|
from .M53S_Plus_Plus import BTMinerM53SPlusPlusVK10
|
||||||
from .M56 import BTMinerM56VH30
|
from .M56 import BTMinerM56VH30
|
||||||
from .M56S import BTMinerM56SVH30
|
from .M56S import BTMinerM56SVH30
|
||||||
from .M56S_Plus import BTMinerM56SPlusVJ30
|
from .M56S_Plus import BTMinerM56SPlusVJ30
|
||||||
|
|||||||
@@ -107,3 +107,4 @@ def validate_command_output(data: dict) -> tuple[bool, str | None]:
|
|||||||
if data[key][0]["STATUS"][0]["STATUS"] not in ["S", "I"]:
|
if data[key][0]["STATUS"][0]["STATUS"] not in ["S", "I"]:
|
||||||
# this is an error
|
# this is an error
|
||||||
return False, f"{key}: " + data[key][0]["STATUS"][0]["Msg"]
|
return False, f"{key}: " + data[key][0]["STATUS"][0]["Msg"]
|
||||||
|
return True, None
|
||||||
|
|||||||
@@ -78,6 +78,9 @@ class BaseMinerRPCAPI:
|
|||||||
# send the command
|
# send the command
|
||||||
data = await self._send_bytes(json.dumps(cmd).encode("utf-8"))
|
data = await self._send_bytes(json.dumps(cmd).encode("utf-8"))
|
||||||
|
|
||||||
|
if data is None:
|
||||||
|
raise APIError("No data returned from the API.")
|
||||||
|
|
||||||
if data == b"Socket connect failed: Connection refused\n":
|
if data == b"Socket connect failed: Connection refused\n":
|
||||||
if not ignore_errors:
|
if not ignore_errors:
|
||||||
raise APIError(data.decode("utf-8"))
|
raise APIError(data.decode("utf-8"))
|
||||||
@@ -90,7 +93,7 @@ class BaseMinerRPCAPI:
|
|||||||
if not validation[0]:
|
if not validation[0]:
|
||||||
if not ignore_errors:
|
if not ignore_errors:
|
||||||
# validate the command succeeded
|
# validate the command succeeded
|
||||||
raise APIError(validation[1])
|
raise APIError(f"{command}: {validation[1]}")
|
||||||
if allow_warning:
|
if allow_warning:
|
||||||
logging.warning(
|
logging.warning(
|
||||||
f"{self.ip}: API Command Error: {command}: {validation[1]}"
|
f"{self.ip}: API Command Error: {command}: {validation[1]}"
|
||||||
@@ -162,7 +165,7 @@ class BaseMinerRPCAPI:
|
|||||||
for func in
|
for func in
|
||||||
# each function in self
|
# each function in self
|
||||||
dir(self)
|
dir(self)
|
||||||
if not func == "commands"
|
if not func in ["commands", "open_api"]
|
||||||
if callable(getattr(self, func)) and
|
if callable(getattr(self, func)) and
|
||||||
# no __ or _ methods
|
# no __ or _ methods
|
||||||
not func.startswith("__") and not func.startswith("_") and
|
not func.startswith("__") and not func.startswith("_") and
|
||||||
@@ -193,12 +196,16 @@ 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,
|
||||||
timeout: int = 100,
|
timeout: int = 100,
|
||||||
) -> bytes:
|
) -> bytes:
|
||||||
|
if port is None:
|
||||||
|
port = self.port
|
||||||
logging.debug(f"{self} - ([Hidden] Send Bytes) - Sending")
|
logging.debug(f"{self} - ([Hidden] Send Bytes) - Sending")
|
||||||
try:
|
try:
|
||||||
# get reader and writer streams
|
# get reader and writer streams
|
||||||
reader, writer = await asyncio.open_connection(str(self.ip), self.port)
|
reader, writer = await asyncio.open_connection(str(self.ip), port)
|
||||||
# handle OSError 121
|
# handle OSError 121
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
if e.errno == 121:
|
if e.errno == 121:
|
||||||
@@ -208,39 +215,14 @@ If you are sure you want to use this command please use API.send_command("{comma
|
|||||||
return b"{}"
|
return b"{}"
|
||||||
|
|
||||||
# send the command
|
# send the command
|
||||||
|
data_task = asyncio.create_task(self._read_bytes(reader, timeout=timeout))
|
||||||
logging.debug(f"{self} - ([Hidden] Send Bytes) - Writing")
|
logging.debug(f"{self} - ([Hidden] Send Bytes) - Writing")
|
||||||
writer.write(data)
|
writer.write(data)
|
||||||
logging.debug(f"{self} - ([Hidden] Send Bytes) - Draining")
|
logging.debug(f"{self} - ([Hidden] Send Bytes) - Draining")
|
||||||
await writer.drain()
|
await writer.drain()
|
||||||
try:
|
|
||||||
# TO address a situation where a whatsminer has an unknown PW -AND-
|
|
||||||
# Fix for stupid whatsminer bug, reboot/restart seem to not load properly in the loop
|
|
||||||
# have to receive, save the data, check if there is more data by reading with a short timeout
|
|
||||||
# append that data if there is more, and then onto the main loop.
|
|
||||||
# the password timeout might need to be longer than 1, but it seems to work for now.
|
|
||||||
ret_data = await asyncio.wait_for(reader.read(1), timeout=1)
|
|
||||||
except asyncio.TimeoutError:
|
|
||||||
return b"{}"
|
|
||||||
try:
|
|
||||||
ret_data += await asyncio.wait_for(reader.read(4096), timeout=timeout)
|
|
||||||
except ConnectionAbortedError:
|
|
||||||
return b"{}"
|
|
||||||
|
|
||||||
# loop to receive all the data
|
await data_task
|
||||||
logging.debug(f"{self} - ([Hidden] Send Bytes) - Receiving")
|
ret_data = data_task.result()
|
||||||
try:
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
d = await asyncio.wait_for(reader.read(4096), timeout=timeout)
|
|
||||||
if not d:
|
|
||||||
break
|
|
||||||
ret_data += d
|
|
||||||
except (asyncio.CancelledError, asyncio.TimeoutError) as e:
|
|
||||||
raise e
|
|
||||||
except (asyncio.CancelledError, asyncio.TimeoutError) as e:
|
|
||||||
raise e
|
|
||||||
except Exception as e:
|
|
||||||
logging.warning(f"{self} - ([Hidden] Send Bytes) - API Command Error {e}")
|
|
||||||
|
|
||||||
# close the connection
|
# close the connection
|
||||||
logging.debug(f"{self} - ([Hidden] Send Bytes) - Closing")
|
logging.debug(f"{self} - ([Hidden] Send Bytes) - Closing")
|
||||||
@@ -249,6 +231,19 @@ If you are sure you want to use this command please use API.send_command("{comma
|
|||||||
|
|
||||||
return ret_data
|
return ret_data
|
||||||
|
|
||||||
|
async def _read_bytes(self, reader: asyncio.StreamReader, timeout: int) -> bytes:
|
||||||
|
ret_data = b""
|
||||||
|
|
||||||
|
# loop to receive all the data
|
||||||
|
logging.debug(f"{self} - ([Hidden] Send Bytes) - Receiving")
|
||||||
|
try:
|
||||||
|
ret_data = await asyncio.wait_for(reader.read(), timeout=timeout)
|
||||||
|
except (asyncio.CancelledError, asyncio.TimeoutError) as e:
|
||||||
|
raise e
|
||||||
|
except Exception as e:
|
||||||
|
logging.warning(f"{self} - ([Hidden] Send Bytes) - API Command Error {e}")
|
||||||
|
return ret_data
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _load_api_data(data: bytes) -> dict:
|
def _load_api_data(data: bytes) -> dict:
|
||||||
# some json from the API returns with a null byte (\x00) on the end
|
# some json from the API returns with a null byte (\x00) on the end
|
||||||
|
|||||||
@@ -24,12 +24,13 @@ import logging
|
|||||||
import re
|
import re
|
||||||
from typing import Literal, Union
|
from typing import Literal, Union
|
||||||
|
|
||||||
|
import httpx
|
||||||
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
||||||
from passlib.handlers.md5_crypt import md5_crypt
|
from passlib.handlers.md5_crypt import md5_crypt
|
||||||
|
|
||||||
from pyasic import settings
|
from pyasic import settings
|
||||||
from pyasic.errors import APIError
|
from pyasic.errors import APIError
|
||||||
from pyasic.misc import api_min_version
|
from pyasic.misc import api_min_version, validate_command_output
|
||||||
from pyasic.rpc.base import BaseMinerRPCAPI
|
from pyasic.rpc.base import BaseMinerRPCAPI
|
||||||
|
|
||||||
### IMPORTANT ###
|
### IMPORTANT ###
|
||||||
@@ -240,6 +241,28 @@ class BTMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
ignore_errors: bool = False,
|
ignore_errors: bool = False,
|
||||||
timeout: int = 10,
|
timeout: int = 10,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
|
) -> dict:
|
||||||
|
try:
|
||||||
|
return await self._send_privileged_command(
|
||||||
|
command=command, ignore_errors=ignore_errors, timeout=timeout, **kwargs
|
||||||
|
)
|
||||||
|
except APIError as e:
|
||||||
|
if not e.message == "can't access write cmd":
|
||||||
|
raise
|
||||||
|
try:
|
||||||
|
await self.open_api()
|
||||||
|
except Exception as e:
|
||||||
|
raise APIError("Failed to open whatsminer API.") from e
|
||||||
|
return await self._send_privileged_command(
|
||||||
|
command=command, ignore_errors=ignore_errors, timeout=timeout, **kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
async def _send_privileged_command(
|
||||||
|
self,
|
||||||
|
command: Union[str, bytes],
|
||||||
|
ignore_errors: bool = False,
|
||||||
|
timeout: int = 10,
|
||||||
|
**kwargs,
|
||||||
) -> dict:
|
) -> dict:
|
||||||
logging.debug(
|
logging.debug(
|
||||||
f"{self} - (Send Privileged Command) - {command} " + f"with args {kwargs}"
|
f"{self} - (Send Privileged Command) - {command} " + f"with args {kwargs}"
|
||||||
@@ -253,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 {}
|
||||||
@@ -272,7 +295,7 @@ class BTMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
|
|
||||||
if not ignore_errors:
|
if not ignore_errors:
|
||||||
# if it fails to validate, it is likely an error
|
# if it fails to validate, it is likely an error
|
||||||
validation = self._validate_command_output(data)
|
validation = validate_command_output(data)
|
||||||
if not validation[0]:
|
if not validation[0]:
|
||||||
raise APIError(validation[1])
|
raise APIError(validation[1])
|
||||||
|
|
||||||
@@ -321,6 +344,36 @@ class BTMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
logging.debug(f"{self} - (Get Token) - Gathered token data: {self.token}")
|
logging.debug(f"{self} - (Get Token) - Gathered token data: {self.token}")
|
||||||
return self.token
|
return self.token
|
||||||
|
|
||||||
|
async def open_api(self):
|
||||||
|
async with httpx.AsyncClient() as c:
|
||||||
|
stage1_req = (
|
||||||
|
await c.post(
|
||||||
|
"https://wmt.pyasic.org/v1/stage1",
|
||||||
|
json={"ip": str(self.ip)},
|
||||||
|
follow_redirects=True,
|
||||||
|
)
|
||||||
|
).json()
|
||||||
|
stage1_res = binascii.hexlify(
|
||||||
|
await self._send_bytes(binascii.unhexlify(stage1_req), port=8889)
|
||||||
|
)
|
||||||
|
stage2_req = (
|
||||||
|
await c.post(
|
||||||
|
"https://wmt.pyasic.org/v1/stage2",
|
||||||
|
json={
|
||||||
|
"ip": str(self.ip),
|
||||||
|
"stage1_result": stage1_res.decode("utf-8"),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
).json()
|
||||||
|
for command in stage2_req:
|
||||||
|
try:
|
||||||
|
await self._send_bytes(
|
||||||
|
binascii.unhexlify(command), timeout=3, port=8889
|
||||||
|
)
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
pass
|
||||||
|
return True
|
||||||
|
|
||||||
#### PRIVILEGED COMMANDS ####
|
#### PRIVILEGED COMMANDS ####
|
||||||
# Please read the top of this file to learn
|
# Please read the top of this file to learn
|
||||||
# how to configure the Whatsminer API to
|
# how to configure the Whatsminer API to
|
||||||
@@ -607,10 +660,10 @@ class BTMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
A reply informing of the status of setting the frequency.
|
A reply informing of the status of setting the frequency.
|
||||||
</details>
|
</details>
|
||||||
"""
|
"""
|
||||||
if not -10 < percent < 100:
|
if not -100 < percent < 100:
|
||||||
raise APIError(
|
raise APIError(
|
||||||
f"Frequency % is outside of the allowed "
|
f"Frequency % is outside of the allowed "
|
||||||
f"range. Please set a % between -10 and "
|
f"range. Please set a % between -100 and "
|
||||||
f"100"
|
f"100"
|
||||||
)
|
)
|
||||||
return await self.send_privileged_command(
|
return await self.send_privileged_command(
|
||||||
|
|||||||
@@ -70,13 +70,15 @@ class BOSerWebAPI(BaseWebAPI):
|
|||||||
not func.startswith("__") and not func.startswith("_")
|
not func.startswith("__") and not func.startswith("_")
|
||||||
]
|
]
|
||||||
|
|
||||||
async def multicommand(self, *commands: str) -> dict:
|
async def multicommand(
|
||||||
|
self, *commands: str, ignore_errors: bool = False, allow_warning: bool = True
|
||||||
|
) -> dict:
|
||||||
result = {"multicommand": True}
|
result = {"multicommand": True}
|
||||||
tasks = {}
|
tasks = {}
|
||||||
for command in commands:
|
for command in commands:
|
||||||
try:
|
try:
|
||||||
tasks[command] = asyncio.create_task(getattr(self, command)())
|
tasks[command] = asyncio.create_task(getattr(self, command)())
|
||||||
except AttributeError:
|
except (APIError, AttributeError):
|
||||||
result["command"] = {}
|
result["command"] = {}
|
||||||
|
|
||||||
await asyncio.gather(*list(tasks.values()))
|
await asyncio.gather(*list(tasks.values()))
|
||||||
|
|||||||
@@ -59,17 +59,23 @@ class BOSMinerWebAPI(BaseWebAPI):
|
|||||||
return {}
|
return {}
|
||||||
raise APIError(f"LUCI web command failed: command={command}")
|
raise APIError(f"LUCI web command failed: command={command}")
|
||||||
|
|
||||||
async def multicommand(self, *commands: str) -> dict:
|
async def multicommand(
|
||||||
|
self, *commands: str, ignore_errors: bool = False, allow_warning: bool = True
|
||||||
|
) -> dict:
|
||||||
data = {}
|
data = {}
|
||||||
for command in commands:
|
for command in commands:
|
||||||
data[command] = await self.send_command(command, ignore_errors=True)
|
data[command] = await self.send_command(
|
||||||
|
command, ignore_errors=ignore_errors
|
||||||
|
)
|
||||||
return data
|
return data
|
||||||
|
|
||||||
async def auth(self, session: httpx.AsyncClient) -> None:
|
async def auth(self, session: httpx.AsyncClient) -> None:
|
||||||
login = {"luci_username": self.username, "luci_password": self.pwd}
|
login = {"luci_username": self.username, "luci_password": self.pwd}
|
||||||
url = f"http://{self.ip}:{self.port}/cgi-bin/luci"
|
url = f"http://{self.ip}:{self.port}/cgi-bin/luci"
|
||||||
headers = {
|
headers = {
|
||||||
"User-Agent": "BTC Tools v0.1", # only seems to respond if this user-agent is set
|
"User-Agent": (
|
||||||
|
"BTC Tools v0.1"
|
||||||
|
), # only seems to respond if this user-agent is set
|
||||||
"Content-Type": "application/x-www-form-urlencoded",
|
"Content-Type": "application/x-www-form-urlencoded",
|
||||||
}
|
}
|
||||||
await session.post(url, headers=headers, data=login)
|
await session.post(url, headers=headers, data=login)
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ 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:
|
||||||
for i in range(settings.get("get_data_retries", 1) + 1):
|
for retry_cnt in range(settings.get("get_data_retries", 1)):
|
||||||
try:
|
try:
|
||||||
if post:
|
if post:
|
||||||
response = await client.post(
|
response = await client.post(
|
||||||
@@ -61,16 +61,16 @@ class ePICWebAPI(BaseWebAPI):
|
|||||||
timeout=5,
|
timeout=5,
|
||||||
)
|
)
|
||||||
if not response.status_code == 200:
|
if not response.status_code == 200:
|
||||||
continue
|
if not ignore_errors:
|
||||||
|
raise APIError(
|
||||||
|
f"Web command {command} failed with status code {response.status_code}"
|
||||||
|
)
|
||||||
|
return {}
|
||||||
json_data = response.json()
|
json_data = response.json()
|
||||||
if json_data:
|
if json_data:
|
||||||
# The API can return a fail status if the miner cannot return the requested data. Catch this and pass
|
# The API can return a fail status if the miner cannot return the requested data. Catch this and pass
|
||||||
if (
|
if not json_data.get("result", True) and not post:
|
||||||
"result" in json_data
|
if retry_cnt < settings.get("get_data_retries", 1) - 1:
|
||||||
and json_data["result"] is False
|
|
||||||
and not post
|
|
||||||
):
|
|
||||||
if not i > settings.get("get_data_retries", 1):
|
|
||||||
continue
|
continue
|
||||||
if not ignore_errors:
|
if not ignore_errors:
|
||||||
raise APIError(json_data["error"])
|
raise APIError(json_data["error"])
|
||||||
@@ -95,19 +95,19 @@ class ePICWebAPI(BaseWebAPI):
|
|||||||
return await self.send_command("reboot", privileged=True)
|
return await self.send_command("reboot", privileged=True)
|
||||||
|
|
||||||
async def set_shutdown_temp(self, params: int) -> dict:
|
async def set_shutdown_temp(self, params: int) -> dict:
|
||||||
return await self.send_command("shutdowntemp", parameters=params)
|
return await self.send_command("shutdowntemp", param=params)
|
||||||
|
|
||||||
async def set_fan(self, params: dict) -> dict:
|
async def set_fan(self, params: dict) -> dict:
|
||||||
return await self.send_command("fanspeed", parameters=params)
|
return await self.send_command("fanspeed", param=params)
|
||||||
|
|
||||||
async def set_ptune_enable(self, params: bool) -> dict:
|
async def set_ptune_enable(self, params: bool) -> dict:
|
||||||
return await self.send_command("perpetualtune", parameters=params)
|
return await self.send_command("perpetualtune", param=params)
|
||||||
|
|
||||||
async def set_ptune_algo(self, params: dict) -> dict:
|
async def set_ptune_algo(self, params: dict) -> dict:
|
||||||
return await self.send_command("perpetualtune/algo", parameters=params)
|
return await self.send_command("perpetualtune/algo", param=params)
|
||||||
|
|
||||||
async def set_pools(self, params: dict) -> dict:
|
async def set_pools(self, params: dict) -> dict:
|
||||||
return await self.send_command("coin", parameters=params)
|
return await self.send_command("coin", param=params)
|
||||||
|
|
||||||
async def pause_mining(self) -> dict:
|
async def pause_mining(self) -> dict:
|
||||||
return await self.send_command("miner", param="Stop")
|
return await self.send_command("miner", param="Stop")
|
||||||
|
|||||||
@@ -138,5 +138,8 @@ class GoldshellWebAPI(BaseWebAPI):
|
|||||||
async def setting(self) -> dict:
|
async def setting(self) -> dict:
|
||||||
return await self.send_command("setting")
|
return await self.send_command("setting")
|
||||||
|
|
||||||
|
async def set_setting(self, values: dict):
|
||||||
|
await self.send_command("setting", **values)
|
||||||
|
|
||||||
async def status(self) -> dict:
|
async def status(self) -> dict:
|
||||||
return await self.send_command("status")
|
return await self.send_command("status")
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "pyasic"
|
name = "pyasic"
|
||||||
version = "0.50.1"
|
version = "0.54.0"
|
||||||
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"
|
||||||
|
|||||||
Reference in New Issue
Block a user