Compare commits

..

12 Commits

Author SHA1 Message Date
Upstream Data
54f0292712 bug: try to fix scan timeout with asyncio.wait_for. 2024-05-13 08:28:12 -06:00
Upstream Data
46c56134f7 docs: update docs generation to fix marathon miners. 2024-04-29 09:14:08 -06:00
Upstream Data
1c1f7f1098 bug: move client into web ping to try to fix scanning failing. 2024-04-26 13:07:08 -06:00
Upstream Data
5c79c6cb0c bug: remove some excepts that were catching propagated cancellations. 2024-04-26 13:00:16 -06:00
Upstream Data
bab4261bed version: bump version number. 2024-04-24 10:39:34 -06:00
Upstream Data
e1d5c89388 bug: fix bad naming of S19J Pro Plus NOPIC. 2024-04-24 10:37:07 -06:00
Upstream Data
5f6c8cca18 docs: update docs. 2024-04-24 10:04:46 -06:00
Upstream Data
39db14b002 version: bump version number. 2024-04-24 10:04:13 -06:00
Upstream Data
3be04c678b feature: Add support for S19jPro+ No PIC. 2024-04-24 10:03:36 -06:00
Upstream Data
099ec35a8f version: bump version number. 2024-04-22 12:28:20 -06:00
Upstream Data
113dfb9170 bug: fix disabling fans when using immersion mode. 2024-04-22 12:27:44 -06:00
Abhishek Patidar
8d19e0ebbb Add tests in rpc_tests (#128) 2024-04-22 09:30:20 -06:00
12 changed files with 188 additions and 56 deletions

View File

@@ -47,8 +47,8 @@ def backend_str(backend: MinerTypes) -> str:
return "Stock Firmware Goldshells" return "Stock Firmware Goldshells"
case MinerTypes.LUX_OS: case MinerTypes.LUX_OS:
return "LuxOS Firmware Miners" return "LuxOS Firmware Miners"
case MinerTypes.EPIC: case MinerTypes.MARATHON:
return "ePIC Firmware Miners" return "Mara Firmware Miners"
def create_url_str(mtype: str): def create_url_str(mtype: str):

View File

@@ -176,8 +176,8 @@
show_root_heading: false show_root_heading: false
heading_level: 4 heading_level: 4
## S19j Pro ## S19j Pro No PIC
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19jPro ::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19jProNoPIC
handler: python handler: python
options: options:
show_root_heading: false show_root_heading: false
@@ -190,6 +190,20 @@
show_root_heading: false show_root_heading: false
heading_level: 4 heading_level: 4
## S19j Pro+
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19jProPlus
handler: python
options:
show_root_heading: false
heading_level: 4
## S19j Pro+ No PIC
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19jProPlusNoPIC
handler: python
options:
show_root_heading: false
heading_level: 4
## S19k Pro No PIC ## S19k Pro No PIC
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19kProNoPIC ::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19kProNoPIC
handler: python handler: python
@@ -365,3 +379,52 @@
show_root_heading: false show_root_heading: false
heading_level: 4 heading_level: 4
## S19 (MaraFW)
::: pyasic.miners.antminer.marathon.X19.S19.MaraS19
handler: python
options:
show_root_heading: false
heading_level: 4
## S19 Pro (MaraFW)
::: pyasic.miners.antminer.marathon.X19.S19.MaraS19Pro
handler: python
options:
show_root_heading: false
heading_level: 4
## S19j (MaraFW)
::: pyasic.miners.antminer.marathon.X19.S19.MaraS19j
handler: python
options:
show_root_heading: false
heading_level: 4
## S19j No PIC (MaraFW)
::: pyasic.miners.antminer.marathon.X19.S19.MaraS19jNoPIC
handler: python
options:
show_root_heading: false
heading_level: 4
## S19j Pro (MaraFW)
::: pyasic.miners.antminer.marathon.X19.S19.MaraS19jPro
handler: python
options:
show_root_heading: false
heading_level: 4
## S19 XP (MaraFW)
::: pyasic.miners.antminer.marathon.X19.S19.MaraS19XP
handler: python
options:
show_root_heading: false
heading_level: 4
## S19K Pro (MaraFW)
::: pyasic.miners.antminer.marathon.X19.S19.MaraS19KPro
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -8,6 +8,13 @@
show_root_heading: false show_root_heading: false
heading_level: 4 heading_level: 4
## T21
::: pyasic.miners.antminer.bmminer.X21.T21.BMMinerT21
handler: python
options:
show_root_heading: false
heading_level: 4
## S21 ## S21
::: pyasic.miners.antminer.bosminer.X21.S21.BOSMinerS21 ::: pyasic.miners.antminer.bosminer.X21.S21.BOSMinerS21
handler: python handler: python
@@ -22,6 +29,13 @@
show_root_heading: false show_root_heading: false
heading_level: 4 heading_level: 4
## T21 (ePIC)
::: pyasic.miners.antminer.epic.X21.T21.ePICT21
handler: python
options:
show_root_heading: false
heading_level: 4
## S21 (LuxOS) ## S21 (LuxOS)
::: pyasic.miners.antminer.luxos.X21.S21.LUXMinerS21 ::: pyasic.miners.antminer.luxos.X21.S21.LUXMinerS21
handler: python handler: python
@@ -29,3 +43,17 @@
show_root_heading: false show_root_heading: false
heading_level: 4 heading_level: 4
## S21 (MaraFW)
::: pyasic.miners.antminer.marathon.X21.S21.MaraS21
handler: python
options:
show_root_heading: false
heading_level: 4
## T21 (MaraFW)
::: pyasic.miners.antminer.marathon.X21.T21.MaraT21
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -89,6 +89,7 @@ details {
<summary>X21 Series:</summary> <summary>X21 Series:</summary>
<ul> <ul>
<li><a href="../antminer/X21#s21">S21</a></li> <li><a href="../antminer/X21#s21">S21</a></li>
<li><a href="../antminer/X21#t21">T21</a></li>
</ul> </ul>
</details> </details>
</ul> </ul>
@@ -453,8 +454,10 @@ details {
<li><a href="../antminer/X19#s19j">S19j</a></li> <li><a href="../antminer/X19#s19j">S19j</a></li>
<li><a href="../antminer/X19#s19j-no-pic">S19j No PIC</a></li> <li><a href="../antminer/X19#s19j-no-pic">S19j No PIC</a></li>
<li><a href="../antminer/X19#s19j-pro">S19j Pro</a></li> <li><a href="../antminer/X19#s19j-pro">S19j Pro</a></li>
<li><a href="../antminer/X19#s19j-pro">S19j Pro</a></li> <li><a href="../antminer/X19#s19j-pro-no-pic">S19j Pro No PIC</a></li>
<li><a href="../antminer/X19#s19j-pro_1">S19j Pro+</a></li> <li><a href="../antminer/X19#s19j-pro_1">S19j Pro+</a></li>
<li><a href="../antminer/X19#s19j-pro_1">S19j Pro+</a></li>
<li><a href="../antminer/X19#s19j-pro_1-no-pic">S19j Pro+ No PIC</a></li>
<li><a href="../antminer/X19#s19k-pro-no-pic">S19k Pro No PIC</a></li> <li><a href="../antminer/X19#s19k-pro-no-pic">S19k Pro No PIC</a></li>
<li><a href="../antminer/X19#s19-xp">S19 XP</a></li> <li><a href="../antminer/X19#s19-xp">S19 XP</a></li>
<li><a href="../antminer/X19#t19">T19</a></li> <li><a href="../antminer/X19#t19">T19</a></li>
@@ -525,12 +528,14 @@ details {
<summary>X21 Series:</summary> <summary>X21 Series:</summary>
<ul> <ul>
<li><a href="../antminer/X21#s21-epic">S21 (ePIC)</a></li> <li><a href="../antminer/X21#s21-epic">S21 (ePIC)</a></li>
<li><a href="../antminer/X21#t21-epic">T21 (ePIC)</a></li>
</ul> </ul>
</details> </details>
<details> <details>
<summary>blockminer Series:</summary> <summary>blockminer Series:</summary>
<ul> <ul>
<li><a href="../blockminer/blockminer#blockminer-520i-epic">BlockMiner 520i (ePIC)</a></li> <li><a href="../blockminer/blockminer#blockminer-520i-epic">BlockMiner 520i (ePIC)</a></li>
<li><a href="../blockminer/blockminer#blockminer-720i-epic">BlockMiner 720i (ePIC)</a></li>
</ul> </ul>
</details> </details>
</ul> </ul>
@@ -602,3 +607,27 @@ details {
</details> </details>
</ul> </ul>
</details> </details>
<details>
<summary>Mara Firmware Miners:</summary>
<ul>
<details>
<summary>X19 Series:</summary>
<ul>
<li><a href="../antminer/X19#s19-marafw">S19 (MaraFW)</a></li>
<li><a href="../antminer/X19#s19-pro-marafw">S19 Pro (MaraFW)</a></li>
<li><a href="../antminer/X19#s19j-marafw">S19j (MaraFW)</a></li>
<li><a href="../antminer/X19#s19j-no-pic-marafw">S19j No PIC (MaraFW)</a></li>
<li><a href="../antminer/X19#s19j-pro-marafw">S19j Pro (MaraFW)</a></li>
<li><a href="../antminer/X19#s19-xp-marafw">S19 XP (MaraFW)</a></li>
<li><a href="../antminer/X19#s19k-pro-marafw">S19K Pro (MaraFW)</a></li>
</ul>
</details>
<details>
<summary>X21 Series:</summary>
<ul>
<li><a href="../antminer/X21#s21-marafw">S21 (MaraFW)</a></li>
<li><a href="../antminer/X21#t21-marafw">T21 (MaraFW)</a></li>
</ul>
</details>
</ul>
</details>

View File

@@ -134,7 +134,6 @@ class FanModeImmersion(MinerConfigValue):
def as_bosminer(self) -> dict: def as_bosminer(self) -> dict:
return { return {
"temp_control": {"mode": "disabled"},
"fan_control": {"min_fans": 0}, "fan_control": {"min_fans": 0},
} }

View File

@@ -23,7 +23,9 @@ from pyasic.miners.models import (
S19j, S19j,
S19jNoPIC, S19jNoPIC,
S19jPro, S19jPro,
S19jProNoPIC,
S19jProPlus, S19jProPlus,
S19jProPlusNoPIC,
S19kProNoPIC, S19kProNoPIC,
S19Plus, S19Plus,
S19Pro, S19Pro,
@@ -58,6 +60,10 @@ class BOSMinerS19jPro(BOSer, S19jPro):
pass pass
class BOSMinerS19jProNoPIC(BOSer, S19jProNoPIC):
pass
class BOSMinerS19kProNoPIC(BOSer, S19kProNoPIC): class BOSMinerS19kProNoPIC(BOSer, S19kProNoPIC):
pass pass
@@ -70,5 +76,9 @@ class BOSMinerS19jProPlus(BOSer, S19jProPlus):
pass pass
class BOSMinerS19jProPlusNoPIC(BOSer, S19jProPlusNoPIC):
pass
class BOSMinerS19XP(BOSer, S19XP): class BOSMinerS19XP(BOSer, S19XP):
pass pass

View File

@@ -21,7 +21,9 @@ from .S19 import (
BOSMinerS19j, BOSMinerS19j,
BOSMinerS19jNoPIC, BOSMinerS19jNoPIC,
BOSMinerS19jPro, BOSMinerS19jPro,
BOSMinerS19jProNoPIC,
BOSMinerS19jProPlus, BOSMinerS19jProPlus,
BOSMinerS19jProPlusNoPIC,
BOSMinerS19kProNoPIC, BOSMinerS19kProNoPIC,
BOSMinerS19Plus, BOSMinerS19Plus,
BOSMinerS19Pro, BOSMinerS19Pro,

View File

@@ -359,8 +359,10 @@ MINER_CLASSES = {
"ANTMINER S19J": BOSMinerS19j, "ANTMINER S19J": BOSMinerS19j,
"ANTMINER S19J88NOPIC": BOSMinerS19jNoPIC, "ANTMINER S19J88NOPIC": BOSMinerS19jNoPIC,
"ANTMINER S19J PRO": BOSMinerS19jPro, "ANTMINER S19J PRO": BOSMinerS19jPro,
"ANTMINER S19J PRO NOPIC": BOSMinerS19jPro, "ANTMINER S19J PRO NOPIC": BOSMinerS19jProNoPIC,
"ANTMINER S19J PRO+": BOSMinerS19jProPlus, "ANTMINER S19J PRO+": BOSMinerS19jProPlus,
"ANTMINER S19J PRO PLUS": BOSMinerS19jProPlus,
"ANTMINER S19J PRO PLUS NOPIC": BOSMinerS19jProPlusNoPIC,
"ANTMINER S19K PRO NOPIC": BOSMinerS19kProNoPIC, "ANTMINER S19K PRO NOPIC": BOSMinerS19kProNoPIC,
"ANTMINER S19 XP": BOSMinerS19XP, "ANTMINER S19 XP": BOSMinerS19XP,
"ANTMINER T19": BOSMinerT19, "ANTMINER T19": BOSMinerT19,
@@ -539,37 +541,26 @@ class MinerFactory:
return await concurrent_get_first_result(tasks, lambda x: x is not None) return await concurrent_get_first_result(tasks, lambda x: x is not None)
async def _get_miner_web(self, ip: str) -> MinerTypes | None: async def _get_miner_web(self, ip: str) -> MinerTypes | None:
tasks = [] urls = [f"http://{ip}/", f"https://{ip}/"]
try: tasks = [asyncio.create_task(self._web_ping(url)) for url in urls]
urls = [f"http://{ip}/", f"https://{ip}/"]
async with httpx.AsyncClient(
transport=settings.transport(verify=False)
) as session:
tasks = [
asyncio.create_task(self._web_ping(session, url)) for url in urls
]
text, resp = await concurrent_get_first_result( text, resp = await concurrent_get_first_result(
tasks, tasks,
lambda x: x[0] is not None lambda x: x[0] is not None and self._parse_web_type(x[0], x[1]) is not None,
and self._parse_web_type(x[0], x[1]) is not None, )
) if text is not None:
if text is not None: return self._parse_web_type(text, resp)
return self._parse_web_type(text, resp)
except asyncio.CancelledError:
for t in tasks:
t.cancel()
try:
await t
except asyncio.CancelledError:
pass
@staticmethod @staticmethod
async def _web_ping( async def _web_ping(url: str) -> tuple[str | None, httpx.Response | None]:
session: httpx.AsyncClient, url: str
) -> tuple[str | None, httpx.Response | None]:
try: try:
resp = await session.get(url, follow_redirects=True) async with httpx.AsyncClient(
transport=settings.transport(verify=False)
) as c:
resp = await asyncio.wait_for(
c.get(url, follow_redirects=True),
settings.get("api_function_timeout", 5),
)
return resp.text, resp return resp.text, resp
except ( except (
httpx.HTTPError, httpx.HTTPError,
@@ -610,27 +601,16 @@ class MinerFactory:
return MinerTypes.AURADINE return MinerTypes.AURADINE
async def _get_miner_socket(self, ip: str) -> MinerTypes | None: async def _get_miner_socket(self, ip: str) -> MinerTypes | None:
tasks = [] commands = ["version", "devdetails"]
try: tasks = [asyncio.create_task(self._socket_ping(ip, cmd)) for cmd in commands]
commands = ["version", "devdetails"]
tasks = [
asyncio.create_task(self._socket_ping(ip, cmd)) for cmd in commands
]
data = await concurrent_get_first_result( data = await concurrent_get_first_result(
tasks, tasks,
lambda x: x is not None and self._parse_socket_type(x) is not None, lambda x: x is not None and self._parse_socket_type(x) is not None,
) )
if data is not None: if data is not None:
d = self._parse_socket_type(data) d = self._parse_socket_type(data)
return d return d
except asyncio.CancelledError:
for t in tasks:
t.cancel()
try:
await t
except asyncio.CancelledError:
pass
@staticmethod @staticmethod
async def _socket_ping(ip: str, cmd: str) -> str | None: async def _socket_ping(ip: str, cmd: str) -> str | None:

View File

@@ -89,12 +89,24 @@ class S19jPro(AntMinerMake):
expected_fans = 4 expected_fans = 4
class S19jProNoPIC(AntMinerMake):
raw_model = "S19j Pro No PIC"
expected_chips = 126
expected_fans = 4
class S19jProPlus(AntMinerMake): class S19jProPlus(AntMinerMake):
raw_model = "S19j Pro+" raw_model = "S19j Pro+"
expected_chips = 120 expected_chips = 120
expected_fans = 4 expected_fans = 4
class S19jProPlusNoPIC(AntMinerMake):
raw_model = "S19j Pro+ No PIC"
expected_chips = 120
expected_fans = 4
class S19kPro(AntMinerMake): class S19kPro(AntMinerMake):
raw_model = "S19k Pro" raw_model = "S19k Pro"
expected_chips = 77 expected_chips = 77

View File

@@ -25,8 +25,11 @@ from .S19 import (
S19j, S19j,
S19jNoPIC, S19jNoPIC,
S19jPro, S19jPro,
S19jProNoPIC,
S19jProPlus, S19jProPlus,
S19jProPlusNoPIC,
S19kPro, S19kPro,
S19KPro,
S19kProNoPIC, S19kProNoPIC,
S19NoPIC, S19NoPIC,
S19Plus, S19Plus,
@@ -34,6 +37,5 @@ from .S19 import (
S19ProHydro, S19ProHydro,
S19ProPlus, S19ProPlus,
S19ProPlusHydro, S19ProPlusHydro,
S19KPro,
) )
from .T19 import T19 from .T19 import T19

View File

@@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "pyasic" name = "pyasic"
version = "0.54.17" version = "0.54.20"
description = "A simplified and standardized interface for Bitcoin ASICs." description = "A simplified and standardized interface for Bitcoin ASICs."
authors = ["UpstreamData <brett@upstreamdata.ca>"] authors = ["UpstreamData <brett@upstreamdata.ca>"]
repository = "https://github.com/UpstreamData/pyasic" repository = "https://github.com/UpstreamData/pyasic"

View File

@@ -24,6 +24,7 @@ from pyasic.rpc.bmminer import BMMinerRPCAPI
from pyasic.rpc.bosminer import BOSMinerRPCAPI from pyasic.rpc.bosminer import BOSMinerRPCAPI
from pyasic.rpc.btminer import BTMinerRPCAPI from pyasic.rpc.btminer import BTMinerRPCAPI
from pyasic.rpc.cgminer import CGMinerRPCAPI from pyasic.rpc.cgminer import CGMinerRPCAPI
from pyasic.rpc.gcminer import GCMinerRPCAPI
from pyasic.rpc.luxminer import LUXMinerRPCAPI from pyasic.rpc.luxminer import LUXMinerRPCAPI
@@ -159,6 +160,12 @@ class TestCGMinerAPI(TestAPIBase):
self.api_str = "CGMiner" self.api_str = "CGMiner"
class TestGCMinerRPCAPI(TestAPIBase):
def setUpData(self):
self.api = GCMinerRPCAPI(self.ip)
self.api_str = "GCMiner"
class TestLuxOSAPI(TestAPIBase): class TestLuxOSAPI(TestAPIBase):
def setUpData(self): def setUpData(self):
self.api = LUXMinerRPCAPI(self.ip) self.api = LUXMinerRPCAPI(self.ip)