feat: add voltage,tuned status to HB. Add pool_data to ePIC

This commit is contained in:
John-Paul Compagnone
2024-06-11 11:10:07 -04:00
parent 3e4b347506
commit 4d9fde572e
5 changed files with 60 additions and 20 deletions

View File

@@ -485,7 +485,7 @@ class MiningModeConfig(MinerConfigOption):
return cls.hashrate_tuning(
hashrate=algo_info["BoardTune"].get("Target"),
algo=TunerAlgo.voltage_optimizer(),
algo=TunerAlgo.board_tune(),
scaling=scaling_cfg,
)
else:

View File

@@ -33,6 +33,8 @@ class HashBoard:
expected_chips: The expected chip count of the board as an int.
serial_number: The serial number of the board.
missing: Whether the board is returned from the miners data as a bool.
tuned: Whether the board is tuned as a bool.
voltage: Current input voltage of the board as a float.
"""
slot: int = 0
@@ -43,6 +45,8 @@ class HashBoard:
expected_chips: int = None
serial_number: str = None
missing: bool = True
tuned: bool = True
voltage: float = None
def get(self, __key: str, default: Any = None):
try:

View File

@@ -15,6 +15,7 @@ class PoolMetrics:
url: URL of the pool.
index: Index of the pool.
user: Username for the pool.
latency: latency of pool connection in milliseconds.
pool_rejected_percent: Percentage of rejected shares by the pool.
pool_stale_percent: Percentage of stale shares by the pool.
"""
@@ -28,6 +29,7 @@ class PoolMetrics:
url: str = None
index: int = None
user: str = None
latency: float = None
pool_rejected_percent: float = field(init=False)
pool_stale_percent: float = field(init=False)

View File

@@ -21,6 +21,7 @@ from pyasic.data import AlgoHashRate, Fan, HashBoard, HashUnit
from pyasic.data.error_codes import MinerErrorData, X19Error
from pyasic.errors import APIError
from pyasic.logger import logger
from pyasic.data.pools import PoolMetrics
from pyasic.miners.data import DataFunction, DataLocations, DataOptions, WebAPICommand
from pyasic.miners.device.firmware import ePICFirmware
from pyasic.web.epic import ePICWebAPI
@@ -58,10 +59,6 @@ EPIC_DATA_LOC = DataLocations(
"_get_wattage",
[WebAPICommand("web_summary", "summary")],
),
str(DataOptions.VOLTAGE): DataFunction(
"_get_voltage",
[WebAPICommand("web_summary", "summary")],
),
str(DataOptions.FANS): DataFunction(
"_get_fans",
[WebAPICommand("web_summary", "summary")],
@@ -82,6 +79,10 @@ EPIC_DATA_LOC = DataLocations(
"_is_mining",
[WebAPICommand("web_summary", "summary")],
),
str(DataOptions.POOLS): DataFunction(
"_get_pools",
[WebAPICommand("web_summary", "summary")],
),
}
)
@@ -219,20 +220,6 @@ class ePIC(ePICFirmware):
except KeyError:
pass
async def _get_voltage(self, web_summary: dict = None) -> Optional[float]:
if web_summary is None:
try:
web_summary = await self.web.summary()
except APIError:
pass
if web_summary is not None:
try:
voltage = web_summary["Power Supply Stats"]["Output Voltage"]
return voltage
except KeyError:
pass
async def _get_hashrate(self, web_summary: dict = None) -> Optional[float]:
if web_summary is None:
try:
@@ -323,6 +310,20 @@ class ePIC(ePICFirmware):
except APIError:
pass
tuned = True
if web_summary is not None:
tuner_running = web_summary["PerpetualTune"]["Running"]
if tuner_running:
algo_info = web_summary["PerpetualTune"]["Algorithm"]
if algo_info.get("VoltageOptimizer") is not None:
tuned = algo_info["VoltageOptimizer"].get("Optimized")
elif algo_info.get("BoardTune") is not None:
tuned = algo_info["BoardTune"].get("Optimized")
else:
tuned = algo_info["ChipTune"].get("Optimized")
# To be extra detailed, also ensure the miner is in "Mining" state
tuned = tuned and web_summary["Status"]["Operating State"] == "Mining"
hb_list = [
HashBoard(slot=i, expected_chips=self.expected_chips)
for i in range(self.expected_hashboards)
@@ -349,6 +350,8 @@ class ePIC(ePICFirmware):
).into(self.algo.unit.default)
hb_list[hb["Index"]].chips = num_of_chips
hb_list[hb["Index"]].temp = hb["Temperature"]
hb_list[hb["Index"]].tuned = tuned
hb_list[hb["Index"]].voltage = hb["Input Voltage"]
return hb_list
async def _is_mining(self, web_summary, *args, **kwargs) -> Optional[bool]:
@@ -411,3 +414,35 @@ class ePIC(ePICFirmware):
except KeyError:
pass
return errors
async def _get_pools(self, web_summary: dict = None) -> List[PoolMetrics]:
if web_summary is None:
try:
web_summary = await self.web.summary()
except APIError:
pass
pool_data = []
try:
if web_summary is not None:
if (
web_summary.get("Session") is not None
and web_summary.get("Stratum") is not None
):
pool_data.append(
PoolMetrics(
accepted=web_summary["Session"].get("Accepted"),
rejected=web_summary["Session"].get("Rejected"),
latency=web_summary["Stratum"].get("Average Latency"),
get_failures=0,
remote_failures=0,
active=web_summary["Stratum"].get("IsPoolConnected"),
alive=web_summary["Stratum"].get("IsPoolConnected"),
url=web_summary["Stratum"].get("Current Pool"),
user=web_summary["Stratum"].get("Current User"),
index=web_summary["Stratum"].get("Config Id"),
)
)
return pool_data
except LookupError:
pass

View File

@@ -37,7 +37,6 @@ class DataOptions(Enum):
IS_MINING = "is_mining"
UPTIME = "uptime"
CONFIG = "config"
VOLTAGE = "voltage"
POOLS = "pools"
def __str__(self):