feature: add auto unit to hashrates and improve model dump for hashrates
This commit is contained in:
@@ -13,19 +13,20 @@
|
|||||||
# See the License for the specific language governing permissions and -
|
# See the License for the specific language governing permissions and -
|
||||||
# limitations under the License. -
|
# limitations under the License. -
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
import time
|
import time
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
from typing import Any, List, Union
|
from typing import Any, List, Union
|
||||||
|
|
||||||
from pydantic import BaseModel, Field, computed_field, field_serializer
|
from pydantic import BaseModel, Field, computed_field
|
||||||
|
|
||||||
from pyasic.config import MinerConfig
|
from pyasic.config import MinerConfig
|
||||||
from pyasic.config.mining import MiningModePowerTune
|
from pyasic.config.mining import MiningModePowerTune
|
||||||
from pyasic.data.pools import PoolMetrics, Scheme
|
from pyasic.data.pools import PoolMetrics, Scheme
|
||||||
from pyasic.device.algorithm.hashrate import AlgoHashRateType
|
from pyasic.device.algorithm.hashrate import AlgoHashRateType
|
||||||
|
from pyasic.device.algorithm.hashrate.base import GenericHashrate
|
||||||
|
|
||||||
|
from ..device.algorithm.hashrate.unit.base import GenericUnit
|
||||||
from .boards import HashBoard
|
from .boards import HashBoard
|
||||||
from .device import DeviceInfo
|
from .device import DeviceInfo
|
||||||
from .error_codes import BraiinsOSError, InnosiliconError, WhatsminerError, X19Error
|
from .error_codes import BraiinsOSError, InnosiliconError, WhatsminerError, X19Error
|
||||||
@@ -135,9 +136,6 @@ class MinerData(BaseModel):
|
|||||||
def fields(cls):
|
def fields(cls):
|
||||||
return list(cls.model_fields.keys())
|
return list(cls.model_fields.keys())
|
||||||
|
|
||||||
def __post_init__(self):
|
|
||||||
self.raw_datetime = datetime.now(timezone.utc).astimezone()
|
|
||||||
|
|
||||||
def get(self, __key: str, default: Any = None):
|
def get(self, __key: str, default: Any = None):
|
||||||
try:
|
try:
|
||||||
val = self.__getitem__(__key)
|
val = self.__getitem__(__key)
|
||||||
@@ -198,35 +196,23 @@ class MinerData(BaseModel):
|
|||||||
|
|
||||||
@computed_field # type: ignore[misc]
|
@computed_field # type: ignore[misc]
|
||||||
@property
|
@property
|
||||||
def hashrate(self) -> AlgoHashRateType:
|
def hashrate(self) -> AlgoHashRateType | None:
|
||||||
if len(self.hashboards) > 0:
|
if len(self.hashboards) > 0:
|
||||||
hr_data = []
|
hr_data = []
|
||||||
for item in self.hashboards:
|
for item in self.hashboards:
|
||||||
if item.hashrate is not None:
|
if item.hashrate is not None:
|
||||||
hr_data.append(item.hashrate)
|
hr_data.append(item.hashrate)
|
||||||
if len(hr_data) > 0:
|
if len(hr_data) > 0:
|
||||||
return sum(hr_data, start=type(hr_data[0])(rate=0))
|
return sum(hr_data, start=self.hashboards[0].hashrate.__class__(rate=0))
|
||||||
return self.raw_hashrate
|
return self.raw_hashrate
|
||||||
|
|
||||||
@field_serializer("hashrate")
|
|
||||||
def serialize_hashrate(self, hashrate: AlgoHashRateType | None) -> float:
|
|
||||||
if hashrate is not None:
|
|
||||||
return float(hashrate)
|
|
||||||
|
|
||||||
@field_serializer("expected_hashrate")
|
|
||||||
def serialize_expected_hashrate(
|
|
||||||
self, expected_hashrate: AlgoHashRateType | None, _info
|
|
||||||
) -> float:
|
|
||||||
if expected_hashrate is not None:
|
|
||||||
return float(expected_hashrate)
|
|
||||||
|
|
||||||
@hashrate.setter
|
@hashrate.setter
|
||||||
def hashrate(self, val):
|
def hashrate(self, val):
|
||||||
self.raw_hashrate = val
|
self.raw_hashrate = val
|
||||||
|
|
||||||
@computed_field # type: ignore[misc]
|
@computed_field # type: ignore[misc]
|
||||||
@property
|
@property
|
||||||
def wattage_limit(self) -> int:
|
def wattage_limit(self) -> int | None:
|
||||||
if self.config is not None:
|
if self.config is not None:
|
||||||
if isinstance(self.config.mining_mode, MiningModePowerTune):
|
if isinstance(self.config.mining_mode, MiningModePowerTune):
|
||||||
return self.config.mining_mode.power
|
return self.config.mining_mode.power
|
||||||
|
|||||||
@@ -51,11 +51,6 @@ class HashBoard(BaseModel):
|
|||||||
active: bool | None = None
|
active: bool | None = None
|
||||||
voltage: float | None = None
|
voltage: float | None = None
|
||||||
|
|
||||||
@field_serializer("hashrate")
|
|
||||||
def serialize_hashrate(self, hashrate: AlgoHashRateType | None) -> float:
|
|
||||||
if hashrate is not None:
|
|
||||||
return float(hashrate)
|
|
||||||
|
|
||||||
def get(self, __key: str, default: Any = None):
|
def get(self, __key: str, default: Any = None):
|
||||||
try:
|
try:
|
||||||
val = self.__getitem__(__key)
|
val = self.__getitem__(__key)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel, field_serializer
|
||||||
from typing_extensions import Self
|
from typing_extensions import Self
|
||||||
|
|
||||||
from .unit.base import AlgoHashRateUnitType, GenericUnit
|
from .unit.base import AlgoHashRateUnitType, GenericUnit
|
||||||
@@ -12,10 +12,31 @@ class AlgoHashRateType(BaseModel, ABC):
|
|||||||
unit: AlgoHashRateUnitType
|
unit: AlgoHashRateUnitType
|
||||||
rate: float
|
rate: float
|
||||||
|
|
||||||
|
@field_serializer("unit")
|
||||||
|
def serialize_unit(self, unit: AlgoHashRateUnitType):
|
||||||
|
return unit.model_dump()
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def into(self, other: "AlgoHashRateUnitType"):
|
def into(self, other: "AlgoHashRateUnitType"):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def auto_unit(self):
|
||||||
|
if 1 < self.rate // int(self.unit.H) < 1000:
|
||||||
|
return self.into(self.unit.H)
|
||||||
|
if 1 < self.rate // int(self.unit.MH) < 1000:
|
||||||
|
return self.into(self.unit.MH)
|
||||||
|
if 1 < self.rate // int(self.unit.GH) < 1000:
|
||||||
|
return self.into(self.unit.GH)
|
||||||
|
if 1 < self.rate // int(self.unit.TH) < 1000:
|
||||||
|
return self.into(self.unit.TH)
|
||||||
|
if 1 < self.rate // int(self.unit.PH) < 1000:
|
||||||
|
return self.into(self.unit.PH)
|
||||||
|
if 1 < self.rate // int(self.unit.EH) < 1000:
|
||||||
|
return self.into(self.unit.EH)
|
||||||
|
if 1 < self.rate // int(self.unit.ZH) < 1000:
|
||||||
|
return self.into(self.unit.ZH)
|
||||||
|
return self
|
||||||
|
|
||||||
def __float__(self):
|
def __float__(self):
|
||||||
return float(self.rate)
|
return float(self.rate)
|
||||||
|
|
||||||
@@ -65,6 +86,9 @@ class AlgoHashRateType(BaseModel, ABC):
|
|||||||
|
|
||||||
|
|
||||||
class GenericHashrate(AlgoHashRateType):
|
class GenericHashrate(AlgoHashRateType):
|
||||||
|
rate: float = 0
|
||||||
|
unit: GenericUnit = GenericUnit.H
|
||||||
|
|
||||||
def into(self, other: GenericUnit):
|
def into(self, other: GenericUnit):
|
||||||
return self.__class__(
|
return self.__class__(
|
||||||
rate=self.rate / (other.value / self.unit.value), unit=other
|
rate=self.rate / (other.value / self.unit.value), unit=other
|
||||||
|
|||||||
@@ -54,6 +54,9 @@ class AlgoHashRateUnitType(IntEnum):
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return str(self)
|
return str(self)
|
||||||
|
|
||||||
|
def model_dump(self):
|
||||||
|
return {"value": self.value, "suffix": str(self)}
|
||||||
|
|
||||||
|
|
||||||
class GenericUnit(AlgoHashRateUnitType):
|
class GenericUnit(AlgoHashRateUnitType):
|
||||||
H = 1
|
H = 1
|
||||||
|
|||||||
Reference in New Issue
Block a user