Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dcf37481bd | ||
|
|
1a9cca84d5 | ||
|
|
c5272d67de | ||
|
|
3bcfb14177 | ||
|
|
566280f280 | ||
|
|
a814f7eefb | ||
|
|
097b8ed534 | ||
|
|
da47d72749 | ||
|
|
abd4d18a01 |
@@ -46,7 +46,7 @@ from pyasic.network import MinerNetwork
|
|||||||
async def scan_and_get_data():
|
async def scan_and_get_data():
|
||||||
# Define network range to be used for scanning
|
# Define network range to be used for scanning
|
||||||
# This can take a list of IPs, a constructor string, or an IP and subnet mask
|
# This can take a list of IPs, a constructor string, or an IP and subnet mask
|
||||||
# The standard mask is /24, and you can pass any IP address in the subnet
|
# The standard mask is /24 (x.x.x.0-255), and you can pass any IP address in the subnet
|
||||||
net = MinerNetwork("192.168.1.69", mask=24)
|
net = MinerNetwork("192.168.1.69", mask=24)
|
||||||
# Scan the network for miners
|
# Scan the network for miners
|
||||||
# This function returns a list of miners of the correct type as a class
|
# This function returns a list of miners of the correct type as a class
|
||||||
@@ -93,6 +93,10 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
If needed, this library exposes a wrapper for the miner API that can be used for advanced data gathering.
|
If needed, this library exposes a wrapper for the miner API that can be used for advanced data gathering.
|
||||||
|
|
||||||
|
You can see more information on basic usage of the APIs past this example in the docs [here](https://pyasic.readthedocs.io/en/latest/API/api/).
|
||||||
|
|
||||||
|
Please see the appropriate API documentation page (pyasic docs -> Advanced -> Miner APIs -> your API type) for a link to that specific miner's API documentation page and more information.
|
||||||
|
|
||||||
#### List available API commands
|
#### List available API commands
|
||||||
```python
|
```python
|
||||||
import asyncio
|
import asyncio
|
||||||
@@ -105,7 +109,8 @@ async def get_api_commands(miner_ip: str):
|
|||||||
miner = await get_miner(miner_ip)
|
miner = await get_miner(miner_ip)
|
||||||
|
|
||||||
# List all available commands
|
# List all available commands
|
||||||
print(miner.api.get_commands())
|
# Can also be called explicitly with the function miner.api.get_commands()
|
||||||
|
print(miner.api.commands)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -90,6 +90,9 @@ details {
|
|||||||
</details>
|
</details>
|
||||||
<details>
|
<details>
|
||||||
<summary><a href="../whatsminer/M3X/#m31s">M31S</a></summary>
|
<summary><a href="../whatsminer/M3X/#m31s">M31S</a></summary>
|
||||||
|
<summary><a href="../whatsminer/M3X/#m31sv10">M31SV10</a></summary>
|
||||||
|
<summary><a href="../whatsminer/M3X/#m31sv20">M31SV20</a></summary>
|
||||||
|
<summary><a href="../whatsminer/M3X/#m31sv60">M31SV60</a></summary>
|
||||||
<summary><a href="../whatsminer/M3X/#m31sv70">M31SV70</a></summary>
|
<summary><a href="../whatsminer/M3X/#m31sv70">M31SV70</a></summary>
|
||||||
</details>
|
</details>
|
||||||
<details>
|
<details>
|
||||||
|
|||||||
@@ -114,9 +114,33 @@
|
|||||||
show_root_heading: false
|
show_root_heading: false
|
||||||
heading_level: 4
|
heading_level: 4
|
||||||
|
|
||||||
|
## M31SV10
|
||||||
|
|
||||||
|
::: pyasic.miners.whatsminer.btminer.M3X.M31S.BTMinerM31SV10
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
## M31SV20
|
||||||
|
|
||||||
|
::: pyasic.miners.whatsminer.btminer.M3X.M31S.BTMinerM31SV20
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
|
## M31SV60
|
||||||
|
|
||||||
|
::: pyasic.miners.whatsminer.btminer.M3X.M31S.BTMinerM31SV60
|
||||||
|
handler: python
|
||||||
|
options:
|
||||||
|
show_root_heading: false
|
||||||
|
heading_level: 4
|
||||||
|
|
||||||
## M31SV70
|
## M31SV70
|
||||||
|
|
||||||
::: pyasic.miners.whatsminer.btminer.M3X.M31S.BTMinerM31S
|
::: pyasic.miners.whatsminer.btminer.M3X.M31S.BTMinerM31SV70
|
||||||
handler: python
|
handler: python
|
||||||
options:
|
options:
|
||||||
show_root_heading: false
|
show_root_heading: false
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ from pyasic.errors import APIError
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
from pyasic.settings import PyasicSettings
|
from pyasic.settings import PyasicSettings
|
||||||
|
|
||||||
|
#TODO: Fix quota splitting in get data
|
||||||
class BOSMiner(BaseMiner):
|
class BOSMiner(BaseMiner):
|
||||||
def __init__(self, ip: str) -> None:
|
def __init__(self, ip: str) -> None:
|
||||||
super().__init__(ip)
|
super().__init__(ip)
|
||||||
@@ -471,6 +471,12 @@ class BOSMiner(BaseMiner):
|
|||||||
data.pool_2_user = pool_2_user
|
data.pool_2_user = pool_2_user
|
||||||
|
|
||||||
if quota:
|
if quota:
|
||||||
|
if not quota == "0":
|
||||||
|
cfg = await self.get_config()
|
||||||
|
if cfg:
|
||||||
|
if len(cfg.pool_groups) > 1:
|
||||||
|
quota = str(cfg.pool_groups[0].quota) + "/" + str(cfg.pool_groups[1].quota)
|
||||||
|
|
||||||
data.pool_split = str(quota)
|
data.pool_split = str(quota)
|
||||||
|
|
||||||
if tunerstatus:
|
if tunerstatus:
|
||||||
@@ -662,7 +668,7 @@ class BOSMiner(BaseMiner):
|
|||||||
except (TypeError, KeyError, ValueError, IndexError):
|
except (TypeError, KeyError, ValueError, IndexError):
|
||||||
pass
|
pass
|
||||||
if groups[0]["strategy"].get("quota"):
|
if groups[0]["strategy"].get("quota"):
|
||||||
data.quota = str(groups[0]["strategy"]["quota"]) + "/" + str(groups[1]["strategy"]["quota"])
|
data.pool_split = str(groups[0]["strategy"]["quota"]) + "/" + str(groups[1]["strategy"]["quota"])
|
||||||
|
|
||||||
data.fault_light = await self.check_light()
|
data.fault_light = await self.check_light()
|
||||||
|
|
||||||
|
|||||||
@@ -238,16 +238,24 @@ class BTMiner(BaseMiner):
|
|||||||
|
|
||||||
async def get_config(self) -> MinerConfig:
|
async def get_config(self) -> MinerConfig:
|
||||||
pools = None
|
pools = None
|
||||||
|
summary = None
|
||||||
cfg = MinerConfig()
|
cfg = MinerConfig()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
pools = await self.api.pools()
|
data = await self.api.multicommand("pools", "summary")
|
||||||
|
pools = data["pools"][0]
|
||||||
|
summary = data["summary"][0]
|
||||||
except APIError as e:
|
except APIError as e:
|
||||||
logging.warning(e)
|
logging.warning(e)
|
||||||
|
|
||||||
if pools:
|
if pools:
|
||||||
if "POOLS" in pools.keys():
|
if "POOLS" in pools:
|
||||||
cfg = cfg.from_api(pools["POOLS"])
|
cfg = cfg.from_api(pools["POOLS"])
|
||||||
|
if summary:
|
||||||
|
if "SUMMARY" in summary:
|
||||||
|
if wattage := summary["SUMMARY"][0].get("Power Limit"):
|
||||||
|
cfg.autotuning_wattage = wattage
|
||||||
|
|
||||||
return cfg
|
return cfg
|
||||||
|
|
||||||
async def get_data(self, allow_warning: bool = True) -> MinerData:
|
async def get_data(self, allow_warning: bool = True) -> MinerData:
|
||||||
|
|||||||
@@ -24,6 +24,31 @@ class M31S(BaseMiner): # noqa - ignore ABC method implementation
|
|||||||
self.fan_count = 2
|
self.fan_count = 2
|
||||||
|
|
||||||
|
|
||||||
|
class M31SV10(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
|
def __init__(self, ip: str):
|
||||||
|
super().__init__()
|
||||||
|
self.ip = ip
|
||||||
|
self.model = "M31S V10"
|
||||||
|
self.nominal_chips = 105
|
||||||
|
self.fan_count = 2
|
||||||
|
|
||||||
|
class M31SV20(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
|
def __init__(self, ip: str):
|
||||||
|
super().__init__()
|
||||||
|
self.ip = ip
|
||||||
|
self.model = "M31S V20"
|
||||||
|
self.nominal_chips = 111
|
||||||
|
self.fan_count = 2
|
||||||
|
|
||||||
|
class M31SV60(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
|
def __init__(self, ip: str):
|
||||||
|
super().__init__()
|
||||||
|
self.ip = ip
|
||||||
|
self.model = "M31S V60"
|
||||||
|
self.nominal_chips = 105
|
||||||
|
self.fan_count = 2
|
||||||
|
|
||||||
|
|
||||||
class M31SV70(BaseMiner): # noqa - ignore ABC method implementation
|
class M31SV70(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ from .M30S_Plus_Plus import (
|
|||||||
M30SPlusPlusVG40,
|
M30SPlusPlusVG40,
|
||||||
M30SPlusPlusVH60,
|
M30SPlusPlusVH60,
|
||||||
)
|
)
|
||||||
from .M31S import M31S, M31SV70
|
from .M31S import M31S, M31SV10, M31SV20, M31SV60, M31SV70
|
||||||
from .M31S_Plus import (
|
from .M31S_Plus import (
|
||||||
M31SPlus,
|
M31SPlus,
|
||||||
M31SPlusV30,
|
M31SPlusV30,
|
||||||
|
|||||||
@@ -218,6 +218,9 @@ class BaseMiner(ABC):
|
|||||||
async def set_power_limit(self, wattage: int) -> bool:
|
async def set_power_limit(self, wattage: int) -> bool:
|
||||||
"""Set the power limit to be used by the miner.
|
"""Set the power limit to be used by the miner.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
wattage: The power limit to set on the miner.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A boolean value of the success of setting the power limit.
|
A boolean value of the success of setting the power limit.
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -195,7 +195,10 @@ MINER_CLASSES = {
|
|||||||
"M31S": {
|
"M31S": {
|
||||||
"Default": BTMinerM31S,
|
"Default": BTMinerM31S,
|
||||||
"BTMiner": BTMinerM31S,
|
"BTMiner": BTMinerM31S,
|
||||||
"V70": BTMinerM31SV70,
|
"10": BTMinerM31SV10,
|
||||||
|
"20": BTMinerM31SV20,
|
||||||
|
"60": BTMinerM31SV60,
|
||||||
|
"70": BTMinerM31SV70,
|
||||||
},
|
},
|
||||||
"M31S+": {
|
"M31S+": {
|
||||||
"Default": BTMinerM31SPlus,
|
"Default": BTMinerM31SPlus,
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from pyasic.miners._backends import BTMiner # noqa - Ignore access to _module
|
from pyasic.miners._backends import BTMiner # noqa - Ignore access to _module
|
||||||
from pyasic.miners._types import M31S, M31SV70 # noqa - Ignore access to _module
|
from pyasic.miners._types import M31S, M31SV10, M31SV20, M31SV60, M31SV70 # noqa - Ignore access to _module
|
||||||
|
|
||||||
|
|
||||||
class BTMinerM31S(BTMiner, M31S):
|
class BTMinerM31S(BTMiner, M31S):
|
||||||
@@ -21,6 +21,23 @@ class BTMinerM31S(BTMiner, M31S):
|
|||||||
super().__init__(ip)
|
super().__init__(ip)
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|
||||||
|
class BTMinerM31SV20(BTMiner, M31SV20):
|
||||||
|
def __init__(self, ip: str) -> None:
|
||||||
|
super().__init__(ip)
|
||||||
|
self.ip = ip
|
||||||
|
|
||||||
|
|
||||||
|
class BTMinerM31SV10(BTMiner, M31SV10):
|
||||||
|
def __init__(self, ip: str) -> None:
|
||||||
|
super().__init__(ip)
|
||||||
|
self.ip = ip
|
||||||
|
|
||||||
|
|
||||||
|
class BTMinerM31SV60(BTMiner, M31SV60):
|
||||||
|
def __init__(self, ip: str) -> None:
|
||||||
|
super().__init__(ip)
|
||||||
|
self.ip = ip
|
||||||
|
|
||||||
|
|
||||||
class BTMinerM31SV70(BTMiner, M31SV70):
|
class BTMinerM31SV70(BTMiner, M31SV70):
|
||||||
def __init__(self, ip: str) -> None:
|
def __init__(self, ip: str) -> None:
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ from .M30S_Plus_Plus import (
|
|||||||
BTMinerM30SPlusPlusVG40,
|
BTMinerM30SPlusPlusVG40,
|
||||||
BTMinerM30SPlusPlusVH60,
|
BTMinerM30SPlusPlusVH60,
|
||||||
)
|
)
|
||||||
from .M31S import BTMinerM31S, BTMinerM31SV70
|
from .M31S import BTMinerM31S, BTMinerM31SV10, BTMinerM31SV20, BTMinerM31SV60, BTMinerM31SV70
|
||||||
from .M31S_Plus import (
|
from .M31S_Plus import (
|
||||||
BTMinerM31SPlus,
|
BTMinerM31SPlus,
|
||||||
BTMinerM31SPlusV30,
|
BTMinerM31SPlusV30,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "pyasic"
|
name = "pyasic"
|
||||||
version = "0.23.3"
|
version = "0.24.2"
|
||||||
description = "A set of modules for interfacing with many common types of ASIC bitcoin miners, using both their API and SSH."
|
description = "A set of modules for interfacing with many common types of ASIC bitcoin miners, using both their API and SSH."
|
||||||
authors = ["UpstreamData <brett@upstreamdata.ca>"]
|
authors = ["UpstreamData <brett@upstreamdata.ca>"]
|
||||||
repository = "https://github.com/UpstreamData/pyasic"
|
repository = "https://github.com/UpstreamData/pyasic"
|
||||||
|
|||||||
Reference in New Issue
Block a user