Compare commits
81 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
18931c4e98 | ||
|
|
8622c080aa | ||
|
|
cb71b2a593 | ||
|
|
ff5956da41 | ||
|
|
acdafc2efd | ||
|
|
b8874092ad | ||
|
|
ad28ba0b3e | ||
|
|
0d90b60eef | ||
|
|
7c18c9f69c | ||
|
|
975560f46f | ||
|
|
bfe9cbf7d9 | ||
|
|
ccb5eb73db | ||
|
|
d143667bd6 | ||
|
|
87d809abc0 | ||
|
|
4dc5b1a541 | ||
|
|
ddd3e867f9 | ||
|
|
77480d3d69 | ||
|
|
0767c93002 | ||
|
|
e690e6dd3b | ||
|
|
d4665ed768 | ||
|
|
b90a92c0df | ||
|
|
50cfcf9796 | ||
|
|
5d204f09da | ||
|
|
4c0410322f | ||
|
|
fbb2b3f6e7 | ||
|
|
0f09fb49fc | ||
|
|
b0d063d6ed | ||
|
|
a68fe70af4 | ||
|
|
43c7ac281b | ||
|
|
a97ae55a06 | ||
|
|
4a3a6f4186 | ||
|
|
f976724ada | ||
|
|
2632bdaa30 | ||
|
|
91016d7b8c | ||
|
|
2b00e741ca | ||
|
|
d496c11d67 | ||
|
|
5880223517 | ||
|
|
394a5dcd0d | ||
|
|
ed0d9f73e4 |
@@ -1,12 +1,15 @@
|
||||
ci:
|
||||
skip:
|
||||
- unittest
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.5.0
|
||||
rev: v5.0.0
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
- id: check-yaml
|
||||
- id: check-added-large-files
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 24.3.0
|
||||
rev: 24.10.0
|
||||
hooks:
|
||||
- id: black
|
||||
- repo: https://github.com/pycqa/isort
|
||||
@@ -24,4 +27,3 @@ repos:
|
||||
'types': [python]
|
||||
args: ["-p '*test.py'"] # Probably this option is absolutely not needed.
|
||||
pass_filenames: false
|
||||
stages: [commit]
|
||||
|
||||
@@ -8,3 +8,10 @@
|
||||
show_root_heading: false
|
||||
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
|
||||
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)
|
||||
::: pyasic.miners.antminer.vnish.X19.S19.VNishS19a
|
||||
handler: python
|
||||
|
||||
@@ -29,6 +29,13 @@
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## T21 (BOS+)
|
||||
::: pyasic.miners.antminer.bosminer.X21.T21.BOSMinerT21
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## S21 (VNish)
|
||||
::: pyasic.miners.antminer.vnish.X21.S21.VNishS21
|
||||
handler: python
|
||||
|
||||
@@ -22,6 +22,20 @@
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## KA3 (Stock)
|
||||
::: pyasic.miners.antminer.bmminer.X3.KA3.BMMinerKA3
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## KS3 (Stock)
|
||||
::: pyasic.miners.antminer.bmminer.X3.KS3.BMMinerKS3
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## L3+ (VNish)
|
||||
::: pyasic.miners.antminer.vnish.X3.L3.VnishL3Plus
|
||||
handler: python
|
||||
|
||||
@@ -8,3 +8,10 @@
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## KS5 (Stock)
|
||||
::: pyasic.miners.antminer.bmminer.X5.KS5.BMMinerKS5
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
|
||||
@@ -8,6 +8,13 @@
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## K7 (Stock)
|
||||
::: pyasic.miners.antminer.bmminer.X7.K7.BMMinerK7
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## L7 (VNish)
|
||||
::: pyasic.miners.antminer.vnish.X7.L7.VnishL7
|
||||
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
|
||||
|
||||
@@ -1,6 +1,20 @@
|
||||
# pyasic
|
||||
## KSX Models
|
||||
|
||||
## KS0 (Stock)
|
||||
::: pyasic.miners.iceriver.iceminer.KSX.KS0.IceRiverKS0
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## KS1 (Stock)
|
||||
::: pyasic.miners.iceriver.iceminer.KSX.KS1.IceRiverKS1
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## KS2 (Stock)
|
||||
::: pyasic.miners.iceriver.iceminer.KSX.KS2.IceRiverKS2
|
||||
handler: python
|
||||
@@ -8,3 +22,45 @@
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## KS3 (Stock)
|
||||
::: pyasic.miners.iceriver.iceminer.KSX.KS3.IceRiverKS3
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## KS3L (Stock)
|
||||
::: pyasic.miners.iceriver.iceminer.KSX.KS3.IceRiverKS3L
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## KS3M (Stock)
|
||||
::: pyasic.miners.iceriver.iceminer.KSX.KS3.IceRiverKS3M
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## 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
|
||||
|
||||
@@ -21,18 +21,22 @@ details {
|
||||
<li><a href="../antminer/X3#d3-stock">D3 (Stock)</a></li>
|
||||
<li><a href="../antminer/X3#hs3-stock">HS3 (Stock)</a></li>
|
||||
<li><a href="../antminer/X3#l3_1-stock">L3+ (Stock)</a></li>
|
||||
<li><a href="../antminer/X3#ka3-stock">KA3 (Stock)</a></li>
|
||||
<li><a href="../antminer/X3#ks3-stock">KS3 (Stock)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>X5 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X5#dr5-stock">DR5 (Stock)</a></li>
|
||||
<li><a href="../antminer/X5#ks5-stock">KS5 (Stock)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>X7 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X7#l7-stock">L7 (Stock)</a></li>
|
||||
<li><a href="../antminer/X7#k7-stock">K7 (Stock)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
@@ -49,6 +53,7 @@ details {
|
||||
<summary>X15 Series:</summary>
|
||||
<ul>
|
||||
<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>
|
||||
</details>
|
||||
<details>
|
||||
@@ -278,6 +283,7 @@ details {
|
||||
<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-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-vj20-stock">M50 VJ20 (Stock)</a></li>
|
||||
<li><a href="../whatsminer/M5X#m50-vj30-stock">M50 VJ30 (Stock)</a></li>
|
||||
@@ -378,6 +384,12 @@ details {
|
||||
<li><a href="../avalonminer/A12X#avalon-1246-stock">Avalon 1246 (Stock)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>nano Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../avalonminer/nano#avalon-nano-3-stock">Avalon Nano 3 (Stock)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
@@ -395,6 +407,13 @@ details {
|
||||
<li><a href="../innosilicon/A10X#a10x-stock">A10X (Stock)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>A11X Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../innosilicon/A11X#a11-stock">A11 (Stock)</a></li>
|
||||
<li><a href="../innosilicon/A11X#a11mx-stock">A11MX (Stock)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
@@ -470,6 +489,7 @@ details {
|
||||
<summary>X21 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X21#s21-bos_1">S21 (BOS+)</a></li>
|
||||
<li><a href="../antminer/X21#t21-bos_1">T21 (BOS+)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
@@ -505,6 +525,7 @@ details {
|
||||
<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-pro-vnish">S19j Pro (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#s19j-pro-vnish">S19j Pro (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#s19a-vnish">S19a (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#s19a-pro-vnish">S19a Pro (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#s19-pro-hydro-vnish">S19 Pro Hydro (VNish)</a></li>
|
||||
@@ -661,7 +682,15 @@ details {
|
||||
<details>
|
||||
<summary>KSX Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../iceriver/KSX#ks0-stock">KS0 (Stock)</a></li>
|
||||
<li><a href="../iceriver/KSX#ks1-stock">KS1 (Stock)</a></li>
|
||||
<li><a href="../iceriver/KSX#ks2-stock">KS2 (Stock)</a></li>
|
||||
<li><a href="../iceriver/KSX#ks3-stock">KS3 (Stock)</a></li>
|
||||
<li><a href="../iceriver/KSX#ks3l-stock">KS3L (Stock)</a></li>
|
||||
<li><a href="../iceriver/KSX#ks3m-stock">KS3M (Stock)</a></li>
|
||||
<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>
|
||||
</details>
|
||||
</ul>
|
||||
|
||||
@@ -71,6 +71,13 @@
|
||||
show_root_heading: false
|
||||
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)
|
||||
::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VJ10
|
||||
handler: python
|
||||
|
||||
386
poetry.lock
generated
386
poetry.lock
generated
@@ -1,4 +1,4 @@
|
||||
# This file is automatically @generated by Poetry 1.8.2 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]]
|
||||
name = "aiofiles"
|
||||
@@ -13,13 +13,13 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "anyio"
|
||||
version = "4.4.0"
|
||||
version = "4.6.2.post1"
|
||||
description = "High level compatibility layer for multiple asynchronous event loop implementations"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "anyio-4.4.0-py3-none-any.whl", hash = "sha256:c1b2d8f46a8a812513012e1107cb0e68c17159a7a594208005a57dc776e1bdc7"},
|
||||
{file = "anyio-4.4.0.tar.gz", hash = "sha256:5aadc6a1bbb7cdb0bede386cac5e2940f5e2ff3aa20277e991cf028e0585ce94"},
|
||||
{file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"},
|
||||
{file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -29,34 +29,19 @@ sniffio = ">=1.1"
|
||||
typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""}
|
||||
|
||||
[package.extras]
|
||||
doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"]
|
||||
test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"]
|
||||
trio = ["trio (>=0.23)"]
|
||||
|
||||
[[package]]
|
||||
name = "astunparse"
|
||||
version = "1.6.3"
|
||||
description = "An AST unparser for Python"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "astunparse-1.6.3-py2.py3-none-any.whl", hash = "sha256:c2652417f2c8b5bb325c885ae329bdf3f86424075c4fd1a128674bc6fba4b8e8"},
|
||||
{file = "astunparse-1.6.3.tar.gz", hash = "sha256:5ad93a8456f0d084c3456d059fd9a92cce667963232cbf763eac3bc5b7940872"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
six = ">=1.6.1,<2.0"
|
||||
wheel = ">=0.23.0,<1.0"
|
||||
doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"]
|
||||
test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"]
|
||||
trio = ["trio (>=0.26.1)"]
|
||||
|
||||
[[package]]
|
||||
name = "asyncssh"
|
||||
version = "2.17.0"
|
||||
version = "2.18.0"
|
||||
description = "AsyncSSH: Asynchronous SSHv2 client and server library"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "asyncssh-2.17.0-py3-none-any.whl", hash = "sha256:70bfe4081793255b0115f7a72efd92d5bad8562639302531223bb00188db9747"},
|
||||
{file = "asyncssh-2.17.0.tar.gz", hash = "sha256:3b159c105aa388c1e2245c4faf483f540ada8cad99402281119100166e5edb3c"},
|
||||
{file = "asyncssh-2.18.0-py3-none-any.whl", hash = "sha256:ee09081200753eca137c893995ce3b95f8e157945aa8bda455ea810b30762d96"},
|
||||
{file = "asyncssh-2.18.0.tar.gz", hash = "sha256:1a322161c01f60b9719dc8f39f80db71e61f3f5e04abbc3420ce503126d87123"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -74,21 +59,23 @@ pywin32 = ["pywin32 (>=227)"]
|
||||
|
||||
[[package]]
|
||||
name = "betterproto"
|
||||
version = "2.0.0b6"
|
||||
version = "2.0.0b7"
|
||||
description = "A better Protobuf / gRPC generator & library"
|
||||
optional = false
|
||||
python-versions = ">=3.7,<4.0"
|
||||
python-versions = "<4.0,>=3.7"
|
||||
files = [
|
||||
{file = "betterproto-2.0.0b6-py3-none-any.whl", hash = "sha256:a0839ec165d110a69d0d116f4d0e2bec8d186af4db826257931f0831dab73fcf"},
|
||||
{file = "betterproto-2.0.0b6.tar.gz", hash = "sha256:720ae92697000f6fcf049c69267d957f0871654c8b0d7458906607685daee784"},
|
||||
{file = "betterproto-2.0.0b7-py3-none-any.whl", hash = "sha256:401ab8055e2f814e77b9c88a74d0e1ae3d1e8a969cced6aeb1b59f71ad63fbd2"},
|
||||
{file = "betterproto-2.0.0b7.tar.gz", hash = "sha256:1b1458ca5278d519bcd62556a4c236f998a91d503f0f71c67b0b954747052af2"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
grpclib = ">=0.4.1,<0.5.0"
|
||||
python-dateutil = ">=2.8,<3.0"
|
||||
typing-extensions = ">=4.7.1,<5.0.0"
|
||||
|
||||
[package.extras]
|
||||
compiler = ["black (>=19.3b0)", "isort (>=5.11.5,<6.0.0)", "jinja2 (>=3.0.3)"]
|
||||
compiler = ["black (>=23.1.0)", "isort (>=5.11.5,<6.0.0)", "jinja2 (>=3.0.3)"]
|
||||
rust-codec = ["betterproto-rust-codec (==0.1.1)"]
|
||||
|
||||
[[package]]
|
||||
name = "certifi"
|
||||
@@ -218,38 +205,38 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "cryptography"
|
||||
version = "43.0.1"
|
||||
version = "43.0.3"
|
||||
description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "cryptography-43.0.1-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:8385d98f6a3bf8bb2d65a73e17ed87a3ba84f6991c155691c51112075f9ffc5d"},
|
||||
{file = "cryptography-43.0.1-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27e613d7077ac613e399270253259d9d53872aaf657471473ebfc9a52935c062"},
|
||||
{file = "cryptography-43.0.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68aaecc4178e90719e95298515979814bda0cbada1256a4485414860bd7ab962"},
|
||||
{file = "cryptography-43.0.1-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:de41fd81a41e53267cb020bb3a7212861da53a7d39f863585d13ea11049cf277"},
|
||||
{file = "cryptography-43.0.1-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f98bf604c82c416bc829e490c700ca1553eafdf2912a91e23a79d97d9801372a"},
|
||||
{file = "cryptography-43.0.1-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:61ec41068b7b74268fa86e3e9e12b9f0c21fcf65434571dbb13d954bceb08042"},
|
||||
{file = "cryptography-43.0.1-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:014f58110f53237ace6a408b5beb6c427b64e084eb451ef25a28308270086494"},
|
||||
{file = "cryptography-43.0.1-cp37-abi3-win32.whl", hash = "sha256:2bd51274dcd59f09dd952afb696bf9c61a7a49dfc764c04dd33ef7a6b502a1e2"},
|
||||
{file = "cryptography-43.0.1-cp37-abi3-win_amd64.whl", hash = "sha256:666ae11966643886c2987b3b721899d250855718d6d9ce41b521252a17985f4d"},
|
||||
{file = "cryptography-43.0.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:ac119bb76b9faa00f48128b7f5679e1d8d437365c5d26f1c2c3f0da4ce1b553d"},
|
||||
{file = "cryptography-43.0.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bbcce1a551e262dfbafb6e6252f1ae36a248e615ca44ba302df077a846a8806"},
|
||||
{file = "cryptography-43.0.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58d4e9129985185a06d849aa6df265bdd5a74ca6e1b736a77959b498e0505b85"},
|
||||
{file = "cryptography-43.0.1-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:d03a475165f3134f773d1388aeb19c2d25ba88b6a9733c5c590b9ff7bbfa2e0c"},
|
||||
{file = "cryptography-43.0.1-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:511f4273808ab590912a93ddb4e3914dfd8a388fed883361b02dea3791f292e1"},
|
||||
{file = "cryptography-43.0.1-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:80eda8b3e173f0f247f711eef62be51b599b5d425c429b5d4ca6a05e9e856baa"},
|
||||
{file = "cryptography-43.0.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:38926c50cff6f533f8a2dae3d7f19541432610d114a70808f0926d5aaa7121e4"},
|
||||
{file = "cryptography-43.0.1-cp39-abi3-win32.whl", hash = "sha256:a575913fb06e05e6b4b814d7f7468c2c660e8bb16d8d5a1faf9b33ccc569dd47"},
|
||||
{file = "cryptography-43.0.1-cp39-abi3-win_amd64.whl", hash = "sha256:d75601ad10b059ec832e78823b348bfa1a59f6b8d545db3a24fd44362a1564cb"},
|
||||
{file = "cryptography-43.0.1-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ea25acb556320250756e53f9e20a4177515f012c9eaea17eb7587a8c4d8ae034"},
|
||||
{file = "cryptography-43.0.1-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c1332724be35d23a854994ff0b66530119500b6053d0bd3363265f7e5e77288d"},
|
||||
{file = "cryptography-43.0.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:fba1007b3ef89946dbbb515aeeb41e30203b004f0b4b00e5e16078b518563289"},
|
||||
{file = "cryptography-43.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5b43d1ea6b378b54a1dc99dd8a2b5be47658fe9a7ce0a58ff0b55f4b43ef2b84"},
|
||||
{file = "cryptography-43.0.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:88cce104c36870d70c49c7c8fd22885875d950d9ee6ab54df2745f83ba0dc365"},
|
||||
{file = "cryptography-43.0.1-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:9d3cdb25fa98afdd3d0892d132b8d7139e2c087da1712041f6b762e4f807cc96"},
|
||||
{file = "cryptography-43.0.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e710bf40870f4db63c3d7d929aa9e09e4e7ee219e703f949ec4073b4294f6172"},
|
||||
{file = "cryptography-43.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7c05650fe8023c5ed0d46793d4b7d7e6cd9c04e68eabe5b0aeea836e37bdcec2"},
|
||||
{file = "cryptography-43.0.1.tar.gz", hash = "sha256:203e92a75716d8cfb491dc47c79e17d0d9207ccffcbcb35f598fbe463ae3444d"},
|
||||
{file = "cryptography-43.0.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e"},
|
||||
{file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e"},
|
||||
{file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f"},
|
||||
{file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6"},
|
||||
{file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18"},
|
||||
{file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd"},
|
||||
{file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73"},
|
||||
{file = "cryptography-43.0.3-cp37-abi3-win32.whl", hash = "sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2"},
|
||||
{file = "cryptography-43.0.3-cp37-abi3-win_amd64.whl", hash = "sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd"},
|
||||
{file = "cryptography-43.0.3-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984"},
|
||||
{file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5"},
|
||||
{file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4"},
|
||||
{file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7"},
|
||||
{file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405"},
|
||||
{file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16"},
|
||||
{file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73"},
|
||||
{file = "cryptography-43.0.3-cp39-abi3-win32.whl", hash = "sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995"},
|
||||
{file = "cryptography-43.0.3-cp39-abi3-win_amd64.whl", hash = "sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362"},
|
||||
{file = "cryptography-43.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d03b5621a135bffecad2c73e9f4deb1a0f977b9a8ffe6f8e002bf6c9d07b918c"},
|
||||
{file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a2a431ee15799d6db9fe80c82b055bae5a752bef645bba795e8e52687c69efe3"},
|
||||
{file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:281c945d0e28c92ca5e5930664c1cefd85efe80e5c0d2bc58dd63383fda29f83"},
|
||||
{file = "cryptography-43.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:f18c716be16bc1fea8e95def49edf46b82fccaa88587a45f8dc0ff6ab5d8e0a7"},
|
||||
{file = "cryptography-43.0.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4a02ded6cd4f0a5562a8887df8b3bd14e822a90f97ac5e544c162899bc467664"},
|
||||
{file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:53a583b6637ab4c4e3591a15bc9db855b8d9dee9a669b550f311480acab6eb08"},
|
||||
{file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1ec0bcf7e17c0c5669d881b1cd38c4972fade441b27bda1051665faaa89bdcaa"},
|
||||
{file = "cryptography-43.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2ce6fae5bdad59577b44e4dfed356944fbf1d925269114c28be377692643b4ff"},
|
||||
{file = "cryptography-43.0.3.tar.gz", hash = "sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -262,18 +249,18 @@ nox = ["nox"]
|
||||
pep8test = ["check-sdist", "click", "mypy", "ruff"]
|
||||
sdist = ["build"]
|
||||
ssh = ["bcrypt (>=3.1.5)"]
|
||||
test = ["certifi", "cryptography-vectors (==43.0.1)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"]
|
||||
test = ["certifi", "cryptography-vectors (==43.0.3)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"]
|
||||
test-randomorder = ["pytest-randomly"]
|
||||
|
||||
[[package]]
|
||||
name = "distlib"
|
||||
version = "0.3.8"
|
||||
version = "0.3.9"
|
||||
description = "Distribution utilities"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "distlib-0.3.8-py2.py3-none-any.whl", hash = "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784"},
|
||||
{file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"},
|
||||
{file = "distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87"},
|
||||
{file = "distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -325,17 +312,16 @@ dev = ["flake8", "markdown", "twine", "wheel"]
|
||||
|
||||
[[package]]
|
||||
name = "griffe"
|
||||
version = "1.3.1"
|
||||
version = "1.5.1"
|
||||
description = "Signatures for entire Python programs. Extract the structure, the frame, the skeleton of your project, to generate API documentation or find breaking changes in your API."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "griffe-1.3.1-py3-none-any.whl", hash = "sha256:940aeb630bc3054b4369567f150b6365be6f11eef46b0ed8623aea96e6d17b19"},
|
||||
{file = "griffe-1.3.1.tar.gz", hash = "sha256:3f86a716b631a4c0f96a43cb75d05d3c85975003c20540426c0eba3b0581c56a"},
|
||||
{file = "griffe-1.5.1-py3-none-any.whl", hash = "sha256:ad6a7980f8c424c9102160aafa3bcdf799df0e75f7829d75af9ee5aef656f860"},
|
||||
{file = "griffe-1.5.1.tar.gz", hash = "sha256:72964f93e08c553257706d6cd2c42d1c172213feb48b2be386f243380b405d4b"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
astunparse = {version = ">=1.6", markers = "python_version < \"3.9\""}
|
||||
colorama = ">=0.4"
|
||||
|
||||
[[package]]
|
||||
@@ -394,13 +380,13 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "httpcore"
|
||||
version = "1.0.5"
|
||||
version = "1.0.6"
|
||||
description = "A minimal low-level HTTP client."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "httpcore-1.0.5-py3-none-any.whl", hash = "sha256:421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5"},
|
||||
{file = "httpcore-1.0.5.tar.gz", hash = "sha256:34a38e2f9291467ee3b44e89dd52615370e152954ba21721378a87b2960f7a61"},
|
||||
{file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"},
|
||||
{file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -411,7 +397,7 @@ h11 = ">=0.13,<0.15"
|
||||
asyncio = ["anyio (>=4.0,<5.0)"]
|
||||
http2 = ["h2 (>=3,<5)"]
|
||||
socks = ["socksio (==1.*)"]
|
||||
trio = ["trio (>=0.22.0,<0.26.0)"]
|
||||
trio = ["trio (>=0.22.0,<1.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "httpx"
|
||||
@@ -551,71 +537,72 @@ testing = ["coverage", "pyyaml"]
|
||||
|
||||
[[package]]
|
||||
name = "markupsafe"
|
||||
version = "2.1.5"
|
||||
version = "3.0.2"
|
||||
description = "Safely add untrusted strings to HTML/XML markup."
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"},
|
||||
{file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"},
|
||||
{file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"},
|
||||
{file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"},
|
||||
{file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"},
|
||||
{file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"},
|
||||
{file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"},
|
||||
{file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"},
|
||||
{file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"},
|
||||
{file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"},
|
||||
{file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"},
|
||||
{file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"},
|
||||
{file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"},
|
||||
{file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"},
|
||||
{file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"},
|
||||
{file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"},
|
||||
{file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"},
|
||||
{file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"},
|
||||
{file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"},
|
||||
{file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"},
|
||||
{file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"},
|
||||
{file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"},
|
||||
{file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"},
|
||||
{file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"},
|
||||
{file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"},
|
||||
{file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"},
|
||||
{file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"},
|
||||
{file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"},
|
||||
{file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"},
|
||||
{file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"},
|
||||
{file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"},
|
||||
{file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"},
|
||||
{file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"},
|
||||
{file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"},
|
||||
{file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"},
|
||||
{file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"},
|
||||
{file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"},
|
||||
{file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"},
|
||||
{file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"},
|
||||
{file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"},
|
||||
{file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"},
|
||||
{file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"},
|
||||
{file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"},
|
||||
{file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"},
|
||||
{file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"},
|
||||
{file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"},
|
||||
{file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"},
|
||||
{file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"},
|
||||
{file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"},
|
||||
{file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"},
|
||||
{file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"},
|
||||
{file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"},
|
||||
{file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"},
|
||||
{file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"},
|
||||
{file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"},
|
||||
{file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"},
|
||||
{file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"},
|
||||
{file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"},
|
||||
{file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"},
|
||||
{file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"},
|
||||
{file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"},
|
||||
{file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"},
|
||||
{file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"},
|
||||
{file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"},
|
||||
{file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"},
|
||||
{file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"},
|
||||
{file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"},
|
||||
{file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"},
|
||||
{file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"},
|
||||
{file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"},
|
||||
{file = "MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d"},
|
||||
{file = "MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93"},
|
||||
{file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832"},
|
||||
{file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84"},
|
||||
{file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca"},
|
||||
{file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798"},
|
||||
{file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e"},
|
||||
{file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4"},
|
||||
{file = "MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d"},
|
||||
{file = "MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b"},
|
||||
{file = "MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf"},
|
||||
{file = "MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225"},
|
||||
{file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028"},
|
||||
{file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8"},
|
||||
{file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c"},
|
||||
{file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557"},
|
||||
{file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22"},
|
||||
{file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48"},
|
||||
{file = "MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30"},
|
||||
{file = "MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"},
|
||||
{file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"},
|
||||
{file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"},
|
||||
{file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"},
|
||||
{file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"},
|
||||
{file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"},
|
||||
{file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"},
|
||||
{file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"},
|
||||
{file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"},
|
||||
{file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"},
|
||||
{file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"},
|
||||
{file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -905,13 +892,13 @@ type = ["mypy (>=1.11.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "pre-commit"
|
||||
version = "3.5.0"
|
||||
version = "4.0.1"
|
||||
description = "A framework for managing and maintaining multi-language pre-commit hooks."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "pre_commit-3.5.0-py2.py3-none-any.whl", hash = "sha256:841dc9aef25daba9a0238cd27984041fa0467b4199fc4852e27950664919f660"},
|
||||
{file = "pre_commit-3.5.0.tar.gz", hash = "sha256:5804465c675b659b0862f07907f96295d490822a450c4c40e747d0b1c6ebcb32"},
|
||||
{file = "pre_commit-4.0.1-py2.py3-none-any.whl", hash = "sha256:efde913840816312445dc98787724647c65473daefe420785f885e8ed9a06878"},
|
||||
{file = "pre_commit-4.0.1.tar.gz", hash = "sha256:80905ac375958c0444c65e9cebebd948b3cdb518f335a091a670a89d652139d2"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -923,13 +910,13 @@ virtualenv = ">=20.10.0"
|
||||
|
||||
[[package]]
|
||||
name = "pyaml"
|
||||
version = "24.7.0"
|
||||
version = "24.9.0"
|
||||
description = "PyYAML-based module to produce a bit more pretty and readable YAML-serialized data"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pyaml-24.7.0-py3-none-any.whl", hash = "sha256:6b06596cb5ac438a3fad1e1bf5775088c4d3afb927e2b03a29305d334835deb2"},
|
||||
{file = "pyaml-24.7.0.tar.gz", hash = "sha256:5d0fdf9e681036fb263a783d0298fc3af580a6e2a6cf1a3314ffc48dc3d91ccb"},
|
||||
{file = "pyaml-24.9.0-py3-none-any.whl", hash = "sha256:31080551502f1014852b3c966a96c796adc79b4cf86e165f28ed83455bf19c62"},
|
||||
{file = "pyaml-24.9.0.tar.gz", hash = "sha256:e78dee8b0d4fed56bb9fa11a8a7858e6fade1ec70a9a122cee6736efac3e69b5"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -951,13 +938,13 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "pymdown-extensions"
|
||||
version = "10.9"
|
||||
version = "10.12"
|
||||
description = "Extension pack for Python Markdown."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pymdown_extensions-10.9-py3-none-any.whl", hash = "sha256:d323f7e90d83c86113ee78f3fe62fc9dee5f56b54d912660703ea1816fed5626"},
|
||||
{file = "pymdown_extensions-10.9.tar.gz", hash = "sha256:6ff740bcd99ec4172a938970d42b96128bdc9d4b9bcad72494f29921dc69b753"},
|
||||
{file = "pymdown_extensions-10.12-py3-none-any.whl", hash = "sha256:49f81412242d3527b8b4967b990df395c89563043bc51a3d2d7d500e52123b77"},
|
||||
{file = "pymdown_extensions-10.12.tar.gz", hash = "sha256:b0ee1e0b2bef1071a47891ab17003bfe5bf824a398e13f49f8ed653b699369a7"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -1081,24 +1068,24 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "tomli"
|
||||
version = "2.0.1"
|
||||
version = "2.0.2"
|
||||
description = "A lil' TOML parser"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
|
||||
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
|
||||
{file = "tomli-2.0.2-py3-none-any.whl", hash = "sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38"},
|
||||
{file = "tomli-2.0.2.tar.gz", hash = "sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tomli-w"
|
||||
version = "1.0.0"
|
||||
version = "1.1.0"
|
||||
description = "A lil' TOML writer"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "tomli_w-1.0.0-py3-none-any.whl", hash = "sha256:9f2a07e8be30a0729e533ec968016807069991ae2fd921a78d42f429ae5f4463"},
|
||||
{file = "tomli_w-1.0.0.tar.gz", hash = "sha256:f463434305e0336248cac9c2dc8076b707d8a12d019dd349f5c1e382dd1ae1b9"},
|
||||
{file = "tomli_w-1.1.0-py3-none-any.whl", hash = "sha256:1403179c78193e3184bfaade390ddbd071cba48a32a2e62ba11aae47490c63f7"},
|
||||
{file = "tomli_w-1.1.0.tar.gz", hash = "sha256:49e847a3a304d516a169a601184932ef0f6b61623fe680f836a2aa7128ed0d33"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1114,13 +1101,13 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "virtualenv"
|
||||
version = "20.26.5"
|
||||
version = "20.27.1"
|
||||
description = "Virtual Python Environment builder"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "virtualenv-20.26.5-py3-none-any.whl", hash = "sha256:4f3ac17b81fba3ce3bd6f4ead2749a72da5929c01774948e243db9ba41df4ff6"},
|
||||
{file = "virtualenv-20.26.5.tar.gz", hash = "sha256:ce489cac131aa58f4b25e321d6d186171f78e6cb13fafbf32a840cee67733ff4"},
|
||||
{file = "virtualenv-20.27.1-py3-none-any.whl", hash = "sha256:f11f1b8a29525562925f745563bfd48b189450f61fb34c4f9cc79dd5aa32a1f4"},
|
||||
{file = "virtualenv-20.27.1.tar.gz", hash = "sha256:142c6be10212543b32c6c45d3d3893dff89112cc588b7d0879ae5a1ec03a47ba"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -1134,65 +1121,46 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess
|
||||
|
||||
[[package]]
|
||||
name = "watchdog"
|
||||
version = "4.0.2"
|
||||
version = "6.0.0"
|
||||
description = "Filesystem events monitoring"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "watchdog-4.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ede7f010f2239b97cc79e6cb3c249e72962404ae3865860855d5cbe708b0fd22"},
|
||||
{file = "watchdog-4.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a2cffa171445b0efa0726c561eca9a27d00a1f2b83846dbd5a4f639c4f8ca8e1"},
|
||||
{file = "watchdog-4.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c50f148b31b03fbadd6d0b5980e38b558046b127dc483e5e4505fcef250f9503"},
|
||||
{file = "watchdog-4.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7c7d4bf585ad501c5f6c980e7be9c4f15604c7cc150e942d82083b31a7548930"},
|
||||
{file = "watchdog-4.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:914285126ad0b6eb2258bbbcb7b288d9dfd655ae88fa28945be05a7b475a800b"},
|
||||
{file = "watchdog-4.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:984306dc4720da5498b16fc037b36ac443816125a3705dfde4fd90652d8028ef"},
|
||||
{file = "watchdog-4.0.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1cdcfd8142f604630deef34722d695fb455d04ab7cfe9963055df1fc69e6727a"},
|
||||
{file = "watchdog-4.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d7ab624ff2f663f98cd03c8b7eedc09375a911794dfea6bf2a359fcc266bff29"},
|
||||
{file = "watchdog-4.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:132937547a716027bd5714383dfc40dc66c26769f1ce8a72a859d6a48f371f3a"},
|
||||
{file = "watchdog-4.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:cd67c7df93eb58f360c43802acc945fa8da70c675b6fa37a241e17ca698ca49b"},
|
||||
{file = "watchdog-4.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:bcfd02377be80ef3b6bc4ce481ef3959640458d6feaae0bd43dd90a43da90a7d"},
|
||||
{file = "watchdog-4.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:980b71510f59c884d684b3663d46e7a14b457c9611c481e5cef08f4dd022eed7"},
|
||||
{file = "watchdog-4.0.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:aa160781cafff2719b663c8a506156e9289d111d80f3387cf3af49cedee1f040"},
|
||||
{file = "watchdog-4.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f6ee8dedd255087bc7fe82adf046f0b75479b989185fb0bdf9a98b612170eac7"},
|
||||
{file = "watchdog-4.0.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0b4359067d30d5b864e09c8597b112fe0a0a59321a0f331498b013fb097406b4"},
|
||||
{file = "watchdog-4.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:770eef5372f146997638d737c9a3c597a3b41037cfbc5c41538fc27c09c3a3f9"},
|
||||
{file = "watchdog-4.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:eeea812f38536a0aa859972d50c76e37f4456474b02bd93674d1947cf1e39578"},
|
||||
{file = "watchdog-4.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b2c45f6e1e57ebb4687690c05bc3a2c1fb6ab260550c4290b8abb1335e0fd08b"},
|
||||
{file = "watchdog-4.0.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:10b6683df70d340ac3279eff0b2766813f00f35a1d37515d2c99959ada8f05fa"},
|
||||
{file = "watchdog-4.0.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:f7c739888c20f99824f7aa9d31ac8a97353e22d0c0e54703a547a218f6637eb3"},
|
||||
{file = "watchdog-4.0.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c100d09ac72a8a08ddbf0629ddfa0b8ee41740f9051429baa8e31bb903ad7508"},
|
||||
{file = "watchdog-4.0.2-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:f5315a8c8dd6dd9425b974515081fc0aadca1d1d61e078d2246509fd756141ee"},
|
||||
{file = "watchdog-4.0.2-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:2d468028a77b42cc685ed694a7a550a8d1771bb05193ba7b24006b8241a571a1"},
|
||||
{file = "watchdog-4.0.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:f15edcae3830ff20e55d1f4e743e92970c847bcddc8b7509bcd172aa04de506e"},
|
||||
{file = "watchdog-4.0.2-py3-none-manylinux2014_aarch64.whl", hash = "sha256:936acba76d636f70db8f3c66e76aa6cb5136a936fc2a5088b9ce1c7a3508fc83"},
|
||||
{file = "watchdog-4.0.2-py3-none-manylinux2014_armv7l.whl", hash = "sha256:e252f8ca942a870f38cf785aef420285431311652d871409a64e2a0a52a2174c"},
|
||||
{file = "watchdog-4.0.2-py3-none-manylinux2014_i686.whl", hash = "sha256:0e83619a2d5d436a7e58a1aea957a3c1ccbf9782c43c0b4fed80580e5e4acd1a"},
|
||||
{file = "watchdog-4.0.2-py3-none-manylinux2014_ppc64.whl", hash = "sha256:88456d65f207b39f1981bf772e473799fcdc10801062c36fd5ad9f9d1d463a73"},
|
||||
{file = "watchdog-4.0.2-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:32be97f3b75693a93c683787a87a0dc8db98bb84701539954eef991fb35f5fbc"},
|
||||
{file = "watchdog-4.0.2-py3-none-manylinux2014_s390x.whl", hash = "sha256:c82253cfc9be68e3e49282831afad2c1f6593af80c0daf1287f6a92657986757"},
|
||||
{file = "watchdog-4.0.2-py3-none-manylinux2014_x86_64.whl", hash = "sha256:c0b14488bd336c5b1845cee83d3e631a1f8b4e9c5091ec539406e4a324f882d8"},
|
||||
{file = "watchdog-4.0.2-py3-none-win32.whl", hash = "sha256:0d8a7e523ef03757a5aa29f591437d64d0d894635f8a50f370fe37f913ce4e19"},
|
||||
{file = "watchdog-4.0.2-py3-none-win_amd64.whl", hash = "sha256:c344453ef3bf875a535b0488e3ad28e341adbd5a9ffb0f7d62cefacc8824ef2b"},
|
||||
{file = "watchdog-4.0.2-py3-none-win_ia64.whl", hash = "sha256:baececaa8edff42cd16558a639a9b0ddf425f93d892e8392a56bf904f5eff22c"},
|
||||
{file = "watchdog-4.0.2.tar.gz", hash = "sha256:b4dfbb6c49221be4535623ea4474a4d6ee0a9cef4a80b20c28db4d858b64e270"},
|
||||
{file = "watchdog-6.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d1cdb490583ebd691c012b3d6dae011000fe42edb7a82ece80965b42abd61f26"},
|
||||
{file = "watchdog-6.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bc64ab3bdb6a04d69d4023b29422170b74681784ffb9463ed4870cf2f3e66112"},
|
||||
{file = "watchdog-6.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c897ac1b55c5a1461e16dae288d22bb2e412ba9807df8397a635d88f671d36c3"},
|
||||
{file = "watchdog-6.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6eb11feb5a0d452ee41f824e271ca311a09e250441c262ca2fd7ebcf2461a06c"},
|
||||
{file = "watchdog-6.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ef810fbf7b781a5a593894e4f439773830bdecb885e6880d957d5b9382a960d2"},
|
||||
{file = "watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:afd0fe1b2270917c5e23c2a65ce50c2a4abb63daafb0d419fde368e272a76b7c"},
|
||||
{file = "watchdog-6.0.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdd4e6f14b8b18c334febb9c4425a878a2ac20efd1e0b231978e7b150f92a948"},
|
||||
{file = "watchdog-6.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c7c15dda13c4eb00d6fb6fc508b3c0ed88b9d5d374056b239c4ad1611125c860"},
|
||||
{file = "watchdog-6.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f10cb2d5902447c7d0da897e2c6768bca89174d0c6e1e30abec5421af97a5b0"},
|
||||
{file = "watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c"},
|
||||
{file = "watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134"},
|
||||
{file = "watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b"},
|
||||
{file = "watchdog-6.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e6f0e77c9417e7cd62af82529b10563db3423625c5fce018430b249bf977f9e8"},
|
||||
{file = "watchdog-6.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:90c8e78f3b94014f7aaae121e6b909674df5b46ec24d6bebc45c44c56729af2a"},
|
||||
{file = "watchdog-6.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e7631a77ffb1f7d2eefa4445ebbee491c720a5661ddf6df3498ebecae5ed375c"},
|
||||
{file = "watchdog-6.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:c7ac31a19f4545dd92fc25d200694098f42c9a8e391bc00bdd362c5736dbf881"},
|
||||
{file = "watchdog-6.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9513f27a1a582d9808cf21a07dae516f0fab1cf2d7683a742c498b93eedabb11"},
|
||||
{file = "watchdog-6.0.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7a0e56874cfbc4b9b05c60c8a1926fedf56324bb08cfbc188969777940aef3aa"},
|
||||
{file = "watchdog-6.0.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:e6439e374fc012255b4ec786ae3c4bc838cd7309a540e5fe0952d03687d8804e"},
|
||||
{file = "watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13"},
|
||||
{file = "watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379"},
|
||||
{file = "watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e"},
|
||||
{file = "watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f"},
|
||||
{file = "watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26"},
|
||||
{file = "watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c"},
|
||||
{file = "watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2"},
|
||||
{file = "watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a"},
|
||||
{file = "watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680"},
|
||||
{file = "watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f"},
|
||||
{file = "watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
watchmedo = ["PyYAML (>=3.10)"]
|
||||
|
||||
[[package]]
|
||||
name = "wheel"
|
||||
version = "0.44.0"
|
||||
description = "A built-package format for Python"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "wheel-0.44.0-py3-none-any.whl", hash = "sha256:2376a90c98cc337d18623527a97c31797bd02bad0033d41547043a1cbfbe448f"},
|
||||
{file = "wheel-0.44.0.tar.gz", hash = "sha256:a29c3f2817e95ab89aa4660681ad547c0e9547f20e75b0562fe7723c9a2a9d49"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
test = ["pytest (>=6.0.0)", "setuptools (>=65)"]
|
||||
|
||||
[[package]]
|
||||
name = "zipp"
|
||||
version = "3.20.2"
|
||||
@@ -1214,5 +1182,5 @@ type = ["pytest-mypy"]
|
||||
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.8"
|
||||
content-hash = "51d647f366f503b12875684f3add9df7757111167fd1dac0fdef0a3ab710756a"
|
||||
python-versions = "^3.9"
|
||||
content-hash = "d611b5e8b0c5611d6ee916cedfb7f07f20dfc90a675ebaed04188e8b3c96aabe"
|
||||
|
||||
@@ -148,6 +148,14 @@ class MinerConfig:
|
||||
**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
|
||||
def from_dict(cls, dict_conf: dict) -> "MinerConfig":
|
||||
"""Constructs a MinerConfig object from a dictionary."""
|
||||
@@ -250,3 +258,21 @@ class MinerConfig:
|
||||
pools=PoolConfig.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:
|
||||
return self.value.as_bitaxe()
|
||||
|
||||
def as_luxos(self) -> dict:
|
||||
return self.value.as_luxos()
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
return self.value(*args, **kwargs)
|
||||
|
||||
@@ -125,6 +128,9 @@ class MinerConfigValue:
|
||||
def as_bitaxe(self) -> dict:
|
||||
return {}
|
||||
|
||||
def as_luxos(self) -> dict:
|
||||
return {}
|
||||
|
||||
def __getitem__(self, item):
|
||||
try:
|
||||
return getattr(self, item)
|
||||
|
||||
@@ -83,6 +83,9 @@ class FanModeNormal(MinerConfigValue):
|
||||
def as_bitaxe(self) -> dict:
|
||||
return {"autoFanspeed": 1}
|
||||
|
||||
def as_luxos(self) -> dict:
|
||||
return {"fanset": {"speed": -1, "min_fans": self.minimum_fans}}
|
||||
|
||||
|
||||
@dataclass
|
||||
class FanModeManual(MinerConfigValue):
|
||||
@@ -144,6 +147,9 @@ class FanModeManual(MinerConfigValue):
|
||||
def as_bitaxe(self) -> dict:
|
||||
return {"autoFanspeed": 0, "fanspeed": self.speed}
|
||||
|
||||
def as_luxos(self) -> dict:
|
||||
return {"fanset": {"speed": self.speed, "min_fans": self.minimum_fans}}
|
||||
|
||||
|
||||
@dataclass
|
||||
class FanModeImmersion(MinerConfigValue):
|
||||
@@ -167,6 +173,9 @@ class FanModeImmersion(MinerConfigValue):
|
||||
def as_mara(self) -> dict:
|
||||
return {"general-config": {"environment-profile": "OilImmersionCooling"}}
|
||||
|
||||
def as_luxos(self) -> dict:
|
||||
return {"fanset": {"speed": 0, "min_fans": 0}}
|
||||
|
||||
|
||||
class FanModeConfig(MinerConfigOption):
|
||||
normal = FanModeNormal
|
||||
@@ -304,3 +313,23 @@ class FanModeConfig(MinerConfigOption):
|
||||
return cls.normal()
|
||||
else:
|
||||
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
|
||||
class MiningModeSleep(MinerConfigValue):
|
||||
@@ -198,7 +201,7 @@ class MiningModePowerTune(MinerConfigValue):
|
||||
def as_boser(self) -> dict:
|
||||
cfg = {
|
||||
"set_performance_mode": SetPerformanceModeRequest(
|
||||
save_action=SaveAction.SAVE_ACTION_SAVE_AND_APPLY,
|
||||
save_action=SaveAction.SAVE_AND_APPLY,
|
||||
mode=PerformanceMode(
|
||||
tuner_mode=TunerPerformanceMode(
|
||||
power_target=PowerTargetMode(
|
||||
@@ -240,6 +243,9 @@ class MiningModePowerTune(MinerConfigValue):
|
||||
}
|
||||
}
|
||||
|
||||
def as_luxos(self) -> dict:
|
||||
return {"autotunerset": {"enabled": True}}
|
||||
|
||||
|
||||
@dataclass
|
||||
class MiningModeHashrateTune(MinerConfigValue):
|
||||
@@ -275,7 +281,7 @@ class MiningModeHashrateTune(MinerConfigValue):
|
||||
def as_boser(self) -> dict:
|
||||
cfg = {
|
||||
"set_performance_mode": SetPerformanceModeRequest(
|
||||
save_action=SaveAction.SAVE_ACTION_SAVE_AND_APPLY,
|
||||
save_action=SaveAction.SAVE_AND_APPLY,
|
||||
mode=PerformanceMode(
|
||||
tuner_mode=TunerPerformanceMode(
|
||||
hashrate_target=HashrateTargetMode(
|
||||
@@ -333,6 +339,9 @@ class MiningModeHashrateTune(MinerConfigValue):
|
||||
}
|
||||
}
|
||||
|
||||
def as_luxos(self) -> dict:
|
||||
return {"autotunerset": {"enabled": True}}
|
||||
|
||||
|
||||
@dataclass
|
||||
class ManualBoardSettings(MinerConfigValue):
|
||||
|
||||
@@ -222,6 +222,18 @@ class Pool(MinerConfigValue):
|
||||
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
|
||||
class PoolGroup(MinerConfigValue):
|
||||
@@ -402,6 +414,15 @@ class PoolGroup(MinerConfigValue):
|
||||
def from_bitaxe(cls, web_system_info: dict) -> "PoolGroup":
|
||||
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
|
||||
class PoolConfig(MinerConfigValue):
|
||||
@@ -467,7 +488,7 @@ class PoolConfig(MinerConfigValue):
|
||||
def as_boser(self, user_suffix: str = None) -> dict:
|
||||
return {
|
||||
"set_pool_groups": SetPoolGroupsRequest(
|
||||
save_action=SaveAction.SAVE_ACTION_SAVE_AND_APPLY,
|
||||
save_action=SaveAction.SAVE_AND_APPLY,
|
||||
pool_groups=[g.as_boser(user_suffix=user_suffix) for g in self.groups],
|
||||
)
|
||||
}
|
||||
@@ -506,6 +527,9 @@ class PoolConfig(MinerConfigValue):
|
||||
def as_bitaxe(self, user_suffix: str = None) -> dict:
|
||||
return self.groups[0].as_bitaxe(user_suffix=user_suffix)
|
||||
|
||||
def as_luxos(self, user_suffix: str = None) -> dict:
|
||||
return {}
|
||||
|
||||
@classmethod
|
||||
def from_api(cls, api_pools: dict) -> "PoolConfig":
|
||||
try:
|
||||
@@ -568,3 +592,24 @@ class PoolConfig(MinerConfigValue):
|
||||
@classmethod
|
||||
def from_bitaxe(cls, web_system_info: dict) -> "PoolConfig":
|
||||
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
|
||||
return temps_config
|
||||
|
||||
def as_luxos(self) -> dict:
|
||||
return {"tempctrlset": [self.target or "", self.hot or "", self.danger or ""]}
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, dict_conf: dict | None) -> "TemperatureConfig":
|
||||
return cls(
|
||||
@@ -130,3 +133,16 @@ class TemperatureConfig(MinerConfigValue):
|
||||
|
||||
return cls(**conf)
|
||||
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.mining import MiningModePowerTune
|
||||
from pyasic.data.pools import PoolMetrics
|
||||
|
||||
from .boards import HashBoard
|
||||
from .device import DeviceInfo
|
||||
from .error_codes import BraiinsOSError, InnosiliconError, WhatsminerError, X19Error
|
||||
from .fans import Fan
|
||||
from .hashrate import AlgoHashRate, HashUnit
|
||||
from pyasic.data.pools import PoolMetrics
|
||||
|
||||
|
||||
@dataclass
|
||||
|
||||
@@ -7,6 +7,7 @@ from urllib.parse import urlparse
|
||||
class Scheme(Enum):
|
||||
STRATUM_V1 = "stratum+tcp"
|
||||
STRATUM_V2 = "stratum2+tcp"
|
||||
STRATUM_V1_SSL = "stratum+ssl"
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -25,7 +26,10 @@ class PoolUrl:
|
||||
@classmethod
|
||||
def from_str(cls, url: str) -> "PoolUrl":
|
||||
parsed_url = urlparse(url)
|
||||
scheme = Scheme(parsed_url.scheme)
|
||||
if not parsed_url.scheme.strip() == "":
|
||||
scheme = Scheme(parsed_url.scheme)
|
||||
else:
|
||||
scheme = Scheme.STRATUM_V1
|
||||
host = parsed_url.hostname
|
||||
port = parsed_url.port
|
||||
pubkey = parsed_url.path.lstrip("/") if scheme == Scheme.STRATUM_V2 else None
|
||||
@@ -85,6 +89,8 @@ class PoolMetrics:
|
||||
@staticmethod
|
||||
def _calculate_percentage(value: int, total: int) -> float:
|
||||
"""Calculate the percentage."""
|
||||
if value is None or total is None:
|
||||
return 0
|
||||
if total == 0:
|
||||
return 0
|
||||
return (value / total) * 100
|
||||
|
||||
@@ -26,6 +26,7 @@ class MinerMake(str, Enum):
|
||||
AURADINE = "Auradine"
|
||||
EPIC = "ePIC"
|
||||
BITAXE = "BitAxe"
|
||||
ICERIVER = "IceRiver"
|
||||
|
||||
def __str__(self):
|
||||
return self.value
|
||||
|
||||
@@ -5,14 +5,19 @@ class AntminerModels(str, Enum):
|
||||
D3 = "D3"
|
||||
HS3 = "HS3"
|
||||
L3Plus = "L3+"
|
||||
KA3 = "KA3"
|
||||
KS3 = "KS3"
|
||||
DR5 = "DR5"
|
||||
KS5 = "KS5"
|
||||
L7 = "L7"
|
||||
K7 = "K7"
|
||||
E9Pro = "E9Pro"
|
||||
S9 = "S9"
|
||||
S9i = "S9i"
|
||||
S9j = "S9j"
|
||||
T9 = "T9"
|
||||
Z15 = "Z15"
|
||||
Z15Pro = "Z15 Pro"
|
||||
S17 = "S17"
|
||||
S17Plus = "S17+"
|
||||
S17Pro = "S17 Pro"
|
||||
@@ -220,6 +225,7 @@ class WhatsminerModels(str, Enum):
|
||||
M50VH60 = "M50 VH60"
|
||||
M50VH70 = "M50 VH70"
|
||||
M50VH80 = "M50 VH80"
|
||||
M50VH90 = "M50 VH90"
|
||||
M50VJ10 = "M50 VJ10"
|
||||
M50VJ20 = "M50 VJ20"
|
||||
M50VJ30 = "M50 VJ30"
|
||||
@@ -293,6 +299,8 @@ class AvalonminerModels(str, Enum):
|
||||
class InnosiliconModels(str, Enum):
|
||||
T3HPlus = "T3H+"
|
||||
A10X = "A10X"
|
||||
A11 = "A11"
|
||||
A11MX = "A11MX"
|
||||
|
||||
def __str__(self):
|
||||
return self.value
|
||||
@@ -341,7 +349,15 @@ class BitAxeModels(str, Enum):
|
||||
|
||||
|
||||
class IceRiverModels(str, Enum):
|
||||
KS0 = "KS0"
|
||||
KS1 = "KS1"
|
||||
KS2 = "KS2"
|
||||
KS3 = "KS3"
|
||||
KS3L = "KS3L"
|
||||
KS3M = "KS3M"
|
||||
KS5 = "KS5"
|
||||
KS5L = "KS5L"
|
||||
KS5M = "KS5M"
|
||||
|
||||
def __str__(self):
|
||||
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,
|
||||
BMMinerS19jNoPIC,
|
||||
BMMinerS19jPro,
|
||||
BMMinerS19KPro,
|
||||
BMMinerS19L,
|
||||
BMMinerS19Plus,
|
||||
BMMinerS19Pro,
|
||||
@@ -30,6 +31,5 @@ from .S19 import (
|
||||
BMMinerS19ProPlus,
|
||||
BMMinerS19ProPlusHydro,
|
||||
BMMinerS19XP,
|
||||
BMMinerS19KPro,
|
||||
)
|
||||
from .T19 import BMMinerT19
|
||||
|
||||
22
pyasic/miners/antminer/bmminer/X3/KA3.py
Normal file
22
pyasic/miners/antminer/bmminer/X3/KA3.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Copyright 2022 Upstream Data Inc -
|
||||
# -
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||
# you may not use this file except in compliance with the License. -
|
||||
# You may obtain a copy of the License at -
|
||||
# -
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||
# -
|
||||
# Unless required by applicable law or agreed to in writing, software -
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.backends import AntminerModern
|
||||
from pyasic.miners.device.models import KA3
|
||||
|
||||
|
||||
class BMMinerKA3(AntminerModern, KA3):
|
||||
pass
|
||||
22
pyasic/miners/antminer/bmminer/X3/KS3.py
Normal file
22
pyasic/miners/antminer/bmminer/X3/KS3.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Copyright 2022 Upstream Data Inc -
|
||||
# -
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||
# you may not use this file except in compliance with the License. -
|
||||
# You may obtain a copy of the License at -
|
||||
# -
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||
# -
|
||||
# Unless required by applicable law or agreed to in writing, software -
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.backends import AntminerModern
|
||||
from pyasic.miners.device.models.antminer import KS3
|
||||
|
||||
|
||||
class BMMinerKS3(AntminerModern, KS3):
|
||||
pass
|
||||
@@ -14,4 +14,6 @@
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
from .HS3 import BMMinerHS3
|
||||
from .KA3 import BMMinerKA3
|
||||
from .KS3 import BMMinerKS3
|
||||
from .L3 import BMMinerL3Plus
|
||||
|
||||
21
pyasic/miners/antminer/bmminer/X5/KS5.py
Normal file
21
pyasic/miners/antminer/bmminer/X5/KS5.py
Normal file
@@ -0,0 +1,21 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Copyright 2022 Upstream Data Inc -
|
||||
# -
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||
# you may not use this file except in compliance with the License. -
|
||||
# You may obtain a copy of the License at -
|
||||
# -
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||
# -
|
||||
# Unless required by applicable law or agreed to in writing, software -
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
from pyasic.miners.backends import AntminerModern
|
||||
from pyasic.miners.device.models import KS5
|
||||
|
||||
|
||||
class BMMinerKS5(AntminerModern, KS5):
|
||||
supports_shutdown = False
|
||||
16
pyasic/miners/antminer/bmminer/X5/__init__.py
Normal file
16
pyasic/miners/antminer/bmminer/X5/__init__.py
Normal file
@@ -0,0 +1,16 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Copyright 2022 Upstream Data Inc -
|
||||
# -
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||
# you may not use this file except in compliance with the License. -
|
||||
# You may obtain a copy of the License at -
|
||||
# -
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||
# -
|
||||
# Unless required by applicable law or agreed to in writing, software -
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
from .KS5 import BMMinerKS5
|
||||
21
pyasic/miners/antminer/bmminer/X7/K7.py
Normal file
21
pyasic/miners/antminer/bmminer/X7/K7.py
Normal file
@@ -0,0 +1,21 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Copyright 2022 Upstream Data Inc -
|
||||
# -
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||
# you may not use this file except in compliance with the License. -
|
||||
# You may obtain a copy of the License at -
|
||||
# -
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||
# -
|
||||
# Unless required by applicable law or agreed to in writing, software -
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
from pyasic.miners.backends import AntminerModern
|
||||
from pyasic.miners.device.models import K7
|
||||
|
||||
|
||||
class BMMinerK7(AntminerModern, K7):
|
||||
pass
|
||||
@@ -13,4 +13,5 @@
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
from .K7 import BMMinerK7
|
||||
from .L7 import BMMinerL7
|
||||
|
||||
@@ -14,8 +14,10 @@
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
from .X3 import *
|
||||
from .X5 import *
|
||||
from .X7 import *
|
||||
from .X9 import *
|
||||
from .X15 import *
|
||||
from .X17 import *
|
||||
from .X19 import *
|
||||
from .X21 import *
|
||||
|
||||
@@ -15,7 +15,4 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from .S21 import ePICS21, ePICS21Pro
|
||||
|
||||
from .T21 import (
|
||||
ePICT21,
|
||||
)
|
||||
from .T21 import ePICT21
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from typing import List, Optional, Union
|
||||
from pathlib import Path
|
||||
import logging
|
||||
from pathlib import Path
|
||||
from typing import List, Optional, Union
|
||||
|
||||
from pyasic.config import MinerConfig, MiningModeConfig
|
||||
from pyasic.data import AlgoHashRate, Fan, HashBoard, HashUnit
|
||||
@@ -141,17 +141,24 @@ class AntminerModern(BMMiner):
|
||||
raise ValueError("File location must be provided for firmware upgrade.")
|
||||
|
||||
try:
|
||||
result = await self.web.update_firmware(file=file, keep_settings=keep_settings)
|
||||
result = await self.web.update_firmware(
|
||||
file=file, keep_settings=keep_settings
|
||||
)
|
||||
|
||||
if result.get("success"):
|
||||
logging.info("Firmware upgrade process completed successfully for AntMiner.")
|
||||
logging.info(
|
||||
"Firmware upgrade process completed successfully for AntMiner."
|
||||
)
|
||||
return "Firmware upgrade completed successfully."
|
||||
else:
|
||||
error_message = result.get("message", "Unknown error")
|
||||
logging.error(f"Firmware upgrade failed. Response: {error_message}")
|
||||
return f"Firmware upgrade failed. Response: {error_message}"
|
||||
except Exception as e:
|
||||
logging.error(f"An error occurred during the firmware upgrade process: {e}", exc_info=True)
|
||||
logging.error(
|
||||
f"An error occurred during the firmware upgrade process: {e}",
|
||||
exc_info=True,
|
||||
)
|
||||
raise
|
||||
|
||||
async def fault_light_on(self) -> bool:
|
||||
@@ -367,7 +374,7 @@ class AntminerModern(BMMiner):
|
||||
|
||||
if web_get_conf is not None:
|
||||
try:
|
||||
if web_get_conf["bitmain-work-mode"].isdigit():
|
||||
if str(web_get_conf["bitmain-work-mode"]).isdigit():
|
||||
return (
|
||||
False if int(web_get_conf["bitmain-work-mode"]) == 1 else True
|
||||
)
|
||||
@@ -590,49 +597,44 @@ class AntminerOld(CGMiner):
|
||||
pass
|
||||
|
||||
if rpc_stats is not None:
|
||||
try:
|
||||
board_offset = -1
|
||||
boards = rpc_stats["STATS"]
|
||||
if len(boards) > 1:
|
||||
for board_num in range(1, 16, 5):
|
||||
for _b_num in range(5):
|
||||
b = boards[1].get(f"chain_acn{board_num + _b_num}")
|
||||
board_offset = -1
|
||||
boards = rpc_stats["STATS"]
|
||||
if len(boards) > 1:
|
||||
for board_num in range(1, 16, 5):
|
||||
for _b_num in range(5):
|
||||
b = boards[1].get(f"chain_acn{board_num + _b_num}")
|
||||
|
||||
if b and not b == 0 and board_offset == -1:
|
||||
board_offset = board_num
|
||||
if board_offset == -1:
|
||||
board_offset = 1
|
||||
if b and not b == 0 and board_offset == -1:
|
||||
board_offset = board_num
|
||||
if board_offset == -1:
|
||||
board_offset = 1
|
||||
|
||||
for i in range(
|
||||
board_offset, board_offset + self.expected_hashboards
|
||||
):
|
||||
hashboard = HashBoard(
|
||||
slot=i - board_offset, expected_chips=self.expected_chips
|
||||
)
|
||||
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}")
|
||||
if chip_temp:
|
||||
hashboard.chip_temp = round(chip_temp)
|
||||
chip_temp = boards[1].get(f"temp{i}")
|
||||
if chip_temp:
|
||||
hashboard.chip_temp = round(chip_temp)
|
||||
|
||||
temp = boards[1].get(f"temp2_{i}")
|
||||
if temp:
|
||||
hashboard.temp = round(temp)
|
||||
temp = boards[1].get(f"temp2_{i}")
|
||||
if temp:
|
||||
hashboard.temp = round(temp)
|
||||
|
||||
hashrate = boards[1].get(f"chain_rate{i}")
|
||||
if hashrate:
|
||||
hashboard.hashrate = AlgoHashRate.SHA256(
|
||||
hashrate, HashUnit.SHA256.GH
|
||||
).into(self.algo.unit.default)
|
||||
hashrate = boards[1].get(f"chain_rate{i}")
|
||||
if hashrate:
|
||||
hashboard.hashrate = AlgoHashRate.SHA256(
|
||||
float(hashrate), HashUnit.SHA256.GH
|
||||
).into(self.algo.unit.default)
|
||||
|
||||
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
|
||||
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)
|
||||
|
||||
return hashboards
|
||||
|
||||
|
||||
@@ -193,7 +193,14 @@ class Auradine(StockFirmware):
|
||||
for key in conf.keys():
|
||||
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.
|
||||
|
||||
@@ -209,7 +216,9 @@ class Auradine(StockFirmware):
|
||||
logging.info("Starting firmware upgrade process.")
|
||||
|
||||
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:
|
||||
result = await self.web.firmware_upgrade(url=url)
|
||||
@@ -220,11 +229,15 @@ class Auradine(StockFirmware):
|
||||
logging.info("Firmware upgrade process completed successfully.")
|
||||
return True
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
##################################################
|
||||
|
||||
@@ -18,6 +18,7 @@ from typing import List, Optional
|
||||
|
||||
from pyasic.config import MinerConfig
|
||||
from pyasic.data import AlgoHashRate, Fan, HashBoard, HashUnit
|
||||
from pyasic.data.pools import PoolMetrics, PoolUrl
|
||||
from pyasic.errors import APIError
|
||||
from pyasic.miners.data import DataFunction, DataLocations, DataOptions, RPCAPICommand
|
||||
from pyasic.miners.device.firmware import StockFirmware
|
||||
@@ -49,6 +50,10 @@ BFGMINER_DATA_LOC = DataLocations(
|
||||
"_get_fans",
|
||||
[RPCAPICommand("rpc_stats", "stats")],
|
||||
),
|
||||
str(DataOptions.POOLS): DataFunction(
|
||||
"_get_pools",
|
||||
[RPCAPICommand("rpc_pools", "pools")],
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
@@ -207,6 +212,36 @@ class BFGMiner(StockFirmware):
|
||||
|
||||
return fans
|
||||
|
||||
async def _get_pools(self, rpc_pools: dict = None) -> List[PoolMetrics]:
|
||||
if rpc_pools is None:
|
||||
try:
|
||||
rpc_pools = await self.rpc.pools()
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
pools_data = []
|
||||
if rpc_pools is not None:
|
||||
try:
|
||||
pools = rpc_pools.get("POOLS", [])
|
||||
for pool_info in pools:
|
||||
url = pool_info.get("URL")
|
||||
pool_url = PoolUrl.from_str(url) if url else None
|
||||
pool_data = PoolMetrics(
|
||||
accepted=pool_info.get("Accepted"),
|
||||
rejected=pool_info.get("Rejected"),
|
||||
get_failures=pool_info.get("Get Failures"),
|
||||
remote_failures=pool_info.get("Remote Failures"),
|
||||
active=pool_info.get("Stratum Active"),
|
||||
alive=pool_info.get("Status") == "Alive",
|
||||
url=pool_url,
|
||||
user=pool_info.get("User"),
|
||||
index=pool_info.get("POOL"),
|
||||
)
|
||||
pools_data.append(pool_data)
|
||||
except LookupError:
|
||||
pass
|
||||
return pools_data
|
||||
|
||||
async def _get_expected_hashrate(
|
||||
self, rpc_stats: dict = None
|
||||
) -> Optional[AlgoHashRate]:
|
||||
@@ -228,4 +263,4 @@ class BFGMiner(StockFirmware):
|
||||
expected_rate, HashUnit.SHA256.from_str(rate_unit)
|
||||
).into(self.algo.unit.default)
|
||||
except LookupError:
|
||||
pass
|
||||
pass
|
||||
|
||||
@@ -41,6 +41,10 @@ BITAXE_DATA_LOC = DataLocations(
|
||||
"_get_api_ver",
|
||||
[WebAPICommand("web_system_info", "system/info")],
|
||||
),
|
||||
str(DataOptions.MAC): DataFunction(
|
||||
"_get_mac",
|
||||
[WebAPICommand("web_system_info", "system/info")],
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
@@ -187,3 +191,16 @@ class BitAxe(BaseMiner):
|
||||
return web_system_info["version"]
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
async def _get_mac(self, web_system_info: dict = None) -> Optional[str]:
|
||||
if web_system_info is None:
|
||||
try:
|
||||
web_system_info = await self.web.system_info()
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
if web_system_info is not None:
|
||||
try:
|
||||
return web_system_info["macAddr"].upper()
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
@@ -798,7 +798,7 @@ class BOSer(BraiinsOSFirmware):
|
||||
async def set_power_limit(self, wattage: int) -> bool:
|
||||
try:
|
||||
result = await self.web.set_power_target(
|
||||
wattage, save_action=SaveAction.SAVE_ACTION_SAVE_AND_FORCE_APPLY
|
||||
wattage, save_action=SaveAction.SAVE_AND_FORCE_APPLY
|
||||
)
|
||||
except APIError:
|
||||
return False
|
||||
@@ -1093,7 +1093,7 @@ class BOSer(BraiinsOSFirmware):
|
||||
get_failures=0,
|
||||
remote_failures=0,
|
||||
active=pool_info.get("active", False),
|
||||
alive=pool_info["alive"],
|
||||
alive=pool_info.get("alive"),
|
||||
)
|
||||
pools_data.append(pool_data)
|
||||
|
||||
|
||||
@@ -23,11 +23,11 @@ import aiofiles
|
||||
from pyasic.config import MinerConfig, MiningModeConfig
|
||||
from pyasic.data import AlgoHashRate, Fan, HashBoard, HashUnit
|
||||
from pyasic.data.error_codes import MinerErrorData, WhatsminerError
|
||||
from pyasic.data.pools import PoolMetrics, PoolUrl
|
||||
from pyasic.errors import APIError
|
||||
from pyasic.miners.data import DataFunction, DataLocations, DataOptions, RPCAPICommand
|
||||
from pyasic.miners.device.firmware import StockFirmware
|
||||
from pyasic.rpc.btminer import BTMinerRPCAPI
|
||||
from pyasic.data.pools import PoolMetrics, PoolUrl
|
||||
|
||||
BTMINER_DATA_LOC = DataLocations(
|
||||
**{
|
||||
@@ -113,7 +113,7 @@ BTMINER_DATA_LOC = DataLocations(
|
||||
str(DataOptions.POOLS): DataFunction(
|
||||
"_get_pools",
|
||||
[RPCAPICommand("rpc_pools", "pools")],
|
||||
)
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -14,15 +14,15 @@
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from typing import Optional, List
|
||||
from typing import List, Optional
|
||||
|
||||
from pyasic.config import MinerConfig
|
||||
from pyasic.data import AlgoHashRate, HashUnit
|
||||
from pyasic.data.pools import PoolMetrics, PoolUrl
|
||||
from pyasic.errors import APIError
|
||||
from pyasic.miners.data import DataFunction, DataLocations, DataOptions, RPCAPICommand
|
||||
from pyasic.miners.device.firmware import StockFirmware
|
||||
from pyasic.rpc.cgminer import CGMinerRPCAPI
|
||||
from pyasic.data.pools import PoolMetrics, PoolUrl
|
||||
|
||||
CGMINER_DATA_LOC = DataLocations(
|
||||
**{
|
||||
|
||||
@@ -454,8 +454,9 @@ class ePIC(ePICFirmware):
|
||||
except LookupError:
|
||||
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.
|
||||
|
||||
@@ -466,4 +467,4 @@ class ePIC(ePICFirmware):
|
||||
Returns:
|
||||
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)
|
||||
|
||||
@@ -62,6 +62,10 @@ GOLDSHELL_DATA_LOC = DataLocations(
|
||||
"_get_fans",
|
||||
[RPCAPICommand("rpc_stats", "stats")],
|
||||
),
|
||||
str(DataOptions.POOLS): DataFunction(
|
||||
"_get_pools",
|
||||
[RPCAPICommand("rpc_pools", "pools")],
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
from typing import List, Optional
|
||||
|
||||
from pyasic import MinerConfig
|
||||
from pyasic.data import AlgoHashRate, Fan, HashBoard, HashUnit
|
||||
from pyasic.data.pools import PoolMetrics, PoolUrl
|
||||
from pyasic.device import MinerAlgo
|
||||
from pyasic.errors import APIError
|
||||
from pyasic.miners.data import DataFunction, DataLocations, DataOptions, WebAPICommand
|
||||
@@ -41,6 +43,10 @@ ICERIVER_DATA_LOC = DataLocations(
|
||||
"_get_uptime",
|
||||
[WebAPICommand("web_userpanel", "userpanel")],
|
||||
),
|
||||
str(DataOptions.POOLS): DataFunction(
|
||||
"_get_pools",
|
||||
[WebAPICommand("web_userpanel", "userpanel")],
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
@@ -67,6 +73,11 @@ class IceRiver(StockFirmware):
|
||||
return False
|
||||
return True
|
||||
|
||||
async def get_config(self) -> MinerConfig:
|
||||
web_userpanel = await self.web.userpanel()
|
||||
|
||||
return MinerConfig.from_iceriver(web_userpanel)
|
||||
|
||||
async def _get_fans(self, web_userpanel: dict = None) -> List[Fan]:
|
||||
if web_userpanel is None:
|
||||
try:
|
||||
@@ -76,7 +87,7 @@ class IceRiver(StockFirmware):
|
||||
|
||||
if web_userpanel is not None:
|
||||
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):
|
||||
pass
|
||||
|
||||
@@ -89,7 +100,9 @@ class IceRiver(StockFirmware):
|
||||
|
||||
if web_userpanel is not None:
|
||||
try:
|
||||
return web_userpanel["mac"].upper().replace("-", ":")
|
||||
return (
|
||||
web_userpanel["userpanel"]["data"]["mac"].upper().replace("-", ":")
|
||||
)
|
||||
except (LookupError, ValueError, TypeError):
|
||||
pass
|
||||
|
||||
@@ -102,7 +115,7 @@ class IceRiver(StockFirmware):
|
||||
|
||||
if web_userpanel is not None:
|
||||
try:
|
||||
return web_userpanel["host"]
|
||||
return web_userpanel["userpanel"]["data"]["host"]
|
||||
except (LookupError, ValueError, TypeError):
|
||||
pass
|
||||
|
||||
@@ -115,9 +128,13 @@ class IceRiver(StockFirmware):
|
||||
|
||||
if web_userpanel is not None:
|
||||
try:
|
||||
base_unit = web_userpanel["unit"]
|
||||
base_unit = web_userpanel["userpanel"]["data"]["unit"]
|
||||
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"),
|
||||
).into(MinerAlgo.SHA256.unit.default)
|
||||
except (LookupError, ValueError, TypeError):
|
||||
@@ -132,7 +149,7 @@ class IceRiver(StockFirmware):
|
||||
|
||||
if web_userpanel is not None:
|
||||
try:
|
||||
return web_userpanel["locate"]
|
||||
return web_userpanel["userpanel"]["data"]["locate"]
|
||||
except (LookupError, ValueError, TypeError):
|
||||
pass
|
||||
return False
|
||||
@@ -146,7 +163,7 @@ class IceRiver(StockFirmware):
|
||||
|
||||
if web_userpanel is not None:
|
||||
try:
|
||||
return web_userpanel["powstate"]
|
||||
return web_userpanel["userpanel"]["data"]["powstate"]
|
||||
except (LookupError, ValueError, TypeError):
|
||||
pass
|
||||
|
||||
@@ -164,14 +181,14 @@ class IceRiver(StockFirmware):
|
||||
|
||||
if web_userpanel is not None:
|
||||
try:
|
||||
for board in web_userpanel["boards"]:
|
||||
idx = board["no"] - 1
|
||||
for board in web_userpanel["userpanel"]["data"]["boards"]:
|
||||
idx = int(board["no"] - 1)
|
||||
hb_list[idx].chip_temp = round(board["outtmp"])
|
||||
hb_list[idx].temp = round(board["intmp"])
|
||||
hb_list[idx].hashrate = AlgoHashRate.SHA256(
|
||||
float(board["rtpow"].replace("G", "")), HashUnit.SHA256.GH
|
||||
).into(self.algo.unit.default)
|
||||
hb_list[idx].chips = board["chipnum"]
|
||||
hb_list[idx].chips = int(board["chipnum"])
|
||||
hb_list[idx].missing = False
|
||||
except LookupError:
|
||||
pass
|
||||
@@ -186,7 +203,7 @@ class IceRiver(StockFirmware):
|
||||
|
||||
if web_userpanel is not None:
|
||||
try:
|
||||
runtime = web_userpanel["runtime"]
|
||||
runtime = web_userpanel["userpanel"]["data"]["runtime"]
|
||||
days, hours, minutes, seconds = runtime.split(":")
|
||||
return (
|
||||
(int(days) * 24 * 60 * 60)
|
||||
@@ -196,3 +213,36 @@ class IceRiver(StockFirmware):
|
||||
)
|
||||
except (LookupError, ValueError, TypeError):
|
||||
pass
|
||||
|
||||
async def _get_pools(self, web_userpanel: dict = None) -> List[PoolMetrics]:
|
||||
if web_userpanel is None:
|
||||
try:
|
||||
web_userpanel = await self.web.userpanel()
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
pools_data = []
|
||||
if web_userpanel is not None:
|
||||
try:
|
||||
pools = web_userpanel["userpanel"]["data"]["pools"]
|
||||
for pool_info in pools:
|
||||
pool_num = pool_info.get("no")
|
||||
if pool_num is not None:
|
||||
pool_num = int(pool_num)
|
||||
if pool_info["addr"] == "":
|
||||
continue
|
||||
url = pool_info.get("addr")
|
||||
pool_url = PoolUrl.from_str(url) if url else None
|
||||
pool_data = PoolMetrics(
|
||||
accepted=pool_info.get("accepted"),
|
||||
rejected=pool_info.get("rejected"),
|
||||
active=pool_info.get("connect"),
|
||||
alive=int(pool_info.get("state", 0)) == 1,
|
||||
url=pool_url,
|
||||
user=pool_info.get("user"),
|
||||
index=pool_num,
|
||||
)
|
||||
pools_data.append(pool_data)
|
||||
except LookupError:
|
||||
pass
|
||||
return pools_data
|
||||
|
||||
@@ -19,6 +19,7 @@ from pyasic.config import MinerConfig
|
||||
from pyasic.data import AlgoHashRate, Fan, HashBoard, HashUnit
|
||||
from pyasic.data.error_codes import MinerErrorData
|
||||
from pyasic.data.error_codes.innosilicon import InnosiliconError
|
||||
from pyasic.data.pools import PoolMetrics, PoolUrl
|
||||
from pyasic.errors import APIError
|
||||
from pyasic.miners.backends import CGMiner
|
||||
from pyasic.miners.data import (
|
||||
@@ -29,7 +30,6 @@ from pyasic.miners.data import (
|
||||
WebAPICommand,
|
||||
)
|
||||
from pyasic.web.innosilicon import InnosiliconWebAPI
|
||||
from pyasic.data.pools import PoolMetrics, PoolUrl
|
||||
|
||||
INNOSILICON_DATA_LOC = DataLocations(
|
||||
**{
|
||||
@@ -92,9 +92,8 @@ INNOSILICON_DATA_LOC = DataLocations(
|
||||
[RPCAPICommand("rpc_stats", "stats")],
|
||||
),
|
||||
str(DataOptions.POOLS): DataFunction(
|
||||
"_get_pools",
|
||||
[RPCAPICommand("rpc_pools", "pools")]
|
||||
)
|
||||
"_get_pools", [RPCAPICommand("rpc_pools", "pools")]
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
@@ -116,7 +115,7 @@ class Innosilicon(CGMiner):
|
||||
except APIError:
|
||||
return self.config
|
||||
|
||||
self.config = MinerConfig.from_inno([pools])
|
||||
self.config = MinerConfig.from_inno(pools["pools"])
|
||||
return self.config
|
||||
|
||||
async def reboot(self) -> bool:
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
from typing import List, Optional
|
||||
import logging
|
||||
from typing import List, Optional
|
||||
|
||||
from pyasic.config import MinerConfig
|
||||
from pyasic.data import AlgoHashRate, Fan, HashBoard, HashUnit
|
||||
@@ -56,6 +56,15 @@ LUXMINER_DATA_LOC = DataLocations(
|
||||
str(DataOptions.POOLS): DataFunction(
|
||||
"_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
|
||||
|
||||
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:
|
||||
try:
|
||||
session_id = await self._get_session()
|
||||
if session_id:
|
||||
await self.rpc.ledset(session_id, "red", "blink")
|
||||
await self.rpc.ledset("red", "blink")
|
||||
return True
|
||||
except (APIError, LookupError):
|
||||
pass
|
||||
@@ -94,9 +87,7 @@ class LUXMiner(LuxOSFirmware):
|
||||
|
||||
async def fault_light_off(self) -> bool:
|
||||
try:
|
||||
session_id = await self._get_session()
|
||||
if session_id:
|
||||
await self.rpc.ledset(session_id, "red", "off")
|
||||
await self.rpc.ledset("red", "off")
|
||||
return True
|
||||
except (APIError, LookupError):
|
||||
pass
|
||||
@@ -107,9 +98,7 @@ class LUXMiner(LuxOSFirmware):
|
||||
|
||||
async def restart_luxminer(self) -> bool:
|
||||
try:
|
||||
session_id = await self._get_session()
|
||||
if session_id:
|
||||
await self.rpc.resetminer(session_id)
|
||||
await self.rpc.resetminer()
|
||||
return True
|
||||
except (APIError, LookupError):
|
||||
pass
|
||||
@@ -117,9 +106,7 @@ class LUXMiner(LuxOSFirmware):
|
||||
|
||||
async def stop_mining(self) -> bool:
|
||||
try:
|
||||
session_id = await self._get_session()
|
||||
if session_id:
|
||||
await self.rpc.curtail(session_id)
|
||||
await self.rpc.sleep()
|
||||
return True
|
||||
except (APIError, LookupError):
|
||||
pass
|
||||
@@ -127,25 +114,27 @@ class LUXMiner(LuxOSFirmware):
|
||||
|
||||
async def resume_mining(self) -> bool:
|
||||
try:
|
||||
session_id = await self._get_session()
|
||||
if session_id:
|
||||
await self.rpc.wakeup(session_id)
|
||||
await self.rpc.wakeup()
|
||||
return True
|
||||
except (APIError, LookupError):
|
||||
pass
|
||||
|
||||
async def reboot(self) -> bool:
|
||||
try:
|
||||
session_id = await self._get_session()
|
||||
if session_id:
|
||||
await self.rpc.rebootdevice(session_id)
|
||||
await self.rpc.rebootdevice()
|
||||
return True
|
||||
except (APIError, LookupError):
|
||||
pass
|
||||
return False
|
||||
|
||||
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:
|
||||
"""
|
||||
@@ -168,20 +157,17 @@ class LUXMiner(LuxOSFirmware):
|
||||
##################################################
|
||||
|
||||
async def _get_mac(self, rpc_config: dict = None) -> Optional[str]:
|
||||
mac = None
|
||||
if rpc_config is None:
|
||||
try:
|
||||
rpc_config = await self.rpc.config()
|
||||
except APIError:
|
||||
return None
|
||||
pass
|
||||
|
||||
if rpc_config is not None:
|
||||
try:
|
||||
mac = rpc_config["CONFIG"][0]["MACAddr"]
|
||||
return rpc_config["CONFIG"][0]["MACAddr"].upper()
|
||||
except KeyError:
|
||||
return None
|
||||
|
||||
return mac
|
||||
pass
|
||||
|
||||
async def _get_hashrate(self, rpc_summary: dict = None) -> Optional[AlgoHashRate]:
|
||||
if rpc_summary is None:
|
||||
@@ -199,59 +185,47 @@ class LUXMiner(LuxOSFirmware):
|
||||
pass
|
||||
|
||||
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:
|
||||
try:
|
||||
rpc_stats = await self.rpc.stats()
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
if rpc_stats is not None:
|
||||
try:
|
||||
board_offset = -1
|
||||
boards = rpc_stats["STATS"]
|
||||
if len(boards) > 1:
|
||||
for board_num in range(1, 16, 5):
|
||||
for _b_num in range(5):
|
||||
b = boards[1].get(f"chain_acn{board_num + _b_num}")
|
||||
|
||||
if b and not b == 0 and board_offset == -1:
|
||||
board_offset = board_num
|
||||
if board_offset == -1:
|
||||
board_offset = 1
|
||||
|
||||
for i in range(
|
||||
board_offset, board_offset + self.expected_hashboards
|
||||
):
|
||||
hashboard = HashBoard(
|
||||
slot=i - board_offset, expected_chips=self.expected_chips
|
||||
# TODO: bugged on S9 because of index issues, fix later.
|
||||
board_stats = rpc_stats["STATS"][1]
|
||||
for idx in range(3):
|
||||
board_n = idx + 1
|
||||
hashboards[idx].hashrate = AlgoHashRate.SHA256(
|
||||
float(board_stats[f"chain_rate{board_n}"]), HashUnit.SHA256.GH
|
||||
).into(self.algo.unit.default)
|
||||
hashboards[idx].chips = int(board_stats[f"chain_acn{board_n}"])
|
||||
chip_temp_data = list(
|
||||
filter(
|
||||
lambda x: not x == 0,
|
||||
map(int, board_stats[f"temp_chip{board_n}"].split("-")),
|
||||
)
|
||||
|
||||
chip_temp = boards[1].get(f"temp{i}")
|
||||
if chip_temp:
|
||||
hashboard.chip_temp = round(chip_temp)
|
||||
|
||||
temp = boards[1].get(f"temp2_{i}")
|
||||
if temp:
|
||||
hashboard.temp = round(temp)
|
||||
|
||||
hashrate = boards[1].get(f"chain_rate{i}")
|
||||
if hashrate:
|
||||
hashboard.hashrate = AlgoHashRate.SHA256(
|
||||
hashrate, HashUnit.SHA256.GH
|
||||
).into(self.algo.unit.default)
|
||||
|
||||
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):
|
||||
)
|
||||
hashboards[idx].chip_temp = (
|
||||
sum([chip_temp_data[0], chip_temp_data[3]]) / 2
|
||||
)
|
||||
board_temp_data = list(
|
||||
filter(
|
||||
lambda x: not x == 0,
|
||||
map(int, board_stats[f"temp_pcb{board_n}"].split("-")),
|
||||
)
|
||||
)
|
||||
hashboards[idx].temp = (
|
||||
sum([board_temp_data[1], board_temp_data[2]]) / 2
|
||||
)
|
||||
hashboards[idx].missing = False
|
||||
except LookupError:
|
||||
pass
|
||||
|
||||
return hashboards
|
||||
|
||||
async def _get_wattage(self, rpc_power: dict = None) -> Optional[int]:
|
||||
@@ -319,6 +293,45 @@ class LUXMiner(LuxOSFirmware):
|
||||
except LookupError:
|
||||
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]:
|
||||
if rpc_pools is None:
|
||||
try:
|
||||
|
||||
@@ -3,13 +3,13 @@ from typing import List, Optional
|
||||
from pyasic import MinerConfig
|
||||
from pyasic.config import MiningModeConfig
|
||||
from pyasic.data import AlgoHashRate, Fan, HashBoard, HashUnit
|
||||
from pyasic.data.pools import PoolMetrics, PoolUrl
|
||||
from pyasic.errors import APIError
|
||||
from pyasic.miners.data import DataFunction, DataLocations, DataOptions, WebAPICommand
|
||||
from pyasic.miners.device.firmware import MaraFirmware
|
||||
from pyasic.misc import merge_dicts
|
||||
from pyasic.rpc.marathon import MaraRPCAPI
|
||||
from pyasic.web.marathon import MaraWebAPI
|
||||
from pyasic.data.pools import PoolMetrics, PoolUrl
|
||||
|
||||
MARA_DATA_LOC = DataLocations(
|
||||
**{
|
||||
@@ -319,11 +319,14 @@ class MaraMiner(MaraFirmware):
|
||||
return []
|
||||
|
||||
active_pool_index = None
|
||||
highest_priority = float('inf')
|
||||
highest_priority = float("inf")
|
||||
|
||||
for pool_info in web_pools:
|
||||
if pool_info.get("status") == "Alive" and pool_info.get("priority", float('inf')) < highest_priority:
|
||||
highest_priority = pool_info.get["priority"]
|
||||
if (
|
||||
pool_info.get("status") == "Alive"
|
||||
and pool_info.get("priority", float("inf")) < highest_priority
|
||||
):
|
||||
highest_priority = pool_info["priority"]
|
||||
active_pool_index = pool_info["index"]
|
||||
|
||||
pools_data = []
|
||||
|
||||
@@ -237,13 +237,17 @@ class VNish(VNishFirmware, BMMiner):
|
||||
|
||||
async def _is_mining(self, web_summary: dict = None) -> Optional[bool]:
|
||||
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:
|
||||
try:
|
||||
is_mining = not web_summary["miner"]["miner_status"]["miner_state"] in [
|
||||
"stopped",
|
||||
"shutting-down",
|
||||
"failure",
|
||||
]
|
||||
return is_mining
|
||||
except LookupError:
|
||||
|
||||
@@ -560,7 +560,14 @@ class BaseMiner(MinerProtocol):
|
||||
if self._ssh_cls is not None:
|
||||
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.
|
||||
|
||||
Parameters:
|
||||
@@ -574,4 +581,5 @@ class BaseMiner(MinerProtocol):
|
||||
"""
|
||||
return False
|
||||
|
||||
|
||||
AnyMiner = TypeVar("AnyMiner", bound=BaseMiner)
|
||||
|
||||
@@ -14,7 +14,4 @@
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from .blockminer import (
|
||||
ePICBlockMiner520i,
|
||||
ePICBlockMiner720i,
|
||||
)
|
||||
from .blockminer import ePICBlockMiner520i, ePICBlockMiner720i
|
||||
|
||||
@@ -43,4 +43,4 @@ class LuxOSFirmware(BaseMiner):
|
||||
|
||||
|
||||
class MaraFirmware(BaseMiner):
|
||||
firmware = MinerFirmware.MARATHON
|
||||
firmware = MinerFirmware.MARATHON
|
||||
|
||||
@@ -51,4 +51,4 @@ class BitAxeMake(BaseMiner):
|
||||
|
||||
|
||||
class IceRiverMake(BaseMiner):
|
||||
make = MinerMake.BITAXE
|
||||
make = MinerMake.ICERIVER
|
||||
|
||||
@@ -21,3 +21,9 @@ class Z15(AntMinerMake):
|
||||
raw_model = MinerModel.ANTMINER.Z15
|
||||
|
||||
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 -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
from .Z15 import Z15
|
||||
from .Z15 import Z15, Z15Pro
|
||||
|
||||
23
pyasic/miners/device/models/antminer/X3/KA3.py
Normal file
23
pyasic/miners/device/models/antminer/X3/KA3.py
Normal file
@@ -0,0 +1,23 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Copyright 2022 Upstream Data Inc -
|
||||
# -
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||
# you may not use this file except in compliance with the License. -
|
||||
# You may obtain a copy of the License at -
|
||||
# -
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||
# -
|
||||
# Unless required by applicable law or agreed to in writing, software -
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
from pyasic.device.models import MinerModel
|
||||
from pyasic.miners.device.makes import AntMinerMake
|
||||
|
||||
|
||||
class KA3(AntMinerMake):
|
||||
raw_model = MinerModel.ANTMINER.KA3
|
||||
|
||||
expected_chips = 92
|
||||
24
pyasic/miners/device/models/antminer/X3/KS3.py
Normal file
24
pyasic/miners/device/models/antminer/X3/KS3.py
Normal file
@@ -0,0 +1,24 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Copyright 2022 Upstream Data Inc -
|
||||
# -
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||
# you may not use this file except in compliance with the License. -
|
||||
# You may obtain a copy of the License at -
|
||||
# -
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||
# -
|
||||
# Unless required by applicable law or agreed to in writing, software -
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
from pyasic.device.models import MinerModel
|
||||
from pyasic.miners.device.makes import AntMinerMake
|
||||
|
||||
|
||||
class KS3(AntMinerMake):
|
||||
raw_model = MinerModel.ANTMINER.KS3
|
||||
|
||||
expected_chips = 92
|
||||
expected_fans = 2
|
||||
@@ -15,4 +15,6 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
from .D3 import D3
|
||||
from .HS3 import HS3
|
||||
from .KA3 import KA3
|
||||
from .KS3 import KS3
|
||||
from .L3 import L3Plus
|
||||
|
||||
23
pyasic/miners/device/models/antminer/X5/KS5.py
Normal file
23
pyasic/miners/device/models/antminer/X5/KS5.py
Normal file
@@ -0,0 +1,23 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Copyright 2022 Upstream Data Inc -
|
||||
# -
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||
# you may not use this file except in compliance with the License. -
|
||||
# You may obtain a copy of the License at -
|
||||
# -
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||
# -
|
||||
# Unless required by applicable law or agreed to in writing, software -
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
from pyasic.device.models import MinerModel
|
||||
from pyasic.miners.device.makes import AntMinerMake
|
||||
|
||||
|
||||
class KS5(AntMinerMake):
|
||||
raw_model = MinerModel.ANTMINER.KS5
|
||||
|
||||
expected_chips = 92
|
||||
@@ -14,3 +14,4 @@
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
from .DR5 import DR5
|
||||
from .KS5 import KS5
|
||||
|
||||
24
pyasic/miners/device/models/antminer/X7/K7.py
Normal file
24
pyasic/miners/device/models/antminer/X7/K7.py
Normal file
@@ -0,0 +1,24 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Copyright 2022 Upstream Data Inc -
|
||||
# -
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||
# you may not use this file except in compliance with the License. -
|
||||
# You may obtain a copy of the License at -
|
||||
# -
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||
# -
|
||||
# Unless required by applicable law or agreed to in writing, software -
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
from pyasic.device.models import MinerModel
|
||||
from pyasic.miners.device.makes import AntMinerMake
|
||||
|
||||
|
||||
class K7(AntMinerMake):
|
||||
raw_model = MinerModel.ANTMINER.K7
|
||||
|
||||
expected_chips = 92
|
||||
expected_fans = 4
|
||||
@@ -13,4 +13,5 @@
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
from .K7 import K7
|
||||
from .L7 import L7
|
||||
|
||||
23
pyasic/miners/device/models/iceriver/KSX/KS0.py
Normal file
23
pyasic/miners/device/models/iceriver/KSX/KS0.py
Normal file
@@ -0,0 +1,23 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Copyright 2024 Upstream Data Inc -
|
||||
# -
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||
# you may not use this file except in compliance with the License. -
|
||||
# You may obtain a copy of the License at -
|
||||
# -
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||
# -
|
||||
# Unless required by applicable law or agreed to in writing, software -
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
from pyasic.device.models import MinerModel
|
||||
from pyasic.miners.device.makes import IceRiverMake
|
||||
|
||||
|
||||
class KS0(IceRiverMake):
|
||||
raw_model = MinerModel.ICERIVER.KS0
|
||||
|
||||
expected_fans = 0
|
||||
23
pyasic/miners/device/models/iceriver/KSX/KS1.py
Normal file
23
pyasic/miners/device/models/iceriver/KSX/KS1.py
Normal file
@@ -0,0 +1,23 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Copyright 2024 Upstream Data Inc -
|
||||
# -
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||
# you may not use this file except in compliance with the License. -
|
||||
# You may obtain a copy of the License at -
|
||||
# -
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||
# -
|
||||
# Unless required by applicable law or agreed to in writing, software -
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
from pyasic.device.models import MinerModel
|
||||
from pyasic.miners.device.makes import IceRiverMake
|
||||
|
||||
|
||||
class KS1(IceRiverMake):
|
||||
raw_model = MinerModel.ICERIVER.KS1
|
||||
|
||||
expected_fans = 4
|
||||
@@ -21,3 +21,4 @@ class KS2(IceRiverMake):
|
||||
raw_model = MinerModel.ICERIVER.KS2
|
||||
|
||||
expected_fans = 4
|
||||
expected_chips = 18
|
||||
|
||||
36
pyasic/miners/device/models/iceriver/KSX/KS3.py
Normal file
36
pyasic/miners/device/models/iceriver/KSX/KS3.py
Normal file
@@ -0,0 +1,36 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Copyright 2024 Upstream Data Inc -
|
||||
# -
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||
# you may not use this file except in compliance with the License. -
|
||||
# You may obtain a copy of the License at -
|
||||
# -
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||
# -
|
||||
# Unless required by applicable law or agreed to in writing, software -
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
from pyasic.device.models import MinerModel
|
||||
from pyasic.miners.device.makes import IceRiverMake
|
||||
|
||||
|
||||
class KS3(IceRiverMake):
|
||||
raw_model = MinerModel.ICERIVER.KS3
|
||||
|
||||
expected_fans = 4
|
||||
|
||||
|
||||
class KS3L(IceRiverMake):
|
||||
raw_model = MinerModel.ICERIVER.KS3L
|
||||
|
||||
expected_fans = 4
|
||||
|
||||
|
||||
class KS3M(IceRiverMake):
|
||||
raw_model = MinerModel.ICERIVER.KS3M
|
||||
|
||||
expected_fans = 4
|
||||
expected_chips = 18
|
||||
36
pyasic/miners/device/models/iceriver/KSX/KS5.py
Normal file
36
pyasic/miners/device/models/iceriver/KSX/KS5.py
Normal file
@@ -0,0 +1,36 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Copyright 2024 Upstream Data Inc -
|
||||
# -
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||
# you may not use this file except in compliance with the License. -
|
||||
# You may obtain a copy of the License at -
|
||||
# -
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||
# -
|
||||
# Unless required by applicable law or agreed to in writing, software -
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
from pyasic.device.models import MinerModel
|
||||
from pyasic.miners.device.makes import IceRiverMake
|
||||
|
||||
|
||||
class KS5(IceRiverMake):
|
||||
raw_model = MinerModel.ICERIVER.KS5
|
||||
|
||||
expected_fans = 4
|
||||
|
||||
|
||||
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
|
||||
@@ -1 +1,5 @@
|
||||
from .KS0 import KS0
|
||||
from .KS1 import KS1
|
||||
from .KS2 import KS2
|
||||
from .KS3 import KS3, KS3L, KS3M
|
||||
from .KS5 import KS5, KS5L, KS5M
|
||||
|
||||
23
pyasic/miners/device/models/innosilicon/A11X/A11.py
Normal file
23
pyasic/miners/device/models/innosilicon/A11X/A11.py
Normal file
@@ -0,0 +1,23 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Copyright 2022 Upstream Data Inc -
|
||||
# -
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||
# you may not use this file except in compliance with the License. -
|
||||
# You may obtain a copy of the License at -
|
||||
# -
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||
# -
|
||||
# Unless required by applicable law or agreed to in writing, software -
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
from pyasic.device.models import MinerModel
|
||||
from pyasic.miners.device.makes import InnosiliconMake
|
||||
|
||||
|
||||
class A11(InnosiliconMake):
|
||||
raw_model = MinerModel.INNOSILICON.A11
|
||||
|
||||
expected_hashboards = 4
|
||||
24
pyasic/miners/device/models/innosilicon/A11X/A11M.py
Normal file
24
pyasic/miners/device/models/innosilicon/A11X/A11M.py
Normal file
@@ -0,0 +1,24 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Copyright 2022 Upstream Data Inc -
|
||||
# -
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||
# you may not use this file except in compliance with the License. -
|
||||
# You may obtain a copy of the License at -
|
||||
# -
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||
# -
|
||||
# Unless required by applicable law or agreed to in writing, software -
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
from pyasic.device.models import MinerModel
|
||||
from pyasic.miners.device.makes import InnosiliconMake
|
||||
|
||||
|
||||
class A11MX(InnosiliconMake):
|
||||
raw_model = MinerModel.INNOSILICON.A11MX
|
||||
|
||||
expected_hashboards = 4
|
||||
expected_chips = 8
|
||||
17
pyasic/miners/device/models/innosilicon/A11X/__init__.py
Normal file
17
pyasic/miners/device/models/innosilicon/A11X/__init__.py
Normal file
@@ -0,0 +1,17 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Copyright 2022 Upstream Data Inc -
|
||||
# -
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||
# you may not use this file except in compliance with the License. -
|
||||
# You may obtain a copy of the License at -
|
||||
# -
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||
# -
|
||||
# Unless required by applicable law or agreed to in writing, software -
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
from .A11 import *
|
||||
from .A11M import *
|
||||
@@ -15,4 +15,5 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from .A10X import *
|
||||
from .A11X import *
|
||||
from .T3X import *
|
||||
|
||||
@@ -78,6 +78,12 @@ class M50VH80(WhatsMinerMake):
|
||||
expected_chips = 111
|
||||
|
||||
|
||||
class M50VH90(WhatsMinerMake):
|
||||
raw_model = MinerModel.WHATSMINER.M50VH90
|
||||
|
||||
expected_chips = 117
|
||||
|
||||
|
||||
class M50VJ10(WhatsMinerMake):
|
||||
raw_model = MinerModel.WHATSMINER.M50VJ10
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ from .M50 import (
|
||||
M50VH60,
|
||||
M50VH70,
|
||||
M50VH80,
|
||||
M50VH90,
|
||||
M50VJ10,
|
||||
M50VJ20,
|
||||
M50VJ30,
|
||||
|
||||
@@ -24,6 +24,8 @@ class M60VK10(WhatsMinerMake):
|
||||
class M60VK20(WhatsMinerMake):
|
||||
raw_model = MinerModel.WHATSMINER.M60VK20
|
||||
|
||||
expected_chips = 172
|
||||
|
||||
|
||||
class M60VK30(WhatsMinerMake):
|
||||
raw_model = MinerModel.WHATSMINER.M60VK30
|
||||
|
||||
@@ -20,6 +20,7 @@ import enum
|
||||
import ipaddress
|
||||
import json
|
||||
import re
|
||||
import warnings
|
||||
from typing import Any, AsyncGenerator, Callable
|
||||
|
||||
import anyio
|
||||
@@ -66,14 +67,19 @@ MINER_CLASSES = {
|
||||
"ANTMINER D3": CGMinerD3,
|
||||
"ANTMINER HS3": BMMinerHS3,
|
||||
"ANTMINER L3+": BMMinerL3Plus,
|
||||
"ANTMINER KA3": BMMinerKA3,
|
||||
"ANTMINER KS3": BMMinerKS3,
|
||||
"ANTMINER DR5": CGMinerDR5,
|
||||
"ANTMINER KS5": BMMinerKS5,
|
||||
"ANTMINER L7": BMMinerL7,
|
||||
"ANTMINER K7": BMMinerK7,
|
||||
"ANTMINER E9 PRO": BMMinerE9Pro,
|
||||
"ANTMINER S9": BMMinerS9,
|
||||
"ANTMINER S9I": BMMinerS9i,
|
||||
"ANTMINER S9J": BMMinerS9j,
|
||||
"ANTMINER T9": BMMinerT9,
|
||||
"ANTMINER Z15": CGMinerZ15,
|
||||
"ANTMINER Z15 PRO": BMMinerZ15Pro,
|
||||
"ANTMINER S17": BMMinerS17,
|
||||
"ANTMINER S17+": BMMinerS17Plus,
|
||||
"ANTMINER S17 PRO": BMMinerS17Pro,
|
||||
@@ -271,6 +277,7 @@ MINER_CLASSES = {
|
||||
"M50VH60": BTMinerM50VH60,
|
||||
"M50VH70": BTMinerM50VH70,
|
||||
"M50VH80": BTMinerM50VH80,
|
||||
"M50VH90": BTMinerM50VH90,
|
||||
"M50VJ10": BTMinerM50VJ10,
|
||||
"M50VJ20": BTMinerM50VJ20,
|
||||
"M50VJ30": BTMinerM50VJ30,
|
||||
@@ -338,6 +345,8 @@ MINER_CLASSES = {
|
||||
None: type("InnosiliconUnknown", (Innosilicon, InnosiliconMake), {}),
|
||||
"T3H+": InnosiliconT3HPlus,
|
||||
"A10X": InnosiliconA10X,
|
||||
"A11": InnosiliconA11,
|
||||
"A11MX": InnosiliconA11MX,
|
||||
},
|
||||
MinerTypes.GOLDSHELL: {
|
||||
None: type("GoldshellUnknown", (GoldshellMiner, GoldshellMake), {}),
|
||||
@@ -390,6 +399,7 @@ MINER_CLASSES = {
|
||||
"ANTMINER S19 PRO": VNishS19Pro,
|
||||
"ANTMINER S19J": VNishS19j,
|
||||
"ANTMINER S19J PRO": VNishS19jPro,
|
||||
"ANTMINER S19J PRO BB": VNishS19jPro,
|
||||
"ANTMINER S19A": VNishS19a,
|
||||
"ANTMINER S19A PRO": VNishS19aPro,
|
||||
"ANTMINER S19 PRO HYD.": VNishS19ProHydro,
|
||||
@@ -457,7 +467,15 @@ MINER_CLASSES = {
|
||||
},
|
||||
MinerTypes.ICERIVER: {
|
||||
None: type("IceRiverUnknown", (IceRiver, IceRiverMake), {}),
|
||||
"KS0": IceRiverKS0,
|
||||
"KS1": IceRiverKS1,
|
||||
"KS2": IceRiverKS2,
|
||||
"KS3": IceRiverKS3,
|
||||
"KS3L": IceRiverKS3L,
|
||||
"KS3M": IceRiverKS3M,
|
||||
"KS5": IceRiverKS5,
|
||||
"KS5L": IceRiverKS5L,
|
||||
"KS5M": IceRiverKS5M,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -536,6 +554,7 @@ class MinerFactory:
|
||||
MinerTypes.AURADINE: self.get_miner_model_auradine,
|
||||
MinerTypes.MARATHON: self.get_miner_model_marathon,
|
||||
MinerTypes.BITAXE: self.get_miner_model_bitaxe,
|
||||
MinerTypes.ICERIVER: self.get_miner_model_iceriver,
|
||||
}
|
||||
fn = miner_model_fns.get(miner_type)
|
||||
|
||||
@@ -617,6 +636,10 @@ class MinerFactory:
|
||||
return MinerTypes.WHATSMINER
|
||||
if "Braiins OS" in web_text:
|
||||
return MinerTypes.BRAIINS_OS
|
||||
if "Luxor Firmware" in web_text:
|
||||
return MinerTypes.LUX_OS
|
||||
if "<TITLE>用户界面</TITLE>" in web_text:
|
||||
return MinerTypes.ICERIVER
|
||||
if "AxeOS" in web_text:
|
||||
return MinerTypes.BITAXE
|
||||
if "cloud-box" in web_text:
|
||||
@@ -631,8 +654,6 @@ class MinerFactory:
|
||||
return MinerTypes.INNOSILICON
|
||||
if "Miner UI" in web_text:
|
||||
return MinerTypes.AURADINE
|
||||
if "<TITLE>用户界面</TITLE>" in web_text:
|
||||
return MinerTypes.ICERIVER
|
||||
|
||||
async def _get_miner_socket(self, ip: str) -> MinerTypes | None:
|
||||
commands = ["version", "devdetails"]
|
||||
@@ -699,10 +720,10 @@ class MinerFactory:
|
||||
return MinerTypes.BRAIINS_OS
|
||||
if "BTMINER" in upper_data or "BITMICRO" in upper_data:
|
||||
return MinerTypes.WHATSMINER
|
||||
if "HIVEON" in upper_data:
|
||||
return MinerTypes.HIVEON
|
||||
if "LUXMINER" in upper_data:
|
||||
return MinerTypes.LUX_OS
|
||||
if "HIVEON" in upper_data:
|
||||
return MinerTypes.HIVEON
|
||||
if "KAONSU" in upper_data:
|
||||
return MinerTypes.MARATHON
|
||||
if "ANTMINER" in upper_data and "DEVDETAILS" not in upper_data:
|
||||
@@ -713,11 +734,13 @@ class MinerFactory:
|
||||
or "BFGMINER" in upper_data
|
||||
):
|
||||
return MinerTypes.GOLDSHELL
|
||||
if "INNOMINER" in upper_data:
|
||||
return MinerTypes.INNOSILICON
|
||||
if "AVALON" in upper_data:
|
||||
return MinerTypes.AVALONMINER
|
||||
if "GCMINER" in upper_data or "FLUXOS" in upper_data:
|
||||
return MinerTypes.AURADINE
|
||||
if "VNISH" in upper_data or "DEVICE PATH" in upper_data:
|
||||
if "VNISH" in upper_data:
|
||||
return MinerTypes.VNISH
|
||||
|
||||
async def send_web_command(
|
||||
@@ -805,12 +828,8 @@ class MinerFactory:
|
||||
# fix an error with a btminer return having a missing comma. (2023-01-06 version)
|
||||
str_data = str_data.replace('""temp0', '","temp0')
|
||||
# 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("1nfo", "info")
|
||||
str_data = str_data.replace("nano", "n4no")
|
||||
str_data = str_data.replace("nan", "0")
|
||||
str_data = str_data.replace("n4no", "nano")
|
||||
str_data = str_data.replace('"inf"', "0")
|
||||
str_data = str_data.replace('"nan"', "0")
|
||||
# fix whatever this garbage from avalonminers is `,"id":1}`
|
||||
if str_data.startswith(","):
|
||||
str_data = f"{{{str_data[1:]}"
|
||||
@@ -835,6 +854,10 @@ class MinerFactory:
|
||||
return MINER_CLASSES[miner_type][str(miner_model).upper()](ip)
|
||||
except LookupError:
|
||||
if miner_type in MINER_CLASSES:
|
||||
warnings.warn(
|
||||
f"Partially supported miner found: {miner_model}, please open an issue with miner data "
|
||||
f"and this model on GitHub (https://github.com/UpstreamData/pyasic/issues)."
|
||||
)
|
||||
return MINER_CLASSES[miner_type][None](ip)
|
||||
return UnknownMiner(str(ip))
|
||||
|
||||
@@ -925,10 +948,19 @@ class MinerFactory:
|
||||
async with httpx.AsyncClient(transport=settings.transport()) as session:
|
||||
auth_req = await session.post(
|
||||
f"http://{ip}/api/auth",
|
||||
data={"username": "admin", "password": "admin"},
|
||||
data={
|
||||
"username": "admin",
|
||||
"password": settings.get(
|
||||
"default_innosilicon_web_password", "admin"
|
||||
),
|
||||
},
|
||||
)
|
||||
auth = auth_req.json()["jwt"]
|
||||
except (httpx.HTTPError, LookupError):
|
||||
return
|
||||
|
||||
try:
|
||||
async with httpx.AsyncClient(transport=settings.transport()) as session:
|
||||
web_data = (
|
||||
await session.post(
|
||||
f"http://{ip}/api/type",
|
||||
@@ -939,6 +971,18 @@ class MinerFactory:
|
||||
return web_data["type"]
|
||||
except (httpx.HTTPError, LookupError):
|
||||
pass
|
||||
try:
|
||||
async with httpx.AsyncClient(transport=settings.transport()) as session:
|
||||
web_data = (
|
||||
await session.post(
|
||||
f"http://{ip}/overview",
|
||||
headers={"Authorization": "Bearer " + auth},
|
||||
data={},
|
||||
)
|
||||
).json()
|
||||
return web_data["type"]
|
||||
except (httpx.HTTPError, LookupError):
|
||||
pass
|
||||
|
||||
async def get_miner_model_braiins_os(self, ip: str) -> str | None:
|
||||
sock_json_data = await self.send_api_command(ip, "devdetails")
|
||||
@@ -1052,6 +1096,39 @@ class MinerFactory:
|
||||
except (TypeError, LookupError):
|
||||
pass
|
||||
|
||||
async def get_miner_model_iceriver(self, ip: str) -> str | None:
|
||||
async with httpx.AsyncClient(transport=settings.transport()) as client:
|
||||
try:
|
||||
# auth
|
||||
await client.post(
|
||||
f"http://{ip}/user/loginpost",
|
||||
params={
|
||||
"post": "6",
|
||||
"user": "admin",
|
||||
"pwd": settings.get(
|
||||
"default_iceriver_web_password", "12345678"
|
||||
),
|
||||
},
|
||||
)
|
||||
except httpx.HTTPError:
|
||||
return None
|
||||
try:
|
||||
resp = await client.post(
|
||||
f"http://{ip}:/user/userpanel", params={"post": "4"}
|
||||
)
|
||||
if not resp.status_code == 200:
|
||||
return
|
||||
result = resp.json()
|
||||
software_ver = result["data"]["softver1"]
|
||||
split_ver = software_ver.split("_")
|
||||
if split_ver[-1] == "miner":
|
||||
miner_ver = split_ver[-2]
|
||||
else:
|
||||
miner_ver = split_ver[-1].replace("miner", "")
|
||||
return miner_ver.upper()
|
||||
except httpx.HTTPError:
|
||||
pass
|
||||
|
||||
|
||||
miner_factory = MinerFactory()
|
||||
|
||||
|
||||
6
pyasic/miners/iceriver/iceminer/KSX/KS0.py
Normal file
6
pyasic/miners/iceriver/iceminer/KSX/KS0.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from pyasic.miners.backends.iceriver import IceRiver
|
||||
from pyasic.miners.device.models import KS0
|
||||
|
||||
|
||||
class IceRiverKS0(IceRiver, KS0):
|
||||
pass
|
||||
6
pyasic/miners/iceriver/iceminer/KSX/KS1.py
Normal file
6
pyasic/miners/iceriver/iceminer/KSX/KS1.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from pyasic.miners.backends.iceriver import IceRiver
|
||||
from pyasic.miners.device.models import KS1
|
||||
|
||||
|
||||
class IceRiverKS1(IceRiver, KS1):
|
||||
pass
|
||||
14
pyasic/miners/iceriver/iceminer/KSX/KS3.py
Normal file
14
pyasic/miners/iceriver/iceminer/KSX/KS3.py
Normal file
@@ -0,0 +1,14 @@
|
||||
from pyasic.miners.backends.iceriver import IceRiver
|
||||
from pyasic.miners.device.models.iceriver import KS3, KS3L, KS3M
|
||||
|
||||
|
||||
class IceRiverKS3(IceRiver, KS3):
|
||||
pass
|
||||
|
||||
|
||||
class IceRiverKS3L(IceRiver, KS3L):
|
||||
pass
|
||||
|
||||
|
||||
class IceRiverKS3M(IceRiver, KS3M):
|
||||
pass
|
||||
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
|
||||
@@ -1 +1,5 @@
|
||||
from .KS0 import IceRiverKS0
|
||||
from .KS1 import IceRiverKS1
|
||||
from .KS2 import IceRiverKS2
|
||||
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
|
||||
22
pyasic/miners/innosilicon/cgminer/A11X/A11M.py
Normal file
22
pyasic/miners/innosilicon/cgminer/A11X/A11M.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Copyright 2022 Upstream Data Inc -
|
||||
# -
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||
# you may not use this file except in compliance with the License. -
|
||||
# You may obtain a copy of the License at -
|
||||
# -
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||
# -
|
||||
# Unless required by applicable law or agreed to in writing, software -
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.backends.innosilicon import Innosilicon
|
||||
from pyasic.miners.device.models import A11MX
|
||||
|
||||
|
||||
class InnosiliconA11MX(Innosilicon, A11MX):
|
||||
pass
|
||||
2
pyasic/miners/innosilicon/cgminer/A11X/__init__.py
Normal file
2
pyasic/miners/innosilicon/cgminer/A11X/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
from .A11 import InnosiliconA11
|
||||
from .A11M import InnosiliconA11MX
|
||||
@@ -15,4 +15,5 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from .A10X import *
|
||||
from .A11X import *
|
||||
from .T3X import *
|
||||
|
||||
@@ -26,6 +26,7 @@ from pyasic.miners.device.models import (
|
||||
M50VH60,
|
||||
M50VH70,
|
||||
M50VH80,
|
||||
M50VH90,
|
||||
M50VJ10,
|
||||
M50VJ20,
|
||||
M50VJ30,
|
||||
@@ -72,6 +73,10 @@ class BTMinerM50VH80(M5X, M50VH80):
|
||||
pass
|
||||
|
||||
|
||||
class BTMinerM50VH90(M5X, M50VH90):
|
||||
pass
|
||||
|
||||
|
||||
class BTMinerM50VJ10(M5X, M50VJ10):
|
||||
pass
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ from .M50 import (
|
||||
BTMinerM50VH60,
|
||||
BTMinerM50VH70,
|
||||
BTMinerM50VH80,
|
||||
BTMinerM50VH90,
|
||||
BTMinerM50VJ10,
|
||||
BTMinerM50VJ20,
|
||||
BTMinerM50VJ30,
|
||||
|
||||
@@ -268,12 +268,8 @@ If you are sure you want to use this command please use API.send_command("{comma
|
||||
# fix an error with a btminer return having a missing comma. (2023-01-06 version)
|
||||
str_data = str_data.replace('""temp0', '","temp0')
|
||||
# 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("1nfo", "info")
|
||||
str_data = str_data.replace("nano", "n4no")
|
||||
str_data = str_data.replace("nan", "0")
|
||||
str_data = str_data.replace("n4no", "nano")
|
||||
str_data = str_data.replace('"inf"', "0")
|
||||
str_data = str_data.replace('"nan"', "0")
|
||||
|
||||
# fix whatever this garbage from avalonminers is `,"id":1}`
|
||||
if str_data.startswith(","):
|
||||
|
||||
@@ -22,8 +22,8 @@ import hashlib
|
||||
import json
|
||||
import logging
|
||||
import re
|
||||
from typing import Literal, Union
|
||||
import struct
|
||||
from typing import Literal, Union
|
||||
|
||||
import httpx
|
||||
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
||||
|
||||
@@ -13,8 +13,9 @@
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
from typing import Literal
|
||||
from typing import Literal, Optional, Union
|
||||
|
||||
from pyasic import APIError
|
||||
from pyasic.rpc.base import BaseMinerRPCAPI
|
||||
|
||||
|
||||
@@ -32,6 +33,48 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
||||
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:
|
||||
"""Add a pool group.
|
||||
<details>
|
||||
@@ -45,7 +88,7 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
||||
Confirmation of adding a pool group.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("addgroup", parameters=f"{name},{quota}")
|
||||
return await self.send_command("addgroup", name, quota)
|
||||
|
||||
async def addpool(
|
||||
self, url: str, user: str, pwd: str = "", group_id: str = None
|
||||
@@ -67,7 +110,7 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
||||
pool_data = [url, user, pwd]
|
||||
if group_id is not None:
|
||||
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:
|
||||
"""Get data for ASC device n.
|
||||
@@ -81,7 +124,7 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
||||
The data for ASC device n.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("asc", parameters=n)
|
||||
return await self.send_command("asc", n)
|
||||
|
||||
async def asccount(self) -> dict:
|
||||
"""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
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("check", parameters=command)
|
||||
return await self.send_command("check", command)
|
||||
|
||||
async def coin(self) -> dict:
|
||||
"""Get information on the current coin.
|
||||
@@ -137,19 +180,38 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
||||
"""
|
||||
return await self.send_command("config")
|
||||
|
||||
async def curtail(self, session_id: str) -> dict:
|
||||
"""Put the miner into sleep mode. Requires a session_id from logon.
|
||||
async def curtail(self) -> dict:
|
||||
"""Put the miner into sleep mode.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
session_id: Session id from the logon command.
|
||||
|
||||
Returns:
|
||||
A confirmation of putting the miner to sleep.
|
||||
</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:
|
||||
"""Get data on all devices with their static details.
|
||||
@@ -185,7 +247,7 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
||||
A confirmation of diabling the pool.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("disablepool", parameters=n)
|
||||
return await self.send_command("disablepool", n)
|
||||
|
||||
async def edevs(self) -> dict:
|
||||
"""Alias for devs"""
|
||||
@@ -203,7 +265,7 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
||||
A confirmation of enabling pool n.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("enablepool", parameters=n)
|
||||
return await self.send_command("enablepool", n)
|
||||
|
||||
async def estats(self) -> dict:
|
||||
"""Alias for stats"""
|
||||
@@ -220,13 +282,14 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
||||
"""
|
||||
return await self.send_command("fans")
|
||||
|
||||
async def fanset(self, session_id: str, speed: int, min_fans: int = None) -> dict:
|
||||
"""Set fan control. Requires a session_id from logon.
|
||||
async def fanset(
|
||||
self, speed: int = None, min_fans: int = None, power_off_speed: int = None
|
||||
) -> dict:
|
||||
"""Set fan control.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
session_id: Session id from the logon command.
|
||||
speed: The fan speed to set. Use -1 to set automatically.
|
||||
min_fans: The minimum number of fans to use. Optional.
|
||||
|
||||
@@ -234,10 +297,14 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
||||
A confirmation of setting fan control values.
|
||||
</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:
|
||||
fanset_data.append(str(min_fans))
|
||||
return await self.send_command("fanset", parameters=",".join(fanset_data))
|
||||
fanset_data.append(f"min_fans={min_fans}")
|
||||
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:
|
||||
"""Get frequency data for a board and chips.
|
||||
@@ -255,17 +322,14 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
||||
frequencyget_data = [str(board_n)]
|
||||
if chip_n is not None:
|
||||
frequencyget_data.append(str(chip_n))
|
||||
return await self.send_command(
|
||||
"frequencyget", parameters=",".join(frequencyget_data)
|
||||
)
|
||||
return await self.send_command("frequencyget", *frequencyget_data)
|
||||
|
||||
async def frequencyset(self, session_id: str, board_n: int, freq: int) -> dict:
|
||||
"""Set frequency. Requires a session_id from logon.
|
||||
async def frequencyset(self, board_n: int, freq: int) -> dict:
|
||||
"""Set frequency.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
session_id: Session id from the logon command.
|
||||
board_n: The board number to set frequency on.
|
||||
freq: The frequency to set.
|
||||
|
||||
@@ -273,26 +337,21 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
||||
A confirmation of setting frequency values.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command(
|
||||
"frequencyset", parameters=f"{session_id},{board_n},{freq}"
|
||||
)
|
||||
return await self.send_privileged_command("frequencyset", board_n, freq)
|
||||
|
||||
async def frequencystop(self, session_id: str, board_n: int) -> dict:
|
||||
"""Stop set frequency. Requires a session_id from logon.
|
||||
async def frequencystop(self, board_n: int) -> dict:
|
||||
"""Stop set frequency.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
session_id: Session id from the logon command.
|
||||
board_n: The board number to set frequency on.
|
||||
|
||||
Returns:
|
||||
A confirmation of stopping frequencyset value.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command(
|
||||
"frequencystop", parameters=f"{session_id},{board_n}"
|
||||
)
|
||||
return await self.send_privileged_command("frequencystop", board_n)
|
||||
|
||||
async def groupquota(self, group_n: int, quota: int) -> dict:
|
||||
"""Set a group's quota.
|
||||
@@ -307,7 +366,7 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
||||
A confirmation of setting quota value.
|
||||
</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:
|
||||
"""Get pool group data.
|
||||
@@ -336,19 +395,14 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
||||
healthchipget_data = [str(board_n)]
|
||||
if chip_n is not None:
|
||||
healthchipget_data.append(str(chip_n))
|
||||
return await self.send_command(
|
||||
"healthchipget", parameters=",".join(healthchipget_data)
|
||||
)
|
||||
return await self.send_command("healthchipget", *healthchipget_data)
|
||||
|
||||
async def healthchipset(
|
||||
self, session_id: str, board_n: int, chip_n: int = None
|
||||
) -> dict:
|
||||
"""Select the next chip to have its health checked. Requires a session_id from logon.
|
||||
async def healthchipset(self, board_n: int, chip_n: int = None) -> dict:
|
||||
"""Select the next chip to have its health checked.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
session_id: Session id from the logon command.
|
||||
board_n: The board number to next get chip health of.
|
||||
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.
|
||||
</details>
|
||||
"""
|
||||
healthchipset_data = [session_id, str(board_n)]
|
||||
healthchipset_data = [str(board_n)]
|
||||
if chip_n is not None:
|
||||
healthchipset_data.append(str(chip_n))
|
||||
return await self.send_command(
|
||||
"healthchipset", parameters=",".join(healthchipset_data)
|
||||
)
|
||||
return await self.send_privileged_command("healthchipset", *healthchipset_data)
|
||||
|
||||
async def healthctrl(self) -> dict:
|
||||
"""Get health check config.
|
||||
@@ -374,15 +426,12 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
||||
"""
|
||||
return await self.send_command("healthctrl")
|
||||
|
||||
async def healthctrlset(
|
||||
self, session_id: str, num_readings: int, amplified_factor: float
|
||||
) -> dict:
|
||||
"""Set health control config. Requires a session_id from logon.
|
||||
async def healthctrlset(self, num_readings: int, amplified_factor: float) -> dict:
|
||||
"""Set health control config.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
session_id: Session id from the logon command.
|
||||
num_readings: The minimum number of readings for evaluation.
|
||||
amplified_factor: Performance factor of the evaluation.
|
||||
|
||||
@@ -390,9 +439,8 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
||||
A confirmation of setting health control config.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command(
|
||||
"healthctrlset",
|
||||
parameters=f"{session_id},{num_readings},{amplified_factor}",
|
||||
return await self.send_privileged_command(
|
||||
"healthctrlset", num_readings, amplified_factor
|
||||
)
|
||||
|
||||
async def kill(self) -> dict:
|
||||
@@ -419,16 +467,14 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
||||
|
||||
async def ledset(
|
||||
self,
|
||||
session_id: str,
|
||||
color: Literal["red"],
|
||||
state: Literal["on", "off", "blink"],
|
||||
) -> dict:
|
||||
"""Set led. Requires a session_id from logon.
|
||||
"""Set led.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
session_id: Session id from the logon command.
|
||||
color: The color LED to set. Can be "red".
|
||||
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.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command(
|
||||
"ledset", parameters=f"{session_id},{color},{state}"
|
||||
)
|
||||
return await self.send_privileged_command("ledset", color, state)
|
||||
|
||||
async def limits(self) -> dict:
|
||||
"""Get max and min values of config parameters.
|
||||
@@ -451,8 +495,8 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
||||
"""
|
||||
return await self.send_command("limits")
|
||||
|
||||
async def logoff(self, session_id: str) -> dict:
|
||||
"""Log off of a session. Requires a session id from an active session.
|
||||
async def logoff(self) -> dict:
|
||||
"""Log off of a session.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
@@ -463,7 +507,9 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
||||
Confirmation of logging off a session.
|
||||
</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:
|
||||
"""Get or create a session.
|
||||
@@ -510,13 +556,12 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
||||
"""
|
||||
return await self.send_command("profiles")
|
||||
|
||||
async def profileset(self, session_id: str, board_n: int, profile: str) -> dict:
|
||||
"""Set active profile for a board. Requires a session_id from logon.
|
||||
async def profileset(self, board_n: int, profile: str) -> dict:
|
||||
"""Set active profile for a board.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
session_id: Session id from the logon command.
|
||||
board_n: The board to set the profile on.
|
||||
profile: The profile name to use.
|
||||
|
||||
@@ -524,17 +569,14 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
||||
A confirmation of setting the profile on board_n.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command(
|
||||
"profileset", parameters=f"{session_id},{board_n},{profile}"
|
||||
)
|
||||
return await self.send_privileged_command("profileset", board_n, profile)
|
||||
|
||||
async def reboot(self, session_id: str, board_n: int, delay_s: int = None) -> dict:
|
||||
"""Reboot a board. Requires a session_id from logon.
|
||||
async def reboot(self, board_n: int, delay_s: int = None) -> dict:
|
||||
"""Reboot a board.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
session_id: Session id from the logon command.
|
||||
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.
|
||||
|
||||
@@ -542,24 +584,21 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
||||
A confirmation of rebooting board_n.
|
||||
</details>
|
||||
"""
|
||||
reboot_data = [session_id, str(board_n)]
|
||||
reboot_data = [str(board_n)]
|
||||
if delay_s is not None:
|
||||
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:
|
||||
"""Reboot the miner. Requires a session_id from logon.
|
||||
async def rebootdevice(self) -> dict:
|
||||
"""Reboot the miner.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
session_id: Session id from the logon command.
|
||||
|
||||
Returns:
|
||||
A confirmation of rebooting the miner.
|
||||
</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:
|
||||
"""Remove a pool group.
|
||||
@@ -575,19 +614,16 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
||||
"""
|
||||
return await self.send_command("removegroup", parameters=group_id)
|
||||
|
||||
async def resetminer(self, session_id: str) -> dict:
|
||||
"""Restart the mining process. Requires a session_id from logon.
|
||||
async def resetminer(self) -> dict:
|
||||
"""Restart the mining process.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
session_id: Session id from the logon command.
|
||||
|
||||
Returns:
|
||||
A confirmation of restarting the mining process.
|
||||
</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:
|
||||
"""Remove a pool.
|
||||
@@ -614,7 +650,9 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
||||
"""
|
||||
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.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
@@ -629,7 +667,7 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command(
|
||||
"tempctrlset", parameters=f"{target},{hot},{dangerous}"
|
||||
"tempctrlset", target or "", hot or "", dangerous or ""
|
||||
)
|
||||
|
||||
async def stats(self) -> dict:
|
||||
@@ -668,7 +706,7 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
||||
A confirmation of switching to the pool.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command("switchpool", parameters=str(pool_id))
|
||||
return await self.send_command("switchpool", pool_id)
|
||||
|
||||
async def tempctrl(self) -> dict:
|
||||
"""Get temperature control data.
|
||||
@@ -716,15 +754,14 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
||||
Board voltage values.
|
||||
</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.
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Parameters:
|
||||
session_id: Session id from the logon command.
|
||||
board_n: The board to set the voltage on.
|
||||
voltage: The voltage to use.
|
||||
|
||||
@@ -732,23 +769,7 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
||||
A confirmation of setting the voltage.
|
||||
</details>
|
||||
"""
|
||||
return await self.send_command(
|
||||
"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)
|
||||
return await self.send_privileged_command("voltageset", board_n, voltage)
|
||||
|
||||
async def upgraderun(self):
|
||||
"""
|
||||
@@ -757,4 +778,4 @@ class LUXMinerRPCAPI(BaseMinerRPCAPI):
|
||||
Returns:
|
||||
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 json
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
import aiofiles
|
||||
import httpx
|
||||
from pathlib import Path
|
||||
|
||||
from pyasic import settings
|
||||
from pyasic.web.base import BaseWebAPI
|
||||
@@ -414,10 +415,7 @@ class AntminerOldWebAPI(BaseWebAPI):
|
||||
parameters = {
|
||||
"file": (file.name, file_content, "application/octet-stream"),
|
||||
"filename": file.name,
|
||||
"keep_settings": keep_settings
|
||||
"keep_settings": keep_settings,
|
||||
}
|
||||
|
||||
return await self.send_command(
|
||||
command="upgrade",
|
||||
**parameters
|
||||
)
|
||||
return await self.send_command(command="upgrade", **parameters)
|
||||
|
||||
93
pyasic/web/braiins_os/better_monkey.py
Normal file
93
pyasic/web/braiins_os/better_monkey.py
Normal file
@@ -0,0 +1,93 @@
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Any, Dict
|
||||
|
||||
from betterproto import DATETIME_ZERO, TYPE_MAP, TYPE_MESSAGE, Casing, Message
|
||||
|
||||
|
||||
# https://github.com/danielgtaylor/python-betterproto/pull/609
|
||||
def to_pydict(
|
||||
self, casing: Casing = Casing.CAMEL, include_default_values: bool = False
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Returns a python dict representation of this object.
|
||||
|
||||
Parameters
|
||||
-----------
|
||||
casing: :class:`Casing`
|
||||
The casing to use for key values. Default is :attr:`Casing.CAMEL` for
|
||||
compatibility purposes.
|
||||
include_default_values: :class:`bool`
|
||||
If ``True`` will include the default values of fields. Default is ``False``.
|
||||
E.g. an ``int32`` field will be included with a value of ``0`` if this is
|
||||
set to ``True``, otherwise this would be ignored.
|
||||
|
||||
Returns
|
||||
--------
|
||||
Dict[:class:`str`, Any]
|
||||
The python dict representation of this object.
|
||||
"""
|
||||
output: Dict[str, Any] = {}
|
||||
defaults = self._betterproto.default_gen
|
||||
for field_name, meta in self._betterproto.meta_by_field_name.items():
|
||||
field_is_repeated = defaults[field_name] is list
|
||||
try:
|
||||
value = getattr(self, field_name)
|
||||
except AttributeError:
|
||||
value = self._get_field_default(field_name)
|
||||
cased_name = casing(field_name).rstrip("_") # type: ignore
|
||||
if meta.proto_type == TYPE_MESSAGE:
|
||||
if isinstance(value, datetime):
|
||||
if (
|
||||
value != DATETIME_ZERO
|
||||
or include_default_values
|
||||
or self._include_default_value_for_oneof(
|
||||
field_name=field_name, meta=meta
|
||||
)
|
||||
):
|
||||
output[cased_name] = value
|
||||
elif isinstance(value, timedelta):
|
||||
if (
|
||||
value != timedelta(0)
|
||||
or include_default_values
|
||||
or self._include_default_value_for_oneof(
|
||||
field_name=field_name, meta=meta
|
||||
)
|
||||
):
|
||||
output[cased_name] = value
|
||||
elif meta.wraps:
|
||||
if value is not None or include_default_values:
|
||||
output[cased_name] = value
|
||||
elif field_is_repeated:
|
||||
# Convert each item.
|
||||
value = [i.to_pydict(casing, include_default_values) for i in value]
|
||||
if value or include_default_values:
|
||||
output[cased_name] = value
|
||||
elif value is None:
|
||||
if include_default_values:
|
||||
output[cased_name] = None
|
||||
elif (
|
||||
value._serialized_on_wire
|
||||
or include_default_values
|
||||
or self._include_default_value_for_oneof(
|
||||
field_name=field_name, meta=meta
|
||||
)
|
||||
):
|
||||
output[cased_name] = value.to_pydict(casing, include_default_values)
|
||||
elif meta.proto_type == TYPE_MAP:
|
||||
for k in value:
|
||||
if hasattr(value[k], "to_pydict"):
|
||||
value[k] = value[k].to_pydict(casing, include_default_values)
|
||||
|
||||
if value or include_default_values:
|
||||
output[cased_name] = value
|
||||
elif (
|
||||
value != self._get_field_default(field_name)
|
||||
or include_default_values
|
||||
or self._include_default_value_for_oneof(field_name=field_name, meta=meta)
|
||||
):
|
||||
output[cased_name] = value
|
||||
return output
|
||||
|
||||
|
||||
def patch():
|
||||
Message.to_pydict = to_pydict
|
||||
@@ -26,6 +26,9 @@ from grpclib.client import Channel
|
||||
from pyasic import settings
|
||||
from pyasic.errors import APIError
|
||||
from pyasic.web.base import BaseWebAPI
|
||||
from pyasic.web.braiins_os.better_monkey import patch
|
||||
|
||||
patch()
|
||||
|
||||
from .proto.braiins.bos import *
|
||||
from .proto.braiins.bos.v1 import *
|
||||
@@ -206,7 +209,7 @@ class BOSerWebAPI(BaseWebAPI):
|
||||
async def set_immersion_mode(
|
||||
self,
|
||||
enable: bool,
|
||||
save_action: SaveAction = SaveAction.SAVE_ACTION_SAVE_AND_APPLY,
|
||||
save_action: SaveAction = SaveAction.SAVE_AND_APPLY,
|
||||
) -> dict:
|
||||
return await self.send_command(
|
||||
"set_immersion_mode",
|
||||
@@ -227,7 +230,7 @@ class BOSerWebAPI(BaseWebAPI):
|
||||
)
|
||||
|
||||
async def set_default_power_target(
|
||||
self, save_action: SaveAction = SaveAction.SAVE_ACTION_SAVE_AND_APPLY
|
||||
self, save_action: SaveAction = SaveAction.SAVE_AND_APPLY
|
||||
) -> dict:
|
||||
return await self.send_command(
|
||||
"set_default_power_target",
|
||||
@@ -238,7 +241,7 @@ class BOSerWebAPI(BaseWebAPI):
|
||||
async def set_power_target(
|
||||
self,
|
||||
power_target: int,
|
||||
save_action: SaveAction = SaveAction.SAVE_ACTION_SAVE_AND_APPLY,
|
||||
save_action: SaveAction = SaveAction.SAVE_AND_APPLY,
|
||||
) -> dict:
|
||||
return await self.send_command(
|
||||
"set_power_target",
|
||||
@@ -251,7 +254,7 @@ class BOSerWebAPI(BaseWebAPI):
|
||||
async def increment_power_target(
|
||||
self,
|
||||
power_target_increment: int,
|
||||
save_action: SaveAction = SaveAction.SAVE_ACTION_SAVE_AND_APPLY,
|
||||
save_action: SaveAction = SaveAction.SAVE_AND_APPLY,
|
||||
) -> dict:
|
||||
return await self.send_command(
|
||||
"increment_power_target",
|
||||
@@ -265,7 +268,7 @@ class BOSerWebAPI(BaseWebAPI):
|
||||
async def decrement_power_target(
|
||||
self,
|
||||
power_target_decrement: int,
|
||||
save_action: SaveAction = SaveAction.SAVE_ACTION_SAVE_AND_APPLY,
|
||||
save_action: SaveAction = SaveAction.SAVE_AND_APPLY,
|
||||
) -> dict:
|
||||
return await self.send_command(
|
||||
"decrement_power_target",
|
||||
@@ -277,7 +280,7 @@ class BOSerWebAPI(BaseWebAPI):
|
||||
)
|
||||
|
||||
async def set_default_hashrate_target(
|
||||
self, save_action: SaveAction = SaveAction.SAVE_ACTION_SAVE_AND_APPLY
|
||||
self, save_action: SaveAction = SaveAction.SAVE_AND_APPLY
|
||||
) -> dict:
|
||||
return await self.send_command(
|
||||
"set_default_hashrate_target",
|
||||
@@ -288,7 +291,7 @@ class BOSerWebAPI(BaseWebAPI):
|
||||
async def set_hashrate_target(
|
||||
self,
|
||||
hashrate_target: float,
|
||||
save_action: SaveAction = SaveAction.SAVE_ACTION_SAVE_AND_APPLY,
|
||||
save_action: SaveAction = SaveAction.SAVE_AND_APPLY,
|
||||
) -> dict:
|
||||
return await self.send_command(
|
||||
"set_hashrate_target",
|
||||
@@ -302,7 +305,7 @@ class BOSerWebAPI(BaseWebAPI):
|
||||
async def increment_hashrate_target(
|
||||
self,
|
||||
hashrate_target_increment: int,
|
||||
save_action: SaveAction = SaveAction.SAVE_ACTION_SAVE_AND_APPLY,
|
||||
save_action: SaveAction = SaveAction.SAVE_AND_APPLY,
|
||||
) -> dict:
|
||||
return await self.send_command(
|
||||
"increment_hashrate_target",
|
||||
@@ -318,7 +321,7 @@ class BOSerWebAPI(BaseWebAPI):
|
||||
async def decrement_hashrate_target(
|
||||
self,
|
||||
hashrate_target_decrement: int,
|
||||
save_action: SaveAction = SaveAction.SAVE_ACTION_SAVE_AND_APPLY,
|
||||
save_action: SaveAction = SaveAction.SAVE_AND_APPLY,
|
||||
) -> dict:
|
||||
return await self.send_command(
|
||||
"decrement_hashrate_target",
|
||||
@@ -359,7 +362,7 @@ class BOSerWebAPI(BaseWebAPI):
|
||||
self,
|
||||
wattage_target: int = None,
|
||||
hashrate_target: int = None,
|
||||
save_action: SaveAction = SaveAction.SAVE_ACTION_SAVE_AND_APPLY,
|
||||
save_action: SaveAction = SaveAction.SAVE_AND_APPLY,
|
||||
) -> dict:
|
||||
if wattage_target is not None and hashrate_target is not None:
|
||||
logging.error(
|
||||
@@ -459,7 +462,7 @@ class BOSerWebAPI(BaseWebAPI):
|
||||
async def enable_hashboards(
|
||||
self,
|
||||
hashboard_ids: List[str],
|
||||
save_action: SaveAction = SaveAction.SAVE_ACTION_SAVE_AND_APPLY,
|
||||
save_action: SaveAction = SaveAction.SAVE_AND_APPLY,
|
||||
) -> dict:
|
||||
return await self.send_command(
|
||||
"enable_hashboards",
|
||||
@@ -472,7 +475,7 @@ class BOSerWebAPI(BaseWebAPI):
|
||||
async def disable_hashboards(
|
||||
self,
|
||||
hashboard_ids: List[str],
|
||||
save_action: SaveAction = SaveAction.SAVE_ACTION_SAVE_AND_APPLY,
|
||||
save_action: SaveAction = SaveAction.SAVE_AND_APPLY,
|
||||
) -> dict:
|
||||
return await self.send_command(
|
||||
"disable_hashboards",
|
||||
@@ -485,7 +488,7 @@ class BOSerWebAPI(BaseWebAPI):
|
||||
async def set_pool_groups(
|
||||
self,
|
||||
pool_groups: List[PoolGroupConfiguration],
|
||||
save_action: SaveAction = SaveAction.SAVE_ACTION_SAVE_AND_APPLY,
|
||||
save_action: SaveAction = SaveAction.SAVE_AND_APPLY,
|
||||
) -> dict:
|
||||
return await self.send_command(
|
||||
"set_pool_groups",
|
||||
|
||||
@@ -18,7 +18,7 @@ if TYPE_CHECKING:
|
||||
|
||||
@dataclass(eq=False, repr=False)
|
||||
class ApiVersion(betterproto.Message):
|
||||
"""LATEST_API_VERSION=1.2.0"""
|
||||
"""LATEST_API_VERSION=1.3.0"""
|
||||
|
||||
major: int = betterproto.uint64_field(1)
|
||||
minor: int = betterproto.uint64_field(2)
|
||||
|
||||
@@ -20,125 +20,129 @@ if TYPE_CHECKING:
|
||||
class SaveAction(betterproto.Enum):
|
||||
"""Save action for different operations"""
|
||||
|
||||
SAVE_ACTION_UNSPECIFIED = 0
|
||||
SAVE_ACTION_SAVE = 1
|
||||
SAVE_ACTION_SAVE_AND_APPLY = 2
|
||||
SAVE_ACTION_SAVE_AND_FORCE_APPLY = 3
|
||||
UNSPECIFIED = 0
|
||||
SAVE = 1
|
||||
SAVE_AND_APPLY = 2
|
||||
SAVE_AND_FORCE_APPLY = 3
|
||||
|
||||
|
||||
class CoolingMode(betterproto.Enum):
|
||||
COOLING_MODE_UNSPECIFIED = 0
|
||||
COOLING_MODE_AUTO = 1
|
||||
COOLING_MODE_MANUAL = 2
|
||||
COOLING_MODE_DISABLED = 3
|
||||
UNSPECIFIED = 0
|
||||
AUTO = 1
|
||||
MANUAL = 2
|
||||
DISABLED = 3
|
||||
|
||||
|
||||
class SensorLocation(betterproto.Enum):
|
||||
SENSOR_LOCATION_UNSPECIFIED = 0
|
||||
SENSOR_LOCATION_CHIP = 1
|
||||
SENSOR_LOCATION_PCB = 2
|
||||
UNSPECIFIED = 0
|
||||
CHIP = 1
|
||||
PCB = 2
|
||||
|
||||
|
||||
class TunerMode(betterproto.Enum):
|
||||
TUNER_MODE_UNSPECIFIED = 0
|
||||
TUNER_MODE_POWER_TARGET = 1
|
||||
TUNER_MODE_HASHRATE_TARGET = 2
|
||||
UNSPECIFIED = 0
|
||||
POWER_TARGET = 1
|
||||
HASHRATE_TARGET = 2
|
||||
|
||||
|
||||
class TunerState(betterproto.Enum):
|
||||
TUNER_STATE_UNSPECIFIED = 0
|
||||
TUNER_STATE_DISABLED = 1
|
||||
TUNER_STATE_STABLE = 2
|
||||
TUNER_STATE_TUNING = 3
|
||||
TUNER_STATE_ERROR = 4
|
||||
UNSPECIFIED = 0
|
||||
DISABLED = 1
|
||||
STABLE = 2
|
||||
TUNING = 3
|
||||
ERROR = 4
|
||||
|
||||
|
||||
class LicenseType(betterproto.Enum):
|
||||
LICENSE_TYPE_UNSPECIFIED = 0
|
||||
LICENSE_TYPE_STANDARD = 1
|
||||
LICENSE_TYPE_CUSTOM = 2
|
||||
UNSPECIFIED = 0
|
||||
STANDARD = 1
|
||||
CUSTOM = 2
|
||||
|
||||
|
||||
class Platform(betterproto.Enum):
|
||||
"""Supported platforms"""
|
||||
|
||||
PLATFORM_UNSPECIFIED = 0
|
||||
PLATFORM_AM1_S9 = 1
|
||||
PLATFORM_AM2_S17 = 2
|
||||
PLATFORM_AM3_BBB = 3
|
||||
PLATFORM_AM3_AML = 4
|
||||
PLATFORM_STM32MP157C_II1_AM2 = 5
|
||||
PLATFORM_CVITEK_BM1_AM2 = 6
|
||||
PLATFORM_ZYNQ_BM3_AM2 = 7
|
||||
UNSPECIFIED = 0
|
||||
AM1_S9 = 1
|
||||
AM2_S17 = 2
|
||||
AM3_BBB = 3
|
||||
AM3_AML = 4
|
||||
STM32MP157C_II1_AM2 = 5
|
||||
CVITEK_BM1_AM2 = 6
|
||||
ZYNQ_BM3_AM2 = 7
|
||||
STM32MP157C_II2_BMM1 = 8
|
||||
|
||||
|
||||
class BosMode(betterproto.Enum):
|
||||
"""BOS modes enumeration"""
|
||||
|
||||
BOS_MODE_UNSPECIFIED = 0
|
||||
BOS_MODE_UPGRADE = 1
|
||||
BOS_MODE_RECOVERY = 2
|
||||
BOS_MODE_SD = 3
|
||||
BOS_MODE_NAND = 4
|
||||
BOS_MODE_EMMC = 5
|
||||
UNSPECIFIED = 0
|
||||
UPGRADE = 1
|
||||
RECOVERY = 2
|
||||
SD = 3
|
||||
NAND = 4
|
||||
EMMC = 5
|
||||
|
||||
|
||||
class MinerBrand(betterproto.Enum):
|
||||
MINER_BRAND_UNSPECIFIED = 0
|
||||
MINER_BRAND_ANTMINER = 1
|
||||
MINER_BRAND_WHATSMINER = 2
|
||||
UNSPECIFIED = 0
|
||||
ANTMINER = 1
|
||||
WHATSMINER = 2
|
||||
|
||||
|
||||
class MinerModel(betterproto.Enum):
|
||||
"""Deprecated: This enumeration is not longer maintained"""
|
||||
|
||||
MINER_MODEL_UNSPECIFIED = 0
|
||||
MINER_MODEL_ANTMINER_S9 = 1
|
||||
MINER_MODEL_ANTMINER_X17 = 2
|
||||
MINER_MODEL_ANTMINER_S17 = 3
|
||||
MINER_MODEL_ANTMINER_S17_PLUS = 4
|
||||
MINER_MODEL_ANTMINER_S17_PRO = 5
|
||||
MINER_MODEL_ANTMINER_S17E = 6
|
||||
MINER_MODEL_ANTMINER_T17 = 7
|
||||
MINER_MODEL_ANTMINER_T17E = 8
|
||||
MINER_MODEL_ANTMINER_T17_PLUS = 9
|
||||
MINER_MODEL_ANTMINER_X19 = 10
|
||||
MINER_MODEL_ANTMINER_S19 = 11
|
||||
MINER_MODEL_ANTMINER_S19_PRO = 12
|
||||
MINER_MODEL_ANTMINER_S19_PLUS = 13
|
||||
MINER_MODEL_ANTMINER_S19J = 14
|
||||
MINER_MODEL_ANTMINER_S19J_PRO = 15
|
||||
MINER_MODEL_ANTMINER_S19A = 16
|
||||
MINER_MODEL_ANTMINER_S19A_PRO = 17
|
||||
MINER_MODEL_ANTMINER_S19XP = 18
|
||||
MINER_MODEL_ANTMINER_T19 = 19
|
||||
MINER_MODEL_ANTMINER_S19J_PRO_PLUS = 20
|
||||
UNSPECIFIED = 0
|
||||
ANTMINER_S9 = 1
|
||||
ANTMINER_X17 = 2
|
||||
ANTMINER_S17 = 3
|
||||
ANTMINER_S17_PLUS = 4
|
||||
ANTMINER_S17_PRO = 5
|
||||
ANTMINER_S17E = 6
|
||||
ANTMINER_T17 = 7
|
||||
ANTMINER_T17E = 8
|
||||
ANTMINER_T17_PLUS = 9
|
||||
ANTMINER_X19 = 10
|
||||
ANTMINER_S19 = 11
|
||||
ANTMINER_S19_PRO = 12
|
||||
ANTMINER_S19_PLUS = 13
|
||||
ANTMINER_S19J = 14
|
||||
ANTMINER_S19J_PRO = 15
|
||||
ANTMINER_S19A = 16
|
||||
ANTMINER_S19A_PRO = 17
|
||||
ANTMINER_S19XP = 18
|
||||
ANTMINER_T19 = 19
|
||||
ANTMINER_S19J_PRO_PLUS = 20
|
||||
|
||||
|
||||
class MinerStatus(betterproto.Enum):
|
||||
MINER_STATUS_UNSPECIFIED = 0
|
||||
MINER_STATUS_NOT_STARTED = 1
|
||||
MINER_STATUS_NORMAL = 2
|
||||
MINER_STATUS_PAUSED = 3
|
||||
MINER_STATUS_SUSPENDED = 4
|
||||
MINER_STATUS_RESTRICTED = 5
|
||||
UNSPECIFIED = 0
|
||||
NOT_STARTED = 1
|
||||
NORMAL = 2
|
||||
PAUSED = 3
|
||||
SUSPENDED = 4
|
||||
RESTRICTED = 5
|
||||
|
||||
|
||||
class SupportArchiveFormat(betterproto.Enum):
|
||||
"""Enumeration for support archive format"""
|
||||
|
||||
SUPPORT_ARCHIVE_FORMAT_UNSPECIFIED = 0
|
||||
SUPPORT_ARCHIVE_FORMAT_ZIP = 1
|
||||
UNSPECIFIED = 0
|
||||
ZIP = 1
|
||||
"""Compressed zip format"""
|
||||
|
||||
SUPPORT_ARCHIVE_FORMAT_BOS = 2
|
||||
BOS = 2
|
||||
"""BOS custom format"""
|
||||
|
||||
ZIP_ENCRYPTED = 3
|
||||
"""Compressed encrypted zip format"""
|
||||
|
||||
|
||||
class NetworkProtocol(betterproto.Enum):
|
||||
NETWORK_PROTOCOL_UNSPECIFIED = 0
|
||||
NETWORK_PROTOCOL_DHCP = 1
|
||||
NETWORK_PROTOCOL_STATIC = 2
|
||||
UNSPECIFIED = 0
|
||||
DHCP = 1
|
||||
STATIC = 2
|
||||
|
||||
|
||||
@dataclass(eq=False, repr=False)
|
||||
@@ -268,8 +272,8 @@ class LoginResponse(betterproto.Message):
|
||||
|
||||
timeout_s: int = betterproto.uint32_field(2)
|
||||
"""
|
||||
Authentication token validity/timeout in seconds. Token validity refreshed
|
||||
to this value with each request.
|
||||
Authentication token validity/timeout in seconds.
|
||||
Token validity refreshed to this value with each request.
|
||||
"""
|
||||
|
||||
|
||||
@@ -277,9 +281,7 @@ class LoginResponse(betterproto.Message):
|
||||
class SetPasswordRequest(betterproto.Message):
|
||||
"""Request for set password action."""
|
||||
|
||||
password: Optional[str] = betterproto.string_field(
|
||||
1, optional=True, group="_password"
|
||||
)
|
||||
password: Optional[str] = betterproto.string_field(1, optional=True)
|
||||
|
||||
|
||||
@dataclass(eq=False, repr=False)
|
||||
@@ -335,8 +337,8 @@ class BasesPoints(betterproto.Message):
|
||||
|
||||
bsp: int = betterproto.uint32_field(1)
|
||||
"""
|
||||
A basis point is one hundredth of 1 percentage point. For example: 1bps =
|
||||
0.01%, 250bps = 2.5%
|
||||
A basis point is one hundredth of 1 percentage point.
|
||||
For example: 1bps = 0.01%, 250bps = 2.5%
|
||||
"""
|
||||
|
||||
|
||||
@@ -409,9 +411,9 @@ class VoltageConstraints(betterproto.Message):
|
||||
@dataclass(eq=False, repr=False)
|
||||
class CoolingAutoMode(betterproto.Message):
|
||||
"""
|
||||
The temperature control modes. Miner software tries to regulate the fan
|
||||
speed so that miner temperature is approximately at the target temperature.
|
||||
The allowed temperature range is 0-200 degree Celsius.
|
||||
The temperature control modes.
|
||||
Miner software tries to regulate the fan speed so that miner temperature is approximately at the target temperature.
|
||||
The allowed temperature range is 0-200 degree Celsius.
|
||||
"""
|
||||
|
||||
target_temperature: "Temperature" = betterproto.message_field(1)
|
||||
@@ -422,8 +424,7 @@ class CoolingAutoMode(betterproto.Message):
|
||||
|
||||
dangerous_temperature: "Temperature" = betterproto.message_field(3)
|
||||
"""
|
||||
Temperature threshold at which BOSMiner shuts down in order to prevent
|
||||
overheating and damaging the miner.
|
||||
Temperature threshold at which BOSMiner shuts down in order to prevent overheating and damaging the miner.
|
||||
"""
|
||||
|
||||
|
||||
@@ -433,12 +434,11 @@ class CoolingManualMode(betterproto.Message):
|
||||
Fans are kept at a fixed, user-defined speed, no matter the temperature.
|
||||
"""
|
||||
|
||||
fan_speed_ratio: Optional[float] = betterproto.double_field(
|
||||
1, optional=True, group="_fan_speed_ratio"
|
||||
)
|
||||
fan_speed_ratio: Optional[float] = betterproto.double_field(1, optional=True)
|
||||
"""
|
||||
User defined fan speed expressed as a ratio between 0.0 and 1.0 where 0.0
|
||||
means completely turned off and 1.0 means running at full speed possible
|
||||
User defined fan speed expressed as a ratio between 0.0 and 1.0
|
||||
where 0.0 means completely turned off and
|
||||
1.0 means running at full speed possible
|
||||
"""
|
||||
|
||||
hot_temperature: "Temperature" = betterproto.message_field(2)
|
||||
@@ -446,8 +446,7 @@ class CoolingManualMode(betterproto.Message):
|
||||
|
||||
dangerous_temperature: "Temperature" = betterproto.message_field(3)
|
||||
"""
|
||||
Temperature threshold at which BOSMiner shuts down in order to prevent
|
||||
overheating and damaging the miner.
|
||||
Temperature threshold at which BOSMiner shuts down in order to prevent overheating and damaging the miner.
|
||||
"""
|
||||
|
||||
|
||||
@@ -455,20 +454,17 @@ class CoolingManualMode(betterproto.Message):
|
||||
class CoolingDisabledMode(betterproto.Message):
|
||||
"""Disable temperature control. May be dangerous."""
|
||||
|
||||
fan_speed_ratio: Optional[float] = betterproto.double_field(
|
||||
1, optional=True, group="_fan_speed_ratio"
|
||||
)
|
||||
fan_speed_ratio: Optional[float] = betterproto.double_field(1, optional=True)
|
||||
"""
|
||||
User defined fan speed expressed as a ratio between 0.0 and 1.0 where 0.0
|
||||
means completely turned off and 1.0 means running at full speed possible
|
||||
User defined fan speed expressed as a ratio between 0.0 and 1.0
|
||||
where 0.0 means completely turned off and
|
||||
1.0 means running at full speed possible
|
||||
"""
|
||||
|
||||
|
||||
@dataclass(eq=False, repr=False)
|
||||
class CoolingConfiguration(betterproto.Message):
|
||||
minimum_required_fans: Optional[int] = betterproto.uint32_field(
|
||||
1, optional=True, group="_minimum_required_fans"
|
||||
)
|
||||
minimum_required_fans: Optional[int] = betterproto.uint32_field(1, optional=True)
|
||||
auto: "CoolingAutoMode" = betterproto.message_field(2, group="mode")
|
||||
manual: "CoolingManualMode" = betterproto.message_field(3, group="mode")
|
||||
disabled: "CoolingDisabledMode" = betterproto.message_field(4, group="mode")
|
||||
@@ -488,23 +484,19 @@ class CoolingConstraints(betterproto.Message):
|
||||
class FanState(betterproto.Message):
|
||||
"""Structure which contain info about one specific miner fan."""
|
||||
|
||||
position: Optional[int] = betterproto.uint32_field(
|
||||
1, optional=True, group="_position"
|
||||
)
|
||||
position: Optional[int] = betterproto.uint32_field(1, optional=True)
|
||||
"""Fan positions/ID"""
|
||||
|
||||
rpm: int = betterproto.uint32_field(2)
|
||||
"""Actual fan RPM (Revolutions/Rotation Per Minute)"""
|
||||
|
||||
target_speed_ratio: Optional[float] = betterproto.double_field(
|
||||
3, optional=True, group="_target_speed_ratio"
|
||||
)
|
||||
target_speed_ratio: Optional[float] = betterproto.double_field(3, optional=True)
|
||||
"""Actual fan speed ratio(PWM) in range 0.0 - 1.0"""
|
||||
|
||||
|
||||
@dataclass(eq=False, repr=False)
|
||||
class TemperatureSensor(betterproto.Message):
|
||||
id: Optional[int] = betterproto.uint32_field(1, optional=True, group="_id")
|
||||
id: Optional[int] = betterproto.uint32_field(1, optional=True)
|
||||
"""Sensor id"""
|
||||
|
||||
location: "SensorLocation" = betterproto.enum_field(2)
|
||||
@@ -523,7 +515,10 @@ class GetCoolingStateRequest(betterproto.Message):
|
||||
|
||||
@dataclass(eq=False, repr=False)
|
||||
class GetCoolingStateResponse(betterproto.Message):
|
||||
"""Response to get current fan states and temperature measurements"""
|
||||
"""
|
||||
Response to get current fan states and
|
||||
temperature measurements
|
||||
"""
|
||||
|
||||
fans: List["FanState"] = betterproto.message_field(1)
|
||||
"""All Fans state"""
|
||||
@@ -551,12 +546,10 @@ class SetImmersionModeResponse(betterproto.Message):
|
||||
|
||||
@dataclass(eq=False, repr=False)
|
||||
class TunerConfiguration(betterproto.Message):
|
||||
enabled: Optional[bool] = betterproto.bool_field(1, optional=True, group="_enabled")
|
||||
enabled: Optional[bool] = betterproto.bool_field(1, optional=True)
|
||||
"""Flag if tuner is enabled"""
|
||||
|
||||
tuner_mode: Optional["TunerMode"] = betterproto.enum_field(
|
||||
2, optional=True, group="_tuner_mode"
|
||||
)
|
||||
tuner_mode: Optional["TunerMode"] = betterproto.enum_field(2, optional=True)
|
||||
"""Tuner mode"""
|
||||
|
||||
power_target: "Power" = betterproto.message_field(3)
|
||||
@@ -583,7 +576,7 @@ class TunerConstraints(betterproto.Message):
|
||||
|
||||
@dataclass(eq=False, repr=False)
|
||||
class DpsConfiguration(betterproto.Message):
|
||||
enabled: Optional[bool] = betterproto.bool_field(1, optional=True, group="_enabled")
|
||||
enabled: Optional[bool] = betterproto.bool_field(1, optional=True)
|
||||
"""Flag if Dynamic Performance Scaling is enabled"""
|
||||
|
||||
power_step: "Power" = betterproto.message_field(2)
|
||||
@@ -598,9 +591,7 @@ class DpsConfiguration(betterproto.Message):
|
||||
min_hashrate_target: "TeraHashrate" = betterproto.message_field(5)
|
||||
"""Dynamic Performance Scaling minimal hashrate target"""
|
||||
|
||||
shutdown_enabled: Optional[bool] = betterproto.bool_field(
|
||||
6, optional=True, group="_shutdown_enabled"
|
||||
)
|
||||
shutdown_enabled: Optional[bool] = betterproto.bool_field(6, optional=True)
|
||||
"""Flag if shutdown for Dynamic Performance Scaling is enabled"""
|
||||
|
||||
shutdown_duration: "Hours" = betterproto.message_field(7)
|
||||
@@ -879,17 +870,13 @@ class SetDpsRequest(betterproto.Message):
|
||||
save_action: "SaveAction" = betterproto.enum_field(1)
|
||||
"""Save action"""
|
||||
|
||||
enable: Optional[bool] = betterproto.bool_field(2, optional=True, group="_enable")
|
||||
enable: Optional[bool] = betterproto.bool_field(2, optional=True)
|
||||
"""Flag if Dynamic Performance Scaling should be enabled"""
|
||||
|
||||
enable_shutdown: Optional[bool] = betterproto.bool_field(
|
||||
3, optional=True, group="_enable_shutdown"
|
||||
)
|
||||
enable_shutdown: Optional[bool] = betterproto.bool_field(3, optional=True)
|
||||
"""Flag if shutdown for Dynamic Performance Scaling should be enabled"""
|
||||
|
||||
shutdown_duration: Optional["Hours"] = betterproto.message_field(
|
||||
4, optional=True, group="_shutdown_duration"
|
||||
)
|
||||
shutdown_duration: Optional["Hours"] = betterproto.message_field(4, optional=True)
|
||||
"""Dynamic Performance Scaling shutdown duration"""
|
||||
|
||||
target: "DpsTarget" = betterproto.message_field(5)
|
||||
@@ -898,17 +885,13 @@ class SetDpsRequest(betterproto.Message):
|
||||
|
||||
@dataclass(eq=False, repr=False)
|
||||
class SetDpsResponse(betterproto.Message):
|
||||
enabled: Optional[bool] = betterproto.bool_field(1, optional=True, group="_enabled")
|
||||
enabled: Optional[bool] = betterproto.bool_field(1, optional=True)
|
||||
"""Flag if Dynamic Performance Scaling is enabled"""
|
||||
|
||||
shutdown_enabled: Optional[bool] = betterproto.bool_field(
|
||||
2, optional=True, group="_shutdown_enabled"
|
||||
)
|
||||
shutdown_enabled: Optional[bool] = betterproto.bool_field(2, optional=True)
|
||||
"""Flag if shutdown for Dynamic Performance Scaling should be enabled"""
|
||||
|
||||
shutdown_duration: Optional["Hours"] = betterproto.message_field(
|
||||
3, optional=True, group="_shutdown_duration"
|
||||
)
|
||||
shutdown_duration: Optional["Hours"] = betterproto.message_field(3, optional=True)
|
||||
"""Dynamic Performance Scaling shutdown duration"""
|
||||
|
||||
power_target: "DpsPowerTarget" = betterproto.message_field(4)
|
||||
@@ -935,7 +918,7 @@ class HashboardConfig(betterproto.Message):
|
||||
id: str = betterproto.string_field(1)
|
||||
"""Hashboard id"""
|
||||
|
||||
enabled: Optional[bool] = betterproto.bool_field(2, optional=True, group="_enabled")
|
||||
enabled: Optional[bool] = betterproto.bool_field(2, optional=True)
|
||||
"""Flag if HB si enabled"""
|
||||
|
||||
frequency: "Frequency" = betterproto.message_field(3)
|
||||
@@ -1019,9 +1002,9 @@ class Quota(betterproto.Message):
|
||||
@dataclass(eq=False, repr=False)
|
||||
class FixedShareRatio(betterproto.Message):
|
||||
"""
|
||||
Structure for fixed share ratio load balance strategy Fixed share ratio is
|
||||
value between 0.0 to 1.0 where 1.0 represents that all work is generated
|
||||
from the group
|
||||
Structure for fixed share ratio load balance strategy
|
||||
Fixed share ratio is value between 0.0 to 1.0 where 1.0 represents that all work is
|
||||
generated from the group
|
||||
"""
|
||||
|
||||
value: float = betterproto.double_field(1)
|
||||
@@ -1058,12 +1041,10 @@ class PoolConfiguration(betterproto.Message):
|
||||
user: str = betterproto.string_field(3)
|
||||
"""Pool connection user"""
|
||||
|
||||
password: Optional[str] = betterproto.string_field(
|
||||
4, optional=True, group="_password"
|
||||
)
|
||||
password: Optional[str] = betterproto.string_field(4, optional=True)
|
||||
"""Pool connection password if set"""
|
||||
|
||||
enabled: Optional[bool] = betterproto.bool_field(5, optional=True, group="_enabled")
|
||||
enabled: Optional[bool] = betterproto.bool_field(5, optional=True)
|
||||
"""Flag if pool connection is enabled"""
|
||||
|
||||
|
||||
@@ -1130,9 +1111,7 @@ class PoolStats(betterproto.Message):
|
||||
generated_work: int = betterproto.uint64_field(6)
|
||||
"""Generated work"""
|
||||
|
||||
last_share_time: Optional[datetime] = betterproto.message_field(
|
||||
7, optional=True, group="_last_share_time"
|
||||
)
|
||||
last_share_time: Optional[datetime] = betterproto.message_field(7, optional=True)
|
||||
"""Last share time"""
|
||||
|
||||
|
||||
@@ -1154,9 +1133,9 @@ class GetPoolGroupsResponse(betterproto.Message):
|
||||
@dataclass(eq=False, repr=False)
|
||||
class CreatePoolGroupRequest(betterproto.Message):
|
||||
"""
|
||||
Request for pool group create action group.uid must not be specified (it
|
||||
will be generated) group.pools[].uid must not be specified (it will be
|
||||
generated)
|
||||
Request for pool group create action
|
||||
group.uid must not be specified (it will be generated)
|
||||
group.pools[].uid must not be specified (it will be generated)
|
||||
"""
|
||||
|
||||
save_action: "SaveAction" = betterproto.enum_field(1)
|
||||
@@ -1177,9 +1156,9 @@ class CreatePoolGroupResponse(betterproto.Message):
|
||||
@dataclass(eq=False, repr=False)
|
||||
class UpdatePoolGroupRequest(betterproto.Message):
|
||||
"""
|
||||
Request for pool group update action group.uid must be specified and
|
||||
represents unique id of group which will be updated group.pools[].uid must
|
||||
not be specified (it will be generated)
|
||||
Request for pool group update action
|
||||
group.uid must be specified and represents unique id of group which will be updated
|
||||
group.pools[].uid must not be specified (it will be generated)
|
||||
"""
|
||||
|
||||
save_action: "SaveAction" = betterproto.enum_field(1)
|
||||
@@ -1221,16 +1200,15 @@ class SetPoolGroupsRequest(betterproto.Message):
|
||||
|
||||
save_action: "SaveAction" = betterproto.enum_field(1)
|
||||
"""
|
||||
Save action SAVE just update config but changes will not be applied
|
||||
SAVE_AND_APPLY and SAVE_AND_FORCE_APPLY are equal for this method. Pools
|
||||
config will be updated and changes will be applied that will trigger
|
||||
restart.
|
||||
Save action
|
||||
SAVE just update config but changes will not be applied
|
||||
SAVE_AND_APPLY and SAVE_AND_FORCE_APPLY are equal for this method. Pools config will be updated and changes will be applied that will trigger restart.
|
||||
"""
|
||||
|
||||
pool_groups: List["PoolGroupConfiguration"] = betterproto.message_field(2)
|
||||
"""
|
||||
Pool groups configuration `uid` must not be specified (it will be
|
||||
generated)
|
||||
Pool groups configuration
|
||||
`uid` must not be specified (it will be generated)
|
||||
"""
|
||||
|
||||
|
||||
@@ -1292,9 +1270,8 @@ class NoneLicense(betterproto.Message):
|
||||
time_to_restricted: int = betterproto.uint32_field(1)
|
||||
"""
|
||||
BOS Initialization timeout - number of seconds elapsed since bosminer start
|
||||
i.e., number of seconds BOS will start mining in restricted mode burning 5%
|
||||
of hashrate For more, see Section 3.10 of
|
||||
https://braiins.com/os/plus/license
|
||||
i.e., number of seconds BOS will start mining in restricted mode burning 5% of hashrate
|
||||
For more, see Section 3.10 of https://braiins.com/os/plus/license
|
||||
"""
|
||||
|
||||
|
||||
@@ -1313,9 +1290,8 @@ class ValidLicense(betterproto.Message):
|
||||
|
||||
time_to_restricted: int = betterproto.uint32_field(3)
|
||||
"""
|
||||
Current license expiration - number of seconds since the moment the license
|
||||
was received i.e., number of seconds BOS will start mining in restricted
|
||||
mode burning 15% of hashrate
|
||||
Current license expiration - number of seconds since the moment the license was received
|
||||
i.e., number of seconds BOS will start mining in restricted mode burning 15% of hashrate
|
||||
"""
|
||||
|
||||
dev_fee: "BasesPoints" = betterproto.message_field(4)
|
||||
@@ -1388,7 +1364,8 @@ class MinerIdentity(betterproto.Message):
|
||||
brand: "MinerBrand" = betterproto.enum_field(1)
|
||||
model: "MinerModel" = betterproto.enum_field(2)
|
||||
"""
|
||||
Deprecated: Use miner_model instead. This field is no longer supported.
|
||||
Deprecated: Use miner_model instead.
|
||||
This field is no longer supported.
|
||||
"""
|
||||
|
||||
name: str = betterproto.string_field(3)
|
||||
@@ -1564,7 +1541,7 @@ class Hashboard(betterproto.Message):
|
||||
stats: "WorkSolverStats" = betterproto.message_field(8)
|
||||
"""Hashboard stats"""
|
||||
|
||||
model: Optional[str] = betterproto.string_field(9, optional=True, group="_model")
|
||||
model: Optional[str] = betterproto.string_field(9, optional=True)
|
||||
"""Hashboard model"""
|
||||
|
||||
|
||||
@@ -1644,9 +1621,7 @@ class GetNetworkConfigurationResponse(betterproto.Message):
|
||||
class SetNetworkConfigurationRequest(betterproto.Message):
|
||||
dhcp: "Dhcp" = betterproto.message_field(1, group="protocol")
|
||||
static: "Static" = betterproto.message_field(2, group="protocol")
|
||||
hostname: Optional[str] = betterproto.string_field(
|
||||
3, optional=True, group="_hostname"
|
||||
)
|
||||
hostname: Optional[str] = betterproto.string_field(3, optional=True)
|
||||
"""Hostname. Existing value will be preserved if this field is not set."""
|
||||
|
||||
|
||||
@@ -1691,27 +1666,21 @@ class GetNetworkInfoRequest(betterproto.Message):
|
||||
@dataclass(eq=False, repr=False)
|
||||
class GetNetworkInfoResponse(betterproto.Message):
|
||||
"""
|
||||
Response message for GetCurrentNetworkConfiguration Represents the current
|
||||
network configuration for the default network interface. Only IPv4 is
|
||||
supported.
|
||||
Response message for GetCurrentNetworkConfiguration
|
||||
Represents the current network configuration for the default network interface.
|
||||
Only IPv4 is supported.
|
||||
"""
|
||||
|
||||
name: str = betterproto.string_field(1)
|
||||
"""Name of the network interface"""
|
||||
|
||||
mac_address: Optional[str] = betterproto.string_field(
|
||||
2, optional=True, group="_mac_address"
|
||||
)
|
||||
mac_address: Optional[str] = betterproto.string_field(2, optional=True)
|
||||
"""MAC address of the network interface"""
|
||||
|
||||
hostname: Optional[str] = betterproto.string_field(
|
||||
3, optional=True, group="_hostname"
|
||||
)
|
||||
hostname: Optional[str] = betterproto.string_field(3, optional=True)
|
||||
"""Miner hostname"""
|
||||
|
||||
protocol: Optional["NetworkProtocol"] = betterproto.enum_field(
|
||||
4, optional=True, group="_protocol"
|
||||
)
|
||||
protocol: Optional["NetworkProtocol"] = betterproto.enum_field(4, optional=True)
|
||||
"""Network protocol"""
|
||||
|
||||
dns_servers: List[str] = betterproto.string_field(5)
|
||||
@@ -1720,9 +1689,7 @@ class GetNetworkInfoResponse(betterproto.Message):
|
||||
networks: List["IpNetwork"] = betterproto.message_field(6)
|
||||
"""List of assigned IP addresses"""
|
||||
|
||||
default_gateway: Optional[str] = betterproto.string_field(
|
||||
7, optional=True, group="_default_gateway"
|
||||
)
|
||||
default_gateway: Optional[str] = betterproto.string_field(7, optional=True)
|
||||
"""Default gateway/route for the interface"""
|
||||
|
||||
|
||||
@@ -2332,7 +2299,7 @@ class MinerServiceStub(betterproto.ServiceStub):
|
||||
timeout: Optional[float] = None,
|
||||
deadline: Optional["Deadline"] = None,
|
||||
metadata: Optional["MetadataLike"] = None
|
||||
) -> AsyncIterator["GetMinerStatusResponse"]:
|
||||
) -> AsyncIterator[GetMinerStatusResponse]:
|
||||
async for response in self._unary_stream(
|
||||
"/braiins.bos.v1.MinerService/GetMinerStatus",
|
||||
get_miner_status_request,
|
||||
@@ -2418,7 +2385,7 @@ class MinerServiceStub(betterproto.ServiceStub):
|
||||
timeout: Optional[float] = None,
|
||||
deadline: Optional["Deadline"] = None,
|
||||
metadata: Optional["MetadataLike"] = None
|
||||
) -> AsyncIterator["GetSupportArchiveResponse"]:
|
||||
) -> AsyncIterator[GetSupportArchiveResponse]:
|
||||
async for response in self._unary_stream(
|
||||
"/braiins.bos.v1.MinerService/GetSupportArchive",
|
||||
get_support_archive_request,
|
||||
@@ -3195,7 +3162,7 @@ class MinerServiceBase(ServiceBase):
|
||||
|
||||
async def get_miner_status(
|
||||
self, get_miner_status_request: "GetMinerStatusRequest"
|
||||
) -> AsyncIterator["GetMinerStatusResponse"]:
|
||||
) -> AsyncIterator[GetMinerStatusResponse]:
|
||||
raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)
|
||||
yield GetMinerStatusResponse()
|
||||
|
||||
@@ -3221,7 +3188,7 @@ class MinerServiceBase(ServiceBase):
|
||||
|
||||
async def get_support_archive(
|
||||
self, get_support_archive_request: "GetSupportArchiveRequest"
|
||||
) -> AsyncIterator["GetSupportArchiveResponse"]:
|
||||
) -> AsyncIterator[GetSupportArchiveResponse]:
|
||||
raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)
|
||||
yield GetSupportArchiveResponse()
|
||||
|
||||
|
||||
@@ -127,6 +127,9 @@ class InnosiliconWebAPI(BaseWebAPI):
|
||||
async def get_all(self) -> dict:
|
||||
return await self.send_command("getAll")
|
||||
|
||||
async def summary(self) -> dict:
|
||||
return await self.send_command("summary")
|
||||
|
||||
async def get_error_detail(self) -> dict:
|
||||
return await self.send_command("getErrorDetail")
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "pyasic"
|
||||
version = "0.60.7"
|
||||
version = "0.62.2"
|
||||
description = "A simplified and standardized interface for Bitcoin ASICs."
|
||||
authors = ["UpstreamData <brett@upstreamdata.ca>"]
|
||||
repository = "https://github.com/UpstreamData/pyasic"
|
||||
@@ -8,21 +8,21 @@ documentation = "https://pyasic.readthedocs.io/en/latest/"
|
||||
readme = "README.md"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.8"
|
||||
python = "^3.9"
|
||||
httpx = ">=0.26.0"
|
||||
asyncssh = ">=2.17.0"
|
||||
passlib = ">=1.7.4"
|
||||
pyaml = ">=23.12.0"
|
||||
tomli = { version = ">=2.0.1", python = "<3.11" }
|
||||
tomli-w = "1.0.0"
|
||||
betterproto = "2.0.0b6"
|
||||
tomli-w = "^1.0.0"
|
||||
aiofiles = ">=23.2.1"
|
||||
betterproto = "2.0.0b7"
|
||||
|
||||
[tool.poetry.group.dev]
|
||||
optional = true
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
pre-commit = "^3.5.0"
|
||||
pre-commit = "^4.0.1"
|
||||
isort = "^5.12.0"
|
||||
|
||||
[tool.poetry.group.docs]
|
||||
|
||||
Reference in New Issue
Block a user