feature: Add bosminer.toml parser.
This commit is contained in:
@@ -119,6 +119,15 @@ class MinerConfig:
|
||||
def from_inno(cls, web_pools: dict):
|
||||
return cls(pools=PoolConfig.from_inno(web_pools))
|
||||
|
||||
@classmethod
|
||||
def from_bosminer(cls, toml_conf: dict):
|
||||
return cls(
|
||||
pools=PoolConfig.from_bosminer(toml_conf),
|
||||
mining_mode=MiningModeConfig.from_bosminer(toml_conf),
|
||||
fan_mode=FanModeConfig.from_bosminer(toml_conf),
|
||||
temperature=TemperatureConfig.from_bosminer(toml_conf),
|
||||
power_scaling=PowerScalingConfig.from_bosminer(toml_conf),
|
||||
)
|
||||
|
||||
def merge(a: dict, b: dict):
|
||||
ret = {}
|
||||
@@ -152,9 +161,11 @@ if __name__ == "__main__":
|
||||
]
|
||||
),
|
||||
mining_mode=MiningModeConfig.power_tuning(3000),
|
||||
temperature=TemperatureConfig(hot=100),
|
||||
temperature=TemperatureConfig(hot=100, danger=110),
|
||||
fan_mode=FanModeConfig.manual(minimum_fans=2, speed=70),
|
||||
power_scaling=PowerScalingConfig.enabled(power_step=100, minimum_power=2400)
|
||||
)
|
||||
print(config)
|
||||
print("WM:", config.as_wm())
|
||||
print("AM Modern:", config.as_am_modern())
|
||||
print("AM Old:", config.as_am_old())
|
||||
@@ -164,3 +175,7 @@ if __name__ == "__main__":
|
||||
print("BOS+ .toml:", config.as_bosminer())
|
||||
print("BOS+ .toml as toml:")
|
||||
print(toml.dumps(config.as_bosminer()))
|
||||
|
||||
bos_parsed = MinerConfig.from_bosminer(config.as_bosminer())
|
||||
print(bos_parsed)
|
||||
print(bos_parsed == config)
|
||||
|
||||
@@ -35,6 +35,17 @@ class FanModeManual(MinerConfigValue):
|
||||
minimum_fans: int = 1
|
||||
speed: int = 100
|
||||
|
||||
@classmethod
|
||||
def from_bosminer(cls, toml_fan_conf: dict):
|
||||
cls_conf = {}
|
||||
if toml_fan_conf.get("min_fans") is not None:
|
||||
cls_conf["minimum_fans"] = toml_fan_conf["min_fans"]
|
||||
if toml_fan_conf.get("speed") is not None:
|
||||
cls_conf["speed"] = toml_fan_conf["speed"]
|
||||
return cls(**cls_conf)
|
||||
|
||||
|
||||
|
||||
def as_am_modern(self):
|
||||
return {"bitmain-fan-ctrl": True, "bitmain-fan-pwn": str(self.speed)}
|
||||
|
||||
@@ -74,4 +85,21 @@ class FanModeConfig(MinerConfigOption):
|
||||
else:
|
||||
return cls.normal()
|
||||
else:
|
||||
return cls.default()
|
||||
return cls.default()
|
||||
|
||||
@classmethod
|
||||
def from_bosminer(cls, toml_conf: dict):
|
||||
if toml_conf.get("temp_control") is None:
|
||||
return cls.default()
|
||||
if toml_conf["temp_control"].get("mode") is None:
|
||||
return cls.default()
|
||||
|
||||
mode = toml_conf["temp_control"]["mode"]
|
||||
if mode == "auto":
|
||||
return cls.normal()
|
||||
elif mode == "manual":
|
||||
if toml_conf.get("fan_control"):
|
||||
return cls.manual().from_bosminer(toml_conf["fan_control"])
|
||||
return cls.manual()
|
||||
elif mode == "disabled":
|
||||
return cls.immersion()
|
||||
|
||||
@@ -65,13 +65,15 @@ class MiningModeHPM(MinerConfigValue):
|
||||
@dataclass
|
||||
class MiningModePowerTune(MinerConfigValue):
|
||||
mode: str = field(init=False, default="power_tuning")
|
||||
power: int
|
||||
power: int = None
|
||||
|
||||
def as_am_modern(self):
|
||||
return {"miner-mode": "0"}
|
||||
|
||||
def as_wm(self):
|
||||
return {"mode": self.mode, self.mode: {"wattage": self.power}}
|
||||
if self.power is not None:
|
||||
return {"mode": self.mode, self.mode: {"wattage": self.power}}
|
||||
return {}
|
||||
|
||||
def as_bosminer(self) -> dict:
|
||||
return {"autotuning": {"enabled": True, "psu_power_limit": self.power}}
|
||||
@@ -80,7 +82,7 @@ class MiningModePowerTune(MinerConfigValue):
|
||||
@dataclass
|
||||
class MiningModeHashrateTune(MinerConfigValue):
|
||||
mode: str = field(init=False, default="hashrate_tuning")
|
||||
hashrate: int
|
||||
hashrate: int = None
|
||||
|
||||
def as_am_modern(self):
|
||||
return {"miner-mode": "0"}
|
||||
@@ -130,4 +132,31 @@ class MiningModeConfig(MinerConfigOption):
|
||||
return cls.sleep()
|
||||
elif int(work_mode) == 3:
|
||||
return cls.low()
|
||||
return cls.default()
|
||||
return cls.default()
|
||||
|
||||
@classmethod
|
||||
def from_bosminer(cls, toml_conf: dict):
|
||||
if toml_conf.get("autotuning") is None:
|
||||
return cls.default()
|
||||
autotuning_conf = toml_conf["autotuning"]
|
||||
|
||||
if autotuning_conf.get("enabled") is None:
|
||||
return cls.default()
|
||||
if not autotuning_conf["enabled"]:
|
||||
return cls.default()
|
||||
|
||||
if autotuning_conf.get("psu_power_limit") is not None:
|
||||
# old autotuning conf
|
||||
return cls.power_tuning(autotuning_conf["psu_power_limit"])
|
||||
if autotuning_conf.get("mode") is not None:
|
||||
# new autotuning conf
|
||||
mode = autotuning_conf["mode"]
|
||||
if mode == "power_target":
|
||||
if autotuning_conf.get("power_target") is not None:
|
||||
return cls.power_tuning(autotuning_conf["power_target"])
|
||||
return cls.power_tuning()
|
||||
if mode == "hashrate_target":
|
||||
if autotuning_conf.get("hashrate_target") is not None:
|
||||
return cls.hashrate_tuning(autotuning_conf["hashrate_target"])
|
||||
return cls.hashrate_tuning()
|
||||
|
||||
|
||||
@@ -122,6 +122,15 @@ class Pool(MinerConfigValue):
|
||||
url=web_pool["url"], user=web_pool["user"], password=web_pool["pass"]
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_bosminer(cls, toml_pool_conf: dict):
|
||||
return cls(
|
||||
url=toml_pool_conf["url"],
|
||||
user=toml_pool_conf["user"],
|
||||
password=toml_pool_conf["pass"],
|
||||
)
|
||||
|
||||
|
||||
|
||||
@dataclass
|
||||
class PoolGroup(MinerConfigValue):
|
||||
@@ -226,6 +235,16 @@ class PoolGroup(MinerConfigValue):
|
||||
def from_inno(cls, web_pools: list):
|
||||
return cls([Pool.from_inno(p) for p in web_pools])
|
||||
|
||||
@classmethod
|
||||
def from_bosminer(cls, toml_group_conf: dict):
|
||||
if toml_group_conf.get("pool") is not None:
|
||||
return cls(
|
||||
name=toml_group_conf["name"],
|
||||
quota=toml_group_conf["quota"],
|
||||
pools=[Pool.from_bosminer(p) for p in toml_group_conf["pool"]],
|
||||
)
|
||||
return cls()
|
||||
|
||||
|
||||
@dataclass
|
||||
class PoolConfig(MinerConfigValue):
|
||||
@@ -303,3 +322,11 @@ class PoolConfig(MinerConfigValue):
|
||||
return cls([PoolGroup.from_inno(web_pools)])
|
||||
|
||||
|
||||
@classmethod
|
||||
def from_bosminer(cls, toml_conf: dict):
|
||||
if toml_conf.get("group") is None:
|
||||
return cls()
|
||||
|
||||
return cls([PoolGroup.from_bosminer(g) for g in toml_conf["group"]])
|
||||
|
||||
|
||||
|
||||
@@ -23,24 +23,66 @@ class PowerScalingShutdownEnabled(MinerConfigValue):
|
||||
mode: str = field(init=False, default="enabled")
|
||||
duration: int = None
|
||||
|
||||
def as_bosminer(self) -> dict:
|
||||
cfg = {"shutdown_enabled": True}
|
||||
|
||||
if self.duration is not None:
|
||||
cfg["shutdown_duration"] = self.duration
|
||||
|
||||
|
||||
@dataclass
|
||||
class PowerScalingShutdownDisabled(MinerConfigValue):
|
||||
mode: str = field(init=False, default="disabled")
|
||||
|
||||
def as_bosminer(self) -> dict:
|
||||
return {"shutdown_enabled": False}
|
||||
|
||||
|
||||
class PowerScalingShutdown(MinerConfigOption):
|
||||
enabled = PowerScalingShutdownEnabled
|
||||
disabled = PowerScalingShutdownDisabled
|
||||
|
||||
@classmethod
|
||||
def from_bosminer(cls, power_scaling_conf: dict):
|
||||
sd_enabled = power_scaling_conf.get("shutdown_enabled")
|
||||
if sd_enabled is not None:
|
||||
if sd_enabled:
|
||||
return cls.enabled(power_scaling_conf.get("shutdown_duration"))
|
||||
else:
|
||||
return cls.disabled()
|
||||
return None
|
||||
|
||||
|
||||
@dataclass
|
||||
class PowerScalingEnabled(MinerConfigValue):
|
||||
mode: str = field(init=False, default="enabled")
|
||||
power_step: int = None
|
||||
minimum_power: int = None
|
||||
shutdown_mode: PowerScalingShutdown = None
|
||||
shutdown_enabled: PowerScalingShutdown = None
|
||||
|
||||
@classmethod
|
||||
def from_bosminer(cls, power_scaling_conf: dict):
|
||||
power_step = power_scaling_conf.get("power_step")
|
||||
min_power = power_scaling_conf.get("min_psu_power_limit")
|
||||
sd_mode = PowerScalingShutdown.from_bosminer(power_scaling_conf)
|
||||
|
||||
return cls(
|
||||
power_step=power_step, minimum_power=min_power, shutdown_enabled=sd_mode
|
||||
)
|
||||
|
||||
def as_bosminer(self) -> dict:
|
||||
cfg = {
|
||||
"enabled": True
|
||||
}
|
||||
if self.power_step is not None:
|
||||
cfg["power_step"] = self.power_step
|
||||
if self.minimum_power is not None:
|
||||
cfg["min_psu_power_limit"] = self.minimum_power
|
||||
|
||||
if self.shutdown_enabled is not None:
|
||||
cfg = {**cfg, **self.shutdown_enabled.as_bosminer()}
|
||||
|
||||
return {"power_scaling": cfg}
|
||||
|
||||
@dataclass
|
||||
class PowerScalingDisabled(MinerConfigValue):
|
||||
@@ -54,3 +96,16 @@ class PowerScalingConfig(MinerConfigOption):
|
||||
@classmethod
|
||||
def default(cls):
|
||||
return cls.disabled()
|
||||
|
||||
@classmethod
|
||||
def from_bosminer(cls, toml_conf: dict):
|
||||
power_scaling = toml_conf.get("power_scaling")
|
||||
if power_scaling is not None:
|
||||
enabled = power_scaling.get("enabled")
|
||||
if enabled is not None:
|
||||
if enabled:
|
||||
return cls.enabled().from_bosminer(power_scaling)
|
||||
else:
|
||||
return cls.disabled()
|
||||
|
||||
return cls.default()
|
||||
@@ -37,3 +37,13 @@ class TemperatureConfig(MinerConfigValue):
|
||||
if self.danger is not None:
|
||||
temp_cfg["dangerous_temp"] = self.danger
|
||||
return {"temp_control": temp_cfg}
|
||||
|
||||
@classmethod
|
||||
def from_bosminer(cls, toml_conf: dict):
|
||||
temp_control = toml_conf.get("temp_control")
|
||||
if temp_control is not None:
|
||||
return cls(
|
||||
target=temp_control.get("target_temp"),
|
||||
hot=temp_control.get("hot_temp"),
|
||||
danger=temp_control.get("dangerous_temp"),
|
||||
)
|
||||
|
||||
@@ -297,11 +297,6 @@ class BOSMiner(BaseMiner):
|
||||
return False
|
||||
|
||||
async def get_config(self) -> MinerConfig:
|
||||
"""Gets the config for the miner and sets it as `self.config`.
|
||||
|
||||
Returns:
|
||||
The config from `self.config`.
|
||||
"""
|
||||
logging.debug(f"{self}: Getting config.")
|
||||
|
||||
try:
|
||||
@@ -316,7 +311,7 @@ class BOSMiner(BaseMiner):
|
||||
(await conn.run("cat /etc/bosminer.toml")).stdout
|
||||
)
|
||||
logging.debug(f"{self}: Converting config file.")
|
||||
cfg = MinerConfig.from_raw(toml_data)
|
||||
cfg = MinerConfig.from_bosminer(toml_data)
|
||||
self.config = cfg
|
||||
return self.config
|
||||
|
||||
|
||||
Reference in New Issue
Block a user