add ePIC UMC S21 support, fix HB generation by using capabilities
This commit is contained in:
@@ -40,6 +40,7 @@ nav:
|
|||||||
- Antminer X15: "miners/antminer/X15.md"
|
- Antminer X15: "miners/antminer/X15.md"
|
||||||
- Antminer X17: "miners/antminer/X17.md"
|
- Antminer X17: "miners/antminer/X17.md"
|
||||||
- Antminer X19: "miners/antminer/X19.md"
|
- Antminer X19: "miners/antminer/X19.md"
|
||||||
|
- Antminer X21: "miners/antminer/X21.md"
|
||||||
- Avalon 7X: "miners/avalonminer/A7X.md"
|
- Avalon 7X: "miners/avalonminer/A7X.md"
|
||||||
- Avalon 8X: "miners/avalonminer/A8X.md"
|
- Avalon 8X: "miners/avalonminer/A8X.md"
|
||||||
- Avalon 9X: "miners/avalonminer/A9X.md"
|
- Avalon 9X: "miners/avalonminer/A9X.md"
|
||||||
|
|||||||
@@ -54,9 +54,9 @@ class FanModeNormal(MinerConfigValue):
|
|||||||
return {
|
return {
|
||||||
"fans": {
|
"fans": {
|
||||||
"Auto": {
|
"Auto": {
|
||||||
"Idle Speed": self.minimum_speed
|
"Idle Speed": (
|
||||||
if not self.minimum_speed == 0
|
self.minimum_speed if not self.minimum_speed == 0 else 100
|
||||||
else 100
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -327,9 +327,11 @@ class PoolGroup(MinerConfigValue):
|
|||||||
return cls(
|
return cls(
|
||||||
pools=[Pool.from_boser(p) for p in grpc_pool_group["pools"]],
|
pools=[Pool.from_boser(p) for p in grpc_pool_group["pools"]],
|
||||||
name=grpc_pool_group["name"],
|
name=grpc_pool_group["name"],
|
||||||
quota=grpc_pool_group["quota"]["value"]
|
quota=(
|
||||||
if grpc_pool_group.get("quota") is not None
|
grpc_pool_group["quota"]["value"]
|
||||||
else 1,
|
if grpc_pool_group.get("quota") is not None
|
||||||
|
else 1
|
||||||
|
),
|
||||||
)
|
)
|
||||||
except LookupError:
|
except LookupError:
|
||||||
return cls()
|
return cls()
|
||||||
|
|||||||
@@ -94,9 +94,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
|
||||||
|
|||||||
22
pyasic/miners/antminer/epic/X21/S21.py
Normal file
22
pyasic/miners/antminer/epic/X21/S21.py
Normal 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 S21
|
||||||
|
|
||||||
|
|
||||||
|
class ePICS21(ePIC, S21):
|
||||||
|
pass
|
||||||
19
pyasic/miners/antminer/epic/X21/__init__.py
Normal file
19
pyasic/miners/antminer/epic/X21/__init__.py
Normal 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 .S21 import (
|
||||||
|
ePICS21,
|
||||||
|
)
|
||||||
@@ -15,3 +15,4 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from .X19 import *
|
from .X19 import *
|
||||||
|
from .X21 import *
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ EPIC_DATA_LOC = DataLocations(
|
|||||||
"_get_hashboards",
|
"_get_hashboards",
|
||||||
[
|
[
|
||||||
WebAPICommand("web_summary", "summary"),
|
WebAPICommand("web_summary", "summary"),
|
||||||
WebAPICommand("web_hashrate", "hashrate"),
|
WebAPICommand("web_capabilities", "capabilities"),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
str(DataOptions.WATTAGE): DataFunction(
|
str(DataOptions.WATTAGE): DataFunction(
|
||||||
@@ -284,7 +284,7 @@ class ePIC(BaseMiner):
|
|||||||
return fans
|
return fans
|
||||||
|
|
||||||
async def _get_hashboards(
|
async def _get_hashboards(
|
||||||
self, web_summary: dict = None, web_hashrate: dict = None
|
self, web_summary: dict = None, web_capabilities: dict = None
|
||||||
) -> List[HashBoard]:
|
) -> List[HashBoard]:
|
||||||
if web_summary is None:
|
if web_summary is None:
|
||||||
try:
|
try:
|
||||||
@@ -292,28 +292,25 @@ class ePIC(BaseMiner):
|
|||||||
except APIError:
|
except APIError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if web_hashrate is not None:
|
if web_capabilities is not None:
|
||||||
try:
|
try:
|
||||||
web_hashrate = await self.web.hashrate()
|
web_capabilities = await self.web.capabilities()
|
||||||
except APIError:
|
except APIError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
hb_list = [
|
hb_list = [
|
||||||
HashBoard(slot=i, expected_chips=self.expected_chips)
|
HashBoard(slot=i, expected_chips=self.expected_chips)
|
||||||
for i in range(self.expected_hashboards)
|
for i in range(self.expected_hashboards)
|
||||||
]
|
]
|
||||||
|
|
||||||
if web_summary.get("HBs") is not None:
|
if web_summary.get("HBs") is not None:
|
||||||
for hb in web_summary["HBs"]:
|
for hb in web_summary["HBs"]:
|
||||||
for hr in web_hashrate:
|
num_of_chips = web_capabilities["Performance Estimator"]["Chip Count"]
|
||||||
if hr["Index"] == hb["Index"]:
|
hashrate = hb["Hashrate"][0]
|
||||||
num_of_chips = len(hr["Data"])
|
# Update the Hashboard object
|
||||||
hashrate = hb["Hashrate"][0]
|
hb_list[hb["Index"]].missing = False
|
||||||
# Update the Hashboard object
|
hb_list[hb["Index"]].hashrate = round(hashrate / 1000000, 2)
|
||||||
hb_list[hr["Index"]].expected_chips = num_of_chips
|
hb_list[hb["Index"]].chips = num_of_chips
|
||||||
hb_list[hr["Index"]].missing = False
|
hb_list[hb["Index"]].temp = hb["Temperature"]
|
||||||
hb_list[hr["Index"]].hashrate = round(hashrate / 1000000, 2)
|
|
||||||
hb_list[hr["Index"]].chips = num_of_chips
|
|
||||||
hb_list[hr["Index"]].temp = hb["Temperature"]
|
|
||||||
return hb_list
|
return hb_list
|
||||||
|
|
||||||
async def _is_mining(self, *args, **kwargs) -> Optional[bool]:
|
async def _is_mining(self, *args, **kwargs) -> Optional[bool]:
|
||||||
|
|||||||
@@ -461,9 +461,11 @@ class MinerProtocol(Protocol):
|
|||||||
ip=str(self.ip),
|
ip=str(self.ip),
|
||||||
make=self.make,
|
make=self.make,
|
||||||
model=self.model,
|
model=self.model,
|
||||||
expected_chips=self.expected_chips * self.expected_hashboards
|
expected_chips=(
|
||||||
if self.expected_chips is not None
|
self.expected_chips * self.expected_hashboards
|
||||||
else 0,
|
if self.expected_chips is not None
|
||||||
|
else 0
|
||||||
|
),
|
||||||
expected_hashboards=self.expected_hashboards,
|
expected_hashboards=self.expected_hashboards,
|
||||||
hashboards=[
|
hashboards=[
|
||||||
HashBoard(slot=i, expected_chips=self.expected_chips)
|
HashBoard(slot=i, expected_chips=self.expected_chips)
|
||||||
|
|||||||
@@ -392,6 +392,7 @@ MINER_CLASSES = {
|
|||||||
"ANTMINER S19J PRO+": ePICS19jProPlus,
|
"ANTMINER S19J PRO+": ePICS19jProPlus,
|
||||||
"ANTMINER S19K PRO": ePICS19kPro,
|
"ANTMINER S19K PRO": ePICS19kPro,
|
||||||
"ANTMINER S19 XP": ePICS19XP,
|
"ANTMINER S19 XP": ePICS19XP,
|
||||||
|
"ANTMINER S21": ePICS21,
|
||||||
},
|
},
|
||||||
MinerTypes.HIVEON: {
|
MinerTypes.HIVEON: {
|
||||||
None: Hiveon,
|
None: Hiveon,
|
||||||
|
|||||||
23
pyasic/miners/models/antminer/X21/S21.py
Normal file
23
pyasic/miners/models/antminer/X21/S21.py
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# 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.makes import AntMinerMake
|
||||||
|
|
||||||
|
|
||||||
|
class S21(AntMinerMake):
|
||||||
|
raw_model = "S21"
|
||||||
|
expected_chips = 108
|
||||||
|
expected_fans = 4
|
||||||
19
pyasic/miners/models/antminer/X21/__init__.py
Normal file
19
pyasic/miners/models/antminer/X21/__init__.py
Normal 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 .S21 import (
|
||||||
|
S21,
|
||||||
|
)
|
||||||
@@ -20,3 +20,4 @@ from .X9 import *
|
|||||||
from .X15 import *
|
from .X15 import *
|
||||||
from .X17 import *
|
from .X17 import *
|
||||||
from .X19 import *
|
from .X19 import *
|
||||||
|
from .X21 import *
|
||||||
|
|||||||
@@ -73,7 +73,9 @@ class BOSMinerWebAPI(BaseWebAPI):
|
|||||||
login = {"luci_username": self.username, "luci_password": self.pwd}
|
login = {"luci_username": self.username, "luci_password": self.pwd}
|
||||||
url = f"http://{self.ip}:{self.port}/cgi-bin/luci"
|
url = f"http://{self.ip}:{self.port}/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)
|
||||||
|
|||||||
Reference in New Issue
Block a user