From ceab8e55b53f1ee80edc936dcf23e13263d7103f Mon Sep 17 00:00:00 2001 From: Upstream Data Date: Mon, 2 Dec 2024 08:59:58 -0700 Subject: [PATCH] feature: add send_config support for vnish --- pyasic/config/__init__.py | 15 ++++++++++++++- pyasic/config/fans.py | 27 +++++++++++++++++++++++++++ pyasic/config/mining/__init__.py | 9 +++++++++ pyasic/config/pools.py | 15 +++++++++++++++ pyasic/config/temperature.py | 12 +++++++++++- pyasic/miners/backends/vnish.py | 5 +++++ pyasic/web/vnish.py | 3 +++ 7 files changed, 84 insertions(+), 2 deletions(-) diff --git a/pyasic/config/__init__.py b/pyasic/config/__init__.py index 66f4336d..dc693080 100644 --- a/pyasic/config/__init__.py +++ b/pyasic/config/__init__.py @@ -16,7 +16,7 @@ from pydantic import BaseModel, Field -from pyasic.config.fans import FanMode, FanModeConfig +from pyasic.config.fans import FanMode, FanModeConfig, FanModeNormal from pyasic.config.mining import MiningMode, MiningModeConfig from pyasic.config.mining.scaling import ScalingConfig from pyasic.config.pools import PoolConfig @@ -159,6 +159,19 @@ class MinerConfig(BaseModel): **self.pools.as_luxos(user_suffix=user_suffix), } + def as_vnish(self, user_suffix: str = None) -> dict: + main_cfg = { + "miner": { + **self.fan_mode.as_vnish(), + **self.temperature.as_vnish(), + **self.mining_mode.as_vnish(), + **self.pools.as_vnish(user_suffix=user_suffix), + } + } + if isinstance(self.fan_mode, FanModeNormal): + main_cfg["miner"]["cooling"]["mode"]["param"] = self.temperature.target + return main_cfg + def as_hammer(self, *args, **kwargs) -> dict: return self.as_am_modern(*args, **kwargs) diff --git a/pyasic/config/fans.py b/pyasic/config/fans.py index 235a2b2c..90f463fe 100644 --- a/pyasic/config/fans.py +++ b/pyasic/config/fans.py @@ -87,6 +87,18 @@ class FanModeNormal(MinerConfigValue): def as_luxos(self) -> dict: return {"fanset": {"speed": -1, "min_fans": self.minimum_fans}} + def as_vnish(self) -> dict: + return { + "cooling": { + "fan_min_count": self.minimum_fans, + "fan_min_duty": self.minimum_speed, + "mode": { + "name": "auto", + "param": None, # Target temp, must be set later... + }, + } + } + class FanModeManual(MinerConfigValue): mode: str = Field(init=False, default="manual") @@ -150,6 +162,18 @@ class FanModeManual(MinerConfigValue): def as_luxos(self) -> dict: return {"fanset": {"speed": self.speed, "min_fans": self.minimum_fans}} + def as_vnish(self) -> dict: + return { + "cooling": { + "fan_min_count": self.minimum_fans, + "fan_min_duty": self.speed, + "mode": { + "name": "manual", + "param": self.speed, # Speed value + }, + } + } + class FanModeImmersion(MinerConfigValue): mode: str = Field(init=False, default="immersion") @@ -175,6 +199,9 @@ class FanModeImmersion(MinerConfigValue): def as_luxos(self) -> dict: return {"fanset": {"speed": 0, "min_fans": 0}} + def as_vnish(self) -> dict: + return {"cooling": {"mode": {"name": "immers"}}} + class FanModeConfig(MinerConfigOption): normal = FanModeNormal diff --git a/pyasic/config/mining/__init__.py b/pyasic/config/mining/__init__.py index 7dc197e6..6af37cf9 100644 --- a/pyasic/config/mining/__init__.py +++ b/pyasic/config/mining/__init__.py @@ -357,6 +357,9 @@ class ManualBoardSettings(MinerConfigValue): return {"miner-mode": "0"} return {"miner-mode": 0} + def as_vnish(self) -> dict: + return {"freq": self.freq} + class MiningModeManual(MinerConfigValue): mode: str = field(init=False, default="manual") @@ -378,6 +381,12 @@ class MiningModeManual(MinerConfigValue): return {"miner-mode": "0"} return {"miner-mode": 0} + def as_vnish(self) -> dict: + return { + "chains": [b.as_vnish() for b in self.boards.values()], + "globals": {"freq": self.global_freq, "volt": self.global_volt}, + } + @classmethod def from_vnish(cls, web_overclock_settings: dict) -> "MiningModeManual": # will raise KeyError if it cant find the settings, values cannot be empty diff --git a/pyasic/config/pools.py b/pyasic/config/pools.py index 68d3c7fc..94943b63 100644 --- a/pyasic/config/pools.py +++ b/pyasic/config/pools.py @@ -146,6 +146,15 @@ class Pool(MinerConfigValue): url=self.url, user=self.user, password=self.password, enabled=True ) + def as_vnish(self, user_suffix: str = None) -> dict: + 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} + @classmethod def from_dict(cls, dict_conf: dict | None) -> "Pool": return cls( @@ -338,6 +347,9 @@ class PoolGroup(MinerConfigValue): pools=[p.as_boser() for p in self.pools], ) + def as_vnish(self, user_suffix: str = None) -> dict: + return {"pools": [p.as_vnish(user_suffix=user_suffix) for p in self.pools]} + @classmethod def from_dict(cls, dict_conf: dict | None) -> "PoolGroup": cls_conf = {} @@ -530,6 +542,9 @@ class PoolConfig(MinerConfigValue): def as_luxos(self, user_suffix: str = None) -> dict: return {} + def as_vnish(self, user_suffix: str = None) -> dict: + return self.groups[0].as_vnish(user_suffix=user_suffix) + @classmethod def from_api(cls, api_pools: dict) -> "PoolConfig": try: diff --git a/pyasic/config/temperature.py b/pyasic/config/temperature.py index 94fec61e..d2085e87 100644 --- a/pyasic/config/temperature.py +++ b/pyasic/config/temperature.py @@ -56,6 +56,9 @@ class TemperatureConfig(MinerConfigValue): def as_luxos(self) -> dict: return {"tempctrlset": [self.target or "", self.hot or "", self.danger or ""]} + def as_vnish(self) -> dict: + return {"misc": {"restart_temp": self.danger}} + @classmethod def from_dict(cls, dict_conf: dict | None) -> "TemperatureConfig": return cls( @@ -95,9 +98,16 @@ class TemperatureConfig(MinerConfigValue): @classmethod def from_vnish(cls, web_settings: dict) -> "TemperatureConfig": + try: + dangerous_temp = web_settings["misc"]["restart_temp"] + except KeyError: + dangerous_temp = None try: if web_settings["miner"]["cooling"]["mode"]["name"] == "auto": - return cls(target=web_settings["miner"]["cooling"]["mode"]["param"]) + return cls( + target=web_settings["miner"]["cooling"]["mode"]["param"], + danger=dangerous_temp, + ) except KeyError: pass return cls() diff --git a/pyasic/miners/backends/vnish.py b/pyasic/miners/backends/vnish.py index 9dba49d1..b426aa95 100644 --- a/pyasic/miners/backends/vnish.py +++ b/pyasic/miners/backends/vnish.py @@ -98,6 +98,11 @@ class VNish(VNishFirmware, BMMiner): data_locations = VNISH_DATA_LOC + async def send_config(self, config: MinerConfig, user_suffix: str = None) -> None: + await self.web.post_settings( + miner_settings=config.as_vnish(user_suffix=user_suffix) + ) + async def restart_backend(self) -> bool: data = await self.web.restart_vnish() if data: diff --git a/pyasic/web/vnish.py b/pyasic/web/vnish.py index 32f08f8a..3333633e 100644 --- a/pyasic/web/vnish.py +++ b/pyasic/web/vnish.py @@ -143,3 +143,6 @@ class VNishWebAPI(BaseWebAPI): async def find_miner(self) -> dict: return await self.send_command("find-miner", privileged=True) + + async def post_settings(self, miner_settings: dict): + return await self.send_command("settings", post=True, **miner_settings)