feature: add bos to config miner types.
This commit is contained in:
@@ -15,6 +15,8 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
from dataclasses import dataclass
|
||||
|
||||
import toml
|
||||
|
||||
from pyasic.config.fans import FanModeConfig
|
||||
from pyasic.config.mining import MiningModeConfig
|
||||
from pyasic.config.pools import PoolConfig
|
||||
@@ -85,11 +87,41 @@ class MinerConfig:
|
||||
**self.power_scaling.as_inno(),
|
||||
}
|
||||
|
||||
def as_bosminer(self, user_suffix: str = None):
|
||||
|
||||
return {
|
||||
**merge(self.fan_mode.as_bosminer(), self.temperature.as_bosminer()),
|
||||
**self.mining_mode.as_bosminer(),
|
||||
**self.pools.as_bosminer(user_suffix=user_suffix),
|
||||
**self.power_scaling.as_bosminer(),
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def from_api(cls, api_pools: dict):
|
||||
return cls(pools=PoolConfig.from_api(api_pools))
|
||||
|
||||
|
||||
|
||||
def merge(a: dict, b: dict):
|
||||
ret = {}
|
||||
for k in a:
|
||||
v = a[k]
|
||||
if k in b.keys():
|
||||
if isinstance(v, dict):
|
||||
ret[k] = merge(a[k], b[k])
|
||||
elif isinstance(v, list):
|
||||
ret[k] = [*v, *b[k]]
|
||||
else:
|
||||
ret[k] = v
|
||||
else:
|
||||
ret[k] = v
|
||||
for k in b:
|
||||
v = b[k]
|
||||
if k not in ret.keys():
|
||||
ret[k] = v
|
||||
return ret
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
config = MinerConfig(
|
||||
pools=PoolConfig.simple(
|
||||
@@ -102,6 +134,8 @@ if __name__ == "__main__":
|
||||
]
|
||||
),
|
||||
mining_mode=MiningModeConfig.power_tuning(3000),
|
||||
temperature=TemperatureConfig(hot=100),
|
||||
fan_mode=FanModeConfig.manual(minimum_fans=2, speed=70),
|
||||
)
|
||||
print("WM:", config.as_wm())
|
||||
print("AM Modern:", config.as_am_modern())
|
||||
@@ -109,3 +143,6 @@ if __name__ == "__main__":
|
||||
print("GS:", config.as_goldshell())
|
||||
print("Avalon:", config.as_avalon())
|
||||
print("Inno:", config.as_inno())
|
||||
print("BOS+ .toml:", config.as_bosminer())
|
||||
print("BOS+ .toml as toml:")
|
||||
print(toml.dumps(config.as_bosminer()))
|
||||
|
||||
@@ -35,7 +35,7 @@ class MinerConfigOption(Enum):
|
||||
def as_avalon(self) -> dict:
|
||||
return self.value.as_avalon()
|
||||
|
||||
def as_bos(self) -> dict:
|
||||
def as_bosminer(self) -> dict:
|
||||
return self.value.as_bos()
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
@@ -61,5 +61,5 @@ class MinerConfigValue:
|
||||
def as_avalon(self) -> dict:
|
||||
return {}
|
||||
|
||||
def as_bos(self) -> dict:
|
||||
def as_bosminer(self) -> dict:
|
||||
return {}
|
||||
|
||||
@@ -25,7 +25,7 @@ class FanModeNormal(MinerConfigValue):
|
||||
def as_am_modern(self):
|
||||
return {"bitmain-fan-ctrl": False, "bitmain-fan-pwn": "100"}
|
||||
|
||||
def as_bos(self):
|
||||
def as_bosminer(self):
|
||||
return {"temp_control": {"mode": "auto"}}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ class FanModeManual(MinerConfigValue):
|
||||
def as_am_modern(self):
|
||||
return {"bitmain-fan-ctrl": True, "bitmain-fan-pwn": str(self.speed)}
|
||||
|
||||
def as_bos(self):
|
||||
def as_bosminer(self):
|
||||
return {
|
||||
"temp_control": {"mode": "manual"},
|
||||
"fan_control": {"min_fans": self.minimum_fans, "speed": self.speed},
|
||||
@@ -52,8 +52,8 @@ class FanModeImmersion(MinerConfigValue):
|
||||
def as_am_modern(self):
|
||||
return {"bitmain-fan-ctrl": True, "bitmain-fan-pwn": "0"}
|
||||
|
||||
def as_bos(self):
|
||||
return {"temp_control": {"mode": "manual"}, "fan_control": {"min_fans": 0}}
|
||||
def as_bosminer(self):
|
||||
return {"temp_control": {"mode": "disabled"}}
|
||||
|
||||
|
||||
class FanModeConfig(MinerConfigOption):
|
||||
|
||||
@@ -73,6 +73,9 @@ class MiningModePowerTune(MinerConfigValue):
|
||||
def as_wm(self):
|
||||
return {"mode": self.mode, self.mode: {"wattage": self.power}}
|
||||
|
||||
def as_bosminer(self) -> dict:
|
||||
return {"autotuning": {"enabled": True, "psu_power_limit": self.power}}
|
||||
|
||||
|
||||
@dataclass
|
||||
class MiningModeHashrateTune(MinerConfigValue):
|
||||
|
||||
@@ -93,6 +93,16 @@ class Pool(MinerConfigValue):
|
||||
def from_api(cls, api_pool: dict):
|
||||
return cls(url=api_pool["URL"], user=api_pool["User"], password="x")
|
||||
|
||||
def as_bosminer(self, user_suffix: str = None):
|
||||
if user_suffix is not None:
|
||||
return {
|
||||
"url": self.url,
|
||||
"user": f"{self.user}{user_suffix}",
|
||||
"pass": self.password,
|
||||
}
|
||||
return {"url": self.url, "user": self.user, "pass": self.password}
|
||||
|
||||
|
||||
@dataclass
|
||||
class PoolGroup(MinerConfigValue):
|
||||
pools: list[Pool] = field(default_factory=list)
|
||||
@@ -178,6 +188,18 @@ class PoolGroup(MinerConfigValue):
|
||||
pools.append(Pool.from_api(pool))
|
||||
return cls(pools=pools)
|
||||
|
||||
def as_bosminer(self, user_suffix: str = None) -> dict:
|
||||
if len(self.pools) > 0:
|
||||
return {
|
||||
"name": self.name,
|
||||
"quota": self.quota,
|
||||
"pool": [
|
||||
pool.as_bosminer(user_suffix=user_suffix) for pool in self.pools
|
||||
],
|
||||
}
|
||||
return {"name": "Group", "quota": 1, "pool": [Pool.as_bosminer()]}
|
||||
|
||||
|
||||
@dataclass
|
||||
class PoolConfig(MinerConfigValue):
|
||||
groups: list[PoolGroup] = field(default_factory=list)
|
||||
@@ -230,4 +252,11 @@ class PoolConfig(MinerConfigValue):
|
||||
pool_data = api_pools["POOLS"]
|
||||
pool_data = sorted(pool_data, key=lambda x: int(x["POOL"]))
|
||||
|
||||
return cls([PoolGroup.from_api(pool_data)])
|
||||
return cls([PoolGroup.from_api(pool_data)])
|
||||
|
||||
def as_bosminer(self, user_suffix: str = None) -> dict:
|
||||
if len(self.groups) > 0:
|
||||
return {
|
||||
"group": [g.as_bosminer(user_suffix=user_suffix) for g in self.groups]
|
||||
}
|
||||
return {"group": [PoolGroup().as_bosminer()]}
|
||||
|
||||
@@ -27,3 +27,13 @@ class TemperatureConfig(MinerConfigValue):
|
||||
@classmethod
|
||||
def default(cls):
|
||||
return cls()
|
||||
|
||||
def as_bosminer(self) -> dict:
|
||||
temp_cfg = {}
|
||||
if self.target is not None:
|
||||
temp_cfg["target_temp"] = self.target
|
||||
if self.hot is not None:
|
||||
temp_cfg["hot_temp"] = self.hot
|
||||
if self.danger is not None:
|
||||
temp_cfg["dangerous_temp"] = self.danger
|
||||
return {"temp_control": temp_cfg}
|
||||
|
||||
Reference in New Issue
Block a user