feature: add custom hashrate types and conversion.

This commit is contained in:
Upstream Data
2024-05-09 15:01:40 -06:00
parent 8ad6f60757
commit 99ff28d3e1
24 changed files with 314 additions and 108 deletions

View File

@@ -28,6 +28,7 @@ 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
@dataclass
@@ -40,6 +41,10 @@ class MinerData:
uptime: The uptime of the miner in seconds.
mac: The MAC address of the miner as a str.
device_info: Info about the device, such as model, make, and firmware.
model: The model of the miner as a str.
make: The make of the miner as a str.
firmware: The firmware on the miner as a str.
algo: The mining algorithm of the miner as a str.
api_ver: The current api version on the miner as a str.
fw_ver: The current firmware version on the miner as a str.
hostname: The network hostname of the miner as a str.
@@ -78,14 +83,15 @@ class MinerData:
make: str = field(init=False)
model: str = field(init=False)
firmware: str = field(init=False)
algo: str = field(init=False)
mac: str = None
api_ver: str = None
fw_ver: str = None
hostname: str = None
# hashrate
hashrate: float = field(init=False)
_hashrate: float = field(repr=False, default=None)
hashrate: AlgoHashRate = field(init=False)
_hashrate: AlgoHashRate = field(repr=False, default=None)
# expected
expected_hashrate: float = None
@@ -212,7 +218,7 @@ class MinerData:
if item.hashrate is not None:
hr_data.append(item.hashrate)
if len(hr_data) > 0:
return round(sum(hr_data), 2)
return sum(hr_data, start=type(hr_data[0])(0))
return self._hashrate
@hashrate.setter
@@ -313,7 +319,7 @@ class MinerData:
return None
if self.hashrate == 0 or self.wattage == 0:
return 0
return round(self.wattage / self.hashrate)
return round(self.wattage / float(self.hashrate))
@efficiency.setter
def efficiency(self, val):
@@ -362,6 +368,15 @@ class MinerData:
def firmware(self, val):
pass
@property
def algo(self): # noqa - Skip PyCharm inspection
if self.device_info.algo is not None:
return str(self.device_info.algo)
@algo.setter
def algo(self, val):
pass
def asdict(self) -> dict:
return asdict(self, dict_factory=self.dict_factory)

View File

@@ -17,6 +17,8 @@
from dataclasses import dataclass
from typing import Any
from .hashrate import AlgoHashRate
@dataclass
class HashBoard:
@@ -34,7 +36,7 @@ class HashBoard:
"""
slot: int = 0
hashrate: float = None
hashrate: AlgoHashRate = None
temp: int = None
chip_temp: int = None
chips: int = None

View File

@@ -1,5 +1,6 @@
from dataclasses import dataclass
from pyasic.device.algorithm import MinerAlgo
from pyasic.device.firmware import MinerFirmware
from pyasic.device.makes import MinerMake
from pyasic.device.models import MinerModel
@@ -10,3 +11,4 @@ class DeviceInfo:
make: MinerMake = None
model: MinerModel = None
firmware: MinerFirmware = None
algo: MinerAlgo = None

View File

@@ -0,0 +1,15 @@
from enum import Enum
from pyasic.data.hashrate.sha256 import SHA256HashRate
from pyasic.device.algorithm.sha256 import SHA256Unit
class AlgoHashRate(Enum):
SHA256 = SHA256HashRate
def __call__(self, *args, **kwargs):
return self.value(*args, **kwargs)
class HashUnit:
SHA256 = SHA256Unit

View File

@@ -0,0 +1,54 @@
from __future__ import annotations
from dataclasses import dataclass
from pyasic.device.algorithm import MinerAlgo
from pyasic.device.algorithm.sha256 import SHA256Unit
@dataclass
class SHA256HashRate:
rate: float
unit: SHA256Unit = MinerAlgo.SHA256.unit.default
def __float__(self):
return float(self.rate)
def __int__(self):
return int(self.rate)
def __repr__(self):
return f"{self.rate} {str(self.unit)}"
def __round__(self, n: int = None):
return round(self.rate, n)
def __add__(self, other: SHA256HashRate | int | float) -> SHA256HashRate:
if isinstance(other, SHA256HashRate):
return SHA256HashRate(self.rate + other.into(self.unit).rate, self.unit)
return SHA256HashRate(self.rate + other, self.unit)
def __sub__(self, other: SHA256HashRate | int | float) -> SHA256HashRate:
if isinstance(other, SHA256HashRate):
return SHA256HashRate(self.rate - other.into(self.unit).rate, self.unit)
return SHA256HashRate(self.rate - other, self.unit)
def __truediv__(self, other: SHA256HashRate | int | float):
if isinstance(other, SHA256HashRate):
return SHA256HashRate(self.rate / other.into(self.unit).rate, self.unit)
return SHA256HashRate(self.rate / other, self.unit)
def __floordiv__(self, other: SHA256HashRate | int | float):
if isinstance(other, SHA256HashRate):
return SHA256HashRate(self.rate // other.into(self.unit).rate, self.unit)
return SHA256HashRate(self.rate // other, self.unit)
def __mul__(self, other: SHA256HashRate | int | float):
if isinstance(other, SHA256HashRate):
return SHA256HashRate(self.rate * other.into(self.unit).rate, self.unit)
return SHA256HashRate(self.rate * other, self.unit)
def into(self, other: SHA256Unit) -> SHA256HashRate:
return SHA256HashRate(
rate=self.rate / (other.value / self.unit.value), unit=other
)

View File

@@ -1,3 +1,4 @@
from .algorithm import MinerAlgo
from .firmware import MinerFirmware
from .makes import MinerMake
from .models import MinerModel

View File

@@ -0,0 +1,5 @@
from pyasic.device.algorithm.sha256 import SHA256Algo
class MinerAlgo:
SHA256 = SHA256Algo

View File

@@ -0,0 +1,69 @@
from __future__ import annotations
from dataclasses import dataclass
from enum import IntEnum
class SHA256Unit(IntEnum):
H = 1
KH = int(H) * 1000
MH = int(KH) * 1000
GH = int(MH) * 1000
TH = int(GH) * 1000
PH = int(TH) * 1000
EH = int(PH) * 1000
ZH = int(EH) * 1000
default = TH
def __str__(self):
if self.value == self.H:
return "H/s"
if self.value == self.KH:
return "KH/s"
if self.value == self.MH:
return "MH/s"
if self.value == self.GH:
return "GH/s"
if self.value == self.TH:
return "TH/s"
if self.value == self.PH:
return "PH/s"
if self.value == self.EH:
return "EH/s"
if self.value == self.ZH:
return "ZH/s"
@classmethod
def from_str(cls, value: str):
if value == "H":
return cls.H
elif value == "KH":
return cls.KH
elif value == "MH":
return cls.MH
elif value == "GH":
return cls.GH
elif value == "TH":
return cls.TH
elif value == "PH":
return cls.PH
elif value == "EH":
return cls.EH
elif value == "ZH":
return cls.ZH
return cls.default
def __repr__(self):
return str(self)
# make this json serializable
class _SHA256Algo(str):
unit = SHA256Unit
def __repr__(self):
return "SHA256Algo"
SHA256Algo = _SHA256Algo("SHA256")

View File

@@ -18,7 +18,7 @@ from typing import List, Optional
import asyncssh
from pyasic.data import HashBoard
from pyasic.data import AlgoHashRate, HashBoard, HashUnit
from pyasic.errors import APIError
from pyasic.miners.backends import Hiveon
from pyasic.miners.data import DataFunction, DataLocations, DataOptions, RPCAPICommand
@@ -121,7 +121,9 @@ class HiveonT9(Hiveon, T9):
chips += rpc_stats["STATS"][1][f"chain_acn{chipset}"]
except (KeyError, IndexError):
pass
hashboards[board].hashrate = round(hashrate / 1000, 2)
hashboards[board].hashrate = AlgoHashRate.SHA256(
hashrate, HashUnit.SHA256.GH
).into(self.algo.unit.default)
hashboards[board].chips = chips
return hashboards

View File

@@ -17,7 +17,7 @@
from typing import List, Optional, Union
from pyasic.config import MinerConfig, MiningModeConfig
from pyasic.data import Fan, HashBoard
from pyasic.data import AlgoHashRate, Fan, HashBoard, HashUnit
from pyasic.data.error_codes import MinerErrorData, X19Error
from pyasic.errors import APIError
from pyasic.miners.backends.bmminer import BMMiner
@@ -218,9 +218,9 @@ class AntminerModern(BMMiner):
if rpc_stats is not None:
try:
for board in rpc_stats["STATS"][0]["chain"]:
hashboards[board["index"]].hashrate = round(
board["rate_real"] / 1000, 2
)
hashboards[board["index"]].hashrate = AlgoHashRate.SHA256(
board["rate_real"], HashUnit.SHA256.GH
).into(self.algo.unit.default)
hashboards[board["index"]].chips = board["asic_num"]
board_temp_data = list(
filter(lambda x: not x == 0, board["temp_pcb"])
@@ -273,12 +273,9 @@ class AntminerModern(BMMiner):
rate_unit = rpc_stats["STATS"][1]["rate_unit"]
except KeyError:
rate_unit = "GH"
if rate_unit == "GH":
return round(expected_rate / 1000, 2)
if rate_unit == "MH":
return round(expected_rate / 1000000, 2)
else:
return round(expected_rate, 2)
return AlgoHashRate.SHA256(
expected_rate, HashUnit.SHA256.from_str(rate_unit)
).int(self.algo.unit.default)
except LookupError:
pass
@@ -552,7 +549,9 @@ class AntminerOld(CGMiner):
hashrate = boards[1].get(f"chain_rate{i}")
if hashrate:
hashboard.hashrate = round(float(hashrate) / 1000, 2)
hashboard.hashrate = AlgoHashRate.SHA256(
hashrate, HashUnit.SHA256.GH
).into(self.algo.unit.default)
chips = boards[1].get(f"chain_acn{i}")
if chips:

View File

@@ -18,7 +18,7 @@ from enum import Enum
from typing import List, Optional
from pyasic.config import MinerConfig
from pyasic.data import Fan, HashBoard
from pyasic.data import AlgoHashRate, Fan, HashBoard, HashUnit
from pyasic.errors import APIError
from pyasic.miners.data import (
DataFunction,
@@ -245,9 +245,9 @@ class Auradine(StockFirmware):
if rpc_summary is not None:
try:
return round(
float(float(rpc_summary["SUMMARY"][0]["MHS 5s"]) / 1000000), 2
)
return AlgoHashRate.SHA256(
rpc_summary["SUMMARY"][0]["MHS 5s"], HashUnit.SHA256.MH
).into(self.algo.unit.default)
except (LookupError, ValueError, TypeError):
pass
@@ -274,9 +274,9 @@ class Auradine(StockFirmware):
try:
for board in rpc_devs["DEVS"]:
b_id = board["ID"] - 1
hashboards[b_id].hashrate = round(
float(float(board["MHS 5s"]) / 1000000), 2
)
hashboards[b_id].hashrate = AlgoHashRate.SHA256(
board["MHS 5s"], HashUnit.SHA256.MH
).into(self.algo.unit.default)
hashboards[b_id].temp = round(float(float(board["Temperature"])), 2)
hashboards[b_id].missing = False
except LookupError:

View File

@@ -17,7 +17,7 @@
import re
from typing import List, Optional
from pyasic.data import Fan, HashBoard
from pyasic.data import AlgoHashRate, Fan, HashBoard, HashUnit
from pyasic.errors import APIError
from pyasic.miners.backends.cgminer import CGMiner
from pyasic.miners.data import DataFunction, DataLocations, DataOptions, RPCAPICommand
@@ -182,7 +182,9 @@ class AvalonMiner(CGMiner):
if rpc_devs is not None:
try:
return round(float(rpc_devs["DEVS"][0]["MHS 1m"] / 1000000), 2)
return AlgoHashRate.SHA256(
rpc_devs["DEVS"][0]["MHS 1m"], HashUnit.SHA256.MH
).into(self.algo.unit.default)
except (KeyError, IndexError, ValueError, TypeError):
pass
@@ -213,7 +215,9 @@ class AvalonMiner(CGMiner):
try:
board_hr = parsed_stats["MGHS"][board]
hashboards[board].hashrate = round(float(board_hr) / 1000, 2)
hashboards[board].hashrate = AlgoHashRate.SHA256(
board_hr, HashUnit.SHA256.GH
).into(self.algo.unit.default)
except LookupError:
pass
@@ -245,7 +249,9 @@ class AvalonMiner(CGMiner):
try:
unparsed_stats = rpc_stats["STATS"][0]["MM ID0"]
parsed_stats = self.parse_stats(unparsed_stats)
return round(float(parsed_stats["GHSmm"]) / 1000, 2)
return AlgoHashRate.SHA256(
parsed_stats["GHSmm"], HashUnit.SHA256.GH
).int(self.algo.unit.default)
except (IndexError, KeyError, ValueError, TypeError):
pass

View File

@@ -17,7 +17,7 @@
from typing import List, Optional
from pyasic.config import MinerConfig
from pyasic.data import Fan, HashBoard
from pyasic.data import AlgoHashRate, Fan, HashBoard, HashUnit
from pyasic.errors import APIError
from pyasic.miners.data import DataFunction, DataLocations, DataOptions, RPCAPICommand
from pyasic.miners.device.firmware import StockFirmware
@@ -115,7 +115,9 @@ class BFGMiner(StockFirmware):
if rpc_summary is not None:
try:
return round(float(rpc_summary["SUMMARY"][0]["MHS 20s"] / 1000000), 2)
return AlgoHashRate.SHA256(
rpc_summary["SUMMARY"][0]["MHS 20s"], HashUnit.SHA256.MH
).into(self.algo.unit.default)
except (LookupError, ValueError, TypeError):
pass
@@ -159,7 +161,9 @@ class BFGMiner(StockFirmware):
hashrate = boards[1].get(f"chain_rate{i}")
if hashrate:
hashboard.hashrate = round(float(hashrate) / 1000, 2)
hashboard.hashrate = AlgoHashRate.SHA256(
hashrate, HashUnit.SHA256.GH
).into(self.algo.unit.default)
chips = boards[1].get(f"chain_acn{i}")
if chips:
@@ -218,11 +222,8 @@ class BFGMiner(StockFirmware):
rate_unit = rpc_stats["STATS"][1]["rate_unit"]
except KeyError:
rate_unit = "GH"
if rate_unit == "GH":
return round(expected_rate / 1000, 2)
if rate_unit == "MH":
return round(expected_rate / 1000000, 2)
else:
return round(expected_rate, 2)
return AlgoHashRate.SHA256(
expected_rate, HashUnit.SHA256.from_str(rate_unit)
).int(self.algo.unit.default)
except LookupError:
pass

View File

@@ -17,7 +17,7 @@
from typing import List, Optional
from pyasic.config import MinerConfig
from pyasic.data import Fan, HashBoard
from pyasic.data import AlgoHashRate, Fan, HashBoard, HashUnit
from pyasic.errors import APIError
from pyasic.miners.data import DataFunction, DataLocations, DataOptions, RPCAPICommand
from pyasic.miners.device.firmware import StockFirmware
@@ -119,7 +119,9 @@ class BMMiner(StockFirmware):
if rpc_summary is not None:
try:
return round(float(rpc_summary["SUMMARY"][0]["GHS 5s"] / 1000), 2)
return AlgoHashRate.SHA256(
rpc_summary["SUMMARY"][0]["GHS 5s"], HashUnit.SHA256.GH
).into(self.algo.unit.default)
except (LookupError, ValueError, TypeError):
pass
@@ -176,7 +178,9 @@ class BMMiner(StockFirmware):
hashrate = boards[1].get(f"chain_rate{i}")
if hashrate:
hashboard.hashrate = round(float(hashrate) / 1000, 2)
hashboard.hashrate = AlgoHashRate.SHA256(
hashrate, HashUnit.SHA256.GH
).into(self.algo.unit.default)
chips = boards[1].get(f"chain_acn{i}")
if chips:
@@ -234,12 +238,9 @@ class BMMiner(StockFirmware):
rate_unit = rpc_stats["STATS"][1]["rate_unit"]
except KeyError:
rate_unit = "GH"
if rate_unit == "GH":
return round(expected_rate / 1000, 2)
if rate_unit == "MH":
return round(expected_rate / 1000000, 2)
else:
return round(expected_rate, 2)
return AlgoHashRate.SHA256(
expected_rate, HashUnit.SHA256.from_str(rate_unit)
).int(self.algo.unit.default)
except LookupError:
pass

View File

@@ -21,7 +21,7 @@ import toml
from pyasic.config import MinerConfig
from pyasic.config.mining import MiningModePowerTune
from pyasic.data import Fan, HashBoard
from pyasic.data import AlgoHashRate, Fan, HashBoard, HashUnit
from pyasic.data.error_codes import BraiinsOSError, MinerErrorData
from pyasic.errors import APIError
from pyasic.miners.data import (
@@ -349,7 +349,9 @@ class BOSMiner(BraiinsOSFirmware):
if rpc_summary is not None:
try:
return round(float(rpc_summary["SUMMARY"][0]["MHS 1m"] / 1000000), 2)
return AlgoHashRate.SHA256(
rpc_summary["SUMMARY"][0]["MHS 1m"], HashUnit.SHA256.MH
).into(self.algo.unit.default)
except (KeyError, IndexError, ValueError, TypeError):
pass
@@ -419,8 +421,9 @@ class BOSMiner(BraiinsOSFirmware):
for board in rpc_devs["DEVS"]:
_id = board["ID"] - offset
hashrate = round(float(board["MHS 1m"] / 1000000), 2)
hashboards[_id].hashrate = hashrate
hashboards[_id].hashrate = AlgoHashRate.SHA256(
board["MHS 1m"], HashUnit.SHA256.MH
).into(self.algo.unit.default)
except (IndexError, KeyError):
pass
@@ -528,11 +531,12 @@ class BOSMiner(BraiinsOSFirmware):
expected_hashrate = round(float(board["Nominal MHS"] / 1000000), 2)
if expected_hashrate:
hr_list.append(expected_hashrate)
if len(hr_list) == 0:
return 0
return AlgoHashRate.SHA256(0)
else:
return round(
(sum(hr_list) / len(hr_list)) * self.expected_hashboards, 2
return AlgoHashRate.SHA256(
(sum(hr_list) / len(hr_list)) * self.expected_hashboards
)
except (IndexError, KeyError):
pass
@@ -783,7 +787,9 @@ class BOSer(BraiinsOSFirmware):
if rpc_summary is not None:
try:
return round(float(rpc_summary["SUMMARY"][0]["MHS 1m"] / 1000000), 2)
return AlgoHashRate.SHA256(
rpc_summary["SUMMARY"][0]["MHS 1m"], HashUnit.SHA256.MH
).into(self.algo.unit.default)
except (KeyError, IndexError, ValueError, TypeError):
pass
@@ -798,7 +804,10 @@ class BOSer(BraiinsOSFirmware):
if grpc_miner_details is not None:
try:
return grpc_miner_details["stickerHashrate"]["gigahashPerSecond"] / 1000
return AlgoHashRate.SHA256(
grpc_miner_details["stickerHashrate"]["gigahashPerSecond"],
HashUnit.SHA256.GH,
).into(self.algo.unit.default)
except LookupError:
pass
@@ -827,13 +836,12 @@ class BOSer(BraiinsOSFirmware):
]
if board.get("stats") is not None:
if not board["stats"]["realHashrate"]["last5S"] == {}:
hashboards[idx].hashrate = round(
hashboards[idx].hashrate = AlgoHashRate.SHA256(
board["stats"]["realHashrate"]["last5S"][
"gigahashPerSecond"
]
/ 1000,
2,
)
],
HashUnit.SHA256.GH,
).into(self.algo.unit.default)
hashboards[idx].missing = False
return hashboards

View File

@@ -18,7 +18,7 @@ import logging
from typing import List, Optional
from pyasic.config import MinerConfig, MiningModeConfig
from pyasic.data import Fan, HashBoard
from pyasic.data import AlgoHashRate, Fan, HashBoard, HashUnit
from pyasic.data.error_codes import MinerErrorData, WhatsminerError
from pyasic.errors import APIError
from pyasic.miners.data import DataFunction, DataLocations, DataOptions, RPCAPICommand
@@ -395,7 +395,9 @@ class BTMiner(StockFirmware):
if rpc_summary is not None:
try:
return round(float(rpc_summary["SUMMARY"][0]["MHS 1m"] / 1000000), 2)
return AlgoHashRate.SHA256(
rpc_summary["SUMMARY"][0]["MHS 1m"], HashUnit.SHA256.MH
).into(self.algo.unit.default)
except LookupError:
pass
@@ -423,9 +425,9 @@ class BTMiner(StockFirmware):
self.expected_hashboards += 1
hashboards[board["ASC"]].chip_temp = round(board["Chip Temp Avg"])
hashboards[board["ASC"]].temp = round(board["Temperature"])
hashboards[board["ASC"]].hashrate = round(
float(board["MHS 1m"] / 1000000), 2
)
hashboards[board["ASC"]].hashrate = AlgoHashRate.SHA256(
board["MHS 1m"], HashUnit.SHA256.MH
).into(self.algo.unit.default)
hashboards[board["ASC"]].chips = board["Effective Chips"]
hashboards[board["ASC"]].serial_number = board["PCB SN"]
hashboards[board["ASC"]].missing = False
@@ -571,7 +573,10 @@ class BTMiner(StockFirmware):
try:
expected_hashrate = rpc_summary["SUMMARY"][0]["Factory GHS"]
if expected_hashrate:
return round(expected_hashrate / 1000, 2)
return AlgoHashRate.SHA256(
expected_hashrate, HashUnit.SHA256.GH
).int(self.algo.unit.default)
except LookupError:
pass

View File

@@ -17,6 +17,7 @@
from typing import Optional
from pyasic.config import MinerConfig
from pyasic.data import AlgoHashRate, HashUnit
from pyasic.errors import APIError
from pyasic.miners.data import DataFunction, DataLocations, DataOptions, RPCAPICommand
from pyasic.miners.device.firmware import StockFirmware
@@ -117,9 +118,9 @@ class CGMiner(StockFirmware):
if rpc_summary is not None:
try:
return round(
float(float(rpc_summary["SUMMARY"][0]["GHS 5s"]) / 1000), 2
)
return AlgoHashRate.SHA256(
rpc_summary["SUMMARY"][0]["GHS 5s"], HashUnit.SHA256.GH
).into(self.algo.unit.default)
except (LookupError, ValueError, TypeError):
pass

View File

@@ -17,7 +17,7 @@
from typing import List, Optional
from pyasic.config import MinerConfig
from pyasic.data import Fan, HashBoard
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
@@ -227,7 +227,9 @@ class ePIC(ePICFirmware):
if web_summary["HBs"] is not None:
for hb in web_summary["HBs"]:
hashrate += hb["Hashrate"][0]
return round(float(float(hashrate / 1000000)), 2)
return AlgoHashRate.SHA256(hashrate, HashUnit.SHA256.MH).into(
HashUnit.SHA256.TH
)
except (LookupError, ValueError, TypeError):
pass
@@ -249,7 +251,9 @@ class ePIC(ePICFirmware):
ideal = hb["Hashrate"][1] / 100
hashrate += hb["Hashrate"][0] / ideal
return round(float(float(hashrate / 1000000)), 2)
return AlgoHashRate.SHA256(hashrate, HashUnit.SHA256.GH).int(
self.algo.unit.default
)
except (LookupError, ValueError, TypeError):
pass
@@ -310,7 +314,9 @@ class ePIC(ePICFirmware):
hashrate = hb["Hashrate"][0]
# Update the Hashboard object
hb_list[hb["Index"]].missing = False
hb_list[hb["Index"]].hashrate = round(hashrate / 1000000, 2)
hb_list[hb["Index"]].hashrate = AlgoHashRate.SHA256(
hashrate, HashUnit.SHA256.MH
).into(self.algo.unit.default)
hb_list[hb["Index"]].chips = num_of_chips
hb_list[hb["Index"]].temp = hb["Temperature"]
return hb_list

View File

@@ -16,7 +16,7 @@
from typing import List
from pyasic.config import MinerConfig, MiningModeConfig
from pyasic.data import HashBoard
from pyasic.data import AlgoHashRate, HashBoard, HashUnit
from pyasic.errors import APIError
from pyasic.logger import logger
from pyasic.miners.backends import BFGMiner
@@ -158,9 +158,9 @@ class GoldshellMiner(BFGMiner):
if board.get("ID") is not None:
try:
b_id = board["ID"]
hashboards[b_id].hashrate = round(
board["MHS 20s"] / 1000000, 2
)
hashboards[b_id].hashrate = AlgoHashRate.SHA256(
board["MHS 20s"], HashUnit.SHA256.MH
).into(self.algo.unit.default)
hashboards[b_id].temp = board["tstemp-2"]
hashboards[b_id].missing = False
except KeyError:

View File

@@ -16,7 +16,7 @@
from typing import List, Optional
from pyasic.config import MinerConfig
from pyasic.data import Fan, HashBoard
from pyasic.data import AlgoHashRate, Fan, HashBoard, HashUnit
from pyasic.data.error_codes import MinerErrorData
from pyasic.data.error_codes.innosilicon import InnosiliconError
from pyasic.errors import APIError
@@ -182,20 +182,21 @@ class Innosilicon(CGMiner):
if web_get_all is not None:
try:
if "Hash Rate H" in web_get_all["total_hash"].keys():
return round(
float(web_get_all["total_hash"]["Hash Rate H"] / 1000000000000),
2,
)
return AlgoHashRate.SHA256(
web_get_all["total_hash"]["Hash Rate H"], HashUnit.SHA256.H
).into(self.algo.unit.default)
elif "Hash Rate" in web_get_all["total_hash"].keys():
return round(
float(web_get_all["total_hash"]["Hash Rate"] / 1000000), 5
)
return AlgoHashRate.SHA256(
web_get_all["total_hash"]["Hash Rate"], HashUnit.SHA256.MH
).into(self.algo.unit.default)
except KeyError:
pass
if rpc_summary is not None:
try:
return round(float(rpc_summary["SUMMARY"][0]["MHS 1m"] / 1000000), 2)
return AlgoHashRate.SHA256(
rpc_summary["SUMMARY"][0]["MHS 1m"], HashUnit.SHA256.MH
).into(self.algo.unit.default)
except (KeyError, IndexError):
pass
@@ -247,9 +248,9 @@ class Innosilicon(CGMiner):
hashrate = board.get("Hash Rate H")
if hashrate:
hashboards[idx].hashrate = round(
hashrate / 1000000000000, 2
)
hashboards[idx].hashrate = AlgoHashRate.SHA256(
hashrate, HashUnit.SHA256.H
).into(self.algo.unit.default)
chip_temp = board.get("Temp max")
if chip_temp:

View File

@@ -16,7 +16,7 @@
from typing import List, Optional
from pyasic.config import MinerConfig
from pyasic.data import Fan, HashBoard
from pyasic.data import AlgoHashRate, Fan, HashBoard, HashUnit
from pyasic.errors import APIError
from pyasic.miners.data import DataFunction, DataLocations, DataOptions, RPCAPICommand
from pyasic.miners.device.firmware import LuxOSFirmware
@@ -171,7 +171,9 @@ class LUXMiner(LuxOSFirmware):
if rpc_summary is not None:
try:
return round(float(rpc_summary["SUMMARY"][0]["GHS 5s"] / 1000), 2)
return AlgoHashRate.SHA256(
rpc_summary["SUMMARY"][0]["GHS 5s"], HashUnit.SHA256.GH
).into(self.algo.unit.default)
except (LookupError, ValueError, TypeError):
pass
@@ -215,7 +217,9 @@ class LUXMiner(LuxOSFirmware):
hashrate = boards[1].get(f"chain_rate{i}")
if hashrate:
hashboard.hashrate = round(float(hashrate) / 1000, 2)
hashboard.hashrate = AlgoHashRate.SHA256(
hashrate, HashUnit.SHA256.GH
).into(self.algo.unit.default)
chips = boards[1].get(f"chain_acn{i}")
if chips:
@@ -273,12 +277,9 @@ class LUXMiner(LuxOSFirmware):
rate_unit = rpc_stats["STATS"][1]["rate_unit"]
except KeyError:
rate_unit = "GH"
if rate_unit == "GH":
return round(expected_rate / 1000, 2)
if rate_unit == "MH":
return round(expected_rate / 1000000, 2)
else:
return round(expected_rate, 2)
return AlgoHashRate.SHA256(
expected_rate, HashUnit.SHA256.from_str(rate_unit)
).int(self.algo.unit.default)
except LookupError:
pass

View File

@@ -2,7 +2,7 @@ from typing import List, Optional
from pyasic import MinerConfig
from pyasic.config import MiningModeConfig
from pyasic.data import Fan, HashBoard
from pyasic.data import AlgoHashRate, Fan, HashBoard, HashUnit
from pyasic.errors import APIError
from pyasic.miners.data import DataFunction, DataLocations, DataOptions, WebAPICommand
from pyasic.miners.device.firmware import MaraFirmware
@@ -170,7 +170,9 @@ class MaraMiner(MaraFirmware):
try:
for hb in web_hashboards["hashboards"]:
idx = hb["index"]
hashboards[idx].hashrate = round(hb["hashrate_average"] / 1000, 2)
hashboards[idx].hashrate = AlgoHashRate.SHA256(
hb["hashrate_average"], HashUnit.SHA256.GH
).into(self.algo.unit.default)
hashboards[idx].temp = round(
sum(hb["temperature_pcb"]) / len(hb["temperature_pcb"]), 2
)
@@ -232,7 +234,9 @@ class MaraMiner(MaraFirmware):
if web_brief is not None:
try:
return round(web_brief["hashrate_realtime"], 2)
return AlgoHashRate.SHA256(
web_brief["hashrate_realtime"], HashUnit.SHA256.TH
).into(self.algo.unit.default)
except LookupError:
pass
@@ -276,7 +280,9 @@ class MaraMiner(MaraFirmware):
if web_brief is not None:
try:
return round(web_brief["hashrate_ideal"] / 1000, 2)
return AlgoHashRate.SHA256(
web_brief["hashrate_ideal"], HashUnit.SHA256.GH
).int(self.algo.unit.default)
except LookupError:
pass

View File

@@ -17,6 +17,7 @@
from typing import Optional
from pyasic import MinerConfig
from pyasic.data import AlgoHashRate, HashUnit
from pyasic.errors import APIError
from pyasic.miners.backends.bmminer import BMMiner
from pyasic.miners.data import (
@@ -186,9 +187,9 @@ class VNish(BMMiner, VNishFirmware):
if rpc_summary is not None:
try:
return round(
float(float(rpc_summary["SUMMARY"][0]["GHS 5s"]) / 1000), 2
)
return AlgoHashRate.SHA256(
rpc_summary["SUMMARY"][0]["GHS 5s"], HashUnit.SHA256.GH
).into(self.algo.unit.default)
except (LookupError, ValueError, TypeError):
pass

View File

@@ -22,6 +22,8 @@ from pyasic.config import MinerConfig
from pyasic.data import Fan, HashBoard, MinerData
from pyasic.data.device import DeviceInfo
from pyasic.data.error_codes import MinerErrorData
from pyasic.device import MinerModel
from pyasic.device.algorithm import MinerAlgo
from pyasic.device.firmware import MinerFirmware
from pyasic.device.makes import MinerMake
from pyasic.errors import APIError
@@ -40,8 +42,9 @@ class MinerProtocol(Protocol):
ssh: _ssh_cls = None
make: MinerMake = None
raw_model: str = None
raw_model: MinerModel = None
firmware: MinerFirmware = None
algo = MinerAlgo.SHA256
expected_hashboards: int = 3
expected_chips: int = None
@@ -84,7 +87,9 @@ class MinerProtocol(Protocol):
@property
def device_info(self) -> DeviceInfo:
return DeviceInfo(make=self.make, model=self.raw_model, firmware=self.firmware)
return DeviceInfo(
make=self.make, model=self.raw_model, firmware=self.firmware, algo=self.algo
)
@property
def api(self):