This release is a pre-release and may not be stable for production use.
pyasic-umhost
Упрощённый и стандартизированный интерфейс для управления Bitcoin ASIC-майнерами.
Форк pyasic — асинхронная Python-библиотека для обнаружения, опроса и управления ASIC-майнерами (Antminer, Whatsminer, Avalon, Braiins OS, VNish, LuxOS, Goldshell, Auradine, Innosilicon, ePIC, Hiveon, BitAxe, Iceriver, Volcminer и др.).
Форк добавляет:
app.py— Streamlit-интерфейс поверх библиотеки.inspector/— инструмент для сбора полного отчёта по майнеру.
Python >3.10, <4.0. Лицензия Apache-2.0.
Установка
Дистрибутив называется pyasic-umhost, но импортируется как pyasic:
pip install pyasic-umhost
import pyasic
Установка для разработки
poetry install --with dev # добавьте ,docs для зависимостей mkdocs
pre-commit install
Запуск Streamlit-интерфейса
Streamlit не объявлен в зависимостях pyproject.toml — установите его отдельно:
pip install streamlit
streamlit run app.py
Быстрый старт
Поиск майнеров в сети
MinerNetwork сканирует подсеть и возвращает список найденных майнеров с уже определённым типом.
import asyncio
from pyasic.network import MinerNetwork
async def scan_miners():
# любой IP трактуется как подсеть /24 (255 адресов)
network = MinerNetwork.from_subnet("192.168.1.50/24") # сеть 192.168.1.0-255
miners = await network.scan()
print(miners)
if __name__ == "__main__":
asyncio.run(scan_miners())
Подключение по известному IP
Если IP уже известен, используйте get_miner() — он определит модель майнера или вернёт UnknownMiner.
import asyncio
from pyasic import get_miner
async def get_miners():
# быстрее опрашивать несколько майнеров параллельно через asyncio.gather
tasks = [get_miner("192.168.1.75"), get_miner("192.168.1.76")]
miners = await asyncio.gather(*tasks)
print(miners)
if __name__ == "__main__":
asyncio.run(get_miners())
Получение данных
get_data() возвращает экземпляр MinerData со всеми данными, которые удалось собрать. Любое поле доступно как атрибут, например MinerData().hashrate.
import asyncio
from pyasic import get_miner
async def gather_miner_data():
miner = await get_miner("192.168.1.75")
if miner is not None:
data = await miner.get_data()
print(data) # весь датакласс
print(data.hashrate) # хешрейт в TH/s
if __name__ == "__main__":
asyncio.run(gather_miner_data())
Для нескольких майнеров запускайте get_data() параллельно:
all_data = await asyncio.gather(*[m.get_data() for m in miners])
Экземпляры MinerData можно складывать и делить на число — удобно для усреднённых данных по парку:
from pyasic import MinerData
data = [MinerData("192.168.1.1"), MinerData("192.168.1.2")]
average = sum(data, start=MinerData("0.0.0.0")) / len(data)
Управление майнером
Каждый класс майнера реализует единый набор управляющих методов из BaseMiner:
check_light, fault_light_on, fault_light_off, get_config, get_data, get_errors,
get_hostname, get_model, reboot, restart_backend, stop_mining, resume_mining,
is_mining, send_config, set_power_limit.
Для stock Antminer stop_mining() и resume_mining() проверяют результат
повторным чтением bitmain-work-mode: ответ CGI M000 сам по себе не
подтверждает смену режима. Сначала используется поле записи miner-mode.
Если прошивка его игнорирует или возвращает структурированный CGI-отказ,
а чтение подтверждает прежний режим, библиотека пробует bitmain-work-mode.
Поддерживаются числовое и строковое значения обоих полей; подтвержденный
формат запоминается в экземпляре майнера. Наличие
bitmain-user-ip-cat не определяет формат: это поле есть и у T21 с прошивкой
26.01.2025, которая принимает только miner-mode.
Пулы и остальные параметры сохраняются из текущей конфигурации. После
потерянного HTTP-ответа (встречается на KS5 при перезапуске сервиса) режим
также проверяется чтением: подтвержденная цель означает успех без повторной
записи. При неизвестном или неподтвержденном режиме методы выбрасывают
APIError, чтобы агент мог записать причину и повторить задачу. Ошибка HTTP
сама по себе не разрешает подбор другого формата. Выход из сна подтверждает
режим работы; запуск плат и восстановление хешрейта могут занять дополнительное время.
Эта совместимость относится к stock-прошивкам с JSON CGI (AntminerModern).
Она не добавляет сон прошивкам, в которых такой функции нет, и не заменяет
отдельные протоколы старого form CGI, VNish, Braiins OS или LuxOS.
Новая схема bitmain-work-mode и необходимость передавать текущие пулы
описаны в официальной документации Bitmain.
import asyncio
from pyasic import get_miner
async def control():
miner = await get_miner("192.168.1.20")
# включить сигнальный диод
await miner.fault_light_on()
# прочитать и записать конфиг
cfg = await miner.get_config()
await miner.send_config(cfg)
if __name__ == "__main__":
asyncio.run(control())
MinerConfig — это унифицированное представление конфигурации майнера (возврат get_config()).
send_config() сам конвертирует его в нужный для конкретного майнера формат.
Настройки
Глобальные настройки (pyasic.settings) упрощают работу с большими парками — например, общий пароль по умолчанию:
from pyasic import settings
settings.update("default_antminer_web_password", "my_pwd")
Значения по умолчанию:
"network_ping_retries": 1,
"network_ping_timeout": 3,
"network_scan_semaphore": None,
"factory_get_retries": 1,
"factory_get_timeout": 3,
"get_data_retries": 1,
"api_function_timeout": 5,
"antminer_mining_mode_as_str": False,
"default_whatsminer_rpc_password": "admin",
"default_innosilicon_web_password": "admin",
"default_antminer_web_password": "root",
"default_bosminer_web_password": "root",
"default_vnish_web_password": "admin",
"default_goldshell_web_password": "123456789",
"default_auradine_web_password": "admin",
"default_epic_web_password": "letmein",
"default_hive_web_password": "admin",
"default_antminer_ssh_password": "miner",
"default_bosminer_ssh_password": "root",
# РАСШИРЕННЫЕ — меняйте только если понимаете, что делаете
"socket_linger_time": 1000,
Тесты
Тесты на стандартном unittest (не pytest):
python -m unittest discover -p '*test.py' # весь набор
ruff check --fix && ruff format # линт и форматирование
mypy # проверка типов
Сборка и публикация на PyPI
Сборка и публикация идут через Poetry. Бэкенд сборки — poetry-core.
1. Поднять версию
PyPI не даёт перезалить уже существующую версию, поэтому перед каждым релизом меняйте version
в [project] файла pyproject.toml (например 0.3.0.dev2 → 0.3.0.dev3 или 0.3.0).
Версии вида
0.3.0.devN— это пре-релизы:pip install pyasic-umhostих по умолчанию не ставит, нуженpip install --pre pyasic-umhost. Для обычного релиза используйте чистую версию без.devN.
2. Настроить токен (один раз)
Получите API-токен на https://pypi.org/manage/account/token/ и сохраните его:
poetry config pypi-token.pypi pypi-AgEIcHl...ваш_токен
3. Собрать и опубликовать
rm -rf dist/ # на всякий случай чистим старые сборки
poetry build # создаст dist/*.whl и dist/*.tar.gz
poetry publish # зальёт на PyPI
Или одной командой:
poetry publish --build
Проверка на TestPyPI (необязательно)
Чтобы прогнать релиз без риска для боевого PyPI:
poetry config repositories.testpypi https://test.pypi.org/legacy/
poetry config pypi-token.testpypi pypi-<test-токен>
poetry publish --build -r testpypi
pip install --pre -i https://test.pypi.org/simple/ pyasic-umhost
Если
poetryпадает сLibrary not loaded: .../Python.framework/...— это значит, что Homebrew обновил Python и venv самого Poetry сломался. Переустановите Poetry:rm -rf "$HOME/Library/Application Support/pypoetry" curl -sSL https://install.python-poetry.org | python3 -
Metadata
Release files for pyasic-umhost 0.3.0.dev7
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| pyasic_umhost-0.3.0.dev7.tar.gz | 221.5 kB | Without provenance | Details for pyasic_umhost-0.3.0.dev7.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pyasic_umhost-0.3.0.dev7-py3-none-any.whl | Python 3 | none | any | Details for pyasic_umhost-0.3.0.dev7-py3-none-any.whl |
Total release size: 764.0 kB
Release files / pyasic_umhost-0.3.0.dev7.tar.gz
| Download URL | pyasic_umhost-0.3.0.dev7.tar.gz |
|---|---|
| Size | 221.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ebd1400c54e288f5f374853dcb50deaf94a2a84525446b9d59eab1d36d8962a5
|
|
BLAKE2b-256 checksum How to use checksums |
b52bc4144b599c89e89493ce13406886eba3feda12c92a119860b2c3915236d8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.4.1 CPython/3.13.14 Darwin/25.6.0
|
Release files / pyasic_umhost-0.3.0.dev7-py3-none-any.whl
| Download URL | pyasic_umhost-0.3.0.dev7-py3-none-any.whl |
|---|---|
| Size | 542.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
59d44503507af0e20966440709559e0dcb42c4e730de94e10d2577b1113552a8
|
|
BLAKE2b-256 checksum How to use checksums |
fe1c53d31f72b8f455ec62462eaa39fba47fb71d730f257a06eafc1e8cbbfb9b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.4.1 CPython/3.13.14 Darwin/25.6.0
|
Security for pyasic-umhost 0.3.0.dev7
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.