refactor: fix merge.
This commit is contained in:
@@ -26,6 +26,7 @@ class BaseWebAPI(ABC):
|
||||
self.ip = ip # ipaddress.ip_address(ip)
|
||||
self.username = "root"
|
||||
self.pwd = "root"
|
||||
self.port = 80
|
||||
|
||||
def __new__(cls, *args, **kwargs):
|
||||
if cls is BaseWebAPI:
|
||||
|
||||
@@ -35,10 +35,12 @@ class AntminerModernWebAPI(BaseWebAPI):
|
||||
allow_warning: bool = True,
|
||||
**parameters: Union[str, int, bool],
|
||||
) -> dict:
|
||||
url = f"http://{self.ip}/cgi-bin/{command}.cgi"
|
||||
url = f"http://{self.ip}:{self.port}/cgi-bin/{command}.cgi"
|
||||
auth = httpx.DigestAuth(self.username, self.pwd)
|
||||
try:
|
||||
async with httpx.AsyncClient(transport=settings.transport()) as client:
|
||||
async with httpx.AsyncClient(
|
||||
transport=settings.transport(),
|
||||
) as client:
|
||||
if parameters:
|
||||
data = await client.post(
|
||||
url,
|
||||
@@ -149,7 +151,7 @@ class AntminerOldWebAPI(BaseWebAPI):
|
||||
allow_warning: bool = True,
|
||||
**parameters: Union[str, int, bool],
|
||||
) -> dict:
|
||||
url = f"http://{self.ip}/cgi-bin/{command}.cgi"
|
||||
url = f"http://{self.ip}:{self.port}/cgi-bin/{command}.cgi"
|
||||
auth = httpx.DigestAuth(self.username, self.pwd)
|
||||
try:
|
||||
async with httpx.AsyncClient(transport=settings.transport()) as client:
|
||||
|
||||
@@ -31,6 +31,7 @@ class BOSMinerWebAPI(BaseWebAPI):
|
||||
ip, settings.get("default_bosminer_password", "root")
|
||||
)
|
||||
self._pwd = settings.get("default_bosminer_password", "root")
|
||||
self._port = 80
|
||||
super().__init__(ip)
|
||||
|
||||
@property
|
||||
@@ -42,6 +43,15 @@ class BOSMinerWebAPI(BaseWebAPI):
|
||||
self._pwd = other
|
||||
self.luci.pwd = other
|
||||
|
||||
@property
|
||||
def port(self):
|
||||
return self._port
|
||||
|
||||
@port.setter
|
||||
def port(self, other: str):
|
||||
self._port = other
|
||||
self.luci.port = other
|
||||
|
||||
async def send_command(
|
||||
self,
|
||||
command: Union[str, dict],
|
||||
@@ -63,6 +73,7 @@ class BOSerWebAPI(BOSMinerWebAPI):
|
||||
ip, settings.get("default_bosminer_password", "root")
|
||||
)
|
||||
self.grpc = BOSerGRPCAPI(ip, settings.get("default_bosminer_password", "root"))
|
||||
self._port = 80
|
||||
super().__init__(ip)
|
||||
|
||||
@property
|
||||
@@ -76,6 +87,16 @@ class BOSerWebAPI(BOSMinerWebAPI):
|
||||
self.gql.pwd = other
|
||||
self.grpc.pwd = other
|
||||
|
||||
@property
|
||||
def port(self):
|
||||
return self._port
|
||||
|
||||
@port.setter
|
||||
def port(self, other: str):
|
||||
self._port = other
|
||||
self.luci.port = other
|
||||
self.gql.port = other
|
||||
|
||||
async def send_command(
|
||||
self,
|
||||
command: Union[str, dict],
|
||||
@@ -84,14 +105,14 @@ class BOSerWebAPI(BOSMinerWebAPI):
|
||||
**parameters: Union[str, int, bool],
|
||||
) -> dict:
|
||||
command_type = self.select_command_type(command)
|
||||
if command_type is "gql":
|
||||
if command_type == "gql":
|
||||
return await self.gql.send_command(command)
|
||||
elif command_type is "grpc":
|
||||
elif command_type == "grpc":
|
||||
try:
|
||||
return await (getattr(self.grpc, command.replace("grpc_", "")))()
|
||||
except AttributeError:
|
||||
raise APIError(f"No gRPC command found for command: {command}")
|
||||
elif command_type is "luci":
|
||||
elif command_type == "luci":
|
||||
return await self.luci.send_command(command)
|
||||
|
||||
@staticmethod
|
||||
|
||||
@@ -26,6 +26,7 @@ class BOSerGraphQLAPI:
|
||||
self.ip = ip
|
||||
self.username = "root"
|
||||
self.pwd = pwd
|
||||
self.port = 80
|
||||
|
||||
async def multicommand(self, *commands: dict) -> dict:
|
||||
def merge(*d: dict):
|
||||
@@ -60,7 +61,7 @@ class BOSerGraphQLAPI:
|
||||
self,
|
||||
command: dict,
|
||||
) -> dict:
|
||||
url = f"http://{self.ip}/graphql"
|
||||
url = f"http://{self.ip}:{self.port}/graphql"
|
||||
query = command
|
||||
if command is None:
|
||||
return {}
|
||||
@@ -93,7 +94,7 @@ class BOSerGraphQLAPI:
|
||||
return "{" + ",".join(data) + "}"
|
||||
|
||||
async def auth(self, client: httpx.AsyncClient) -> None:
|
||||
url = f"http://{self.ip}/graphql"
|
||||
url = f"http://{self.ip}:{self.port}/graphql"
|
||||
await client.post(
|
||||
url,
|
||||
json={
|
||||
|
||||
@@ -14,9 +14,11 @@
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
import asyncio
|
||||
import logging
|
||||
from datetime import timedelta
|
||||
|
||||
from betterproto import Message
|
||||
from grpclib import GRPCError, Status
|
||||
from grpclib.client import Channel
|
||||
|
||||
from pyasic.errors import APIError
|
||||
@@ -44,6 +46,7 @@ class BOSerGRPCAPI:
|
||||
self.ip = ip
|
||||
self.username = "root"
|
||||
self.pwd = pwd
|
||||
self.port = 50051
|
||||
self._auth = None
|
||||
self._auth_time = datetime.now()
|
||||
|
||||
@@ -90,13 +93,23 @@ class BOSerGRPCAPI:
|
||||
metadata = []
|
||||
if auth:
|
||||
metadata.append(("authorization", await self.auth()))
|
||||
async with Channel(self.ip, 50051) as c:
|
||||
endpoint = getattr(BOSMinerGRPCStub(c), command)
|
||||
if endpoint is None:
|
||||
if not ignore_errors:
|
||||
raise APIError(f"Command not found - {endpoint}")
|
||||
return {}
|
||||
return (await endpoint(message, metadata=metadata)).to_pydict()
|
||||
try:
|
||||
async with Channel(self.ip, self.port) as c:
|
||||
endpoint = getattr(BOSMinerGRPCStub(c), command)
|
||||
if endpoint is None:
|
||||
if not ignore_errors:
|
||||
raise APIError(f"Command not found - {endpoint}")
|
||||
return {}
|
||||
try:
|
||||
return (await endpoint(message, metadata=metadata)).to_pydict()
|
||||
except GRPCError as e:
|
||||
if e.status == Status.UNAUTHENTICATED:
|
||||
await self._get_auth()
|
||||
metadata = [("authorization", await self.auth())]
|
||||
return (await endpoint(message, metadata=metadata)).to_pydict()
|
||||
raise e
|
||||
except GRPCError as e:
|
||||
raise APIError(f"gRPC command failed - {endpoint}") from e
|
||||
|
||||
async def auth(self):
|
||||
if self._auth is not None and self._auth_time - datetime.now() < timedelta(
|
||||
@@ -107,7 +120,7 @@ class BOSerGRPCAPI:
|
||||
return self._auth
|
||||
|
||||
async def _get_auth(self):
|
||||
async with Channel(self.ip, 50051) as c:
|
||||
async with Channel(self.ip, self.port) as c:
|
||||
req = LoginRequest(username=self.username, password=self.pwd)
|
||||
async with c.request(
|
||||
"/braiins.bos.v1.AuthenticationService/Login",
|
||||
@@ -152,7 +165,9 @@ class BOSerGRPCAPI:
|
||||
)
|
||||
|
||||
async def get_locate_device_status(self):
|
||||
return await self.send_command("get_locate_device_status")
|
||||
return await self.send_command(
|
||||
"get_locate_device_status", GetLocateDeviceStatusRequest()
|
||||
)
|
||||
|
||||
async def set_password(self, password: str = None):
|
||||
return await self.send_command(
|
||||
@@ -281,16 +296,72 @@ class BOSerGRPCAPI:
|
||||
|
||||
async def set_dps(
|
||||
self,
|
||||
enable: bool,
|
||||
power_step: int,
|
||||
min_power_target: int,
|
||||
enable_shutdown: bool = None,
|
||||
shutdown_duration: int = None,
|
||||
):
|
||||
raise NotImplementedError
|
||||
return await self.send_command("braiins.bos.v1.PerformanceService/SetDPS")
|
||||
|
||||
async def set_performance_mode(self):
|
||||
raise NotImplementedError
|
||||
return await self.send_command(
|
||||
"braiins.bos.v1.PerformanceService/SetPerformanceMode"
|
||||
"set_dps",
|
||||
message=SetDpsRequest(
|
||||
enable=enable,
|
||||
enable_shutdown=enable_shutdown,
|
||||
shutdown_duration=shutdown_duration,
|
||||
target=DpsTarget(
|
||||
power_target=DpsPowerTarget(
|
||||
power_step=Power(power_step),
|
||||
min_power_target=Power(min_power_target),
|
||||
)
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
async def set_performance_mode(
|
||||
self,
|
||||
wattage_target: int = None,
|
||||
hashrate_target: int = None,
|
||||
save_action: SaveAction = SaveAction.SAVE_ACTION_SAVE_AND_APPLY,
|
||||
):
|
||||
if wattage_target is not None and hashrate_target is not None:
|
||||
logging.error(
|
||||
"Cannot use both wattage_target and hashrate_target, using wattage_target."
|
||||
)
|
||||
elif wattage_target is None and hashrate_target is None:
|
||||
raise APIError(
|
||||
"No target supplied, please supply either wattage_target or hashrate_target."
|
||||
)
|
||||
if wattage_target is not None:
|
||||
return await self.send_command(
|
||||
"set_performance_mode",
|
||||
message=SetPerformanceModeRequest(
|
||||
save_action=save_action,
|
||||
mode=PerformanceMode(
|
||||
tuner_mode=TunerPerformanceMode(
|
||||
power_target=PowerTargetMode(
|
||||
power_target=Power(watt=wattage_target)
|
||||
)
|
||||
)
|
||||
),
|
||||
),
|
||||
)
|
||||
if hashrate_target is not None:
|
||||
return await self.send_command(
|
||||
"set_performance_mode",
|
||||
message=SetPerformanceModeRequest(
|
||||
save_action=save_action,
|
||||
mode=PerformanceMode(
|
||||
tuner_mode=TunerPerformanceMode(
|
||||
hashrate_target=HashrateTargetMode(
|
||||
hashrate_target=TeraHashrate(
|
||||
terahash_per_second=hashrate_target
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
async def get_active_performance_mode(self):
|
||||
return await self.send_command(
|
||||
"get_active_performance_mode", GetPerformanceModeRequest()
|
||||
|
||||
@@ -26,6 +26,7 @@ class BOSMinerLuCIAPI:
|
||||
self.ip = ip
|
||||
self.username = "root"
|
||||
self.pwd = pwd
|
||||
self.port = 80
|
||||
|
||||
async def multicommand(self, *commands: str) -> dict:
|
||||
data = {}
|
||||
@@ -38,7 +39,7 @@ class BOSMinerLuCIAPI:
|
||||
async with httpx.AsyncClient(transport=settings.transport()) as client:
|
||||
await self.auth(client)
|
||||
data = await client.get(
|
||||
f"http://{self.ip}/cgi-bin/luci/{path}",
|
||||
f"http://{self.ip}:{self.port}/cgi-bin/luci/{path}",
|
||||
headers={"User-Agent": "BTC Tools v0.1"},
|
||||
)
|
||||
if data.status_code == 200:
|
||||
@@ -55,7 +56,7 @@ class BOSMinerLuCIAPI:
|
||||
|
||||
async def auth(self, session: httpx.AsyncClient):
|
||||
login = {"luci_username": self.username, "luci_password": self.pwd}
|
||||
url = f"http://{self.ip}/cgi-bin/luci"
|
||||
url = f"http://{self.ip}:{self.port}/cgi-bin/luci"
|
||||
headers = {
|
||||
"User-Agent": "BTC Tools v0.1", # only seems to respond if this user-agent is set
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
|
||||
@@ -29,6 +29,7 @@ class ePICWebAPI(BaseWebAPI):
|
||||
self.username = "root"
|
||||
self.pwd = settings.get("default_epic_password", "letmein")
|
||||
self.token = None
|
||||
self.port = 4028
|
||||
|
||||
async def send_command(
|
||||
self,
|
||||
@@ -50,13 +51,13 @@ class ePICWebAPI(BaseWebAPI):
|
||||
"password": self.pwd,
|
||||
}
|
||||
response = await client.post(
|
||||
f"http://{self.ip}:4028/{command}",
|
||||
f"http://{self.ip}:{self.port}/{command}",
|
||||
timeout=5,
|
||||
json=epic_param,
|
||||
)
|
||||
else:
|
||||
response = await client.get(
|
||||
f"http://{self.ip}:4028/{command}",
|
||||
f"http://{self.ip}:{self.port}/{command}",
|
||||
timeout=5,
|
||||
)
|
||||
if not response.status_code == 200:
|
||||
|
||||
@@ -33,10 +33,10 @@ class GoldshellWebAPI(BaseWebAPI):
|
||||
async def auth(self):
|
||||
async with httpx.AsyncClient(transport=settings.transport()) as client:
|
||||
try:
|
||||
await client.get(f"http://{self.ip}/user/logout")
|
||||
await client.get(f"http://{self.ip}:{self.port}/user/logout")
|
||||
auth = (
|
||||
await client.get(
|
||||
f"http://{self.ip}/user/login?username={self.username}&password={self.pwd}&cipher=false"
|
||||
f"http://{self.ip}:{self.port}/user/login?username={self.username}&password={self.pwd}&cipher=false"
|
||||
)
|
||||
).json()
|
||||
except httpx.HTTPError:
|
||||
@@ -46,7 +46,7 @@ class GoldshellWebAPI(BaseWebAPI):
|
||||
try:
|
||||
auth = (
|
||||
await client.get(
|
||||
f"http://{self.ip}/user/login?username=admin&password=bbad7537f4c8b6ea31eea0b3d760e257&cipher=true"
|
||||
f"http://{self.ip}:{self.port}/user/login?username=admin&password=bbad7537f4c8b6ea31eea0b3d760e257&cipher=true"
|
||||
)
|
||||
).json()
|
||||
except (httpx.HTTPError, json.JSONDecodeError):
|
||||
@@ -76,14 +76,14 @@ class GoldshellWebAPI(BaseWebAPI):
|
||||
try:
|
||||
if parameters:
|
||||
response = await client.put(
|
||||
f"http://{self.ip}/mcb/{command}",
|
||||
f"http://{self.ip}:{self.port}/mcb/{command}",
|
||||
headers={"Authorization": "Bearer " + self.jwt},
|
||||
timeout=settings.get("api_function_timeout", 5),
|
||||
json=parameters,
|
||||
)
|
||||
else:
|
||||
response = await client.get(
|
||||
f"http://{self.ip}/mcb/{command}",
|
||||
f"http://{self.ip}:{self.port}/mcb/{command}",
|
||||
headers={"Authorization": "Bearer " + self.jwt},
|
||||
timeout=settings.get("api_function_timeout", 5),
|
||||
)
|
||||
@@ -106,7 +106,7 @@ class GoldshellWebAPI(BaseWebAPI):
|
||||
for command in commands:
|
||||
try:
|
||||
response = await client.get(
|
||||
f"http://{self.ip}/mcb/{command}",
|
||||
f"http://{self.ip}:{self.port}/mcb/{command}",
|
||||
headers={"Authorization": "Bearer " + self.jwt},
|
||||
timeout=settings.get("api_function_timeout", 5),
|
||||
)
|
||||
|
||||
@@ -35,7 +35,7 @@ class InnosiliconWebAPI(BaseWebAPI):
|
||||
async with httpx.AsyncClient(transport=settings.transport()) as client:
|
||||
try:
|
||||
auth = await client.post(
|
||||
f"http://{self.ip}/api/auth",
|
||||
f"http://{self.ip}:{self.port}/api/auth",
|
||||
data={"username": self.username, "password": self.pwd},
|
||||
)
|
||||
except httpx.HTTPError:
|
||||
@@ -58,7 +58,7 @@ class InnosiliconWebAPI(BaseWebAPI):
|
||||
for i in range(settings.get("get_data_retries", 1)):
|
||||
try:
|
||||
response = await client.post(
|
||||
f"http://{self.ip}/api/{command}",
|
||||
f"http://{self.ip}:{self.port}/api/{command}",
|
||||
headers={"Authorization": "Bearer " + self.jwt},
|
||||
timeout=settings.get("api_function_timeout", 5),
|
||||
json=parameters,
|
||||
@@ -94,7 +94,7 @@ class InnosiliconWebAPI(BaseWebAPI):
|
||||
for command in commands:
|
||||
try:
|
||||
response = await client.post(
|
||||
f"http://{self.ip}/api/{command}",
|
||||
f"http://{self.ip}:{self.port}/api/{command}",
|
||||
headers={"Authorization": "Bearer " + self.jwt},
|
||||
timeout=settings.get("api_function_timeout", 5),
|
||||
)
|
||||
|
||||
@@ -34,7 +34,7 @@ class VNishWebAPI(BaseWebAPI):
|
||||
async with httpx.AsyncClient(transport=settings.transport()) as client:
|
||||
try:
|
||||
auth = await client.post(
|
||||
f"http://{self.ip}/api/v1/unlock",
|
||||
f"http://{self.ip}:{self.port}/api/v1/unlock",
|
||||
json={"pw": self.pwd},
|
||||
)
|
||||
except httpx.HTTPError:
|
||||
@@ -68,21 +68,21 @@ class VNishWebAPI(BaseWebAPI):
|
||||
if parameters.get("post"):
|
||||
parameters.pop("post")
|
||||
response = await client.post(
|
||||
f"http://{self.ip}/api/v1/{command}",
|
||||
f"http://{self.ip}:{self.port}/api/v1/{command}",
|
||||
headers={"Authorization": auth},
|
||||
timeout=settings.get("api_function_timeout", 5),
|
||||
json=parameters,
|
||||
)
|
||||
elif not parameters == {}:
|
||||
response = await client.post(
|
||||
f"http://{self.ip}/api/v1/{command}",
|
||||
f"http://{self.ip}:{self.port}/api/v1/{command}",
|
||||
headers={"Authorization": auth},
|
||||
timeout=settings.get("api_function_timeout", 5),
|
||||
json=parameters,
|
||||
)
|
||||
else:
|
||||
response = await client.get(
|
||||
f"http://{self.ip}/api/v1/{command}",
|
||||
f"http://{self.ip}:{self.port}/api/v1/{command}",
|
||||
headers={"Authorization": auth},
|
||||
timeout=settings.get("api_function_timeout", 5),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user