Compare commits
164 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7d682b62ac | ||
|
|
6739a1001f | ||
|
|
56e4a5307f | ||
|
|
88de27c9e7 | ||
|
|
a77113c4db | ||
|
|
c19945bb82 | ||
|
|
1756937d20 | ||
|
|
c7b7fe864b | ||
|
|
e7ebefd1bf | ||
|
|
4677efbc46 | ||
|
|
4b7a1a0495 | ||
|
|
cc4e7da4e5 | ||
|
|
a3d2d7d35e | ||
|
|
d67de98bd0 | ||
|
|
fd1a3e459b | ||
|
|
adcab694b5 | ||
|
|
2bb097272f | ||
|
|
896968dded | ||
|
|
56b8f7c5b3 | ||
|
|
0ed7559aef | ||
|
|
275d87e4fe | ||
|
|
c3ab814d77 | ||
|
|
05a8569205 | ||
|
|
b098cb8136 | ||
|
|
75fe7857e4 | ||
|
|
66797aced1 | ||
|
|
4a71e38078 | ||
|
|
9fb07e4fa3 | ||
|
|
74792771ec | ||
|
|
fa6e8a976d | ||
|
|
f20531cff5 | ||
|
|
8b1cbed9ce | ||
|
|
0194e13427 | ||
|
|
82d71abf54 | ||
|
|
e71cfadf6e | ||
|
|
18931c4e98 | ||
|
|
8622c080aa | ||
|
|
cb71b2a593 | ||
|
|
ff5956da41 | ||
|
|
acdafc2efd | ||
|
|
b8874092ad | ||
|
|
ad28ba0b3e | ||
|
|
0d90b60eef | ||
|
|
7c18c9f69c | ||
|
|
975560f46f | ||
|
|
bfe9cbf7d9 | ||
|
|
ccb5eb73db | ||
|
|
d143667bd6 | ||
|
|
87d809abc0 | ||
|
|
4dc5b1a541 | ||
|
|
ddd3e867f9 | ||
|
|
77480d3d69 | ||
|
|
0767c93002 | ||
|
|
e690e6dd3b | ||
|
|
d4665ed768 | ||
|
|
b90a92c0df | ||
|
|
50cfcf9796 | ||
|
|
5d204f09da | ||
|
|
4c0410322f | ||
|
|
fbb2b3f6e7 | ||
|
|
0f09fb49fc | ||
|
|
b0d063d6ed | ||
|
|
a68fe70af4 | ||
|
|
43c7ac281b | ||
|
|
a97ae55a06 | ||
|
|
4a3a6f4186 | ||
|
|
f976724ada | ||
|
|
2632bdaa30 | ||
|
|
91016d7b8c | ||
|
|
2b00e741ca | ||
|
|
d496c11d67 | ||
|
|
5880223517 | ||
|
|
394a5dcd0d | ||
|
|
7365275f46 | ||
|
|
0ecab5fdd4 | ||
|
|
ed0d9f73e4 | ||
|
|
28f4e16662 | ||
|
|
b9b0bff946 | ||
|
|
790718a5df | ||
|
|
96a0301f5e | ||
|
|
c57b019b7d | ||
|
|
af920c4dda | ||
|
|
f3d11788ed | ||
|
|
fd0e02af59 | ||
|
|
2a6c51d52c | ||
|
|
2d62e2070b | ||
|
|
b143bd70f0 | ||
|
|
605509c57c | ||
|
|
7036137b23 | ||
|
|
7a9ff535b4 | ||
|
|
f185bafe2a | ||
|
|
ab81d5d020 | ||
|
|
0965e6489b | ||
|
|
792e1c9cad | ||
|
|
a6721f971a | ||
|
|
8113d0e4e0 | ||
|
|
e3c7d3f8a2 | ||
|
|
6415de8c73 | ||
|
|
f2838cf31d | ||
|
|
fbd49b370d | ||
|
|
79f7296576 | ||
|
|
76f4ca5f89 | ||
|
|
477acda1c1 | ||
|
|
a57f343dcc | ||
|
|
36e9201ed4 | ||
|
|
c1525501d4 | ||
|
|
e4bb90a569 | ||
|
|
28642cc521 | ||
|
|
beae79ddec | ||
|
|
f02e10ab3d | ||
|
|
d0b9dff476 | ||
|
|
501e290839 | ||
|
|
a0daf37f80 | ||
|
|
8111b1ff4b | ||
|
|
754087afd6 | ||
|
|
5e16b6092c | ||
|
|
21636a75fa | ||
|
|
f124f5422a | ||
|
|
1e5d1a2528 | ||
|
|
1fcef07902 | ||
|
|
41e7dd8056 | ||
|
|
dccc35db5f | ||
|
|
0cfe59aa34 | ||
|
|
6fdd156fa3 | ||
|
|
e9fcf25ad3 | ||
|
|
a9422165ca | ||
|
|
0ea5ee8239 | ||
|
|
fba25cba61 | ||
|
|
343b5a1c50 | ||
|
|
63522aad81 | ||
|
|
b957aa7fba | ||
|
|
a71aa6868a | ||
|
|
6b50bf0cf7 | ||
|
|
d00444ec56 | ||
|
|
e7ed39fe39 | ||
|
|
168d68d0b2 | ||
|
|
63cddfdde3 | ||
|
|
4a642fd3da | ||
|
|
13c0407b2d | ||
|
|
794ed6d103 | ||
|
|
d0aeb5a6ce | ||
|
|
030f8c6079 | ||
|
|
7195e204ce | ||
|
|
962a328219 | ||
|
|
1cec2ca7f3 | ||
|
|
a3c4187411 | ||
|
|
18a2df5d9b | ||
|
|
4b4670201a | ||
|
|
92f70c9a76 | ||
|
|
8664b53991 | ||
|
|
31aeca2340 | ||
|
|
ae3d38603a | ||
|
|
e649348af2 | ||
|
|
ba58e80ec3 | ||
|
|
45e2c9a403 | ||
|
|
1bb597999d | ||
|
|
ba69a1de2c | ||
|
|
64265206c2 | ||
|
|
eec8f66b81 | ||
|
|
999e8ef318 | ||
|
|
eefb055a3f | ||
|
|
9c41a6b28f | ||
|
|
bf0e2e6cfe | ||
|
|
4a2adabe95 |
@@ -1,3 +1,6 @@
|
|||||||
|
ci:
|
||||||
|
skip:
|
||||||
|
- unittest
|
||||||
repos:
|
repos:
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
rev: v4.5.0
|
rev: v4.5.0
|
||||||
@@ -24,4 +27,3 @@ repos:
|
|||||||
'types': [python]
|
'types': [python]
|
||||||
args: ["-p '*test.py'"] # Probably this option is absolutely not needed.
|
args: ["-p '*test.py'"] # Probably this option is absolutely not needed.
|
||||||
pass_filenames: false
|
pass_filenames: false
|
||||||
stages: [commit]
|
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ def backend_str(backend: MinerTypes) -> str:
|
|||||||
return "Mara Firmware Miners"
|
return "Mara Firmware Miners"
|
||||||
case MinerTypes.BITAXE:
|
case MinerTypes.BITAXE:
|
||||||
return "Stock Firmware BitAxe Miners"
|
return "Stock Firmware BitAxe Miners"
|
||||||
|
case MinerTypes.ICERIVER:
|
||||||
|
return "Stock Firmware IceRiver Miners"
|
||||||
|
|
||||||
|
|
||||||
def create_url_str(mtype: str):
|
def create_url_str(mtype: str):
|
||||||
|
|||||||
@@ -8,3 +8,10 @@
|
|||||||
show_root_heading: false
|
show_root_heading: false
|
||||||
heading_level: 4
|
heading_level: 4
|
||||||
|
|
||||||
|
## Z15 Pro (Stock)
|
||||||
|
::: pyasic.miners.antminer.bmminer.X15.Z15.BMMinerZ15Pro
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
|||||||
@@ -225,6 +225,13 @@
|
|||||||
show_root_heading: false
|
show_root_heading: false
|
||||||
heading_level: 4
|
heading_level: 4
|
||||||
|
|
||||||
|
## S19 Pro+ Hydro (BOS+)
|
||||||
|
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19ProPlusHydro
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
## T19 (BOS+)
|
## T19 (BOS+)
|
||||||
::: pyasic.miners.antminer.bosminer.X19.T19.BOSMinerT19
|
::: pyasic.miners.antminer.bosminer.X19.T19.BOSMinerT19
|
||||||
handler: python
|
handler: python
|
||||||
@@ -267,6 +274,13 @@
|
|||||||
show_root_heading: false
|
show_root_heading: false
|
||||||
heading_level: 4
|
heading_level: 4
|
||||||
|
|
||||||
|
## S19j Pro (VNish)
|
||||||
|
::: pyasic.miners.antminer.vnish.X19.S19.VNishS19jPro
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
## S19a (VNish)
|
## S19a (VNish)
|
||||||
::: pyasic.miners.antminer.vnish.X19.S19.VNishS19a
|
::: pyasic.miners.antminer.vnish.X19.S19.VNishS19a
|
||||||
handler: python
|
handler: python
|
||||||
@@ -281,6 +295,13 @@
|
|||||||
show_root_heading: false
|
show_root_heading: false
|
||||||
heading_level: 4
|
heading_level: 4
|
||||||
|
|
||||||
|
## S19 Pro Hydro (VNish)
|
||||||
|
::: pyasic.miners.antminer.vnish.X19.S19.VNishS19ProHydro
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
## T19 (VNish)
|
## T19 (VNish)
|
||||||
::: pyasic.miners.antminer.vnish.X19.T19.VNishT19
|
::: pyasic.miners.antminer.vnish.X19.T19.VNishT19
|
||||||
handler: python
|
handler: python
|
||||||
|
|||||||
@@ -8,6 +8,13 @@
|
|||||||
show_root_heading: false
|
show_root_heading: false
|
||||||
heading_level: 4
|
heading_level: 4
|
||||||
|
|
||||||
|
## S21 Pro (Stock)
|
||||||
|
::: pyasic.miners.antminer.bmminer.X21.S21.BMMinerS21Pro
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
## T21 (Stock)
|
## T21 (Stock)
|
||||||
::: pyasic.miners.antminer.bmminer.X21.T21.BMMinerT21
|
::: pyasic.miners.antminer.bmminer.X21.T21.BMMinerT21
|
||||||
handler: python
|
handler: python
|
||||||
@@ -22,6 +29,13 @@
|
|||||||
show_root_heading: false
|
show_root_heading: false
|
||||||
heading_level: 4
|
heading_level: 4
|
||||||
|
|
||||||
|
## T21 (BOS+)
|
||||||
|
::: pyasic.miners.antminer.bosminer.X21.T21.BOSMinerT21
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
## S21 (VNish)
|
## S21 (VNish)
|
||||||
::: pyasic.miners.antminer.vnish.X21.S21.VNishS21
|
::: pyasic.miners.antminer.vnish.X21.S21.VNishS21
|
||||||
handler: python
|
handler: python
|
||||||
@@ -36,6 +50,13 @@
|
|||||||
show_root_heading: false
|
show_root_heading: false
|
||||||
heading_level: 4
|
heading_level: 4
|
||||||
|
|
||||||
|
## S21 Pro (ePIC)
|
||||||
|
::: pyasic.miners.antminer.epic.X21.S21.ePICS21Pro
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
## T21 (ePIC)
|
## T21 (ePIC)
|
||||||
::: pyasic.miners.antminer.epic.X21.T21.ePICT21
|
::: pyasic.miners.antminer.epic.X21.T21.ePICT21
|
||||||
handler: python
|
handler: python
|
||||||
|
|||||||
@@ -22,6 +22,20 @@
|
|||||||
show_root_heading: false
|
show_root_heading: false
|
||||||
heading_level: 4
|
heading_level: 4
|
||||||
|
|
||||||
|
## KA3 (Stock)
|
||||||
|
::: pyasic.miners.antminer.bmminer.X3.KA3.BMMinerKA3
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
## KS3 (Stock)
|
||||||
|
::: pyasic.miners.antminer.bmminer.X3.KS3.BMMinerKS3
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
## L3+ (VNish)
|
## L3+ (VNish)
|
||||||
::: pyasic.miners.antminer.vnish.X3.L3.VnishL3Plus
|
::: pyasic.miners.antminer.vnish.X3.L3.VnishL3Plus
|
||||||
handler: python
|
handler: python
|
||||||
|
|||||||
@@ -8,3 +8,10 @@
|
|||||||
show_root_heading: false
|
show_root_heading: false
|
||||||
heading_level: 4
|
heading_level: 4
|
||||||
|
|
||||||
|
## KS5 (Stock)
|
||||||
|
::: pyasic.miners.antminer.bmminer.X5.KS5.BMMinerKS5
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,13 @@
|
|||||||
show_root_heading: false
|
show_root_heading: false
|
||||||
heading_level: 4
|
heading_level: 4
|
||||||
|
|
||||||
|
## K7 (Stock)
|
||||||
|
::: pyasic.miners.antminer.bmminer.X7.K7.BMMinerK7
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
## L7 (VNish)
|
## L7 (VNish)
|
||||||
::: pyasic.miners.antminer.vnish.X7.L7.VnishL7
|
::: pyasic.miners.antminer.vnish.X7.L7.VnishL7
|
||||||
handler: python
|
handler: python
|
||||||
|
|||||||
10
docs/miners/avalonminer/nano.md
Normal file
10
docs/miners/avalonminer/nano.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# pyasic
|
||||||
|
## nano Models
|
||||||
|
|
||||||
|
## Avalon Nano 3 (Stock)
|
||||||
|
::: pyasic.miners.avalonminer.cgminer.nano.nano3.CGMinerAvalonNano3
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
45
docs/miners/iceriver/KSX.md
Normal file
45
docs/miners/iceriver/KSX.md
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
# pyasic
|
||||||
|
## KSX Models
|
||||||
|
|
||||||
|
## KS0 (Stock)
|
||||||
|
::: pyasic.miners.iceriver.iceminer.KSX.KS0.IceRiverKS0
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
## KS1 (Stock)
|
||||||
|
::: pyasic.miners.iceriver.iceminer.KSX.KS1.IceRiverKS1
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
## KS2 (Stock)
|
||||||
|
::: pyasic.miners.iceriver.iceminer.KSX.KS2.IceRiverKS2
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
## KS3 (Stock)
|
||||||
|
::: pyasic.miners.iceriver.iceminer.KSX.KS3.IceRiverKS3
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
## KS3L (Stock)
|
||||||
|
::: pyasic.miners.iceriver.iceminer.KSX.KS3.IceRiverKS3L
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
## KS3M (Stock)
|
||||||
|
::: pyasic.miners.iceriver.iceminer.KSX.KS3.IceRiverKS3M
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
17
docs/miners/innosilicon/A11X.md
Normal file
17
docs/miners/innosilicon/A11X.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# pyasic
|
||||||
|
## A11X Models
|
||||||
|
|
||||||
|
## A11 (Stock)
|
||||||
|
::: pyasic.miners.innosilicon.cgminer.A11X.A11.InnosiliconA11
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
## A11MX (Stock)
|
||||||
|
::: pyasic.miners.innosilicon.cgminer.A11X.A11M.InnosiliconA11MX
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
@@ -21,18 +21,22 @@ details {
|
|||||||
<li><a href="../antminer/X3#d3-stock">D3 (Stock)</a></li>
|
<li><a href="../antminer/X3#d3-stock">D3 (Stock)</a></li>
|
||||||
<li><a href="../antminer/X3#hs3-stock">HS3 (Stock)</a></li>
|
<li><a href="../antminer/X3#hs3-stock">HS3 (Stock)</a></li>
|
||||||
<li><a href="../antminer/X3#l3_1-stock">L3+ (Stock)</a></li>
|
<li><a href="../antminer/X3#l3_1-stock">L3+ (Stock)</a></li>
|
||||||
|
<li><a href="../antminer/X3#ka3-stock">KA3 (Stock)</a></li>
|
||||||
|
<li><a href="../antminer/X3#ks3-stock">KS3 (Stock)</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</details>
|
</details>
|
||||||
<details>
|
<details>
|
||||||
<summary>X5 Series:</summary>
|
<summary>X5 Series:</summary>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="../antminer/X5#dr5-stock">DR5 (Stock)</a></li>
|
<li><a href="../antminer/X5#dr5-stock">DR5 (Stock)</a></li>
|
||||||
|
<li><a href="../antminer/X5#ks5-stock">KS5 (Stock)</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</details>
|
</details>
|
||||||
<details>
|
<details>
|
||||||
<summary>X7 Series:</summary>
|
<summary>X7 Series:</summary>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="../antminer/X7#l7-stock">L7 (Stock)</a></li>
|
<li><a href="../antminer/X7#l7-stock">L7 (Stock)</a></li>
|
||||||
|
<li><a href="../antminer/X7#k7-stock">K7 (Stock)</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</details>
|
</details>
|
||||||
<details>
|
<details>
|
||||||
@@ -49,6 +53,7 @@ details {
|
|||||||
<summary>X15 Series:</summary>
|
<summary>X15 Series:</summary>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="../antminer/X15#z15-stock">Z15 (Stock)</a></li>
|
<li><a href="../antminer/X15#z15-stock">Z15 (Stock)</a></li>
|
||||||
|
<li><a href="../antminer/X15#z15-pro-stock">Z15 Pro (Stock)</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</details>
|
</details>
|
||||||
<details>
|
<details>
|
||||||
@@ -89,6 +94,7 @@ details {
|
|||||||
<summary>X21 Series:</summary>
|
<summary>X21 Series:</summary>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="../antminer/X21#s21-stock">S21 (Stock)</a></li>
|
<li><a href="../antminer/X21#s21-stock">S21 (Stock)</a></li>
|
||||||
|
<li><a href="../antminer/X21#s21-pro-stock">S21 Pro (Stock)</a></li>
|
||||||
<li><a href="../antminer/X21#t21-stock">T21 (Stock)</a></li>
|
<li><a href="../antminer/X21#t21-stock">T21 (Stock)</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</details>
|
</details>
|
||||||
@@ -277,6 +283,7 @@ details {
|
|||||||
<li><a href="../whatsminer/M5X#m50-vh60-stock">M50 VH60 (Stock)</a></li>
|
<li><a href="../whatsminer/M5X#m50-vh60-stock">M50 VH60 (Stock)</a></li>
|
||||||
<li><a href="../whatsminer/M5X#m50-vh70-stock">M50 VH70 (Stock)</a></li>
|
<li><a href="../whatsminer/M5X#m50-vh70-stock">M50 VH70 (Stock)</a></li>
|
||||||
<li><a href="../whatsminer/M5X#m50-vh80-stock">M50 VH80 (Stock)</a></li>
|
<li><a href="../whatsminer/M5X#m50-vh80-stock">M50 VH80 (Stock)</a></li>
|
||||||
|
<li><a href="../whatsminer/M5X#m50-vh90-stock">M50 VH90 (Stock)</a></li>
|
||||||
<li><a href="../whatsminer/M5X#m50-vj10-stock">M50 VJ10 (Stock)</a></li>
|
<li><a href="../whatsminer/M5X#m50-vj10-stock">M50 VJ10 (Stock)</a></li>
|
||||||
<li><a href="../whatsminer/M5X#m50-vj20-stock">M50 VJ20 (Stock)</a></li>
|
<li><a href="../whatsminer/M5X#m50-vj20-stock">M50 VJ20 (Stock)</a></li>
|
||||||
<li><a href="../whatsminer/M5X#m50-vj30-stock">M50 VJ30 (Stock)</a></li>
|
<li><a href="../whatsminer/M5X#m50-vj30-stock">M50 VJ30 (Stock)</a></li>
|
||||||
@@ -377,6 +384,12 @@ details {
|
|||||||
<li><a href="../avalonminer/A12X#avalon-1246-stock">Avalon 1246 (Stock)</a></li>
|
<li><a href="../avalonminer/A12X#avalon-1246-stock">Avalon 1246 (Stock)</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</details>
|
</details>
|
||||||
|
<details>
|
||||||
|
<summary>nano Series:</summary>
|
||||||
|
<ul>
|
||||||
|
<li><a href="../avalonminer/nano#avalon-nano-3-stock">Avalon Nano 3 (Stock)</a></li>
|
||||||
|
</ul>
|
||||||
|
</details>
|
||||||
</ul>
|
</ul>
|
||||||
</details>
|
</details>
|
||||||
<details>
|
<details>
|
||||||
@@ -394,6 +407,13 @@ details {
|
|||||||
<li><a href="../innosilicon/A10X#a10x-stock">A10X (Stock)</a></li>
|
<li><a href="../innosilicon/A10X#a10x-stock">A10X (Stock)</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</details>
|
</details>
|
||||||
|
<details>
|
||||||
|
<summary>A11X Series:</summary>
|
||||||
|
<ul>
|
||||||
|
<li><a href="../innosilicon/A11X#a11-stock">A11 (Stock)</a></li>
|
||||||
|
<li><a href="../innosilicon/A11X#a11mx-stock">A11MX (Stock)</a></li>
|
||||||
|
</ul>
|
||||||
|
</details>
|
||||||
</ul>
|
</ul>
|
||||||
</details>
|
</details>
|
||||||
<details>
|
<details>
|
||||||
@@ -461,6 +481,7 @@ details {
|
|||||||
<li><a href="../antminer/X19#s19k-pro-no-pic-bos_1">S19k Pro No PIC (BOS+)</a></li>
|
<li><a href="../antminer/X19#s19k-pro-no-pic-bos_1">S19k Pro No PIC (BOS+)</a></li>
|
||||||
<li><a href="../antminer/X19#s19k-pro-no-pic-bos_1">S19k Pro No PIC (BOS+)</a></li>
|
<li><a href="../antminer/X19#s19k-pro-no-pic-bos_1">S19k Pro No PIC (BOS+)</a></li>
|
||||||
<li><a href="../antminer/X19#s19-xp-bos_1">S19 XP (BOS+)</a></li>
|
<li><a href="../antminer/X19#s19-xp-bos_1">S19 XP (BOS+)</a></li>
|
||||||
|
<li><a href="../antminer/X19#s19-pro_1-hydro-bos_1">S19 Pro+ Hydro (BOS+)</a></li>
|
||||||
<li><a href="../antminer/X19#t19-bos_1">T19 (BOS+)</a></li>
|
<li><a href="../antminer/X19#t19-bos_1">T19 (BOS+)</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</details>
|
</details>
|
||||||
@@ -468,6 +489,7 @@ details {
|
|||||||
<summary>X21 Series:</summary>
|
<summary>X21 Series:</summary>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="../antminer/X21#s21-bos_1">S21 (BOS+)</a></li>
|
<li><a href="../antminer/X21#s21-bos_1">S21 (BOS+)</a></li>
|
||||||
|
<li><a href="../antminer/X21#t21-bos_1">T21 (BOS+)</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</details>
|
</details>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -503,8 +525,10 @@ details {
|
|||||||
<li><a href="../antminer/X19#s19-pro-vnish">S19 Pro (VNish)</a></li>
|
<li><a href="../antminer/X19#s19-pro-vnish">S19 Pro (VNish)</a></li>
|
||||||
<li><a href="../antminer/X19#s19j-vnish">S19j (VNish)</a></li>
|
<li><a href="../antminer/X19#s19j-vnish">S19j (VNish)</a></li>
|
||||||
<li><a href="../antminer/X19#s19j-pro-vnish">S19j Pro (VNish)</a></li>
|
<li><a href="../antminer/X19#s19j-pro-vnish">S19j Pro (VNish)</a></li>
|
||||||
|
<li><a href="../antminer/X19#s19j-pro-vnish">S19j Pro (VNish)</a></li>
|
||||||
<li><a href="../antminer/X19#s19a-vnish">S19a (VNish)</a></li>
|
<li><a href="../antminer/X19#s19a-vnish">S19a (VNish)</a></li>
|
||||||
<li><a href="../antminer/X19#s19a-pro-vnish">S19a Pro (VNish)</a></li>
|
<li><a href="../antminer/X19#s19a-pro-vnish">S19a Pro (VNish)</a></li>
|
||||||
|
<li><a href="../antminer/X19#s19-pro-hydro-vnish">S19 Pro Hydro (VNish)</a></li>
|
||||||
<li><a href="../antminer/X19#t19-vnish">T19 (VNish)</a></li>
|
<li><a href="../antminer/X19#t19-vnish">T19 (VNish)</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</details>
|
</details>
|
||||||
@@ -535,6 +559,7 @@ details {
|
|||||||
<summary>X21 Series:</summary>
|
<summary>X21 Series:</summary>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="../antminer/X21#s21-epic">S21 (ePIC)</a></li>
|
<li><a href="../antminer/X21#s21-epic">S21 (ePIC)</a></li>
|
||||||
|
<li><a href="../antminer/X21#s21-pro-epic">S21 Pro (ePIC)</a></li>
|
||||||
<li><a href="../antminer/X21#t21-epic">T21 (ePIC)</a></li>
|
<li><a href="../antminer/X21#t21-epic">T21 (ePIC)</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</details>
|
</details>
|
||||||
@@ -651,3 +676,19 @@ details {
|
|||||||
</details>
|
</details>
|
||||||
</ul>
|
</ul>
|
||||||
</details>
|
</details>
|
||||||
|
<details>
|
||||||
|
<summary>Stock Firmware IceRiver Miners:</summary>
|
||||||
|
<ul>
|
||||||
|
<details>
|
||||||
|
<summary>KSX Series:</summary>
|
||||||
|
<ul>
|
||||||
|
<li><a href="../iceriver/KSX#ks0-stock">KS0 (Stock)</a></li>
|
||||||
|
<li><a href="../iceriver/KSX#ks1-stock">KS1 (Stock)</a></li>
|
||||||
|
<li><a href="../iceriver/KSX#ks2-stock">KS2 (Stock)</a></li>
|
||||||
|
<li><a href="../iceriver/KSX#ks3-stock">KS3 (Stock)</a></li>
|
||||||
|
<li><a href="../iceriver/KSX#ks3l-stock">KS3L (Stock)</a></li>
|
||||||
|
<li><a href="../iceriver/KSX#ks3m-stock">KS3M (Stock)</a></li>
|
||||||
|
</ul>
|
||||||
|
</details>
|
||||||
|
</ul>
|
||||||
|
</details>
|
||||||
@@ -71,6 +71,13 @@
|
|||||||
show_root_heading: false
|
show_root_heading: false
|
||||||
heading_level: 4
|
heading_level: 4
|
||||||
|
|
||||||
|
## M50 VH90 (Stock)
|
||||||
|
::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VH90
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
## M50 VJ10 (Stock)
|
## M50 VJ10 (Stock)
|
||||||
::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VJ10
|
::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VJ10
|
||||||
handler: python
|
handler: python
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ Settings options:
|
|||||||
- `default_hive_web_password`
|
- `default_hive_web_password`
|
||||||
- `default_antminer_ssh_password`
|
- `default_antminer_ssh_password`
|
||||||
- `default_bosminer_ssh_password`
|
- `default_bosminer_ssh_password`
|
||||||
- `socket_linger_time`
|
|
||||||
|
|
||||||
|
|
||||||
### get
|
### get
|
||||||
|
|||||||
981
poetry.lock
generated
981
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -250,3 +250,9 @@ class MinerConfig:
|
|||||||
pools=PoolConfig.from_bitaxe(web_system_info),
|
pools=PoolConfig.from_bitaxe(web_system_info),
|
||||||
fan_mode=FanModeConfig.from_bitaxe(web_system_info),
|
fan_mode=FanModeConfig.from_bitaxe(web_system_info),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_iceriver(cls, web_userpanel: dict) -> "MinerConfig":
|
||||||
|
return cls(
|
||||||
|
pools=PoolConfig.from_iceriver(web_userpanel),
|
||||||
|
)
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ class MiningModePowerTune(MinerConfigValue):
|
|||||||
def as_boser(self) -> dict:
|
def as_boser(self) -> dict:
|
||||||
cfg = {
|
cfg = {
|
||||||
"set_performance_mode": SetPerformanceModeRequest(
|
"set_performance_mode": SetPerformanceModeRequest(
|
||||||
save_action=SaveAction.SAVE_ACTION_SAVE_AND_APPLY,
|
save_action=SaveAction.SAVE_AND_APPLY,
|
||||||
mode=PerformanceMode(
|
mode=PerformanceMode(
|
||||||
tuner_mode=TunerPerformanceMode(
|
tuner_mode=TunerPerformanceMode(
|
||||||
power_target=PowerTargetMode(
|
power_target=PowerTargetMode(
|
||||||
@@ -275,7 +275,7 @@ class MiningModeHashrateTune(MinerConfigValue):
|
|||||||
def as_boser(self) -> dict:
|
def as_boser(self) -> dict:
|
||||||
cfg = {
|
cfg = {
|
||||||
"set_performance_mode": SetPerformanceModeRequest(
|
"set_performance_mode": SetPerformanceModeRequest(
|
||||||
save_action=SaveAction.SAVE_ACTION_SAVE_AND_APPLY,
|
save_action=SaveAction.SAVE_AND_APPLY,
|
||||||
mode=PerformanceMode(
|
mode=PerformanceMode(
|
||||||
tuner_mode=TunerPerformanceMode(
|
tuner_mode=TunerPerformanceMode(
|
||||||
hashrate_target=HashrateTargetMode(
|
hashrate_target=HashrateTargetMode(
|
||||||
|
|||||||
@@ -222,6 +222,14 @@ class Pool(MinerConfigValue):
|
|||||||
password=web_system_info.get("stratumPassword", ""),
|
password=web_system_info.get("stratumPassword", ""),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_iceriver(cls, web_pool: dict) -> "Pool":
|
||||||
|
return cls(
|
||||||
|
url=web_pool["addr"],
|
||||||
|
user=web_pool["user"],
|
||||||
|
password=web_pool["pass"],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class PoolGroup(MinerConfigValue):
|
class PoolGroup(MinerConfigValue):
|
||||||
@@ -402,6 +410,15 @@ class PoolGroup(MinerConfigValue):
|
|||||||
def from_bitaxe(cls, web_system_info: dict) -> "PoolGroup":
|
def from_bitaxe(cls, web_system_info: dict) -> "PoolGroup":
|
||||||
return cls(pools=[Pool.from_bitaxe(web_system_info)])
|
return cls(pools=[Pool.from_bitaxe(web_system_info)])
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_iceriver(cls, web_userpanel: dict) -> "PoolGroup":
|
||||||
|
return cls(
|
||||||
|
pools=[
|
||||||
|
Pool.from_iceriver(web_pool)
|
||||||
|
for web_pool in web_userpanel["data"]["pools"]
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class PoolConfig(MinerConfigValue):
|
class PoolConfig(MinerConfigValue):
|
||||||
@@ -467,7 +484,7 @@ class PoolConfig(MinerConfigValue):
|
|||||||
def as_boser(self, user_suffix: str = None) -> dict:
|
def as_boser(self, user_suffix: str = None) -> dict:
|
||||||
return {
|
return {
|
||||||
"set_pool_groups": SetPoolGroupsRequest(
|
"set_pool_groups": SetPoolGroupsRequest(
|
||||||
save_action=SaveAction.SAVE_ACTION_SAVE_AND_APPLY,
|
save_action=SaveAction.SAVE_AND_APPLY,
|
||||||
pool_groups=[g.as_boser(user_suffix=user_suffix) for g in self.groups],
|
pool_groups=[g.as_boser(user_suffix=user_suffix) for g in self.groups],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -568,3 +585,7 @@ class PoolConfig(MinerConfigValue):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def from_bitaxe(cls, web_system_info: dict) -> "PoolConfig":
|
def from_bitaxe(cls, web_system_info: dict) -> "PoolConfig":
|
||||||
return cls(groups=[PoolGroup.from_bitaxe(web_system_info)])
|
return cls(groups=[PoolGroup.from_bitaxe(web_system_info)])
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_iceriver(cls, web_userpanel: dict) -> "PoolConfig":
|
||||||
|
return cls(groups=[PoolGroup.from_iceriver(web_userpanel)])
|
||||||
|
|||||||
@@ -23,13 +23,13 @@ from typing import Any, List, Union
|
|||||||
|
|
||||||
from pyasic.config import MinerConfig
|
from pyasic.config import MinerConfig
|
||||||
from pyasic.config.mining import MiningModePowerTune
|
from pyasic.config.mining import MiningModePowerTune
|
||||||
|
from pyasic.data.pools import PoolMetrics
|
||||||
|
|
||||||
from .boards import HashBoard
|
from .boards import HashBoard
|
||||||
from .device import DeviceInfo
|
from .device import DeviceInfo
|
||||||
from .error_codes import BraiinsOSError, InnosiliconError, WhatsminerError, X19Error
|
from .error_codes import BraiinsOSError, InnosiliconError, WhatsminerError, X19Error
|
||||||
from .fans import Fan
|
from .fans import Fan
|
||||||
from .hashrate import AlgoHashRate, HashUnit
|
from .hashrate import AlgoHashRate, HashUnit
|
||||||
from pyasic.data.pools import PoolMetrics
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ from urllib.parse import urlparse
|
|||||||
class Scheme(Enum):
|
class Scheme(Enum):
|
||||||
STRATUM_V1 = "stratum+tcp"
|
STRATUM_V1 = "stratum+tcp"
|
||||||
STRATUM_V2 = "stratum2+tcp"
|
STRATUM_V2 = "stratum2+tcp"
|
||||||
|
STRATUM_V1_SSL = "stratum+ssl"
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@@ -25,7 +26,10 @@ class PoolUrl:
|
|||||||
@classmethod
|
@classmethod
|
||||||
def from_str(cls, url: str) -> "PoolUrl":
|
def from_str(cls, url: str) -> "PoolUrl":
|
||||||
parsed_url = urlparse(url)
|
parsed_url = urlparse(url)
|
||||||
|
if not parsed_url.scheme.strip() == "":
|
||||||
scheme = Scheme(parsed_url.scheme)
|
scheme = Scheme(parsed_url.scheme)
|
||||||
|
else:
|
||||||
|
scheme = Scheme.STRATUM_V1
|
||||||
host = parsed_url.hostname
|
host = parsed_url.hostname
|
||||||
port = parsed_url.port
|
port = parsed_url.port
|
||||||
pubkey = parsed_url.path.lstrip("/") if scheme == Scheme.STRATUM_V2 else None
|
pubkey = parsed_url.path.lstrip("/") if scheme == Scheme.STRATUM_V2 else None
|
||||||
@@ -85,6 +89,8 @@ class PoolMetrics:
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def _calculate_percentage(value: int, total: int) -> float:
|
def _calculate_percentage(value: int, total: int) -> float:
|
||||||
"""Calculate the percentage."""
|
"""Calculate the percentage."""
|
||||||
|
if value is None or total is None:
|
||||||
|
return 0
|
||||||
if total == 0:
|
if total == 0:
|
||||||
return 0
|
return 0
|
||||||
return (value / total) * 100
|
return (value / total) * 100
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ class MinerMake(str, Enum):
|
|||||||
AURADINE = "Auradine"
|
AURADINE = "Auradine"
|
||||||
EPIC = "ePIC"
|
EPIC = "ePIC"
|
||||||
BITAXE = "BitAxe"
|
BITAXE = "BitAxe"
|
||||||
|
ICERIVER = "IceRiver"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.value
|
return self.value
|
||||||
|
|||||||
@@ -5,14 +5,19 @@ class AntminerModels(str, Enum):
|
|||||||
D3 = "D3"
|
D3 = "D3"
|
||||||
HS3 = "HS3"
|
HS3 = "HS3"
|
||||||
L3Plus = "L3+"
|
L3Plus = "L3+"
|
||||||
|
KA3 = "KA3"
|
||||||
|
KS3 = "KS3"
|
||||||
DR5 = "DR5"
|
DR5 = "DR5"
|
||||||
|
KS5 = "KS5"
|
||||||
L7 = "L7"
|
L7 = "L7"
|
||||||
|
K7 = "K7"
|
||||||
E9Pro = "E9Pro"
|
E9Pro = "E9Pro"
|
||||||
S9 = "S9"
|
S9 = "S9"
|
||||||
S9i = "S9i"
|
S9i = "S9i"
|
||||||
S9j = "S9j"
|
S9j = "S9j"
|
||||||
T9 = "T9"
|
T9 = "T9"
|
||||||
Z15 = "Z15"
|
Z15 = "Z15"
|
||||||
|
Z15Pro = "Z15 Pro"
|
||||||
S17 = "S17"
|
S17 = "S17"
|
||||||
S17Plus = "S17+"
|
S17Plus = "S17+"
|
||||||
S17Pro = "S17 Pro"
|
S17Pro = "S17 Pro"
|
||||||
@@ -44,6 +49,7 @@ class AntminerModels(str, Enum):
|
|||||||
S19kProNoPIC = "S19k Pro No PIC"
|
S19kProNoPIC = "S19k Pro No PIC"
|
||||||
T19 = "T19"
|
T19 = "T19"
|
||||||
S21 = "S21"
|
S21 = "S21"
|
||||||
|
S21Pro = "S21 Pro"
|
||||||
T21 = "T21"
|
T21 = "T21"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
@@ -219,6 +225,7 @@ class WhatsminerModels(str, Enum):
|
|||||||
M50VH60 = "M50 VH60"
|
M50VH60 = "M50 VH60"
|
||||||
M50VH70 = "M50 VH70"
|
M50VH70 = "M50 VH70"
|
||||||
M50VH80 = "M50 VH80"
|
M50VH80 = "M50 VH80"
|
||||||
|
M50VH90 = "M50 VH90"
|
||||||
M50VJ10 = "M50 VJ10"
|
M50VJ10 = "M50 VJ10"
|
||||||
M50VJ20 = "M50 VJ20"
|
M50VJ20 = "M50 VJ20"
|
||||||
M50VJ30 = "M50 VJ30"
|
M50VJ30 = "M50 VJ30"
|
||||||
@@ -283,6 +290,7 @@ class AvalonminerModels(str, Enum):
|
|||||||
Avalon1066 = "Avalon 1066"
|
Avalon1066 = "Avalon 1066"
|
||||||
Avalon1166Pro = "Avalon 1166 Pro"
|
Avalon1166Pro = "Avalon 1166 Pro"
|
||||||
Avalon1246 = "Avalon 1246"
|
Avalon1246 = "Avalon 1246"
|
||||||
|
AvalonNano3 = "Avalon Nano 3"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.value
|
return self.value
|
||||||
@@ -291,6 +299,8 @@ class AvalonminerModels(str, Enum):
|
|||||||
class InnosiliconModels(str, Enum):
|
class InnosiliconModels(str, Enum):
|
||||||
T3HPlus = "T3H+"
|
T3HPlus = "T3H+"
|
||||||
A10X = "A10X"
|
A10X = "A10X"
|
||||||
|
A11 = "A11"
|
||||||
|
A11MX = "A11MX"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.value
|
return self.value
|
||||||
@@ -338,6 +348,18 @@ class BitAxeModels(str, Enum):
|
|||||||
return self.value
|
return self.value
|
||||||
|
|
||||||
|
|
||||||
|
class IceRiverModels(str, Enum):
|
||||||
|
KS0 = "KS0"
|
||||||
|
KS1 = "KS1"
|
||||||
|
KS2 = "KS2"
|
||||||
|
KS3 = "KS3"
|
||||||
|
KS3L = "KS3L"
|
||||||
|
KS3M = "KS3M"
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.value
|
||||||
|
|
||||||
|
|
||||||
class MinerModel:
|
class MinerModel:
|
||||||
ANTMINER = AntminerModels
|
ANTMINER = AntminerModels
|
||||||
WHATSMINER = WhatsminerModels
|
WHATSMINER = WhatsminerModels
|
||||||
@@ -347,3 +369,4 @@ class MinerModel:
|
|||||||
AURADINE = AuradineModels
|
AURADINE = AuradineModels
|
||||||
EPIC = ePICModels
|
EPIC = ePICModels
|
||||||
BITAXE = BitAxeModels
|
BITAXE = BitAxeModels
|
||||||
|
ICERIVER = IceRiverModels
|
||||||
|
|||||||
22
pyasic/miners/antminer/bmminer/X15/Z15.py
Normal file
22
pyasic/miners/antminer/bmminer/X15/Z15.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Copyright 2022 Upstream Data Inc -
|
||||||
|
# -
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||||
|
# you may not use this file except in compliance with the License. -
|
||||||
|
# You may obtain a copy of the License at -
|
||||||
|
# -
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||||
|
# -
|
||||||
|
# Unless required by applicable law or agreed to in writing, software -
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||||
|
# See the License for the specific language governing permissions and -
|
||||||
|
# limitations under the License. -
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
from pyasic.miners.backends import AntminerModern
|
||||||
|
from pyasic.miners.device.models import Z15Pro
|
||||||
|
|
||||||
|
|
||||||
|
class BMMinerZ15Pro(AntminerModern, Z15Pro):
|
||||||
|
pass
|
||||||
16
pyasic/miners/antminer/bmminer/X15/__init__.py
Normal file
16
pyasic/miners/antminer/bmminer/X15/__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 .Z15 import BMMinerZ15Pro
|
||||||
@@ -23,6 +23,7 @@ from .S19 import (
|
|||||||
BMMinerS19j,
|
BMMinerS19j,
|
||||||
BMMinerS19jNoPIC,
|
BMMinerS19jNoPIC,
|
||||||
BMMinerS19jPro,
|
BMMinerS19jPro,
|
||||||
|
BMMinerS19KPro,
|
||||||
BMMinerS19L,
|
BMMinerS19L,
|
||||||
BMMinerS19Plus,
|
BMMinerS19Plus,
|
||||||
BMMinerS19Pro,
|
BMMinerS19Pro,
|
||||||
@@ -30,6 +31,5 @@ from .S19 import (
|
|||||||
BMMinerS19ProPlus,
|
BMMinerS19ProPlus,
|
||||||
BMMinerS19ProPlusHydro,
|
BMMinerS19ProPlusHydro,
|
||||||
BMMinerS19XP,
|
BMMinerS19XP,
|
||||||
BMMinerS19KPro,
|
|
||||||
)
|
)
|
||||||
from .T19 import BMMinerT19
|
from .T19 import BMMinerT19
|
||||||
|
|||||||
@@ -15,8 +15,12 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import AntminerModern
|
from pyasic.miners.backends import AntminerModern
|
||||||
from pyasic.miners.device.models import S21
|
from pyasic.miners.device.models import S21, S21Pro
|
||||||
|
|
||||||
|
|
||||||
class BMMinerS21(AntminerModern, S21):
|
class BMMinerS21(AntminerModern, S21):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class BMMinerS21Pro(AntminerModern, S21Pro):
|
||||||
|
pass
|
||||||
|
|||||||
@@ -13,5 +13,5 @@
|
|||||||
# See the License for the specific language governing permissions and -
|
# See the License for the specific language governing permissions and -
|
||||||
# limitations under the License. -
|
# limitations under the License. -
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
from .S21 import BMMinerS21
|
from .S21 import BMMinerS21, BMMinerS21Pro
|
||||||
from .T21 import BMMinerT21
|
from .T21 import BMMinerT21
|
||||||
|
|||||||
22
pyasic/miners/antminer/bmminer/X3/KA3.py
Normal file
22
pyasic/miners/antminer/bmminer/X3/KA3.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Copyright 2022 Upstream Data Inc -
|
||||||
|
# -
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||||
|
# you may not use this file except in compliance with the License. -
|
||||||
|
# You may obtain a copy of the License at -
|
||||||
|
# -
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||||
|
# -
|
||||||
|
# Unless required by applicable law or agreed to in writing, software -
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||||
|
# See the License for the specific language governing permissions and -
|
||||||
|
# limitations under the License. -
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
from pyasic.miners.backends import AntminerModern
|
||||||
|
from pyasic.miners.device.models import KA3
|
||||||
|
|
||||||
|
|
||||||
|
class BMMinerKA3(AntminerModern, KA3):
|
||||||
|
pass
|
||||||
22
pyasic/miners/antminer/bmminer/X3/KS3.py
Normal file
22
pyasic/miners/antminer/bmminer/X3/KS3.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Copyright 2022 Upstream Data Inc -
|
||||||
|
# -
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||||
|
# you may not use this file except in compliance with the License. -
|
||||||
|
# You may obtain a copy of the License at -
|
||||||
|
# -
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||||
|
# -
|
||||||
|
# Unless required by applicable law or agreed to in writing, software -
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||||
|
# See the License for the specific language governing permissions and -
|
||||||
|
# limitations under the License. -
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
from pyasic.miners.backends import AntminerModern
|
||||||
|
from pyasic.miners.device.models.antminer import KS3
|
||||||
|
|
||||||
|
|
||||||
|
class BMMinerKS3(AntminerModern, KS3):
|
||||||
|
pass
|
||||||
@@ -14,4 +14,6 @@
|
|||||||
# limitations under the License. -
|
# limitations under the License. -
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
from .HS3 import BMMinerHS3
|
from .HS3 import BMMinerHS3
|
||||||
|
from .KA3 import BMMinerKA3
|
||||||
|
from .KS3 import BMMinerKS3
|
||||||
from .L3 import BMMinerL3Plus
|
from .L3 import BMMinerL3Plus
|
||||||
|
|||||||
21
pyasic/miners/antminer/bmminer/X5/KS5.py
Normal file
21
pyasic/miners/antminer/bmminer/X5/KS5.py
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Copyright 2022 Upstream Data Inc -
|
||||||
|
# -
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||||
|
# you may not use this file except in compliance with the License. -
|
||||||
|
# You may obtain a copy of the License at -
|
||||||
|
# -
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||||
|
# -
|
||||||
|
# Unless required by applicable law or agreed to in writing, software -
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||||
|
# See the License for the specific language governing permissions and -
|
||||||
|
# limitations under the License. -
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
from pyasic.miners.backends import AntminerModern
|
||||||
|
from pyasic.miners.device.models import KS5
|
||||||
|
|
||||||
|
|
||||||
|
class BMMinerKS5(AntminerModern, KS5):
|
||||||
|
supports_shutdown = False
|
||||||
16
pyasic/miners/antminer/bmminer/X5/__init__.py
Normal file
16
pyasic/miners/antminer/bmminer/X5/__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 .KS5 import BMMinerKS5
|
||||||
21
pyasic/miners/antminer/bmminer/X7/K7.py
Normal file
21
pyasic/miners/antminer/bmminer/X7/K7.py
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Copyright 2022 Upstream Data Inc -
|
||||||
|
# -
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||||
|
# you may not use this file except in compliance with the License. -
|
||||||
|
# You may obtain a copy of the License at -
|
||||||
|
# -
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||||
|
# -
|
||||||
|
# Unless required by applicable law or agreed to in writing, software -
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||||
|
# See the License for the specific language governing permissions and -
|
||||||
|
# limitations under the License. -
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
from pyasic.miners.backends import AntminerModern
|
||||||
|
from pyasic.miners.device.models import K7
|
||||||
|
|
||||||
|
|
||||||
|
class BMMinerK7(AntminerModern, K7):
|
||||||
|
pass
|
||||||
@@ -13,4 +13,5 @@
|
|||||||
# See the License for the specific language governing permissions and -
|
# See the License for the specific language governing permissions and -
|
||||||
# limitations under the License. -
|
# limitations under the License. -
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
from .K7 import BMMinerK7
|
||||||
from .L7 import BMMinerL7
|
from .L7 import BMMinerL7
|
||||||
|
|||||||
@@ -14,8 +14,10 @@
|
|||||||
# limitations under the License. -
|
# limitations under the License. -
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
from .X3 import *
|
from .X3 import *
|
||||||
|
from .X5 import *
|
||||||
from .X7 import *
|
from .X7 import *
|
||||||
from .X9 import *
|
from .X9 import *
|
||||||
|
from .X15 import *
|
||||||
from .X17 import *
|
from .X17 import *
|
||||||
from .X19 import *
|
from .X19 import *
|
||||||
from .X21 import *
|
from .X21 import *
|
||||||
|
|||||||
22
pyasic/miners/antminer/bosminer/X21/T21.py
Normal file
22
pyasic/miners/antminer/bosminer/X21/T21.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Copyright 2022 Upstream Data Inc -
|
||||||
|
# -
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||||
|
# you may not use this file except in compliance with the License. -
|
||||||
|
# You may obtain a copy of the License at -
|
||||||
|
# -
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||||
|
# -
|
||||||
|
# Unless required by applicable law or agreed to in writing, software -
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||||
|
# See the License for the specific language governing permissions and -
|
||||||
|
# limitations under the License. -
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
from pyasic.miners.backends import BOSer
|
||||||
|
from pyasic.miners.device.models import T21
|
||||||
|
|
||||||
|
|
||||||
|
class BOSMinerT21(BOSer, T21):
|
||||||
|
pass
|
||||||
@@ -15,3 +15,4 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from .S21 import BOSMinerS21
|
from .S21 import BOSMinerS21
|
||||||
|
from .T21 import BOSMinerT21
|
||||||
|
|||||||
@@ -15,8 +15,12 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import ePIC
|
from pyasic.miners.backends import ePIC
|
||||||
from pyasic.miners.device.models import S21
|
from pyasic.miners.device.models import S21, S21Pro
|
||||||
|
|
||||||
|
|
||||||
class ePICS21(ePIC, S21):
|
class ePICS21(ePIC, S21):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ePICS21Pro(ePIC, S21Pro):
|
||||||
|
pass
|
||||||
|
|||||||
@@ -14,10 +14,5 @@
|
|||||||
# limitations under the License. -
|
# limitations under the License. -
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from .S21 import (
|
from .S21 import ePICS21, ePICS21Pro
|
||||||
ePICS21,
|
from .T21 import ePICT21
|
||||||
)
|
|
||||||
|
|
||||||
from .T21 import (
|
|
||||||
ePICT21,
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -20,3 +20,4 @@ from .A9X import *
|
|||||||
from .A10X import *
|
from .A10X import *
|
||||||
from .A11X import *
|
from .A11X import *
|
||||||
from .A12X import *
|
from .A12X import *
|
||||||
|
from .nano import *
|
||||||
|
|||||||
17
pyasic/miners/avalonminer/cgminer/nano/__init__.py
Normal file
17
pyasic/miners/avalonminer/cgminer/nano/__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 .nano3 import CGMinerAvalonNano3
|
||||||
22
pyasic/miners/avalonminer/cgminer/nano/nano3.py
Normal file
22
pyasic/miners/avalonminer/cgminer/nano/nano3.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Copyright 2022 Upstream Data Inc -
|
||||||
|
# -
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||||
|
# you may not use this file except in compliance with the License. -
|
||||||
|
# You may obtain a copy of the License at -
|
||||||
|
# -
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||||
|
# -
|
||||||
|
# Unless required by applicable law or agreed to in writing, software -
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||||
|
# See the License for the specific language governing permissions and -
|
||||||
|
# limitations under the License. -
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
from pyasic.miners.backends import AvalonMiner
|
||||||
|
from pyasic.miners.device.models import AvalonNano3
|
||||||
|
|
||||||
|
|
||||||
|
class CGMinerAvalonNano3(AvalonMiner, AvalonNano3):
|
||||||
|
pass
|
||||||
@@ -24,6 +24,7 @@ from .cgminer import CGMiner
|
|||||||
from .epic import ePIC
|
from .epic import ePIC
|
||||||
from .goldshell import GoldshellMiner
|
from .goldshell import GoldshellMiner
|
||||||
from .hiveon import Hiveon
|
from .hiveon import Hiveon
|
||||||
|
from .iceriver import IceRiver
|
||||||
from .innosilicon import Innosilicon
|
from .innosilicon import Innosilicon
|
||||||
from .luxminer import LUXMiner
|
from .luxminer import LUXMiner
|
||||||
from .marathon import MaraMiner
|
from .marathon import MaraMiner
|
||||||
|
|||||||
@@ -14,6 +14,8 @@
|
|||||||
# limitations under the License. -
|
# limitations under the License. -
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
import logging
|
||||||
|
from pathlib import Path
|
||||||
from typing import List, Optional, Union
|
from typing import List, Optional, Union
|
||||||
|
|
||||||
from pyasic.config import MinerConfig, MiningModeConfig
|
from pyasic.config import MinerConfig, MiningModeConfig
|
||||||
@@ -124,6 +126,41 @@ class AntminerModern(BMMiner):
|
|||||||
# break
|
# break
|
||||||
# await asyncio.sleep(1)
|
# await asyncio.sleep(1)
|
||||||
|
|
||||||
|
async def upgrade_firmware(self, file: Path, keep_settings: bool = True) -> str:
|
||||||
|
"""
|
||||||
|
Upgrade the firmware of the AntMiner device.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
file (Path): Path to the firmware file.
|
||||||
|
keep_settings (bool): Whether to keep the current settings after the update.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: Result of the upgrade process.
|
||||||
|
"""
|
||||||
|
if not file:
|
||||||
|
raise ValueError("File location must be provided for firmware upgrade.")
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = await self.web.update_firmware(
|
||||||
|
file=file, keep_settings=keep_settings
|
||||||
|
)
|
||||||
|
|
||||||
|
if result.get("success"):
|
||||||
|
logging.info(
|
||||||
|
"Firmware upgrade process completed successfully for AntMiner."
|
||||||
|
)
|
||||||
|
return "Firmware upgrade completed successfully."
|
||||||
|
else:
|
||||||
|
error_message = result.get("message", "Unknown error")
|
||||||
|
logging.error(f"Firmware upgrade failed. Response: {error_message}")
|
||||||
|
return f"Firmware upgrade failed. Response: {error_message}"
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(
|
||||||
|
f"An error occurred during the firmware upgrade process: {e}",
|
||||||
|
exc_info=True,
|
||||||
|
)
|
||||||
|
raise
|
||||||
|
|
||||||
async def fault_light_on(self) -> bool:
|
async def fault_light_on(self) -> bool:
|
||||||
data = await self.web.blink(blink=True)
|
data = await self.web.blink(blink=True)
|
||||||
if data:
|
if data:
|
||||||
@@ -337,7 +374,7 @@ class AntminerModern(BMMiner):
|
|||||||
|
|
||||||
if web_get_conf is not None:
|
if web_get_conf is not None:
|
||||||
try:
|
try:
|
||||||
if web_get_conf["bitmain-work-mode"].isdigit():
|
if str(web_get_conf["bitmain-work-mode"]).isdigit():
|
||||||
return (
|
return (
|
||||||
False if int(web_get_conf["bitmain-work-mode"]) == 1 else True
|
False if int(web_get_conf["bitmain-work-mode"]) == 1 else True
|
||||||
)
|
)
|
||||||
@@ -427,6 +464,10 @@ ANTMINER_OLD_DATA_LOC = DataLocations(
|
|||||||
"_get_uptime",
|
"_get_uptime",
|
||||||
[RPCAPICommand("rpc_stats", "stats")],
|
[RPCAPICommand("rpc_stats", "stats")],
|
||||||
),
|
),
|
||||||
|
str(DataOptions.POOLS): DataFunction(
|
||||||
|
"_get_pools",
|
||||||
|
[RPCAPICommand("rpc_pools", "pools")],
|
||||||
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -556,7 +597,6 @@ class AntminerOld(CGMiner):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
if rpc_stats is not None:
|
if rpc_stats is not None:
|
||||||
try:
|
|
||||||
board_offset = -1
|
board_offset = -1
|
||||||
boards = rpc_stats["STATS"]
|
boards = rpc_stats["STATS"]
|
||||||
if len(boards) > 1:
|
if len(boards) > 1:
|
||||||
@@ -569,9 +609,7 @@ class AntminerOld(CGMiner):
|
|||||||
if board_offset == -1:
|
if board_offset == -1:
|
||||||
board_offset = 1
|
board_offset = 1
|
||||||
|
|
||||||
for i in range(
|
for i in range(board_offset, board_offset + self.expected_hashboards):
|
||||||
board_offset, board_offset + self.expected_hashboards
|
|
||||||
):
|
|
||||||
hashboard = HashBoard(
|
hashboard = HashBoard(
|
||||||
slot=i - board_offset, expected_chips=self.expected_chips
|
slot=i - board_offset, expected_chips=self.expected_chips
|
||||||
)
|
)
|
||||||
@@ -587,7 +625,7 @@ class AntminerOld(CGMiner):
|
|||||||
hashrate = boards[1].get(f"chain_rate{i}")
|
hashrate = boards[1].get(f"chain_rate{i}")
|
||||||
if hashrate:
|
if hashrate:
|
||||||
hashboard.hashrate = AlgoHashRate.SHA256(
|
hashboard.hashrate = AlgoHashRate.SHA256(
|
||||||
hashrate, HashUnit.SHA256.GH
|
float(hashrate), HashUnit.SHA256.GH
|
||||||
).into(self.algo.unit.default)
|
).into(self.algo.unit.default)
|
||||||
|
|
||||||
chips = boards[1].get(f"chain_acn{i}")
|
chips = boards[1].get(f"chain_acn{i}")
|
||||||
@@ -597,8 +635,6 @@ class AntminerOld(CGMiner):
|
|||||||
if (not chips) or (not chips > 0):
|
if (not chips) or (not chips > 0):
|
||||||
hashboard.missing = True
|
hashboard.missing = True
|
||||||
hashboards.append(hashboard)
|
hashboards.append(hashboard)
|
||||||
except (LookupError, ValueError, TypeError):
|
|
||||||
pass
|
|
||||||
|
|
||||||
return hashboards
|
return hashboards
|
||||||
|
|
||||||
|
|||||||
@@ -193,6 +193,53 @@ class Auradine(StockFirmware):
|
|||||||
for key in conf.keys():
|
for key in conf.keys():
|
||||||
await self.web.send_command(command=key, **conf[key])
|
await self.web.send_command(command=key, **conf[key])
|
||||||
|
|
||||||
|
async def upgrade_firmware(
|
||||||
|
self,
|
||||||
|
*,
|
||||||
|
url: str = None,
|
||||||
|
version: str = "latest",
|
||||||
|
keep_settings: bool = False,
|
||||||
|
**kwargs,
|
||||||
|
) -> bool:
|
||||||
|
"""
|
||||||
|
Upgrade the firmware of the Auradine device.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
url (str): The URL to download the firmware from.
|
||||||
|
version (str): The version of the firmware to upgrade to.
|
||||||
|
keep_settings (bool): Whether to keep the current settings during the upgrade.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True if the firmware upgrade was successful, False otherwise.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
logging.info("Starting firmware upgrade process.")
|
||||||
|
|
||||||
|
if not url and not version:
|
||||||
|
raise ValueError(
|
||||||
|
"Either URL or version must be provided for firmware upgrade."
|
||||||
|
)
|
||||||
|
|
||||||
|
if url:
|
||||||
|
result = await self.web.firmware_upgrade(url=url)
|
||||||
|
else:
|
||||||
|
result = await self.web.firmware_upgrade(version=version)
|
||||||
|
|
||||||
|
if result.get("STATUS", [{}])[0].get("STATUS") == "S":
|
||||||
|
logging.info("Firmware upgrade process completed successfully.")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
logging.error(
|
||||||
|
f"Firmware upgrade failed: {result.get('error', 'Unknown error')}"
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(
|
||||||
|
f"An error occurred during the firmware upgrade process: {str(e)}"
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
|
||||||
##################################################
|
##################################################
|
||||||
### DATA GATHERING FUNCTIONS (get_{some_data}) ###
|
### DATA GATHERING FUNCTIONS (get_{some_data}) ###
|
||||||
##################################################
|
##################################################
|
||||||
|
|||||||
@@ -68,6 +68,10 @@ AVALON_DATA_LOC = DataLocations(
|
|||||||
"_get_uptime",
|
"_get_uptime",
|
||||||
[RPCAPICommand("rpc_stats", "stats")],
|
[RPCAPICommand("rpc_stats", "stats")],
|
||||||
),
|
),
|
||||||
|
str(DataOptions.POOLS): DataFunction(
|
||||||
|
"_get_pools",
|
||||||
|
[RPCAPICommand("rpc_pools", "pools")],
|
||||||
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -114,7 +118,7 @@ class AvalonMiner(CGMiner):
|
|||||||
stats_items = []
|
stats_items = []
|
||||||
stats_dict = {}
|
stats_dict = {}
|
||||||
for item in _stats_items:
|
for item in _stats_items:
|
||||||
if ":" in item:
|
if ": " in item:
|
||||||
data = item.replace("]", "").split("[")
|
data = item.replace("]", "").split("[")
|
||||||
data_list = [i.split(": ") for i in data[1].strip().split(", ")]
|
data_list = [i.split(": ") for i in data[1].strip().split(", ")]
|
||||||
data_dict = {}
|
data_dict = {}
|
||||||
@@ -143,9 +147,6 @@ class AvalonMiner(CGMiner):
|
|||||||
if raw_data[0] == "":
|
if raw_data[0] == "":
|
||||||
raw_data = raw_data[1:]
|
raw_data = raw_data[1:]
|
||||||
|
|
||||||
if len(raw_data) == 2:
|
|
||||||
stats_dict[raw_data[0]] = raw_data[1]
|
|
||||||
else:
|
|
||||||
stats_dict[raw_data[0]] = raw_data[1:]
|
stats_dict[raw_data[0]] = raw_data[1:]
|
||||||
stats_items.append(raw_data)
|
stats_items.append(raw_data)
|
||||||
|
|
||||||
@@ -216,7 +217,7 @@ class AvalonMiner(CGMiner):
|
|||||||
try:
|
try:
|
||||||
board_hr = parsed_stats["MGHS"][board]
|
board_hr = parsed_stats["MGHS"][board]
|
||||||
hashboards[board].hashrate = AlgoHashRate.SHA256(
|
hashboards[board].hashrate = AlgoHashRate.SHA256(
|
||||||
board_hr, HashUnit.SHA256.GH
|
float(board_hr), HashUnit.SHA256.GH
|
||||||
).into(self.algo.unit.default)
|
).into(self.algo.unit.default)
|
||||||
except LookupError:
|
except LookupError:
|
||||||
pass
|
pass
|
||||||
@@ -252,7 +253,7 @@ class AvalonMiner(CGMiner):
|
|||||||
unparsed_stats = rpc_stats["STATS"][0]["MM ID0"]
|
unparsed_stats = rpc_stats["STATS"][0]["MM ID0"]
|
||||||
parsed_stats = self.parse_stats(unparsed_stats)
|
parsed_stats = self.parse_stats(unparsed_stats)
|
||||||
return AlgoHashRate.SHA256(
|
return AlgoHashRate.SHA256(
|
||||||
parsed_stats["GHSmm"], HashUnit.SHA256.GH
|
float(parsed_stats["GHSmm"][0]), HashUnit.SHA256.GH
|
||||||
).into(self.algo.unit.default)
|
).into(self.algo.unit.default)
|
||||||
except (IndexError, KeyError, ValueError, TypeError):
|
except (IndexError, KeyError, ValueError, TypeError):
|
||||||
pass
|
pass
|
||||||
@@ -268,7 +269,7 @@ class AvalonMiner(CGMiner):
|
|||||||
try:
|
try:
|
||||||
unparsed_stats = rpc_stats["STATS"][0]["MM ID0"]
|
unparsed_stats = rpc_stats["STATS"][0]["MM ID0"]
|
||||||
parsed_stats = self.parse_stats(unparsed_stats)
|
parsed_stats = self.parse_stats(unparsed_stats)
|
||||||
return float(parsed_stats["Temp"])
|
return float(parsed_stats["Temp"][0])
|
||||||
except (IndexError, KeyError, ValueError, TypeError):
|
except (IndexError, KeyError, ValueError, TypeError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -283,7 +284,7 @@ class AvalonMiner(CGMiner):
|
|||||||
try:
|
try:
|
||||||
unparsed_stats = rpc_stats["STATS"][0]["MM ID0"]
|
unparsed_stats = rpc_stats["STATS"][0]["MM ID0"]
|
||||||
parsed_stats = self.parse_stats(unparsed_stats)
|
parsed_stats = self.parse_stats(unparsed_stats)
|
||||||
return int(parsed_stats["MPO"])
|
return int(parsed_stats["MPO"][0])
|
||||||
except (IndexError, KeyError, ValueError, TypeError):
|
except (IndexError, KeyError, ValueError, TypeError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -304,7 +305,7 @@ class AvalonMiner(CGMiner):
|
|||||||
|
|
||||||
for fan in range(self.expected_fans):
|
for fan in range(self.expected_fans):
|
||||||
try:
|
try:
|
||||||
fans_data[fan].speed = int(parsed_stats[f"Fan{fan + 1}"])
|
fans_data[fan].speed = int(parsed_stats[f"Fan{fan + 1}"][0])
|
||||||
except (IndexError, KeyError, ValueError, TypeError):
|
except (IndexError, KeyError, ValueError, TypeError):
|
||||||
pass
|
pass
|
||||||
return fans_data
|
return fans_data
|
||||||
@@ -322,7 +323,7 @@ class AvalonMiner(CGMiner):
|
|||||||
try:
|
try:
|
||||||
unparsed_stats = rpc_stats["STATS"][0]["MM ID0"]
|
unparsed_stats = rpc_stats["STATS"][0]["MM ID0"]
|
||||||
parsed_stats = self.parse_stats(unparsed_stats)
|
parsed_stats = self.parse_stats(unparsed_stats)
|
||||||
led = int(parsed_stats["Led"])
|
led = int(parsed_stats["Led"][0])
|
||||||
return True if led == 1 else False
|
return True if led == 1 else False
|
||||||
except (IndexError, KeyError, ValueError, TypeError):
|
except (IndexError, KeyError, ValueError, TypeError):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ from typing import List, Optional
|
|||||||
|
|
||||||
from pyasic.config import MinerConfig
|
from pyasic.config import MinerConfig
|
||||||
from pyasic.data import AlgoHashRate, Fan, HashBoard, HashUnit
|
from pyasic.data import AlgoHashRate, Fan, HashBoard, HashUnit
|
||||||
|
from pyasic.data.pools import PoolMetrics, PoolUrl
|
||||||
from pyasic.errors import APIError
|
from pyasic.errors import APIError
|
||||||
from pyasic.miners.data import DataFunction, DataLocations, DataOptions, RPCAPICommand
|
from pyasic.miners.data import DataFunction, DataLocations, DataOptions, RPCAPICommand
|
||||||
from pyasic.miners.device.firmware import StockFirmware
|
from pyasic.miners.device.firmware import StockFirmware
|
||||||
@@ -49,6 +50,10 @@ BFGMINER_DATA_LOC = DataLocations(
|
|||||||
"_get_fans",
|
"_get_fans",
|
||||||
[RPCAPICommand("rpc_stats", "stats")],
|
[RPCAPICommand("rpc_stats", "stats")],
|
||||||
),
|
),
|
||||||
|
str(DataOptions.POOLS): DataFunction(
|
||||||
|
"_get_pools",
|
||||||
|
[RPCAPICommand("rpc_pools", "pools")],
|
||||||
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -207,6 +212,36 @@ class BFGMiner(StockFirmware):
|
|||||||
|
|
||||||
return fans
|
return fans
|
||||||
|
|
||||||
|
async def _get_pools(self, rpc_pools: dict = None) -> List[PoolMetrics]:
|
||||||
|
if rpc_pools is None:
|
||||||
|
try:
|
||||||
|
rpc_pools = await self.rpc.pools()
|
||||||
|
except APIError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
pools_data = []
|
||||||
|
if rpc_pools is not None:
|
||||||
|
try:
|
||||||
|
pools = rpc_pools.get("POOLS", [])
|
||||||
|
for pool_info in pools:
|
||||||
|
url = pool_info.get("URL")
|
||||||
|
pool_url = PoolUrl.from_str(url) if url else None
|
||||||
|
pool_data = PoolMetrics(
|
||||||
|
accepted=pool_info.get("Accepted"),
|
||||||
|
rejected=pool_info.get("Rejected"),
|
||||||
|
get_failures=pool_info.get("Get Failures"),
|
||||||
|
remote_failures=pool_info.get("Remote Failures"),
|
||||||
|
active=pool_info.get("Stratum Active"),
|
||||||
|
alive=pool_info.get("Status") == "Alive",
|
||||||
|
url=pool_url,
|
||||||
|
user=pool_info.get("User"),
|
||||||
|
index=pool_info.get("POOL"),
|
||||||
|
)
|
||||||
|
pools_data.append(pool_data)
|
||||||
|
except LookupError:
|
||||||
|
pass
|
||||||
|
return pools_data
|
||||||
|
|
||||||
async def _get_expected_hashrate(
|
async def _get_expected_hashrate(
|
||||||
self, rpc_stats: dict = None
|
self, rpc_stats: dict = None
|
||||||
) -> Optional[AlgoHashRate]:
|
) -> Optional[AlgoHashRate]:
|
||||||
|
|||||||
@@ -41,6 +41,10 @@ BITAXE_DATA_LOC = DataLocations(
|
|||||||
"_get_api_ver",
|
"_get_api_ver",
|
||||||
[WebAPICommand("web_system_info", "system/info")],
|
[WebAPICommand("web_system_info", "system/info")],
|
||||||
),
|
),
|
||||||
|
str(DataOptions.MAC): DataFunction(
|
||||||
|
"_get_mac",
|
||||||
|
[WebAPICommand("web_system_info", "system/info")],
|
||||||
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -187,3 +191,16 @@ class BitAxe(BaseMiner):
|
|||||||
return web_system_info["version"]
|
return web_system_info["version"]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
async def _get_mac(self, web_system_info: dict = None) -> Optional[str]:
|
||||||
|
if web_system_info is None:
|
||||||
|
try:
|
||||||
|
web_system_info = await self.web.system_info()
|
||||||
|
except APIError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if web_system_info is not None:
|
||||||
|
try:
|
||||||
|
return web_system_info["macAddr"].upper()
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|||||||
@@ -20,7 +20,12 @@ from pathlib import Path
|
|||||||
from typing import List, Optional, Union
|
from typing import List, Optional, Union
|
||||||
|
|
||||||
import aiofiles
|
import aiofiles
|
||||||
import toml
|
import tomli_w
|
||||||
|
|
||||||
|
try:
|
||||||
|
import tomllib
|
||||||
|
except ImportError:
|
||||||
|
import tomli as tomllib
|
||||||
|
|
||||||
from pyasic.config import MinerConfig
|
from pyasic.config import MinerConfig
|
||||||
from pyasic.config.mining import MiningModePowerTune
|
from pyasic.config.mining import MiningModePowerTune
|
||||||
@@ -177,10 +182,10 @@ class BOSMiner(BraiinsOSFirmware):
|
|||||||
raw_data = await self.ssh.get_config_file()
|
raw_data = await self.ssh.get_config_file()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
toml_data = toml.loads(raw_data)
|
toml_data = tomllib.loads(raw_data)
|
||||||
cfg = MinerConfig.from_bosminer(toml_data)
|
cfg = MinerConfig.from_bosminer(toml_data)
|
||||||
self.config = cfg
|
self.config = cfg
|
||||||
except toml.TomlDecodeError as e:
|
except tomllib.TOMLDecodeError as e:
|
||||||
raise APIError("Failed to decode toml when getting config.") from e
|
raise APIError("Failed to decode toml when getting config.") from e
|
||||||
except TypeError as e:
|
except TypeError as e:
|
||||||
raise APIError("Failed to decode toml when getting config.") from e
|
raise APIError("Failed to decode toml when getting config.") from e
|
||||||
@@ -191,7 +196,7 @@ class BOSMiner(BraiinsOSFirmware):
|
|||||||
self.config = config
|
self.config = config
|
||||||
parsed_cfg = config.as_bosminer(user_suffix=user_suffix)
|
parsed_cfg = config.as_bosminer(user_suffix=user_suffix)
|
||||||
|
|
||||||
toml_conf = toml.dumps(
|
toml_conf = tomli_w.dumps(
|
||||||
{
|
{
|
||||||
"format": {
|
"format": {
|
||||||
"version": "2.0",
|
"version": "2.0",
|
||||||
@@ -721,6 +726,9 @@ BOSER_DATA_LOC = DataLocations(
|
|||||||
"_get_uptime",
|
"_get_uptime",
|
||||||
[RPCAPICommand("rpc_summary", "summary")],
|
[RPCAPICommand("rpc_summary", "summary")],
|
||||||
),
|
),
|
||||||
|
str(DataOptions.POOLS): DataFunction(
|
||||||
|
"_get_pools", [WebAPICommand("grpc_pool_groups", "get_pool_groups")]
|
||||||
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -790,7 +798,7 @@ class BOSer(BraiinsOSFirmware):
|
|||||||
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(
|
result = await self.web.set_power_target(
|
||||||
wattage, save_action=SaveAction.SAVE_ACTION_SAVE_AND_FORCE_APPLY
|
wattage, save_action=SaveAction.SAVE_AND_FORCE_APPLY
|
||||||
)
|
)
|
||||||
except APIError:
|
except APIError:
|
||||||
return False
|
return False
|
||||||
@@ -918,8 +926,10 @@ class BOSer(BraiinsOSFirmware):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
if grpc_hashboards is not None:
|
if grpc_hashboards is not None:
|
||||||
for board in grpc_hashboards["hashboards"]:
|
grpc_boards = sorted(
|
||||||
idx = int(board["id"]) - 1
|
grpc_hashboards["hashboards"], key=lambda x: int(x["id"])
|
||||||
|
)
|
||||||
|
for idx, board in enumerate(grpc_boards):
|
||||||
if board.get("chipsCount") is not None:
|
if board.get("chipsCount") is not None:
|
||||||
hashboards[idx].chips = board["chipsCount"]
|
hashboards[idx].chips = board["chipsCount"]
|
||||||
if board.get("boardTemp") is not None:
|
if board.get("boardTemp") is not None:
|
||||||
@@ -943,7 +953,7 @@ class BOSer(BraiinsOSFirmware):
|
|||||||
async def _get_wattage(self, grpc_miner_stats: dict = None) -> Optional[int]:
|
async def _get_wattage(self, grpc_miner_stats: dict = None) -> Optional[int]:
|
||||||
if grpc_miner_stats is None:
|
if grpc_miner_stats is None:
|
||||||
try:
|
try:
|
||||||
grpc_miner_stats = self.web.get_miner_stats()
|
grpc_miner_stats = await self.web.get_miner_stats()
|
||||||
except APIError:
|
except APIError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -975,7 +985,7 @@ class BOSer(BraiinsOSFirmware):
|
|||||||
async def _get_fans(self, grpc_cooling_state: dict = None) -> List[Fan]:
|
async def _get_fans(self, grpc_cooling_state: dict = None) -> List[Fan]:
|
||||||
if grpc_cooling_state is None:
|
if grpc_cooling_state is None:
|
||||||
try:
|
try:
|
||||||
grpc_cooling_state = self.web.get_cooling_state()
|
grpc_cooling_state = await self.web.get_cooling_state()
|
||||||
except APIError:
|
except APIError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -1064,3 +1074,27 @@ class BOSer(BraiinsOSFirmware):
|
|||||||
return int(rpc_summary["SUMMARY"][0]["Elapsed"])
|
return int(rpc_summary["SUMMARY"][0]["Elapsed"])
|
||||||
except LookupError:
|
except LookupError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
async def _get_pools(self, grpc_pool_groups: dict = None) -> List[PoolMetrics]:
|
||||||
|
if grpc_pool_groups is None:
|
||||||
|
try:
|
||||||
|
grpc_pool_groups = await self.web.get_pool_groups()
|
||||||
|
except APIError:
|
||||||
|
return []
|
||||||
|
pools_data = []
|
||||||
|
for group in grpc_pool_groups["poolGroups"]:
|
||||||
|
for idx, pool_info in enumerate(group["pools"]):
|
||||||
|
pool_data = PoolMetrics(
|
||||||
|
url=pool_info["url"],
|
||||||
|
user=pool_info["user"],
|
||||||
|
index=idx,
|
||||||
|
accepted=pool_info["stats"].get("acceptedShares", 0),
|
||||||
|
rejected=pool_info["stats"].get("rejectedShares", 0),
|
||||||
|
get_failures=0,
|
||||||
|
remote_failures=0,
|
||||||
|
active=pool_info.get("active", False),
|
||||||
|
alive=pool_info.get("alive"),
|
||||||
|
)
|
||||||
|
pools_data.append(pool_data)
|
||||||
|
|
||||||
|
return pools_data
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import aiofiles
|
|||||||
from pyasic.config import MinerConfig, MiningModeConfig
|
from pyasic.config import MinerConfig, MiningModeConfig
|
||||||
from pyasic.data import AlgoHashRate, Fan, HashBoard, HashUnit
|
from pyasic.data import AlgoHashRate, Fan, HashBoard, HashUnit
|
||||||
from pyasic.data.error_codes import MinerErrorData, WhatsminerError
|
from pyasic.data.error_codes import MinerErrorData, WhatsminerError
|
||||||
|
from pyasic.data.pools import PoolMetrics, PoolUrl
|
||||||
from pyasic.errors import APIError
|
from pyasic.errors import APIError
|
||||||
from pyasic.miners.data import DataFunction, DataLocations, DataOptions, RPCAPICommand
|
from pyasic.miners.data import DataFunction, DataLocations, DataOptions, RPCAPICommand
|
||||||
from pyasic.miners.device.firmware import StockFirmware
|
from pyasic.miners.device.firmware import StockFirmware
|
||||||
@@ -109,6 +110,10 @@ BTMINER_DATA_LOC = DataLocations(
|
|||||||
"_get_uptime",
|
"_get_uptime",
|
||||||
[RPCAPICommand("rpc_summary", "summary")],
|
[RPCAPICommand("rpc_summary", "summary")],
|
||||||
),
|
),
|
||||||
|
str(DataOptions.POOLS): DataFunction(
|
||||||
|
"_get_pools",
|
||||||
|
[RPCAPICommand("rpc_pools", "pools")],
|
||||||
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -655,13 +660,42 @@ class BTMiner(StockFirmware):
|
|||||||
except LookupError:
|
except LookupError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
async def upgrade_firmware(self, file: Path, token: str):
|
async def _get_pools(self, rpc_pools: dict = None) -> List[PoolMetrics]:
|
||||||
|
if rpc_pools is None:
|
||||||
|
try:
|
||||||
|
rpc_pools = await self.rpc.pools()
|
||||||
|
except APIError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
pools_data = []
|
||||||
|
if rpc_pools is not None:
|
||||||
|
try:
|
||||||
|
pools = rpc_pools.get("POOLS", [])
|
||||||
|
for pool_info in pools:
|
||||||
|
url = pool_info.get("URL")
|
||||||
|
pool_url = PoolUrl.from_str(url) if url else None
|
||||||
|
pool_data = PoolMetrics(
|
||||||
|
accepted=pool_info.get("Accepted"),
|
||||||
|
rejected=pool_info.get("Rejected"),
|
||||||
|
get_failures=pool_info.get("Get Failures"),
|
||||||
|
remote_failures=pool_info.get("Remote Failures"),
|
||||||
|
active=pool_info.get("Stratum Active"),
|
||||||
|
alive=pool_info.get("Status") == "Alive",
|
||||||
|
url=pool_url,
|
||||||
|
user=pool_info.get("User"),
|
||||||
|
index=pool_info.get("POOL"),
|
||||||
|
)
|
||||||
|
pools_data.append(pool_data)
|
||||||
|
except LookupError:
|
||||||
|
pass
|
||||||
|
return pools_data
|
||||||
|
|
||||||
|
async def upgrade_firmware(self, file: Path):
|
||||||
"""
|
"""
|
||||||
Upgrade the firmware of the Whatsminer device.
|
Upgrade the firmware of the Whatsminer device.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
file (Path): The local file path of the firmware to be uploaded.
|
file (Path): The local file path of the firmware to be uploaded.
|
||||||
token (str): The authentication token for the firmware upgrade.
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
str: Confirmation message after upgrading the firmware.
|
str: Confirmation message after upgrading the firmware.
|
||||||
|
|||||||
@@ -14,10 +14,11 @@
|
|||||||
# limitations under the License. -
|
# limitations under the License. -
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from typing import Optional
|
from typing import List, Optional
|
||||||
|
|
||||||
from pyasic.config import MinerConfig
|
from pyasic.config import MinerConfig
|
||||||
from pyasic.data import AlgoHashRate, HashUnit
|
from pyasic.data import AlgoHashRate, HashUnit
|
||||||
|
from pyasic.data.pools import PoolMetrics, PoolUrl
|
||||||
from pyasic.errors import APIError
|
from pyasic.errors import APIError
|
||||||
from pyasic.miners.data import DataFunction, DataLocations, DataOptions, RPCAPICommand
|
from pyasic.miners.data import DataFunction, DataLocations, DataOptions, RPCAPICommand
|
||||||
from pyasic.miners.device.firmware import StockFirmware
|
from pyasic.miners.device.firmware import StockFirmware
|
||||||
@@ -53,6 +54,10 @@ CGMINER_DATA_LOC = DataLocations(
|
|||||||
"_get_uptime",
|
"_get_uptime",
|
||||||
[RPCAPICommand("rpc_stats", "stats")],
|
[RPCAPICommand("rpc_stats", "stats")],
|
||||||
),
|
),
|
||||||
|
str(DataOptions.POOLS): DataFunction(
|
||||||
|
"_get_pools",
|
||||||
|
[RPCAPICommand("rpc_pools", "pools")],
|
||||||
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -136,3 +141,33 @@ class CGMiner(StockFirmware):
|
|||||||
return int(rpc_stats["STATS"][1]["Elapsed"])
|
return int(rpc_stats["STATS"][1]["Elapsed"])
|
||||||
except LookupError:
|
except LookupError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
async def _get_pools(self, rpc_pools: dict = None) -> List[PoolMetrics]:
|
||||||
|
if rpc_pools is None:
|
||||||
|
try:
|
||||||
|
rpc_pools = await self.rpc.pools()
|
||||||
|
except APIError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
pools_data = []
|
||||||
|
if rpc_pools is not None:
|
||||||
|
try:
|
||||||
|
pools = rpc_pools.get("POOLS", [])
|
||||||
|
for pool_info in pools:
|
||||||
|
url = pool_info.get("URL")
|
||||||
|
pool_url = PoolUrl.from_str(url) if url else None
|
||||||
|
pool_data = PoolMetrics(
|
||||||
|
accepted=pool_info.get("Accepted"),
|
||||||
|
rejected=pool_info.get("Rejected"),
|
||||||
|
get_failures=pool_info.get("Get Failures"),
|
||||||
|
remote_failures=pool_info.get("Remote Failures"),
|
||||||
|
active=pool_info.get("Stratum Active"),
|
||||||
|
alive=pool_info.get("Status") == "Alive",
|
||||||
|
url=pool_url,
|
||||||
|
user=pool_info.get("User"),
|
||||||
|
index=pool_info.get("POOL"),
|
||||||
|
)
|
||||||
|
pools_data.append(pool_data)
|
||||||
|
except LookupError:
|
||||||
|
pass
|
||||||
|
return pools_data
|
||||||
|
|||||||
@@ -454,8 +454,9 @@ class ePIC(ePICFirmware):
|
|||||||
except LookupError:
|
except LookupError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
async def upgrade_firmware(self, file: Path | str, keep_settings: bool = True) -> bool:
|
async def upgrade_firmware(
|
||||||
|
self, file: Path | str, keep_settings: bool = True
|
||||||
|
) -> bool:
|
||||||
"""
|
"""
|
||||||
Upgrade the firmware of the ePIC miner device.
|
Upgrade the firmware of the ePIC miner device.
|
||||||
|
|
||||||
|
|||||||
@@ -62,6 +62,10 @@ GOLDSHELL_DATA_LOC = DataLocations(
|
|||||||
"_get_fans",
|
"_get_fans",
|
||||||
[RPCAPICommand("rpc_stats", "stats")],
|
[RPCAPICommand("rpc_stats", "stats")],
|
||||||
),
|
),
|
||||||
|
str(DataOptions.POOLS): DataFunction(
|
||||||
|
"_get_pools",
|
||||||
|
[RPCAPICommand("rpc_pools", "pools")],
|
||||||
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
248
pyasic/miners/backends/iceriver.py
Normal file
248
pyasic/miners/backends/iceriver.py
Normal file
@@ -0,0 +1,248 @@
|
|||||||
|
from typing import List, Optional
|
||||||
|
|
||||||
|
from pyasic import MinerConfig
|
||||||
|
from pyasic.data import AlgoHashRate, Fan, HashBoard, HashUnit
|
||||||
|
from pyasic.data.pools import PoolMetrics, PoolUrl
|
||||||
|
from pyasic.device import MinerAlgo
|
||||||
|
from pyasic.errors import APIError
|
||||||
|
from pyasic.miners.data import DataFunction, DataLocations, DataOptions, WebAPICommand
|
||||||
|
from pyasic.miners.device.firmware import StockFirmware
|
||||||
|
from pyasic.web.iceriver import IceRiverWebAPI
|
||||||
|
|
||||||
|
ICERIVER_DATA_LOC = DataLocations(
|
||||||
|
**{
|
||||||
|
str(DataOptions.MAC): DataFunction(
|
||||||
|
"_get_mac",
|
||||||
|
[WebAPICommand("web_userpanel", "userpanel")],
|
||||||
|
),
|
||||||
|
str(DataOptions.FANS): DataFunction(
|
||||||
|
"_get_fans",
|
||||||
|
[WebAPICommand("web_userpanel", "userpanel")],
|
||||||
|
),
|
||||||
|
str(DataOptions.HOSTNAME): DataFunction(
|
||||||
|
"_get_hostname",
|
||||||
|
[WebAPICommand("web_userpanel", "userpanel")],
|
||||||
|
),
|
||||||
|
str(DataOptions.HASHRATE): DataFunction(
|
||||||
|
"_get_hashrate",
|
||||||
|
[WebAPICommand("web_userpanel", "userpanel")],
|
||||||
|
),
|
||||||
|
str(DataOptions.IS_MINING): DataFunction(
|
||||||
|
"_is_mining",
|
||||||
|
[WebAPICommand("web_userpanel", "userpanel")],
|
||||||
|
),
|
||||||
|
str(DataOptions.FAULT_LIGHT): DataFunction(
|
||||||
|
"_get_fault_light",
|
||||||
|
[WebAPICommand("web_userpanel", "userpanel")],
|
||||||
|
),
|
||||||
|
str(DataOptions.HASHBOARDS): DataFunction(
|
||||||
|
"_get_hashboards",
|
||||||
|
[WebAPICommand("web_userpanel", "userpanel")],
|
||||||
|
),
|
||||||
|
str(DataOptions.UPTIME): DataFunction(
|
||||||
|
"_get_uptime",
|
||||||
|
[WebAPICommand("web_userpanel", "userpanel")],
|
||||||
|
),
|
||||||
|
str(DataOptions.POOLS): DataFunction(
|
||||||
|
"_get_pools",
|
||||||
|
[WebAPICommand("web_userpanel", "userpanel")],
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class IceRiver(StockFirmware):
|
||||||
|
"""Handler for IceRiver miners"""
|
||||||
|
|
||||||
|
_web_cls = IceRiverWebAPI
|
||||||
|
web: IceRiverWebAPI
|
||||||
|
|
||||||
|
data_locations = ICERIVER_DATA_LOC
|
||||||
|
|
||||||
|
async def fault_light_off(self) -> bool:
|
||||||
|
try:
|
||||||
|
await self.web.locate(False)
|
||||||
|
except APIError:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
async def fault_light_on(self) -> bool:
|
||||||
|
try:
|
||||||
|
await self.web.locate(True)
|
||||||
|
except APIError:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
async def get_config(self) -> MinerConfig:
|
||||||
|
web_userpanel = await self.web.userpanel()
|
||||||
|
|
||||||
|
return MinerConfig.from_iceriver(web_userpanel)
|
||||||
|
|
||||||
|
async def _get_fans(self, web_userpanel: dict = None) -> List[Fan]:
|
||||||
|
if web_userpanel is None:
|
||||||
|
try:
|
||||||
|
web_userpanel = await self.web.userpanel()
|
||||||
|
except APIError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if web_userpanel is not None:
|
||||||
|
try:
|
||||||
|
return [Fan(spd) for spd in web_userpanel["userpanel"]["data"]["fans"]]
|
||||||
|
except (LookupError, ValueError, TypeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def _get_mac(self, web_userpanel: dict = None) -> Optional[str]:
|
||||||
|
if web_userpanel is None:
|
||||||
|
try:
|
||||||
|
web_userpanel = await self.web.userpanel()
|
||||||
|
except APIError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if web_userpanel is not None:
|
||||||
|
try:
|
||||||
|
return (
|
||||||
|
web_userpanel["userpanel"]["data"]["mac"].upper().replace("-", ":")
|
||||||
|
)
|
||||||
|
except (LookupError, ValueError, TypeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def _get_hostname(self, web_userpanel: dict = None) -> Optional[str]:
|
||||||
|
if web_userpanel is None:
|
||||||
|
try:
|
||||||
|
web_userpanel = await self.web.userpanel()
|
||||||
|
except APIError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if web_userpanel is not None:
|
||||||
|
try:
|
||||||
|
return web_userpanel["userpanel"]["data"]["host"]
|
||||||
|
except (LookupError, ValueError, TypeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def _get_hashrate(self, web_userpanel: dict = None) -> Optional[AlgoHashRate]:
|
||||||
|
if web_userpanel is None:
|
||||||
|
try:
|
||||||
|
web_userpanel = await self.web.userpanel()
|
||||||
|
except APIError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if web_userpanel is not None:
|
||||||
|
try:
|
||||||
|
base_unit = web_userpanel["userpanel"]["data"]["unit"]
|
||||||
|
return AlgoHashRate.SHA256(
|
||||||
|
float(
|
||||||
|
web_userpanel["userpanel"]["data"]["rtpow"].replace(
|
||||||
|
base_unit, ""
|
||||||
|
)
|
||||||
|
),
|
||||||
|
unit=MinerAlgo.SHA256.unit.from_str(base_unit + "H"),
|
||||||
|
).into(MinerAlgo.SHA256.unit.default)
|
||||||
|
except (LookupError, ValueError, TypeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def _get_fault_light(self, web_userpanel: dict = None) -> bool:
|
||||||
|
if web_userpanel is None:
|
||||||
|
try:
|
||||||
|
web_userpanel = await self.web.userpanel()
|
||||||
|
except APIError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if web_userpanel is not None:
|
||||||
|
try:
|
||||||
|
return web_userpanel["userpanel"]["data"]["locate"]
|
||||||
|
except (LookupError, ValueError, TypeError):
|
||||||
|
pass
|
||||||
|
return False
|
||||||
|
|
||||||
|
async def _is_mining(self, web_userpanel: dict = None) -> Optional[bool]:
|
||||||
|
if web_userpanel is None:
|
||||||
|
try:
|
||||||
|
web_userpanel = await self.web.userpanel()
|
||||||
|
except APIError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if web_userpanel is not None:
|
||||||
|
try:
|
||||||
|
return web_userpanel["userpanel"]["data"]["powstate"]
|
||||||
|
except (LookupError, ValueError, TypeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def _get_hashboards(self, web_userpanel: dict = None) -> List[HashBoard]:
|
||||||
|
if web_userpanel is None:
|
||||||
|
try:
|
||||||
|
web_userpanel = await self.web.userpanel()
|
||||||
|
except APIError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
hb_list = [
|
||||||
|
HashBoard(slot=i, expected_chips=self.expected_chips)
|
||||||
|
for i in range(self.expected_hashboards)
|
||||||
|
]
|
||||||
|
|
||||||
|
if web_userpanel is not None:
|
||||||
|
try:
|
||||||
|
for board in web_userpanel["userpanel"]["data"]["boards"]:
|
||||||
|
idx = int(board["no"] - 1)
|
||||||
|
hb_list[idx].chip_temp = round(board["outtmp"])
|
||||||
|
hb_list[idx].temp = round(board["intmp"])
|
||||||
|
hb_list[idx].hashrate = AlgoHashRate.SHA256(
|
||||||
|
float(board["rtpow"].replace("G", "")), HashUnit.SHA256.GH
|
||||||
|
).into(self.algo.unit.default)
|
||||||
|
hb_list[idx].chips = int(board["chipnum"])
|
||||||
|
hb_list[idx].missing = False
|
||||||
|
except LookupError:
|
||||||
|
pass
|
||||||
|
return hb_list
|
||||||
|
|
||||||
|
async def _get_uptime(self, web_userpanel: dict = None) -> Optional[int]:
|
||||||
|
if web_userpanel is None:
|
||||||
|
try:
|
||||||
|
web_userpanel = await self.web.userpanel()
|
||||||
|
except APIError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if web_userpanel is not None:
|
||||||
|
try:
|
||||||
|
runtime = web_userpanel["userpanel"]["data"]["runtime"]
|
||||||
|
days, hours, minutes, seconds = runtime.split(":")
|
||||||
|
return (
|
||||||
|
(int(days) * 24 * 60 * 60)
|
||||||
|
+ (int(hours) * 60 * 60)
|
||||||
|
+ (int(minutes) * 60)
|
||||||
|
+ int(seconds)
|
||||||
|
)
|
||||||
|
except (LookupError, ValueError, TypeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def _get_pools(self, web_userpanel: dict = None) -> List[PoolMetrics]:
|
||||||
|
if web_userpanel is None:
|
||||||
|
try:
|
||||||
|
web_userpanel = await self.web.userpanel()
|
||||||
|
except APIError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
pools_data = []
|
||||||
|
if web_userpanel is not None:
|
||||||
|
try:
|
||||||
|
pools = web_userpanel["userpanel"]["data"]["pools"]
|
||||||
|
for pool_info in pools:
|
||||||
|
pool_num = pool_info.get("no")
|
||||||
|
if pool_num is not None:
|
||||||
|
pool_num = int(pool_num)
|
||||||
|
if pool_info["addr"] == "":
|
||||||
|
continue
|
||||||
|
url = pool_info.get("addr")
|
||||||
|
pool_url = PoolUrl.from_str(url) if url else None
|
||||||
|
pool_data = PoolMetrics(
|
||||||
|
accepted=pool_info.get("accepted"),
|
||||||
|
rejected=pool_info.get("rejected"),
|
||||||
|
active=pool_info.get("connect"),
|
||||||
|
alive=int(pool_info.get("state", 0)) == 1,
|
||||||
|
url=pool_url,
|
||||||
|
user=pool_info.get("user"),
|
||||||
|
index=pool_num,
|
||||||
|
)
|
||||||
|
pools_data.append(pool_data)
|
||||||
|
except LookupError:
|
||||||
|
pass
|
||||||
|
return pools_data
|
||||||
@@ -19,6 +19,7 @@ from pyasic.config import MinerConfig
|
|||||||
from pyasic.data import AlgoHashRate, Fan, HashBoard, HashUnit
|
from pyasic.data import AlgoHashRate, Fan, HashBoard, HashUnit
|
||||||
from pyasic.data.error_codes import MinerErrorData
|
from pyasic.data.error_codes import MinerErrorData
|
||||||
from pyasic.data.error_codes.innosilicon import InnosiliconError
|
from pyasic.data.error_codes.innosilicon import InnosiliconError
|
||||||
|
from pyasic.data.pools import PoolMetrics, PoolUrl
|
||||||
from pyasic.errors import APIError
|
from pyasic.errors import APIError
|
||||||
from pyasic.miners.backends import CGMiner
|
from pyasic.miners.backends import CGMiner
|
||||||
from pyasic.miners.data import (
|
from pyasic.miners.data import (
|
||||||
@@ -29,7 +30,6 @@ from pyasic.miners.data import (
|
|||||||
WebAPICommand,
|
WebAPICommand,
|
||||||
)
|
)
|
||||||
from pyasic.web.innosilicon import InnosiliconWebAPI
|
from pyasic.web.innosilicon import InnosiliconWebAPI
|
||||||
from pyasic.data.pools import PoolMetrics, PoolUrl
|
|
||||||
|
|
||||||
INNOSILICON_DATA_LOC = DataLocations(
|
INNOSILICON_DATA_LOC = DataLocations(
|
||||||
**{
|
**{
|
||||||
@@ -92,9 +92,8 @@ INNOSILICON_DATA_LOC = DataLocations(
|
|||||||
[RPCAPICommand("rpc_stats", "stats")],
|
[RPCAPICommand("rpc_stats", "stats")],
|
||||||
),
|
),
|
||||||
str(DataOptions.POOLS): DataFunction(
|
str(DataOptions.POOLS): DataFunction(
|
||||||
"_get_pools",
|
"_get_pools", [RPCAPICommand("rpc_pools", "pools")]
|
||||||
[RPCAPICommand("rpc_pools", "pools")]
|
),
|
||||||
)
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -116,7 +115,7 @@ class Innosilicon(CGMiner):
|
|||||||
except APIError:
|
except APIError:
|
||||||
return self.config
|
return self.config
|
||||||
|
|
||||||
self.config = MinerConfig.from_inno([pools])
|
self.config = MinerConfig.from_inno(pools["pools"])
|
||||||
return self.config
|
return self.config
|
||||||
|
|
||||||
async def reboot(self) -> bool:
|
async def reboot(self) -> bool:
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
# See the License for the specific language governing permissions and -
|
# See the License for the specific language governing permissions and -
|
||||||
# limitations under the License. -
|
# limitations under the License. -
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
import logging
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
|
|
||||||
from pyasic.config import MinerConfig
|
from pyasic.config import MinerConfig
|
||||||
@@ -146,6 +147,22 @@ class LUXMiner(LuxOSFirmware):
|
|||||||
async def get_config(self) -> MinerConfig:
|
async def get_config(self) -> MinerConfig:
|
||||||
return self.config
|
return self.config
|
||||||
|
|
||||||
|
async def upgrade_firmware(self) -> bool:
|
||||||
|
"""
|
||||||
|
Upgrade the firmware on a LuxOS miner by calling the 'updaterun' API command.
|
||||||
|
Returns:
|
||||||
|
bool: True if the firmware upgrade was successfully initiated, False otherwise.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
await self.rpc.upgraderun()
|
||||||
|
logging.info(f"{self.ip}: Firmware upgrade initiated successfully.")
|
||||||
|
return True
|
||||||
|
|
||||||
|
except APIError as e:
|
||||||
|
logging.error(f"{self.ip}: Firmware upgrade failed: {e}")
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
##################################################
|
##################################################
|
||||||
### DATA GATHERING FUNCTIONS (get_{some_data}) ###
|
### DATA GATHERING FUNCTIONS (get_{some_data}) ###
|
||||||
##################################################
|
##################################################
|
||||||
|
|||||||
@@ -3,10 +3,12 @@ from typing import List, Optional
|
|||||||
from pyasic import MinerConfig
|
from pyasic import MinerConfig
|
||||||
from pyasic.config import MiningModeConfig
|
from pyasic.config import MiningModeConfig
|
||||||
from pyasic.data import AlgoHashRate, Fan, HashBoard, HashUnit
|
from pyasic.data import AlgoHashRate, Fan, HashBoard, HashUnit
|
||||||
|
from pyasic.data.pools import PoolMetrics, PoolUrl
|
||||||
from pyasic.errors import APIError
|
from pyasic.errors import APIError
|
||||||
from pyasic.miners.data import DataFunction, DataLocations, DataOptions, WebAPICommand
|
from pyasic.miners.data import DataFunction, DataLocations, DataOptions, WebAPICommand
|
||||||
from pyasic.miners.device.firmware import MaraFirmware
|
from pyasic.miners.device.firmware import MaraFirmware
|
||||||
from pyasic.misc import merge_dicts
|
from pyasic.misc import merge_dicts
|
||||||
|
from pyasic.rpc.marathon import MaraRPCAPI
|
||||||
from pyasic.web.marathon import MaraWebAPI
|
from pyasic.web.marathon import MaraWebAPI
|
||||||
|
|
||||||
MARA_DATA_LOC = DataLocations(
|
MARA_DATA_LOC = DataLocations(
|
||||||
@@ -59,11 +61,17 @@ MARA_DATA_LOC = DataLocations(
|
|||||||
"_get_uptime",
|
"_get_uptime",
|
||||||
[WebAPICommand("web_brief", "brief")],
|
[WebAPICommand("web_brief", "brief")],
|
||||||
),
|
),
|
||||||
|
str(DataOptions.POOLS): DataFunction(
|
||||||
|
"_get_pools",
|
||||||
|
[WebAPICommand("web_pools", "pools")],
|
||||||
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class MaraMiner(MaraFirmware):
|
class MaraMiner(MaraFirmware):
|
||||||
|
_rpc_cls = MaraRPCAPI
|
||||||
|
rpc: MaraRPCAPI
|
||||||
_web_cls = MaraWebAPI
|
_web_cls = MaraWebAPI
|
||||||
web: MaraWebAPI
|
web: MaraWebAPI
|
||||||
|
|
||||||
@@ -302,3 +310,43 @@ class MaraMiner(MaraFirmware):
|
|||||||
return web_miner_config["mode"]["concorde"]["power-target"]
|
return web_miner_config["mode"]["concorde"]["power-target"]
|
||||||
except LookupError:
|
except LookupError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
async def _get_pools(self, web_pools: list = None) -> List[PoolMetrics]:
|
||||||
|
if web_pools is None:
|
||||||
|
try:
|
||||||
|
web_pools = await self.web.pools()
|
||||||
|
except APIError:
|
||||||
|
return []
|
||||||
|
|
||||||
|
active_pool_index = None
|
||||||
|
highest_priority = float("inf")
|
||||||
|
|
||||||
|
for pool_info in web_pools:
|
||||||
|
if (
|
||||||
|
pool_info.get("status") == "Alive"
|
||||||
|
and pool_info.get("priority", float("inf")) < highest_priority
|
||||||
|
):
|
||||||
|
highest_priority = pool_info["priority"]
|
||||||
|
active_pool_index = pool_info["index"]
|
||||||
|
|
||||||
|
pools_data = []
|
||||||
|
if web_pools is not None:
|
||||||
|
try:
|
||||||
|
for pool_info in web_pools:
|
||||||
|
url = pool_info.get("url")
|
||||||
|
pool_url = PoolUrl.from_str(url) if url else None
|
||||||
|
pool_data = PoolMetrics(
|
||||||
|
accepted=pool_info.get("accepted"),
|
||||||
|
rejected=pool_info.get("rejected"),
|
||||||
|
get_failures=pool_info.get("stale"),
|
||||||
|
remote_failures=pool_info.get("discarded"),
|
||||||
|
active=pool_info.get("index") == active_pool_index,
|
||||||
|
alive=pool_info.get("status") == "Alive",
|
||||||
|
url=pool_url,
|
||||||
|
user=pool_info.get("user"),
|
||||||
|
index=pool_info.get("index"),
|
||||||
|
)
|
||||||
|
pools_data.append(pool_data)
|
||||||
|
except LookupError:
|
||||||
|
pass
|
||||||
|
return pools_data
|
||||||
|
|||||||
@@ -237,13 +237,17 @@ class VNish(VNishFirmware, BMMiner):
|
|||||||
|
|
||||||
async def _is_mining(self, web_summary: dict = None) -> Optional[bool]:
|
async def _is_mining(self, web_summary: dict = None) -> Optional[bool]:
|
||||||
if web_summary is None:
|
if web_summary is None:
|
||||||
|
try:
|
||||||
web_summary = await self.web.summary()
|
web_summary = await self.web.summary()
|
||||||
|
except APIError:
|
||||||
|
pass
|
||||||
|
|
||||||
if web_summary is not None:
|
if web_summary is not None:
|
||||||
try:
|
try:
|
||||||
is_mining = not web_summary["miner"]["miner_status"]["miner_state"] in [
|
is_mining = not web_summary["miner"]["miner_status"]["miner_state"] in [
|
||||||
"stopped",
|
"stopped",
|
||||||
"shutting-down",
|
"shutting-down",
|
||||||
|
"failure",
|
||||||
]
|
]
|
||||||
return is_mining
|
return is_mining
|
||||||
except LookupError:
|
except LookupError:
|
||||||
|
|||||||
@@ -560,5 +560,26 @@ class BaseMiner(MinerProtocol):
|
|||||||
if self._ssh_cls is not None:
|
if self._ssh_cls is not None:
|
||||||
self.ssh = self._ssh_cls(ip)
|
self.ssh = self._ssh_cls(ip)
|
||||||
|
|
||||||
|
async def upgrade_firmware(
|
||||||
|
self,
|
||||||
|
*,
|
||||||
|
file: str = None,
|
||||||
|
url: str = None,
|
||||||
|
version: str = None,
|
||||||
|
keep_settings: bool = True,
|
||||||
|
) -> bool:
|
||||||
|
"""Upgrade the firmware of the miner.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
file (str, optional): The file path to the firmware to upgrade from. Must be a valid file path if provided.
|
||||||
|
url (str, optional): The URL to download the firmware from. Must be a valid URL if provided.
|
||||||
|
version (str, optional): The version of the firmware to upgrade to. If None, the version will be inferred from the file or URL.
|
||||||
|
keep_settings (bool, optional): Whether to keep the current settings during the upgrade. Defaults to True.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A boolean value of the success of the firmware upgrade.
|
||||||
|
"""
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
AnyMiner = TypeVar("AnyMiner", bound=BaseMiner)
|
AnyMiner = TypeVar("AnyMiner", bound=BaseMiner)
|
||||||
|
|||||||
@@ -14,7 +14,4 @@
|
|||||||
# limitations under the License. -
|
# limitations under the License. -
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from .blockminer import (
|
from .blockminer import ePICBlockMiner520i, ePICBlockMiner720i
|
||||||
ePICBlockMiner520i,
|
|
||||||
ePICBlockMiner720i,
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -48,3 +48,7 @@ class ePICMake(BaseMiner):
|
|||||||
|
|
||||||
class BitAxeMake(BaseMiner):
|
class BitAxeMake(BaseMiner):
|
||||||
make = MinerMake.BITAXE
|
make = MinerMake.BITAXE
|
||||||
|
|
||||||
|
|
||||||
|
class IceRiverMake(BaseMiner):
|
||||||
|
make = MinerMake.ICERIVER
|
||||||
|
|||||||
@@ -19,5 +19,6 @@ from .auradine import *
|
|||||||
from .avalonminer import *
|
from .avalonminer import *
|
||||||
from .epic import *
|
from .epic import *
|
||||||
from .goldshell import *
|
from .goldshell import *
|
||||||
|
from .iceriver import *
|
||||||
from .innosilicon import *
|
from .innosilicon import *
|
||||||
from .whatsminer import *
|
from .whatsminer import *
|
||||||
|
|||||||
@@ -21,3 +21,9 @@ class Z15(AntMinerMake):
|
|||||||
raw_model = MinerModel.ANTMINER.Z15
|
raw_model = MinerModel.ANTMINER.Z15
|
||||||
|
|
||||||
expected_chips = 3
|
expected_chips = 3
|
||||||
|
|
||||||
|
|
||||||
|
class Z15Pro(AntMinerMake):
|
||||||
|
raw_model = MinerModel.ANTMINER.Z15Pro
|
||||||
|
|
||||||
|
expected_chips = 6
|
||||||
|
|||||||
@@ -13,4 +13,4 @@
|
|||||||
# See the License for the specific language governing permissions and -
|
# See the License for the specific language governing permissions and -
|
||||||
# limitations under the License. -
|
# limitations under the License. -
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
from .Z15 import Z15
|
from .Z15 import Z15, Z15Pro
|
||||||
|
|||||||
@@ -22,3 +22,10 @@ class S21(AntMinerMake):
|
|||||||
|
|
||||||
expected_chips = 108
|
expected_chips = 108
|
||||||
expected_fans = 4
|
expected_fans = 4
|
||||||
|
|
||||||
|
|
||||||
|
class S21Pro(AntMinerMake):
|
||||||
|
raw_model = MinerModel.ANTMINER.S21Pro
|
||||||
|
|
||||||
|
expected_chips = 65
|
||||||
|
expected_fans = 4
|
||||||
|
|||||||
@@ -14,5 +14,5 @@
|
|||||||
# limitations under the License. -
|
# limitations under the License. -
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from .S21 import S21
|
from .S21 import S21, S21Pro
|
||||||
from .T21 import T21
|
from .T21 import T21
|
||||||
|
|||||||
23
pyasic/miners/device/models/antminer/X3/KA3.py
Normal file
23
pyasic/miners/device/models/antminer/X3/KA3.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.device.models import MinerModel
|
||||||
|
from pyasic.miners.device.makes import AntMinerMake
|
||||||
|
|
||||||
|
|
||||||
|
class KA3(AntMinerMake):
|
||||||
|
raw_model = MinerModel.ANTMINER.KA3
|
||||||
|
|
||||||
|
expected_chips = 92
|
||||||
24
pyasic/miners/device/models/antminer/X3/KS3.py
Normal file
24
pyasic/miners/device/models/antminer/X3/KS3.py
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Copyright 2022 Upstream Data Inc -
|
||||||
|
# -
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||||
|
# you may not use this file except in compliance with the License. -
|
||||||
|
# You may obtain a copy of the License at -
|
||||||
|
# -
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||||
|
# -
|
||||||
|
# Unless required by applicable law or agreed to in writing, software -
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||||
|
# See the License for the specific language governing permissions and -
|
||||||
|
# limitations under the License. -
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
from pyasic.device.models import MinerModel
|
||||||
|
from pyasic.miners.device.makes import AntMinerMake
|
||||||
|
|
||||||
|
|
||||||
|
class KS3(AntMinerMake):
|
||||||
|
raw_model = MinerModel.ANTMINER.KS3
|
||||||
|
|
||||||
|
expected_chips = 92
|
||||||
|
expected_fans = 2
|
||||||
@@ -15,4 +15,6 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
from .D3 import D3
|
from .D3 import D3
|
||||||
from .HS3 import HS3
|
from .HS3 import HS3
|
||||||
|
from .KA3 import KA3
|
||||||
|
from .KS3 import KS3
|
||||||
from .L3 import L3Plus
|
from .L3 import L3Plus
|
||||||
|
|||||||
23
pyasic/miners/device/models/antminer/X5/KS5.py
Normal file
23
pyasic/miners/device/models/antminer/X5/KS5.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.device.models import MinerModel
|
||||||
|
from pyasic.miners.device.makes import AntMinerMake
|
||||||
|
|
||||||
|
|
||||||
|
class KS5(AntMinerMake):
|
||||||
|
raw_model = MinerModel.ANTMINER.KS5
|
||||||
|
|
||||||
|
expected_chips = 92
|
||||||
@@ -14,3 +14,4 @@
|
|||||||
# limitations under the License. -
|
# limitations under the License. -
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
from .DR5 import DR5
|
from .DR5 import DR5
|
||||||
|
from .KS5 import KS5
|
||||||
|
|||||||
24
pyasic/miners/device/models/antminer/X7/K7.py
Normal file
24
pyasic/miners/device/models/antminer/X7/K7.py
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Copyright 2022 Upstream Data Inc -
|
||||||
|
# -
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||||
|
# you may not use this file except in compliance with the License. -
|
||||||
|
# You may obtain a copy of the License at -
|
||||||
|
# -
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||||
|
# -
|
||||||
|
# Unless required by applicable law or agreed to in writing, software -
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||||
|
# See the License for the specific language governing permissions and -
|
||||||
|
# limitations under the License. -
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
from pyasic.device.models import MinerModel
|
||||||
|
from pyasic.miners.device.makes import AntMinerMake
|
||||||
|
|
||||||
|
|
||||||
|
class K7(AntMinerMake):
|
||||||
|
raw_model = MinerModel.ANTMINER.K7
|
||||||
|
|
||||||
|
expected_chips = 92
|
||||||
|
expected_fans = 4
|
||||||
@@ -13,4 +13,5 @@
|
|||||||
# See the License for the specific language governing permissions and -
|
# See the License for the specific language governing permissions and -
|
||||||
# limitations under the License. -
|
# limitations under the License. -
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
from .K7 import K7
|
||||||
from .L7 import L7
|
from .L7 import L7
|
||||||
|
|||||||
@@ -20,3 +20,4 @@ from .A9X import *
|
|||||||
from .A10X import *
|
from .A10X import *
|
||||||
from .A11X import *
|
from .A11X import *
|
||||||
from .A12X import *
|
from .A12X import *
|
||||||
|
from .nano import *
|
||||||
|
|||||||
1
pyasic/miners/device/models/avalonminer/nano/__init__.py
Normal file
1
pyasic/miners/device/models/avalonminer/nano/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
from .nano3 import AvalonNano3
|
||||||
10
pyasic/miners/device/models/avalonminer/nano/nano3.py
Normal file
10
pyasic/miners/device/models/avalonminer/nano/nano3.py
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
from pyasic.device import MinerModel
|
||||||
|
from pyasic.miners.device.makes import AvalonMinerMake
|
||||||
|
|
||||||
|
|
||||||
|
class AvalonNano3(AvalonMinerMake):
|
||||||
|
raw_model = MinerModel.AVALONMINER.AvalonNano3
|
||||||
|
|
||||||
|
expected_hashboards = 1
|
||||||
|
expected_chips = 10
|
||||||
|
expected_fans = 1
|
||||||
23
pyasic/miners/device/models/iceriver/KSX/KS0.py
Normal file
23
pyasic/miners/device/models/iceriver/KSX/KS0.py
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Copyright 2024 Upstream Data Inc -
|
||||||
|
# -
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||||
|
# you may not use this file except in compliance with the License. -
|
||||||
|
# You may obtain a copy of the License at -
|
||||||
|
# -
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||||
|
# -
|
||||||
|
# Unless required by applicable law or agreed to in writing, software -
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||||
|
# See the License for the specific language governing permissions and -
|
||||||
|
# limitations under the License. -
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
from pyasic.device.models import MinerModel
|
||||||
|
from pyasic.miners.device.makes import IceRiverMake
|
||||||
|
|
||||||
|
|
||||||
|
class KS0(IceRiverMake):
|
||||||
|
raw_model = MinerModel.ICERIVER.KS0
|
||||||
|
|
||||||
|
expected_fans = 0
|
||||||
23
pyasic/miners/device/models/iceriver/KSX/KS1.py
Normal file
23
pyasic/miners/device/models/iceriver/KSX/KS1.py
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Copyright 2024 Upstream Data Inc -
|
||||||
|
# -
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||||
|
# you may not use this file except in compliance with the License. -
|
||||||
|
# You may obtain a copy of the License at -
|
||||||
|
# -
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||||
|
# -
|
||||||
|
# Unless required by applicable law or agreed to in writing, software -
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||||
|
# See the License for the specific language governing permissions and -
|
||||||
|
# limitations under the License. -
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
from pyasic.device.models import MinerModel
|
||||||
|
from pyasic.miners.device.makes import IceRiverMake
|
||||||
|
|
||||||
|
|
||||||
|
class KS1(IceRiverMake):
|
||||||
|
raw_model = MinerModel.ICERIVER.KS1
|
||||||
|
|
||||||
|
expected_fans = 4
|
||||||
24
pyasic/miners/device/models/iceriver/KSX/KS2.py
Normal file
24
pyasic/miners/device/models/iceriver/KSX/KS2.py
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Copyright 2024 Upstream Data Inc -
|
||||||
|
# -
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||||
|
# you may not use this file except in compliance with the License. -
|
||||||
|
# You may obtain a copy of the License at -
|
||||||
|
# -
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||||
|
# -
|
||||||
|
# Unless required by applicable law or agreed to in writing, software -
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||||
|
# See the License for the specific language governing permissions and -
|
||||||
|
# limitations under the License. -
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
from pyasic.device.models import MinerModel
|
||||||
|
from pyasic.miners.device.makes import IceRiverMake
|
||||||
|
|
||||||
|
|
||||||
|
class KS2(IceRiverMake):
|
||||||
|
raw_model = MinerModel.ICERIVER.KS2
|
||||||
|
|
||||||
|
expected_fans = 4
|
||||||
|
expected_chips = 18
|
||||||
36
pyasic/miners/device/models/iceriver/KSX/KS3.py
Normal file
36
pyasic/miners/device/models/iceriver/KSX/KS3.py
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Copyright 2024 Upstream Data Inc -
|
||||||
|
# -
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||||
|
# you may not use this file except in compliance with the License. -
|
||||||
|
# You may obtain a copy of the License at -
|
||||||
|
# -
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||||
|
# -
|
||||||
|
# Unless required by applicable law or agreed to in writing, software -
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||||
|
# See the License for the specific language governing permissions and -
|
||||||
|
# limitations under the License. -
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
from pyasic.device.models import MinerModel
|
||||||
|
from pyasic.miners.device.makes import IceRiverMake
|
||||||
|
|
||||||
|
|
||||||
|
class KS3(IceRiverMake):
|
||||||
|
raw_model = MinerModel.ICERIVER.KS3
|
||||||
|
|
||||||
|
expected_fans = 4
|
||||||
|
|
||||||
|
|
||||||
|
class KS3L(IceRiverMake):
|
||||||
|
raw_model = MinerModel.ICERIVER.KS3L
|
||||||
|
|
||||||
|
expected_fans = 4
|
||||||
|
|
||||||
|
|
||||||
|
class KS3M(IceRiverMake):
|
||||||
|
raw_model = MinerModel.ICERIVER.KS3M
|
||||||
|
|
||||||
|
expected_fans = 4
|
||||||
|
expected_chips = 18
|
||||||
4
pyasic/miners/device/models/iceriver/KSX/__init__.py
Normal file
4
pyasic/miners/device/models/iceriver/KSX/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
from .KS0 import KS0
|
||||||
|
from .KS1 import KS1
|
||||||
|
from .KS2 import KS2
|
||||||
|
from .KS3 import KS3, KS3L, KS3M
|
||||||
1
pyasic/miners/device/models/iceriver/__init__.py
Normal file
1
pyasic/miners/device/models/iceriver/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
from .KSX import *
|
||||||
23
pyasic/miners/device/models/innosilicon/A11X/A11.py
Normal file
23
pyasic/miners/device/models/innosilicon/A11X/A11.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.device.models import MinerModel
|
||||||
|
from pyasic.miners.device.makes import InnosiliconMake
|
||||||
|
|
||||||
|
|
||||||
|
class A11(InnosiliconMake):
|
||||||
|
raw_model = MinerModel.INNOSILICON.A11
|
||||||
|
|
||||||
|
expected_hashboards = 4
|
||||||
24
pyasic/miners/device/models/innosilicon/A11X/A11M.py
Normal file
24
pyasic/miners/device/models/innosilicon/A11X/A11M.py
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Copyright 2022 Upstream Data Inc -
|
||||||
|
# -
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||||
|
# you may not use this file except in compliance with the License. -
|
||||||
|
# You may obtain a copy of the License at -
|
||||||
|
# -
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||||
|
# -
|
||||||
|
# Unless required by applicable law or agreed to in writing, software -
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||||
|
# See the License for the specific language governing permissions and -
|
||||||
|
# limitations under the License. -
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
from pyasic.device.models import MinerModel
|
||||||
|
from pyasic.miners.device.makes import InnosiliconMake
|
||||||
|
|
||||||
|
|
||||||
|
class A11MX(InnosiliconMake):
|
||||||
|
raw_model = MinerModel.INNOSILICON.A11MX
|
||||||
|
|
||||||
|
expected_hashboards = 4
|
||||||
|
expected_chips = 8
|
||||||
17
pyasic/miners/device/models/innosilicon/A11X/__init__.py
Normal file
17
pyasic/miners/device/models/innosilicon/A11X/__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 .A11 import *
|
||||||
|
from .A11M import *
|
||||||
@@ -15,4 +15,5 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from .A10X import *
|
from .A10X import *
|
||||||
|
from .A11X import *
|
||||||
from .T3X import *
|
from .T3X import *
|
||||||
|
|||||||
@@ -69,6 +69,8 @@ class M50VH60(WhatsMinerMake):
|
|||||||
class M50VH70(WhatsMinerMake):
|
class M50VH70(WhatsMinerMake):
|
||||||
raw_model = MinerModel.WHATSMINER.M50VH70
|
raw_model = MinerModel.WHATSMINER.M50VH70
|
||||||
|
|
||||||
|
expected_chips = 105
|
||||||
|
|
||||||
|
|
||||||
class M50VH80(WhatsMinerMake):
|
class M50VH80(WhatsMinerMake):
|
||||||
raw_model = MinerModel.WHATSMINER.M50VH80
|
raw_model = MinerModel.WHATSMINER.M50VH80
|
||||||
@@ -76,6 +78,12 @@ class M50VH80(WhatsMinerMake):
|
|||||||
expected_chips = 111
|
expected_chips = 111
|
||||||
|
|
||||||
|
|
||||||
|
class M50VH90(WhatsMinerMake):
|
||||||
|
raw_model = MinerModel.WHATSMINER.M50VH90
|
||||||
|
|
||||||
|
expected_chips = 117
|
||||||
|
|
||||||
|
|
||||||
class M50VJ10(WhatsMinerMake):
|
class M50VJ10(WhatsMinerMake):
|
||||||
raw_model = MinerModel.WHATSMINER.M50VJ10
|
raw_model = MinerModel.WHATSMINER.M50VJ10
|
||||||
|
|
||||||
@@ -83,6 +91,10 @@ class M50VJ10(WhatsMinerMake):
|
|||||||
class M50VJ20(WhatsMinerMake):
|
class M50VJ20(WhatsMinerMake):
|
||||||
raw_model = MinerModel.WHATSMINER.M50VJ20
|
raw_model = MinerModel.WHATSMINER.M50VJ20
|
||||||
|
|
||||||
|
expected_chips = 111
|
||||||
|
|
||||||
|
|
||||||
class M50VJ30(WhatsMinerMake):
|
class M50VJ30(WhatsMinerMake):
|
||||||
raw_model = MinerModel.WHATSMINER.M50VJ30
|
raw_model = MinerModel.WHATSMINER.M50VJ30
|
||||||
|
|
||||||
|
expected_chips = 117
|
||||||
|
|||||||
@@ -51,3 +51,5 @@ class M50SVH40(WhatsMinerMake):
|
|||||||
|
|
||||||
class M50SVH50(WhatsMinerMake):
|
class M50SVH50(WhatsMinerMake):
|
||||||
raw_model = MinerModel.WHATSMINER.M50SVH50
|
raw_model = MinerModel.WHATSMINER.M50SVH50
|
||||||
|
|
||||||
|
expected_chips = 135
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ from .M50 import (
|
|||||||
M50VH60,
|
M50VH60,
|
||||||
M50VH70,
|
M50VH70,
|
||||||
M50VH80,
|
M50VH80,
|
||||||
|
M50VH90,
|
||||||
M50VJ10,
|
M50VJ10,
|
||||||
M50VJ20,
|
M50VJ20,
|
||||||
M50VJ30,
|
M50VJ30,
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ class M60VK10(WhatsMinerMake):
|
|||||||
class M60VK20(WhatsMinerMake):
|
class M60VK20(WhatsMinerMake):
|
||||||
raw_model = MinerModel.WHATSMINER.M60VK20
|
raw_model = MinerModel.WHATSMINER.M60VK20
|
||||||
|
|
||||||
|
expected_chips = 172
|
||||||
|
|
||||||
|
|
||||||
class M60VK30(WhatsMinerMake):
|
class M60VK30(WhatsMinerMake):
|
||||||
raw_model = MinerModel.WHATSMINER.M60VK30
|
raw_model = MinerModel.WHATSMINER.M60VK30
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import enum
|
|||||||
import ipaddress
|
import ipaddress
|
||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
|
import warnings
|
||||||
from typing import Any, AsyncGenerator, Callable
|
from typing import Any, AsyncGenerator, Callable
|
||||||
|
|
||||||
import anyio
|
import anyio
|
||||||
@@ -38,6 +39,7 @@ from pyasic.miners.bitaxe import *
|
|||||||
from pyasic.miners.blockminer import *
|
from pyasic.miners.blockminer import *
|
||||||
from pyasic.miners.device.makes import *
|
from pyasic.miners.device.makes import *
|
||||||
from pyasic.miners.goldshell import *
|
from pyasic.miners.goldshell import *
|
||||||
|
from pyasic.miners.iceriver import *
|
||||||
from pyasic.miners.innosilicon import *
|
from pyasic.miners.innosilicon import *
|
||||||
from pyasic.miners.whatsminer import *
|
from pyasic.miners.whatsminer import *
|
||||||
|
|
||||||
@@ -56,6 +58,7 @@ class MinerTypes(enum.Enum):
|
|||||||
AURADINE = 10
|
AURADINE = 10
|
||||||
MARATHON = 11
|
MARATHON = 11
|
||||||
BITAXE = 12
|
BITAXE = 12
|
||||||
|
ICERIVER = 13
|
||||||
|
|
||||||
|
|
||||||
MINER_CLASSES = {
|
MINER_CLASSES = {
|
||||||
@@ -64,14 +67,19 @@ MINER_CLASSES = {
|
|||||||
"ANTMINER D3": CGMinerD3,
|
"ANTMINER D3": CGMinerD3,
|
||||||
"ANTMINER HS3": BMMinerHS3,
|
"ANTMINER HS3": BMMinerHS3,
|
||||||
"ANTMINER L3+": BMMinerL3Plus,
|
"ANTMINER L3+": BMMinerL3Plus,
|
||||||
|
"ANTMINER KA3": BMMinerKA3,
|
||||||
|
"ANTMINER KS3": BMMinerKS3,
|
||||||
"ANTMINER DR5": CGMinerDR5,
|
"ANTMINER DR5": CGMinerDR5,
|
||||||
|
"ANTMINER KS5": BMMinerKS5,
|
||||||
"ANTMINER L7": BMMinerL7,
|
"ANTMINER L7": BMMinerL7,
|
||||||
|
"ANTMINER K7": BMMinerK7,
|
||||||
"ANTMINER E9 PRO": BMMinerE9Pro,
|
"ANTMINER E9 PRO": BMMinerE9Pro,
|
||||||
"ANTMINER S9": BMMinerS9,
|
"ANTMINER S9": BMMinerS9,
|
||||||
"ANTMINER S9I": BMMinerS9i,
|
"ANTMINER S9I": BMMinerS9i,
|
||||||
"ANTMINER S9J": BMMinerS9j,
|
"ANTMINER S9J": BMMinerS9j,
|
||||||
"ANTMINER T9": BMMinerT9,
|
"ANTMINER T9": BMMinerT9,
|
||||||
"ANTMINER Z15": CGMinerZ15,
|
"ANTMINER Z15": CGMinerZ15,
|
||||||
|
"ANTMINER Z15 PRO": BMMinerZ15Pro,
|
||||||
"ANTMINER S17": BMMinerS17,
|
"ANTMINER S17": BMMinerS17,
|
||||||
"ANTMINER S17+": BMMinerS17Plus,
|
"ANTMINER S17+": BMMinerS17Plus,
|
||||||
"ANTMINER S17 PRO": BMMinerS17Pro,
|
"ANTMINER S17 PRO": BMMinerS17Pro,
|
||||||
@@ -97,6 +105,7 @@ MINER_CLASSES = {
|
|||||||
"ANTMINER S19K PRO": BMMinerS19KPro,
|
"ANTMINER S19K PRO": BMMinerS19KPro,
|
||||||
"ANTMINER T19": BMMinerT19,
|
"ANTMINER T19": BMMinerT19,
|
||||||
"ANTMINER S21": BMMinerS21,
|
"ANTMINER S21": BMMinerS21,
|
||||||
|
"ANTMINER S21 PRO": BMMinerS21Pro,
|
||||||
"ANTMINER T21": BMMinerT21,
|
"ANTMINER T21": BMMinerT21,
|
||||||
},
|
},
|
||||||
MinerTypes.WHATSMINER: {
|
MinerTypes.WHATSMINER: {
|
||||||
@@ -268,6 +277,7 @@ MINER_CLASSES = {
|
|||||||
"M50VH60": BTMinerM50VH60,
|
"M50VH60": BTMinerM50VH60,
|
||||||
"M50VH70": BTMinerM50VH70,
|
"M50VH70": BTMinerM50VH70,
|
||||||
"M50VH80": BTMinerM50VH80,
|
"M50VH80": BTMinerM50VH80,
|
||||||
|
"M50VH90": BTMinerM50VH90,
|
||||||
"M50VJ10": BTMinerM50VJ10,
|
"M50VJ10": BTMinerM50VJ10,
|
||||||
"M50VJ20": BTMinerM50VJ20,
|
"M50VJ20": BTMinerM50VJ20,
|
||||||
"M50VJ30": BTMinerM50VJ30,
|
"M50VJ30": BTMinerM50VJ30,
|
||||||
@@ -329,11 +339,14 @@ MINER_CLASSES = {
|
|||||||
"AVALONMINER 1066": CGMinerAvalon1066,
|
"AVALONMINER 1066": CGMinerAvalon1066,
|
||||||
"AVALONMINER 1166PRO": CGMinerAvalon1166Pro,
|
"AVALONMINER 1166PRO": CGMinerAvalon1166Pro,
|
||||||
"AVALONMINER 1246": CGMinerAvalon1246,
|
"AVALONMINER 1246": CGMinerAvalon1246,
|
||||||
|
"AVALONMINER NANO3": CGMinerAvalonNano3,
|
||||||
},
|
},
|
||||||
MinerTypes.INNOSILICON: {
|
MinerTypes.INNOSILICON: {
|
||||||
None: type("InnosiliconUnknown", (Innosilicon, InnosiliconMake), {}),
|
None: type("InnosiliconUnknown", (Innosilicon, InnosiliconMake), {}),
|
||||||
"T3H+": InnosiliconT3HPlus,
|
"T3H+": InnosiliconT3HPlus,
|
||||||
"A10X": InnosiliconA10X,
|
"A10X": InnosiliconA10X,
|
||||||
|
"A11": InnosiliconA11,
|
||||||
|
"A11MX": InnosiliconA11MX,
|
||||||
},
|
},
|
||||||
MinerTypes.GOLDSHELL: {
|
MinerTypes.GOLDSHELL: {
|
||||||
None: type("GoldshellUnknown", (GoldshellMiner, GoldshellMake), {}),
|
None: type("GoldshellUnknown", (GoldshellMiner, GoldshellMake), {}),
|
||||||
@@ -372,6 +385,7 @@ MINER_CLASSES = {
|
|||||||
"ANTMINER S19 PRO+ HYD.": BOSMinerS19ProPlusHydro,
|
"ANTMINER S19 PRO+ HYD.": BOSMinerS19ProPlusHydro,
|
||||||
"ANTMINER T19": BOSMinerT19,
|
"ANTMINER T19": BOSMinerT19,
|
||||||
"ANTMINER S21": BOSMinerS21,
|
"ANTMINER S21": BOSMinerS21,
|
||||||
|
"ANTMINER T21": BOSMinerT21,
|
||||||
},
|
},
|
||||||
MinerTypes.VNISH: {
|
MinerTypes.VNISH: {
|
||||||
None: VNish,
|
None: VNish,
|
||||||
@@ -385,6 +399,7 @@ MINER_CLASSES = {
|
|||||||
"ANTMINER S19 PRO": VNishS19Pro,
|
"ANTMINER S19 PRO": VNishS19Pro,
|
||||||
"ANTMINER S19J": VNishS19j,
|
"ANTMINER S19J": VNishS19j,
|
||||||
"ANTMINER S19J PRO": VNishS19jPro,
|
"ANTMINER S19J PRO": VNishS19jPro,
|
||||||
|
"ANTMINER S19J PRO BB": VNishS19jPro,
|
||||||
"ANTMINER S19A": VNishS19a,
|
"ANTMINER S19A": VNishS19a,
|
||||||
"ANTMINER S19A PRO": VNishS19aPro,
|
"ANTMINER S19A PRO": VNishS19aPro,
|
||||||
"ANTMINER S19 PRO HYD.": VNishS19ProHydro,
|
"ANTMINER S19 PRO HYD.": VNishS19ProHydro,
|
||||||
@@ -401,6 +416,7 @@ MINER_CLASSES = {
|
|||||||
"ANTMINER S19K PRO": ePICS19kPro,
|
"ANTMINER S19K PRO": ePICS19kPro,
|
||||||
"ANTMINER S19 XP": ePICS19XP,
|
"ANTMINER S19 XP": ePICS19XP,
|
||||||
"ANTMINER S21": ePICS21,
|
"ANTMINER S21": ePICS21,
|
||||||
|
"ANTMINER S21 PRO": ePICS21Pro,
|
||||||
"ANTMINER T21": ePICT21,
|
"ANTMINER T21": ePICT21,
|
||||||
"BLOCKMINER 520I": ePICBlockMiner520i,
|
"BLOCKMINER 520I": ePICBlockMiner520i,
|
||||||
"BLOCKMINER 720I": ePICBlockMiner720i,
|
"BLOCKMINER 720I": ePICBlockMiner720i,
|
||||||
@@ -449,6 +465,15 @@ MINER_CLASSES = {
|
|||||||
"BM1366": BitAxeUltra,
|
"BM1366": BitAxeUltra,
|
||||||
"BM1397": BitAxeMax,
|
"BM1397": BitAxeMax,
|
||||||
},
|
},
|
||||||
|
MinerTypes.ICERIVER: {
|
||||||
|
None: type("IceRiverUnknown", (IceRiver, IceRiverMake), {}),
|
||||||
|
"KS0": IceRiverKS0,
|
||||||
|
"KS1": IceRiverKS1,
|
||||||
|
"KS2": IceRiverKS2,
|
||||||
|
"KS3": IceRiverKS3,
|
||||||
|
"KS3L": IceRiverKS3L,
|
||||||
|
"KS3M": IceRiverKS3M,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -526,6 +551,7 @@ class MinerFactory:
|
|||||||
MinerTypes.AURADINE: self.get_miner_model_auradine,
|
MinerTypes.AURADINE: self.get_miner_model_auradine,
|
||||||
MinerTypes.MARATHON: self.get_miner_model_marathon,
|
MinerTypes.MARATHON: self.get_miner_model_marathon,
|
||||||
MinerTypes.BITAXE: self.get_miner_model_bitaxe,
|
MinerTypes.BITAXE: self.get_miner_model_bitaxe,
|
||||||
|
MinerTypes.ICERIVER: self.get_miner_model_iceriver,
|
||||||
}
|
}
|
||||||
fn = miner_model_fns.get(miner_type)
|
fn = miner_model_fns.get(miner_type)
|
||||||
|
|
||||||
@@ -607,6 +633,10 @@ class MinerFactory:
|
|||||||
return MinerTypes.WHATSMINER
|
return MinerTypes.WHATSMINER
|
||||||
if "Braiins OS" in web_text:
|
if "Braiins OS" in web_text:
|
||||||
return MinerTypes.BRAIINS_OS
|
return MinerTypes.BRAIINS_OS
|
||||||
|
if "Luxor Firmware" in web_text:
|
||||||
|
return MinerTypes.LUX_OS
|
||||||
|
if "<TITLE>用户界面</TITLE>" in web_text:
|
||||||
|
return MinerTypes.ICERIVER
|
||||||
if "AxeOS" in web_text:
|
if "AxeOS" in web_text:
|
||||||
return MinerTypes.BITAXE
|
return MinerTypes.BITAXE
|
||||||
if "cloud-box" in web_text:
|
if "cloud-box" in web_text:
|
||||||
@@ -687,8 +717,6 @@ class MinerFactory:
|
|||||||
return MinerTypes.BRAIINS_OS
|
return MinerTypes.BRAIINS_OS
|
||||||
if "BTMINER" in upper_data or "BITMICRO" in upper_data:
|
if "BTMINER" in upper_data or "BITMICRO" in upper_data:
|
||||||
return MinerTypes.WHATSMINER
|
return MinerTypes.WHATSMINER
|
||||||
if "VNISH" in upper_data or "DEVICE PATH" in upper_data:
|
|
||||||
return MinerTypes.VNISH
|
|
||||||
if "HIVEON" in upper_data:
|
if "HIVEON" in upper_data:
|
||||||
return MinerTypes.HIVEON
|
return MinerTypes.HIVEON
|
||||||
if "LUXMINER" in upper_data:
|
if "LUXMINER" in upper_data:
|
||||||
@@ -703,10 +731,14 @@ class MinerFactory:
|
|||||||
or "BFGMINER" in upper_data
|
or "BFGMINER" in upper_data
|
||||||
):
|
):
|
||||||
return MinerTypes.GOLDSHELL
|
return MinerTypes.GOLDSHELL
|
||||||
|
if "INNOMINER" in upper_data:
|
||||||
|
return MinerTypes.INNOSILICON
|
||||||
if "AVALON" in upper_data:
|
if "AVALON" in upper_data:
|
||||||
return MinerTypes.AVALONMINER
|
return MinerTypes.AVALONMINER
|
||||||
if "GCMINER" in upper_data or "FLUXOS" in upper_data:
|
if "GCMINER" in upper_data or "FLUXOS" in upper_data:
|
||||||
return MinerTypes.AURADINE
|
return MinerTypes.AURADINE
|
||||||
|
if "VNISH" in upper_data:
|
||||||
|
return MinerTypes.VNISH
|
||||||
|
|
||||||
async def send_web_command(
|
async def send_web_command(
|
||||||
self,
|
self,
|
||||||
@@ -796,7 +828,9 @@ class MinerFactory:
|
|||||||
str_data = str_data.replace("info", "1nfo")
|
str_data = str_data.replace("info", "1nfo")
|
||||||
str_data = str_data.replace("inf", "0")
|
str_data = str_data.replace("inf", "0")
|
||||||
str_data = str_data.replace("1nfo", "info")
|
str_data = str_data.replace("1nfo", "info")
|
||||||
|
str_data = str_data.replace("nano", "n4no")
|
||||||
str_data = str_data.replace("nan", "0")
|
str_data = str_data.replace("nan", "0")
|
||||||
|
str_data = str_data.replace("n4no", "nano")
|
||||||
# fix whatever this garbage from avalonminers is `,"id":1}`
|
# fix whatever this garbage from avalonminers is `,"id":1}`
|
||||||
if str_data.startswith(","):
|
if str_data.startswith(","):
|
||||||
str_data = f"{{{str_data[1:]}"
|
str_data = f"{{{str_data[1:]}"
|
||||||
@@ -821,6 +855,10 @@ class MinerFactory:
|
|||||||
return MINER_CLASSES[miner_type][str(miner_model).upper()](ip)
|
return MINER_CLASSES[miner_type][str(miner_model).upper()](ip)
|
||||||
except LookupError:
|
except LookupError:
|
||||||
if miner_type in MINER_CLASSES:
|
if miner_type in MINER_CLASSES:
|
||||||
|
warnings.warn(
|
||||||
|
f"Partially supported miner found: {miner_model}, please open an issue with miner data "
|
||||||
|
f"and this model on GitHub (https://github.com/UpstreamData/pyasic/issues)."
|
||||||
|
)
|
||||||
return MINER_CLASSES[miner_type][None](ip)
|
return MINER_CLASSES[miner_type][None](ip)
|
||||||
return UnknownMiner(str(ip))
|
return UnknownMiner(str(ip))
|
||||||
|
|
||||||
@@ -896,10 +934,12 @@ class MinerFactory:
|
|||||||
async def get_miner_model_avalonminer(self, ip: str) -> str | None:
|
async def get_miner_model_avalonminer(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")
|
||||||
try:
|
try:
|
||||||
miner_model = sock_json_data["VERSION"][0]["PROD"]
|
miner_model = sock_json_data["VERSION"][0]["PROD"].upper()
|
||||||
if "-" in miner_model:
|
if "-" in miner_model:
|
||||||
miner_model = miner_model.split("-")[0]
|
miner_model = miner_model.split("-")[0]
|
||||||
|
if miner_model in ["AVALONNANO", "AVALON0O"]:
|
||||||
|
nano_subtype = sock_json_data["VERSION"][0]["MODEL"].upper()
|
||||||
|
miner_model = f"AVALONMINER {nano_subtype}"
|
||||||
return miner_model
|
return miner_model
|
||||||
except (TypeError, LookupError):
|
except (TypeError, LookupError):
|
||||||
pass
|
pass
|
||||||
@@ -909,10 +949,19 @@ class MinerFactory:
|
|||||||
async with httpx.AsyncClient(transport=settings.transport()) as session:
|
async with httpx.AsyncClient(transport=settings.transport()) as session:
|
||||||
auth_req = await session.post(
|
auth_req = await session.post(
|
||||||
f"http://{ip}/api/auth",
|
f"http://{ip}/api/auth",
|
||||||
data={"username": "admin", "password": "admin"},
|
data={
|
||||||
|
"username": "admin",
|
||||||
|
"password": settings.get(
|
||||||
|
"default_innosilicon_web_password", "admin"
|
||||||
|
),
|
||||||
|
},
|
||||||
)
|
)
|
||||||
auth = auth_req.json()["jwt"]
|
auth = auth_req.json()["jwt"]
|
||||||
|
except (httpx.HTTPError, LookupError):
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
async with httpx.AsyncClient(transport=settings.transport()) as session:
|
||||||
web_data = (
|
web_data = (
|
||||||
await session.post(
|
await session.post(
|
||||||
f"http://{ip}/api/type",
|
f"http://{ip}/api/type",
|
||||||
@@ -923,6 +972,18 @@ class MinerFactory:
|
|||||||
return web_data["type"]
|
return web_data["type"]
|
||||||
except (httpx.HTTPError, LookupError):
|
except (httpx.HTTPError, LookupError):
|
||||||
pass
|
pass
|
||||||
|
try:
|
||||||
|
async with httpx.AsyncClient(transport=settings.transport()) as session:
|
||||||
|
web_data = (
|
||||||
|
await session.post(
|
||||||
|
f"http://{ip}/overview",
|
||||||
|
headers={"Authorization": "Bearer " + auth},
|
||||||
|
data={},
|
||||||
|
)
|
||||||
|
).json()
|
||||||
|
return web_data["type"]
|
||||||
|
except (httpx.HTTPError, LookupError):
|
||||||
|
pass
|
||||||
|
|
||||||
async def get_miner_model_braiins_os(self, ip: str) -> str | None:
|
async def get_miner_model_braiins_os(self, ip: str) -> str | None:
|
||||||
sock_json_data = await self.send_api_command(ip, "devdetails")
|
sock_json_data = await self.send_api_command(ip, "devdetails")
|
||||||
@@ -1036,6 +1097,39 @@ class MinerFactory:
|
|||||||
except (TypeError, LookupError):
|
except (TypeError, LookupError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
async def get_miner_model_iceriver(self, ip: str) -> str | None:
|
||||||
|
async with httpx.AsyncClient(transport=settings.transport()) as client:
|
||||||
|
try:
|
||||||
|
# auth
|
||||||
|
await client.post(
|
||||||
|
f"http://{ip}/user/loginpost",
|
||||||
|
params={
|
||||||
|
"post": "6",
|
||||||
|
"user": "admin",
|
||||||
|
"pwd": settings.get(
|
||||||
|
"default_iceriver_web_password", "12345678"
|
||||||
|
),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
except httpx.HTTPError:
|
||||||
|
return None
|
||||||
|
try:
|
||||||
|
resp = await client.post(
|
||||||
|
f"http://{ip}:/user/userpanel", params={"post": "4"}
|
||||||
|
)
|
||||||
|
if not resp.status_code == 200:
|
||||||
|
return
|
||||||
|
result = resp.json()
|
||||||
|
software_ver = result["data"]["softver1"]
|
||||||
|
split_ver = software_ver.split("_")
|
||||||
|
if split_ver[-1] == "miner":
|
||||||
|
miner_ver = split_ver[-2]
|
||||||
|
else:
|
||||||
|
miner_ver = split_ver[-1].replace("miner", "")
|
||||||
|
return miner_ver.upper()
|
||||||
|
except httpx.HTTPError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
miner_factory = MinerFactory()
|
miner_factory = MinerFactory()
|
||||||
|
|
||||||
|
|||||||
1
pyasic/miners/iceriver/__init__.py
Normal file
1
pyasic/miners/iceriver/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
from .iceminer import *
|
||||||
6
pyasic/miners/iceriver/iceminer/KSX/KS0.py
Normal file
6
pyasic/miners/iceriver/iceminer/KSX/KS0.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
from pyasic.miners.backends.iceriver import IceRiver
|
||||||
|
from pyasic.miners.device.models import KS0
|
||||||
|
|
||||||
|
|
||||||
|
class IceRiverKS0(IceRiver, KS0):
|
||||||
|
pass
|
||||||
6
pyasic/miners/iceriver/iceminer/KSX/KS1.py
Normal file
6
pyasic/miners/iceriver/iceminer/KSX/KS1.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
from pyasic.miners.backends.iceriver import IceRiver
|
||||||
|
from pyasic.miners.device.models import KS1
|
||||||
|
|
||||||
|
|
||||||
|
class IceRiverKS1(IceRiver, KS1):
|
||||||
|
pass
|
||||||
6
pyasic/miners/iceriver/iceminer/KSX/KS2.py
Normal file
6
pyasic/miners/iceriver/iceminer/KSX/KS2.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
from pyasic.miners.backends.iceriver import IceRiver
|
||||||
|
from pyasic.miners.device.models import KS2
|
||||||
|
|
||||||
|
|
||||||
|
class IceRiverKS2(IceRiver, KS2):
|
||||||
|
pass
|
||||||
14
pyasic/miners/iceriver/iceminer/KSX/KS3.py
Normal file
14
pyasic/miners/iceriver/iceminer/KSX/KS3.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
from pyasic.miners.backends.iceriver import IceRiver
|
||||||
|
from pyasic.miners.device.models.iceriver import KS3, KS3L, KS3M
|
||||||
|
|
||||||
|
|
||||||
|
class IceRiverKS3(IceRiver, KS3):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class IceRiverKS3L(IceRiver, KS3L):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class IceRiverKS3M(IceRiver, KS3M):
|
||||||
|
pass
|
||||||
4
pyasic/miners/iceriver/iceminer/KSX/__init__.py
Normal file
4
pyasic/miners/iceriver/iceminer/KSX/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
from .KS0 import IceRiverKS0
|
||||||
|
from .KS1 import IceRiverKS1
|
||||||
|
from .KS2 import IceRiverKS2
|
||||||
|
from .KS3 import IceRiverKS3, IceRiverKS3L, IceRiverKS3M
|
||||||
1
pyasic/miners/iceriver/iceminer/__init__.py
Normal file
1
pyasic/miners/iceriver/iceminer/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
from .KSX import *
|
||||||
22
pyasic/miners/innosilicon/cgminer/A11X/A11.py
Normal file
22
pyasic/miners/innosilicon/cgminer/A11X/A11.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.innosilicon import Innosilicon
|
||||||
|
from pyasic.miners.device.models import A11
|
||||||
|
|
||||||
|
|
||||||
|
class InnosiliconA11(Innosilicon, A11):
|
||||||
|
pass
|
||||||
22
pyasic/miners/innosilicon/cgminer/A11X/A11M.py
Normal file
22
pyasic/miners/innosilicon/cgminer/A11X/A11M.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.innosilicon import Innosilicon
|
||||||
|
from pyasic.miners.device.models import A11MX
|
||||||
|
|
||||||
|
|
||||||
|
class InnosiliconA11MX(Innosilicon, A11MX):
|
||||||
|
pass
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user