Compare commits

...

4 Commits

Author SHA1 Message Date
Brett Rowan
55786b154d version: bump version number 2024-12-20 10:16:19 -07:00
Brett Rowan
6ab9681dec feature: add auto unit to hashrates and improve model dump for hashrates 2024-12-20 10:16:01 -07:00
Brett Rowan
89641c6316 version: bump version number 2024-12-20 09:26:16 -07:00
Brett Rowan
136ff6a688 feature: add generic hashrate type for doing sums 2024-12-20 09:25:52 -07:00
5 changed files with 56 additions and 28 deletions

View File

@@ -13,19 +13,20 @@
# See the License for the specific language governing permissions and -
# limitations under the License. -
# ------------------------------------------------------------------------------
import copy
import time
from datetime import datetime, timezone
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.mining import MiningModePowerTune
from pyasic.data.pools import PoolMetrics, Scheme
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 .device import DeviceInfo
from .error_codes import BraiinsOSError, InnosiliconError, WhatsminerError, X19Error
@@ -135,9 +136,6 @@ class MinerData(BaseModel):
def fields(cls):
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):
try:
val = self.__getitem__(__key)
@@ -198,35 +196,23 @@ class MinerData(BaseModel):
@computed_field # type: ignore[misc]
@property
def hashrate(self) -> AlgoHashRateType:
def hashrate(self) -> AlgoHashRateType | None:
if len(self.hashboards) > 0:
hr_data = []
for item in self.hashboards:
if item.hashrate is not None:
hr_data.append(item.hashrate)
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
@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
def hashrate(self, val):
self.raw_hashrate = val
@computed_field # type: ignore[misc]
@property
def wattage_limit(self) -> int:
def wattage_limit(self) -> int | None:
if self.config is not None:
if isinstance(self.config.mining_mode, MiningModePowerTune):
return self.config.mining_mode.power

View File

@@ -51,11 +51,6 @@ class HashBoard(BaseModel):
active: bool | 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):
try:
val = self.__getitem__(__key)

View File

@@ -2,20 +2,41 @@ from __future__ import annotations
from abc import ABC, abstractmethod
from pydantic import BaseModel
from pydantic import BaseModel, field_serializer
from typing_extensions import Self
from .unit.base import AlgoHashRateUnitType
from .unit.base import AlgoHashRateUnitType, GenericUnit
class AlgoHashRateType(BaseModel, ABC):
unit: AlgoHashRateUnitType
rate: float
@field_serializer("unit")
def serialize_unit(self, unit: AlgoHashRateUnitType):
return unit.model_dump()
@abstractmethod
def into(self, other: "AlgoHashRateUnitType"):
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):
return float(self.rate)
@@ -62,3 +83,13 @@ class AlgoHashRateType(BaseModel, ABC):
rate=self.rate * other.into(self.unit).rate, unit=self.unit
)
return self.__class__(rate=self.rate * other, unit=self.unit)
class GenericHashrate(AlgoHashRateType):
rate: float = 0
unit: GenericUnit = GenericUnit.H
def into(self, other: GenericUnit):
return self.__class__(
rate=self.rate / (other.value / self.unit.value), unit=other
)

View File

@@ -53,3 +53,19 @@ class AlgoHashRateUnitType(IntEnum):
def __repr__(self):
return str(self)
def model_dump(self):
return {"value": self.value, "suffix": str(self)}
class GenericUnit(AlgoHashRateUnitType):
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 = H

View File

@@ -1,6 +1,6 @@
[tool.poetry]
name = "pyasic"
version = "0.66.2"
version = "0.67.0"
description = "A simplified and standardized interface for Bitcoin ASICs."
authors = ["UpstreamData <brett@upstreamdata.ca>"]
repository = "https://github.com/UpstreamData/pyasic"