Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5ac5770331 | ||
|
|
f131ebbdf5 | ||
|
|
5441e50f73 | ||
|
|
dc6a952de4 | ||
|
|
b781d215fb | ||
|
|
086b31ba23 | ||
|
|
46b7352769 | ||
|
|
e218c5039d | ||
|
|
3bb392980e | ||
|
|
92264619d2 | ||
|
|
3e21829fae | ||
|
|
d3619b0e48 | ||
|
|
0fbb05d62d | ||
|
|
01fc2591ad | ||
|
|
c08d7fa5cd | ||
|
|
91c0e1c125 |
@@ -20,12 +20,19 @@ import random
|
|||||||
import string
|
import string
|
||||||
import time
|
import time
|
||||||
from dataclasses import asdict, dataclass, fields
|
from dataclasses import asdict, dataclass, fields
|
||||||
|
from enum import IntEnum
|
||||||
from typing import Dict, List, Literal
|
from typing import Dict, List, Literal
|
||||||
|
|
||||||
import toml
|
import toml
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
|
|
||||||
|
class X19PowerMode(IntEnum):
|
||||||
|
Normal = 0
|
||||||
|
Sleep = 1
|
||||||
|
LPM = 3
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class _Pool:
|
class _Pool:
|
||||||
"""A dataclass for pool information.
|
"""A dataclass for pool information.
|
||||||
@@ -267,6 +274,7 @@ class MinerConfig:
|
|||||||
|
|
||||||
asicboost: bool = None
|
asicboost: bool = None
|
||||||
|
|
||||||
|
miner_mode: IntEnum = X19PowerMode.Normal
|
||||||
autotuning_enabled: bool = True
|
autotuning_enabled: bool = True
|
||||||
autotuning_mode: Literal["power", "hashrate"] = None
|
autotuning_mode: Literal["power", "hashrate"] = None
|
||||||
autotuning_wattage: int = None
|
autotuning_wattage: int = None
|
||||||
@@ -287,6 +295,8 @@ class MinerConfig:
|
|||||||
logging.debug(f"MinerConfig - (To Dict) - Dumping Dict config")
|
logging.debug(f"MinerConfig - (To Dict) - Dumping Dict config")
|
||||||
data_dict = asdict(self)
|
data_dict = asdict(self)
|
||||||
for key in asdict(self).keys():
|
for key in asdict(self).keys():
|
||||||
|
if isinstance(data_dict[key], IntEnum):
|
||||||
|
data_dict[key] = data_dict[key].value
|
||||||
if data_dict[key] is None:
|
if data_dict[key] is None:
|
||||||
del data_dict[key]
|
del data_dict[key]
|
||||||
return data_dict
|
return data_dict
|
||||||
@@ -324,8 +334,7 @@ class MinerConfig:
|
|||||||
self.fan_speed = int(data["bitmain-fan-pwm"])
|
self.fan_speed = int(data["bitmain-fan-pwm"])
|
||||||
elif key == "bitmain-work-mode":
|
elif key == "bitmain-work-mode":
|
||||||
if data[key]:
|
if data[key]:
|
||||||
if data[key] == 1:
|
self.miner_mode = X19PowerMode(int(data[key]))
|
||||||
self.autotuning_wattage = 0
|
|
||||||
elif key == "fan_control":
|
elif key == "fan_control":
|
||||||
for _key in data[key].keys():
|
for _key in data[key].keys():
|
||||||
if _key == "min_fans":
|
if _key == "min_fans":
|
||||||
@@ -457,10 +466,8 @@ class MinerConfig:
|
|||||||
"pools": self.pool_groups[0].as_x19(user_suffix=user_suffix),
|
"pools": self.pool_groups[0].as_x19(user_suffix=user_suffix),
|
||||||
"bitmain-fan-ctrl": False,
|
"bitmain-fan-ctrl": False,
|
||||||
"bitmain-fan-pwn": 100,
|
"bitmain-fan-pwn": 100,
|
||||||
"miner-mode": 0, # Normal Mode
|
"miner-mode": self.miner_mode.value,
|
||||||
}
|
}
|
||||||
if self.autotuning_wattage == 0:
|
|
||||||
cfg["miner-mode"] = 1 # Sleep Mode
|
|
||||||
|
|
||||||
if not self.temp_mode == "auto":
|
if not self.temp_mode == "auto":
|
||||||
cfg["bitmain-fan-ctrl"] = True
|
cfg["bitmain-fan-ctrl"] = True
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ class APIError(Exception):
|
|||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
if self.message:
|
if self.message:
|
||||||
|
if self.message == "can't access write cmd":
|
||||||
|
return f"{self.message}, please make sure your miner has been unlocked."
|
||||||
return f"{self.message}"
|
return f"{self.message}"
|
||||||
else:
|
else:
|
||||||
return "Incorrect API parameters."
|
return "Incorrect API parameters."
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ from typing import List, Optional, Union
|
|||||||
import httpx
|
import httpx
|
||||||
|
|
||||||
from pyasic.API import APIError
|
from pyasic.API import APIError
|
||||||
from pyasic.config import MinerConfig
|
from pyasic.config import MinerConfig, X19PowerMode
|
||||||
from pyasic.data.error_codes import MinerErrorData, X19Error
|
from pyasic.data.error_codes import MinerErrorData, X19Error
|
||||||
from pyasic.miners._backends import BMMiner # noqa - Ignore access to _module
|
from pyasic.miners._backends import BMMiner # noqa - Ignore access to _module
|
||||||
from pyasic.settings import PyasicSettings
|
from pyasic.settings import PyasicSettings
|
||||||
@@ -101,13 +101,13 @@ class X19(BMMiner):
|
|||||||
|
|
||||||
async def stop_mining(self) -> bool:
|
async def stop_mining(self) -> bool:
|
||||||
cfg = await self.get_config()
|
cfg = await self.get_config()
|
||||||
cfg.autotuning_wattage = 0
|
cfg.miner_mode = X19PowerMode.Sleep
|
||||||
await self.send_config(cfg)
|
await self.send_config(cfg)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
async def resume_mining(self) -> bool:
|
async def resume_mining(self) -> bool:
|
||||||
cfg = await self.get_config()
|
cfg = await self.get_config()
|
||||||
cfg.autotuning_wattage = 1
|
cfg.miner_mode = X19PowerMode.Normal
|
||||||
await self.send_config(cfg)
|
await self.send_config(cfg)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
import ipaddress
|
import ipaddress
|
||||||
import logging
|
import logging
|
||||||
|
import warnings
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from typing import List, Optional, Tuple, Union
|
from typing import List, Optional, Tuple, Union
|
||||||
|
|
||||||
@@ -151,10 +152,17 @@ class BTMiner(BaseMiner):
|
|||||||
summary = data["summary"][0]
|
summary = data["summary"][0]
|
||||||
except APIError as e:
|
except APIError as e:
|
||||||
logging.warning(e)
|
logging.warning(e)
|
||||||
|
except LookupError:
|
||||||
|
pass
|
||||||
|
|
||||||
if pools:
|
if pools:
|
||||||
if "POOLS" in pools:
|
if "POOLS" in pools:
|
||||||
cfg = cfg.from_api(pools["POOLS"])
|
cfg = cfg.from_api(pools["POOLS"])
|
||||||
|
else:
|
||||||
|
# somethings wrong with the miner
|
||||||
|
warnings.warn(
|
||||||
|
f"Failed to gather pool config for miner: {self}, miner did not return pool information."
|
||||||
|
)
|
||||||
if summary:
|
if summary:
|
||||||
if "SUMMARY" in summary:
|
if "SUMMARY" in summary:
|
||||||
if wattage := summary["SUMMARY"][0].get("Power Limit"):
|
if wattage := summary["SUMMARY"][0].get("Power Limit"):
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "pyasic"
|
name = "pyasic"
|
||||||
version = "0.30.1"
|
version = "0.30.9"
|
||||||
description = "A set of modules for interfacing with many common types of ASIC bitcoin miners, using both their API and SSH."
|
description = "A set of modules for interfacing with many common types of ASIC bitcoin miners, using both their API and SSH."
|
||||||
authors = ["UpstreamData <brett@upstreamdata.ca>"]
|
authors = ["UpstreamData <brett@upstreamdata.ca>"]
|
||||||
repository = "https://github.com/UpstreamData/pyasic"
|
repository = "https://github.com/UpstreamData/pyasic"
|
||||||
|
|||||||
Reference in New Issue
Block a user