Merge pull request #110 from jpcomps/add_blockminer_support

ePIC: Add Blockminer support
This commit is contained in:
Brett Rowan
2024-02-21 13:21:45 -07:00
committed by GitHub
12 changed files with 134 additions and 38 deletions

View File

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

View File

@@ -0,0 +1,17 @@
# ------------------------------------------------------------------------------
# Copyright 2022 Upstream Data Inc -
# -
# Licensed under the Apache License, Version 2.0 (the "License"); -
# you may not use this file except in compliance with the License. -
# You may obtain a copy of the License at -
# -
# http://www.apache.org/licenses/LICENSE-2.0 -
# -
# Unless required by applicable law or agreed to in writing, software -
# distributed under the License is distributed on an "AS IS" BASIS, -
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
# See the License for the specific language governing permissions and -
# limitations under the License. -
# ------------------------------------------------------------------------------
from .epic import *

View File

@@ -0,0 +1,17 @@
# ------------------------------------------------------------------------------
# Copyright 2022 Upstream Data Inc -
# -
# Licensed under the Apache License, Version 2.0 (the "License"); -
# you may not use this file except in compliance with the License. -
# You may obtain a copy of the License at -
# -
# http://www.apache.org/licenses/LICENSE-2.0 -
# -
# Unless required by applicable law or agreed to in writing, software -
# distributed under the License is distributed on an "AS IS" BASIS, -
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
# See the License for the specific language governing permissions and -
# limitations under the License. -
# ------------------------------------------------------------------------------
from .blockminer import *

View File

@@ -0,0 +1,19 @@
# ------------------------------------------------------------------------------
# Copyright 2022 Upstream Data Inc -
# -
# Licensed under the Apache License, Version 2.0 (the "License"); -
# you may not use this file except in compliance with the License. -
# You may obtain a copy of the License at -
# -
# http://www.apache.org/licenses/LICENSE-2.0 -
# -
# Unless required by applicable law or agreed to in writing, software -
# distributed under the License is distributed on an "AS IS" BASIS, -
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
# See the License for the specific language governing permissions and -
# limitations under the License. -
# ------------------------------------------------------------------------------
from .blockminer import (
ePICBlockMiner520i,
)

View File

@@ -0,0 +1,22 @@
# ------------------------------------------------------------------------------
# Copyright 2022 Upstream Data Inc -
# -
# Licensed under the Apache License, Version 2.0 (the "License"); -
# you may not use this file except in compliance with the License. -
# You may obtain a copy of the License at -
# -
# http://www.apache.org/licenses/LICENSE-2.0 -
# -
# Unless required by applicable law or agreed to in writing, software -
# distributed under the License is distributed on an "AS IS" BASIS, -
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
# See the License for the specific language governing permissions and -
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners.backends import ePIC
from pyasic.miners.models import BlockMiner520i
class ePICBlockMiner520i(ePIC, BlockMiner520i):
pass

View File

@@ -29,6 +29,7 @@ from pyasic import settings
from pyasic.logger import logger
from pyasic.miners.antminer import *
from pyasic.miners.auradine import *
from pyasic.miners.blockminer import *
from pyasic.miners.avalonminer import *
from pyasic.miners.backends import (
Auradine,
@@ -396,6 +397,7 @@ MINER_CLASSES = {
"ANTMINER S19K PRO": ePICS19kPro,
"ANTMINER S19 XP": ePICS19XP,
"ANTMINER S21": ePICS21,
"BLOCKMINER 520I": ePICBlockMiner520i,
},
MinerTypes.HIVEON: {
None: Hiveon,
@@ -942,12 +944,16 @@ class MinerFactory:
pass
async def get_miner_model_epic(self, ip: str) -> str | None:
sock_json_data = await self.send_web_command(ip, ":4028/capabilities")
try:
miner_model = sock_json_data["Model"]
return miner_model
except (TypeError, LookupError):
pass
for retry_cnt in range(settings.get("get_data_retries", 1)):
sock_json_data = await self.send_web_command(ip, ":4028/capabilities")
try:
miner_model = sock_json_data["Model"]
return miner_model
except (TypeError, LookupError):
if retry_cnt < settings.get("get_data_retries", 1) - 1:
continue
else:
pass
async def get_miner_model_hiveon(self, ip: str) -> str | None:
sock_json_data = await self.send_api_command(ip, "version")

View File

@@ -39,3 +39,7 @@ class GoldshellMake(BaseMiner):
class AuradineMake(BaseMiner):
make = "Auradine"
class ePICMake(BaseMiner):
make = "ePIC"

View File

@@ -20,3 +20,4 @@ from .avalonminer import *
from .goldshell import *
from .innosilicon import *
from .whatsminer import *
from .epic import *

View File

@@ -0,0 +1 @@
from .blockminer import *

View File

@@ -0,0 +1 @@
from .blockminer import *

View File

@@ -0,0 +1,7 @@
from pyasic.miners.makes import ePICMake
class BlockMiner520i(ePICMake):
raw_model = "BlockMiner 520i"
expected_chips = 124
expected_fans = 4

View File

@@ -44,37 +44,40 @@ class ePICWebAPI(BaseWebAPI):
post = privileged or not parameters == {}
async with httpx.AsyncClient(transport=settings.transport()) as client:
try:
if post:
response = await client.post(
f"http://{self.ip}:{self.port}/{command}",
timeout=5,
json={
**parameters,
"password": self.pwd,
},
)
else:
response = await client.get(
f"http://{self.ip}:{self.port}/{command}",
timeout=5,
)
if not response.status_code == 200:
if not ignore_errors:
raise APIError(
f"Web command {command} failed with status code {response.status_code}"
for retry_cnt in range(settings.get("get_data_retries", 1)):
try:
if post:
response = await client.post(
f"http://{self.ip}:{self.port}/{command}",
timeout=5,
json={
**parameters,
"password": self.pwd,
},
)
return {}
json_data = response.json()
if json_data:
# The API can return a fail status if the miner cannot return the requested data. Catch this and pass
if not json_data.get("result", True) and not post:
else:
response = await client.get(
f"http://{self.ip}:{self.port}/{command}",
timeout=5,
)
if not response.status_code == 200:
if not ignore_errors:
raise APIError(json_data["error"])
return json_data
return {"success": True}
except (httpx.HTTPError, json.JSONDecodeError, AttributeError):
pass
raise APIError(
f"Web command {command} failed with status code {response.status_code}"
)
return {}
json_data = response.json()
if json_data:
# The API can return a fail status if the miner cannot return the requested data. Catch this and pass
if not json_data.get("result", True) and not post:
if retry_cnt < settings.get("get_data_retries", 1) - 1:
continue
if not ignore_errors:
raise APIError(json_data["error"])
return json_data
return {"success": True}
except (httpx.HTTPError, json.JSONDecodeError, AttributeError):
pass
async def multicommand(
self, *commands: str, ignore_errors: bool = False, allow_warning: bool = True