Compare commits
48 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
309356243b | ||
|
|
e9b4cc9bd6 | ||
|
|
648c54de93 | ||
|
|
e1ce96ab1b | ||
|
|
86860a8dc4 | ||
|
|
5212641f45 | ||
|
|
52432e6043 | ||
|
|
727e484860 | ||
|
|
6c091756d2 | ||
|
|
14533ce4fe | ||
|
|
82d1840039 | ||
|
|
8e6240cdba | ||
|
|
5749e173d1 | ||
|
|
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 |
@@ -1,12 +1,15 @@
|
|||||||
|
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: v5.0.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: trailing-whitespace
|
- id: trailing-whitespace
|
||||||
- id: check-yaml
|
- id: check-yaml
|
||||||
- id: check-added-large-files
|
- id: check-added-large-files
|
||||||
- repo: https://github.com/psf/black
|
- repo: https://github.com/psf/black
|
||||||
rev: 24.3.0
|
rev: 24.10.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: black
|
- id: black
|
||||||
- repo: https://github.com/pycqa/isort
|
- repo: https://github.com/pycqa/isort
|
||||||
@@ -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]
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -274,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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
@@ -43,3 +43,24 @@
|
|||||||
show_root_heading: false
|
show_root_heading: false
|
||||||
heading_level: 4
|
heading_level: 4
|
||||||
|
|
||||||
|
## KS5 (Stock)
|
||||||
|
::: pyasic.miners.iceriver.iceminer.KSX.KS5.IceRiverKS5
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
## KS5L (Stock)
|
||||||
|
::: pyasic.miners.iceriver.iceminer.KSX.KS5.IceRiverKS5L
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
## KS5M (Stock)
|
||||||
|
::: pyasic.miners.iceriver.iceminer.KSX.KS5.IceRiverKS5M
|
||||||
|
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
|
||||||
|
|
||||||
@@ -36,6 +36,7 @@ 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>
|
||||||
@@ -52,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>
|
||||||
@@ -281,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>
|
||||||
@@ -407,6 +410,7 @@ details {
|
|||||||
<details>
|
<details>
|
||||||
<summary>A11X Series:</summary>
|
<summary>A11X Series:</summary>
|
||||||
<ul>
|
<ul>
|
||||||
|
<li><a href="../innosilicon/A11X#a11-stock">A11 (Stock)</a></li>
|
||||||
<li><a href="../innosilicon/A11X#a11mx-stock">A11MX (Stock)</a></li>
|
<li><a href="../innosilicon/A11X#a11mx-stock">A11MX (Stock)</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</details>
|
</details>
|
||||||
@@ -521,6 +525,7 @@ 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#s19-pro-hydro-vnish">S19 Pro Hydro (VNish)</a></li>
|
||||||
@@ -683,6 +688,9 @@ details {
|
|||||||
<li><a href="../iceriver/KSX#ks3-stock">KS3 (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#ks3l-stock">KS3L (Stock)</a></li>
|
||||||
<li><a href="../iceriver/KSX#ks3m-stock">KS3M (Stock)</a></li>
|
<li><a href="../iceriver/KSX#ks3m-stock">KS3M (Stock)</a></li>
|
||||||
|
<li><a href="../iceriver/KSX#ks5-stock">KS5 (Stock)</a></li>
|
||||||
|
<li><a href="../iceriver/KSX#ks5l-stock">KS5L (Stock)</a></li>
|
||||||
|
<li><a href="../iceriver/KSX#ks5m-stock">KS5M (Stock)</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</details>
|
</details>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
64
poetry.lock
generated
64
poetry.lock
generated
@@ -1,4 +1,4 @@
|
|||||||
# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand.
|
# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand.
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aiofiles"
|
name = "aiofiles"
|
||||||
@@ -1121,41 +1121,41 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "watchdog"
|
name = "watchdog"
|
||||||
version = "5.0.3"
|
version = "6.0.0"
|
||||||
description = "Filesystem events monitoring"
|
description = "Filesystem events monitoring"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.9"
|
python-versions = ">=3.9"
|
||||||
files = [
|
files = [
|
||||||
{file = "watchdog-5.0.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:85527b882f3facda0579bce9d743ff7f10c3e1e0db0a0d0e28170a7d0e5ce2ea"},
|
{file = "watchdog-6.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d1cdb490583ebd691c012b3d6dae011000fe42edb7a82ece80965b42abd61f26"},
|
||||||
{file = "watchdog-5.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:53adf73dcdc0ef04f7735066b4a57a4cd3e49ef135daae41d77395f0b5b692cb"},
|
{file = "watchdog-6.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bc64ab3bdb6a04d69d4023b29422170b74681784ffb9463ed4870cf2f3e66112"},
|
||||||
{file = "watchdog-5.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e25adddab85f674acac303cf1f5835951345a56c5f7f582987d266679979c75b"},
|
{file = "watchdog-6.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c897ac1b55c5a1461e16dae288d22bb2e412ba9807df8397a635d88f671d36c3"},
|
||||||
{file = "watchdog-5.0.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f01f4a3565a387080dc49bdd1fefe4ecc77f894991b88ef927edbfa45eb10818"},
|
{file = "watchdog-6.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6eb11feb5a0d452ee41f824e271ca311a09e250441c262ca2fd7ebcf2461a06c"},
|
||||||
{file = "watchdog-5.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:91b522adc25614cdeaf91f7897800b82c13b4b8ac68a42ca959f992f6990c490"},
|
{file = "watchdog-6.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ef810fbf7b781a5a593894e4f439773830bdecb885e6880d957d5b9382a960d2"},
|
||||||
{file = "watchdog-5.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d52db5beb5e476e6853da2e2d24dbbbed6797b449c8bf7ea118a4ee0d2c9040e"},
|
{file = "watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:afd0fe1b2270917c5e23c2a65ce50c2a4abb63daafb0d419fde368e272a76b7c"},
|
||||||
{file = "watchdog-5.0.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:94d11b07c64f63f49876e0ab8042ae034674c8653bfcdaa8c4b32e71cfff87e8"},
|
{file = "watchdog-6.0.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdd4e6f14b8b18c334febb9c4425a878a2ac20efd1e0b231978e7b150f92a948"},
|
||||||
{file = "watchdog-5.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:349c9488e1d85d0a58e8cb14222d2c51cbc801ce11ac3936ab4c3af986536926"},
|
{file = "watchdog-6.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c7c15dda13c4eb00d6fb6fc508b3c0ed88b9d5d374056b239c4ad1611125c860"},
|
||||||
{file = "watchdog-5.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:53a3f10b62c2d569e260f96e8d966463dec1a50fa4f1b22aec69e3f91025060e"},
|
{file = "watchdog-6.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f10cb2d5902447c7d0da897e2c6768bca89174d0c6e1e30abec5421af97a5b0"},
|
||||||
{file = "watchdog-5.0.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:950f531ec6e03696a2414b6308f5c6ff9dab7821a768c9d5788b1314e9a46ca7"},
|
{file = "watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c"},
|
||||||
{file = "watchdog-5.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ae6deb336cba5d71476caa029ceb6e88047fc1dc74b62b7c4012639c0b563906"},
|
{file = "watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134"},
|
||||||
{file = "watchdog-5.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1021223c08ba8d2d38d71ec1704496471ffd7be42cfb26b87cd5059323a389a1"},
|
{file = "watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b"},
|
||||||
{file = "watchdog-5.0.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:752fb40efc7cc8d88ebc332b8f4bcbe2b5cc7e881bccfeb8e25054c00c994ee3"},
|
{file = "watchdog-6.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e6f0e77c9417e7cd62af82529b10563db3423625c5fce018430b249bf977f9e8"},
|
||||||
{file = "watchdog-5.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a2e8f3f955d68471fa37b0e3add18500790d129cc7efe89971b8a4cc6fdeb0b2"},
|
{file = "watchdog-6.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:90c8e78f3b94014f7aaae121e6b909674df5b46ec24d6bebc45c44c56729af2a"},
|
||||||
{file = "watchdog-5.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b8ca4d854adcf480bdfd80f46fdd6fb49f91dd020ae11c89b3a79e19454ec627"},
|
{file = "watchdog-6.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e7631a77ffb1f7d2eefa4445ebbee491c720a5661ddf6df3498ebecae5ed375c"},
|
||||||
{file = "watchdog-5.0.3-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:90a67d7857adb1d985aca232cc9905dd5bc4803ed85cfcdcfcf707e52049eda7"},
|
{file = "watchdog-6.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:c7ac31a19f4545dd92fc25d200694098f42c9a8e391bc00bdd362c5736dbf881"},
|
||||||
{file = "watchdog-5.0.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:720ef9d3a4f9ca575a780af283c8fd3a0674b307651c1976714745090da5a9e8"},
|
{file = "watchdog-6.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9513f27a1a582d9808cf21a07dae516f0fab1cf2d7683a742c498b93eedabb11"},
|
||||||
{file = "watchdog-5.0.3-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:223160bb359281bb8e31c8f1068bf71a6b16a8ad3d9524ca6f523ac666bb6a1e"},
|
{file = "watchdog-6.0.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7a0e56874cfbc4b9b05c60c8a1926fedf56324bb08cfbc188969777940aef3aa"},
|
||||||
{file = "watchdog-5.0.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:560135542c91eaa74247a2e8430cf83c4342b29e8ad4f520ae14f0c8a19cfb5b"},
|
{file = "watchdog-6.0.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:e6439e374fc012255b4ec786ae3c4bc838cd7309a540e5fe0952d03687d8804e"},
|
||||||
{file = "watchdog-5.0.3-py3-none-manylinux2014_aarch64.whl", hash = "sha256:dd021efa85970bd4824acacbb922066159d0f9e546389a4743d56919b6758b91"},
|
{file = "watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13"},
|
||||||
{file = "watchdog-5.0.3-py3-none-manylinux2014_armv7l.whl", hash = "sha256:78864cc8f23dbee55be34cc1494632a7ba30263951b5b2e8fc8286b95845f82c"},
|
{file = "watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379"},
|
||||||
{file = "watchdog-5.0.3-py3-none-manylinux2014_i686.whl", hash = "sha256:1e9679245e3ea6498494b3028b90c7b25dbb2abe65c7d07423ecfc2d6218ff7c"},
|
{file = "watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e"},
|
||||||
{file = "watchdog-5.0.3-py3-none-manylinux2014_ppc64.whl", hash = "sha256:9413384f26b5d050b6978e6fcd0c1e7f0539be7a4f1a885061473c5deaa57221"},
|
{file = "watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f"},
|
||||||
{file = "watchdog-5.0.3-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:294b7a598974b8e2c6123d19ef15de9abcd282b0fbbdbc4d23dfa812959a9e05"},
|
{file = "watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26"},
|
||||||
{file = "watchdog-5.0.3-py3-none-manylinux2014_s390x.whl", hash = "sha256:26dd201857d702bdf9d78c273cafcab5871dd29343748524695cecffa44a8d97"},
|
{file = "watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c"},
|
||||||
{file = "watchdog-5.0.3-py3-none-manylinux2014_x86_64.whl", hash = "sha256:0f9332243355643d567697c3e3fa07330a1d1abf981611654a1f2bf2175612b7"},
|
{file = "watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2"},
|
||||||
{file = "watchdog-5.0.3-py3-none-win32.whl", hash = "sha256:c66f80ee5b602a9c7ab66e3c9f36026590a0902db3aea414d59a2f55188c1f49"},
|
{file = "watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a"},
|
||||||
{file = "watchdog-5.0.3-py3-none-win_amd64.whl", hash = "sha256:f00b4cf737f568be9665563347a910f8bdc76f88c2970121c86243c8cfdf90e9"},
|
{file = "watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680"},
|
||||||
{file = "watchdog-5.0.3-py3-none-win_ia64.whl", hash = "sha256:49f4d36cb315c25ea0d946e018c01bb028048023b9e103d3d3943f58e109dd45"},
|
{file = "watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f"},
|
||||||
{file = "watchdog-5.0.3.tar.gz", hash = "sha256:108f42a7f0345042a854d4d0ad0834b741d421330d5f575b81cb27b883500176"},
|
{file = "watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
|
|||||||
@@ -148,6 +148,14 @@ class MinerConfig:
|
|||||||
**self.pools.as_bitaxe(user_suffix=user_suffix),
|
**self.pools.as_bitaxe(user_suffix=user_suffix),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def as_luxos(self, user_suffix: str = None) -> dict:
|
||||||
|
return {
|
||||||
|
**self.fan_mode.as_luxos(),
|
||||||
|
**self.temperature.as_luxos(),
|
||||||
|
**self.mining_mode.as_luxos(),
|
||||||
|
**self.pools.as_luxos(user_suffix=user_suffix),
|
||||||
|
}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_dict(cls, dict_conf: dict) -> "MinerConfig":
|
def from_dict(cls, dict_conf: dict) -> "MinerConfig":
|
||||||
"""Constructs a MinerConfig object from a dictionary."""
|
"""Constructs a MinerConfig object from a dictionary."""
|
||||||
@@ -250,3 +258,21 @@ 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),
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_luxos(
|
||||||
|
cls, rpc_tempctrl: dict, rpc_fans: dict, rpc_pools: dict, rpc_groups: dict
|
||||||
|
) -> "MinerConfig":
|
||||||
|
return cls(
|
||||||
|
temperature=TemperatureConfig.from_luxos(rpc_tempctrl=rpc_tempctrl),
|
||||||
|
fan_mode=FanModeConfig.from_luxos(
|
||||||
|
rpc_tempctrl=rpc_tempctrl, rpc_fans=rpc_fans
|
||||||
|
),
|
||||||
|
pools=PoolConfig.from_luxos(rpc_pools=rpc_pools, rpc_groups=rpc_groups),
|
||||||
|
)
|
||||||
|
|||||||
@@ -63,6 +63,9 @@ class MinerConfigOption(Enum):
|
|||||||
def as_bitaxe(self) -> dict:
|
def as_bitaxe(self) -> dict:
|
||||||
return self.value.as_bitaxe()
|
return self.value.as_bitaxe()
|
||||||
|
|
||||||
|
def as_luxos(self) -> dict:
|
||||||
|
return self.value.as_luxos()
|
||||||
|
|
||||||
def __call__(self, *args, **kwargs):
|
def __call__(self, *args, **kwargs):
|
||||||
return self.value(*args, **kwargs)
|
return self.value(*args, **kwargs)
|
||||||
|
|
||||||
@@ -125,6 +128,9 @@ class MinerConfigValue:
|
|||||||
def as_bitaxe(self) -> dict:
|
def as_bitaxe(self) -> dict:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
def as_luxos(self) -> dict:
|
||||||
|
return {}
|
||||||
|
|
||||||
def __getitem__(self, item):
|
def __getitem__(self, item):
|
||||||
try:
|
try:
|
||||||
return getattr(self, item)
|
return getattr(self, item)
|
||||||
|
|||||||
@@ -83,6 +83,9 @@ class FanModeNormal(MinerConfigValue):
|
|||||||
def as_bitaxe(self) -> dict:
|
def as_bitaxe(self) -> dict:
|
||||||
return {"autoFanspeed": 1}
|
return {"autoFanspeed": 1}
|
||||||
|
|
||||||
|
def as_luxos(self) -> dict:
|
||||||
|
return {"fanset": {"speed": -1, "min_fans": self.minimum_fans}}
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class FanModeManual(MinerConfigValue):
|
class FanModeManual(MinerConfigValue):
|
||||||
@@ -144,6 +147,9 @@ class FanModeManual(MinerConfigValue):
|
|||||||
def as_bitaxe(self) -> dict:
|
def as_bitaxe(self) -> dict:
|
||||||
return {"autoFanspeed": 0, "fanspeed": self.speed}
|
return {"autoFanspeed": 0, "fanspeed": self.speed}
|
||||||
|
|
||||||
|
def as_luxos(self) -> dict:
|
||||||
|
return {"fanset": {"speed": self.speed, "min_fans": self.minimum_fans}}
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class FanModeImmersion(MinerConfigValue):
|
class FanModeImmersion(MinerConfigValue):
|
||||||
@@ -167,6 +173,9 @@ class FanModeImmersion(MinerConfigValue):
|
|||||||
def as_mara(self) -> dict:
|
def as_mara(self) -> dict:
|
||||||
return {"general-config": {"environment-profile": "OilImmersionCooling"}}
|
return {"general-config": {"environment-profile": "OilImmersionCooling"}}
|
||||||
|
|
||||||
|
def as_luxos(self) -> dict:
|
||||||
|
return {"fanset": {"speed": 0, "min_fans": 0}}
|
||||||
|
|
||||||
|
|
||||||
class FanModeConfig(MinerConfigOption):
|
class FanModeConfig(MinerConfigOption):
|
||||||
normal = FanModeNormal
|
normal = FanModeNormal
|
||||||
@@ -304,3 +313,23 @@ class FanModeConfig(MinerConfigOption):
|
|||||||
return cls.normal()
|
return cls.normal()
|
||||||
else:
|
else:
|
||||||
return cls.manual(speed=web_system_info["fanspeed"])
|
return cls.manual(speed=web_system_info["fanspeed"])
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_luxos(cls, rpc_fans: dict, rpc_tempctrl: dict):
|
||||||
|
try:
|
||||||
|
mode = rpc_tempctrl["TEMPCTRL"][0]["Mode"]
|
||||||
|
if mode == "Manual":
|
||||||
|
speed = rpc_fans["FANS"][0]["Speed"]
|
||||||
|
min_fans = rpc_fans["FANCTRL"][0]["MinFans"]
|
||||||
|
if min_fans == 0 and speed == 0:
|
||||||
|
return cls.immersion()
|
||||||
|
return cls.manual(
|
||||||
|
speed=speed,
|
||||||
|
minimum_fans=min_fans,
|
||||||
|
)
|
||||||
|
return cls.normal(
|
||||||
|
minimum_fans=rpc_fans["FANCTRL"][0]["MinFans"],
|
||||||
|
)
|
||||||
|
except LookupError:
|
||||||
|
pass
|
||||||
|
return cls.default()
|
||||||
|
|||||||
@@ -70,6 +70,9 @@ class MiningModeNormal(MinerConfigValue):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def as_luxos(self) -> dict:
|
||||||
|
return {"autotunerset": {"enabled": False}}
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class MiningModeSleep(MinerConfigValue):
|
class MiningModeSleep(MinerConfigValue):
|
||||||
@@ -240,6 +243,9 @@ class MiningModePowerTune(MinerConfigValue):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def as_luxos(self) -> dict:
|
||||||
|
return {"autotunerset": {"enabled": True}}
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class MiningModeHashrateTune(MinerConfigValue):
|
class MiningModeHashrateTune(MinerConfigValue):
|
||||||
@@ -333,6 +339,9 @@ class MiningModeHashrateTune(MinerConfigValue):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def as_luxos(self) -> dict:
|
||||||
|
return {"autotunerset": {"enabled": True}}
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class ManualBoardSettings(MinerConfigValue):
|
class ManualBoardSettings(MinerConfigValue):
|
||||||
|
|||||||
@@ -222,6 +222,18 @@ class Pool(MinerConfigValue):
|
|||||||
password=web_system_info.get("stratumPassword", ""),
|
password=web_system_info.get("stratumPassword", ""),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_luxos(cls, rpc_pools: dict) -> "Pool":
|
||||||
|
return cls.from_api(rpc_pools)
|
||||||
|
|
||||||
|
@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 +414,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):
|
||||||
@@ -506,6 +527,9 @@ class PoolConfig(MinerConfigValue):
|
|||||||
def as_bitaxe(self, user_suffix: str = None) -> dict:
|
def as_bitaxe(self, user_suffix: str = None) -> dict:
|
||||||
return self.groups[0].as_bitaxe(user_suffix=user_suffix)
|
return self.groups[0].as_bitaxe(user_suffix=user_suffix)
|
||||||
|
|
||||||
|
def as_luxos(self, user_suffix: str = None) -> dict:
|
||||||
|
return {}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_api(cls, api_pools: dict) -> "PoolConfig":
|
def from_api(cls, api_pools: dict) -> "PoolConfig":
|
||||||
try:
|
try:
|
||||||
@@ -568,3 +592,24 @@ 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)])
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_luxos(cls, rpc_groups: dict, rpc_pools: dict) -> "PoolConfig":
|
||||||
|
return cls(
|
||||||
|
groups=[
|
||||||
|
PoolGroup(
|
||||||
|
pools=[
|
||||||
|
Pool.from_luxos(pool)
|
||||||
|
for pool in rpc_pools["POOLS"]
|
||||||
|
if pool["GROUP"] == group["GROUP"]
|
||||||
|
],
|
||||||
|
name=group["Name"],
|
||||||
|
quota=group["Quota"],
|
||||||
|
)
|
||||||
|
for group in rpc_groups["GROUPS"]
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|||||||
@@ -54,6 +54,9 @@ class TemperatureConfig(MinerConfigValue):
|
|||||||
temps_config["temps"]["shutdown"] = self.hot
|
temps_config["temps"]["shutdown"] = self.hot
|
||||||
return temps_config
|
return temps_config
|
||||||
|
|
||||||
|
def as_luxos(self) -> dict:
|
||||||
|
return {"tempctrlset": [self.target or "", self.hot or "", self.danger or ""]}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_dict(cls, dict_conf: dict | None) -> "TemperatureConfig":
|
def from_dict(cls, dict_conf: dict | None) -> "TemperatureConfig":
|
||||||
return cls(
|
return cls(
|
||||||
@@ -130,3 +133,16 @@ class TemperatureConfig(MinerConfigValue):
|
|||||||
|
|
||||||
return cls(**conf)
|
return cls(**conf)
|
||||||
return cls.default()
|
return cls.default()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_luxos(cls, rpc_tempctrl: dict) -> "TemperatureConfig":
|
||||||
|
try:
|
||||||
|
tempctrl_config = rpc_tempctrl["TEMPCTRL"][0]
|
||||||
|
return cls(
|
||||||
|
target=tempctrl_config.get("Target"),
|
||||||
|
hot=tempctrl_config.get("Hot"),
|
||||||
|
danger=tempctrl_config.get("Dangerous"),
|
||||||
|
)
|
||||||
|
except LookupError:
|
||||||
|
pass
|
||||||
|
return cls.default()
|
||||||
|
|||||||
@@ -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, Scheme
|
||||||
|
|
||||||
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
|
||||||
@@ -154,7 +154,11 @@ class MinerData:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def dict_factory(x):
|
def dict_factory(x):
|
||||||
return {k: v for (k, v) in x if not k.startswith("_")}
|
return {
|
||||||
|
k: v.value if isinstance(v, Scheme) else v
|
||||||
|
for (k, v) in x
|
||||||
|
if not k.startswith("_")
|
||||||
|
}
|
||||||
|
|
||||||
def __post_init__(self):
|
def __post_init__(self):
|
||||||
self._datetime = datetime.now(timezone.utc).astimezone()
|
self._datetime = datetime.now(timezone.utc).astimezone()
|
||||||
|
|||||||
@@ -89,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
|
||||||
|
|||||||
@@ -10,12 +10,15 @@ class AntminerModels(str, Enum):
|
|||||||
DR5 = "DR5"
|
DR5 = "DR5"
|
||||||
KS5 = "KS5"
|
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"
|
||||||
|
D9 = "D9"
|
||||||
Z15 = "Z15"
|
Z15 = "Z15"
|
||||||
|
Z15Pro = "Z15 Pro"
|
||||||
S17 = "S17"
|
S17 = "S17"
|
||||||
S17Plus = "S17+"
|
S17Plus = "S17+"
|
||||||
S17Pro = "S17 Pro"
|
S17Pro = "S17 Pro"
|
||||||
@@ -223,6 +226,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"
|
||||||
@@ -296,6 +300,7 @@ class AvalonminerModels(str, Enum):
|
|||||||
class InnosiliconModels(str, Enum):
|
class InnosiliconModels(str, Enum):
|
||||||
T3HPlus = "T3H+"
|
T3HPlus = "T3H+"
|
||||||
A10X = "A10X"
|
A10X = "A10X"
|
||||||
|
A11 = "A11"
|
||||||
A11MX = "A11MX"
|
A11MX = "A11MX"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
@@ -351,6 +356,9 @@ class IceRiverModels(str, Enum):
|
|||||||
KS3 = "KS3"
|
KS3 = "KS3"
|
||||||
KS3L = "KS3L"
|
KS3L = "KS3L"
|
||||||
KS3M = "KS3M"
|
KS3M = "KS3M"
|
||||||
|
KS5 = "KS5"
|
||||||
|
KS5L = "KS5L"
|
||||||
|
KS5M = "KS5M"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.value
|
return self.value
|
||||||
|
|||||||
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
|
||||||
|
|||||||
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
|
||||||
|
|||||||
22
pyasic/miners/antminer/bmminer/X9/D9.py
Normal file
22
pyasic/miners/antminer/bmminer/X9/D9.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 D9
|
||||||
|
|
||||||
|
|
||||||
|
class BMMinerD9(AntminerModern, D9):
|
||||||
|
pass
|
||||||
@@ -14,6 +14,7 @@
|
|||||||
# limitations under the License. -
|
# limitations under the License. -
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
from .D9 import BMMinerD9
|
||||||
from .E9 import BMMinerE9Pro
|
from .E9 import BMMinerE9Pro
|
||||||
from .S9 import BMMinerS9, BMMinerS9i, BMMinerS9j
|
from .S9 import BMMinerS9, BMMinerS9i, BMMinerS9j
|
||||||
from .T9 import BMMinerT9
|
from .T9 import BMMinerT9
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ from .X3 import *
|
|||||||
from .X5 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 *
|
||||||
|
|||||||
@@ -15,7 +15,4 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from .S21 import ePICS21, ePICS21Pro
|
from .S21 import ePICS21, ePICS21Pro
|
||||||
|
from .T21 import ePICT21
|
||||||
from .T21 import (
|
|
||||||
ePICT21,
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -597,49 +597,44 @@ 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:
|
for board_num in range(1, 16, 5):
|
||||||
for board_num in range(1, 16, 5):
|
for _b_num in range(5):
|
||||||
for _b_num in range(5):
|
b = boards[1].get(f"chain_acn{board_num + _b_num}")
|
||||||
b = boards[1].get(f"chain_acn{board_num + _b_num}")
|
|
||||||
|
|
||||||
if b and not b == 0 and board_offset == -1:
|
if b and not b == 0 and board_offset == -1:
|
||||||
board_offset = board_num
|
board_offset = board_num
|
||||||
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(
|
||||||
):
|
slot=i - board_offset, expected_chips=self.expected_chips
|
||||||
hashboard = HashBoard(
|
)
|
||||||
slot=i - board_offset, expected_chips=self.expected_chips
|
|
||||||
)
|
|
||||||
|
|
||||||
chip_temp = boards[1].get(f"temp{i}")
|
chip_temp = boards[1].get(f"temp{i}")
|
||||||
if chip_temp:
|
if chip_temp:
|
||||||
hashboard.chip_temp = round(chip_temp)
|
hashboard.chip_temp = round(chip_temp)
|
||||||
|
|
||||||
temp = boards[1].get(f"temp2_{i}")
|
temp = boards[1].get(f"temp2_{i}")
|
||||||
if temp:
|
if temp:
|
||||||
hashboard.temp = round(temp)
|
hashboard.temp = round(temp)
|
||||||
|
|
||||||
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}")
|
||||||
if chips:
|
if chips:
|
||||||
hashboard.chips = chips
|
hashboard.chips = chips
|
||||||
hashboard.missing = False
|
hashboard.missing = False
|
||||||
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,7 +193,14 @@ 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:
|
async def upgrade_firmware(
|
||||||
|
self,
|
||||||
|
*,
|
||||||
|
url: str = None,
|
||||||
|
version: str = "latest",
|
||||||
|
keep_settings: bool = False,
|
||||||
|
**kwargs,
|
||||||
|
) -> bool:
|
||||||
"""
|
"""
|
||||||
Upgrade the firmware of the Auradine device.
|
Upgrade the firmware of the Auradine device.
|
||||||
|
|
||||||
@@ -209,7 +216,9 @@ class Auradine(StockFirmware):
|
|||||||
logging.info("Starting firmware upgrade process.")
|
logging.info("Starting firmware upgrade process.")
|
||||||
|
|
||||||
if not url and not version:
|
if not url and not version:
|
||||||
raise ValueError("Either URL or version must be provided for firmware upgrade.")
|
raise ValueError(
|
||||||
|
"Either URL or version must be provided for firmware upgrade."
|
||||||
|
)
|
||||||
|
|
||||||
if url:
|
if url:
|
||||||
result = await self.web.firmware_upgrade(url=url)
|
result = await self.web.firmware_upgrade(url=url)
|
||||||
@@ -220,11 +229,15 @@ class Auradine(StockFirmware):
|
|||||||
logging.info("Firmware upgrade process completed successfully.")
|
logging.info("Firmware upgrade process completed successfully.")
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
logging.error(f"Firmware upgrade failed: {result.get('error', 'Unknown error')}")
|
logging.error(
|
||||||
|
f"Firmware upgrade failed: {result.get('error', 'Unknown error')}"
|
||||||
|
)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error(f"An error occurred during the firmware upgrade process: {str(e)}")
|
logging.error(
|
||||||
|
f"An error occurred during the firmware upgrade process: {str(e)}"
|
||||||
|
)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
##################################################
|
##################################################
|
||||||
|
|||||||
@@ -18,11 +18,11 @@ 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
|
||||||
from pyasic.rpc.bfgminer import BFGMinerRPCAPI
|
from pyasic.rpc.bfgminer import BFGMinerRPCAPI
|
||||||
from pyasic.data.pools import PoolMetrics, PoolUrl
|
|
||||||
|
|
||||||
BFGMINER_DATA_LOC = DataLocations(
|
BFGMINER_DATA_LOC = DataLocations(
|
||||||
**{
|
**{
|
||||||
@@ -263,4 +263,4 @@ class BFGMiner(StockFirmware):
|
|||||||
expected_rate, HashUnit.SHA256.from_str(rate_unit)
|
expected_rate, HashUnit.SHA256.from_str(rate_unit)
|
||||||
).into(self.algo.unit.default)
|
).into(self.algo.unit.default)
|
||||||
except LookupError:
|
except LookupError:
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -23,11 +23,11 @@ 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
|
||||||
from pyasic.rpc.btminer import BTMinerRPCAPI
|
from pyasic.rpc.btminer import BTMinerRPCAPI
|
||||||
from pyasic.data.pools import PoolMetrics, PoolUrl
|
|
||||||
|
|
||||||
BTMINER_DATA_LOC = DataLocations(
|
BTMINER_DATA_LOC = DataLocations(
|
||||||
**{
|
**{
|
||||||
@@ -113,7 +113,7 @@ BTMINER_DATA_LOC = DataLocations(
|
|||||||
str(DataOptions.POOLS): DataFunction(
|
str(DataOptions.POOLS): DataFunction(
|
||||||
"_get_pools",
|
"_get_pools",
|
||||||
[RPCAPICommand("rpc_pools", "pools")],
|
[RPCAPICommand("rpc_pools", "pools")],
|
||||||
)
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -14,15 +14,15 @@
|
|||||||
# limitations under the License. -
|
# limitations under the License. -
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from typing import Optional, List
|
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
|
||||||
from pyasic.rpc.cgminer import CGMinerRPCAPI
|
from pyasic.rpc.cgminer import CGMinerRPCAPI
|
||||||
from pyasic.data.pools import PoolMetrics, PoolUrl
|
|
||||||
|
|
||||||
CGMINER_DATA_LOC = DataLocations(
|
CGMINER_DATA_LOC = DataLocations(
|
||||||
**{
|
**{
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|
||||||
@@ -466,4 +467,4 @@ class ePIC(ePICFirmware):
|
|||||||
Returns:
|
Returns:
|
||||||
bool: Whether the firmware update succeeded.
|
bool: Whether the firmware update succeeded.
|
||||||
"""
|
"""
|
||||||
return await self.web.system_update(file=file, keep_settings=keep_settings)
|
return await self.web.system_update(file=file, keep_settings=keep_settings)
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
|
|
||||||
|
from pyasic 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.device import MinerAlgo
|
from pyasic.device import MinerAlgo
|
||||||
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
|
||||||
@@ -41,6 +43,10 @@ ICERIVER_DATA_LOC = DataLocations(
|
|||||||
"_get_uptime",
|
"_get_uptime",
|
||||||
[WebAPICommand("web_userpanel", "userpanel")],
|
[WebAPICommand("web_userpanel", "userpanel")],
|
||||||
),
|
),
|
||||||
|
str(DataOptions.POOLS): DataFunction(
|
||||||
|
"_get_pools",
|
||||||
|
[WebAPICommand("web_userpanel", "userpanel")],
|
||||||
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -67,6 +73,11 @@ class IceRiver(StockFirmware):
|
|||||||
return False
|
return False
|
||||||
return True
|
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]:
|
async def _get_fans(self, web_userpanel: dict = None) -> List[Fan]:
|
||||||
if web_userpanel is None:
|
if web_userpanel is None:
|
||||||
try:
|
try:
|
||||||
@@ -76,7 +87,7 @@ class IceRiver(StockFirmware):
|
|||||||
|
|
||||||
if web_userpanel is not None:
|
if web_userpanel is not None:
|
||||||
try:
|
try:
|
||||||
return [Fan(spd) for spd in web_userpanel["fans"]]
|
return [Fan(spd) for spd in web_userpanel["userpanel"]["data"]["fans"]]
|
||||||
except (LookupError, ValueError, TypeError):
|
except (LookupError, ValueError, TypeError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -89,7 +100,9 @@ class IceRiver(StockFirmware):
|
|||||||
|
|
||||||
if web_userpanel is not None:
|
if web_userpanel is not None:
|
||||||
try:
|
try:
|
||||||
return web_userpanel["mac"].upper().replace("-", ":")
|
return (
|
||||||
|
web_userpanel["userpanel"]["data"]["mac"].upper().replace("-", ":")
|
||||||
|
)
|
||||||
except (LookupError, ValueError, TypeError):
|
except (LookupError, ValueError, TypeError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -102,7 +115,7 @@ class IceRiver(StockFirmware):
|
|||||||
|
|
||||||
if web_userpanel is not None:
|
if web_userpanel is not None:
|
||||||
try:
|
try:
|
||||||
return web_userpanel["host"]
|
return web_userpanel["userpanel"]["data"]["host"]
|
||||||
except (LookupError, ValueError, TypeError):
|
except (LookupError, ValueError, TypeError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -115,9 +128,13 @@ class IceRiver(StockFirmware):
|
|||||||
|
|
||||||
if web_userpanel is not None:
|
if web_userpanel is not None:
|
||||||
try:
|
try:
|
||||||
base_unit = web_userpanel["unit"]
|
base_unit = web_userpanel["userpanel"]["data"]["unit"]
|
||||||
return AlgoHashRate.SHA256(
|
return AlgoHashRate.SHA256(
|
||||||
float(web_userpanel["rtpow"].replace(base_unit, "")),
|
float(
|
||||||
|
web_userpanel["userpanel"]["data"]["rtpow"].replace(
|
||||||
|
base_unit, ""
|
||||||
|
)
|
||||||
|
),
|
||||||
unit=MinerAlgo.SHA256.unit.from_str(base_unit + "H"),
|
unit=MinerAlgo.SHA256.unit.from_str(base_unit + "H"),
|
||||||
).into(MinerAlgo.SHA256.unit.default)
|
).into(MinerAlgo.SHA256.unit.default)
|
||||||
except (LookupError, ValueError, TypeError):
|
except (LookupError, ValueError, TypeError):
|
||||||
@@ -132,7 +149,7 @@ class IceRiver(StockFirmware):
|
|||||||
|
|
||||||
if web_userpanel is not None:
|
if web_userpanel is not None:
|
||||||
try:
|
try:
|
||||||
return web_userpanel["locate"]
|
return web_userpanel["userpanel"]["data"]["locate"]
|
||||||
except (LookupError, ValueError, TypeError):
|
except (LookupError, ValueError, TypeError):
|
||||||
pass
|
pass
|
||||||
return False
|
return False
|
||||||
@@ -146,7 +163,7 @@ class IceRiver(StockFirmware):
|
|||||||
|
|
||||||
if web_userpanel is not None:
|
if web_userpanel is not None:
|
||||||
try:
|
try:
|
||||||
return web_userpanel["powstate"]
|
return web_userpanel["userpanel"]["data"]["powstate"]
|
||||||
except (LookupError, ValueError, TypeError):
|
except (LookupError, ValueError, TypeError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -164,7 +181,7 @@ class IceRiver(StockFirmware):
|
|||||||
|
|
||||||
if web_userpanel is not None:
|
if web_userpanel is not None:
|
||||||
try:
|
try:
|
||||||
for board in web_userpanel["boards"]:
|
for board in web_userpanel["userpanel"]["data"]["boards"]:
|
||||||
idx = int(board["no"] - 1)
|
idx = int(board["no"] - 1)
|
||||||
hb_list[idx].chip_temp = round(board["outtmp"])
|
hb_list[idx].chip_temp = round(board["outtmp"])
|
||||||
hb_list[idx].temp = round(board["intmp"])
|
hb_list[idx].temp = round(board["intmp"])
|
||||||
@@ -186,7 +203,7 @@ class IceRiver(StockFirmware):
|
|||||||
|
|
||||||
if web_userpanel is not None:
|
if web_userpanel is not None:
|
||||||
try:
|
try:
|
||||||
runtime = web_userpanel["runtime"]
|
runtime = web_userpanel["userpanel"]["data"]["runtime"]
|
||||||
days, hours, minutes, seconds = runtime.split(":")
|
days, hours, minutes, seconds = runtime.split(":")
|
||||||
return (
|
return (
|
||||||
(int(days) * 24 * 60 * 60)
|
(int(days) * 24 * 60 * 60)
|
||||||
@@ -196,3 +213,36 @@ class IceRiver(StockFirmware):
|
|||||||
)
|
)
|
||||||
except (LookupError, ValueError, TypeError):
|
except (LookupError, ValueError, TypeError):
|
||||||
pass
|
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
|
||||||
|
|||||||
@@ -13,8 +13,8 @@
|
|||||||
# 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 typing import List, Optional
|
|
||||||
import logging
|
import logging
|
||||||
|
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
|
||||||
@@ -56,6 +56,15 @@ LUXMINER_DATA_LOC = DataLocations(
|
|||||||
str(DataOptions.POOLS): DataFunction(
|
str(DataOptions.POOLS): DataFunction(
|
||||||
"_get_pools", [RPCAPICommand("rpc_pools", "pools")]
|
"_get_pools", [RPCAPICommand("rpc_pools", "pools")]
|
||||||
),
|
),
|
||||||
|
str(DataOptions.FW_VERSION): DataFunction(
|
||||||
|
"_get_fw_ver", [RPCAPICommand("rpc_version", "version")]
|
||||||
|
),
|
||||||
|
str(DataOptions.API_VERSION): DataFunction(
|
||||||
|
"_get_api_ver", [RPCAPICommand("rpc_version", "version")]
|
||||||
|
),
|
||||||
|
str(DataOptions.FAULT_LIGHT): DataFunction(
|
||||||
|
"_get_fault_light", [RPCAPICommand("rpc_config", "config")]
|
||||||
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -68,25 +77,9 @@ class LUXMiner(LuxOSFirmware):
|
|||||||
|
|
||||||
data_locations = LUXMINER_DATA_LOC
|
data_locations = LUXMINER_DATA_LOC
|
||||||
|
|
||||||
async def _get_session(self) -> Optional[str]:
|
|
||||||
try:
|
|
||||||
data = await self.rpc.session()
|
|
||||||
if not data["SESSION"][0]["SessionID"] == "":
|
|
||||||
return data["SESSION"][0]["SessionID"]
|
|
||||||
except APIError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
try:
|
|
||||||
data = await self.rpc.logon()
|
|
||||||
return data["SESSION"][0]["SessionID"]
|
|
||||||
except (LookupError, APIError):
|
|
||||||
return
|
|
||||||
|
|
||||||
async def fault_light_on(self) -> bool:
|
async def fault_light_on(self) -> bool:
|
||||||
try:
|
try:
|
||||||
session_id = await self._get_session()
|
await self.rpc.ledset("red", "blink")
|
||||||
if session_id:
|
|
||||||
await self.rpc.ledset(session_id, "red", "blink")
|
|
||||||
return True
|
return True
|
||||||
except (APIError, LookupError):
|
except (APIError, LookupError):
|
||||||
pass
|
pass
|
||||||
@@ -94,9 +87,7 @@ class LUXMiner(LuxOSFirmware):
|
|||||||
|
|
||||||
async def fault_light_off(self) -> bool:
|
async def fault_light_off(self) -> bool:
|
||||||
try:
|
try:
|
||||||
session_id = await self._get_session()
|
await self.rpc.ledset("red", "off")
|
||||||
if session_id:
|
|
||||||
await self.rpc.ledset(session_id, "red", "off")
|
|
||||||
return True
|
return True
|
||||||
except (APIError, LookupError):
|
except (APIError, LookupError):
|
||||||
pass
|
pass
|
||||||
@@ -107,9 +98,7 @@ class LUXMiner(LuxOSFirmware):
|
|||||||
|
|
||||||
async def restart_luxminer(self) -> bool:
|
async def restart_luxminer(self) -> bool:
|
||||||
try:
|
try:
|
||||||
session_id = await self._get_session()
|
await self.rpc.resetminer()
|
||||||
if session_id:
|
|
||||||
await self.rpc.resetminer(session_id)
|
|
||||||
return True
|
return True
|
||||||
except (APIError, LookupError):
|
except (APIError, LookupError):
|
||||||
pass
|
pass
|
||||||
@@ -117,9 +106,7 @@ class LUXMiner(LuxOSFirmware):
|
|||||||
|
|
||||||
async def stop_mining(self) -> bool:
|
async def stop_mining(self) -> bool:
|
||||||
try:
|
try:
|
||||||
session_id = await self._get_session()
|
await self.rpc.sleep()
|
||||||
if session_id:
|
|
||||||
await self.rpc.curtail(session_id)
|
|
||||||
return True
|
return True
|
||||||
except (APIError, LookupError):
|
except (APIError, LookupError):
|
||||||
pass
|
pass
|
||||||
@@ -127,25 +114,27 @@ class LUXMiner(LuxOSFirmware):
|
|||||||
|
|
||||||
async def resume_mining(self) -> bool:
|
async def resume_mining(self) -> bool:
|
||||||
try:
|
try:
|
||||||
session_id = await self._get_session()
|
await self.rpc.wakeup()
|
||||||
if session_id:
|
|
||||||
await self.rpc.wakeup(session_id)
|
|
||||||
return True
|
return True
|
||||||
except (APIError, LookupError):
|
except (APIError, LookupError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
async def reboot(self) -> bool:
|
async def reboot(self) -> bool:
|
||||||
try:
|
try:
|
||||||
session_id = await self._get_session()
|
await self.rpc.rebootdevice()
|
||||||
if session_id:
|
|
||||||
await self.rpc.rebootdevice(session_id)
|
|
||||||
return True
|
return True
|
||||||
except (APIError, LookupError):
|
except (APIError, LookupError):
|
||||||
pass
|
pass
|
||||||
return False
|
return False
|
||||||
|
|
||||||
async def get_config(self) -> MinerConfig:
|
async def get_config(self) -> MinerConfig:
|
||||||
return self.config
|
data = await self.rpc.multicommand("tempctrl", "fans", "pools", "groups")
|
||||||
|
return MinerConfig.from_luxos(
|
||||||
|
rpc_tempctrl=data.get("tempctrl", [{}])[0],
|
||||||
|
rpc_fans=data.get("fans", [{}])[0],
|
||||||
|
rpc_pools=data.get("pools", [{}])[0],
|
||||||
|
rpc_groups=data.get("groups", [{}])[0],
|
||||||
|
)
|
||||||
|
|
||||||
async def upgrade_firmware(self) -> bool:
|
async def upgrade_firmware(self) -> bool:
|
||||||
"""
|
"""
|
||||||
@@ -168,20 +157,17 @@ class LUXMiner(LuxOSFirmware):
|
|||||||
##################################################
|
##################################################
|
||||||
|
|
||||||
async def _get_mac(self, rpc_config: dict = None) -> Optional[str]:
|
async def _get_mac(self, rpc_config: dict = None) -> Optional[str]:
|
||||||
mac = None
|
|
||||||
if rpc_config is None:
|
if rpc_config is None:
|
||||||
try:
|
try:
|
||||||
rpc_config = await self.rpc.config()
|
rpc_config = await self.rpc.config()
|
||||||
except APIError:
|
except APIError:
|
||||||
return None
|
pass
|
||||||
|
|
||||||
if rpc_config is not None:
|
if rpc_config is not None:
|
||||||
try:
|
try:
|
||||||
mac = rpc_config["CONFIG"][0]["MACAddr"]
|
return rpc_config["CONFIG"][0]["MACAddr"].upper()
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return None
|
pass
|
||||||
|
|
||||||
return mac
|
|
||||||
|
|
||||||
async def _get_hashrate(self, rpc_summary: dict = None) -> Optional[AlgoHashRate]:
|
async def _get_hashrate(self, rpc_summary: dict = None) -> Optional[AlgoHashRate]:
|
||||||
if rpc_summary is None:
|
if rpc_summary is None:
|
||||||
@@ -199,59 +185,47 @@ class LUXMiner(LuxOSFirmware):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
async def _get_hashboards(self, rpc_stats: dict = None) -> List[HashBoard]:
|
async def _get_hashboards(self, rpc_stats: dict = None) -> List[HashBoard]:
|
||||||
hashboards = []
|
hashboards = [
|
||||||
|
HashBoard(idx, expected_chips=self.expected_chips)
|
||||||
|
for idx in range(self.expected_hashboards)
|
||||||
|
]
|
||||||
|
|
||||||
if rpc_stats is None:
|
if rpc_stats is None:
|
||||||
try:
|
try:
|
||||||
rpc_stats = await self.rpc.stats()
|
rpc_stats = await self.rpc.stats()
|
||||||
except APIError:
|
except APIError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if rpc_stats is not None:
|
if rpc_stats is not None:
|
||||||
try:
|
try:
|
||||||
board_offset = -1
|
# TODO: bugged on S9 because of index issues, fix later.
|
||||||
boards = rpc_stats["STATS"]
|
board_stats = rpc_stats["STATS"][1]
|
||||||
if len(boards) > 1:
|
for idx in range(3):
|
||||||
for board_num in range(1, 16, 5):
|
board_n = idx + 1
|
||||||
for _b_num in range(5):
|
hashboards[idx].hashrate = AlgoHashRate.SHA256(
|
||||||
b = boards[1].get(f"chain_acn{board_num + _b_num}")
|
float(board_stats[f"chain_rate{board_n}"]), HashUnit.SHA256.GH
|
||||||
|
).into(self.algo.unit.default)
|
||||||
if b and not b == 0 and board_offset == -1:
|
hashboards[idx].chips = int(board_stats[f"chain_acn{board_n}"])
|
||||||
board_offset = board_num
|
chip_temp_data = list(
|
||||||
if board_offset == -1:
|
filter(
|
||||||
board_offset = 1
|
lambda x: not x == 0,
|
||||||
|
map(int, board_stats[f"temp_chip{board_n}"].split("-")),
|
||||||
for i in range(
|
|
||||||
board_offset, board_offset + self.expected_hashboards
|
|
||||||
):
|
|
||||||
hashboard = HashBoard(
|
|
||||||
slot=i - board_offset, expected_chips=self.expected_chips
|
|
||||||
)
|
)
|
||||||
|
)
|
||||||
chip_temp = boards[1].get(f"temp{i}")
|
hashboards[idx].chip_temp = (
|
||||||
if chip_temp:
|
sum([chip_temp_data[0], chip_temp_data[3]]) / 2
|
||||||
hashboard.chip_temp = round(chip_temp)
|
)
|
||||||
|
board_temp_data = list(
|
||||||
temp = boards[1].get(f"temp2_{i}")
|
filter(
|
||||||
if temp:
|
lambda x: not x == 0,
|
||||||
hashboard.temp = round(temp)
|
map(int, board_stats[f"temp_pcb{board_n}"].split("-")),
|
||||||
|
)
|
||||||
hashrate = boards[1].get(f"chain_rate{i}")
|
)
|
||||||
if hashrate:
|
hashboards[idx].temp = (
|
||||||
hashboard.hashrate = AlgoHashRate.SHA256(
|
sum([board_temp_data[1], board_temp_data[2]]) / 2
|
||||||
hashrate, HashUnit.SHA256.GH
|
)
|
||||||
).into(self.algo.unit.default)
|
hashboards[idx].missing = False
|
||||||
|
except LookupError:
|
||||||
chips = boards[1].get(f"chain_acn{i}")
|
|
||||||
if chips:
|
|
||||||
hashboard.chips = chips
|
|
||||||
hashboard.missing = False
|
|
||||||
if (not chips) or (not chips > 0):
|
|
||||||
hashboard.missing = True
|
|
||||||
hashboards.append(hashboard)
|
|
||||||
except (LookupError, ValueError, TypeError):
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return hashboards
|
return hashboards
|
||||||
|
|
||||||
async def _get_wattage(self, rpc_power: dict = None) -> Optional[int]:
|
async def _get_wattage(self, rpc_power: dict = None) -> Optional[int]:
|
||||||
@@ -319,6 +293,45 @@ class LUXMiner(LuxOSFirmware):
|
|||||||
except LookupError:
|
except LookupError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
async def _get_fw_ver(self, rpc_version: dict = None) -> Optional[str]:
|
||||||
|
if rpc_version is None:
|
||||||
|
try:
|
||||||
|
rpc_version = await self.rpc.version()
|
||||||
|
except APIError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if rpc_version is not None:
|
||||||
|
try:
|
||||||
|
return rpc_version["VERSION"][0]["Miner"]
|
||||||
|
except LookupError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def _get_api_ver(self, rpc_version: dict = None) -> Optional[str]:
|
||||||
|
if rpc_version is None:
|
||||||
|
try:
|
||||||
|
rpc_version = await self.rpc.version()
|
||||||
|
except APIError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if rpc_version is not None:
|
||||||
|
try:
|
||||||
|
return rpc_version["VERSION"][0]["API"]
|
||||||
|
except LookupError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def _get_fault_light(self, rpc_config: dict = None) -> Optional[bool]:
|
||||||
|
if rpc_config is None:
|
||||||
|
try:
|
||||||
|
rpc_config = await self.rpc.config()
|
||||||
|
except APIError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if rpc_config is not None:
|
||||||
|
try:
|
||||||
|
return not rpc_config["CONFIG"][0]["RedLed"] == "off"
|
||||||
|
except LookupError:
|
||||||
|
pass
|
||||||
|
|
||||||
async def _get_pools(self, rpc_pools: dict = None) -> List[PoolMetrics]:
|
async def _get_pools(self, rpc_pools: dict = None) -> List[PoolMetrics]:
|
||||||
if rpc_pools is None:
|
if rpc_pools is None:
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -3,13 +3,13 @@ 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.rpc.marathon import MaraRPCAPI
|
||||||
from pyasic.web.marathon import MaraWebAPI
|
from pyasic.web.marathon import MaraWebAPI
|
||||||
from pyasic.data.pools import PoolMetrics, PoolUrl
|
|
||||||
|
|
||||||
MARA_DATA_LOC = DataLocations(
|
MARA_DATA_LOC = DataLocations(
|
||||||
**{
|
**{
|
||||||
@@ -319,11 +319,14 @@ class MaraMiner(MaraFirmware):
|
|||||||
return []
|
return []
|
||||||
|
|
||||||
active_pool_index = None
|
active_pool_index = None
|
||||||
highest_priority = float('inf')
|
highest_priority = float("inf")
|
||||||
|
|
||||||
for pool_info in web_pools:
|
for pool_info in web_pools:
|
||||||
if pool_info.get("status") == "Alive" and pool_info.get("priority", float('inf')) < highest_priority:
|
if (
|
||||||
highest_priority = pool_info.get["priority"]
|
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"]
|
active_pool_index = pool_info["index"]
|
||||||
|
|
||||||
pools_data = []
|
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:
|
||||||
web_summary = await self.web.summary()
|
try:
|
||||||
|
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,7 +560,14 @@ 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:
|
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.
|
"""Upgrade the firmware of the miner.
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
@@ -574,4 +581,5 @@ class BaseMiner(MinerProtocol):
|
|||||||
"""
|
"""
|
||||||
return False
|
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,
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -43,4 +43,4 @@ class LuxOSFirmware(BaseMiner):
|
|||||||
|
|
||||||
|
|
||||||
class MaraFirmware(BaseMiner):
|
class MaraFirmware(BaseMiner):
|
||||||
firmware = MinerFirmware.MARATHON
|
firmware = MinerFirmware.MARATHON
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
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
|
||||||
|
|||||||
23
pyasic/miners/device/models/antminer/X9/D9.py
Normal file
23
pyasic/miners/device/models/antminer/X9/D9.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 D9(AntMinerMake):
|
||||||
|
raw_model = MinerModel.ANTMINER.D9
|
||||||
|
|
||||||
|
expected_chips = 126
|
||||||
@@ -14,6 +14,7 @@
|
|||||||
# limitations under the License. -
|
# limitations under the License. -
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
from .D9 import D9
|
||||||
from .E9 import E9Pro
|
from .E9 import E9Pro
|
||||||
from .S9 import S9, S9i, S9j
|
from .S9 import S9, S9i, S9j
|
||||||
from .T9 import T9
|
from .T9 import T9
|
||||||
|
|||||||
37
pyasic/miners/device/models/iceriver/KSX/KS5.py
Normal file
37
pyasic/miners/device/models/iceriver/KSX/KS5.py
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# 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 KS5(IceRiverMake):
|
||||||
|
raw_model = MinerModel.ICERIVER.KS5
|
||||||
|
|
||||||
|
expected_fans = 4
|
||||||
|
expected_chips = 92
|
||||||
|
|
||||||
|
|
||||||
|
class KS5L(IceRiverMake):
|
||||||
|
raw_model = MinerModel.ICERIVER.KS5L
|
||||||
|
|
||||||
|
expected_fans = 4
|
||||||
|
expected_chips = 18
|
||||||
|
|
||||||
|
|
||||||
|
class KS5M(IceRiverMake):
|
||||||
|
raw_model = MinerModel.ICERIVER.KS5M
|
||||||
|
|
||||||
|
expected_fans = 4
|
||||||
@@ -2,3 +2,4 @@ from .KS0 import KS0
|
|||||||
from .KS1 import KS1
|
from .KS1 import KS1
|
||||||
from .KS2 import KS2
|
from .KS2 import KS2
|
||||||
from .KS3 import KS3, KS3L, KS3M
|
from .KS3 import KS3, KS3L, KS3M
|
||||||
|
from .KS5 import KS5, KS5L, KS5M
|
||||||
|
|||||||
24
pyasic/miners/device/models/innosilicon/A11X/A11.py
Normal file
24
pyasic/miners/device/models/innosilicon/A11X/A11.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 A11(InnosiliconMake):
|
||||||
|
raw_model = MinerModel.INNOSILICON.A11
|
||||||
|
|
||||||
|
expected_hashboards = 4
|
||||||
|
expected_chips = 8
|
||||||
@@ -21,3 +21,4 @@ class A11MX(InnosiliconMake):
|
|||||||
raw_model = MinerModel.INNOSILICON.A11MX
|
raw_model = MinerModel.INNOSILICON.A11MX
|
||||||
|
|
||||||
expected_hashboards = 4
|
expected_hashboards = 4
|
||||||
|
expected_chips = 8
|
||||||
|
|||||||
@@ -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 .A11 import *
|
||||||
from .A11M import *
|
from .A11M import *
|
||||||
|
|||||||
@@ -78,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
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ from .M50 import (
|
|||||||
M50VH60,
|
M50VH60,
|
||||||
M50VH70,
|
M50VH70,
|
||||||
M50VH80,
|
M50VH80,
|
||||||
|
M50VH90,
|
||||||
M50VJ10,
|
M50VJ10,
|
||||||
M50VJ20,
|
M50VJ20,
|
||||||
M50VJ30,
|
M50VJ30,
|
||||||
|
|||||||
@@ -72,12 +72,15 @@ MINER_CLASSES = {
|
|||||||
"ANTMINER DR5": CGMinerDR5,
|
"ANTMINER DR5": CGMinerDR5,
|
||||||
"ANTMINER KS5": BMMinerKS5,
|
"ANTMINER KS5": BMMinerKS5,
|
||||||
"ANTMINER L7": BMMinerL7,
|
"ANTMINER L7": BMMinerL7,
|
||||||
|
"ANTMINER K7": BMMinerK7,
|
||||||
"ANTMINER E9 PRO": BMMinerE9Pro,
|
"ANTMINER E9 PRO": BMMinerE9Pro,
|
||||||
|
"ANTMINER D9": BMMinerD9,
|
||||||
"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,
|
||||||
@@ -275,6 +278,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,
|
||||||
@@ -342,6 +346,7 @@ MINER_CLASSES = {
|
|||||||
None: type("InnosiliconUnknown", (Innosilicon, InnosiliconMake), {}),
|
None: type("InnosiliconUnknown", (Innosilicon, InnosiliconMake), {}),
|
||||||
"T3H+": InnosiliconT3HPlus,
|
"T3H+": InnosiliconT3HPlus,
|
||||||
"A10X": InnosiliconA10X,
|
"A10X": InnosiliconA10X,
|
||||||
|
"A11": InnosiliconA11,
|
||||||
"A11MX": InnosiliconA11MX,
|
"A11MX": InnosiliconA11MX,
|
||||||
},
|
},
|
||||||
MinerTypes.GOLDSHELL: {
|
MinerTypes.GOLDSHELL: {
|
||||||
@@ -395,6 +400,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,
|
||||||
@@ -468,6 +474,9 @@ MINER_CLASSES = {
|
|||||||
"KS3": IceRiverKS3,
|
"KS3": IceRiverKS3,
|
||||||
"KS3L": IceRiverKS3L,
|
"KS3L": IceRiverKS3L,
|
||||||
"KS3M": IceRiverKS3M,
|
"KS3M": IceRiverKS3M,
|
||||||
|
"KS5": IceRiverKS5,
|
||||||
|
"KS5L": IceRiverKS5L,
|
||||||
|
"KS5M": IceRiverKS5M,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -546,6 +555,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)
|
||||||
|
|
||||||
@@ -627,6 +637,8 @@ 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:
|
if "<TITLE>用户界面</TITLE>" in web_text:
|
||||||
return MinerTypes.ICERIVER
|
return MinerTypes.ICERIVER
|
||||||
if "AxeOS" in web_text:
|
if "AxeOS" in web_text:
|
||||||
@@ -709,10 +721,10 @@ 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 "HIVEON" in upper_data:
|
|
||||||
return MinerTypes.HIVEON
|
|
||||||
if "LUXMINER" in upper_data:
|
if "LUXMINER" in upper_data:
|
||||||
return MinerTypes.LUX_OS
|
return MinerTypes.LUX_OS
|
||||||
|
if "HIVEON" in upper_data:
|
||||||
|
return MinerTypes.HIVEON
|
||||||
if "KAONSU" in upper_data:
|
if "KAONSU" in upper_data:
|
||||||
return MinerTypes.MARATHON
|
return MinerTypes.MARATHON
|
||||||
if "ANTMINER" in upper_data and "DEVDETAILS" not in upper_data:
|
if "ANTMINER" in upper_data and "DEVDETAILS" not in upper_data:
|
||||||
@@ -817,12 +829,8 @@ class MinerFactory:
|
|||||||
# fix an error with a btminer return having a missing comma. (2023-01-06 version)
|
# fix an error with a btminer return having a missing comma. (2023-01-06 version)
|
||||||
str_data = str_data.replace('""temp0', '","temp0')
|
str_data = str_data.replace('""temp0', '","temp0')
|
||||||
# fix an error with Avalonminers returning inf and nan
|
# fix an error with Avalonminers returning inf and nan
|
||||||
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('"nan"', "0")
|
||||||
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("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:]}"
|
||||||
|
|||||||
14
pyasic/miners/iceriver/iceminer/KSX/KS5.py
Normal file
14
pyasic/miners/iceriver/iceminer/KSX/KS5.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
from pyasic.miners.backends.iceriver import IceRiver
|
||||||
|
from pyasic.miners.device.models.iceriver import KS5, KS5L, KS5M
|
||||||
|
|
||||||
|
|
||||||
|
class IceRiverKS5(IceRiver, KS5):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class IceRiverKS5L(IceRiver, KS5L):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class IceRiverKS5M(IceRiver, KS5M):
|
||||||
|
pass
|
||||||
@@ -2,3 +2,4 @@ from .KS0 import IceRiverKS0
|
|||||||
from .KS1 import IceRiverKS1
|
from .KS1 import IceRiverKS1
|
||||||
from .KS2 import IceRiverKS2
|
from .KS2 import IceRiverKS2
|
||||||
from .KS3 import IceRiverKS3, IceRiverKS3L, IceRiverKS3M
|
from .KS3 import IceRiverKS3, IceRiverKS3L, IceRiverKS3M
|
||||||
|
from .KS5 import IceRiverKS5, IceRiverKS5L, IceRiverKS5M
|
||||||
|
|||||||
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
|
||||||
@@ -1 +1,2 @@
|
|||||||
|
from .A11 import InnosiliconA11
|
||||||
from .A11M import InnosiliconA11MX
|
from .A11M import InnosiliconA11MX
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ from pyasic.miners.device.models import (
|
|||||||
M50VH60,
|
M50VH60,
|
||||||
M50VH70,
|
M50VH70,
|
||||||
M50VH80,
|
M50VH80,
|
||||||
|
M50VH90,
|
||||||
M50VJ10,
|
M50VJ10,
|
||||||
M50VJ20,
|
M50VJ20,
|
||||||
M50VJ30,
|
M50VJ30,
|
||||||
@@ -72,6 +73,10 @@ class BTMinerM50VH80(M5X, M50VH80):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class BTMinerM50VH90(M5X, M50VH90):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class BTMinerM50VJ10(M5X, M50VJ10):
|
class BTMinerM50VJ10(M5X, M50VJ10):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ from .M50 import (
|
|||||||
BTMinerM50VH60,
|
BTMinerM50VH60,
|
||||||
BTMinerM50VH70,
|
BTMinerM50VH70,
|
||||||
BTMinerM50VH80,
|
BTMinerM50VH80,
|
||||||
|
BTMinerM50VH90,
|
||||||
BTMinerM50VJ10,
|
BTMinerM50VJ10,
|
||||||
BTMinerM50VJ20,
|
BTMinerM50VJ20,
|
||||||
BTMinerM50VJ30,
|
BTMinerM50VJ30,
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ import hashlib
|
|||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
from typing import Literal, Union
|
|
||||||
import struct
|
import struct
|
||||||
|
from typing import Literal, Union
|
||||||
|
|
||||||
import httpx
|
import httpx
|
||||||
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
||||||
|
|||||||
@@ -13,8 +13,9 @@
|
|||||||
# 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 typing import Literal
|
from typing import Literal, Optional, Union
|
||||||
|
|
||||||
|
from pyasic import APIError
|
||||||
from pyasic.rpc.base import BaseMinerRPCAPI
|
from pyasic.rpc.base import BaseMinerRPCAPI
|
||||||
|
|
||||||
|
|
||||||
@@ -32,6 +33,48 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
rely on it to send the command for them.
|
rely on it to send the command for them.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.session_token = None
|
||||||
|
|
||||||
|
async def send_privileged_command(
|
||||||
|
self, command: Union[str, bytes], *args, **kwargs
|
||||||
|
) -> dict:
|
||||||
|
if self.session_token is None:
|
||||||
|
await self.auth()
|
||||||
|
return await self.send_command(
|
||||||
|
command,
|
||||||
|
self.session_token,
|
||||||
|
*args,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
async def send_command(
|
||||||
|
self,
|
||||||
|
command: Union[str, bytes],
|
||||||
|
*args,
|
||||||
|
**kwargs,
|
||||||
|
) -> dict:
|
||||||
|
if kwargs.get("parameters") is not None and len(args) == 0:
|
||||||
|
return await super().send_command(command, **kwargs)
|
||||||
|
return await super().send_command(command, parameters=",".join(args), **kwargs)
|
||||||
|
|
||||||
|
async def auth(self) -> Optional[str]:
|
||||||
|
try:
|
||||||
|
data = await self.session()
|
||||||
|
if not data["SESSION"][0]["SessionID"] == "":
|
||||||
|
self.session_token = data["SESSION"][0]["SessionID"]
|
||||||
|
return self.session_token
|
||||||
|
except APIError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
data = await self.logon()
|
||||||
|
self.session_token = data["SESSION"][0]["SessionID"]
|
||||||
|
return self.session_token
|
||||||
|
except (LookupError, APIError):
|
||||||
|
pass
|
||||||
|
|
||||||
async def addgroup(self, name: str, quota: int) -> dict:
|
async def addgroup(self, name: str, quota: int) -> dict:
|
||||||
"""Add a pool group.
|
"""Add a pool group.
|
||||||
<details>
|
<details>
|
||||||
@@ -45,7 +88,7 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
Confirmation of adding a pool group.
|
Confirmation of adding a pool group.
|
||||||
</details>
|
</details>
|
||||||
"""
|
"""
|
||||||
return await self.send_command("addgroup", parameters=f"{name},{quota}")
|
return await self.send_command("addgroup", name, quota)
|
||||||
|
|
||||||
async def addpool(
|
async def addpool(
|
||||||
self, url: str, user: str, pwd: str = "", group_id: str = None
|
self, url: str, user: str, pwd: str = "", group_id: str = None
|
||||||
@@ -67,7 +110,7 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
pool_data = [url, user, pwd]
|
pool_data = [url, user, pwd]
|
||||||
if group_id is not None:
|
if group_id is not None:
|
||||||
pool_data.append(group_id)
|
pool_data.append(group_id)
|
||||||
return await self.send_command("addpool", parameters=",".join(pool_data))
|
return await self.send_command("addpool", *pool_data)
|
||||||
|
|
||||||
async def asc(self, n: int) -> dict:
|
async def asc(self, n: int) -> dict:
|
||||||
"""Get data for ASC device n.
|
"""Get data for ASC device n.
|
||||||
@@ -81,7 +124,7 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
The data for ASC device n.
|
The data for ASC device n.
|
||||||
</details>
|
</details>
|
||||||
"""
|
"""
|
||||||
return await self.send_command("asc", parameters=n)
|
return await self.send_command("asc", n)
|
||||||
|
|
||||||
async def asccount(self) -> dict:
|
async def asccount(self) -> dict:
|
||||||
"""Get data on the number of ASC devices and their info.
|
"""Get data on the number of ASC devices and their info.
|
||||||
@@ -108,7 +151,7 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
* Access (Y/N) <- you have access to use the command
|
* Access (Y/N) <- you have access to use the command
|
||||||
</details>
|
</details>
|
||||||
"""
|
"""
|
||||||
return await self.send_command("check", parameters=command)
|
return await self.send_command("check", command)
|
||||||
|
|
||||||
async def coin(self) -> dict:
|
async def coin(self) -> dict:
|
||||||
"""Get information on the current coin.
|
"""Get information on the current coin.
|
||||||
@@ -137,19 +180,38 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
"""
|
"""
|
||||||
return await self.send_command("config")
|
return await self.send_command("config")
|
||||||
|
|
||||||
async def curtail(self, session_id: str) -> dict:
|
async def curtail(self) -> dict:
|
||||||
"""Put the miner into sleep mode. Requires a session_id from logon.
|
"""Put the miner into sleep mode.
|
||||||
<details>
|
<details>
|
||||||
<summary>Expand</summary>
|
<summary>Expand</summary>
|
||||||
|
|
||||||
Parameters:
|
|
||||||
session_id: Session id from the logon command.
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A confirmation of putting the miner to sleep.
|
A confirmation of putting the miner to sleep.
|
||||||
</details>
|
</details>
|
||||||
"""
|
"""
|
||||||
return await self.send_command("curtail", parameters=session_id)
|
return await self.send_privileged_command("curtail", "sleep")
|
||||||
|
|
||||||
|
async def sleep(self) -> dict:
|
||||||
|
"""Put the miner into sleep mode.
|
||||||
|
<details>
|
||||||
|
<summary>Expand</summary>
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A confirmation of putting the miner to sleep.
|
||||||
|
</details>
|
||||||
|
"""
|
||||||
|
return await self.send_privileged_command("curtail", "sleep")
|
||||||
|
|
||||||
|
async def wakeup(self) -> dict:
|
||||||
|
"""Wake the miner up from sleep mode.
|
||||||
|
<details>
|
||||||
|
<summary>Expand</summary>
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A confirmation of waking the miner up.
|
||||||
|
</details>
|
||||||
|
"""
|
||||||
|
return await self.send_privileged_command("curtail", "wakeup")
|
||||||
|
|
||||||
async def devdetails(self) -> dict:
|
async def devdetails(self) -> dict:
|
||||||
"""Get data on all devices with their static details.
|
"""Get data on all devices with their static details.
|
||||||
@@ -185,7 +247,7 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
A confirmation of diabling the pool.
|
A confirmation of diabling the pool.
|
||||||
</details>
|
</details>
|
||||||
"""
|
"""
|
||||||
return await self.send_command("disablepool", parameters=n)
|
return await self.send_command("disablepool", n)
|
||||||
|
|
||||||
async def edevs(self) -> dict:
|
async def edevs(self) -> dict:
|
||||||
"""Alias for devs"""
|
"""Alias for devs"""
|
||||||
@@ -203,7 +265,7 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
A confirmation of enabling pool n.
|
A confirmation of enabling pool n.
|
||||||
</details>
|
</details>
|
||||||
"""
|
"""
|
||||||
return await self.send_command("enablepool", parameters=n)
|
return await self.send_command("enablepool", n)
|
||||||
|
|
||||||
async def estats(self) -> dict:
|
async def estats(self) -> dict:
|
||||||
"""Alias for stats"""
|
"""Alias for stats"""
|
||||||
@@ -220,13 +282,14 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
"""
|
"""
|
||||||
return await self.send_command("fans")
|
return await self.send_command("fans")
|
||||||
|
|
||||||
async def fanset(self, session_id: str, speed: int, min_fans: int = None) -> dict:
|
async def fanset(
|
||||||
"""Set fan control. Requires a session_id from logon.
|
self, speed: int = None, min_fans: int = None, power_off_speed: int = None
|
||||||
|
) -> dict:
|
||||||
|
"""Set fan control.
|
||||||
<details>
|
<details>
|
||||||
<summary>Expand</summary>
|
<summary>Expand</summary>
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
session_id: Session id from the logon command.
|
|
||||||
speed: The fan speed to set. Use -1 to set automatically.
|
speed: The fan speed to set. Use -1 to set automatically.
|
||||||
min_fans: The minimum number of fans to use. Optional.
|
min_fans: The minimum number of fans to use. Optional.
|
||||||
|
|
||||||
@@ -234,10 +297,14 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
A confirmation of setting fan control values.
|
A confirmation of setting fan control values.
|
||||||
</details>
|
</details>
|
||||||
"""
|
"""
|
||||||
fanset_data = [str(session_id), str(speed)]
|
fanset_data = []
|
||||||
|
if speed is not None:
|
||||||
|
fanset_data.append(f"speed={speed}")
|
||||||
if min_fans is not None:
|
if min_fans is not None:
|
||||||
fanset_data.append(str(min_fans))
|
fanset_data.append(f"min_fans={min_fans}")
|
||||||
return await self.send_command("fanset", parameters=",".join(fanset_data))
|
if power_off_speed is not None:
|
||||||
|
fanset_data.append(f"power_off_speed={power_off_speed}")
|
||||||
|
return await self.send_privileged_command("fanset", *fanset_data)
|
||||||
|
|
||||||
async def frequencyget(self, board_n: int, chip_n: int = None) -> dict:
|
async def frequencyget(self, board_n: int, chip_n: int = None) -> dict:
|
||||||
"""Get frequency data for a board and chips.
|
"""Get frequency data for a board and chips.
|
||||||
@@ -255,17 +322,14 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
frequencyget_data = [str(board_n)]
|
frequencyget_data = [str(board_n)]
|
||||||
if chip_n is not None:
|
if chip_n is not None:
|
||||||
frequencyget_data.append(str(chip_n))
|
frequencyget_data.append(str(chip_n))
|
||||||
return await self.send_command(
|
return await self.send_command("frequencyget", *frequencyget_data)
|
||||||
"frequencyget", parameters=",".join(frequencyget_data)
|
|
||||||
)
|
|
||||||
|
|
||||||
async def frequencyset(self, session_id: str, board_n: int, freq: int) -> dict:
|
async def frequencyset(self, board_n: int, freq: int) -> dict:
|
||||||
"""Set frequency. Requires a session_id from logon.
|
"""Set frequency.
|
||||||
<details>
|
<details>
|
||||||
<summary>Expand</summary>
|
<summary>Expand</summary>
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
session_id: Session id from the logon command.
|
|
||||||
board_n: The board number to set frequency on.
|
board_n: The board number to set frequency on.
|
||||||
freq: The frequency to set.
|
freq: The frequency to set.
|
||||||
|
|
||||||
@@ -273,26 +337,21 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
A confirmation of setting frequency values.
|
A confirmation of setting frequency values.
|
||||||
</details>
|
</details>
|
||||||
"""
|
"""
|
||||||
return await self.send_command(
|
return await self.send_privileged_command("frequencyset", board_n, freq)
|
||||||
"frequencyset", parameters=f"{session_id},{board_n},{freq}"
|
|
||||||
)
|
|
||||||
|
|
||||||
async def frequencystop(self, session_id: str, board_n: int) -> dict:
|
async def frequencystop(self, board_n: int) -> dict:
|
||||||
"""Stop set frequency. Requires a session_id from logon.
|
"""Stop set frequency.
|
||||||
<details>
|
<details>
|
||||||
<summary>Expand</summary>
|
<summary>Expand</summary>
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
session_id: Session id from the logon command.
|
|
||||||
board_n: The board number to set frequency on.
|
board_n: The board number to set frequency on.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A confirmation of stopping frequencyset value.
|
A confirmation of stopping frequencyset value.
|
||||||
</details>
|
</details>
|
||||||
"""
|
"""
|
||||||
return await self.send_command(
|
return await self.send_privileged_command("frequencystop", board_n)
|
||||||
"frequencystop", parameters=f"{session_id},{board_n}"
|
|
||||||
)
|
|
||||||
|
|
||||||
async def groupquota(self, group_n: int, quota: int) -> dict:
|
async def groupquota(self, group_n: int, quota: int) -> dict:
|
||||||
"""Set a group's quota.
|
"""Set a group's quota.
|
||||||
@@ -307,7 +366,7 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
A confirmation of setting quota value.
|
A confirmation of setting quota value.
|
||||||
</details>
|
</details>
|
||||||
"""
|
"""
|
||||||
return await self.send_command("groupquota", parameters=f"{group_n},{quota}")
|
return await self.send_command("groupquota", group_n, quota)
|
||||||
|
|
||||||
async def groups(self) -> dict:
|
async def groups(self) -> dict:
|
||||||
"""Get pool group data.
|
"""Get pool group data.
|
||||||
@@ -336,19 +395,14 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
healthchipget_data = [str(board_n)]
|
healthchipget_data = [str(board_n)]
|
||||||
if chip_n is not None:
|
if chip_n is not None:
|
||||||
healthchipget_data.append(str(chip_n))
|
healthchipget_data.append(str(chip_n))
|
||||||
return await self.send_command(
|
return await self.send_command("healthchipget", *healthchipget_data)
|
||||||
"healthchipget", parameters=",".join(healthchipget_data)
|
|
||||||
)
|
|
||||||
|
|
||||||
async def healthchipset(
|
async def healthchipset(self, board_n: int, chip_n: int = None) -> dict:
|
||||||
self, session_id: str, board_n: int, chip_n: int = None
|
"""Select the next chip to have its health checked.
|
||||||
) -> dict:
|
|
||||||
"""Select the next chip to have its health checked. Requires a session_id from logon.
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Expand</summary>
|
<summary>Expand</summary>
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
session_id: Session id from the logon command.
|
|
||||||
board_n: The board number to next get chip health of.
|
board_n: The board number to next get chip health of.
|
||||||
chip_n: The chip number to next get chip health of. Optional.
|
chip_n: The chip number to next get chip health of. Optional.
|
||||||
|
|
||||||
@@ -356,12 +410,10 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
Confirmation of selecting the next health check chip.
|
Confirmation of selecting the next health check chip.
|
||||||
</details>
|
</details>
|
||||||
"""
|
"""
|
||||||
healthchipset_data = [session_id, str(board_n)]
|
healthchipset_data = [str(board_n)]
|
||||||
if chip_n is not None:
|
if chip_n is not None:
|
||||||
healthchipset_data.append(str(chip_n))
|
healthchipset_data.append(str(chip_n))
|
||||||
return await self.send_command(
|
return await self.send_privileged_command("healthchipset", *healthchipset_data)
|
||||||
"healthchipset", parameters=",".join(healthchipset_data)
|
|
||||||
)
|
|
||||||
|
|
||||||
async def healthctrl(self) -> dict:
|
async def healthctrl(self) -> dict:
|
||||||
"""Get health check config.
|
"""Get health check config.
|
||||||
@@ -374,15 +426,12 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
"""
|
"""
|
||||||
return await self.send_command("healthctrl")
|
return await self.send_command("healthctrl")
|
||||||
|
|
||||||
async def healthctrlset(
|
async def healthctrlset(self, num_readings: int, amplified_factor: float) -> dict:
|
||||||
self, session_id: str, num_readings: int, amplified_factor: float
|
"""Set health control config.
|
||||||
) -> dict:
|
|
||||||
"""Set health control config. Requires a session_id from logon.
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Expand</summary>
|
<summary>Expand</summary>
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
session_id: Session id from the logon command.
|
|
||||||
num_readings: The minimum number of readings for evaluation.
|
num_readings: The minimum number of readings for evaluation.
|
||||||
amplified_factor: Performance factor of the evaluation.
|
amplified_factor: Performance factor of the evaluation.
|
||||||
|
|
||||||
@@ -390,9 +439,8 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
A confirmation of setting health control config.
|
A confirmation of setting health control config.
|
||||||
</details>
|
</details>
|
||||||
"""
|
"""
|
||||||
return await self.send_command(
|
return await self.send_privileged_command(
|
||||||
"healthctrlset",
|
"healthctrlset", num_readings, amplified_factor
|
||||||
parameters=f"{session_id},{num_readings},{amplified_factor}",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
async def kill(self) -> dict:
|
async def kill(self) -> dict:
|
||||||
@@ -419,16 +467,14 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
|
|
||||||
async def ledset(
|
async def ledset(
|
||||||
self,
|
self,
|
||||||
session_id: str,
|
|
||||||
color: Literal["red"],
|
color: Literal["red"],
|
||||||
state: Literal["on", "off", "blink"],
|
state: Literal["on", "off", "blink"],
|
||||||
) -> dict:
|
) -> dict:
|
||||||
"""Set led. Requires a session_id from logon.
|
"""Set led.
|
||||||
<details>
|
<details>
|
||||||
<summary>Expand</summary>
|
<summary>Expand</summary>
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
session_id: Session id from the logon command.
|
|
||||||
color: The color LED to set. Can be "red".
|
color: The color LED to set. Can be "red".
|
||||||
state: The state to set the LED to. Can be "on", "off", or "blink".
|
state: The state to set the LED to. Can be "on", "off", or "blink".
|
||||||
|
|
||||||
@@ -436,9 +482,7 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
A confirmation of setting LED.
|
A confirmation of setting LED.
|
||||||
</details>
|
</details>
|
||||||
"""
|
"""
|
||||||
return await self.send_command(
|
return await self.send_privileged_command("ledset", color, state)
|
||||||
"ledset", parameters=f"{session_id},{color},{state}"
|
|
||||||
)
|
|
||||||
|
|
||||||
async def limits(self) -> dict:
|
async def limits(self) -> dict:
|
||||||
"""Get max and min values of config parameters.
|
"""Get max and min values of config parameters.
|
||||||
@@ -451,8 +495,8 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
"""
|
"""
|
||||||
return await self.send_command("limits")
|
return await self.send_command("limits")
|
||||||
|
|
||||||
async def logoff(self, session_id: str) -> dict:
|
async def logoff(self) -> dict:
|
||||||
"""Log off of a session. Requires a session id from an active session.
|
"""Log off of a session.
|
||||||
<details>
|
<details>
|
||||||
<summary>Expand</summary>
|
<summary>Expand</summary>
|
||||||
|
|
||||||
@@ -463,7 +507,9 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
Confirmation of logging off a session.
|
Confirmation of logging off a session.
|
||||||
</details>
|
</details>
|
||||||
"""
|
"""
|
||||||
return await self.send_command("logoff", parameters=session_id)
|
res = await self.send_privileged_command("logoff")
|
||||||
|
self.session_token = None
|
||||||
|
return res
|
||||||
|
|
||||||
async def logon(self) -> dict:
|
async def logon(self) -> dict:
|
||||||
"""Get or create a session.
|
"""Get or create a session.
|
||||||
@@ -510,13 +556,12 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
"""
|
"""
|
||||||
return await self.send_command("profiles")
|
return await self.send_command("profiles")
|
||||||
|
|
||||||
async def profileset(self, session_id: str, board_n: int, profile: str) -> dict:
|
async def profileset(self, board_n: int, profile: str) -> dict:
|
||||||
"""Set active profile for a board. Requires a session_id from logon.
|
"""Set active profile for a board.
|
||||||
<details>
|
<details>
|
||||||
<summary>Expand</summary>
|
<summary>Expand</summary>
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
session_id: Session id from the logon command.
|
|
||||||
board_n: The board to set the profile on.
|
board_n: The board to set the profile on.
|
||||||
profile: The profile name to use.
|
profile: The profile name to use.
|
||||||
|
|
||||||
@@ -524,17 +569,14 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
A confirmation of setting the profile on board_n.
|
A confirmation of setting the profile on board_n.
|
||||||
</details>
|
</details>
|
||||||
"""
|
"""
|
||||||
return await self.send_command(
|
return await self.send_privileged_command("profileset", board_n, profile)
|
||||||
"profileset", parameters=f"{session_id},{board_n},{profile}"
|
|
||||||
)
|
|
||||||
|
|
||||||
async def reboot(self, session_id: str, board_n: int, delay_s: int = None) -> dict:
|
async def reboot(self, board_n: int, delay_s: int = None) -> dict:
|
||||||
"""Reboot a board. Requires a session_id from logon.
|
"""Reboot a board.
|
||||||
<details>
|
<details>
|
||||||
<summary>Expand</summary>
|
<summary>Expand</summary>
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
session_id: Session id from the logon command.
|
|
||||||
board_n: The board to reboot.
|
board_n: The board to reboot.
|
||||||
delay_s: The number of seconds to delay until startup. If it is 0, the board will just stop. Optional.
|
delay_s: The number of seconds to delay until startup. If it is 0, the board will just stop. Optional.
|
||||||
|
|
||||||
@@ -542,24 +584,21 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
A confirmation of rebooting board_n.
|
A confirmation of rebooting board_n.
|
||||||
</details>
|
</details>
|
||||||
"""
|
"""
|
||||||
reboot_data = [session_id, str(board_n)]
|
reboot_data = [str(board_n)]
|
||||||
if delay_s is not None:
|
if delay_s is not None:
|
||||||
reboot_data.append(str(delay_s))
|
reboot_data.append(str(delay_s))
|
||||||
return await self.send_command("reboot", parameters=",".join(reboot_data))
|
return await self.send_privileged_command("reboot", *reboot_data)
|
||||||
|
|
||||||
async def rebootdevice(self, session_id: str) -> dict:
|
async def rebootdevice(self) -> dict:
|
||||||
"""Reboot the miner. Requires a session_id from logon.
|
"""Reboot the miner.
|
||||||
<details>
|
<details>
|
||||||
<summary>Expand</summary>
|
<summary>Expand</summary>
|
||||||
|
|
||||||
Parameters:
|
|
||||||
session_id: Session id from the logon command.
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A confirmation of rebooting the miner.
|
A confirmation of rebooting the miner.
|
||||||
</details>
|
</details>
|
||||||
"""
|
"""
|
||||||
return await self.send_command("rebootdevice", parameters=session_id)
|
return await self.send_privileged_command("rebootdevice")
|
||||||
|
|
||||||
async def removegroup(self, group_id: str) -> dict:
|
async def removegroup(self, group_id: str) -> dict:
|
||||||
"""Remove a pool group.
|
"""Remove a pool group.
|
||||||
@@ -575,19 +614,16 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
"""
|
"""
|
||||||
return await self.send_command("removegroup", parameters=group_id)
|
return await self.send_command("removegroup", parameters=group_id)
|
||||||
|
|
||||||
async def resetminer(self, session_id: str) -> dict:
|
async def resetminer(self) -> dict:
|
||||||
"""Restart the mining process. Requires a session_id from logon.
|
"""Restart the mining process.
|
||||||
<details>
|
<details>
|
||||||
<summary>Expand</summary>
|
<summary>Expand</summary>
|
||||||
|
|
||||||
Parameters:
|
|
||||||
session_id: Session id from the logon command.
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A confirmation of restarting the mining process.
|
A confirmation of restarting the mining process.
|
||||||
</details>
|
</details>
|
||||||
"""
|
"""
|
||||||
return await self.send_command("resetminer", parameters=session_id)
|
return await self.send_privileged_command("resetminer")
|
||||||
|
|
||||||
async def removepool(self, pool_id: int) -> dict:
|
async def removepool(self, pool_id: int) -> dict:
|
||||||
"""Remove a pool.
|
"""Remove a pool.
|
||||||
@@ -614,7 +650,9 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
"""
|
"""
|
||||||
return await self.send_command("session")
|
return await self.send_command("session")
|
||||||
|
|
||||||
async def tempctrlset(self, target: int, hot: int, dangerous: int) -> dict:
|
async def tempctrlset(
|
||||||
|
self, target: int = None, hot: int = None, dangerous: int = None
|
||||||
|
) -> dict:
|
||||||
"""Set temp control values.
|
"""Set temp control values.
|
||||||
<details>
|
<details>
|
||||||
<summary>Expand</summary>
|
<summary>Expand</summary>
|
||||||
@@ -629,7 +667,7 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
</details>
|
</details>
|
||||||
"""
|
"""
|
||||||
return await self.send_command(
|
return await self.send_command(
|
||||||
"tempctrlset", parameters=f"{target},{hot},{dangerous}"
|
"tempctrlset", target or "", hot or "", dangerous or ""
|
||||||
)
|
)
|
||||||
|
|
||||||
async def stats(self) -> dict:
|
async def stats(self) -> dict:
|
||||||
@@ -668,7 +706,7 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
A confirmation of switching to the pool.
|
A confirmation of switching to the pool.
|
||||||
</details>
|
</details>
|
||||||
"""
|
"""
|
||||||
return await self.send_command("switchpool", parameters=str(pool_id))
|
return await self.send_command("switchpool", pool_id)
|
||||||
|
|
||||||
async def tempctrl(self) -> dict:
|
async def tempctrl(self) -> dict:
|
||||||
"""Get temperature control data.
|
"""Get temperature control data.
|
||||||
@@ -716,15 +754,14 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
Board voltage values.
|
Board voltage values.
|
||||||
</details>
|
</details>
|
||||||
"""
|
"""
|
||||||
return await self.send_command("frequencyget", parameters=str(board_n))
|
return await self.send_command("frequencyget", board_n)
|
||||||
|
|
||||||
async def voltageset(self, session_id: str, board_n: int, voltage: float) -> dict:
|
async def voltageset(self, board_n: int, voltage: float) -> dict:
|
||||||
"""Set voltage values.
|
"""Set voltage values.
|
||||||
<details>
|
<details>
|
||||||
<summary>Expand</summary>
|
<summary>Expand</summary>
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
session_id: Session id from the logon command.
|
|
||||||
board_n: The board to set the voltage on.
|
board_n: The board to set the voltage on.
|
||||||
voltage: The voltage to use.
|
voltage: The voltage to use.
|
||||||
|
|
||||||
@@ -732,23 +769,7 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
A confirmation of setting the voltage.
|
A confirmation of setting the voltage.
|
||||||
</details>
|
</details>
|
||||||
"""
|
"""
|
||||||
return await self.send_command(
|
return await self.send_privileged_command("voltageset", board_n, voltage)
|
||||||
"voltageset", parameters=f"{session_id},{board_n},{voltage}"
|
|
||||||
)
|
|
||||||
|
|
||||||
async def wakeup(self, session_id: str) -> dict:
|
|
||||||
"""Take the miner out of sleep mode. Requires a session_id from logon.
|
|
||||||
<details>
|
|
||||||
<summary>Expand</summary>
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
session_id: Session id from the logon command.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A confirmation of resuming mining.
|
|
||||||
</details>
|
|
||||||
"""
|
|
||||||
return await self.send_command("wakeup", parameters=session_id)
|
|
||||||
|
|
||||||
async def upgraderun(self):
|
async def upgraderun(self):
|
||||||
"""
|
"""
|
||||||
@@ -757,4 +778,4 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
Returns:
|
Returns:
|
||||||
The response from the miner after sending the 'updaterun' command.
|
The response from the miner after sending the 'updaterun' command.
|
||||||
"""
|
"""
|
||||||
return await self.send_command("updaterun")
|
return await self.send_command("updaterun")
|
||||||
|
|||||||
@@ -17,10 +17,11 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import json
|
import json
|
||||||
|
from pathlib import Path
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
import aiofiles
|
import aiofiles
|
||||||
import httpx
|
import httpx
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
from pyasic import settings
|
from pyasic import settings
|
||||||
from pyasic.web.base import BaseWebAPI
|
from pyasic.web.base import BaseWebAPI
|
||||||
@@ -414,10 +415,7 @@ class AntminerOldWebAPI(BaseWebAPI):
|
|||||||
parameters = {
|
parameters = {
|
||||||
"file": (file.name, file_content, "application/octet-stream"),
|
"file": (file.name, file_content, "application/octet-stream"),
|
||||||
"filename": file.name,
|
"filename": file.name,
|
||||||
"keep_settings": keep_settings
|
"keep_settings": keep_settings,
|
||||||
}
|
}
|
||||||
|
|
||||||
return await self.send_command(
|
return await self.send_command(command="upgrade", **parameters)
|
||||||
command="upgrade",
|
|
||||||
**parameters
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -4,17 +4,12 @@
|
|||||||
# This file has been @generated
|
# This file has been @generated
|
||||||
|
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import (
|
from typing import TYPE_CHECKING, Dict, Optional
|
||||||
TYPE_CHECKING,
|
|
||||||
Dict,
|
|
||||||
Optional,
|
|
||||||
)
|
|
||||||
|
|
||||||
import betterproto
|
import betterproto
|
||||||
import grpclib
|
import grpclib
|
||||||
from betterproto.grpc.grpclib_server import ServiceBase
|
from betterproto.grpc.grpclib_server import ServiceBase
|
||||||
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
import grpclib.server
|
import grpclib.server
|
||||||
from betterproto.grpc.grpclib_client import MetadataLike
|
from betterproto.grpc.grpclib_client import MetadataLike
|
||||||
|
|||||||
@@ -5,19 +5,12 @@
|
|||||||
import warnings
|
import warnings
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import (
|
from typing import TYPE_CHECKING, AsyncIterator, Dict, List, Optional
|
||||||
TYPE_CHECKING,
|
|
||||||
AsyncIterator,
|
|
||||||
Dict,
|
|
||||||
List,
|
|
||||||
Optional,
|
|
||||||
)
|
|
||||||
|
|
||||||
import betterproto
|
import betterproto
|
||||||
import grpclib
|
import grpclib
|
||||||
from betterproto.grpc.grpclib_server import ServiceBase
|
from betterproto.grpc.grpclib_server import ServiceBase
|
||||||
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
import grpclib.server
|
import grpclib.server
|
||||||
from betterproto.grpc.grpclib_client import MetadataLike
|
from betterproto.grpc.grpclib_client import MetadataLike
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "pyasic"
|
name = "pyasic"
|
||||||
version = "0.61.6"
|
version = "0.62.4"
|
||||||
description = "A simplified and standardized interface for Bitcoin ASICs."
|
description = "A simplified and standardized interface for Bitcoin ASICs."
|
||||||
authors = ["UpstreamData <brett@upstreamdata.ca>"]
|
authors = ["UpstreamData <brett@upstreamdata.ca>"]
|
||||||
repository = "https://github.com/UpstreamData/pyasic"
|
repository = "https://github.com/UpstreamData/pyasic"
|
||||||
@@ -15,8 +15,8 @@ passlib = ">=1.7.4"
|
|||||||
pyaml = ">=23.12.0"
|
pyaml = ">=23.12.0"
|
||||||
tomli = { version = ">=2.0.1", python = "<3.11" }
|
tomli = { version = ">=2.0.1", python = "<3.11" }
|
||||||
tomli-w = "^1.0.0"
|
tomli-w = "^1.0.0"
|
||||||
betterproto = "2.0.0b7"
|
|
||||||
aiofiles = ">=23.2.1"
|
aiofiles = ">=23.2.1"
|
||||||
|
betterproto = "2.0.0b7"
|
||||||
|
|
||||||
[tool.poetry.group.dev]
|
[tool.poetry.group.dev]
|
||||||
optional = true
|
optional = true
|
||||||
|
|||||||
Reference in New Issue
Block a user