Compare commits

...

11 Commits

Author SHA1 Message Date
Brett Rowan
b81276cb19 version: bump version number 2025-04-16 08:40:36 -06:00
Adrian
8dcc72b1bb T21 working on LuxOS (#331) 2025-04-14 12:55:54 -06:00
Timur Taipov
540572356f feature: add support for S21+ hydro (#326) 2025-04-14 09:15:06 -06:00
Ryan Heideman
83035a869b feature: Add Support for Avalon Nano 3s (#329) 2025-04-12 15:34:45 -06:00
Brett Rowan
4c104a59ff version: bump version number 2025-04-01 09:24:20 -06:00
Brett Rowan
e708ae3728 bug: remove MSKminer web identification 2025-04-01 09:23:51 -06:00
Wilfred Allyn
a4352816ee bug: pass atmset param as bool 2025-04-01 07:48:42 -06:00
Will Jackson
336bd9c002 bug: update set_dps configuration to handle optional power and hashrate parameters (#319)
* bug: update set_dps configuration to handle optional power and hashrate parameters
2025-03-27 11:09:47 -06:00
Wilfred Allyn
e3c917efde feature: set supports_autotuning True for luxminer 2025-03-26 08:06:38 -06:00
Brett Rowan
4d71012ed6 version: bump version number
Closes: #310
2025-03-20 10:46:30 -06:00
Will Jackson
1acdba8ae0 bug: fix set_dps configuration to handle power target parameters correctly (#318)
* bug: fix set_dps configuration to handle power target parameters correctly

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-03-20 10:45:48 -06:00
20 changed files with 177 additions and 35 deletions

View File

@@ -53,6 +53,19 @@
show_root_heading: false
heading_level: 0
## S21+ Hydro (Stock)
- [x] Shutdowns
- [x] Power Modes
- [ ] Setpoints
- [ ] Presets
::: pyasic.miners.antminer.bmminer.X21.S21.BMMinerS21PlusHydro
handler: python
options:
show_root_heading: false
heading_level: 0
## T21 (Stock)
- [x] Shutdowns
@@ -174,7 +187,7 @@
- [x] Shutdowns
- [ ] Power Modes
- [ ] Setpoints
- [x] Setpoints
- [x] Presets
::: pyasic.miners.antminer.luxos.X21.S21.LUXMinerS21
@@ -183,6 +196,19 @@
show_root_heading: false
heading_level: 0
## T21 (LuxOS)
- [x] Shutdowns
- [ ] Power Modes
- [x] Setpoints
- [x] Presets
::: pyasic.miners.antminer.luxos.X21.T21.LUXMinerT21
handler: python
options:
show_root_heading: false
heading_level: 0
## S21 (MaraFW)
- [ ] Shutdowns

View File

@@ -14,3 +14,16 @@
show_root_heading: false
heading_level: 0
## Avalon Nano 3s (Stock)
- [ ] Shutdowns
- [ ] Power Modes
- [ ] Setpoints
- [ ] Presets
::: pyasic.miners.avalonminer.cgminer.nano.nano3.CGMinerAvalonNano3s
handler: python
options:
show_root_heading: false
heading_level: 0

View File

@@ -104,6 +104,7 @@ details {
<li><a href="../antminer/X21#s21-stock">S21 (Stock)</a></li>
<li><a href="../antminer/X21#s21-stock">S21 (Stock)</a></li>
<li><a href="../antminer/X21#s21_1-stock">S21+ (Stock)</a></li>
<li><a href="../antminer/X21#s21_1-hydro-stock">S21+ Hydro (Stock)</a></li>
<li><a href="../antminer/X21#s21-pro-stock">S21 Pro (Stock)</a></li>
<li><a href="../antminer/X21#t21-stock">T21 (Stock)</a></li>
<li><a href="../antminer/X21#s21-hydro-stock">S21 Hydro (Stock)</a></li>
@@ -554,6 +555,9 @@ details {
<ul>
<li><a href="../avalonminer/nano#avalon-nano-3-stock">Avalon Nano 3 (Stock)</a></li>
</ul>
<ul>
<li><a href="../avalonminer/nano#avalon-nano-3s-stock">Avalon Nano 3s (Stock)</a></li>
</ul>
</details>
<details>
<summary>A15X Series:</summary>

View File

@@ -258,15 +258,16 @@ class MiningModePowerTune(MinerConfigValue):
sd_cfg = {}
if self.scaling.shutdown is not None:
sd_cfg = self.scaling.shutdown.as_boser()
power_target_kwargs = {}
if self.scaling.step is not None:
power_target_kwargs["power_step"] = Power(self.scaling.step)
if self.scaling.minimum is not None:
power_target_kwargs["min_power_target"] = Power(self.scaling.minimum)
cfg["set_dps"] = SetDpsRequest(
save_action=SaveAction.SAVE_AND_APPLY,
enable=True,
**sd_cfg,
target=DpsTarget(
power_target=DpsPowerTarget(
power_step=Power(self.scaling.step),
min_power_target=Power(self.scaling.minimum),
)
),
target=DpsTarget(power_target=DpsPowerTarget(**power_target_kwargs)),
)
return cfg
@@ -329,7 +330,6 @@ class MiningModeHashrateTune(MinerConfigValue):
conf["hashrate_target"] = self.hashrate
return {"autotuning": conf}
@property
def as_boser(self) -> dict:
cfg = {
"set_performance_mode": SetPerformanceModeRequest(
@@ -349,14 +349,21 @@ class MiningModeHashrateTune(MinerConfigValue):
sd_cfg = {}
if self.scaling.shutdown is not None:
sd_cfg = self.scaling.shutdown.as_boser()
hashrate_target_kwargs = {}
if self.scaling.step is not None:
hashrate_target_kwargs["hashrate_step"] = TeraHashrate(
self.scaling.step
)
if self.scaling.minimum is not None:
hashrate_target_kwargs["min_hashrate_target"] = TeraHashrate(
self.scaling.minimum
)
cfg["set_dps"] = SetDpsRequest(
save_action=SaveAction.SAVE_AND_APPLY,
enable=True,
**sd_cfg,
target=DpsTarget(
hashrate_target=DpsHashrateTarget(
hashrate_step=TeraHashrate(self.scaling.step),
min_hashrate_target=TeraHashrate(self.scaling.minimum),
)
hashrate_target=DpsHashrateTarget(**hashrate_target_kwargs)
),
)

View File

@@ -28,6 +28,8 @@ class HashBoard(BaseModel):
Attributes:
slot: The slot of the board as an int.
hashrate: The hashrate of the board in TH/s as a float.
inlet_temp: Inlet temperature for hydro asics as an int
outlet_temp: Outlet temperature for hydro asics as an int
temp: The temperature of the PCB as an int.
chip_temp: The temperature of the chips as an int.
chips: The chip count of the board as an int.
@@ -41,6 +43,8 @@ class HashBoard(BaseModel):
slot: int = 0
hashrate: AlgoHashRateType | None = None
inlet_temp: float | None = None
outlet_temp: float | None = None
temp: float | None = None
chip_temp: float | None = None
chips: int | None = None

View File

@@ -59,6 +59,7 @@ class AntminerModels(MinerModelType):
T19 = "T19"
S21 = "S21"
S21Plus = "S21+"
S21PlusHydro = "S21+ Hydro"
S21Pro = "S21 Pro"
S21Hydro = "S21 Hydro"
T21 = "T21"
@@ -451,6 +452,7 @@ class AvalonminerModels(MinerModelType):
Avalon1246 = "Avalon 1246"
Avalon1566 = "Avalon 1566"
AvalonNano3 = "Avalon Nano 3"
AvalonNano3s = "Avalon Nano 3s"
def __str__(self):
return self.value

View File

@@ -15,7 +15,7 @@
# ------------------------------------------------------------------------------
from pyasic.miners.backends import AntminerModern
from pyasic.miners.device.models import S21, S21Hydro, S21Plus, S21Pro
from pyasic.miners.device.models import S21, S21Hydro, S21Plus, S21PlusHydro, S21Pro
class BMMinerS21(AntminerModern, S21):
@@ -26,6 +26,10 @@ class BMMinerS21Plus(AntminerModern, S21Plus):
pass
class BMMinerS21PlusHydro(AntminerModern, S21PlusHydro):
pass
class BMMinerS21Pro(AntminerModern, S21Pro):
pass

View File

@@ -13,5 +13,11 @@
# See the License for the specific language governing permissions and -
# limitations under the License. -
# ------------------------------------------------------------------------------
from .S21 import BMMinerS21, BMMinerS21Hydro, BMMinerS21Plus, BMMinerS21Pro
from .S21 import (
BMMinerS21,
BMMinerS21Hydro,
BMMinerS21Plus,
BMMinerS21PlusHydro,
BMMinerS21Pro,
)
from .T21 import BMMinerT21

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 LUXMiner
from pyasic.miners.device.models import S21, T21
class LUXMinerT21(LUXMiner, T21):
pass

View File

@@ -15,3 +15,4 @@
# ------------------------------------------------------------------------------
from .S21 import LUXMinerS21
from .T21 import LUXMinerT21

View File

@@ -14,4 +14,4 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from .nano3 import CGMinerAvalonNano3
from .nano3 import CGMinerAvalonNano3, CGMinerAvalonNano3s

View File

@@ -24,7 +24,7 @@ from pyasic.miners.data import (
RPCAPICommand,
WebAPICommand,
)
from pyasic.miners.device.models import AvalonNano3
from pyasic.miners.device.models import AvalonNano3, AvalonNano3s
from pyasic.web.avalonminer import AvalonMinerWebAPI
AVALON_NANO_DATA_LOC = DataLocations(
@@ -105,3 +105,7 @@ class CGMinerAvalonNano3(AvalonMiner, AvalonNano3):
return mac.upper()
except (KeyError, ValueError):
pass
class CGMinerAvalonNano3s(AvalonMiner, AvalonNano3s):
pass

View File

@@ -272,18 +272,47 @@ class AntminerModern(BMMiner):
rate=board["rate_real"], unit=self.algo.unit.GH
).into(self.algo.unit.default)
hashboards[board["index"]].chips = board["asic_num"]
board_temp_data = list(
filter(lambda x: not x == 0, board["temp_pcb"])
)
hashboards[board["index"]].temp = sum(board_temp_data) / len(
board_temp_data
)
chip_temp_data = list(
filter(lambda x: not x == 0, board["temp_chip"])
)
hashboards[board["index"]].chip_temp = sum(chip_temp_data) / len(
chip_temp_data
)
if "S21+ Hyd" in self.model:
hashboards[board["index"]].inlet_temp = board["temp_pcb"][0]
hashboards[board["index"]].outlet_temp = board["temp_pcb"][2]
hashboards[board["index"]].chip_temp = board["temp_pic"][0]
board_temp_data = list(
filter(
lambda x: not x == 0,
[
board["temp_pic"][1],
board["temp_pic"][2],
board["temp_pic"][3],
board["temp_pcb"][1],
board["temp_pcb"][3],
],
)
)
hashboards[board["index"]].temp = (
sum(board_temp_data) / len(board_temp_data)
if len(board_temp_data) > 0
else 0
)
else:
board_temp_data = list(
filter(lambda x: not x == 0, board["temp_pcb"])
)
hashboards[board["index"]].temp = (
sum(board_temp_data) / len(board_temp_data)
if len(board_temp_data) > 0
else 0
)
chip_temp_data = list(
filter(lambda x: not x == 0, board["temp_chip"])
)
hashboards[board["index"]].chip_temp = (
sum(chip_temp_data) / len(chip_temp_data)
if len(chip_temp_data) > 0
else 0
)
hashboards[board["index"]].serial_number = board["sn"]
hashboards[board["index"]].missing = False
except LookupError:

View File

@@ -86,6 +86,7 @@ class LUXMiner(LuxOSFirmware):
supports_shutdown = True
supports_presets = True
supports_autotuning = True
data_locations = LUXMINER_DATA_LOC
@@ -191,10 +192,10 @@ class LUXMiner(LuxOSFirmware):
try:
if await self.atm_enabled():
re_enable_atm = True
await self.rpc.atmset("enabled=false")
await self.rpc.atmset(enabled=False)
result = await self.rpc.profileset(new_preset)
if re_enable_atm:
await self.rpc.atmset("enabled=true")
await self.rpc.atmset(enabled=True)
except APIError:
raise
except Exception as e:

View File

@@ -36,6 +36,15 @@ class S21Plus(AntMinerMake):
algo = MinerAlgo.SHA256
class S21PlusHydro(AntMinerMake):
raw_model = MinerModel.ANTMINER.S21PlusHydro
expected_chips = 95
expected_fans = 0
expected_hashboards = 3
algo = MinerAlgo.SHA256
class S21Pro(AntMinerMake):
raw_model = MinerModel.ANTMINER.S21Pro

View File

@@ -14,5 +14,5 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from .S21 import S21, S21Hydro, S21Plus, S21Pro
from .S21 import S21, S21Hydro, S21Plus, S21PlusHydro, S21Pro
from .T21 import T21

View File

@@ -1 +1 @@
from .nano3 import AvalonNano3
from .nano3 import AvalonNano3, AvalonNano3s

View File

@@ -10,3 +10,12 @@ class AvalonNano3(AvalonMinerMake):
expected_chips = 10
expected_fans = 1
algo = MinerAlgo.SHA256
class AvalonNano3s(AvalonMinerMake):
raw_model = MinerModel.AVALONMINER.AvalonNano3s
expected_hashboards = 1
expected_chips = 12
expected_fans = 1
algo = MinerAlgo.SHA256

View File

@@ -121,6 +121,7 @@ MINER_CLASSES = {
"ANTMINER BHB68601": BMMinerS21, # ???
"ANTMINER BHB68606": BMMinerS21, # ???
"ANTMINER S21+": BMMinerS21Plus,
"ANTMINER S21+ HYD.": BMMinerS21PlusHydro,
"ANTMINER S21 PRO": BMMinerS21Pro,
"ANTMINER T21": BMMinerT21,
"ANTMINER S21 HYD.": BMMinerS21Hydro,
@@ -506,6 +507,7 @@ MINER_CLASSES = {
"AVALONMINER 1166PRO": CGMinerAvalon1166Pro,
"AVALONMINER 1246": CGMinerAvalon1246,
"AVALONMINER NANO3": CGMinerAvalonNano3,
"AVALON NANO3S": CGMinerAvalonNano3s,
"AVALONMINER 15-194": CGMinerAvalon1566,
},
MinerTypes.INNOSILICON: {
@@ -621,6 +623,7 @@ MINER_CLASSES = {
"ANTMINER S19 XP": LUXMinerS19XP,
"ANTMINER T19": LUXMinerT19,
"ANTMINER S21": LUXMinerS21,
"ANTMINER T21": LUXMinerT21,
},
MinerTypes.AURADINE: {
None: type("AuradineUnknown", (Auradine, AuradineMake), {}),
@@ -879,8 +882,6 @@ class MinerFactory:
return MinerTypes.INNOSILICON
if "Miner UI" in web_text:
return MinerTypes.AURADINE
if "<title>Antminer</title>" in web_text:
return MinerTypes.MSKMINER
async def _get_miner_socket(self, ip: str) -> MinerTypes | None:
commands = ["version", "devdetails"]

View File

@@ -1,6 +1,6 @@
[project]
name = "pyasic"
version = "0.72.2"
version = "0.72.6"
description = "A simplified and standardized interface for Bitcoin ASICs."
authors = [{name = "UpstreamData", email = "brett@upstreamdata.ca"}]