feature: add nominal_hashrate to miner data

This commit is contained in:
UpstreamData
2023-01-27 09:41:25 -07:00
parent c4b4fa293d
commit 85d7f0abfb
12 changed files with 138 additions and 0 deletions

View File

@@ -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)

View File

@@ -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(),

View File

@@ -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,

View File

@@ -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 {}

View File

@@ -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),

View File

@@ -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(),

View File

@@ -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(),

View File

@@ -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

View File

@@ -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),

View File

@@ -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].

View File

@@ -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
),

View File

@@ -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 {}