Skip to main content
Pre-release

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 -

Release files for pyasic-umhost 0.3.0.dev6

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pyasic-umhost 0.3.0.dev6
File Size Uploaded
pyasic_umhost-0.3.0.dev6.tar.gz 221.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pyasic-umhost 0.3.0.dev6
File Interpreter ABI Platform
pyasic_umhost-0.3.0.dev6-py3-none-any.whl Python 3 none any Details

Total release size: 763.9 kB

Release files / pyasic_umhost-0.3.0.dev6.tar.gz

Download URL pyasic_umhost-0.3.0.dev6.tar.gz
Size 221.4 kB
Tags Source
SHA-256 checksum
How to use checksums
cdbd63197b52f898e2041a37977282c66d989635e697488cd4af854477fd29bd
BLAKE2b-256 checksum
How to use checksums
fa0a6b9be770bd5939939f68653eec480652bc96db492dc6e3b15cceca87857e
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.dev6-py3-none-any.whl

Download URL pyasic_umhost-0.3.0.dev6-py3-none-any.whl
Size 542.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
215497264d8139f1b8e47269eb2ece6d074d5ccf86dd572892e859fae82c41e6
BLAKE2b-256 checksum
How to use checksums
a388155fb67955b66833351733b355cd57cf3e0c954f2783c5c2828ed5904f6b
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 history Release notifications | RSS feed

This release

0.3.0.dev6 This release

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.9

2 release files

0.1.8

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

0.0.9

2 release files

0.0.8

2 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page