Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bafa91cc47 | ||
|
|
16399510fa | ||
|
|
e9f54eec0a | ||
|
|
fbbbc9f215 | ||
|
|
69e4f575c0 | ||
|
|
e95659d2e0 | ||
|
|
35f34310ec | ||
|
|
acc18e20fd | ||
|
|
72460eac08 | ||
|
|
3e5f9d4eca | ||
|
|
e873fa252c | ||
|
|
ff2c083a19 | ||
|
|
a30a84c34b | ||
|
|
97d2023298 | ||
|
|
1ce8430a14 | ||
|
|
1c0b638818 | ||
|
|
e852588eeb | ||
|
|
08b9bfd854 | ||
|
|
7ee2f3a29a | ||
|
|
5ee6a38f39 | ||
|
|
8f0bfd5f83 | ||
|
|
c54f39fc77 | ||
|
|
eb40769ccf | ||
|
|
418c62b40d | ||
|
|
198a480c35 |
10
README.md
10
README.md
@@ -38,7 +38,6 @@ There are 2 main ways to get a miner (and the functions attached to it), via sca
|
||||
#### Scanning for miners
|
||||
```python
|
||||
import asyncio
|
||||
import sys
|
||||
|
||||
from pyasic.network import MinerNetwork
|
||||
|
||||
@@ -72,9 +71,8 @@ if __name__ == "__main__":
|
||||
#### Getting a miner if you know the IP
|
||||
```python
|
||||
import asyncio
|
||||
import sys
|
||||
|
||||
from pyasic.miners import get_miner
|
||||
from pyasic import get_miner
|
||||
|
||||
|
||||
# define asynchronous function to get miner and data
|
||||
@@ -98,9 +96,8 @@ If needed, this library exposes a wrapper for the miner API that can be used for
|
||||
#### List available API commands
|
||||
```python
|
||||
import asyncio
|
||||
import sys
|
||||
|
||||
from pyasic.miners import get_miner
|
||||
from pyasic import get_miner
|
||||
|
||||
|
||||
async def get_api_commands(miner_ip: str):
|
||||
@@ -121,9 +118,8 @@ The miner API commands will raise an `APIError` if they fail with a bad status c
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
import sys
|
||||
|
||||
from pyasic.miners import get_miner
|
||||
from pyasic import get_miner
|
||||
|
||||
|
||||
async def get_api_commands(miner_ip: str):
|
||||
|
||||
@@ -117,10 +117,11 @@ These functions are
|
||||
[`get_hostname`](#get-hostname),
|
||||
[`get_model`](#get-model),
|
||||
[`reboot`](#reboot),
|
||||
[`restart_backend`](#restart-backend), and
|
||||
[`stop_mining`](#stop-mining), and
|
||||
[`resume_mining`](#resume-mining), and
|
||||
[`send_config`](#send-config).
|
||||
[`restart_backend`](#restart-backend),
|
||||
[`stop_mining`](#stop-mining),
|
||||
[`resume_mining`](#resume-mining),
|
||||
[`send_config`](#send-config), and
|
||||
[`set_power_limit`](#set-power-limit).
|
||||
|
||||
<br>
|
||||
|
||||
@@ -228,6 +229,14 @@ These functions are
|
||||
|
||||
<br>
|
||||
|
||||
### Set Power Limit
|
||||
::: pyasic.miners.BaseMiner.set_power_limit
|
||||
handler: python
|
||||
options:
|
||||
heading_level: 4
|
||||
|
||||
<br>
|
||||
|
||||
## [`MinerConfig`][pyasic.config.MinerConfig] and [`MinerData`][pyasic.data.MinerData]
|
||||
|
||||
Pyasic implements a few dataclasses as helpers to make data return types consistent across different miners and miner APIs. The different fields of these dataclasses can all be viewed with the classmethod `cls.fields()`.
|
||||
|
||||
@@ -90,6 +90,7 @@ details {
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href="../whatsminer/M3X/#m31s">M31S</a></summary>
|
||||
<summary><a href="../whatsminer/M3X/#m31sv70">M31SV70</a></summary>
|
||||
</details>
|
||||
<details>
|
||||
<summary><a href="../whatsminer/M3X/#m31s_1">M31S+</a></summary>
|
||||
|
||||
@@ -108,6 +108,14 @@
|
||||
|
||||
## M31S
|
||||
|
||||
::: pyasic.miners.whatsminer.btminer.M3X.M31S.BTMinerM31S
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 4
|
||||
|
||||
## M31SV70
|
||||
|
||||
::: pyasic.miners.whatsminer.btminer.M3X.M31S.BTMinerM31S
|
||||
handler: python
|
||||
options:
|
||||
|
||||
@@ -198,7 +198,6 @@ If you are sure you want to use this command please use API.send_command("{comma
|
||||
|
||||
@staticmethod
|
||||
def _load_api_data(data: bytes) -> dict:
|
||||
str_data = None
|
||||
# some json from the API returns with a null byte (\x00) on the end
|
||||
if data.endswith(b"\x00"):
|
||||
# handle the null byte
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import asyncio
|
||||
import base64
|
||||
import binascii
|
||||
import hashlib
|
||||
@@ -582,7 +581,7 @@ class BTMinerAPI(BaseMinerAPI):
|
||||
return await self.send_privileged_command("set_hostname", hostname=hostname)
|
||||
|
||||
async def set_power_pct(self, percent: int) -> dict:
|
||||
"""Set the power percentage of the miner.
|
||||
"""Set the power percentage of the miner based on current power. Used for temporary adjustment.
|
||||
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
@@ -642,6 +641,119 @@ class BTMinerAPI(BaseMinerAPI):
|
||||
"pre_power_on", complete="false", msg=msg
|
||||
)
|
||||
|
||||
### ADDED IN V2.0.5 Whatsminer API ###
|
||||
async def set_temp_offset(self, temp_offset: int):
|
||||
"""Set the offset of miner hash board target temperature.
|
||||
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Set the offset of miner hash board target temperature, only works after
|
||||
changing the password of the miner using the Whatsminer tool.
|
||||
|
||||
Parameters:
|
||||
temp_offset: Target temperature offset.
|
||||
Returns:
|
||||
|
||||
A reply informing of the status of setting temp offset.
|
||||
</details>
|
||||
|
||||
"""
|
||||
if not -30 < temp_offset < 0:
|
||||
raise APIError(
|
||||
f"Temp offset is outside of the allowed "
|
||||
f"range. Please set a number between -30 and "
|
||||
f"0."
|
||||
)
|
||||
|
||||
return await self.send_privileged_command("set_temp_offset", temp_offset=temp_offset)
|
||||
|
||||
async def adjust_power_limit(self, power_limit: int):
|
||||
"""Set the upper limit of the miner's power. Cannot be higher than the ordinary power of the machine.
|
||||
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Set the upper limit of the miner's power, only works after
|
||||
changing the password of the miner using the Whatsminer tool.
|
||||
The miner will reboot after this is set.
|
||||
|
||||
Parameters:
|
||||
power_limit: New power limit.
|
||||
Returns:
|
||||
|
||||
A reply informing of the status of setting power limit.
|
||||
</details>
|
||||
|
||||
"""
|
||||
return await self.send_privileged_command("adjust_power_limit", power_limit=power_limit)
|
||||
|
||||
|
||||
async def adjust_upfreq_speed(self, upfreq_speed: int):
|
||||
"""Set the upfreq speed, 0 is the normal speed, 9 is the fastest speed.
|
||||
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Set the upfreq speed, 0 is the normal speed, 9 is the fastest speed, only works after
|
||||
changing the password of the miner using the Whatsminer tool.
|
||||
The faster the speed, the greater the final hash rate and power deviation, and the stability
|
||||
may be impacted. Fast boot mode cannot be used at the same time.
|
||||
|
||||
Parameters:
|
||||
upfreq_speed: New upfreq speed.
|
||||
Returns:
|
||||
|
||||
A reply informing of the status of setting upfreq speed.
|
||||
</details>
|
||||
"""
|
||||
if not 0 < upfreq_speed < 9:
|
||||
raise APIError(
|
||||
f"Upfreq speed is outside of the allowed "
|
||||
f"range. Please set a number between 0 (Normal) and "
|
||||
f"9 (Fastest)."
|
||||
)
|
||||
return await self.send_privileged_command("adjust_upfreq_speed", upfreq_speed=upfreq_speed)
|
||||
|
||||
async def set_poweroff_cool(self, poweroff_cool: bool):
|
||||
"""Set whether to cool the machine when mining is stopped.
|
||||
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Set whether to cool the machine when mining is stopped, only works after
|
||||
changing the password of the miner using the Whatsminer tool.
|
||||
|
||||
Parameters:
|
||||
poweroff_cool: Whether to cool the miner during power off mode.
|
||||
Returns:
|
||||
|
||||
A reply informing of the status of setting power off cooling mode.
|
||||
</details>
|
||||
"""
|
||||
|
||||
return await self.send_privileged_command("set_poweroff_cool", poweroff_cool=int(poweroff_cool))
|
||||
|
||||
async def set_fan_zero_speed(self, fan_zero_speed: bool):
|
||||
"""Sets whether the fan speed supports the lowest 0 speed.
|
||||
|
||||
<details>
|
||||
<summary>Expand</summary>
|
||||
|
||||
Sets whether the fan speed supports the lowest 0 speed, only works after
|
||||
changing the password of the miner using the Whatsminer tool.
|
||||
|
||||
Parameters:
|
||||
fan_zero_speed: Whether the fan is allowed to support 0 speed.
|
||||
Returns:
|
||||
|
||||
A reply informing of the status of setting fan minimum speed.
|
||||
</details>
|
||||
|
||||
"""
|
||||
return await self.send_privileged_command("set_fan_zero_speed", fan_zero_speed=int(fan_zero_speed))
|
||||
|
||||
|
||||
#### END privileged COMMANDS ####
|
||||
|
||||
async def summary(self) -> dict:
|
||||
|
||||
@@ -17,7 +17,7 @@ import random
|
||||
import string
|
||||
import time
|
||||
from dataclasses import asdict, dataclass, fields
|
||||
from typing import List, Literal
|
||||
from typing import List, Literal, Dict
|
||||
|
||||
import toml
|
||||
import yaml
|
||||
@@ -193,7 +193,7 @@ class _PoolGroup:
|
||||
return pools
|
||||
|
||||
def as_wm(self, user_suffix: str = None) -> List[dict]:
|
||||
"""Convert the data in this class to a list usable by an Whatsminer device.
|
||||
"""Convert the data in this class to a list usable by a Whatsminer device.
|
||||
|
||||
Parameters:
|
||||
user_suffix: The suffix to append to username.
|
||||
@@ -399,13 +399,13 @@ class MinerConfig:
|
||||
"""
|
||||
return self.from_dict(yaml.load(data, Loader=yaml.SafeLoader))
|
||||
|
||||
def as_wm(self, user_suffix: str = None) -> List[dict]:
|
||||
"""Convert the data in this class to a config usable by an Whatsminer device.
|
||||
def as_wm(self, user_suffix: str = None) -> Dict[str, int]:
|
||||
"""Convert the data in this class to a config usable by a Whatsminer device.
|
||||
|
||||
Parameters:
|
||||
user_suffix: The suffix to append to username.
|
||||
"""
|
||||
return self.pool_groups[0].as_wm(user_suffix=user_suffix)
|
||||
return {"pools": self.pool_groups[0].as_wm(user_suffix=user_suffix), "wattage": self.autotuning_wattage}
|
||||
|
||||
def as_inno(self, user_suffix: str = None) -> dict:
|
||||
"""Convert the data in this class to a config usable by an Innosilicon device.
|
||||
|
||||
@@ -17,7 +17,6 @@ import json
|
||||
import time
|
||||
from dataclasses import asdict, dataclass, field, fields
|
||||
from datetime import datetime, timezone
|
||||
from functools import reduce
|
||||
from typing import List, Union
|
||||
|
||||
from .error_codes import BraiinsOSError, InnosiliconError, WhatsminerError, X19Error
|
||||
|
||||
@@ -349,3 +349,7 @@ class BMMiner(BaseMiner):
|
||||
data.pool_split = str(quota)
|
||||
|
||||
return data
|
||||
|
||||
|
||||
async def set_power_limit(self, wattage: int) -> bool:
|
||||
return False
|
||||
|
||||
@@ -83,7 +83,7 @@ class BOSMiner(BaseMiner):
|
||||
d = await client.post(url, json={"query": query})
|
||||
if d.status_code == 200:
|
||||
return d.json()
|
||||
except httpx.ReadError:
|
||||
except (httpx.ReadError, httpx.ReadTimeout):
|
||||
return None
|
||||
return None
|
||||
|
||||
@@ -356,9 +356,6 @@ class BOSMiner(BaseMiner):
|
||||
],
|
||||
)
|
||||
|
||||
board_offset = -1
|
||||
fan_offset = -1
|
||||
|
||||
model = await self.get_model()
|
||||
hostname = await self.get_hostname()
|
||||
mac = await self.get_mac()
|
||||
@@ -551,6 +548,8 @@ class BOSMiner(BaseMiner):
|
||||
if not query_data:
|
||||
return None
|
||||
query_data = query_data["data"]
|
||||
if not query_data:
|
||||
return None
|
||||
|
||||
data.mac = await self.get_mac()
|
||||
data.model = await self.get_model()
|
||||
@@ -663,7 +662,7 @@ class BOSMiner(BaseMiner):
|
||||
except (TypeError, KeyError, ValueError, IndexError):
|
||||
pass
|
||||
if groups[0]["strategy"].get("quota"):
|
||||
data.quota = groups[0]["strategy"]["quota"] + "/" + groups[1]["strategy"]["quota"]
|
||||
data.quota = str(groups[0]["strategy"]["quota"]) + "/" + str(groups[1]["strategy"]["quota"])
|
||||
|
||||
data.fault_light = await self.check_light()
|
||||
|
||||
@@ -672,3 +671,14 @@ class BOSMiner(BaseMiner):
|
||||
async def get_mac(self):
|
||||
result = await self.send_ssh_command("cat /sys/class/net/eth0/address")
|
||||
return result.upper().strip()
|
||||
|
||||
async def set_power_limit(self, wattage: int) -> bool:
|
||||
try:
|
||||
cfg = await self.get_config()
|
||||
cfg.autotuning_wattage = wattage
|
||||
await self.send_config(cfg)
|
||||
except Exception as e:
|
||||
logging.warning(f"{self} set_power_limit: {e}")
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
@@ -104,5 +104,8 @@ class BOSMinerOld(BaseMiner):
|
||||
async def send_config(self, config: MinerConfig, user_suffix: str = None) -> None:
|
||||
return None
|
||||
|
||||
async def get_data(self) -> MinerData:
|
||||
async def get_data(self, **kwargs) -> MinerData:
|
||||
return MinerData(ip=str(self.ip))
|
||||
|
||||
async def set_power_limit(self, wattage: int) -> bool:
|
||||
return False
|
||||
|
||||
@@ -211,18 +211,24 @@ class BTMiner(BaseMiner):
|
||||
|
||||
async def send_config(self, config: MinerConfig, user_suffix: str = None) -> None:
|
||||
conf = config.as_wm(user_suffix=user_suffix)
|
||||
pools_conf = conf["pools"]
|
||||
|
||||
await self.api.update_pools(
|
||||
conf[0]["url"],
|
||||
conf[0]["user"],
|
||||
conf[0]["pass"],
|
||||
conf[1]["url"],
|
||||
conf[1]["user"],
|
||||
conf[1]["pass"],
|
||||
conf[2]["url"],
|
||||
conf[2]["user"],
|
||||
conf[2]["pass"],
|
||||
pools_conf[0]["url"],
|
||||
pools_conf[0]["user"],
|
||||
pools_conf[0]["pass"],
|
||||
pools_conf[1]["url"],
|
||||
pools_conf[1]["user"],
|
||||
pools_conf[1]["pass"],
|
||||
pools_conf[2]["url"],
|
||||
pools_conf[2]["user"],
|
||||
pools_conf[2]["pass"],
|
||||
)
|
||||
try:
|
||||
await self.api.adjust_power_limit(conf["wattage"])
|
||||
except APIError:
|
||||
# cannot set wattage
|
||||
pass
|
||||
|
||||
async def get_config(self) -> MinerConfig:
|
||||
pools = None
|
||||
@@ -432,3 +438,13 @@ class BTMiner(BaseMiner):
|
||||
data.mac = mac
|
||||
|
||||
return data
|
||||
|
||||
|
||||
async def set_power_limit(self, wattage: int) -> bool:
|
||||
try:
|
||||
await self.api.adjust_power_limit(wattage)
|
||||
except Exception as e:
|
||||
logging.warning(f"{self} set_power_limit: {e}")
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
@@ -335,3 +335,6 @@ class CGMiner(BaseMiner):
|
||||
data.pool_split = str(quota)
|
||||
|
||||
return data
|
||||
|
||||
async def set_power_limit(self, wattage: int) -> bool:
|
||||
return False
|
||||
|
||||
@@ -61,3 +61,6 @@ class Hiveon(BMMiner):
|
||||
bad_boards[board] = []
|
||||
bad_boards[board].append(chain)
|
||||
return bad_boards
|
||||
|
||||
async def set_power_limit(self, wattage: int) -> bool:
|
||||
return False
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class S17(BaseMiner):
|
||||
class S17(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class S17Plus(BaseMiner):
|
||||
class S17Plus(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class S17Pro(BaseMiner):
|
||||
class S17Pro(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class S17e(BaseMiner):
|
||||
class S17e(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class T17(BaseMiner):
|
||||
class T17(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class T17Plus(BaseMiner):
|
||||
class T17Plus(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class T17e(BaseMiner):
|
||||
class T17e(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class S19(BaseMiner):
|
||||
class S19(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class S19Pro(BaseMiner):
|
||||
class S19Pro(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class S19XP(BaseMiner):
|
||||
class S19XP(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class S19a(BaseMiner):
|
||||
class S19a(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
24
pyasic/miners/_types/antminer/X19/S19a_Pro.py
Normal file
24
pyasic/miners/_types/antminer/X19/S19a_Pro.py
Normal file
@@ -0,0 +1,24 @@
|
||||
# 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.base import BaseMiner
|
||||
|
||||
|
||||
class S19aPro(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "S19a Pro"
|
||||
self.nominal_chips = 100
|
||||
self.fan_count = 4
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class S19j(BaseMiner):
|
||||
class S19j(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class S19jPro(BaseMiner):
|
||||
class S19jPro(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class T19(BaseMiner):
|
||||
class T19(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
@@ -16,6 +16,7 @@ from .S19 import S19
|
||||
from .S19_Pro import S19Pro
|
||||
from .S19_XP import S19XP
|
||||
from .S19a import S19a
|
||||
from .S19a_Pro import S19aPro
|
||||
from .S19j import S19j
|
||||
from .S19j_Pro import S19jPro
|
||||
from .T19 import T19
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class S9(BaseMiner):
|
||||
class S9(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class S9i(BaseMiner):
|
||||
class S9i(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class T9(BaseMiner):
|
||||
class T9(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class Avalon1026(BaseMiner):
|
||||
class Avalon1026(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class Avalon1047(BaseMiner):
|
||||
class Avalon1047(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class Avalon1066(BaseMiner):
|
||||
class Avalon1066(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
@@ -15,10 +15,11 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class Avalon721(BaseMiner):
|
||||
class Avalon721(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "Avalon 721"
|
||||
self.chip_count = 18 # This miner has 4 boards totaling 72
|
||||
self.fan_count = 1 # also only 1 fan
|
||||
self.ideal_hashboards = 4
|
||||
self.chip_count = 18
|
||||
self.fan_count = 1
|
||||
|
||||
@@ -15,10 +15,11 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class Avalon741(BaseMiner):
|
||||
class Avalon741(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "Avalon 741"
|
||||
self.chip_count = 22 # This miner has 4 boards totaling 88
|
||||
self.fan_count = 1 # also only 1 fan
|
||||
self.ideal_hashboards = 4
|
||||
self.chip_count = 22
|
||||
self.fan_count = 1
|
||||
|
||||
@@ -15,10 +15,11 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class Avalon761(BaseMiner):
|
||||
class Avalon761(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "Avalon 761"
|
||||
self.chip_count = 18 # This miner has 4 boards totaling 72
|
||||
self.fan_count = 1 # also only 1 fan
|
||||
self.ideal_hashboards = 4
|
||||
self.chip_count = 18
|
||||
self.fan_count = 1
|
||||
|
||||
@@ -15,10 +15,11 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class Avalon821(BaseMiner):
|
||||
class Avalon821(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "Avalon 821"
|
||||
self.chip_count = 26 # This miner has 4 boards totaling 104
|
||||
self.fan_count = 1 # also only 1 fan
|
||||
self.ideal_hashboards = 4
|
||||
self.chip_count = 26
|
||||
self.fan_count = 1
|
||||
|
||||
@@ -15,10 +15,11 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class Avalon841(BaseMiner):
|
||||
class Avalon841(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "Avalon 841"
|
||||
self.chip_count = 26 # This miner has 4 boards totaling 104
|
||||
self.fan_count = 1 # also only 1 fan
|
||||
self.ideal_hashboards = 4
|
||||
self.chip_count = 26
|
||||
self.fan_count = 1
|
||||
|
||||
@@ -15,10 +15,11 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class Avalon851(BaseMiner):
|
||||
class Avalon851(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "Avalon 851"
|
||||
self.chip_count = 26 # This miner has 4 boards totaling 104
|
||||
self.fan_count = 1 # also only 1 fan
|
||||
self.ideal_hashboards = 4
|
||||
self.chip_count = 26
|
||||
self.fan_count = 1
|
||||
|
||||
@@ -15,10 +15,11 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class Avalon921(BaseMiner):
|
||||
class Avalon921(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "Avalon 921"
|
||||
self.chip_count = 26 # This miner has 4 boards totaling 104
|
||||
self.fan_count = 1 # also only 1 fan
|
||||
self.ideal_hashboards = 4
|
||||
self.chip_count = 26
|
||||
self.fan_count = 1
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class InnosiliconT3HPlus(BaseMiner):
|
||||
class InnosiliconT3HPlus(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class M20(BaseMiner):
|
||||
class M20(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
@@ -24,7 +24,7 @@ class M20(BaseMiner):
|
||||
self.fan_count = 2
|
||||
|
||||
|
||||
class M20V10(BaseMiner):
|
||||
class M20V10(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class M20S(BaseMiner):
|
||||
class M20S(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
@@ -24,7 +24,7 @@ class M20S(BaseMiner):
|
||||
self.fan_count = 2
|
||||
|
||||
|
||||
class M20SV10(BaseMiner):
|
||||
class M20SV10(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
@@ -33,7 +33,7 @@ class M20SV10(BaseMiner):
|
||||
self.fan_count = 2
|
||||
|
||||
|
||||
class M20SV20(BaseMiner):
|
||||
class M20SV20(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class M20SPlus(BaseMiner):
|
||||
class M20SPlus(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class M21(BaseMiner):
|
||||
class M21(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class M21S(BaseMiner):
|
||||
class M21S(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
@@ -24,7 +24,7 @@ class M21S(BaseMiner):
|
||||
self.fan_count = 2
|
||||
|
||||
|
||||
class M21SV60(BaseMiner):
|
||||
class M21SV60(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
@@ -33,7 +33,7 @@ class M21SV60(BaseMiner):
|
||||
self.fan_count = 2
|
||||
|
||||
|
||||
class M21SV20(BaseMiner):
|
||||
class M21SV20(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class M21SPlus(BaseMiner):
|
||||
class M21SPlus(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class M30S(BaseMiner):
|
||||
class M30S(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
@@ -24,7 +24,7 @@ class M30S(BaseMiner):
|
||||
self.fan_count = 2
|
||||
|
||||
|
||||
class M30SV50(BaseMiner):
|
||||
class M30SV50(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
@@ -33,7 +33,7 @@ class M30SV50(BaseMiner):
|
||||
self.fan_count = 2
|
||||
|
||||
|
||||
class M30SVG20(BaseMiner):
|
||||
class M30SVG20(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
@@ -42,7 +42,7 @@ class M30SVG20(BaseMiner):
|
||||
self.fan_count = 2
|
||||
|
||||
|
||||
class M30SVE20(BaseMiner):
|
||||
class M30SVE20(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
@@ -51,7 +51,7 @@ class M30SVE20(BaseMiner):
|
||||
self.fan_count = 2
|
||||
|
||||
|
||||
class M30SVE10(BaseMiner):
|
||||
class M30SVE10(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class M30SPlus(BaseMiner):
|
||||
class M30SPlus(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
@@ -24,7 +24,7 @@ class M30SPlus(BaseMiner):
|
||||
self.fan_count = 2
|
||||
|
||||
|
||||
class M30SPlusVG60(BaseMiner):
|
||||
class M30SPlusVG60(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
@@ -33,7 +33,7 @@ class M30SPlusVG60(BaseMiner):
|
||||
self.fan_count = 2
|
||||
|
||||
|
||||
class M30SPlusVE40(BaseMiner):
|
||||
class M30SPlusVE40(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
@@ -42,7 +42,7 @@ class M30SPlusVE40(BaseMiner):
|
||||
self.fan_count = 2
|
||||
|
||||
|
||||
class M30SPlusVF20(BaseMiner):
|
||||
class M30SPlusVF20(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class M30SPlusPlus(BaseMiner):
|
||||
class M30SPlusPlus(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
@@ -24,7 +24,7 @@ class M30SPlusPlus(BaseMiner):
|
||||
self.fan_count = 2
|
||||
|
||||
|
||||
class M30SPlusPlusVG30(BaseMiner):
|
||||
class M30SPlusPlusVG30(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
@@ -33,7 +33,7 @@ class M30SPlusPlusVG30(BaseMiner):
|
||||
self.fan_count = 2
|
||||
|
||||
|
||||
class M30SPlusPlusVG40(BaseMiner):
|
||||
class M30SPlusPlusVG40(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
@@ -42,7 +42,7 @@ class M30SPlusPlusVG40(BaseMiner):
|
||||
self.fan_count = 2
|
||||
|
||||
|
||||
class M30SPlusPlusVH60(BaseMiner):
|
||||
class M30SPlusPlusVH60(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
@@ -15,10 +15,19 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class M31S(BaseMiner):
|
||||
class M31S(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "M31S"
|
||||
# TODO: Add chip count for this miner (per board) - self.nominal_chips
|
||||
self.nominal_chips = 111
|
||||
self.fan_count = 2
|
||||
|
||||
|
||||
class M31SV70(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
self.model = "M31S V70"
|
||||
self.nominal_chips = 111
|
||||
self.fan_count = 2
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class M31SPlus(BaseMiner):
|
||||
class M31SPlus(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
@@ -24,7 +24,7 @@ class M31SPlus(BaseMiner):
|
||||
self.fan_count = 2
|
||||
|
||||
|
||||
class M31SPlusVE20(BaseMiner):
|
||||
class M31SPlusVE20(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
@@ -33,7 +33,7 @@ class M31SPlusVE20(BaseMiner):
|
||||
self.fan_count = 2
|
||||
|
||||
|
||||
class M31SPlusV30(BaseMiner):
|
||||
class M31SPlusV30(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
@@ -42,7 +42,7 @@ class M31SPlusV30(BaseMiner):
|
||||
self.fan_count = 2
|
||||
|
||||
|
||||
class M31SPlusV40(BaseMiner):
|
||||
class M31SPlusV40(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
@@ -51,7 +51,7 @@ class M31SPlusV40(BaseMiner):
|
||||
self.fan_count = 2
|
||||
|
||||
|
||||
class M31SPlusV60(BaseMiner):
|
||||
class M31SPlusV60(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
@@ -60,7 +60,7 @@ class M31SPlusV60(BaseMiner):
|
||||
self.fan_count = 2
|
||||
|
||||
|
||||
class M31SPlusV80(BaseMiner):
|
||||
class M31SPlusV80(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
@@ -69,7 +69,7 @@ class M31SPlusV80(BaseMiner):
|
||||
self.fan_count = 2
|
||||
|
||||
|
||||
class M31SPlusV90(BaseMiner):
|
||||
class M31SPlusV90(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class M32(BaseMiner):
|
||||
class M32(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
@@ -24,7 +24,7 @@ class M32(BaseMiner):
|
||||
self.fan_count = 2
|
||||
|
||||
|
||||
class M32V20(BaseMiner):
|
||||
class M32V20(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class M32S(BaseMiner):
|
||||
class M32S(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class M34SPlus(BaseMiner):
|
||||
class M34SPlus(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
@@ -25,7 +25,7 @@ class M34SPlus(BaseMiner):
|
||||
self.fan_count = 0
|
||||
|
||||
|
||||
class M34SPlusVE10(BaseMiner):
|
||||
class M34SPlusVE10(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
@@ -20,7 +20,7 @@ from .M30S_Plus_Plus import (
|
||||
M30SPlusPlusVG40,
|
||||
M30SPlusPlusVH60,
|
||||
)
|
||||
from .M31S import M31S
|
||||
from .M31S import M31S, M31SV70
|
||||
from .M31S_Plus import (
|
||||
M31SPlus,
|
||||
M31SPlusV30,
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from pyasic.miners.base import BaseMiner
|
||||
|
||||
|
||||
class M50(BaseMiner):
|
||||
class M50(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
@@ -24,7 +24,7 @@ class M50(BaseMiner):
|
||||
self.fan_count = 2
|
||||
|
||||
|
||||
class M50VH50(BaseMiner):
|
||||
class M50VH50(BaseMiner): # noqa - ignore ABC method implementation
|
||||
def __init__(self, ip: str):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
23
pyasic/miners/antminer/bmminer/X19/S19a_Pro.py
Normal file
23
pyasic/miners/antminer/bmminer/X19/S19a_Pro.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._types import S19aPro # noqa - Ignore access to _module
|
||||
|
||||
from .X19 import BMMinerX19
|
||||
|
||||
|
||||
class BMMinerS19aPro(BMMinerX19, S19aPro):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.ip = ip
|
||||
@@ -62,7 +62,7 @@ class BMMinerX19(BMMiner):
|
||||
|
||||
try:
|
||||
async with httpx.AsyncClient() as client:
|
||||
await client.post(url, data=conf, auth=auth)
|
||||
await client.post(url, data=conf, auth=auth) # noqa - ignore conf being a str
|
||||
except httpx.ReadTimeout:
|
||||
pass
|
||||
for i in range(7):
|
||||
@@ -102,7 +102,7 @@ class BMMinerX19(BMMiner):
|
||||
auth = httpx.DigestAuth(self.uname, self.pwd)
|
||||
data = json.dumps({"blink": "true"})
|
||||
async with httpx.AsyncClient() as client:
|
||||
data = await client.post(url, data=data, auth=auth)
|
||||
data = await client.post(url, data=data, auth=auth) # noqa - ignore conf being a str
|
||||
if data.status_code == 200:
|
||||
data = data.json()
|
||||
if data.get("code") == "B000":
|
||||
@@ -115,7 +115,7 @@ class BMMinerX19(BMMiner):
|
||||
auth = httpx.DigestAuth(self.uname, self.pwd)
|
||||
data = json.dumps({"blink": "false"})
|
||||
async with httpx.AsyncClient() as client:
|
||||
data = await client.post(url, data=data, auth=auth)
|
||||
data = await client.post(url, data=data, auth=auth) # noqa - ignore conf being a str
|
||||
if data.status_code == 200:
|
||||
data = data.json()
|
||||
if data.get("code") == "B100":
|
||||
@@ -139,7 +139,10 @@ class BMMinerX19(BMMiner):
|
||||
async with httpx.AsyncClient() as client:
|
||||
data = await client.get(url, auth=auth)
|
||||
if data:
|
||||
data = data.json()
|
||||
try:
|
||||
data = data.json()
|
||||
except json.decoder.JSONDecodeError:
|
||||
return []
|
||||
if "SUMMARY" in data.keys():
|
||||
if "status" in data["SUMMARY"][0].keys():
|
||||
for item in data["SUMMARY"][0]["status"]:
|
||||
|
||||
@@ -16,6 +16,7 @@ from .S19 import BMMinerS19
|
||||
from .S19_Pro import BMMinerS19Pro
|
||||
from .S19_XP import BMMinerS19XP
|
||||
from .S19a import BMMinerS19a
|
||||
from .S19a_Pro import BMMinerS19aPro
|
||||
from .S19j import BMMinerS19j
|
||||
from .S19j_Pro import BMMinerS19jPro
|
||||
from .T19 import BMMinerT19
|
||||
|
||||
@@ -44,7 +44,6 @@ class HiveonT9(Hiveon, T9):
|
||||
ideal_hashboards=self.ideal_hashboards,
|
||||
)
|
||||
|
||||
board_offset = -1
|
||||
fan_offset = -1
|
||||
|
||||
model = await self.get_model()
|
||||
|
||||
@@ -15,18 +15,14 @@
|
||||
import ipaddress
|
||||
import logging
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import List, TypeVar, Union
|
||||
from typing import List, TypeVar
|
||||
|
||||
import asyncssh
|
||||
|
||||
from pyasic.config import MinerConfig
|
||||
from pyasic.data import MinerData
|
||||
from pyasic.data.error_codes import (
|
||||
BraiinsOSError,
|
||||
InnosiliconError,
|
||||
MinerErrorData,
|
||||
WhatsminerError,
|
||||
X19Error,
|
||||
)
|
||||
|
||||
|
||||
@@ -220,4 +216,12 @@ class BaseMiner(ABC):
|
||||
pass
|
||||
|
||||
|
||||
@abstractmethod
|
||||
async def set_power_limit(self, wattage: int) -> bool:
|
||||
"""Set the power limit to be used by the miner.
|
||||
|
||||
Returns:
|
||||
A boolean value of the success of setting the power limit.
|
||||
"""
|
||||
|
||||
AnyMiner = TypeVar("AnyMiner", bound=BaseMiner)
|
||||
|
||||
@@ -169,9 +169,6 @@ class CGMinerInnosiliconT3HPlus(CGMiner, InnosiliconT3HPlus):
|
||||
],
|
||||
)
|
||||
|
||||
board_offset = -1
|
||||
fan_offset = -1
|
||||
|
||||
model = await self.get_model()
|
||||
hostname = await self.get_hostname()
|
||||
|
||||
|
||||
@@ -131,6 +131,10 @@ MINER_CLASSES = {
|
||||
"Default": BMMinerS19a,
|
||||
"BMMiner": BMMinerS19a,
|
||||
},
|
||||
"ANTMINER S19A PRO": {
|
||||
"Default": BMMinerS19aPro,
|
||||
"BMMiner": BMMinerS19aPro,
|
||||
},
|
||||
"ANTMINER T19": {
|
||||
"Default": BMMinerT19,
|
||||
"BOSMiner+": BOSMinerT19,
|
||||
@@ -186,10 +190,12 @@ MINER_CLASSES = {
|
||||
"BTMiner": BTMinerM30SPlusPlus,
|
||||
"G40": BTMinerM30SPlusPlusVG40,
|
||||
"G30": BTMinerM30SPlusPlusVG30,
|
||||
"H60": BTMinerM30SPlusPlusVH60,
|
||||
},
|
||||
"M31S": {
|
||||
"Default": BTMinerM31S,
|
||||
"BTMiner": BTMinerM31S,
|
||||
"V70": BTMinerM31SV70,
|
||||
},
|
||||
"M31S+": {
|
||||
"Default": BTMinerM31SPlus,
|
||||
@@ -448,16 +454,21 @@ class MinerFactory(metaclass=Singleton):
|
||||
api = "BOSMiner+"
|
||||
except (KeyError, TypeError, ValueError, IndexError):
|
||||
pass
|
||||
|
||||
if not model:
|
||||
# braiins OS bug check just in case
|
||||
if "s9" in devdetails["STATUS"][0]["Description"]:
|
||||
model = "ANTMINER S9"
|
||||
if "s17" in version["STATUS"][0]["Description"]:
|
||||
model = "ANTMINER S17"
|
||||
if not api:
|
||||
if "boser" in version["STATUS"][0]["Description"]:
|
||||
api = "BOSMiner+"
|
||||
try:
|
||||
if not model:
|
||||
# braiins OS bug check just in case
|
||||
if "s9" in devdetails["STATUS"][0]["Description"]:
|
||||
model = "ANTMINER S9"
|
||||
if "s17" in version["STATUS"][0]["Description"]:
|
||||
model = "ANTMINER S17"
|
||||
except (KeyError, TypeError, ValueError, IndexError):
|
||||
pass
|
||||
try:
|
||||
if not api:
|
||||
if "boser" in version["STATUS"][0]["Description"]:
|
||||
api = "BOSMiner+"
|
||||
except (KeyError, TypeError, ValueError, IndexError):
|
||||
pass
|
||||
else:
|
||||
try:
|
||||
_model = await self.__get_model_from_graphql(ip)
|
||||
@@ -572,7 +583,7 @@ class MinerFactory(metaclass=Singleton):
|
||||
try:
|
||||
if data["version"][0]["STATUS"][0]["Msg"] == "Disconnected":
|
||||
return data["devdetails"], data["version"]
|
||||
except KeyError:
|
||||
except (KeyError, TypeError):
|
||||
pass
|
||||
raise APIError(validation[1])
|
||||
# copy each part of the main command to devdetails and version
|
||||
|
||||
@@ -74,3 +74,6 @@ class UnknownMiner(BaseMiner):
|
||||
|
||||
async def get_data(self, allow_warning: bool = False) -> MinerData:
|
||||
return MinerData(ip=str(self.ip))
|
||||
|
||||
async def set_power_limit(self, wattage: int) -> bool:
|
||||
return False
|
||||
|
||||
@@ -13,10 +13,16 @@
|
||||
# limitations under the License.
|
||||
|
||||
from pyasic.miners._backends import BTMiner # noqa - Ignore access to _module
|
||||
from pyasic.miners._types import M31S # noqa - Ignore access to _module
|
||||
from pyasic.miners._types import M31S, M31SV70 # noqa - Ignore access to _module
|
||||
|
||||
|
||||
class BTMinerM31S(BTMiner, M31S):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.ip = ip
|
||||
|
||||
|
||||
class BTMinerM31SV70(BTMiner, M31SV70):
|
||||
def __init__(self, ip: str) -> None:
|
||||
super().__init__(ip)
|
||||
self.ip = ip
|
||||
|
||||
@@ -31,7 +31,7 @@ from .M30S_Plus_Plus import (
|
||||
BTMinerM30SPlusPlusVG40,
|
||||
BTMinerM30SPlusPlusVH60,
|
||||
)
|
||||
from .M31S import BTMinerM31S
|
||||
from .M31S import BTMinerM31S, BTMinerM31SV70
|
||||
from .M31S_Plus import (
|
||||
BTMinerM31SPlus,
|
||||
BTMinerM31SPlusV30,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "pyasic"
|
||||
version = "0.21.11"
|
||||
version = "0.23.0"
|
||||
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>"]
|
||||
repository = "https://github.com/UpstreamData/pyasic"
|
||||
|
||||
@@ -16,10 +16,9 @@ import inspect
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from pyasic.miners._backends import CGMiner
|
||||
from pyasic.miners._backends import CGMiner # noqa
|
||||
from pyasic.miners.base import BaseMiner
|
||||
from pyasic.miners.miner_factory import MINER_CLASSES, MinerFactory
|
||||
from pyasic.miners.miner_listener import MinerListener
|
||||
|
||||
|
||||
class MinersTest(unittest.TestCase):
|
||||
|
||||
@@ -16,7 +16,6 @@ import ipaddress
|
||||
import unittest
|
||||
|
||||
from pyasic.network import MinerNetwork
|
||||
from pyasic.network.net_range import MinerNetworkRange
|
||||
|
||||
|
||||
class NetworkTest(unittest.TestCase):
|
||||
|
||||
Reference in New Issue
Block a user