Merge pull request #84 from jpcomps/master

This commit is contained in:
b-rowan
2023-12-23 13:07:47 -07:00
committed by GitHub
10 changed files with 213 additions and 85 deletions

View File

@@ -161,6 +161,15 @@ class MinerConfig:
power_scaling=PowerScalingConfig.from_bosminer(toml_conf), power_scaling=PowerScalingConfig.from_bosminer(toml_conf),
) )
@classmethod
def from_epic(cls, web_conf: dict) -> "MinerConfig":
return cls(
pools=PoolConfig.from_epic(web_conf),
fan_mode=FanModeConfig.from_epic(web_conf),
temperature=TemperatureConfig.from_epic(web_conf),
mining_mode=MiningModeConfig.from_epic(web_conf),
)
def merge(a: dict, b: dict) -> dict: def merge(a: dict, b: dict) -> dict:
result = deepcopy(a) result = deepcopy(a)

View File

@@ -116,6 +116,17 @@ class FanModeConfig(MinerConfigOption):
else: else:
return cls.default() return cls.default()
@classmethod
def from_epic(cls, web_conf: dict):
try:
fan_mode = web_conf["Fans"]["Fan Mode"]
if fan_mode.get("Manual") is not None:
return cls.manual(speed=fan_mode.get("Manual"))
else:
return cls.normal()
except KeyError:
return cls.default()
@classmethod @classmethod
def from_bosminer(cls, toml_conf: dict): def from_bosminer(cls, toml_conf: dict):
if toml_conf.get("temp_control") is None: if toml_conf.get("temp_control") is None:

View File

@@ -186,6 +186,29 @@ class MiningModeConfig(MinerConfigOption):
return cls.low() return cls.low()
return cls.default() return cls.default()
@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"
]
)
else:
return cls.hashrate_tuning(
web_conf["PerpetualTune"]["Algorithm"]["ChipTune"]["Target"]
)
else:
return cls.normal()
except KeyError:
return cls.default()
@classmethod @classmethod
def from_bosminer(cls, toml_conf: dict): def from_bosminer(cls, toml_conf: dict):
if toml_conf.get("autotuning") is None: if toml_conf.get("autotuning") is None:

View File

@@ -108,6 +108,12 @@ class Pool(MinerConfigValue):
def from_api(cls, api_pool: dict) -> "Pool": def from_api(cls, api_pool: dict) -> "Pool":
return cls(url=api_pool["URL"], user=api_pool["User"], password="x") return cls(url=api_pool["URL"], user=api_pool["User"], password="x")
@classmethod
def from_epic(cls, api_pool: dict) -> "Pool":
return cls(
url=api_pool["pool"], user=api_pool["login"], password=api_pool["password"]
)
@classmethod @classmethod
def from_am_modern(cls, web_pool: dict) -> "Pool": def from_am_modern(cls, web_pool: dict) -> "Pool":
return cls( return cls(
@@ -237,6 +243,13 @@ class PoolGroup(MinerConfigValue):
pools.append(Pool.from_api(pool)) pools.append(Pool.from_api(pool))
return cls(pools=pools) return cls(pools=pools)
@classmethod
def from_epic(cls, api_pool_list: list) -> "PoolGroup":
pools = []
for pool in api_pool_list:
pools.append(Pool.from_epic(pool))
return cls(pools=pools)
@classmethod @classmethod
def from_am_modern(cls, web_pool_list: list) -> "PoolGroup": def from_am_modern(cls, web_pool_list: list) -> "PoolGroup":
pools = [] pools = []
@@ -334,6 +347,11 @@ class PoolConfig(MinerConfigValue):
return cls([PoolGroup.from_api(pool_data)]) return cls([PoolGroup.from_api(pool_data)])
@classmethod
def from_epic(cls, web_conf: dict) -> "PoolConfig":
pool_data = web_conf["StratumConfigs"]
return cls([PoolGroup.from_epic(pool_data)])
@classmethod @classmethod
def from_am_modern(cls, web_conf: dict) -> "PoolConfig": def from_am_modern(cls, web_conf: dict) -> "PoolConfig":
pool_data = web_conf["pools"] pool_data = web_conf["pools"]

View File

@@ -56,3 +56,18 @@ class TemperatureConfig(MinerConfigValue):
hot=temp_control.get("hot_temp"), hot=temp_control.get("hot_temp"),
danger=temp_control.get("dangerous_temp"), danger=temp_control.get("dangerous_temp"),
) )
@classmethod
def from_epic(cls, web_conf: dict) -> "TemperatureConfig":
dangerous_temp = None
try:
hot_temp = web_conf["Misc"]["Shutdown Temp"]
except KeyError:
hot_temp = None
# Need to do this in two blocks to avoid KeyError if one is missing
try:
target_temp = web_conf["Fans"]["Fan Mode"]["Auto"]["Target Temperature"]
except KeyError:
target_temp = None
return cls(target=target_temp, hot=hot_temp, danger=dangerous_temp)

View File

@@ -161,9 +161,9 @@ class MinerData:
percent_expected_wattage: float = field(init=False) percent_expected_wattage: float = field(init=False)
nominal: bool = field(init=False) nominal: bool = field(init=False)
config: MinerConfig = None config: MinerConfig = None
errors: List[ errors: List[Union[WhatsminerError, BraiinsOSError, X19Error, InnosiliconError]] = (
Union[WhatsminerError, BraiinsOSError, X19Error, InnosiliconError] field(default_factory=list)
] = field(default_factory=list) )
fault_light: Union[bool, None] = None fault_light: Union[bool, None] = None
efficiency: int = field(init=False) efficiency: int = field(init=False)
is_mining: bool = True is_mining: bool = True

View File

@@ -537,7 +537,7 @@ class BOSMiner(BaseMiner):
pass pass
try: try:
async with (await self._get_ssh_connection()) as conn: async with await self._get_ssh_connection() as conn:
if conn is not None: if conn is not None:
data = await conn.run("cat /proc/sys/kernel/hostname") data = await conn.run("cat /proc/sys/kernel/hostname")
host = data.stdout.strip() host = data.stdout.strip()

View File

@@ -18,6 +18,7 @@ from typing import List, Optional, Tuple, Union
from pyasic.data import Fan, HashBoard from pyasic.data import Fan, HashBoard
from pyasic.data.error_codes import MinerErrorData, X19Error from pyasic.data.error_codes import MinerErrorData, X19Error
from pyasic.config import MinerConfig, MiningModeConfig
from pyasic.errors import APIError from pyasic.errors import APIError
from pyasic.logger import logger from pyasic.logger import logger
from pyasic.miners.backends.bmminer import BMMiner from pyasic.miners.backends.bmminer import BMMiner
@@ -74,6 +75,23 @@ class ePIC(BMMiner):
return self.model + " (ePIC)" return self.model + " (ePIC)"
return "? (ePIC)" return "? (ePIC)"
async def get_config(self) -> MinerConfig:
summary = None
try:
summary = await self.web.summary()
except APIError as e:
logger.warning(e)
except LookupError:
pass
if summary is not None:
cfg = MinerConfig.from_epic(summary)
else:
cfg = MinerConfig()
self.config = cfg
return self.config
async def restart_backend(self) -> bool: async def restart_backend(self) -> bool:
data = await self.web.restart_epic() data = await self.web.restart_epic()
if data: if data:

View File

@@ -189,11 +189,13 @@ class BOSMinerGQLAPI:
await client.post( await client.post(
url, url,
json={ json={
"query": 'mutation{auth{login(username:"' "query": (
+ "root" 'mutation{auth{login(username:"'
+ '", password:"' + "root"
+ self.pwd + '", password:"'
+ '"){__typename}}}' + self.pwd
+ '"){__typename}}}'
)
}, },
) )
@@ -233,7 +235,9 @@ class BOSMinerLuCIAPI:
login = {"luci_username": self.username, "luci_password": self.pwd} login = {"luci_username": self.username, "luci_password": self.pwd}
url = f"http://{self.ip}/cgi-bin/luci" url = f"http://{self.ip}/cgi-bin/luci"
headers = { headers = {
"User-Agent": "BTC Tools v0.1", # only seems to respond if this user-agent is set "User-Agent": (
"BTC Tools v0.1"
), # only seems to respond if this user-agent is set
"Content-Type": "application/x-www-form-urlencoded", "Content-Type": "application/x-www-form-urlencoded",
} }
await session.post(url, headers=headers, data=login) await session.post(url, headers=headers, data=login)

View File

@@ -2357,17 +2357,21 @@ class ActionsServiceBase(ServiceBase):
RebootRequest, RebootRequest,
RebootResponse, RebootResponse,
), ),
"/braiins.bos.v1.ActionsService/SetLocateDeviceStatus": grpclib.const.Handler( "/braiins.bos.v1.ActionsService/SetLocateDeviceStatus": (
self.__rpc_set_locate_device_status, grpclib.const.Handler(
grpclib.const.Cardinality.UNARY_UNARY, self.__rpc_set_locate_device_status,
SetLocateDeviceStatusRequest, grpclib.const.Cardinality.UNARY_UNARY,
LocateDeviceStatusResponse, SetLocateDeviceStatusRequest,
LocateDeviceStatusResponse,
)
), ),
"/braiins.bos.v1.ActionsService/GetLocateDeviceStatus": grpclib.const.Handler( "/braiins.bos.v1.ActionsService/GetLocateDeviceStatus": (
self.__rpc_get_locate_device_status, grpclib.const.Handler(
grpclib.const.Cardinality.UNARY_UNARY, self.__rpc_get_locate_device_status,
GetLocateDeviceStatusRequest, grpclib.const.Cardinality.UNARY_UNARY,
LocateDeviceStatusResponse, GetLocateDeviceStatusRequest,
LocateDeviceStatusResponse,
)
), ),
} }
@@ -2644,17 +2648,21 @@ class PerformanceServiceBase(ServiceBase):
GetTunerStateRequest, GetTunerStateRequest,
GetTunerStateResponse, GetTunerStateResponse,
), ),
"/braiins.bos.v1.PerformanceService/ListTargetProfiles": grpclib.const.Handler( "/braiins.bos.v1.PerformanceService/ListTargetProfiles": (
self.__rpc_list_target_profiles, grpclib.const.Handler(
grpclib.const.Cardinality.UNARY_UNARY, self.__rpc_list_target_profiles,
ListTargetProfilesRequest, grpclib.const.Cardinality.UNARY_UNARY,
ListTargetProfilesResponse, ListTargetProfilesRequest,
ListTargetProfilesResponse,
)
), ),
"/braiins.bos.v1.PerformanceService/SetDefaultPowerTarget": grpclib.const.Handler( "/braiins.bos.v1.PerformanceService/SetDefaultPowerTarget": (
self.__rpc_set_default_power_target, grpclib.const.Handler(
grpclib.const.Cardinality.UNARY_UNARY, self.__rpc_set_default_power_target,
SetDefaultPowerTargetRequest, grpclib.const.Cardinality.UNARY_UNARY,
SetPowerTargetResponse, SetDefaultPowerTargetRequest,
SetPowerTargetResponse,
)
), ),
"/braiins.bos.v1.PerformanceService/SetPowerTarget": grpclib.const.Handler( "/braiins.bos.v1.PerformanceService/SetPowerTarget": grpclib.const.Handler(
self.__rpc_set_power_target, self.__rpc_set_power_target,
@@ -2662,41 +2670,53 @@ class PerformanceServiceBase(ServiceBase):
SetPowerTargetRequest, SetPowerTargetRequest,
SetPowerTargetResponse, SetPowerTargetResponse,
), ),
"/braiins.bos.v1.PerformanceService/IncrementPowerTarget": grpclib.const.Handler( "/braiins.bos.v1.PerformanceService/IncrementPowerTarget": (
self.__rpc_increment_power_target, grpclib.const.Handler(
grpclib.const.Cardinality.UNARY_UNARY, self.__rpc_increment_power_target,
IncrementPowerTargetRequest, grpclib.const.Cardinality.UNARY_UNARY,
SetPowerTargetResponse, IncrementPowerTargetRequest,
SetPowerTargetResponse,
)
), ),
"/braiins.bos.v1.PerformanceService/DecrementPowerTarget": grpclib.const.Handler( "/braiins.bos.v1.PerformanceService/DecrementPowerTarget": (
self.__rpc_decrement_power_target, grpclib.const.Handler(
grpclib.const.Cardinality.UNARY_UNARY, self.__rpc_decrement_power_target,
DecrementPowerTargetRequest, grpclib.const.Cardinality.UNARY_UNARY,
SetPowerTargetResponse, DecrementPowerTargetRequest,
SetPowerTargetResponse,
)
), ),
"/braiins.bos.v1.PerformanceService/SetDefaultHashrateTarget": grpclib.const.Handler( "/braiins.bos.v1.PerformanceService/SetDefaultHashrateTarget": (
self.__rpc_set_default_hashrate_target, grpclib.const.Handler(
grpclib.const.Cardinality.UNARY_UNARY, self.__rpc_set_default_hashrate_target,
SetDefaultHashrateTargetRequest, grpclib.const.Cardinality.UNARY_UNARY,
SetHashrateTargetResponse, SetDefaultHashrateTargetRequest,
SetHashrateTargetResponse,
)
), ),
"/braiins.bos.v1.PerformanceService/SetHashrateTarget": grpclib.const.Handler( "/braiins.bos.v1.PerformanceService/SetHashrateTarget": (
self.__rpc_set_hashrate_target, grpclib.const.Handler(
grpclib.const.Cardinality.UNARY_UNARY, self.__rpc_set_hashrate_target,
SetHashrateTargetRequest, grpclib.const.Cardinality.UNARY_UNARY,
SetHashrateTargetResponse, SetHashrateTargetRequest,
SetHashrateTargetResponse,
)
), ),
"/braiins.bos.v1.PerformanceService/IncrementHashrateTarget": grpclib.const.Handler( "/braiins.bos.v1.PerformanceService/IncrementHashrateTarget": (
self.__rpc_increment_hashrate_target, grpclib.const.Handler(
grpclib.const.Cardinality.UNARY_UNARY, self.__rpc_increment_hashrate_target,
IncrementHashrateTargetRequest, grpclib.const.Cardinality.UNARY_UNARY,
SetHashrateTargetResponse, IncrementHashrateTargetRequest,
SetHashrateTargetResponse,
)
), ),
"/braiins.bos.v1.PerformanceService/DecrementHashrateTarget": grpclib.const.Handler( "/braiins.bos.v1.PerformanceService/DecrementHashrateTarget": (
self.__rpc_decrement_hashrate_target, grpclib.const.Handler(
grpclib.const.Cardinality.UNARY_UNARY, self.__rpc_decrement_hashrate_target,
DecrementHashrateTargetRequest, grpclib.const.Cardinality.UNARY_UNARY,
SetHashrateTargetResponse, DecrementHashrateTargetRequest,
SetHashrateTargetResponse,
)
), ),
"/braiins.bos.v1.PerformanceService/SetDPS": grpclib.const.Handler( "/braiins.bos.v1.PerformanceService/SetDPS": grpclib.const.Handler(
self.__rpc_set_dps, self.__rpc_set_dps,
@@ -2704,23 +2724,29 @@ class PerformanceServiceBase(ServiceBase):
SetDpsRequest, SetDpsRequest,
SetDpsResponse, SetDpsResponse,
), ),
"/braiins.bos.v1.PerformanceService/SetPerformanceMode": grpclib.const.Handler( "/braiins.bos.v1.PerformanceService/SetPerformanceMode": (
self.__rpc_set_performance_mode, grpclib.const.Handler(
grpclib.const.Cardinality.UNARY_UNARY, self.__rpc_set_performance_mode,
SetPerformanceModeRequest, grpclib.const.Cardinality.UNARY_UNARY,
PerformanceMode, SetPerformanceModeRequest,
PerformanceMode,
)
), ),
"/braiins.bos.v1.PerformanceService/GetActivePerformanceMode": grpclib.const.Handler( "/braiins.bos.v1.PerformanceService/GetActivePerformanceMode": (
self.__rpc_get_active_performance_mode, grpclib.const.Handler(
grpclib.const.Cardinality.UNARY_UNARY, self.__rpc_get_active_performance_mode,
GetPerformanceModeRequest, grpclib.const.Cardinality.UNARY_UNARY,
PerformanceMode, GetPerformanceModeRequest,
PerformanceMode,
)
), ),
"/braiins.bos.v1.PerformanceService/RemoveTunedProfiles": grpclib.const.Handler( "/braiins.bos.v1.PerformanceService/RemoveTunedProfiles": (
self.__rpc_remove_tuned_profiles, grpclib.const.Handler(
grpclib.const.Cardinality.UNARY_UNARY, self.__rpc_remove_tuned_profiles,
RemoveTunedProfilesRequest, grpclib.const.Cardinality.UNARY_UNARY,
RemoveTunedProfilesResponse, RemoveTunedProfilesRequest,
RemoveTunedProfilesResponse,
)
), ),
} }
@@ -2836,17 +2862,21 @@ class ConfigurationServiceBase(ServiceBase):
def __mapping__(self) -> Dict[str, grpclib.const.Handler]: def __mapping__(self) -> Dict[str, grpclib.const.Handler]:
return { return {
"/braiins.bos.v1.ConfigurationService/GetMinerConfiguration": grpclib.const.Handler( "/braiins.bos.v1.ConfigurationService/GetMinerConfiguration": (
self.__rpc_get_miner_configuration, grpclib.const.Handler(
grpclib.const.Cardinality.UNARY_UNARY, self.__rpc_get_miner_configuration,
GetMinerConfigurationRequest, grpclib.const.Cardinality.UNARY_UNARY,
GetMinerConfigurationResponse, GetMinerConfigurationRequest,
GetMinerConfigurationResponse,
)
), ),
"/braiins.bos.v1.ConfigurationService/GetConstraints": grpclib.const.Handler( "/braiins.bos.v1.ConfigurationService/GetConstraints": (
self.__rpc_get_constraints, grpclib.const.Handler(
grpclib.const.Cardinality.UNARY_UNARY, self.__rpc_get_constraints,
GetConstraintsRequest, grpclib.const.Cardinality.UNARY_UNARY,
GetConstraintsResponse, GetConstraintsRequest,
GetConstraintsResponse,
)
), ),
} }