From a76d1c6149dd693f9b98dbfe15a00eb2a249c1d7 Mon Sep 17 00:00:00 2001 From: John-Paul Compagnone Date: Sat, 10 Feb 2024 19:35:46 -0500 Subject: [PATCH] add ePIC UMC S21 support, fix HB generation by using capabilities --- mkdocs.yml | 1 + pyasic/config/fans.py | 6 ++--- pyasic/config/pools.py | 8 +++--- pyasic/data/__init__.py | 6 ++--- pyasic/miners/antminer/epic/X21/S21.py | 22 +++++++++++++++ pyasic/miners/antminer/epic/X21/__init__.py | 19 +++++++++++++ pyasic/miners/antminer/epic/__init__.py | 1 + pyasic/miners/backends/epic.py | 27 +++++++++---------- pyasic/miners/base.py | 8 +++--- pyasic/miners/factory.py | 1 + pyasic/miners/models/antminer/X21/S21.py | 23 ++++++++++++++++ pyasic/miners/models/antminer/X21/__init__.py | 19 +++++++++++++ pyasic/miners/models/antminer/__init__.py | 1 + pyasic/web/braiins_os/bosminer.py | 4 ++- 14 files changed, 118 insertions(+), 28 deletions(-) create mode 100644 pyasic/miners/antminer/epic/X21/S21.py create mode 100644 pyasic/miners/antminer/epic/X21/__init__.py create mode 100644 pyasic/miners/models/antminer/X21/S21.py create mode 100644 pyasic/miners/models/antminer/X21/__init__.py diff --git a/mkdocs.yml b/mkdocs.yml index db0155ae..72d3af82 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -40,6 +40,7 @@ nav: - Antminer X15: "miners/antminer/X15.md" - Antminer X17: "miners/antminer/X17.md" - Antminer X19: "miners/antminer/X19.md" + - Antminer X21: "miners/antminer/X21.md" - Avalon 7X: "miners/avalonminer/A7X.md" - Avalon 8X: "miners/avalonminer/A8X.md" - Avalon 9X: "miners/avalonminer/A9X.md" diff --git a/pyasic/config/fans.py b/pyasic/config/fans.py index f2d79526..520f9da9 100644 --- a/pyasic/config/fans.py +++ b/pyasic/config/fans.py @@ -54,9 +54,9 @@ class FanModeNormal(MinerConfigValue): return { "fans": { "Auto": { - "Idle Speed": self.minimum_speed - if not self.minimum_speed == 0 - else 100 + "Idle Speed": ( + self.minimum_speed if not self.minimum_speed == 0 else 100 + ) } } } diff --git a/pyasic/config/pools.py b/pyasic/config/pools.py index e84cc57a..a54b6186 100644 --- a/pyasic/config/pools.py +++ b/pyasic/config/pools.py @@ -327,9 +327,11 @@ class PoolGroup(MinerConfigValue): return cls( pools=[Pool.from_boser(p) for p in grpc_pool_group["pools"]], name=grpc_pool_group["name"], - quota=grpc_pool_group["quota"]["value"] - if grpc_pool_group.get("quota") is not None - else 1, + quota=( + grpc_pool_group["quota"]["value"] + if grpc_pool_group.get("quota") is not None + else 1 + ), ) except LookupError: return cls() diff --git a/pyasic/data/__init__.py b/pyasic/data/__init__.py index 835c28ea..eb6d1e4a 100644 --- a/pyasic/data/__init__.py +++ b/pyasic/data/__init__.py @@ -94,9 +94,9 @@ 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 diff --git a/pyasic/miners/antminer/epic/X21/S21.py b/pyasic/miners/antminer/epic/X21/S21.py new file mode 100644 index 00000000..02beaa1c --- /dev/null +++ b/pyasic/miners/antminer/epic/X21/S21.py @@ -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 diff --git a/pyasic/miners/antminer/epic/X21/__init__.py b/pyasic/miners/antminer/epic/X21/__init__.py new file mode 100644 index 00000000..8f17eb76 --- /dev/null +++ b/pyasic/miners/antminer/epic/X21/__init__.py @@ -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, +) diff --git a/pyasic/miners/antminer/epic/__init__.py b/pyasic/miners/antminer/epic/__init__.py index 36309a49..a30383b5 100644 --- a/pyasic/miners/antminer/epic/__init__.py +++ b/pyasic/miners/antminer/epic/__init__.py @@ -15,3 +15,4 @@ # ------------------------------------------------------------------------------ from .X19 import * +from .X21 import * diff --git a/pyasic/miners/backends/epic.py b/pyasic/miners/backends/epic.py index 23a396d2..e615a8c8 100644 --- a/pyasic/miners/backends/epic.py +++ b/pyasic/miners/backends/epic.py @@ -51,7 +51,7 @@ EPIC_DATA_LOC = DataLocations( "_get_hashboards", [ WebAPICommand("web_summary", "summary"), - WebAPICommand("web_hashrate", "hashrate"), + WebAPICommand("web_capabilities", "capabilities"), ], ), str(DataOptions.WATTAGE): DataFunction( @@ -284,7 +284,7 @@ class ePIC(BaseMiner): return fans async def _get_hashboards( - self, web_summary: dict = None, web_hashrate: dict = None + self, web_summary: dict = None, web_capabilities: dict = None ) -> List[HashBoard]: if web_summary is None: try: @@ -292,28 +292,25 @@ class ePIC(BaseMiner): except APIError: pass - if web_hashrate is not None: + if web_capabilities is not None: try: - web_hashrate = await self.web.hashrate() + web_capabilities = await self.web.capabilities() except APIError: pass + hb_list = [ HashBoard(slot=i, expected_chips=self.expected_chips) for i in range(self.expected_hashboards) ] - if web_summary.get("HBs") is not None: for hb in web_summary["HBs"]: - for hr in web_hashrate: - if hr["Index"] == hb["Index"]: - num_of_chips = len(hr["Data"]) - hashrate = hb["Hashrate"][0] - # Update the Hashboard object - hb_list[hr["Index"]].expected_chips = num_of_chips - hb_list[hr["Index"]].missing = False - hb_list[hr["Index"]].hashrate = round(hashrate / 1000000, 2) - hb_list[hr["Index"]].chips = num_of_chips - hb_list[hr["Index"]].temp = hb["Temperature"] + num_of_chips = web_capabilities["Performance Estimator"]["Chip Count"] + hashrate = hb["Hashrate"][0] + # Update the Hashboard object + hb_list[hb["Index"]].missing = False + hb_list[hb["Index"]].hashrate = round(hashrate / 1000000, 2) + hb_list[hb["Index"]].chips = num_of_chips + hb_list[hb["Index"]].temp = hb["Temperature"] return hb_list async def _is_mining(self, *args, **kwargs) -> Optional[bool]: diff --git a/pyasic/miners/base.py b/pyasic/miners/base.py index 224a05e9..4ce3ea71 100644 --- a/pyasic/miners/base.py +++ b/pyasic/miners/base.py @@ -461,9 +461,11 @@ class MinerProtocol(Protocol): ip=str(self.ip), make=self.make, model=self.model, - expected_chips=self.expected_chips * self.expected_hashboards - if self.expected_chips is not None - else 0, + expected_chips=( + self.expected_chips * self.expected_hashboards + if self.expected_chips is not None + else 0 + ), expected_hashboards=self.expected_hashboards, hashboards=[ HashBoard(slot=i, expected_chips=self.expected_chips) diff --git a/pyasic/miners/factory.py b/pyasic/miners/factory.py index 91fde5d6..810ea5f3 100644 --- a/pyasic/miners/factory.py +++ b/pyasic/miners/factory.py @@ -392,6 +392,7 @@ MINER_CLASSES = { "ANTMINER S19J PRO+": ePICS19jProPlus, "ANTMINER S19K PRO": ePICS19kPro, "ANTMINER S19 XP": ePICS19XP, + "ANTMINER S21": ePICS21, }, MinerTypes.HIVEON: { None: Hiveon, diff --git a/pyasic/miners/models/antminer/X21/S21.py b/pyasic/miners/models/antminer/X21/S21.py new file mode 100644 index 00000000..a6c53bc2 --- /dev/null +++ b/pyasic/miners/models/antminer/X21/S21.py @@ -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 diff --git a/pyasic/miners/models/antminer/X21/__init__.py b/pyasic/miners/models/antminer/X21/__init__.py new file mode 100644 index 00000000..dd7471cf --- /dev/null +++ b/pyasic/miners/models/antminer/X21/__init__.py @@ -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, +) diff --git a/pyasic/miners/models/antminer/__init__.py b/pyasic/miners/models/antminer/__init__.py index 67428e10..9701835d 100644 --- a/pyasic/miners/models/antminer/__init__.py +++ b/pyasic/miners/models/antminer/__init__.py @@ -20,3 +20,4 @@ from .X9 import * from .X15 import * from .X17 import * from .X19 import * +from .X21 import * diff --git a/pyasic/web/braiins_os/bosminer.py b/pyasic/web/braiins_os/bosminer.py index a0500602..9b64f6f6 100644 --- a/pyasic/web/braiins_os/bosminer.py +++ b/pyasic/web/braiins_os/bosminer.py @@ -73,7 +73,9 @@ class BOSMinerWebAPI(BaseWebAPI): login = {"luci_username": self.username, "luci_password": self.pwd} 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 + "User-Agent": ( + "BTC Tools v0.1" + ), # only seems to respond if this user-agent is set "Content-Type": "application/x-www-form-urlencoded", } await session.post(url, headers=headers, data=login)