Compare commits

..

1 Commits

Author SHA1 Message Date
Upstream Data
bd9fd81b17 version: bump version number 2025-01-20 08:54:14 -07:00
42 changed files with 379 additions and 776 deletions

View File

@@ -1,8 +1,7 @@
ci:
skip:
- poetry-lock
- unittest
- generate-docs
- pytest
repos:
- repo: https://github.com/python-poetry/poetry
rev: 2.0.1
@@ -23,11 +22,11 @@ repos:
exclude: ^mkdocs\.yml$
- id: check-added-large-files
- repo: https://github.com/psf/black
rev: 25.1.0
rev: 24.10.0
hooks:
- id: black
- repo: https://github.com/pycqa/isort
rev: 6.0.0
rev: 5.13.2
hooks:
- id: isort
name: isort (python)
@@ -38,12 +37,6 @@ repos:
name: unittest
entry: python -m unittest discover
language: system
types: [ python ]
'types': [python]
args: ["-p '*test.py'"] # Probably this option is absolutely not needed.
pass_filenames: false
- id: generate-docs
name: generate-docs
entry: python docs/generate_miners.py
language: system
types: [ python ]
pass_filenames: false

View File

@@ -2,7 +2,6 @@ import asyncio
import importlib
import os
import warnings
from pathlib import Path
from pyasic.miners.factory import MINER_CLASSES, MinerTypes
@@ -52,15 +51,12 @@ def backend_str(backend: MinerTypes) -> str:
return "Mara Firmware Miners"
case MinerTypes.BITAXE:
return "Stock Firmware BitAxe Miners"
case MinerTypes.LUCKYMINER:
return "Stock Firmware Lucky Miners"
case MinerTypes.ICERIVER:
return "Stock Firmware IceRiver Miners"
case MinerTypes.HAMMER:
return "Stock Firmware Hammer Miners"
case MinerTypes.VOLCMINER:
return "Stock Firmware Volcminers"
raise TypeError("Unknown miner backend, cannot generate docs")
def create_url_str(mtype: str):
@@ -139,14 +135,14 @@ for m in MINER_CLASSES:
done.append(miner)
def create_directory_structure(directory, data):
async def create_directory_structure(directory, data):
if not os.path.exists(directory):
os.makedirs(directory)
for key, value in data.items():
subdirectory = os.path.join(directory, key)
if isinstance(value, dict):
create_directory_structure(subdirectory, value)
await create_directory_structure(subdirectory, value)
elif isinstance(value, list):
file_path = os.path.join(subdirectory + ".md")
@@ -167,7 +163,7 @@ def create_directory_structure(directory, data):
)
def create_supported_types(directory):
async def create_supported_types(directory):
with open(os.path.join(directory, "supported_types.md"), "w") as file:
file.write(SUPPORTED_TYPES_HEADER)
for mback in MINER_CLASSES:
@@ -184,7 +180,7 @@ def create_supported_types(directory):
for mtype in backend_types:
file.write(MINER_TYPE_HEADER.format(mtype))
for minstance in backend_types[mtype]:
model = minstance("1.1.1.1").model
model = await minstance("1.1.1.1").get_model()
file.write(
MINER_DETAILS.format(
make(minstance), mtype, create_url_str(model), model
@@ -194,7 +190,6 @@ def create_supported_types(directory):
file.write(BACKEND_TYPE_CLOSER)
if __name__ == "__main__":
root_directory = Path(__file__).parent.joinpath("miners")
create_directory_structure(root_directory, m_data)
create_supported_types(root_directory)
root_directory = os.path.join(os.getcwd(), "miners")
asyncio.run(create_directory_structure(root_directory, m_data))
asyncio.run(create_supported_types(root_directory))

View File

@@ -495,19 +495,6 @@
show_root_heading: false
heading_level: 0
## S19i (VNish)
- [x] Shutdowns
- [ ] Power Modes
- [x] Setpoints
- [x] Presets
::: pyasic.miners.antminer.vnish.X19.S19.VNishS19i
handler: python
options:
show_root_heading: false
heading_level: 0
## S19j (VNish)
- [x] Shutdowns
@@ -703,19 +690,6 @@
show_root_heading: false
heading_level: 0
## S19 No PIC (Hive)
- [ ] Shutdowns
- [ ] Power Modes
- [ ] Setpoints
- [ ] Presets
::: pyasic.miners.antminer.hiveon.X19.S19.HiveonS19NoPIC
handler: python
options:
show_root_heading: false
heading_level: 0
## S19 (LuxOS)
- [x] Shutdowns

View File

@@ -14,19 +14,6 @@
show_root_heading: false
heading_level: 0
## S21 Hydro (Stock)
- [x] Shutdowns
- [x] Power Modes
- [ ] Setpoints
- [ ] Presets
::: pyasic.miners.antminer.bmminer.X21.S21.BMMinerS21Hydro
handler: python
options:
show_root_heading: false
heading_level: 0
## S21 Pro (Stock)
- [x] Shutdowns
@@ -66,19 +53,6 @@
show_root_heading: false
heading_level: 0
## S21 Pro (BOS+)
- [x] Shutdowns
- [ ] Power Modes
- [x] Setpoints
- [ ] Presets
::: pyasic.miners.antminer.bosminer.X21.S21.BOSMinerS21Pro
handler: python
options:
show_root_heading: false
heading_level: 0
## T21 (BOS+)
- [x] Shutdowns

View File

@@ -1,16 +0,0 @@
# pyasic
## LV Models
## LV08 (Stock)
- [ ] Shutdowns
- [ ] Power Modes
- [ ] Setpoints
- [ ] Presets
::: pyasic.miners.luckyminer.espminer.LV.LV08.LuckyMinerLV08
handler: python
options:
show_root_heading: false
heading_level: 0

View File

@@ -105,7 +105,6 @@ details {
<li><a href="../antminer/X21#s21-stock">S21 (Stock)</a></li>
<li><a href="../antminer/X21#s21-pro-stock">S21 Pro (Stock)</a></li>
<li><a href="../antminer/X21#t21-stock">T21 (Stock)</a></li>
<li><a href="../antminer/X21#s21-hydro-stock">S21 Hydro (Stock)</a></li>
</ul>
</details>
</ul>
@@ -653,7 +652,6 @@ details {
<summary>X21 Series:</summary>
<ul>
<li><a href="../antminer/X21#s21-bos_1">S21 (BOS+)</a></li>
<li><a href="../antminer/X21#s21-pro-bos_1">S21 Pro (BOS+)</a></li>
<li><a href="../antminer/X21#t21-bos_1">T21 (BOS+)</a></li>
</ul>
</details>
@@ -696,7 +694,6 @@ details {
<li><a href="../antminer/X19#s19-no-pic-vnish">S19 No PIC (VNish)</a></li>
<li><a href="../antminer/X19#s19-pro-vnish">S19 Pro (VNish)</a></li>
<li><a href="../antminer/X19#s19j-vnish">S19j (VNish)</a></li>
<li><a href="../antminer/X19#s19i-vnish">S19i (VNish)</a></li>
<li><a href="../antminer/X19#s19j-pro-vnish">S19j Pro (VNish)</a></li>
<li><a href="../antminer/X19#s19j-pro-vnish">S19j Pro (VNish)</a></li>
<li><a href="../antminer/X19#s19j-pro-vnish">S19j Pro (VNish)</a></li>
@@ -763,7 +760,6 @@ details {
<ul>
<li><a href="../antminer/X19#s19j-pro-hive">S19j Pro (Hive)</a></li>
<li><a href="../antminer/X19#s19-hive">S19 (Hive)</a></li>
<li><a href="../antminer/X19#s19-no-pic-hive">S19 No PIC (Hive)</a></li>
</ul>
</details>
</ul>
@@ -863,17 +859,6 @@ details {
</ul>
</details>
<details>
<summary>Stock Firmware Lucky Miners:</summary>
<ul>
<details>
<summary>LV Series:</summary>
<ul>
<li><a href="../luckyminer/LV#lv08-stock">LV08 (Stock)</a></li>
</ul>
</details>
</ul>
</details>
<details>
<summary>Stock Firmware IceRiver Miners:</summary>
<ul>
<details>

110
poetry.lock generated
View File

@@ -74,18 +74,18 @@ pywin32 = ["pywin32 (>=227)"]
[[package]]
name = "babel"
version = "2.17.0"
version = "2.16.0"
description = "Internationalization utilities"
optional = false
python-versions = ">=3.8"
groups = ["docs"]
files = [
{file = "babel-2.17.0-py3-none-any.whl", hash = "sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2"},
{file = "babel-2.17.0.tar.gz", hash = "sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d"},
{file = "babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b"},
{file = "babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316"},
]
[package.extras]
dev = ["backports.zoneinfo", "freezegun (>=1.0,<2.0)", "jinja2 (>=3.0)", "pytest (>=6.0)", "pytest-cov", "pytz", "setuptools", "tzdata"]
dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"]
[[package]]
name = "betterproto"
@@ -110,14 +110,14 @@ rust-codec = ["betterproto-rust-codec (==0.1.1)"]
[[package]]
name = "certifi"
version = "2025.1.31"
version = "2024.12.14"
description = "Python package for providing Mozilla's CA Bundle."
optional = false
python-versions = ">=3.6"
groups = ["main", "docs"]
files = [
{file = "certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe"},
{file = "certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651"},
{file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"},
{file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"},
]
[[package]]
@@ -422,19 +422,19 @@ test = ["pytest (>=6)"]
[[package]]
name = "filelock"
version = "3.17.0"
version = "3.16.1"
description = "A platform independent file lock."
optional = false
python-versions = ">=3.9"
python-versions = ">=3.8"
groups = ["dev"]
files = [
{file = "filelock-3.17.0-py3-none-any.whl", hash = "sha256:533dc2f7ba78dc2f0f531fc6c4940addf7b70a481e269a5a3b93be94ffbe8338"},
{file = "filelock-3.17.0.tar.gz", hash = "sha256:ee4e77401ef576ebb38cd7f13b9b28893194acc20a8e68e18730ba9c0e54660e"},
{file = "filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0"},
{file = "filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435"},
]
[package.extras]
docs = ["furo (>=2024.8.6)", "sphinx (>=8.1.3)", "sphinx-autodoc-typehints (>=3)"]
testing = ["covdefaults (>=2.3)", "coverage (>=7.6.10)", "diff-cover (>=9.2.1)", "pytest (>=8.3.4)", "pytest-asyncio (>=0.25.2)", "pytest-cov (>=6)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.28.1)"]
docs = ["furo (>=2024.8.6)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4.1)"]
testing = ["covdefaults (>=2.3)", "coverage (>=7.6.1)", "diff-cover (>=9.2)", "pytest (>=8.3.3)", "pytest-asyncio (>=0.24)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.26.4)"]
typing = ["typing-extensions (>=4.12.2)"]
[[package]]
@@ -457,14 +457,14 @@ dev = ["flake8", "markdown", "twine", "wheel"]
[[package]]
name = "griffe"
version = "1.5.6"
version = "1.5.5"
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.9"
groups = ["docs"]
files = [
{file = "griffe-1.5.6-py3-none-any.whl", hash = "sha256:b2a3afe497c6c1f952e54a23095ecc09435016293e77af8478ed65df1022a394"},
{file = "griffe-1.5.6.tar.gz", hash = "sha256:181f6666d5aceb6cd6e2da5a2b646cfb431e47a0da1fda283845734b67e10944"},
{file = "griffe-1.5.5-py3-none-any.whl", hash = "sha256:2761b1e8876c6f1f9ab1af274df93ea6bbadd65090de5f38f4cb5cc84897c7dd"},
{file = "griffe-1.5.5.tar.gz", hash = "sha256:35ee5b38b93d6a839098aad0f92207e6ad6b70c3e8866c08ca669275b8cba585"},
]
[package.dependencies]
@@ -502,30 +502,30 @@ files = [
[[package]]
name = "h2"
version = "4.2.0"
description = "Pure-Python HTTP/2 protocol implementation"
version = "4.1.0"
description = "HTTP/2 State-Machine based protocol implementation"
optional = false
python-versions = ">=3.9"
python-versions = ">=3.6.1"
groups = ["main"]
files = [
{file = "h2-4.2.0-py3-none-any.whl", hash = "sha256:479a53ad425bb29af087f3458a61d30780bc818e4ebcf01f0b536ba916462ed0"},
{file = "h2-4.2.0.tar.gz", hash = "sha256:c8a52129695e88b1a0578d8d2cc6842bbd79128ac685463b887ee278126ad01f"},
{file = "h2-4.1.0-py3-none-any.whl", hash = "sha256:03a46bcf682256c95b5fd9e9a99c1323584c3eec6440d379b9903d709476bc6d"},
{file = "h2-4.1.0.tar.gz", hash = "sha256:a83aca08fbe7aacb79fec788c9c0bac936343560ed9ec18b82a13a12c28d2abb"},
]
[package.dependencies]
hpack = ">=4.1,<5"
hyperframe = ">=6.1,<7"
hpack = ">=4.0,<5"
hyperframe = ">=6.0,<7"
[[package]]
name = "hpack"
version = "4.1.0"
description = "Pure-Python HPACK header encoding"
version = "4.0.0"
description = "Pure-Python HPACK header compression"
optional = false
python-versions = ">=3.9"
python-versions = ">=3.6.1"
groups = ["main"]
files = [
{file = "hpack-4.1.0-py3-none-any.whl", hash = "sha256:157ac792668d995c657d93111f46b4535ed114f0c9c8d672271bbec7eae1b496"},
{file = "hpack-4.1.0.tar.gz", hash = "sha256:ec5eca154f7056aa06f196a557655c5b009b382873ac8d1e66e79e87535f1dca"},
{file = "hpack-4.0.0-py3-none-any.whl", hash = "sha256:84a076fad3dc9a9f8063ccb8041ef100867b1878b25ef0ee63847a5d53818a6c"},
{file = "hpack-4.0.0.tar.gz", hash = "sha256:fc41de0c63e687ebffde81187a948221294896f6bdc0ae2312708df339430095"},
]
[[package]]
@@ -577,26 +577,26 @@ zstd = ["zstandard (>=0.18.0)"]
[[package]]
name = "hyperframe"
version = "6.1.0"
description = "Pure-Python HTTP/2 framing"
version = "6.0.1"
description = "HTTP/2 framing layer for Python"
optional = false
python-versions = ">=3.9"
python-versions = ">=3.6.1"
groups = ["main"]
files = [
{file = "hyperframe-6.1.0-py3-none-any.whl", hash = "sha256:b03380493a519fce58ea5af42e4a42317bf9bd425596f7a0835ffce80f1a42e5"},
{file = "hyperframe-6.1.0.tar.gz", hash = "sha256:f630908a00854a7adeabd6382b43923a4c4cd4b821fcb527e6ab9e15382a3b08"},
{file = "hyperframe-6.0.1-py3-none-any.whl", hash = "sha256:0ec6bafd80d8ad2195c4f03aacba3a8265e57bc4cff261e802bf39970ed02a15"},
{file = "hyperframe-6.0.1.tar.gz", hash = "sha256:ae510046231dc8e9ecb1a6586f63d2347bf4c8905914aa84ba585ae85f28a914"},
]
[[package]]
name = "identify"
version = "2.6.6"
version = "2.6.5"
description = "File identification library for Python"
optional = false
python-versions = ">=3.9"
groups = ["dev"]
files = [
{file = "identify-2.6.6-py2.py3-none-any.whl", hash = "sha256:cbd1810bce79f8b671ecb20f53ee0ae8e86ae84b557de31d89709dc2a48ba881"},
{file = "identify-2.6.6.tar.gz", hash = "sha256:7bec12768ed44ea4761efb47806f0a41f86e7c0a5fdf5950d4648c90eca7e251"},
{file = "identify-2.6.5-py2.py3-none-any.whl", hash = "sha256:14181a47091eb75b337af4c23078c9d09225cd4c48929f521f3bf16b09d02566"},
{file = "identify-2.6.5.tar.gz", hash = "sha256:c10b33f250e5bba374fae86fb57f3adcebf1161bce7cdf92031915fd480c13bc"},
]
[package.extras]
@@ -619,15 +619,15 @@ all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2
[[package]]
name = "importlib-metadata"
version = "8.6.1"
version = "8.5.0"
description = "Read metadata from Python packages"
optional = false
python-versions = ">=3.9"
python-versions = ">=3.8"
groups = ["docs"]
markers = "python_version < \"3.10\""
files = [
{file = "importlib_metadata-8.6.1-py3-none-any.whl", hash = "sha256:02a89390c1e15fdfdc0d7c6b25cb3e62650d0494005c97d6f148bf5b9787525e"},
{file = "importlib_metadata-8.6.1.tar.gz", hash = "sha256:310b41d755445d74569f993ccfc22838295d9fe005425094fad953d7f15c8580"},
{file = "importlib_metadata-8.5.0-py3-none-any.whl", hash = "sha256:45e54197d28b7a7f1559e60b95e7c567032b602131fbd588f1497f47880aa68b"},
{file = "importlib_metadata-8.5.0.tar.gz", hash = "sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7"},
]
[package.dependencies]
@@ -639,7 +639,7 @@ cover = ["pytest-cov"]
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
enabler = ["pytest-enabler (>=2.2)"]
perf = ["ipython"]
test = ["flufl.flake8", "importlib_resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"]
test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"]
type = ["pytest-mypy"]
[[package]]
@@ -846,14 +846,14 @@ pyyaml = ">=5.1"
[[package]]
name = "mkdocs-material"
version = "9.6.2"
version = "9.5.50"
description = "Documentation that simply works"
optional = false
python-versions = ">=3.8"
groups = ["docs"]
files = [
{file = "mkdocs_material-9.6.2-py3-none-any.whl", hash = "sha256:71d90dbd63b393ad11a4d90151dfe3dcbfcd802c0f29ce80bebd9bbac6abc753"},
{file = "mkdocs_material-9.6.2.tar.gz", hash = "sha256:a3de1c5d4c745f10afa78b1a02f917b9dce0808fb206adc0f5bb48b58c1ca21f"},
{file = "mkdocs_material-9.5.50-py3-none-any.whl", hash = "sha256:f24100f234741f4d423a9d672a909d859668a4f404796be3cf035f10d6050385"},
{file = "mkdocs_material-9.5.50.tar.gz", hash = "sha256:ae5fe16f3d7c9ccd05bb6916a7da7420cf99a9ce5e33debd9d40403a090d5825"},
]
[package.dependencies]
@@ -1127,14 +1127,14 @@ type = ["mypy (>=1.11.2)"]
[[package]]
name = "pre-commit"
version = "4.1.0"
version = "4.0.1"
description = "A framework for managing and maintaining multi-language pre-commit hooks."
optional = false
python-versions = ">=3.9"
groups = ["dev"]
files = [
{file = "pre_commit-4.1.0-py2.py3-none-any.whl", hash = "sha256:d29e7cb346295bcc1cc75fc3e92e343495e3ea0196c9ec6ba53f49f10ab6ae7b"},
{file = "pre_commit-4.1.0.tar.gz", hash = "sha256:ae3f018575a588e30dfddfab9a05448bfbd6b73d78709617b5a2b853549716d4"},
{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]
@@ -1177,14 +1177,14 @@ files = [
[[package]]
name = "pydantic"
version = "2.10.6"
version = "2.10.5"
description = "Data validation using Python type hints"
optional = false
python-versions = ">=3.8"
groups = ["main"]
files = [
{file = "pydantic-2.10.6-py3-none-any.whl", hash = "sha256:427d664bf0b8a2b34ff5dd0f5a18df00591adcee7198fbd71981054cef37b584"},
{file = "pydantic-2.10.6.tar.gz", hash = "sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236"},
{file = "pydantic-2.10.5-py3-none-any.whl", hash = "sha256:4dd4e322dbe55472cb7ca7e73f4b63574eecccf2835ffa2af9021ce113c83c53"},
{file = "pydantic-2.10.5.tar.gz", hash = "sha256:278b38dbbaec562011d659ee05f63346951b3a248a6f3642e1bc68894ea2b4ff"},
]
[package.dependencies]
@@ -1326,14 +1326,14 @@ windows-terminal = ["colorama (>=0.4.6)"]
[[package]]
name = "pymdown-extensions"
version = "10.14.3"
version = "10.14"
description = "Extension pack for Python Markdown."
optional = false
python-versions = ">=3.8"
groups = ["docs"]
files = [
{file = "pymdown_extensions-10.14.3-py3-none-any.whl", hash = "sha256:05e0bee73d64b9c71a4ae17c72abc2f700e8bc8403755a00580b49a4e9f189e9"},
{file = "pymdown_extensions-10.14.3.tar.gz", hash = "sha256:41e576ce3f5d650be59e900e4ceff231e0aed2a88cf30acaee41e02f063a061b"},
{file = "pymdown_extensions-10.14-py3-none-any.whl", hash = "sha256:202481f716cc8250e4be8fce997781ebf7917701b59652458ee47f2401f818b5"},
{file = "pymdown_extensions-10.14.tar.gz", hash = "sha256:741bd7c4ff961ba40b7528d32284c53bc436b8b1645e8e37c3e57770b8700a34"},
]
[package.dependencies]
@@ -1759,5 +1759,5 @@ type = ["pytest-mypy"]
[metadata]
lock-version = "2.1"
python-versions = ">3.9, <4.0"
content-hash = "67a8e0d34c0d1af0f8e4d617d80fd5afc8d197e5d5444f78fd82e4f716a52965"
python-versions = "^3.9"
content-hash = "a0d1e4d454da0d9d3c246a4f1047e804db5726c175071d95b7007e88689cdbf2"

View File

@@ -143,12 +143,12 @@ class MinerConfig(BaseModel):
**self.pools.as_mara(user_suffix=user_suffix),
}
def as_espminer(self, user_suffix: str | None = None) -> dict:
def as_bitaxe(self, user_suffix: str | None = None) -> dict:
return {
**self.fan_mode.as_espminer(),
**self.temperature.as_espminer(),
**self.mining_mode.as_espminer(),
**self.pools.as_espminer(user_suffix=user_suffix),
**self.fan_mode.as_bitaxe(),
**self.temperature.as_bitaxe(),
**self.mining_mode.as_bitaxe(),
**self.pools.as_bitaxe(user_suffix=user_suffix),
}
def as_luxos(self, user_suffix: str | None = None) -> dict:
@@ -272,10 +272,10 @@ class MinerConfig(BaseModel):
)
@classmethod
def from_espminer(cls, web_system_info: dict) -> "MinerConfig":
def from_bitaxe(cls, web_system_info: dict) -> "MinerConfig":
return cls(
pools=PoolConfig.from_espminer(web_system_info),
fan_mode=FanModeConfig.from_espminer(web_system_info),
pools=PoolConfig.from_bitaxe(web_system_info),
fan_mode=FanModeConfig.from_bitaxe(web_system_info),
)
@classmethod

View File

@@ -61,8 +61,8 @@ class MinerConfigOption(Enum):
def as_mara(self) -> dict:
return self.value.as_mara()
def as_espminer(self) -> dict:
return self.value.as_espminer()
def as_bitaxe(self) -> dict:
return self.value.as_bitaxe()
def as_luxos(self) -> dict:
return self.value.as_luxos()
@@ -125,7 +125,7 @@ class MinerConfigValue(BaseModel):
def as_mara(self) -> dict:
return {}
def as_espminer(self) -> dict:
def as_bitaxe(self) -> dict:
return {}
def as_luxos(self) -> dict:

View File

@@ -81,7 +81,7 @@ class FanModeNormal(MinerConfigValue):
},
}
def as_espminer(self) -> dict:
def as_bitaxe(self) -> dict:
return {"autoFanspeed": 1}
def as_luxos(self) -> dict:
@@ -156,7 +156,7 @@ class FanModeManual(MinerConfigValue):
},
}
def as_espminer(self) -> dict:
def as_bitaxe(self) -> dict:
return {"autoFanspeed": 0, "fanspeed": self.speed}
def as_luxos(self) -> dict:
@@ -342,7 +342,7 @@ class FanModeConfig(MinerConfigOption):
return cls.default()
@classmethod
def from_espminer(cls, web_system_info: dict):
def from_bitaxe(cls, web_system_info: dict):
if web_system_info["autofanspeed"] == 1:
return cls.normal()
else:

View File

@@ -102,7 +102,7 @@ class Pool(MinerConfigValue):
"pass": self.password,
}
def as_espminer(self, user_suffix: str | None = None) -> dict:
def as_bitaxe(self, user_suffix: str | None = None) -> dict:
return {
"stratumURL": self.url,
"stratumUser": f"{self.user}{user_suffix or ''}",
@@ -192,7 +192,7 @@ class Pool(MinerConfigValue):
)
@classmethod
def from_espminer(cls, web_system_info: dict) -> "Pool":
def from_bitaxe(cls, web_system_info: dict) -> "Pool":
url = f"stratum+tcp://{web_system_info['stratumURL']}:{web_system_info['stratumPort']}"
return cls(
url=url,
@@ -306,8 +306,8 @@ class PoolGroup(MinerConfigValue):
def as_mara(self, user_suffix: str | None = None) -> list:
return [p.as_mara(user_suffix=user_suffix) for p in self.pools]
def as_espminer(self, user_suffix: str | None = None) -> dict:
return self.pools[0].as_espminer(user_suffix=user_suffix)
def as_bitaxe(self, user_suffix: str | None = None) -> dict:
return self.pools[0].as_bitaxe(user_suffix=user_suffix)
def as_boser(self, user_suffix: str | None = None) -> PoolGroupConfiguration:
return PoolGroupConfiguration(
@@ -395,8 +395,8 @@ class PoolGroup(MinerConfigValue):
return cls(pools=[Pool.from_mara(pool_conf) for pool_conf in web_config_pools])
@classmethod
def from_espminer(cls, web_system_info: dict) -> "PoolGroup":
return cls(pools=[Pool.from_espminer(web_system_info)])
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":
@@ -507,8 +507,8 @@ class PoolConfig(MinerConfigValue):
return {"pools": self.groups[0].as_mara(user_suffix=user_suffix)}
return {"pools": []}
def as_espminer(self, user_suffix: str | None = None) -> dict:
return self.groups[0].as_espminer(user_suffix=user_suffix)
def as_bitaxe(self, user_suffix: str | None = None) -> dict:
return self.groups[0].as_bitaxe(user_suffix=user_suffix)
def as_luxos(self, user_suffix: str | None = None) -> dict:
return {}
@@ -576,8 +576,8 @@ class PoolConfig(MinerConfigValue):
return cls(groups=[PoolGroup.from_mara(web_config["pools"])])
@classmethod
def from_espminer(cls, web_system_info: dict) -> "PoolConfig":
return cls(groups=[PoolGroup.from_espminer(web_system_info)])
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":

View File

@@ -26,7 +26,6 @@ class MinerMake(str, Enum):
AURADINE = "Auradine"
EPIC = "ePIC"
BITAXE = "BitAxe"
LUCKYMINER = "LuckyMiner"
ICERIVER = "IceRiver"
HAMMER = "Hammer"
VOLCMINER = "VolcMiner"

View File

@@ -59,7 +59,6 @@ class AntminerModels(MinerModelType):
T19 = "T19"
S21 = "S21"
S21Pro = "S21 Pro"
S21Hydro = "S21 Hydro"
T21 = "T21"
def __str__(self):
@@ -508,13 +507,6 @@ class BitAxeModels(MinerModelType):
return self.value
class LuckyMinerModels(MinerModelType):
BM1366 = "LV08"
def __str__(self):
return self.value
class IceRiverModels(MinerModelType):
KS0 = "KS0"
KS1 = "KS1"
@@ -558,7 +550,6 @@ class MinerModel:
AURADINE = AuradineModels
EPIC = ePICModels
BITAXE = BitAxeModels
LUCKYMINER = LuckyMinerModels
ICERIVER = IceRiverModels
HAMMER = HammerModels
VOLCMINER = VolcMinerModels

View File

@@ -15,7 +15,7 @@
# ------------------------------------------------------------------------------
from pyasic.miners.backends import AntminerModern
from pyasic.miners.device.models import S21, S21Hydro, S21Pro
from pyasic.miners.device.models import S21, S21Pro
class BMMinerS21(AntminerModern, S21):
@@ -24,7 +24,3 @@ class BMMinerS21(AntminerModern, S21):
class BMMinerS21Pro(AntminerModern, S21Pro):
pass
class BMMinerS21Hydro(AntminerModern, S21Hydro):
pass

View File

@@ -13,5 +13,5 @@
# See the License for the specific language governing permissions and -
# limitations under the License. -
# ------------------------------------------------------------------------------
from .S21 import BMMinerS21, BMMinerS21Hydro, BMMinerS21Pro
from .S21 import BMMinerS21, BMMinerS21Pro
from .T21 import BMMinerT21

View File

@@ -15,12 +15,8 @@
# ------------------------------------------------------------------------------
from pyasic.miners.backends import BOSer
from pyasic.miners.device.models import S21, S21Pro
from pyasic.miners.device.models import S21
class BOSMinerS21(BOSer, S21):
pass
class BOSMinerS21Pro(BOSer, S21Pro):
pass

View File

@@ -14,5 +14,5 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from .S21 import BOSMinerS21, BOSMinerS21Pro
from .S21 import BOSMinerS21
from .T21 import BOSMinerT21

View File

@@ -27,7 +27,6 @@ from pyasic.miners.device.models import (
S19jNoPIC,
S19jPro,
S19KPro,
S19NoPIC,
S19Plus,
S19Pro,
S19ProHydro,
@@ -40,10 +39,6 @@ class HiveonS19(HiveonModern, S19):
pass
class HiveonS19NoPIC(HiveonModern, S19NoPIC):
pass
class HiveonS19Plus(HiveonModern, S19Plus):
pass

View File

@@ -25,7 +25,6 @@ from .S19 import (
HiveonS19jPro,
HiveonS19KPro,
HiveonS19L,
HiveonS19NoPIC,
HiveonS19Plus,
HiveonS19Pro,
HiveonS19ProHydro,

View File

@@ -13,91 +13,10 @@
# See the License for the specific language governing permissions and -
# limitations under the License. -
# ------------------------------------------------------------------------------
from typing import Optional
from pyasic import APIError
from pyasic.miners.backends import AvalonMiner
from pyasic.miners.data import (
DataFunction,
DataLocations,
DataOptions,
RPCAPICommand,
WebAPICommand,
)
from pyasic.miners.device.models import AvalonNano3
from pyasic.web.avalonminer import AvalonMinerWebAPI
AVALON_NANO_DATA_LOC = DataLocations(
**{
str(DataOptions.MAC): DataFunction(
"_get_mac",
[WebAPICommand("web_minerinfo", "get_minerinfo")],
),
str(DataOptions.API_VERSION): DataFunction(
"_get_api_ver",
[RPCAPICommand("rpc_version", "version")],
),
str(DataOptions.FW_VERSION): DataFunction(
"_get_fw_ver",
[RPCAPICommand("rpc_version", "version")],
),
str(DataOptions.HASHRATE): DataFunction(
"_get_hashrate",
[RPCAPICommand("rpc_devs", "devs")],
),
str(DataOptions.EXPECTED_HASHRATE): DataFunction(
"_get_expected_hashrate",
[RPCAPICommand("rpc_stats", "stats")],
),
str(DataOptions.HASHBOARDS): DataFunction(
"_get_hashboards",
[RPCAPICommand("rpc_stats", "stats")],
),
str(DataOptions.ENVIRONMENT_TEMP): DataFunction(
"_get_env_temp",
[RPCAPICommand("rpc_stats", "stats")],
),
str(DataOptions.WATTAGE_LIMIT): DataFunction(
"_get_wattage_limit",
[RPCAPICommand("rpc_stats", "stats")],
),
str(DataOptions.FANS): DataFunction(
"_get_fans",
[RPCAPICommand("rpc_stats", "stats")],
),
str(DataOptions.FAULT_LIGHT): DataFunction(
"_get_fault_light",
[RPCAPICommand("rpc_stats", "stats")],
),
str(DataOptions.UPTIME): DataFunction(
"_get_uptime",
[RPCAPICommand("rpc_stats", "stats")],
),
str(DataOptions.POOLS): DataFunction(
"_get_pools",
[RPCAPICommand("rpc_pools", "pools")],
),
}
)
class CGMinerAvalonNano3(AvalonMiner, AvalonNano3):
_web_cls = AvalonMinerWebAPI
web: AvalonMinerWebAPI
data_locations = AVALON_NANO_DATA_LOC
async def _get_mac(self, web_minerinfo: dict) -> Optional[dict]:
if web_minerinfo is None:
try:
web_minerinfo = await self.web.minerinfo()
except APIError:
pass
if web_minerinfo is not None:
try:
mac = web_minerinfo.get("mac")
if mac is not None:
return mac.upper()
except (KeyError, ValueError):
pass
pass

View File

@@ -28,7 +28,6 @@ from .hammer import BlackMiner
from .hiveon import HiveonModern, HiveonOld
from .iceriver import IceRiver
from .innosilicon import Innosilicon
from .luckyminer import LuckyMiner
from .luxminer import LUXMiner
from .marathon import MaraMiner
from .unknown import UnknownMiner

View File

@@ -1,7 +1,235 @@
from pyasic.miners.backends.espminer import ESPMiner
from typing import List, Optional
from pyasic import APIError, MinerConfig
from pyasic.data import Fan, HashBoard
from pyasic.device.algorithm import AlgoHashRate
from pyasic.device.firmware import MinerFirmware
from pyasic.miners.base import BaseMiner
from pyasic.miners.data import DataFunction, DataLocations, DataOptions, WebAPICommand
from pyasic.web.bitaxe import BitAxeWebAPI
BITAXE_DATA_LOC = DataLocations(
**{
str(DataOptions.HASHRATE): DataFunction(
"_get_hashrate",
[WebAPICommand("web_system_info", "system/info")],
),
str(DataOptions.EXPECTED_HASHRATE): DataFunction(
"_get_expected_hashrate",
[WebAPICommand("web_system_info", "system/info")],
),
str(DataOptions.WATTAGE): DataFunction(
"_get_wattage",
[WebAPICommand("web_system_info", "system/info")],
),
str(DataOptions.UPTIME): DataFunction(
"_get_uptime",
[WebAPICommand("web_system_info", "system/info")],
),
str(DataOptions.HASHBOARDS): DataFunction(
"_get_hashboards",
[WebAPICommand("web_system_info", "system/info")],
),
str(DataOptions.HOSTNAME): DataFunction(
"_get_hostname",
[WebAPICommand("web_system_info", "system/info")],
),
str(DataOptions.FANS): DataFunction(
"_get_fans",
[WebAPICommand("web_system_info", "system/info")],
),
str(DataOptions.FW_VERSION): DataFunction(
"_get_fw_ver",
[WebAPICommand("web_system_info", "system/info")],
),
str(DataOptions.API_VERSION): DataFunction(
"_get_api_ver",
[WebAPICommand("web_system_info", "system/info")],
),
str(DataOptions.MAC): DataFunction(
"_get_mac",
[WebAPICommand("web_system_info", "system/info")],
),
}
)
class BitAxe(ESPMiner):
class BitAxe(BaseMiner):
"""Handler for BitAxe"""
pass
web: BitAxeWebAPI
_web_cls = BitAxeWebAPI
firmware = MinerFirmware.STOCK
data_locations = BITAXE_DATA_LOC
async def reboot(self) -> bool:
await self.web.restart()
return True
async def get_config(self) -> MinerConfig:
web_system_info = await self.web.system_info()
return MinerConfig.from_bitaxe(web_system_info)
async def send_config(self, config: MinerConfig, user_suffix: str = None) -> None:
await self.web.update_settings(**config.as_bitaxe())
async def _get_wattage(self, web_system_info: dict = None) -> Optional[int]:
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 round(web_system_info["power"])
except KeyError:
pass
async def _get_hashrate(
self, web_system_info: dict = None
) -> Optional[AlgoHashRate]:
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 self.algo.hashrate(
rate=float(web_system_info["hashRate"]), unit=self.algo.unit.GH
).into(self.algo.unit.default)
except KeyError:
pass
async def _get_expected_hashrate(
self, web_system_info: dict = None
) -> Optional[AlgoHashRate]:
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:
expected_hashrate = (
web_system_info.get("smallCoreCount")
* web_system_info.get("asicCount")
* web_system_info.get("frequency")
)
return self.algo.hashrate(
rate=float(expected_hashrate), unit=self.algo.unit.MH
).into(self.algo.unit.default)
except KeyError:
pass
async def _get_uptime(self, web_system_info: dict = None) -> Optional[int]:
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["uptimeSeconds"]
except KeyError:
pass
async def _get_hashboards(self, web_system_info: dict = None) -> List[HashBoard]:
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 [
HashBoard(
hashrate=self.algo.hashrate(
rate=float(web_system_info["hashRate"]),
unit=self.algo.unit.GH,
).into(self.algo.unit.default),
chip_temp=web_system_info.get("temp"),
temp=web_system_info.get("vrTemp"),
chips=web_system_info.get("asicCount", 1),
expected_chips=self.expected_chips,
missing=False,
active=True,
voltage=web_system_info.get("voltage"),
)
]
except KeyError:
pass
return []
async def _get_fans(self, web_system_info: dict = None) -> List[Fan]:
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 [Fan(speed=web_system_info["fanrpm"])]
except KeyError:
pass
return []
async def _get_hostname(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["hostname"]
except KeyError:
pass
async def _get_api_ver(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["version"]
except KeyError:
pass
async def _get_fw_ver(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["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

View File

@@ -1,235 +0,0 @@
from typing import List, Optional
from pyasic import APIError, MinerConfig
from pyasic.data import Fan, HashBoard
from pyasic.device.algorithm import AlgoHashRate
from pyasic.device.firmware import MinerFirmware
from pyasic.miners.base import BaseMiner
from pyasic.miners.data import DataFunction, DataLocations, DataOptions, WebAPICommand
from pyasic.web.espminer import ESPMinerWebAPI
ESPMINER_DATA_LOC = DataLocations(
**{
str(DataOptions.HASHRATE): DataFunction(
"_get_hashrate",
[WebAPICommand("web_system_info", "system/info")],
),
str(DataOptions.EXPECTED_HASHRATE): DataFunction(
"_get_expected_hashrate",
[WebAPICommand("web_system_info", "system/info")],
),
str(DataOptions.WATTAGE): DataFunction(
"_get_wattage",
[WebAPICommand("web_system_info", "system/info")],
),
str(DataOptions.UPTIME): DataFunction(
"_get_uptime",
[WebAPICommand("web_system_info", "system/info")],
),
str(DataOptions.HASHBOARDS): DataFunction(
"_get_hashboards",
[WebAPICommand("web_system_info", "system/info")],
),
str(DataOptions.HOSTNAME): DataFunction(
"_get_hostname",
[WebAPICommand("web_system_info", "system/info")],
),
str(DataOptions.FANS): DataFunction(
"_get_fans",
[WebAPICommand("web_system_info", "system/info")],
),
str(DataOptions.FW_VERSION): DataFunction(
"_get_fw_ver",
[WebAPICommand("web_system_info", "system/info")],
),
str(DataOptions.API_VERSION): DataFunction(
"_get_api_ver",
[WebAPICommand("web_system_info", "system/info")],
),
str(DataOptions.MAC): DataFunction(
"_get_mac",
[WebAPICommand("web_system_info", "system/info")],
),
}
)
class ESPMiner(BaseMiner):
"""Handler for ESPMiner"""
web: ESPMinerWebAPI
_web_cls = ESPMinerWebAPI
firmware = MinerFirmware.STOCK
data_locations = ESPMINER_DATA_LOC
async def reboot(self) -> bool:
await self.web.restart()
return True
async def get_config(self) -> MinerConfig:
web_system_info = await self.web.system_info()
return MinerConfig.from_espminer(web_system_info)
async def send_config(self, config: MinerConfig, user_suffix: str = None) -> None:
await self.web.update_settings(**config.as_espminer())
async def _get_wattage(self, web_system_info: dict = None) -> Optional[int]:
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 round(web_system_info["power"])
except KeyError:
pass
async def _get_hashrate(
self, web_system_info: dict = None
) -> Optional[AlgoHashRate]:
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 self.algo.hashrate(
rate=float(web_system_info["hashRate"]), unit=self.algo.unit.GH
).into(self.algo.unit.default)
except KeyError:
pass
async def _get_expected_hashrate(
self, web_system_info: dict = None
) -> Optional[AlgoHashRate]:
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:
expected_hashrate = (
web_system_info.get("smallCoreCount")
* web_system_info.get("asicCount")
* web_system_info.get("frequency")
)
return self.algo.hashrate(
rate=float(expected_hashrate), unit=self.algo.unit.MH
).into(self.algo.unit.default)
except KeyError:
pass
async def _get_uptime(self, web_system_info: dict = None) -> Optional[int]:
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["uptimeSeconds"]
except KeyError:
pass
async def _get_hashboards(self, web_system_info: dict = None) -> List[HashBoard]:
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 [
HashBoard(
hashrate=self.algo.hashrate(
rate=float(web_system_info["hashRate"]),
unit=self.algo.unit.GH,
).into(self.algo.unit.default),
chip_temp=web_system_info.get("temp"),
temp=web_system_info.get("vrTemp"),
chips=web_system_info.get("asicCount", 1),
expected_chips=self.expected_chips,
missing=False,
active=True,
voltage=web_system_info.get("voltage"),
)
]
except KeyError:
pass
return []
async def _get_fans(self, web_system_info: dict = None) -> List[Fan]:
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 [Fan(speed=web_system_info["fanrpm"])]
except KeyError:
pass
return []
async def _get_hostname(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["hostname"]
except KeyError:
pass
async def _get_api_ver(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["version"]
except KeyError:
pass
async def _get_fw_ver(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["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

View File

@@ -1,7 +0,0 @@
from pyasic.miners.backends.espminer import ESPMiner
class LuckyMiner(ESPMiner):
"""Handler for LuckyMiner"""
pass

View File

@@ -50,10 +50,6 @@ class BitAxeMake(BaseMiner):
make = MinerMake.BITAXE
class LuckyMinerMake(BaseMiner):
make = MinerMake.LUCKYMINER
class IceRiverMake(BaseMiner):
make = MinerMake.ICERIVER

View File

@@ -34,12 +34,3 @@ class S21Pro(AntMinerMake):
expected_fans = 4
expected_hashboards = 3
algo = MinerAlgo.SHA256
class S21Hydro(AntMinerMake):
raw_model = MinerModel.ANTMINER.S21Hydro
expected_chips = 216
expected_hashboards = 2
expected_fans = 0
algo = MinerAlgo.SHA256

View File

@@ -14,5 +14,5 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from .S21 import S21, S21Hydro, S21Pro
from .S21 import S21, S21Pro
from .T21 import T21

View File

@@ -1,12 +0,0 @@
from pyasic.device.algorithm import MinerAlgo
from pyasic.device.models import MinerModel
from pyasic.miners.device.makes import LuckyMinerMake
class LV08(LuckyMinerMake):
raw_model = MinerModel.LUCKYMINER.BM1366
expected_hashboards = 1
expected_chips = 1
expected_fans = 1
algo = MinerAlgo.SHA256

View File

@@ -1 +0,0 @@
from .LV08 import LV08

View File

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

View File

@@ -41,7 +41,6 @@ from pyasic.miners.goldshell import *
from pyasic.miners.hammer import *
from pyasic.miners.iceriver import *
from pyasic.miners.innosilicon import *
from pyasic.miners.luckyminer import *
from pyasic.miners.volcminer import *
from pyasic.miners.whatsminer import *
@@ -63,7 +62,6 @@ class MinerTypes(enum.Enum):
ICERIVER = 13
HAMMER = 14
VOLCMINER = 15
LUCKYMINER = 16
MINER_CLASSES = {
@@ -119,7 +117,6 @@ MINER_CLASSES = {
"ANTMINER BHB68606": BMMinerS21, # ???
"ANTMINER S21 PRO": BMMinerS21Pro,
"ANTMINER T21": BMMinerT21,
"ANTMINER S21 HYD.": BMMinerS21Hydro,
},
MinerTypes.WHATSMINER: {
None: type("WhatsminerUnknown", (BTMiner, WhatsMinerMake), {}),
@@ -547,7 +544,6 @@ MINER_CLASSES = {
"ANTMINER S19 PRO+ HYD.": BOSMinerS19ProPlusHydro,
"ANTMINER T19": BOSMinerT19,
"ANTMINER S21": BOSMinerS21,
"ANTMINER S21 PRO": BOSMinerS21Pro,
"ANTMINER T21": BOSMinerT21,
"BRAIINS MINI MINER BMM 100": BraiinsBMM100,
"BRAIINS MINI MINER BMM 101": BraiinsBMM101,
@@ -563,7 +559,7 @@ MINER_CLASSES = {
"ANTMINER S19NOPIC": VNishS19NoPIC,
"ANTMINER S19 PRO": VNishS19Pro,
"ANTMINER S19J": VNishS19j,
"ANTMINER S19I": VNishS19i,
"ANTMINER S19I": VNishS19j,
"ANTMINER S19J PRO": VNishS19jPro,
"ANTMINER S19J PRO A": VNishS19jPro,
"ANTMINER S19J PRO BB": VNishS19jPro,
@@ -596,7 +592,6 @@ MINER_CLASSES = {
"ANTMINER T9": HiveonT9,
"ANTMINER S19JPRO": HiveonS19jPro,
"ANTMINER S19": HiveonS19,
"ANTMINER S19X88": HiveonS19NoPIC,
},
MinerTypes.LUX_OS: {
None: LUXMiner,
@@ -639,10 +634,6 @@ MINER_CLASSES = {
"BM1397": BitAxeMax,
"BM1370": BitAxeGamma,
},
MinerTypes.LUCKYMINER: {
None: LuckyMiner,
"BM1366": LuckyMinerLV08,
},
MinerTypes.ICERIVER: {
None: type("IceRiverUnknown", (IceRiver, IceRiverMake), {}),
"KS0": IceRiverKS0,
@@ -740,7 +731,6 @@ class MinerFactory:
MinerTypes.AURADINE: self.get_miner_model_auradine,
MinerTypes.MARATHON: self.get_miner_model_marathon,
MinerTypes.BITAXE: self.get_miner_model_bitaxe,
MinerTypes.LUCKYMINER: self.get_miner_model_luckyminer,
MinerTypes.ICERIVER: self.get_miner_model_iceriver,
MinerTypes.HAMMER: self.get_miner_model_hammer,
MinerTypes.VOLCMINER: self.get_miner_model_volcminer,
@@ -843,8 +833,6 @@ class MinerFactory:
return MinerTypes.ICERIVER
if "AxeOS" in web_text:
return MinerTypes.BITAXE
if "Lucky miner" in web_text:
return MinerTypes.LUCKYMINER
if "cloud-box" in web_text:
return MinerTypes.GOLDSHELL
if "AnthillOS" in web_text:
@@ -889,7 +877,6 @@ class MinerFactory:
await writer.drain()
# loop to receive all the data
timeouts_remaining = max(1, int(settings.get("factory_get_timeout", 3)))
while True:
try:
d = await asyncio.wait_for(reader.read(4096), timeout=1)
@@ -897,10 +884,7 @@ class MinerFactory:
break
data += d
except asyncio.TimeoutError:
timeouts_remaining -= 1
if not timeouts_remaining:
logger.warning(f"{ip}: Socket ping timeout.")
break
pass
except ConnectionResetError:
return
except asyncio.CancelledError:
@@ -1308,18 +1292,6 @@ class MinerFactory:
except (TypeError, LookupError):
pass
async def get_miner_model_luckyminer(self, ip: str) -> str | None:
web_json_data = await self.send_web_command(ip, "/api/system/info")
try:
miner_model = web_json_data["ASICModel"]
if miner_model == "":
return None
return miner_model
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:

View File

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

View File

@@ -1,6 +0,0 @@
from pyasic.miners.backends.luckyminer import LuckyMiner
from pyasic.miners.device.models.luckyminer import LV08
class LuckyMinerLV08(LuckyMiner, LV08):
pass

View File

@@ -1 +0,0 @@
from .LV08 import LuckyMinerLV08

View File

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

View File

@@ -31,7 +31,7 @@ _settings = { # defaults
"default_whatsminer_rpc_password": "admin",
"default_innosilicon_web_password": "admin",
"default_antminer_web_password": "root",
"default_hammer_web_password": "root",
"default_hammer_web_password": "ltc@dog",
"default_volcminer_web_password": "ltc@dog",
"default_bosminer_web_password": "root",
"default_vnish_web_password": "admin",

View File

@@ -1,110 +0,0 @@
# ------------------------------------------------------------------------------
# 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 __future__ import annotations
import asyncio
import hashlib
import json
from pathlib import Path
from typing import Any
import aiofiles
import httpx
from pyasic import settings
from pyasic.web.base import BaseWebAPI
class AvalonMinerWebAPI(BaseWebAPI):
def __init__(self, ip: str) -> None:
"""Initialize the modern Avalonminer API client with a specific IP address.
Args:
ip (str): IP address of the Avalonminer device.
"""
super().__init__(ip)
self.username = "root"
self.pwd = settings.get("default_avalonminer_web_password", "root")
async def send_command(
self,
command: str | bytes,
ignore_errors: bool = False,
allow_warning: bool = True,
**parameters: Any,
) -> dict:
"""Send a command to the Avalonminer device using HTTP digest authentication.
Args:
command (str | bytes): The CGI command to send.
ignore_errors (bool): If True, ignore any HTTP errors.
allow_warning (bool): If True, proceed with warnings.
**parameters: Arbitrary keyword arguments to be sent as parameters in the request.
Returns:
dict: The JSON response from the device or an empty dictionary if an error occurs.
"""
cookie_data = "ff0000ff" + hashlib.sha256(self.pwd.encode()).hexdigest()[:24]
url = f"http://{self.ip}:{self.port}/{command}.cgi"
try:
async with httpx.AsyncClient(transport=settings.transport()) as client:
client.cookies.set("auth", cookie_data)
resp = await client.get(url)
raw_data = resp.text.replace("minerinfoCallback(", "").replace(");", "")
return json.loads(raw_data)
except httpx.HTTPError:
pass
return {}
async def multicommand(
self, *commands: str, ignore_errors: bool = False, allow_warning: bool = True
) -> dict:
async with httpx.AsyncClient(transport=settings.transport()) as client:
cookie_data = (
"ff0000ff" + hashlib.sha256(self.pwd.encode()).hexdigest()[:24]
)
client.cookies.set("auth", cookie_data)
tasks = [
asyncio.create_task(self._handle_multicommand(client, command))
for command in commands
]
all_data = await asyncio.gather(*tasks)
data = {}
for item in all_data:
data.update(item)
data["multicommand"] = True
return data
async def _handle_multicommand(
self, client: httpx.AsyncClient, command: str
) -> dict:
try:
url = f"http://{self.ip}:{self.port}/{command}.cgi"
resp = await client.get(url)
raw_data = resp.text.replace("minerinfoCallback(", "").replace(");", "")
return json.loads(raw_data)
except httpx.HTTPError:
pass
return {}
async def minerinfo(self):
return await self.send_command("get_minerinfo")
async def home(self):
return await self.send_command("get_home")

View File

@@ -10,7 +10,7 @@ from pyasic import APIError, settings
from pyasic.web.base import BaseWebAPI
class ESPMinerWebAPI(BaseWebAPI):
class BitAxeWebAPI(BaseWebAPI):
async def send_command(
self,
command: str | bytes,

View File

@@ -39,7 +39,7 @@ class ApiVersionServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "ApiVersion":
return await self._unary_unary(
"/braiins.bos.ApiVersionService/GetApiVersion",

View File

@@ -1706,7 +1706,7 @@ class ActionsServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "StartResponse":
return await self._unary_unary(
"/braiins.bos.v1.ActionsService/Start",
@@ -1723,7 +1723,7 @@ class ActionsServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "StopResponse":
return await self._unary_unary(
"/braiins.bos.v1.ActionsService/Stop",
@@ -1740,7 +1740,7 @@ class ActionsServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "PauseMiningResponse":
return await self._unary_unary(
"/braiins.bos.v1.ActionsService/PauseMining",
@@ -1757,7 +1757,7 @@ class ActionsServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "ResumeMiningResponse":
return await self._unary_unary(
"/braiins.bos.v1.ActionsService/ResumeMining",
@@ -1774,7 +1774,7 @@ class ActionsServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "RestartResponse":
return await self._unary_unary(
"/braiins.bos.v1.ActionsService/Restart",
@@ -1791,7 +1791,7 @@ class ActionsServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "RebootResponse":
return await self._unary_unary(
"/braiins.bos.v1.ActionsService/Reboot",
@@ -1808,7 +1808,7 @@ class ActionsServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "LocateDeviceStatusResponse":
return await self._unary_unary(
"/braiins.bos.v1.ActionsService/SetLocateDeviceStatus",
@@ -1825,7 +1825,7 @@ class ActionsServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "LocateDeviceStatusResponse":
return await self._unary_unary(
"/braiins.bos.v1.ActionsService/GetLocateDeviceStatus",
@@ -1844,7 +1844,7 @@ class AuthenticationServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "LoginResponse":
return await self._unary_unary(
"/braiins.bos.v1.AuthenticationService/Login",
@@ -1861,7 +1861,7 @@ class AuthenticationServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "SetPasswordResponse":
return await self._unary_unary(
"/braiins.bos.v1.AuthenticationService/SetPassword",
@@ -1880,7 +1880,7 @@ class CoolingServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "GetCoolingStateResponse":
return await self._unary_unary(
"/braiins.bos.v1.CoolingService/GetCoolingState",
@@ -1897,7 +1897,7 @@ class CoolingServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "SetImmersionModeResponse":
return await self._unary_unary(
"/braiins.bos.v1.CoolingService/SetImmersionMode",
@@ -1916,7 +1916,7 @@ class PerformanceServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "GetTunerStateResponse":
return await self._unary_unary(
"/braiins.bos.v1.PerformanceService/GetTunerState",
@@ -1933,7 +1933,7 @@ class PerformanceServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "ListTargetProfilesResponse":
return await self._unary_unary(
"/braiins.bos.v1.PerformanceService/ListTargetProfiles",
@@ -1950,7 +1950,7 @@ class PerformanceServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "SetPowerTargetResponse":
return await self._unary_unary(
"/braiins.bos.v1.PerformanceService/SetDefaultPowerTarget",
@@ -1967,7 +1967,7 @@ class PerformanceServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "SetPowerTargetResponse":
return await self._unary_unary(
"/braiins.bos.v1.PerformanceService/SetPowerTarget",
@@ -1984,7 +1984,7 @@ class PerformanceServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "SetPowerTargetResponse":
return await self._unary_unary(
"/braiins.bos.v1.PerformanceService/IncrementPowerTarget",
@@ -2001,7 +2001,7 @@ class PerformanceServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "SetPowerTargetResponse":
return await self._unary_unary(
"/braiins.bos.v1.PerformanceService/DecrementPowerTarget",
@@ -2018,7 +2018,7 @@ class PerformanceServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "SetHashrateTargetResponse":
return await self._unary_unary(
"/braiins.bos.v1.PerformanceService/SetDefaultHashrateTarget",
@@ -2035,7 +2035,7 @@ class PerformanceServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "SetHashrateTargetResponse":
return await self._unary_unary(
"/braiins.bos.v1.PerformanceService/SetHashrateTarget",
@@ -2052,7 +2052,7 @@ class PerformanceServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "SetHashrateTargetResponse":
return await self._unary_unary(
"/braiins.bos.v1.PerformanceService/IncrementHashrateTarget",
@@ -2069,7 +2069,7 @@ class PerformanceServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "SetHashrateTargetResponse":
return await self._unary_unary(
"/braiins.bos.v1.PerformanceService/DecrementHashrateTarget",
@@ -2086,7 +2086,7 @@ class PerformanceServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "SetDpsResponse":
return await self._unary_unary(
"/braiins.bos.v1.PerformanceService/SetDPS",
@@ -2103,7 +2103,7 @@ class PerformanceServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "PerformanceMode":
return await self._unary_unary(
"/braiins.bos.v1.PerformanceService/SetPerformanceMode",
@@ -2120,7 +2120,7 @@ class PerformanceServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "PerformanceMode":
return await self._unary_unary(
"/braiins.bos.v1.PerformanceService/GetActivePerformanceMode",
@@ -2137,7 +2137,7 @@ class PerformanceServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "RemoveTunedProfilesResponse":
return await self._unary_unary(
"/braiins.bos.v1.PerformanceService/RemoveTunedProfiles",
@@ -2156,7 +2156,7 @@ class PoolServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "GetPoolGroupsResponse":
return await self._unary_unary(
"/braiins.bos.v1.PoolService/GetPoolGroups",
@@ -2173,7 +2173,7 @@ class PoolServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "CreatePoolGroupResponse":
return await self._unary_unary(
"/braiins.bos.v1.PoolService/CreatePoolGroup",
@@ -2190,7 +2190,7 @@ class PoolServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "UpdatePoolGroupResponse":
return await self._unary_unary(
"/braiins.bos.v1.PoolService/UpdatePoolGroup",
@@ -2207,7 +2207,7 @@ class PoolServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "RemovePoolGroupResponse":
return await self._unary_unary(
"/braiins.bos.v1.PoolService/RemovePoolGroup",
@@ -2224,7 +2224,7 @@ class PoolServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "SetPoolGroupsResponse":
return await self._unary_unary(
"/braiins.bos.v1.PoolService/SetPoolGroups",
@@ -2243,7 +2243,7 @@ class ConfigurationServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "GetMinerConfigurationResponse":
return await self._unary_unary(
"/braiins.bos.v1.ConfigurationService/GetMinerConfiguration",
@@ -2260,7 +2260,7 @@ class ConfigurationServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "GetConstraintsResponse":
return await self._unary_unary(
"/braiins.bos.v1.ConfigurationService/GetConstraints",
@@ -2279,7 +2279,7 @@ class LicenseServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "GetLicenseStateResponse":
return await self._unary_unary(
"/braiins.bos.v1.LicenseService/GetLicenseState",
@@ -2298,7 +2298,7 @@ class MinerServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> AsyncIterator[GetMinerStatusResponse]:
async for response in self._unary_stream(
"/braiins.bos.v1.MinerService/GetMinerStatus",
@@ -2316,7 +2316,7 @@ class MinerServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "GetMinerDetailsResponse":
return await self._unary_unary(
"/braiins.bos.v1.MinerService/GetMinerDetails",
@@ -2333,7 +2333,7 @@ class MinerServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "GetMinerStatsResponse":
return await self._unary_unary(
"/braiins.bos.v1.MinerService/GetMinerStats",
@@ -2350,7 +2350,7 @@ class MinerServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "GetErrorsResponse":
return await self._unary_unary(
"/braiins.bos.v1.MinerService/GetErrors",
@@ -2367,7 +2367,7 @@ class MinerServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "GetHashboardsResponse":
return await self._unary_unary(
"/braiins.bos.v1.MinerService/GetHashboards",
@@ -2384,7 +2384,7 @@ class MinerServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> AsyncIterator[GetSupportArchiveResponse]:
async for response in self._unary_stream(
"/braiins.bos.v1.MinerService/GetSupportArchive",
@@ -2402,7 +2402,7 @@ class MinerServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "EnableHashboardsResponse":
return await self._unary_unary(
"/braiins.bos.v1.MinerService/EnableHashboards",
@@ -2419,7 +2419,7 @@ class MinerServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "DisableHashboardsResponse":
return await self._unary_unary(
"/braiins.bos.v1.MinerService/DisableHashboards",
@@ -2438,7 +2438,7 @@ class NetworkServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "GetNetworkConfigurationResponse":
return await self._unary_unary(
"/braiins.bos.v1.NetworkService/GetNetworkConfiguration",
@@ -2455,7 +2455,7 @@ class NetworkServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "SetNetworkConfigurationResponse":
return await self._unary_unary(
"/braiins.bos.v1.NetworkService/SetNetworkConfiguration",
@@ -2472,7 +2472,7 @@ class NetworkServiceStub(betterproto.ServiceStub):
*,
timeout: Optional[float] = None,
deadline: Optional["Deadline"] = None,
metadata: Optional["MetadataLike"] = None,
metadata: Optional["MetadataLike"] = None
) -> "GetNetworkInfoResponse":
return await self._unary_unary(
"/braiins.bos.v1.NetworkService/GetNetworkInfo",

View File

@@ -1,7 +0,0 @@
from __future__ import annotations
from .bitaxe import ESPMinerWebAPI
class LuckyMinerWebAPI(ESPMinerWebAPI):
pass

View File

@@ -1,6 +1,6 @@
[project]
name = "pyasic"
version = "0.71.1"
version = "0.70.0"
description = "A simplified and standardized interface for Bitcoin ASICs."
authors = [{name = "UpstreamData", email = "brett@upstreamdata.ca"}]
@@ -40,11 +40,10 @@ classifiers = [
"Programming Language :: Python :: 3.13",
]
requires-python = ">3.9, <4.0"
requires-python = "^3.9"
dependencies = [
"httpx>=0.26.0",
"asyncssh>=2.17.0",
"cryptography>=39.0",
"passlib>=1.7.4",
"pyaml>=23.12.0",
"tomli (>=2.2.1,<3.0.0) ; python_version < '3.11'",