Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d67de98bd0 | ||
|
|
fd1a3e459b | ||
|
|
adcab694b5 | ||
|
|
2bb097272f | ||
|
|
896968dded | ||
|
|
56b8f7c5b3 | ||
|
|
0ed7559aef | ||
|
|
275d87e4fe | ||
|
|
c3ab814d77 | ||
|
|
05a8569205 | ||
|
|
b098cb8136 | ||
|
|
75fe7857e4 | ||
|
|
66797aced1 | ||
|
|
4a71e38078 | ||
|
|
9fb07e4fa3 | ||
|
|
74792771ec | ||
|
|
fa6e8a976d | ||
|
|
f20531cff5 |
@@ -1,3 +1,6 @@
|
||||
ci:
|
||||
skip:
|
||||
- unittest
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.5.0
|
||||
@@ -24,4 +27,3 @@ repos:
|
||||
'types': [python]
|
||||
args: ["-p '*test.py'"] # Probably this option is absolutely not needed.
|
||||
pass_filenames: false
|
||||
stages: [commit]
|
||||
|
||||
24
poetry.lock
generated
24
poetry.lock
generated
@@ -1,4 +1,4 @@
|
||||
# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand.
|
||||
# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "aiofiles"
|
||||
@@ -62,21 +62,25 @@ name = "betterproto"
|
||||
version = "2.0.0b7"
|
||||
description = "A better Protobuf / gRPC generator & library"
|
||||
optional = false
|
||||
python-versions = "<4.0,>=3.7"
|
||||
files = [
|
||||
{file = "betterproto-2.0.0b7-py3-none-any.whl", hash = "sha256:401ab8055e2f814e77b9c88a74d0e1ae3d1e8a969cced6aeb1b59f71ad63fbd2"},
|
||||
{file = "betterproto-2.0.0b7.tar.gz", hash = "sha256:1b1458ca5278d519bcd62556a4c236f998a91d503f0f71c67b0b954747052af2"},
|
||||
]
|
||||
python-versions = "^3.7"
|
||||
files = []
|
||||
develop = false
|
||||
|
||||
[package.dependencies]
|
||||
grpclib = ">=0.4.1,<0.5.0"
|
||||
python-dateutil = ">=2.8,<3.0"
|
||||
typing-extensions = ">=4.7.1,<5.0.0"
|
||||
grpclib = "^0.4.1"
|
||||
python-dateutil = "^2.8"
|
||||
typing-extensions = "^4.7.1"
|
||||
|
||||
[package.extras]
|
||||
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.source]
|
||||
type = "git"
|
||||
url = "https://github.com/danielgtaylor/python-betterproto"
|
||||
reference = "v.2.0.0b7"
|
||||
resolved_reference = "1538e156a1eadb88799eca009a238093d6bb40df"
|
||||
|
||||
[[package]]
|
||||
name = "certifi"
|
||||
version = "2024.8.30"
|
||||
@@ -1183,4 +1187,4 @@ type = ["pytest-mypy"]
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.9"
|
||||
content-hash = "d611b5e8b0c5611d6ee916cedfb7f07f20dfc90a675ebaed04188e8b3c96aabe"
|
||||
content-hash = "503e85a8a0f1720b55634c5706cc6c2f4fbe8d14eb9b585ffce7e1e81811a70d"
|
||||
|
||||
@@ -250,3 +250,9 @@ 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),
|
||||
)
|
||||
|
||||
@@ -222,6 +222,14 @@ class Pool(MinerConfigValue):
|
||||
password=web_system_info.get("stratumPassword", ""),
|
||||
)
|
||||
|
||||
@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 +410,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):
|
||||
@@ -568,3 +585,7 @@ 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)])
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -89,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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -15,7 +15,4 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from .S21 import ePICS21, ePICS21Pro
|
||||
|
||||
from .T21 import (
|
||||
ePICT21,
|
||||
)
|
||||
from .T21 import ePICT21
|
||||
|
||||
@@ -597,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,11 +18,11 @@ 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
|
||||
from pyasic.rpc.bfgminer import BFGMinerRPCAPI
|
||||
from pyasic.data.pools import PoolMetrics, PoolUrl
|
||||
|
||||
BFGMINER_DATA_LOC = DataLocations(
|
||||
**{
|
||||
@@ -263,4 +263,4 @@ class BFGMiner(StockFirmware):
|
||||
expected_rate, HashUnit.SHA256.from_str(rate_unit)
|
||||
).into(self.algo.unit.default)
|
||||
except LookupError:
|
||||
pass
|
||||
pass
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,7 +181,7 @@ class IceRiver(StockFirmware):
|
||||
|
||||
if web_userpanel is not None:
|
||||
try:
|
||||
for board in web_userpanel["boards"]:
|
||||
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"])
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,10 +319,13 @@ 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:
|
||||
if (
|
||||
pool_info.get("status") == "Alive"
|
||||
and pool_info.get("priority", float("inf")) < highest_priority
|
||||
):
|
||||
highest_priority = pool_info.get["priority"]
|
||||
active_pool_index = pool_info["index"]
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -757,4 +757,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)
|
||||
|
||||
@@ -4,17 +4,12 @@
|
||||
# This file has been @generated
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import (
|
||||
TYPE_CHECKING,
|
||||
Dict,
|
||||
Optional,
|
||||
)
|
||||
from typing import TYPE_CHECKING, Dict, Optional
|
||||
|
||||
import betterproto
|
||||
import grpclib
|
||||
from betterproto.grpc.grpclib_server import ServiceBase
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import grpclib.server
|
||||
from betterproto.grpc.grpclib_client import MetadataLike
|
||||
|
||||
@@ -5,19 +5,12 @@
|
||||
import warnings
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime
|
||||
from typing import (
|
||||
TYPE_CHECKING,
|
||||
AsyncIterator,
|
||||
Dict,
|
||||
List,
|
||||
Optional,
|
||||
)
|
||||
from typing import TYPE_CHECKING, AsyncIterator, Dict, List, Optional
|
||||
|
||||
import betterproto
|
||||
import grpclib
|
||||
from betterproto.grpc.grpclib_server import ServiceBase
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import grpclib.server
|
||||
from betterproto.grpc.grpclib_client import MetadataLike
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "pyasic"
|
||||
version = "0.61.8"
|
||||
version = "0.61.15"
|
||||
description = "A simplified and standardized interface for Bitcoin ASICs."
|
||||
authors = ["UpstreamData <brett@upstreamdata.ca>"]
|
||||
repository = "https://github.com/UpstreamData/pyasic"
|
||||
@@ -15,8 +15,8 @@ passlib = ">=1.7.4"
|
||||
pyaml = ">=23.12.0"
|
||||
tomli = { version = ">=2.0.1", python = "<3.11" }
|
||||
tomli-w = "^1.0.0"
|
||||
betterproto = "2.0.0b7"
|
||||
aiofiles = ">=23.2.1"
|
||||
betterproto = "2.0.0b7"
|
||||
|
||||
[tool.poetry.group.dev]
|
||||
optional = true
|
||||
|
||||
Reference in New Issue
Block a user