Add ePIC send_config and config.as_epic (#101)
* feature: Add epic send_config. * feature: remove UID from epic config. * feature: add default for temp configs in epic.
This commit is contained in:
@@ -110,10 +110,9 @@ class MinerConfig:
|
||||
|
||||
def as_epic(self, user_suffix: str = None) -> dict:
|
||||
return {
|
||||
**self.fan_mode.as_epic(),
|
||||
**self.temperature.as_epic(),
|
||||
**merge_dicts(self.fan_mode.as_epic(), self.temperature.as_epic()),
|
||||
**self.mining_mode.as_epic(),
|
||||
**self.pools.as_epic(),
|
||||
**self.pools.as_epic(user_suffix=user_suffix),
|
||||
**self.power_scaling.as_epic(),
|
||||
}
|
||||
|
||||
|
||||
@@ -50,6 +50,17 @@ class FanModeNormal(MinerConfigValue):
|
||||
def as_bosminer(self) -> dict:
|
||||
return {"temp_control": {"mode": "auto"}}
|
||||
|
||||
def as_epic(self) -> dict:
|
||||
return {
|
||||
"fans": {
|
||||
"Auto": {
|
||||
"Idle Speed": self.minimum_speed
|
||||
if not self.minimum_speed == 0
|
||||
else 100
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@dataclass
|
||||
class FanModeManual(MinerConfigValue):
|
||||
@@ -96,6 +107,9 @@ class FanModeManual(MinerConfigValue):
|
||||
def as_auradine(self) -> dict:
|
||||
return {"fan": {"percentage": self.speed}}
|
||||
|
||||
def as_epic(self) -> dict:
|
||||
return {"fans": {"Manual": {"speed": self.speed}}}
|
||||
|
||||
|
||||
@dataclass
|
||||
class FanModeImmersion(MinerConfigValue):
|
||||
|
||||
@@ -47,6 +47,9 @@ class MiningModeNormal(MinerConfigValue):
|
||||
def as_auradine(self) -> dict:
|
||||
return {"mode": {"mode": self.mode}}
|
||||
|
||||
def as_epic(self) -> dict:
|
||||
return {"ptune": {"enabled": False}}
|
||||
|
||||
|
||||
@dataclass
|
||||
class MiningModeSleep(MinerConfigValue):
|
||||
@@ -65,6 +68,9 @@ class MiningModeSleep(MinerConfigValue):
|
||||
def as_auradine(self) -> dict:
|
||||
return {"mode": {"sleep": "on"}}
|
||||
|
||||
def as_epic(self) -> dict:
|
||||
return {"ptune": {"algo": "Sleep", "target": 0}}
|
||||
|
||||
|
||||
@dataclass
|
||||
class MiningModeLPM(MinerConfigValue):
|
||||
@@ -102,14 +108,52 @@ class MiningModeHPM(MinerConfigValue):
|
||||
return {"mode": {"mode": "turbo"}}
|
||||
|
||||
|
||||
class StandardPowerTuneAlgo(MinerConfigValue):
|
||||
mode: str = field(init=False, default="standard")
|
||||
|
||||
def as_epic(self):
|
||||
return VOptPowerTuneAlgo().as_epic()
|
||||
|
||||
|
||||
class VOptPowerTuneAlgo(MinerConfigValue):
|
||||
mode: str = field(init=False, default="standard")
|
||||
|
||||
def as_epic(self):
|
||||
return "VoltageOptimizer"
|
||||
|
||||
|
||||
class ChipTunePowerTuneAlgo(MinerConfigValue):
|
||||
mode: str = field(init=False, default="standard")
|
||||
|
||||
def as_epic(self):
|
||||
return "ChipTune"
|
||||
|
||||
|
||||
class PowerTunerAlgo(MinerConfigOption):
|
||||
standard = StandardPowerTuneAlgo
|
||||
voltage_optimizer = VOptPowerTuneAlgo
|
||||
chip_tune = ChipTunePowerTuneAlgo
|
||||
|
||||
@classmethod
|
||||
def default(cls):
|
||||
return cls.standard()
|
||||
|
||||
|
||||
@dataclass
|
||||
class MiningModePowerTune(MinerConfigValue):
|
||||
mode: str = field(init=False, default="power_tuning")
|
||||
power: int = None
|
||||
algo: PowerTunerAlgo = PowerTunerAlgo.default()
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, dict_conf: dict | None) -> "MiningModePowerTune":
|
||||
return cls(dict_conf.get("power"))
|
||||
cls_conf = {}
|
||||
if dict_conf.get("power"):
|
||||
cls_conf["power"] = dict_conf["power"]
|
||||
if dict_conf.get("algo"):
|
||||
cls_conf["algo"] = dict_conf["algo"]
|
||||
|
||||
return cls(**cls_conf)
|
||||
|
||||
def as_am_modern(self) -> dict:
|
||||
return {"miner-mode": "0"}
|
||||
@@ -139,6 +183,9 @@ class MiningModePowerTune(MinerConfigValue):
|
||||
def as_auradine(self) -> dict:
|
||||
return {"mode": {"mode": "custom", "tune": "power", "power": self.power}}
|
||||
|
||||
def as_epic(self) -> dict:
|
||||
return {"ptune": {**self.algo.as_epic(), "target": self.power}}
|
||||
|
||||
|
||||
@dataclass
|
||||
class MiningModeHashrateTune(MinerConfigValue):
|
||||
@@ -262,20 +309,18 @@ class MiningModeConfig(MinerConfigOption):
|
||||
@classmethod
|
||||
def from_epic(cls, web_conf: dict):
|
||||
try:
|
||||
work_mode = web_conf["PerpetualTune"]["Running"]
|
||||
if work_mode:
|
||||
if (
|
||||
web_conf["PerpetualTune"]["Algorithm"].get("VoltageOptimizer")
|
||||
is not None
|
||||
):
|
||||
return cls.hashrate_tuning(
|
||||
web_conf["PerpetualTune"]["Algorithm"]["VoltageOptimizer"][
|
||||
"Target"
|
||||
]
|
||||
tuner_running = web_conf["PerpetualTune"]["Running"]
|
||||
if tuner_running:
|
||||
algo_info = web_conf["PerpetualTune"]["Algorithm"]
|
||||
if algo_info.get("VoltageOptimizer") is not None:
|
||||
return cls.power_tuning(
|
||||
power=algo_info["VoltageOptimizer"]["Target"],
|
||||
algo=PowerTunerAlgo.voltage_optimizer,
|
||||
)
|
||||
else:
|
||||
return cls.hashrate_tuning(
|
||||
web_conf["PerpetualTune"]["Algorithm"]["ChipTune"]["Target"]
|
||||
return cls.power_tuning(
|
||||
power=algo_info["ChipTune"]["Target"],
|
||||
algo=PowerTunerAlgo.chip_tune,
|
||||
)
|
||||
else:
|
||||
return cls.normal()
|
||||
|
||||
@@ -109,6 +109,15 @@ class Pool(MinerConfigValue):
|
||||
}
|
||||
return {"url": self.url, "user": self.user, "pass": self.password}
|
||||
|
||||
def as_epic(self, user_suffix: str = None):
|
||||
if user_suffix is not None:
|
||||
return {
|
||||
"pool": self.url,
|
||||
"login": f"{self.user}{user_suffix}",
|
||||
"password": self.password,
|
||||
}
|
||||
return {"pool": self.url, "login": self.user, "password": self.password}
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, dict_conf: dict | None) -> "Pool":
|
||||
return cls(
|
||||
@@ -255,6 +264,17 @@ class PoolGroup(MinerConfigValue):
|
||||
def as_auradine(self, user_suffix: str = None) -> list:
|
||||
return [p.as_auradine(user_suffix=user_suffix) for p in self.pools]
|
||||
|
||||
def as_epic(self, user_suffix: str = None) -> dict:
|
||||
if len(self.pools) > 0:
|
||||
conf = {
|
||||
"name": self.name,
|
||||
"pool": [pool.as_epic(user_suffix=user_suffix) for pool in self.pools],
|
||||
}
|
||||
if self.quota is not None:
|
||||
conf["quota"] = self.quota
|
||||
return conf
|
||||
return {"name": self.name, "pool": []}
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, dict_conf: dict | None) -> "PoolGroup":
|
||||
cls_conf = {}
|
||||
@@ -396,6 +416,25 @@ class PoolConfig(MinerConfigValue):
|
||||
}
|
||||
return {"updatepools": {"pools": PoolGroup().as_auradine()}}
|
||||
|
||||
def as_epic(self, user_suffix: str = None) -> dict:
|
||||
if len(self.groups) > 0:
|
||||
return {
|
||||
"pools": {
|
||||
"coin": "Btc",
|
||||
"stratum_configs": [
|
||||
g.as_epic(user_suffix=user_suffix) for g in self.groups
|
||||
],
|
||||
"unique_id": False,
|
||||
}
|
||||
}
|
||||
return {
|
||||
"pools": {
|
||||
"coin": "Btc",
|
||||
"stratum_configs": [PoolGroup().as_epic()],
|
||||
"unique_id": False,
|
||||
}
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def from_api(cls, api_pools: dict) -> "PoolConfig":
|
||||
try:
|
||||
|
||||
@@ -40,6 +40,16 @@ class TemperatureConfig(MinerConfigValue):
|
||||
temp_cfg["dangerous_temp"] = self.danger
|
||||
return {"temp_control": temp_cfg}
|
||||
|
||||
def as_epic(self) -> dict:
|
||||
temps_config = {"temps": {}, "fans": {"Auto": {}}}
|
||||
if self.target is not None:
|
||||
temps_config["fans"]["Target Temperature"] = self.target
|
||||
else:
|
||||
temps_config["fans"]["Target Temperature"] = 60
|
||||
if self.danger is not None:
|
||||
temps_config["temps"]["shutdown"] = self.danger
|
||||
return temps_config
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, dict_conf: dict | None) -> "TemperatureConfig":
|
||||
return cls(
|
||||
|
||||
@@ -107,6 +107,30 @@ class ePIC(BaseMiner):
|
||||
self.config = cfg
|
||||
return self.config
|
||||
|
||||
async def send_config(self, config: MinerConfig, user_suffix: str = None) -> None:
|
||||
self.config = config
|
||||
conf = self.config.as_epic(user_suffix=user_suffix)
|
||||
|
||||
try:
|
||||
# Temps
|
||||
if not conf.get("temps", {}) == {}:
|
||||
await self.web.set_shutdown_temp(conf["temps"]["shutdown"])
|
||||
# Fans
|
||||
if not conf["fans"].get("Manual", {}) == {}:
|
||||
await self.web.set_fan({"Manual": conf["fans"]["Manual"]})
|
||||
elif not conf["fans"].get("Auto", {}) == {}:
|
||||
await self.web.set_fan({"Auto": conf["fans"]["Auto"]})
|
||||
|
||||
# Mining Mode -- Need to handle that you may not be able to change while miner is tuning
|
||||
if conf["ptune"].get("enabled", True):
|
||||
await self.web.set_ptune_enable(True)
|
||||
await self.web.set_ptune_algo(**conf["ptune"])
|
||||
|
||||
## Pools
|
||||
await self.web.set_pools(conf["pools"])
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
async def restart_backend(self) -> bool:
|
||||
data = await self.web.restart_epic()
|
||||
if data:
|
||||
|
||||
@@ -24,7 +24,6 @@ from pyasic.data.error_codes import MinerErrorData
|
||||
from pyasic.errors import APIError
|
||||
from pyasic.logger import logger
|
||||
from pyasic.miners.data import DataLocations, DataOptions, RPCAPICommand, WebAPICommand
|
||||
from pyasic.rpc.base import BaseMinerRPCAPI
|
||||
|
||||
|
||||
class MinerProtocol(Protocol):
|
||||
|
||||
@@ -94,6 +94,21 @@ class ePICWebAPI(BaseWebAPI):
|
||||
async def reboot(self) -> dict:
|
||||
return await self.send_command("reboot", privileged=True)
|
||||
|
||||
async def set_shutdown_temp(self, params: int) -> dict:
|
||||
return await self.send_command("shutdowntemp", parameters=params)
|
||||
|
||||
async def set_fan(self, params: dict) -> dict:
|
||||
return await self.send_command("fanspeed", parameters=params)
|
||||
|
||||
async def set_ptune_enable(self, params: bool) -> dict:
|
||||
return await self.send_command("perpetualtune", parameters=params)
|
||||
|
||||
async def set_ptune_algo(self, params: dict) -> dict:
|
||||
return await self.send_command("perpetualtune/algo", parameters=params)
|
||||
|
||||
async def set_pools(self, params: dict) -> dict:
|
||||
return await self.send_command("coin", parameters=params)
|
||||
|
||||
async def pause_mining(self) -> dict:
|
||||
return await self.send_command("miner", param="Stop")
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ class TestConfig(unittest.TestCase):
|
||||
},
|
||||
"fan_mode": {"mode": "manual", "speed": 90, "minimum_fans": 2},
|
||||
"temperature": {"target": 70, "hot": None, "danger": 120},
|
||||
"mining_mode": {"mode": "power_tuning", "power": 3000},
|
||||
"mining_mode": {"mode": "power_tuning", "power": 3000, "algo": {}},
|
||||
"power_scaling": {
|
||||
"mode": "enabled",
|
||||
"power_step": 100,
|
||||
|
||||
Reference in New Issue
Block a user