feature: add nominal_hashrate to miner data
This commit is contained in:
@@ -47,6 +47,7 @@ class MinerData:
|
||||
fw_ver: The current firmware version on the miner as a str.
|
||||
hostname: The network hostname of the miner as a str.
|
||||
hashrate: The hashrate of the miner in TH/s as a float.
|
||||
nominal_hashrate: The factory nominal hashrate of the miner in TH/s as a float.
|
||||
left_board_hashrate: The hashrate of the left board of the miner in TH/s as a float.
|
||||
center_board_hashrate: The hashrate of the center board of the miner in TH/s as a float.
|
||||
right_board_hashrate: The hashrate of the right board of the miner in TH/s as a float.
|
||||
@@ -91,6 +92,7 @@ class MinerData:
|
||||
fw_ver: str = "Unknown"
|
||||
hostname: str = "Unknown"
|
||||
hashrate: float = 0
|
||||
nominal_hashrate: float = 0
|
||||
hashboards: List[HashBoard] = field(default_factory=list)
|
||||
ideal_hashboards: int = 1
|
||||
left_board_hashrate: float = field(init=False)
|
||||
|
||||
@@ -316,6 +316,30 @@ class BMMiner(BaseMiner):
|
||||
async def get_fault_light(self) -> bool:
|
||||
return False
|
||||
|
||||
async def get_nominal_hashrate(self, api_stats: dict = None) -> Optional[float]:
|
||||
# X19 method, not sure compatibility
|
||||
if not api_stats:
|
||||
try:
|
||||
api_stats = await self.api.stats()
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
if api_stats:
|
||||
try:
|
||||
ideal_rate = api_stats["STATS"][1]["total_rateideal"]
|
||||
try:
|
||||
rate_unit = api_stats["STATS"][1]["rate_unit"]
|
||||
except KeyError:
|
||||
rate_unit = "GH"
|
||||
if rate_unit == "GH":
|
||||
return round(ideal_rate/1000, 2)
|
||||
if rate_unit == "MH":
|
||||
return round(ideal_rate/1000000, 2)
|
||||
else:
|
||||
return round(ideal_rate, 2)
|
||||
except (KeyError, IndexError):
|
||||
pass
|
||||
|
||||
async def _get_data(self, allow_warning: bool) -> dict:
|
||||
miner_data = None
|
||||
for i in range(PyasicSettings().miner_get_data_retries):
|
||||
@@ -370,6 +394,7 @@ class BMMiner(BaseMiner):
|
||||
"fw_ver": None, # Done at end.
|
||||
"hostname": await self.get_hostname(),
|
||||
"hashrate": await self.get_hashrate(api_summary=summary),
|
||||
"nominal_hashrate": await self.get_nominal_hashrate(api_stats=stats),
|
||||
"hashboards": await self.get_hashboards(api_stats=stats),
|
||||
# ideal_hashboards - Done at start
|
||||
"env_temp": await self.get_env_temp(),
|
||||
|
||||
@@ -825,6 +825,31 @@ class BOSMiner(BaseMiner):
|
||||
logging.debug(f"SSH command failed - Fault Light - {e}")
|
||||
return self.light
|
||||
|
||||
async def get_nominal_hashrate(self, api_devs: dict = None) -> Optional[float]:
|
||||
if not api_devs:
|
||||
try:
|
||||
api_devs = await self.api.devs()
|
||||
except APIError:
|
||||
pass
|
||||
nom_hr = 0
|
||||
|
||||
if api_devs:
|
||||
try:
|
||||
offset = 6 if api_devs["DEVS"][0]["ID"] in [6, 7, 8] else 0
|
||||
hr_list = []
|
||||
|
||||
for board in api_devs["DEVS"]:
|
||||
_id = board["ID"] - offset
|
||||
nominal_hashrate = round(float(board["Nominal MHS"] / 1000000), 2)
|
||||
if nominal_hashrate:
|
||||
hr_list.append(nominal_hashrate)
|
||||
if len(hr_list) == 0:
|
||||
return 0
|
||||
else:
|
||||
return round((sum(hr_list)/len(hr_list))*self.ideal_hashboards, 2)
|
||||
except (IndexError, KeyError):
|
||||
pass
|
||||
|
||||
async def _get_data(self, allow_warning: bool) -> dict:
|
||||
miner_data = None
|
||||
for i in range(PyasicSettings().miner_get_data_retries):
|
||||
@@ -902,6 +927,7 @@ class BOSMiner(BaseMiner):
|
||||
"hashrate": await self.get_hashrate(
|
||||
api_summary=summary, graphql_hashrate=gql_data
|
||||
),
|
||||
"nominal_hashrate": await self.get_nominal_hashrate(api_devs=devs),
|
||||
"hashboards": await self.get_hashboards(
|
||||
api_temps=temps,
|
||||
api_devdetails=devdetails,
|
||||
|
||||
@@ -177,6 +177,9 @@ class BOSMinerOld(BaseMiner):
|
||||
async def get_fault_light(self) -> bool:
|
||||
return False
|
||||
|
||||
async def get_nominal_hashrate(self) -> Optional[float]:
|
||||
return None
|
||||
|
||||
async def _get_data(self, allow_warning: bool) -> dict:
|
||||
return {}
|
||||
|
||||
|
||||
@@ -487,6 +487,22 @@ class BTMiner(BaseMiner):
|
||||
|
||||
return errors
|
||||
|
||||
async def get_nominal_hashrate(self, api_summary: dict = None):
|
||||
if not api_summary:
|
||||
try:
|
||||
api_summary = await self.api.summary()
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
if api_summary:
|
||||
try:
|
||||
nominal_hashrate = api_summary["SUMMARY"][0]["Factory GHS"]
|
||||
if nominal_hashrate:
|
||||
return round(nominal_hashrate/1000, 2)
|
||||
except (KeyError, IndexError):
|
||||
pass
|
||||
|
||||
|
||||
async def get_fault_light(self, api_miner_info: dict = None) -> bool:
|
||||
data = None
|
||||
|
||||
@@ -564,6 +580,7 @@ class BTMiner(BaseMiner):
|
||||
"fw_ver": None, # - Done at end
|
||||
"hostname": await self.get_hostname(api_miner_info=miner_info),
|
||||
"hashrate": await self.get_hashrate(api_summary=summary),
|
||||
"nominal_hashrate": await self.get_nominal_hashrate(api_summary=summary),
|
||||
"hashboards": await self.get_hashboards(api_devs=devs),
|
||||
# ideal_hashboards - Done at start
|
||||
"env_temp": await self.get_env_temp(api_summary=summary),
|
||||
|
||||
@@ -364,6 +364,30 @@ class CGMiner(BaseMiner):
|
||||
async def get_fault_light(self) -> bool:
|
||||
return False
|
||||
|
||||
async def get_nominal_hashrate(self, api_stats: dict = None) -> Optional[float]:
|
||||
# X19 method, not sure compatibility
|
||||
if not api_stats:
|
||||
try:
|
||||
api_stats = await self.api.stats()
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
if api_stats:
|
||||
try:
|
||||
ideal_rate = api_stats["STATS"][1]["total_rateideal"]
|
||||
try:
|
||||
rate_unit = api_stats["STATS"][1]["rate_unit"]
|
||||
except KeyError:
|
||||
rate_unit = "GH"
|
||||
if rate_unit == "GH":
|
||||
return round(ideal_rate/1000, 2)
|
||||
if rate_unit == "MH":
|
||||
return round(ideal_rate/1000000, 2)
|
||||
else:
|
||||
return round(ideal_rate, 2)
|
||||
except (KeyError, IndexError):
|
||||
pass
|
||||
|
||||
async def _get_data(self, allow_warning: bool) -> dict:
|
||||
miner_data = None
|
||||
for i in range(PyasicSettings().miner_get_data_retries):
|
||||
@@ -417,6 +441,7 @@ class CGMiner(BaseMiner):
|
||||
"fw_ver": None, # - Done at end
|
||||
"hostname": await self.get_hostname(),
|
||||
"hashrate": await self.get_hashrate(api_summary=summary),
|
||||
"nominal_hashrate": await self.get_nominal_hashrate(api_stats=stats),
|
||||
"hashboards": await self.get_hashboards(api_stats=stats),
|
||||
# ideal_hashboards - Done at start
|
||||
"env_temp": await self.get_env_temp(),
|
||||
|
||||
@@ -325,6 +325,7 @@ class CGMinerAvalon(CGMiner):
|
||||
"fw_ver": None, # - Done at end
|
||||
"hostname": await self.get_hostname(),
|
||||
"hashrate": await self.get_hashrate(api_summary=summary),
|
||||
"nominal_hashrate": await self.get_nominal_hashrate(api_stats=stats),
|
||||
"hashboards": await self.get_hashboards(api_stats=stats),
|
||||
# ideal_hashboards - Done at start
|
||||
"env_temp": await self.get_env_temp(),
|
||||
|
||||
@@ -18,6 +18,7 @@ from typing import List, Union, Optional
|
||||
|
||||
import httpx
|
||||
|
||||
from pyasic.API import APIError
|
||||
from pyasic.config import MinerConfig
|
||||
from pyasic.data.error_codes import MinerErrorData, X19Error
|
||||
from pyasic.miners._backends import BMMiner # noqa - Ignore access to _module
|
||||
@@ -148,3 +149,26 @@ class BMMinerX19(BMMiner):
|
||||
except KeyError:
|
||||
pass
|
||||
return self.light
|
||||
|
||||
async def get_nominal_hashrate(self, api_stats: dict = None) -> Optional[float]:
|
||||
if not api_stats:
|
||||
try:
|
||||
api_stats = await self.api.stats()
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
if api_stats:
|
||||
try:
|
||||
ideal_rate = api_stats["STATS"][1]["total_rateideal"]
|
||||
try:
|
||||
rate_unit = api_stats["STATS"][1]["rate_unit"]
|
||||
except KeyError:
|
||||
rate_unit = "GH"
|
||||
if rate_unit == "GH":
|
||||
return round(ideal_rate/1000, 2)
|
||||
if rate_unit == "MH":
|
||||
return round(ideal_rate/1000000, 2)
|
||||
else:
|
||||
return round(ideal_rate, 2)
|
||||
except (KeyError, IndexError):
|
||||
pass
|
||||
|
||||
@@ -160,6 +160,7 @@ class HiveonT9(Hiveon, T9):
|
||||
"fw_ver": None, # - Done at end
|
||||
"hostname": await self.get_hostname(),
|
||||
"hashrate": await self.get_hashrate(api_summary=summary),
|
||||
"nominal_hashrate": await self.get_nominal_hashrate(api_stats=stats),
|
||||
"hashboards": await self.get_hashboards(api_stats=stats),
|
||||
# ideal_hashboards - Done at start
|
||||
"env_temp": await self.get_env_temp(api_stats=stats),
|
||||
|
||||
@@ -301,6 +301,16 @@ class BaseMiner(ABC):
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def get_nominal_hashrate(self, *args, **kwargs) -> Optional[float]:
|
||||
"""Get the nominal hashrate from factory if available.
|
||||
|
||||
Returns:
|
||||
A float value of nominal hashrate in TH/s.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
async def get_data(self, allow_warning: bool = False) -> MinerData:
|
||||
"""Get data from the miner in the form of [`MinerData`][pyasic.data.MinerData].
|
||||
|
||||
|
||||
@@ -414,6 +414,7 @@ class CGMinerInnosiliconT3HPlus(CGMiner, InnosiliconT3HPlus):
|
||||
"hashrate": await self.get_hashrate(
|
||||
api_summary=summary, web_all_data=web_all_data
|
||||
),
|
||||
"nominal_hashrate": await self.get_nominal_hashrate(api_stats=stats),
|
||||
"hashboards": await self.get_hashboards(
|
||||
api_stats=stats, web_all_data=web_all_data
|
||||
),
|
||||
|
||||
@@ -143,6 +143,9 @@ class UnknownMiner(BaseMiner):
|
||||
async def get_fault_light(self) -> bool:
|
||||
return False
|
||||
|
||||
async def get_nominal_hashrate(self) -> Optional[float]:
|
||||
return None
|
||||
|
||||
async def _get_data(self, allow_warning: bool) -> dict:
|
||||
return {}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user