Compare commits
63 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e9f54eec0a | ||
|
|
fbbbc9f215 | ||
|
|
69e4f575c0 | ||
|
|
e95659d2e0 | ||
|
|
35f34310ec | ||
|
|
acc18e20fd | ||
|
|
72460eac08 | ||
|
|
3e5f9d4eca | ||
|
|
e873fa252c | ||
|
|
ff2c083a19 | ||
|
|
a30a84c34b | ||
|
|
97d2023298 | ||
|
|
1ce8430a14 | ||
|
|
1c0b638818 | ||
|
|
e852588eeb | ||
|
|
08b9bfd854 | ||
|
|
7ee2f3a29a | ||
|
|
5ee6a38f39 | ||
|
|
8f0bfd5f83 | ||
|
|
c54f39fc77 | ||
|
|
eb40769ccf | ||
|
|
418c62b40d | ||
|
|
198a480c35 | ||
|
|
2d4bf4e847 | ||
|
|
774e3d1a62 | ||
|
|
ade3cd6fee | ||
|
|
28dc3ccb84 | ||
|
|
6ca8582ec3 | ||
|
|
74b4aeb44a | ||
|
|
9c7ab5ac57 | ||
|
|
65ecf1fea2 | ||
|
|
44142c658b | ||
|
|
25a205ce6c | ||
|
|
25094084cf | ||
|
|
4eac601153 | ||
|
|
f0d8d66b9b | ||
|
|
cfa550f8c0 | ||
|
|
91f6a5bf41 | ||
|
|
464bd6be65 | ||
|
|
031d7e2186 | ||
|
|
126b0d124c | ||
|
|
81c84a3e8f | ||
|
|
406d5bd549 | ||
|
|
cd5fe09fd9 | ||
|
|
766fc4efed | ||
|
|
b70fed40c8 | ||
|
|
255d98fd08 | ||
|
|
78304631f7 | ||
|
|
ab230844fc | ||
|
|
8a58cb9fd3 | ||
|
|
70b6ed73dc | ||
|
|
d2400bf44e | ||
|
|
db780fe876 | ||
|
|
cd84ae828a | ||
|
|
970d5d1031 | ||
|
|
da0e327ec7 | ||
|
|
4c84a8d572 | ||
|
|
1cfd895deb | ||
|
|
d0da08eb10 | ||
|
|
ee4f2cd87d | ||
|
|
8a6577c8aa | ||
|
|
ed5eae4187 | ||
|
|
f3b25027ad |
@@ -9,6 +9,12 @@ repos:
|
|||||||
rev: 22.6.0
|
rev: 22.6.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: black
|
- id: black
|
||||||
|
- repo: https://github.com/pycqa/isort
|
||||||
|
rev: 5.10.1
|
||||||
|
hooks:
|
||||||
|
- id: isort
|
||||||
|
name: isort (python)
|
||||||
|
|
||||||
- repo: local
|
- repo: local
|
||||||
hooks:
|
hooks:
|
||||||
- id: unittest
|
- id: unittest
|
||||||
|
|||||||
14
README.md
14
README.md
@@ -18,6 +18,10 @@ You can install pyasic directly from pip with the command `pip install pyasic`.
|
|||||||
For those of you who aren't comfortable with code and developer tools, there are windows builds of GUI applications that use this library [here](https://drive.google.com/drive/folders/1DjR8UOS_g0ehfiJcgmrV0FFoqFvE9akW?usp=sharing).
|
For those of you who aren't comfortable with code and developer tools, there are windows builds of GUI applications that use this library [here](https://drive.google.com/drive/folders/1DjR8UOS_g0ehfiJcgmrV0FFoqFvE9akW?usp=sharing).
|
||||||
|
|
||||||
## Developer Setup
|
## Developer Setup
|
||||||
|
It is highly reccommended that you contribute to this project through [`pyasic-super`](https://github.com/UpstreamData/pyasic-super) using its submodules. This allows testing in conjunction with other `pyasic` related programs.
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
This repo uses poetry for dependencies, which can be installed by following the guide on their website [here](https://python-poetry.org/docs/#installation).
|
This repo uses poetry for dependencies, which can be installed by following the guide on their website [here](https://python-poetry.org/docs/#installation).
|
||||||
|
|
||||||
After you have poetry installed, run `poetry install --with dev`, or `poetry install --with dev,docs` if you want to include packages required for documentation.
|
After you have poetry installed, run `poetry install --with dev`, or `poetry install --with dev,docs` if you want to include packages required for documentation.
|
||||||
@@ -34,7 +38,6 @@ There are 2 main ways to get a miner (and the functions attached to it), via sca
|
|||||||
#### Scanning for miners
|
#### Scanning for miners
|
||||||
```python
|
```python
|
||||||
import asyncio
|
import asyncio
|
||||||
import sys
|
|
||||||
|
|
||||||
from pyasic.network import MinerNetwork
|
from pyasic.network import MinerNetwork
|
||||||
|
|
||||||
@@ -68,9 +71,8 @@ if __name__ == "__main__":
|
|||||||
#### Getting a miner if you know the IP
|
#### Getting a miner if you know the IP
|
||||||
```python
|
```python
|
||||||
import asyncio
|
import asyncio
|
||||||
import sys
|
|
||||||
|
|
||||||
from pyasic.miners import get_miner
|
from pyasic import get_miner
|
||||||
|
|
||||||
|
|
||||||
# define asynchronous function to get miner and data
|
# define asynchronous function to get miner and data
|
||||||
@@ -94,9 +96,8 @@ If needed, this library exposes a wrapper for the miner API that can be used for
|
|||||||
#### List available API commands
|
#### List available API commands
|
||||||
```python
|
```python
|
||||||
import asyncio
|
import asyncio
|
||||||
import sys
|
|
||||||
|
|
||||||
from pyasic.miners import get_miner
|
from pyasic import get_miner
|
||||||
|
|
||||||
|
|
||||||
async def get_api_commands(miner_ip: str):
|
async def get_api_commands(miner_ip: str):
|
||||||
@@ -117,9 +118,8 @@ The miner API commands will raise an `APIError` if they fail with a bad status c
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
import asyncio
|
import asyncio
|
||||||
import sys
|
|
||||||
|
|
||||||
from pyasic.miners import get_miner
|
from pyasic import get_miner
|
||||||
|
|
||||||
|
|
||||||
async def get_api_commands(miner_ip: str):
|
async def get_api_commands(miner_ip: str):
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ 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/#m31sv70">M31SV70</a></summary>
|
||||||
</details>
|
</details>
|
||||||
<details>
|
<details>
|
||||||
<summary><a href="../whatsminer/M3X/#m31s_1">M31S+</a></summary>
|
<summary><a href="../whatsminer/M3X/#m31s_1">M31S+</a></summary>
|
||||||
|
|||||||
@@ -108,6 +108,14 @@
|
|||||||
|
|
||||||
## M31S
|
## 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
|
::: pyasic.miners.whatsminer.btminer.M3X.M31S.BTMinerM31S
|
||||||
handler: python
|
handler: python
|
||||||
options:
|
options:
|
||||||
|
|||||||
@@ -13,12 +13,12 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import json
|
|
||||||
import ipaddress
|
import ipaddress
|
||||||
import warnings
|
import json
|
||||||
import logging
|
import logging
|
||||||
from typing import Union
|
|
||||||
import re
|
import re
|
||||||
|
import warnings
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
from pyasic.errors import APIError, APIWarning
|
from pyasic.errors import APIError, APIWarning
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ If you are sure you want to use this command please use API.send_command("{comma
|
|||||||
reader, writer = await asyncio.open_connection(str(self.ip), self.port)
|
reader, writer = await asyncio.open_connection(str(self.ip), self.port)
|
||||||
# handle OSError 121
|
# handle OSError 121
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
if e.winerror == "121":
|
if getattr(e, "winerror") == "121":
|
||||||
logging.warning("Semaphore Timeout has Expired.")
|
logging.warning("Semaphore Timeout has Expired.")
|
||||||
return b"{}"
|
return b"{}"
|
||||||
|
|
||||||
@@ -198,7 +198,6 @@ If you are sure you want to use this command please use API.send_command("{comma
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _load_api_data(data: bytes) -> dict:
|
def _load_api_data(data: bytes) -> dict:
|
||||||
str_data = None
|
|
||||||
# some json from the API returns with a null byte (\x00) on the end
|
# some json from the API returns with a null byte (\x00) on the end
|
||||||
if data.endswith(b"\x00"):
|
if data.endswith(b"\x00"):
|
||||||
# handle the null byte
|
# handle the null byte
|
||||||
|
|||||||
@@ -13,8 +13,7 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from pyasic.API import BaseMinerAPI
|
from pyasic.API import APIError, BaseMinerAPI
|
||||||
from pyasic.API import APIError
|
|
||||||
|
|
||||||
|
|
||||||
class BMMinerAPI(BaseMinerAPI):
|
class BMMinerAPI(BaseMinerAPI):
|
||||||
|
|||||||
@@ -12,23 +12,21 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import re
|
|
||||||
import json
|
|
||||||
import hashlib
|
|
||||||
import binascii
|
|
||||||
import base64
|
import base64
|
||||||
|
import binascii
|
||||||
|
import hashlib
|
||||||
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
import re
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
from passlib.handlers.md5_crypt import md5_crypt
|
|
||||||
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
||||||
|
from passlib.handlers.md5_crypt import md5_crypt
|
||||||
|
|
||||||
from pyasic.errors import APIError
|
|
||||||
from pyasic.API import BaseMinerAPI
|
from pyasic.API import BaseMinerAPI
|
||||||
|
from pyasic.errors import APIError
|
||||||
from pyasic.settings import PyasicSettings
|
from pyasic.settings import PyasicSettings
|
||||||
|
|
||||||
|
|
||||||
### IMPORTANT ###
|
### IMPORTANT ###
|
||||||
# you need to change the password of the miners using the Whatsminer
|
# you need to change the password of the miners using the Whatsminer
|
||||||
# tool, then you can set them back to admin with this tool, but they
|
# tool, then you can set them back to admin with this tool, but they
|
||||||
@@ -583,7 +581,7 @@ class BTMinerAPI(BaseMinerAPI):
|
|||||||
return await self.send_privileged_command("set_hostname", hostname=hostname)
|
return await self.send_privileged_command("set_hostname", hostname=hostname)
|
||||||
|
|
||||||
async def set_power_pct(self, percent: int) -> dict:
|
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>
|
<details>
|
||||||
<summary>Expand</summary>
|
<summary>Expand</summary>
|
||||||
@@ -643,6 +641,119 @@ class BTMinerAPI(BaseMinerAPI):
|
|||||||
"pre_power_on", complete="false", msg=msg
|
"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 ####
|
#### END privileged COMMANDS ####
|
||||||
|
|
||||||
async def summary(self) -> dict:
|
async def summary(self) -> dict:
|
||||||
|
|||||||
@@ -12,10 +12,10 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from pyasic.API import BaseMinerAPI, APIError
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
from pyasic.API import APIError, BaseMinerAPI
|
||||||
|
|
||||||
|
|
||||||
class CGMinerAPI(BaseMinerAPI):
|
class CGMinerAPI(BaseMinerAPI):
|
||||||
"""An abstraction of the CGMiner API.
|
"""An abstraction of the CGMiner API.
|
||||||
|
|||||||
@@ -16,26 +16,20 @@ from pyasic.API.bosminer import BOSMinerAPI
|
|||||||
from pyasic.API.btminer import BTMinerAPI
|
from pyasic.API.btminer import BTMinerAPI
|
||||||
from pyasic.API.cgminer import CGMinerAPI
|
from pyasic.API.cgminer import CGMinerAPI
|
||||||
from pyasic.API.unknown import UnknownAPI
|
from pyasic.API.unknown import UnknownAPI
|
||||||
|
|
||||||
from pyasic.config import MinerConfig
|
from pyasic.config import MinerConfig
|
||||||
|
|
||||||
from pyasic.data import (
|
from pyasic.data import (
|
||||||
MinerData,
|
|
||||||
BraiinsOSError,
|
BraiinsOSError,
|
||||||
InnosiliconError,
|
InnosiliconError,
|
||||||
|
MinerData,
|
||||||
WhatsminerError,
|
WhatsminerError,
|
||||||
X19Error,
|
X19Error,
|
||||||
)
|
)
|
||||||
|
|
||||||
from pyasic.errors import APIError, APIWarning
|
from pyasic.errors import APIError, APIWarning
|
||||||
|
|
||||||
from pyasic.miners import get_miner
|
from pyasic.miners import get_miner
|
||||||
from pyasic.miners.base import AnyMiner
|
from pyasic.miners.base import AnyMiner
|
||||||
from pyasic.miners.miner_factory import MinerFactory
|
from pyasic.miners.miner_factory import MinerFactory
|
||||||
from pyasic.miners.miner_listener import MinerListener
|
from pyasic.miners.miner_listener import MinerListener
|
||||||
|
|
||||||
from pyasic.network import MinerNetwork
|
from pyasic.network import MinerNetwork
|
||||||
|
|
||||||
from pyasic.settings import PyasicSettings
|
from pyasic.settings import PyasicSettings
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
|
|||||||
@@ -12,15 +12,15 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from dataclasses import dataclass, asdict, fields
|
import json
|
||||||
from typing import Literal, List
|
|
||||||
import random
|
import random
|
||||||
import string
|
import string
|
||||||
|
import time
|
||||||
|
from dataclasses import asdict, dataclass, fields
|
||||||
|
from typing import List, Literal, Dict
|
||||||
|
|
||||||
import toml
|
import toml
|
||||||
import yaml
|
import yaml
|
||||||
import json
|
|
||||||
import time
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@@ -193,7 +193,7 @@ class _PoolGroup:
|
|||||||
return pools
|
return pools
|
||||||
|
|
||||||
def as_wm(self, user_suffix: str = None) -> List[dict]:
|
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:
|
Parameters:
|
||||||
user_suffix: The suffix to append to username.
|
user_suffix: The suffix to append to username.
|
||||||
@@ -399,13 +399,13 @@ class MinerConfig:
|
|||||||
"""
|
"""
|
||||||
return self.from_dict(yaml.load(data, Loader=yaml.SafeLoader))
|
return self.from_dict(yaml.load(data, Loader=yaml.SafeLoader))
|
||||||
|
|
||||||
def as_wm(self, user_suffix: str = None) -> List[dict]:
|
def as_wm(self, user_suffix: str = None) -> Dict[str, int]:
|
||||||
"""Convert the data in this class to a config usable by an Whatsminer device.
|
"""Convert the data in this class to a config usable by a Whatsminer device.
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
user_suffix: The suffix to append to username.
|
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:
|
def as_inno(self, user_suffix: str = None) -> dict:
|
||||||
"""Convert the data in this class to a config usable by an Innosilicon device.
|
"""Convert the data in this class to a config usable by an Innosilicon device.
|
||||||
|
|||||||
@@ -12,15 +12,14 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from typing import Union, List
|
|
||||||
from dataclasses import dataclass, field, asdict, fields
|
|
||||||
from datetime import datetime, timezone
|
|
||||||
from functools import reduce
|
|
||||||
import time
|
|
||||||
import json
|
|
||||||
import copy
|
import copy
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
from dataclasses import asdict, dataclass, field, fields
|
||||||
|
from datetime import datetime, timezone
|
||||||
|
from typing import List, Union
|
||||||
|
|
||||||
from .error_codes import X19Error, WhatsminerError, BraiinsOSError, InnosiliconError
|
from .error_codes import BraiinsOSError, InnosiliconError, WhatsminerError, X19Error
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from dataclasses import dataclass, asdict, fields
|
from dataclasses import asdict, dataclass, fields
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
|||||||
@@ -12,13 +12,13 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from .whatsminer import WhatsminerError
|
|
||||||
from .bos import BraiinsOSError
|
|
||||||
from .X19 import X19Error
|
|
||||||
from .innosilicon import InnosiliconError
|
|
||||||
|
|
||||||
from typing import TypeVar
|
from typing import TypeVar
|
||||||
|
|
||||||
|
from .bos import BraiinsOSError
|
||||||
|
from .innosilicon import InnosiliconError
|
||||||
|
from .whatsminer import WhatsminerError
|
||||||
|
from .X19 import X19Error
|
||||||
|
|
||||||
MinerErrorData = TypeVar(
|
MinerErrorData = TypeVar(
|
||||||
"MinerErrorData", WhatsminerError, BraiinsOSError, X19Error, InnosiliconError
|
"MinerErrorData", WhatsminerError, BraiinsOSError, X19Error, InnosiliconError
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from dataclasses import dataclass, asdict, fields
|
from dataclasses import asdict, dataclass, fields
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from dataclasses import dataclass, field, asdict, fields
|
from dataclasses import asdict, dataclass, field, fields
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from dataclasses import dataclass, field, asdict, fields
|
from dataclasses import asdict, dataclass, field, fields
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from pyasic.settings import PyasicSettings
|
from pyasic.settings import PyasicSettings
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -15,9 +15,10 @@
|
|||||||
import ipaddress
|
import ipaddress
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
from pyasic.miners.base import BaseMiner, AnyMiner
|
from pyasic.miners.base import AnyMiner, BaseMiner
|
||||||
from pyasic.miners.miner_factory import MinerFactory
|
from pyasic.miners.miner_factory import MinerFactory
|
||||||
|
|
||||||
|
|
||||||
# abstracted version of get miner that is easier to access
|
# abstracted version of get miner that is easier to access
|
||||||
async def get_miner(ip: Union[ipaddress.ip_address, str]) -> AnyMiner:
|
async def get_miner(ip: Union[ipaddress.ip_address, str]) -> AnyMiner:
|
||||||
return await MinerFactory().get_miner(ip)
|
return await MinerFactory().get_miner(ip)
|
||||||
|
|||||||
@@ -14,16 +14,13 @@
|
|||||||
|
|
||||||
import ipaddress
|
import ipaddress
|
||||||
import logging
|
import logging
|
||||||
from typing import Union, List
|
from typing import List, Union
|
||||||
|
|
||||||
|
|
||||||
from pyasic.API.bmminer import BMMinerAPI
|
from pyasic.API.bmminer import BMMinerAPI
|
||||||
from pyasic.miners.base import BaseMiner
|
|
||||||
|
|
||||||
from pyasic.data import MinerData, HashBoard
|
|
||||||
from pyasic.config import MinerConfig
|
from pyasic.config import MinerConfig
|
||||||
|
from pyasic.data import HashBoard, MinerData
|
||||||
from pyasic.data.error_codes import MinerErrorData
|
from pyasic.data.error_codes import MinerErrorData
|
||||||
|
from pyasic.miners.base import BaseMiner
|
||||||
from pyasic.settings import PyasicSettings
|
from pyasic.settings import PyasicSettings
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -13,22 +13,19 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
import ipaddress
|
import ipaddress
|
||||||
import logging
|
|
||||||
import json
|
import json
|
||||||
from typing import Union, List
|
import logging
|
||||||
|
from typing import List, Union
|
||||||
|
|
||||||
import toml
|
import toml
|
||||||
|
import httpx
|
||||||
|
|
||||||
|
|
||||||
from pyasic.miners.base import BaseMiner
|
|
||||||
from pyasic.API.bosminer import BOSMinerAPI
|
from pyasic.API.bosminer import BOSMinerAPI
|
||||||
from pyasic.errors import APIError
|
|
||||||
|
|
||||||
from pyasic.data.error_codes import BraiinsOSError, MinerErrorData
|
|
||||||
from pyasic.data import MinerData, HashBoard
|
|
||||||
|
|
||||||
from pyasic.config import MinerConfig
|
from pyasic.config import MinerConfig
|
||||||
|
from pyasic.data import HashBoard, MinerData
|
||||||
|
from pyasic.data.error_codes import BraiinsOSError, MinerErrorData
|
||||||
|
from pyasic.errors import APIError
|
||||||
|
from pyasic.miners.base import BaseMiner
|
||||||
from pyasic.settings import PyasicSettings
|
from pyasic.settings import PyasicSettings
|
||||||
|
|
||||||
|
|
||||||
@@ -69,6 +66,27 @@ class BOSMiner(BaseMiner):
|
|||||||
# return the result, either command output or None
|
# return the result, either command output or None
|
||||||
return str(result)
|
return str(result)
|
||||||
|
|
||||||
|
async def send_graphql_query(self, query) -> Union[dict, None]:
|
||||||
|
url = f"http://{self.ip}/graphql"
|
||||||
|
try:
|
||||||
|
async with httpx.AsyncClient() as client:
|
||||||
|
_auth = await client.post(
|
||||||
|
url,
|
||||||
|
json={
|
||||||
|
"query": 'mutation{auth{login(username:"'
|
||||||
|
+ self.uname
|
||||||
|
+ '", password:"'
|
||||||
|
+ self.pwd
|
||||||
|
+ '"){__typename}}}'
|
||||||
|
},
|
||||||
|
)
|
||||||
|
d = await client.post(url, json={"query": query})
|
||||||
|
if d.status_code == 200:
|
||||||
|
return d.json()
|
||||||
|
except (httpx.ReadError, httpx.ReadTimeout):
|
||||||
|
return None
|
||||||
|
return None
|
||||||
|
|
||||||
async def fault_light_on(self) -> bool:
|
async def fault_light_on(self) -> bool:
|
||||||
"""Sends command to turn on fault light on the miner."""
|
"""Sends command to turn on fault light on the miner."""
|
||||||
logging.debug(f"{self}: Sending fault_light on command.")
|
logging.debug(f"{self}: Sending fault_light on command.")
|
||||||
@@ -152,6 +170,11 @@ class BOSMiner(BaseMiner):
|
|||||||
"""
|
"""
|
||||||
if self.hostname:
|
if self.hostname:
|
||||||
return self.hostname
|
return self.hostname
|
||||||
|
# get hostname through GraphQL
|
||||||
|
if data := await self.send_graphql_query("{bos {hostname}}"):
|
||||||
|
self.hostname = data["data"]["bos"]["hostname"]
|
||||||
|
return self.hostname
|
||||||
|
|
||||||
try:
|
try:
|
||||||
async with (await self._get_ssh_connection()) as conn:
|
async with (await self._get_ssh_connection()) as conn:
|
||||||
if conn is not None:
|
if conn is not None:
|
||||||
@@ -215,9 +238,15 @@ class BOSMiner(BaseMiner):
|
|||||||
if self.version:
|
if self.version:
|
||||||
logging.debug(f"Found version for {self.ip}: {self.version}")
|
logging.debug(f"Found version for {self.ip}: {self.version}")
|
||||||
return self.version
|
return self.version
|
||||||
|
version_data = None
|
||||||
|
# try to get data from graphql
|
||||||
|
data = await self.send_graphql_query("{bos{info{version{full}}}}")
|
||||||
|
if data:
|
||||||
|
version_data = data["bos"]["info"]["version"]["full"]
|
||||||
|
|
||||||
# get output of bos version file
|
if not version_data:
|
||||||
version_data = await self.send_ssh_command("cat /etc/bos_version")
|
# try version data file
|
||||||
|
version_data = await self.send_ssh_command("cat /etc/bos_version")
|
||||||
|
|
||||||
# if we get the version data, parse it
|
# if we get the version data, parse it
|
||||||
if version_data:
|
if version_data:
|
||||||
@@ -248,6 +277,15 @@ class BOSMiner(BaseMiner):
|
|||||||
async def check_light(self) -> bool:
|
async def check_light(self) -> bool:
|
||||||
if self.light:
|
if self.light:
|
||||||
return self.light
|
return self.light
|
||||||
|
# get light through GraphQL
|
||||||
|
if data := await self.send_graphql_query("{bos {faultLight}}"):
|
||||||
|
try:
|
||||||
|
self.light = data["data"]["bos"]["faultLight"]
|
||||||
|
return self.light
|
||||||
|
except (TypeError, KeyError, ValueError, IndexError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# get light via ssh if that fails (10x slower)
|
||||||
data = (
|
data = (
|
||||||
await self.send_ssh_command("cat /sys/class/leds/'Red LED'/delay_off")
|
await self.send_ssh_command("cat /sys/class/leds/'Red LED'/delay_off")
|
||||||
).strip()
|
).strip()
|
||||||
@@ -289,6 +327,7 @@ class BOSMiner(BaseMiner):
|
|||||||
if board["Status"] not in [
|
if board["Status"] not in [
|
||||||
"Stable",
|
"Stable",
|
||||||
"Testing performance profile",
|
"Testing performance profile",
|
||||||
|
"Tuning individual chips"
|
||||||
]:
|
]:
|
||||||
_error = board["Status"].split(" {")[0]
|
_error = board["Status"].split(" {")[0]
|
||||||
_error = _error[0].lower() + _error[1:]
|
_error = _error[0].lower() + _error[1:]
|
||||||
@@ -303,6 +342,10 @@ class BOSMiner(BaseMiner):
|
|||||||
Returns:
|
Returns:
|
||||||
A [`MinerData`][pyasic.data.MinerData] instance containing the miners data.
|
A [`MinerData`][pyasic.data.MinerData] instance containing the miners data.
|
||||||
"""
|
"""
|
||||||
|
d = await self._graphql_get_data()
|
||||||
|
if d:
|
||||||
|
return d
|
||||||
|
|
||||||
data = MinerData(
|
data = MinerData(
|
||||||
ip=str(self.ip),
|
ip=str(self.ip),
|
||||||
ideal_chips=self.nominal_chips * self.ideal_hashboards,
|
ideal_chips=self.nominal_chips * self.ideal_hashboards,
|
||||||
@@ -313,9 +356,6 @@ class BOSMiner(BaseMiner):
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
board_offset = -1
|
|
||||||
fan_offset = -1
|
|
||||||
|
|
||||||
model = await self.get_model()
|
model = await self.get_model()
|
||||||
hostname = await self.get_hostname()
|
hostname = await self.get_hostname()
|
||||||
mac = await self.get_mac()
|
mac = await self.get_mac()
|
||||||
@@ -342,7 +382,7 @@ class BOSMiner(BaseMiner):
|
|||||||
"devdetails",
|
"devdetails",
|
||||||
"fans",
|
"fans",
|
||||||
"devs",
|
"devs",
|
||||||
allow_warning=allow_warning
|
allow_warning=allow_warning,
|
||||||
)
|
)
|
||||||
except APIError as e:
|
except APIError as e:
|
||||||
if str(e.message) == "Not ready":
|
if str(e.message) == "Not ready":
|
||||||
@@ -441,7 +481,7 @@ class BOSMiner(BaseMiner):
|
|||||||
wattage_limit = tuner[0].get("PowerLimit")
|
wattage_limit = tuner[0].get("PowerLimit")
|
||||||
if wattage_limit:
|
if wattage_limit:
|
||||||
data.wattage_limit = wattage_limit
|
data.wattage_limit = wattage_limit
|
||||||
if wattage:
|
if wattage is not None:
|
||||||
data.wattage = wattage
|
data.wattage = wattage
|
||||||
|
|
||||||
chain_status = tuner[0].get("TunerChainStatus")
|
chain_status = tuner[0].get("TunerChainStatus")
|
||||||
@@ -493,6 +533,141 @@ class BOSMiner(BaseMiner):
|
|||||||
data.hashboards[_id].hashrate = hashrate
|
data.hashboards[_id].hashrate = hashrate
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
async def _graphql_get_data(self) -> Union[MinerData, None]:
|
||||||
|
data = MinerData(
|
||||||
|
ip=str(self.ip),
|
||||||
|
ideal_chips=self.nominal_chips * self.ideal_hashboards,
|
||||||
|
ideal_hashboards=self.ideal_hashboards,
|
||||||
|
hashboards=[
|
||||||
|
HashBoard(slot=i, expected_chips=self.nominal_chips, missing=True)
|
||||||
|
for i in range(self.ideal_hashboards)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
query = "{bos {hostname}, bosminer{config{... on BosminerConfig{groups{pools{url, user}, strategy{... on QuotaStrategy {quota}}}}}, info{fans{name, rpm}, workSolver{realHashrate{mhs1M}, temperatures{degreesC}, power{limitW, approxConsumptionW}, childSolvers{name, realHashrate{mhs1M}, hwDetails{chips}, tuner{statusMessages}, temperatures{degreesC}}}}}}"
|
||||||
|
query_data = await self.send_graphql_query(query)
|
||||||
|
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()
|
||||||
|
if query_data.get("bos"):
|
||||||
|
if query_data["bos"].get("hostname"):
|
||||||
|
data.hostname = query_data["bos"]["hostname"]
|
||||||
|
|
||||||
|
try:
|
||||||
|
if query_data["bosminer"]["info"]["workSolver"]["realHashrate"].get("mhs1M"):
|
||||||
|
data.hashrate = round(
|
||||||
|
query_data["bosminer"]["info"]["workSolver"]["realHashrate"]["mhs1M"]
|
||||||
|
/ 1000000,
|
||||||
|
2,
|
||||||
|
)
|
||||||
|
except (TypeError, KeyError, ValueError, IndexError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
boards = None
|
||||||
|
if query_data.get("bosminer"):
|
||||||
|
if query_data["bosminer"].get("info"):
|
||||||
|
if query_data["bosminer"]["info"].get("workSolver"):
|
||||||
|
boards = query_data["bosminer"]["info"]["workSolver"].get("childSolvers")
|
||||||
|
if boards:
|
||||||
|
offset = 6 if int(boards[0]["name"]) in [6, 7, 8] else int(boards[0]["name"])
|
||||||
|
for hb in boards:
|
||||||
|
_id = int(hb["name"]) - offset
|
||||||
|
|
||||||
|
board = data.hashboards[_id]
|
||||||
|
board.hashrate = round(hb["realHashrate"]["mhs1M"] / 1000000, 2)
|
||||||
|
temps = hb["temperatures"]
|
||||||
|
try:
|
||||||
|
if len(temps) > 0:
|
||||||
|
board.temp = round(hb["temperatures"][0]["degreesC"])
|
||||||
|
if len(temps) > 1:
|
||||||
|
board.chip_temp = round(hb["temperatures"][1]["degreesC"])
|
||||||
|
except (TypeError, KeyError, ValueError, IndexError):
|
||||||
|
pass
|
||||||
|
details = hb.get("hwDetails")
|
||||||
|
if details:
|
||||||
|
if chips := details["chips"]:
|
||||||
|
board.chips = chips
|
||||||
|
board.missing = False
|
||||||
|
|
||||||
|
tuner = hb.get("tuner")
|
||||||
|
if tuner:
|
||||||
|
if msg := tuner.get("statusMessages"):
|
||||||
|
if len(msg) > 0:
|
||||||
|
if hb["tuner"]["statusMessages"][0] not in [
|
||||||
|
"Stable",
|
||||||
|
"Testing performance profile",
|
||||||
|
"Tuning individual chips"
|
||||||
|
]:
|
||||||
|
data.errors.append(
|
||||||
|
BraiinsOSError(f"Slot {_id} {hb['tuner']['statusMessages'][0]}")
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
data.wattage = query_data["bosminer"]["info"]["workSolver"]["power"]["approxConsumptionW"]
|
||||||
|
except (TypeError, KeyError, ValueError, IndexError):
|
||||||
|
data.wattage = 0
|
||||||
|
try:
|
||||||
|
data.wattage_limit = query_data["bosminer"]["info"]["workSolver"]["power"]["limitW"]
|
||||||
|
except (TypeError, KeyError, ValueError, IndexError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
for n in range(self.fan_count):
|
||||||
|
try:
|
||||||
|
setattr(data, f"fan_{n + 1}", query_data["bosminer"]["info"]["fans"][n]["rpm"])
|
||||||
|
except (TypeError, KeyError, ValueError, IndexError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
groups = None
|
||||||
|
if query_data.get("bosminer"):
|
||||||
|
if query_data["bosminer"].get("config"):
|
||||||
|
groups = query_data["bosminer"]["config"].get("groups")
|
||||||
|
if groups:
|
||||||
|
if len(groups) == 1:
|
||||||
|
try:
|
||||||
|
data.pool_1_user = groups[0]["pools"][0]["user"]
|
||||||
|
except (TypeError, KeyError, ValueError, IndexError):
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
data.pool_1_url = groups[0]["pools"][0]["url"]
|
||||||
|
except (TypeError, KeyError, ValueError, IndexError):
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
data.pool_2_user = groups[0]["pools"][1]["user"]
|
||||||
|
except (TypeError, KeyError, ValueError, IndexError):
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
data.pool_2_url = groups[0]["pools"][1]["url"]
|
||||||
|
except (TypeError, KeyError, ValueError, IndexError):
|
||||||
|
pass
|
||||||
|
data.quota = 0
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
data.pool_1_user = groups[0]["pools"][0]["user"]
|
||||||
|
except (TypeError, KeyError, ValueError, IndexError):
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
data.pool_1_url = groups[0]["pools"][0]["url"]
|
||||||
|
except (TypeError, KeyError, ValueError, IndexError):
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
data.pool_2_user = groups[1]["pools"][0]["user"]
|
||||||
|
except (TypeError, KeyError, ValueError, IndexError):
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
data.pool_2_url = groups[1]["pools"][0]["url"]
|
||||||
|
except (TypeError, KeyError, ValueError, IndexError):
|
||||||
|
pass
|
||||||
|
if groups[0]["strategy"].get("quota"):
|
||||||
|
data.quota = str(groups[0]["strategy"]["quota"]) + "/" + str(groups[1]["strategy"]["quota"])
|
||||||
|
|
||||||
|
data.fault_light = await self.check_light()
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
async def get_mac(self):
|
async def get_mac(self):
|
||||||
result = await self.send_ssh_command("cat /sys/class/net/eth0/address")
|
result = await self.send_ssh_command("cat /sys/class/net/eth0/address")
|
||||||
return result.upper().strip()
|
return result.upper().strip()
|
||||||
|
|||||||
@@ -12,16 +12,15 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import ipaddress
|
import ipaddress
|
||||||
from typing import Union, List
|
import logging
|
||||||
|
from typing import List, Union
|
||||||
|
|
||||||
from pyasic.API.bosminer import BOSMinerAPI
|
from pyasic.API.bosminer import BOSMinerAPI
|
||||||
from pyasic.miners.base import BaseMiner
|
|
||||||
from pyasic.config import MinerConfig
|
from pyasic.config import MinerConfig
|
||||||
from pyasic.data import MinerData
|
from pyasic.data import MinerData
|
||||||
from pyasic.data.error_codes import MinerErrorData
|
from pyasic.data.error_codes import MinerErrorData
|
||||||
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class BOSMinerOld(BaseMiner):
|
class BOSMinerOld(BaseMiner):
|
||||||
@@ -105,5 +104,5 @@ class BOSMinerOld(BaseMiner):
|
|||||||
async def send_config(self, config: MinerConfig, user_suffix: str = None) -> None:
|
async def send_config(self, config: MinerConfig, user_suffix: str = None) -> None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
async def get_data(self) -> MinerData:
|
async def get_data(self, **kwargs) -> MinerData:
|
||||||
return MinerData(ip=str(self.ip))
|
return MinerData(ip=str(self.ip))
|
||||||
|
|||||||
@@ -14,17 +14,14 @@
|
|||||||
|
|
||||||
import ipaddress
|
import ipaddress
|
||||||
import logging
|
import logging
|
||||||
from typing import Union, List
|
from typing import List, Union
|
||||||
|
|
||||||
|
|
||||||
from pyasic.API.btminer import BTMinerAPI
|
from pyasic.API.btminer import BTMinerAPI
|
||||||
from pyasic.miners.base import BaseMiner
|
|
||||||
from pyasic.errors import APIError
|
|
||||||
|
|
||||||
from pyasic.data import MinerData, HashBoard
|
|
||||||
from pyasic.data.error_codes import WhatsminerError, MinerErrorData
|
|
||||||
from pyasic.config import MinerConfig
|
from pyasic.config import MinerConfig
|
||||||
|
from pyasic.data import HashBoard, MinerData
|
||||||
|
from pyasic.data.error_codes import MinerErrorData, WhatsminerError
|
||||||
|
from pyasic.errors import APIError
|
||||||
|
from pyasic.miners.base import BaseMiner
|
||||||
from pyasic.settings import PyasicSettings
|
from pyasic.settings import PyasicSettings
|
||||||
|
|
||||||
|
|
||||||
@@ -214,18 +211,24 @@ class BTMiner(BaseMiner):
|
|||||||
|
|
||||||
async def send_config(self, config: MinerConfig, user_suffix: str = None) -> None:
|
async def send_config(self, config: MinerConfig, user_suffix: str = None) -> None:
|
||||||
conf = config.as_wm(user_suffix=user_suffix)
|
conf = config.as_wm(user_suffix=user_suffix)
|
||||||
|
pools_conf = conf["pools"]
|
||||||
|
|
||||||
await self.api.update_pools(
|
await self.api.update_pools(
|
||||||
conf[0]["url"],
|
pools_conf[0]["url"],
|
||||||
conf[0]["user"],
|
pools_conf[0]["user"],
|
||||||
conf[0]["pass"],
|
pools_conf[0]["pass"],
|
||||||
conf[1]["url"],
|
pools_conf[1]["url"],
|
||||||
conf[1]["user"],
|
pools_conf[1]["user"],
|
||||||
conf[1]["pass"],
|
pools_conf[1]["pass"],
|
||||||
conf[2]["url"],
|
pools_conf[2]["url"],
|
||||||
conf[2]["user"],
|
pools_conf[2]["user"],
|
||||||
conf[2]["pass"],
|
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:
|
async def get_config(self) -> MinerConfig:
|
||||||
pools = None
|
pools = None
|
||||||
|
|||||||
@@ -14,17 +14,14 @@
|
|||||||
|
|
||||||
import ipaddress
|
import ipaddress
|
||||||
import logging
|
import logging
|
||||||
from typing import Union, List
|
from typing import List, Union
|
||||||
|
|
||||||
|
|
||||||
from pyasic.API.cgminer import CGMinerAPI
|
from pyasic.API.cgminer import CGMinerAPI
|
||||||
from pyasic.miners.base import BaseMiner
|
|
||||||
from pyasic.errors import APIError
|
|
||||||
from pyasic.config import MinerConfig
|
from pyasic.config import MinerConfig
|
||||||
|
from pyasic.data import HashBoard, MinerData
|
||||||
from pyasic.data import MinerData, HashBoard
|
|
||||||
from pyasic.data.error_codes import MinerErrorData
|
from pyasic.data.error_codes import MinerErrorData
|
||||||
|
from pyasic.errors import APIError
|
||||||
|
from pyasic.miners.base import BaseMiner
|
||||||
from pyasic.settings import PyasicSettings
|
from pyasic.settings import PyasicSettings
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -12,9 +12,10 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from pyasic.miners._backends import BMMiner
|
|
||||||
import ipaddress
|
import ipaddress
|
||||||
|
|
||||||
|
from pyasic.miners._backends import BMMiner
|
||||||
|
|
||||||
|
|
||||||
class Hiveon(BMMiner):
|
class Hiveon(BMMiner):
|
||||||
def __init__(self, ip: str) -> None:
|
def __init__(self, ip: str) -> None:
|
||||||
|
|||||||
@@ -14,5 +14,5 @@
|
|||||||
|
|
||||||
from .antminer import *
|
from .antminer import *
|
||||||
from .avalonminer import *
|
from .avalonminer import *
|
||||||
from .whatsminer import *
|
|
||||||
from .innosilicon import *
|
from .innosilicon import *
|
||||||
|
from .whatsminer import *
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class S17(BaseMiner):
|
class S17(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class S17Plus(BaseMiner):
|
class S17Plus(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class S17Pro(BaseMiner):
|
class S17Pro(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class S17e(BaseMiner):
|
class S17e(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class T17(BaseMiner):
|
class T17(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class T17Plus(BaseMiner):
|
class T17Plus(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class T17e(BaseMiner):
|
class T17e(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ from .S17 import S17
|
|||||||
from .S17_Plus import S17Plus
|
from .S17_Plus import S17Plus
|
||||||
from .S17_Pro import S17Pro
|
from .S17_Pro import S17Pro
|
||||||
from .S17e import S17e
|
from .S17e import S17e
|
||||||
|
|
||||||
from .T17 import T17
|
from .T17 import T17
|
||||||
from .T17_Plus import T17Plus
|
from .T17_Plus import T17Plus
|
||||||
from .T17e import T17e
|
from .T17e import T17e
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class S19(BaseMiner):
|
class S19(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class S19Pro(BaseMiner):
|
class S19Pro(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class S19XP(BaseMiner):
|
class S19XP(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class S19a(BaseMiner):
|
class S19a(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
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
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class S19j(BaseMiner):
|
class S19j(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class S19jPro(BaseMiner):
|
class S19jPro(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class T19(BaseMiner):
|
class T19(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|||||||
@@ -14,12 +14,9 @@
|
|||||||
|
|
||||||
from .S19 import S19
|
from .S19 import S19
|
||||||
from .S19_Pro import S19Pro
|
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 import S19j
|
||||||
from .S19j_Pro import S19jPro
|
from .S19j_Pro import S19jPro
|
||||||
|
|
||||||
from .S19_XP import S19XP
|
|
||||||
|
|
||||||
from .S19a import S19a
|
|
||||||
|
|
||||||
from .T19 import T19
|
from .T19 import T19
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class S9(BaseMiner):
|
class S9(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class S9i(BaseMiner):
|
class S9i(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class T9(BaseMiner):
|
class T9(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class Avalon1026(BaseMiner):
|
class Avalon1026(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class Avalon1047(BaseMiner):
|
class Avalon1047(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class Avalon1066(BaseMiner):
|
class Avalon1066(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|||||||
@@ -15,10 +15,11 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class Avalon721(BaseMiner):
|
class Avalon721(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
self.model = "Avalon 721"
|
self.model = "Avalon 721"
|
||||||
self.chip_count = 18 # This miner has 4 boards totaling 72
|
self.ideal_hashboards = 4
|
||||||
self.fan_count = 1 # also only 1 fan
|
self.chip_count = 18
|
||||||
|
self.fan_count = 1
|
||||||
|
|||||||
@@ -15,10 +15,11 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class Avalon741(BaseMiner):
|
class Avalon741(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
self.model = "Avalon 741"
|
self.model = "Avalon 741"
|
||||||
self.chip_count = 22 # This miner has 4 boards totaling 88
|
self.ideal_hashboards = 4
|
||||||
self.fan_count = 1 # also only 1 fan
|
self.chip_count = 22
|
||||||
|
self.fan_count = 1
|
||||||
|
|||||||
@@ -15,10 +15,11 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class Avalon761(BaseMiner):
|
class Avalon761(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
self.model = "Avalon 761"
|
self.model = "Avalon 761"
|
||||||
self.chip_count = 18 # This miner has 4 boards totaling 72
|
self.ideal_hashboards = 4
|
||||||
self.fan_count = 1 # also only 1 fan
|
self.chip_count = 18
|
||||||
|
self.fan_count = 1
|
||||||
|
|||||||
@@ -15,10 +15,11 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class Avalon821(BaseMiner):
|
class Avalon821(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
self.model = "Avalon 821"
|
self.model = "Avalon 821"
|
||||||
self.chip_count = 26 # This miner has 4 boards totaling 104
|
self.ideal_hashboards = 4
|
||||||
self.fan_count = 1 # also only 1 fan
|
self.chip_count = 26
|
||||||
|
self.fan_count = 1
|
||||||
|
|||||||
@@ -15,10 +15,11 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class Avalon841(BaseMiner):
|
class Avalon841(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
self.model = "Avalon 841"
|
self.model = "Avalon 841"
|
||||||
self.chip_count = 26 # This miner has 4 boards totaling 104
|
self.ideal_hashboards = 4
|
||||||
self.fan_count = 1 # also only 1 fan
|
self.chip_count = 26
|
||||||
|
self.fan_count = 1
|
||||||
|
|||||||
@@ -15,10 +15,11 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class Avalon851(BaseMiner):
|
class Avalon851(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
self.model = "Avalon 851"
|
self.model = "Avalon 851"
|
||||||
self.chip_count = 26 # This miner has 4 boards totaling 104
|
self.ideal_hashboards = 4
|
||||||
self.fan_count = 1 # also only 1 fan
|
self.chip_count = 26
|
||||||
|
self.fan_count = 1
|
||||||
|
|||||||
@@ -15,10 +15,11 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class Avalon921(BaseMiner):
|
class Avalon921(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
self.model = "Avalon 921"
|
self.model = "Avalon 921"
|
||||||
self.chip_count = 26 # This miner has 4 boards totaling 104
|
self.ideal_hashboards = 4
|
||||||
self.fan_count = 1 # also only 1 fan
|
self.chip_count = 26
|
||||||
|
self.fan_count = 1
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class InnosiliconT3HPlus(BaseMiner):
|
class InnosiliconT3HPlus(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str) -> None:
|
def __init__(self, ip: str) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class M20(BaseMiner):
|
class M20(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
@@ -24,7 +24,7 @@ class M20(BaseMiner):
|
|||||||
self.fan_count = 2
|
self.fan_count = 2
|
||||||
|
|
||||||
|
|
||||||
class M20V10(BaseMiner):
|
class M20V10(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class M20S(BaseMiner):
|
class M20S(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
@@ -24,7 +24,7 @@ class M20S(BaseMiner):
|
|||||||
self.fan_count = 2
|
self.fan_count = 2
|
||||||
|
|
||||||
|
|
||||||
class M20SV10(BaseMiner):
|
class M20SV10(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
@@ -33,7 +33,7 @@ class M20SV10(BaseMiner):
|
|||||||
self.fan_count = 2
|
self.fan_count = 2
|
||||||
|
|
||||||
|
|
||||||
class M20SV20(BaseMiner):
|
class M20SV20(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class M20SPlus(BaseMiner):
|
class M20SPlus(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class M21(BaseMiner):
|
class M21(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class M21S(BaseMiner):
|
class M21S(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
@@ -24,7 +24,7 @@ class M21S(BaseMiner):
|
|||||||
self.fan_count = 2
|
self.fan_count = 2
|
||||||
|
|
||||||
|
|
||||||
class M21SV60(BaseMiner):
|
class M21SV60(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
@@ -33,7 +33,7 @@ class M21SV60(BaseMiner):
|
|||||||
self.fan_count = 2
|
self.fan_count = 2
|
||||||
|
|
||||||
|
|
||||||
class M21SV20(BaseMiner):
|
class M21SV20(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class M21SPlus(BaseMiner):
|
class M21SPlus(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
from .M20 import M20, M20V10
|
from .M20 import M20, M20V10
|
||||||
from .M20S import M20S, M20SV10, M20SV20
|
from .M20S import M20S, M20SV10, M20SV20
|
||||||
from .M20S_Plus import M20SPlus
|
from .M20S_Plus import M20SPlus
|
||||||
|
|
||||||
from .M21 import M21
|
from .M21 import M21
|
||||||
from .M21S import M21S, M21SV20, M21SV60
|
from .M21S import M21S, M21SV20, M21SV60
|
||||||
from .M21S_Plus import M21SPlus
|
from .M21S_Plus import M21SPlus
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class M30S(BaseMiner):
|
class M30S(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
@@ -24,7 +24,7 @@ class M30S(BaseMiner):
|
|||||||
self.fan_count = 2
|
self.fan_count = 2
|
||||||
|
|
||||||
|
|
||||||
class M30SV50(BaseMiner):
|
class M30SV50(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
@@ -33,7 +33,7 @@ class M30SV50(BaseMiner):
|
|||||||
self.fan_count = 2
|
self.fan_count = 2
|
||||||
|
|
||||||
|
|
||||||
class M30SVG20(BaseMiner):
|
class M30SVG20(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
@@ -42,7 +42,7 @@ class M30SVG20(BaseMiner):
|
|||||||
self.fan_count = 2
|
self.fan_count = 2
|
||||||
|
|
||||||
|
|
||||||
class M30SVE20(BaseMiner):
|
class M30SVE20(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
@@ -51,7 +51,7 @@ class M30SVE20(BaseMiner):
|
|||||||
self.fan_count = 2
|
self.fan_count = 2
|
||||||
|
|
||||||
|
|
||||||
class M30SVE10(BaseMiner):
|
class M30SVE10(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class M30SPlus(BaseMiner):
|
class M30SPlus(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
@@ -24,7 +24,7 @@ class M30SPlus(BaseMiner):
|
|||||||
self.fan_count = 2
|
self.fan_count = 2
|
||||||
|
|
||||||
|
|
||||||
class M30SPlusVG60(BaseMiner):
|
class M30SPlusVG60(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
@@ -33,7 +33,7 @@ class M30SPlusVG60(BaseMiner):
|
|||||||
self.fan_count = 2
|
self.fan_count = 2
|
||||||
|
|
||||||
|
|
||||||
class M30SPlusVE40(BaseMiner):
|
class M30SPlusVE40(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
@@ -42,7 +42,7 @@ class M30SPlusVE40(BaseMiner):
|
|||||||
self.fan_count = 2
|
self.fan_count = 2
|
||||||
|
|
||||||
|
|
||||||
class M30SPlusVF20(BaseMiner):
|
class M30SPlusVF20(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class M30SPlusPlus(BaseMiner):
|
class M30SPlusPlus(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
@@ -24,7 +24,7 @@ class M30SPlusPlus(BaseMiner):
|
|||||||
self.fan_count = 2
|
self.fan_count = 2
|
||||||
|
|
||||||
|
|
||||||
class M30SPlusPlusVG30(BaseMiner):
|
class M30SPlusPlusVG30(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
@@ -33,7 +33,7 @@ class M30SPlusPlusVG30(BaseMiner):
|
|||||||
self.fan_count = 2
|
self.fan_count = 2
|
||||||
|
|
||||||
|
|
||||||
class M30SPlusPlusVG40(BaseMiner):
|
class M30SPlusPlusVG40(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
@@ -42,7 +42,7 @@ class M30SPlusPlusVG40(BaseMiner):
|
|||||||
self.fan_count = 2
|
self.fan_count = 2
|
||||||
|
|
||||||
|
|
||||||
class M30SPlusPlusVH60(BaseMiner):
|
class M30SPlusPlusVH60(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|||||||
@@ -15,10 +15,19 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class M31S(BaseMiner):
|
class M31S(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
self.model = "M31S"
|
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
|
self.fan_count = 2
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class M31SPlus(BaseMiner):
|
class M31SPlus(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
@@ -24,7 +24,7 @@ class M31SPlus(BaseMiner):
|
|||||||
self.fan_count = 2
|
self.fan_count = 2
|
||||||
|
|
||||||
|
|
||||||
class M31SPlusVE20(BaseMiner):
|
class M31SPlusVE20(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
@@ -33,7 +33,7 @@ class M31SPlusVE20(BaseMiner):
|
|||||||
self.fan_count = 2
|
self.fan_count = 2
|
||||||
|
|
||||||
|
|
||||||
class M31SPlusV30(BaseMiner):
|
class M31SPlusV30(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
@@ -42,7 +42,7 @@ class M31SPlusV30(BaseMiner):
|
|||||||
self.fan_count = 2
|
self.fan_count = 2
|
||||||
|
|
||||||
|
|
||||||
class M31SPlusV40(BaseMiner):
|
class M31SPlusV40(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
@@ -51,7 +51,7 @@ class M31SPlusV40(BaseMiner):
|
|||||||
self.fan_count = 2
|
self.fan_count = 2
|
||||||
|
|
||||||
|
|
||||||
class M31SPlusV60(BaseMiner):
|
class M31SPlusV60(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
@@ -60,7 +60,7 @@ class M31SPlusV60(BaseMiner):
|
|||||||
self.fan_count = 2
|
self.fan_count = 2
|
||||||
|
|
||||||
|
|
||||||
class M31SPlusV80(BaseMiner):
|
class M31SPlusV80(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
@@ -69,7 +69,7 @@ class M31SPlusV80(BaseMiner):
|
|||||||
self.fan_count = 2
|
self.fan_count = 2
|
||||||
|
|
||||||
|
|
||||||
class M31SPlusV90(BaseMiner):
|
class M31SPlusV90(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class M32(BaseMiner):
|
class M32(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
@@ -24,7 +24,7 @@ class M32(BaseMiner):
|
|||||||
self.fan_count = 2
|
self.fan_count = 2
|
||||||
|
|
||||||
|
|
||||||
class M32V20(BaseMiner):
|
class M32V20(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class M32S(BaseMiner):
|
class M32S(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class M34SPlus(BaseMiner):
|
class M34SPlus(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
@@ -25,7 +25,7 @@ class M34SPlus(BaseMiner):
|
|||||||
self.fan_count = 0
|
self.fan_count = 0
|
||||||
|
|
||||||
|
|
||||||
class M34SPlusVE10(BaseMiner):
|
class M34SPlusVE10(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|||||||
@@ -12,26 +12,24 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from .M30S import M30S, M30SVE10, M30SVE20, M30SVG20, M30SV50
|
from .M30S import M30S, M30SV50, M30SVE10, M30SVE20, M30SVG20
|
||||||
from .M30S_Plus import M30SPlus, M30SPlusVG60, M30SPlusVE40, M30SPlusVF20
|
from .M30S_Plus import M30SPlus, M30SPlusVE40, M30SPlusVF20, M30SPlusVG60
|
||||||
from .M30S_Plus_Plus import (
|
from .M30S_Plus_Plus import (
|
||||||
M30SPlusPlus,
|
M30SPlusPlus,
|
||||||
M30SPlusPlusVG30,
|
M30SPlusPlusVG30,
|
||||||
M30SPlusPlusVG40,
|
M30SPlusPlusVG40,
|
||||||
M30SPlusPlusVH60,
|
M30SPlusPlusVH60,
|
||||||
)
|
)
|
||||||
|
from .M31S import M31S, M31SV70
|
||||||
from .M31S import M31S
|
|
||||||
from .M31S_Plus import (
|
from .M31S_Plus import (
|
||||||
M31SPlus,
|
M31SPlus,
|
||||||
M31SPlusVE20,
|
|
||||||
M31SPlusV30,
|
M31SPlusV30,
|
||||||
M31SPlusV40,
|
M31SPlusV40,
|
||||||
M31SPlusV80,
|
|
||||||
M31SPlusV60,
|
M31SPlusV60,
|
||||||
|
M31SPlusV80,
|
||||||
M31SPlusV90,
|
M31SPlusV90,
|
||||||
|
M31SPlusVE20,
|
||||||
)
|
)
|
||||||
|
|
||||||
from .M32 import M32, M32V20
|
from .M32 import M32, M32V20
|
||||||
from .M32S import M32S
|
from .M32S import M32S
|
||||||
from .M34S_Plus import M34SPlus, M34SPlusVE10
|
from .M34S_Plus import M34SPlus, M34SPlusVE10
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
from pyasic.miners.base import BaseMiner
|
from pyasic.miners.base import BaseMiner
|
||||||
|
|
||||||
|
|
||||||
class M50(BaseMiner):
|
class M50(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
@@ -24,7 +24,7 @@ class M50(BaseMiner):
|
|||||||
self.fan_count = 2
|
self.fan_count = 2
|
||||||
|
|
||||||
|
|
||||||
class M50VH50(BaseMiner):
|
class M50VH50(BaseMiner): # noqa - ignore ABC method implementation
|
||||||
def __init__(self, ip: str):
|
def __init__(self, ip: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|||||||
@@ -12,9 +12,10 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from .X17 import BMMinerX17
|
|
||||||
from pyasic.miners._types import S17 # noqa - Ignore access to _module
|
from pyasic.miners._types import S17 # noqa - Ignore access to _module
|
||||||
|
|
||||||
|
from .X17 import BMMinerX17
|
||||||
|
|
||||||
|
|
||||||
class BMMinerS17(BMMinerX17, S17):
|
class BMMinerS17(BMMinerX17, S17):
|
||||||
def __init__(self, ip: str) -> None:
|
def __init__(self, ip: str) -> None:
|
||||||
|
|||||||
@@ -12,9 +12,10 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from .X17 import BMMinerX17
|
|
||||||
from pyasic.miners._types import S17Plus # noqa - Ignore access to _module
|
from pyasic.miners._types import S17Plus # noqa - Ignore access to _module
|
||||||
|
|
||||||
|
from .X17 import BMMinerX17
|
||||||
|
|
||||||
|
|
||||||
class BMMinerS17Plus(BMMinerX17, S17Plus):
|
class BMMinerS17Plus(BMMinerX17, S17Plus):
|
||||||
def __init__(self, ip: str) -> None:
|
def __init__(self, ip: str) -> None:
|
||||||
|
|||||||
@@ -12,9 +12,10 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from .X17 import BMMinerX17
|
|
||||||
from pyasic.miners._types import S17Pro # noqa - Ignore access to _module
|
from pyasic.miners._types import S17Pro # noqa - Ignore access to _module
|
||||||
|
|
||||||
|
from .X17 import BMMinerX17
|
||||||
|
|
||||||
|
|
||||||
class BMMinerS17Pro(BMMinerX17, S17Pro):
|
class BMMinerS17Pro(BMMinerX17, S17Pro):
|
||||||
def __init__(self, ip: str) -> None:
|
def __init__(self, ip: str) -> None:
|
||||||
|
|||||||
@@ -12,9 +12,10 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from .X17 import BMMinerX17
|
|
||||||
from pyasic.miners._types import S17e # noqa - Ignore access to _module
|
from pyasic.miners._types import S17e # noqa - Ignore access to _module
|
||||||
|
|
||||||
|
from .X17 import BMMinerX17
|
||||||
|
|
||||||
|
|
||||||
class BMMinerS17e(BMMinerX17, S17e):
|
class BMMinerS17e(BMMinerX17, S17e):
|
||||||
def __init__(self, ip: str) -> None:
|
def __init__(self, ip: str) -> None:
|
||||||
|
|||||||
@@ -12,9 +12,10 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from .X17 import BMMinerX17
|
|
||||||
from pyasic.miners._types import T17 # noqa - Ignore access to _module
|
from pyasic.miners._types import T17 # noqa - Ignore access to _module
|
||||||
|
|
||||||
|
from .X17 import BMMinerX17
|
||||||
|
|
||||||
|
|
||||||
class BMMinerT17(BMMinerX17, T17):
|
class BMMinerT17(BMMinerX17, T17):
|
||||||
def __init__(self, ip: str) -> None:
|
def __init__(self, ip: str) -> None:
|
||||||
|
|||||||
@@ -12,9 +12,10 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from .X17 import BMMinerX17
|
|
||||||
from pyasic.miners._types import T17Plus # noqa - Ignore access to _module
|
from pyasic.miners._types import T17Plus # noqa - Ignore access to _module
|
||||||
|
|
||||||
|
from .X17 import BMMinerX17
|
||||||
|
|
||||||
|
|
||||||
class BMMinerT17Plus(BMMinerX17, T17Plus):
|
class BMMinerT17Plus(BMMinerX17, T17Plus):
|
||||||
def __init__(self, ip: str) -> None:
|
def __init__(self, ip: str) -> None:
|
||||||
|
|||||||
@@ -12,9 +12,10 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from .X17 import BMMinerX17
|
|
||||||
from pyasic.miners._types import T17e # noqa - Ignore access to _module
|
from pyasic.miners._types import T17e # noqa - Ignore access to _module
|
||||||
|
|
||||||
|
from .X17 import BMMinerX17
|
||||||
|
|
||||||
|
|
||||||
class BMMinerT17e(BMMinerX17, T17e):
|
class BMMinerT17e(BMMinerX17, T17e):
|
||||||
def __init__(self, ip: str) -> None:
|
def __init__(self, ip: str) -> None:
|
||||||
|
|||||||
@@ -12,12 +12,12 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from pyasic.miners._backends import BMMiner # noqa - Ignore access to _module
|
from typing import Union
|
||||||
|
|
||||||
from pyasic.settings import PyasicSettings
|
|
||||||
|
|
||||||
import httpx
|
import httpx
|
||||||
from typing import Union
|
|
||||||
|
from pyasic.miners._backends import BMMiner # noqa - Ignore access to _module
|
||||||
|
from pyasic.settings import PyasicSettings
|
||||||
|
|
||||||
|
|
||||||
class BMMinerX17(BMMiner):
|
class BMMinerX17(BMMiner):
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ from .S17 import BMMinerS17
|
|||||||
from .S17_Plus import BMMinerS17Plus
|
from .S17_Plus import BMMinerS17Plus
|
||||||
from .S17_Pro import BMMinerS17Pro
|
from .S17_Pro import BMMinerS17Pro
|
||||||
from .S17e import BMMinerS17e
|
from .S17e import BMMinerS17e
|
||||||
|
|
||||||
from .T17 import BMMinerT17
|
from .T17 import BMMinerT17
|
||||||
from .T17_Plus import BMMinerT17Plus
|
from .T17_Plus import BMMinerT17Plus
|
||||||
from .T17e import BMMinerT17e
|
from .T17e import BMMinerT17e
|
||||||
|
|||||||
@@ -12,9 +12,10 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from .X19 import BMMinerX19
|
|
||||||
from pyasic.miners._types import S19 # noqa - Ignore access to _module
|
from pyasic.miners._types import S19 # noqa - Ignore access to _module
|
||||||
|
|
||||||
|
from .X19 import BMMinerX19
|
||||||
|
|
||||||
|
|
||||||
class BMMinerS19(BMMinerX19, S19):
|
class BMMinerS19(BMMinerX19, S19):
|
||||||
def __init__(self, ip: str) -> None:
|
def __init__(self, ip: str) -> None:
|
||||||
|
|||||||
@@ -12,9 +12,10 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from .X19 import BMMinerX19
|
|
||||||
from pyasic.miners._types import S19Pro # noqa - Ignore access to _module
|
from pyasic.miners._types import S19Pro # noqa - Ignore access to _module
|
||||||
|
|
||||||
|
from .X19 import BMMinerX19
|
||||||
|
|
||||||
|
|
||||||
class BMMinerS19Pro(BMMinerX19, S19Pro):
|
class BMMinerS19Pro(BMMinerX19, S19Pro):
|
||||||
def __init__(self, ip: str) -> None:
|
def __init__(self, ip: str) -> None:
|
||||||
|
|||||||
@@ -12,9 +12,10 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from .X19 import BMMinerX19
|
|
||||||
from pyasic.miners._types import S19XP # noqa - Ignore access to _module
|
from pyasic.miners._types import S19XP # noqa - Ignore access to _module
|
||||||
|
|
||||||
|
from .X19 import BMMinerX19
|
||||||
|
|
||||||
|
|
||||||
class BMMinerS19XP(BMMinerX19, S19XP):
|
class BMMinerS19XP(BMMinerX19, S19XP):
|
||||||
def __init__(self, ip: str) -> None:
|
def __init__(self, ip: str) -> None:
|
||||||
|
|||||||
@@ -12,9 +12,10 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from .X19 import BMMinerX19
|
|
||||||
from pyasic.miners._types import S19a # noqa - Ignore access to _module
|
from pyasic.miners._types import S19a # noqa - Ignore access to _module
|
||||||
|
|
||||||
|
from .X19 import BMMinerX19
|
||||||
|
|
||||||
|
|
||||||
class BMMinerS19a(BMMinerX19, S19a):
|
class BMMinerS19a(BMMinerX19, S19a):
|
||||||
def __init__(self, ip: str) -> None:
|
def __init__(self, ip: str) -> None:
|
||||||
|
|||||||
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
|
||||||
@@ -12,9 +12,10 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from .X19 import BMMinerX19
|
|
||||||
from pyasic.miners._types import S19j # noqa - Ignore access to _module
|
from pyasic.miners._types import S19j # noqa - Ignore access to _module
|
||||||
|
|
||||||
|
from .X19 import BMMinerX19
|
||||||
|
|
||||||
|
|
||||||
class BMMinerS19j(BMMinerX19, S19j):
|
class BMMinerS19j(BMMinerX19, S19j):
|
||||||
def __init__(self, ip: str) -> None:
|
def __init__(self, ip: str) -> None:
|
||||||
|
|||||||
@@ -12,9 +12,10 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from .X19 import BMMinerX19
|
|
||||||
from pyasic.miners._types import S19jPro # noqa - Ignore access to _module
|
from pyasic.miners._types import S19jPro # noqa - Ignore access to _module
|
||||||
|
|
||||||
|
from .X19 import BMMinerX19
|
||||||
|
|
||||||
|
|
||||||
class BMMinerS19jPro(BMMinerX19, S19jPro):
|
class BMMinerS19jPro(BMMinerX19, S19jPro):
|
||||||
def __init__(self, ip: str) -> None:
|
def __init__(self, ip: str) -> None:
|
||||||
|
|||||||
@@ -12,9 +12,10 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from .X19 import BMMinerX19
|
|
||||||
from pyasic.miners._types import T19 # noqa - Ignore access to _module
|
from pyasic.miners._types import T19 # noqa - Ignore access to _module
|
||||||
|
|
||||||
|
from .X19 import BMMinerX19
|
||||||
|
|
||||||
|
|
||||||
class BMMinerT19(BMMinerX19, T19):
|
class BMMinerT19(BMMinerX19, T19):
|
||||||
def __init__(self, ip: str) -> None:
|
def __init__(self, ip: str) -> None:
|
||||||
|
|||||||
@@ -12,16 +12,16 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from pyasic.miners._backends import BMMiner # noqa - Ignore access to _module
|
import asyncio
|
||||||
|
import json
|
||||||
from pyasic.config import MinerConfig
|
from typing import List, Union
|
||||||
from pyasic.data.error_codes import X19Error, MinerErrorData
|
|
||||||
from pyasic.settings import PyasicSettings
|
|
||||||
|
|
||||||
import httpx
|
import httpx
|
||||||
import json
|
|
||||||
import asyncio
|
from pyasic.config import MinerConfig
|
||||||
from typing import Union, List
|
from pyasic.data.error_codes import MinerErrorData, X19Error
|
||||||
|
from pyasic.miners._backends import BMMiner # noqa - Ignore access to _module
|
||||||
|
from pyasic.settings import PyasicSettings
|
||||||
|
|
||||||
|
|
||||||
class BMMinerX19(BMMiner):
|
class BMMinerX19(BMMiner):
|
||||||
@@ -62,7 +62,7 @@ class BMMinerX19(BMMiner):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
async with httpx.AsyncClient() as client:
|
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:
|
except httpx.ReadTimeout:
|
||||||
pass
|
pass
|
||||||
for i in range(7):
|
for i in range(7):
|
||||||
@@ -102,7 +102,7 @@ class BMMinerX19(BMMiner):
|
|||||||
auth = httpx.DigestAuth(self.uname, self.pwd)
|
auth = httpx.DigestAuth(self.uname, self.pwd)
|
||||||
data = json.dumps({"blink": "true"})
|
data = json.dumps({"blink": "true"})
|
||||||
async with httpx.AsyncClient() as client:
|
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:
|
if data.status_code == 200:
|
||||||
data = data.json()
|
data = data.json()
|
||||||
if data.get("code") == "B000":
|
if data.get("code") == "B000":
|
||||||
@@ -115,7 +115,7 @@ class BMMinerX19(BMMiner):
|
|||||||
auth = httpx.DigestAuth(self.uname, self.pwd)
|
auth = httpx.DigestAuth(self.uname, self.pwd)
|
||||||
data = json.dumps({"blink": "false"})
|
data = json.dumps({"blink": "false"})
|
||||||
async with httpx.AsyncClient() as client:
|
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:
|
if data.status_code == 200:
|
||||||
data = data.json()
|
data = data.json()
|
||||||
if data.get("code") == "B100":
|
if data.get("code") == "B100":
|
||||||
@@ -139,7 +139,10 @@ class BMMinerX19(BMMiner):
|
|||||||
async with httpx.AsyncClient() as client:
|
async with httpx.AsyncClient() as client:
|
||||||
data = await client.get(url, auth=auth)
|
data = await client.get(url, auth=auth)
|
||||||
if data:
|
if data:
|
||||||
data = data.json()
|
try:
|
||||||
|
data = data.json()
|
||||||
|
except json.decoder.JSONDecodeError:
|
||||||
|
return []
|
||||||
if "SUMMARY" in data.keys():
|
if "SUMMARY" in data.keys():
|
||||||
if "status" in data["SUMMARY"][0].keys():
|
if "status" in data["SUMMARY"][0].keys():
|
||||||
for item in data["SUMMARY"][0]["status"]:
|
for item in data["SUMMARY"][0]["status"]:
|
||||||
|
|||||||
@@ -14,12 +14,9 @@
|
|||||||
|
|
||||||
from .S19 import BMMinerS19
|
from .S19 import BMMinerS19
|
||||||
from .S19_Pro import BMMinerS19Pro
|
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 import BMMinerS19j
|
||||||
from .S19j_Pro import BMMinerS19jPro
|
from .S19j_Pro import BMMinerS19jPro
|
||||||
|
|
||||||
from .S19_XP import BMMinerS19XP
|
|
||||||
|
|
||||||
from .S19a import BMMinerS19a
|
|
||||||
|
|
||||||
from .T19 import BMMinerT19
|
from .T19 import BMMinerT19
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ from .S17 import BOSMinerS17
|
|||||||
from .S17_Plus import BOSMinerS17Plus
|
from .S17_Plus import BOSMinerS17Plus
|
||||||
from .S17_Pro import BOSMinerS17Pro
|
from .S17_Pro import BOSMinerS17Pro
|
||||||
from .S17e import BOSMinerS17e
|
from .S17e import BOSMinerS17e
|
||||||
|
|
||||||
from .T17 import BOSMinerT17
|
from .T17 import BOSMinerT17
|
||||||
from .T17_Plus import BOSMinerT17Plus
|
from .T17_Plus import BOSMinerT17Plus
|
||||||
from .T17e import BOSMinerT17e
|
from .T17e import BOSMinerT17e
|
||||||
|
|||||||
@@ -14,8 +14,6 @@
|
|||||||
|
|
||||||
from .S19 import BOSMinerS19
|
from .S19 import BOSMinerS19
|
||||||
from .S19_Pro import BOSMinerS19Pro
|
from .S19_Pro import BOSMinerS19Pro
|
||||||
|
|
||||||
from .S19j import BOSMinerS19j
|
from .S19j import BOSMinerS19j
|
||||||
from .S19j_Pro import BOSMinerS19jPro
|
from .S19j_Pro import BOSMinerS19jPro
|
||||||
|
|
||||||
from .T19 import BOSMinerT19
|
from .T19 import BOSMinerT19
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ from .S17 import CGMinerS17
|
|||||||
from .S17_Plus import CGMinerS17Plus
|
from .S17_Plus import CGMinerS17Plus
|
||||||
from .S17_Pro import CGMinerS17Pro
|
from .S17_Pro import CGMinerS17Pro
|
||||||
from .S17e import CGMinerS17e
|
from .S17e import CGMinerS17e
|
||||||
|
|
||||||
from .T17 import CGMinerT17
|
from .T17 import CGMinerT17
|
||||||
from .T17_Plus import CGMinerT17Plus
|
from .T17_Plus import CGMinerT17Plus
|
||||||
from .T17e import CGMinerT17e
|
from .T17e import CGMinerT17e
|
||||||
|
|||||||
@@ -14,8 +14,6 @@
|
|||||||
|
|
||||||
from .S19 import CGMinerS19
|
from .S19 import CGMinerS19
|
||||||
from .S19_Pro import CGMinerS19Pro
|
from .S19_Pro import CGMinerS19Pro
|
||||||
|
|
||||||
from .S19j import CGMinerS19j
|
from .S19j import CGMinerS19j
|
||||||
from .S19j_Pro import CGMinerS19jPro
|
from .S19j_Pro import CGMinerS19jPro
|
||||||
|
|
||||||
from .T19 import CGMinerT19
|
from .T19 import CGMinerT19
|
||||||
|
|||||||
@@ -12,10 +12,9 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
from pyasic.data import HashBoard, MinerData
|
||||||
from pyasic.miners._backends import Hiveon # noqa - Ignore access to _module
|
from pyasic.miners._backends import Hiveon # noqa - Ignore access to _module
|
||||||
from pyasic.miners._types import T9 # noqa - Ignore access to _module
|
from pyasic.miners._types import T9 # noqa - Ignore access to _module
|
||||||
|
|
||||||
from pyasic.data import MinerData, HashBoard
|
|
||||||
from pyasic.settings import PyasicSettings
|
from pyasic.settings import PyasicSettings
|
||||||
|
|
||||||
|
|
||||||
@@ -45,7 +44,6 @@ class HiveonT9(Hiveon, T9):
|
|||||||
ideal_hashboards=self.ideal_hashboards,
|
ideal_hashboards=self.ideal_hashboards,
|
||||||
)
|
)
|
||||||
|
|
||||||
board_offset = -1
|
|
||||||
fan_offset = -1
|
fan_offset = -1
|
||||||
|
|
||||||
model = await self.get_model()
|
model = await self.get_model()
|
||||||
|
|||||||
@@ -12,9 +12,10 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from .A10X import CGMinerA10X
|
|
||||||
from pyasic.miners._types import Avalon1026 # noqa - Ignore access to _module
|
from pyasic.miners._types import Avalon1026 # noqa - Ignore access to _module
|
||||||
|
|
||||||
|
from .A10X import CGMinerA10X
|
||||||
|
|
||||||
|
|
||||||
class CGMinerAvalon1026(CGMinerA10X, Avalon1026):
|
class CGMinerAvalon1026(CGMinerA10X, Avalon1026):
|
||||||
def __init__(self, ip: str) -> None:
|
def __init__(self, ip: str) -> None:
|
||||||
|
|||||||
@@ -12,9 +12,10 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from .A10X import CGMinerA10X
|
|
||||||
from pyasic.miners._types import Avalon1047 # noqa - Ignore access to _module
|
from pyasic.miners._types import Avalon1047 # noqa - Ignore access to _module
|
||||||
|
|
||||||
|
from .A10X import CGMinerA10X
|
||||||
|
|
||||||
|
|
||||||
class CGMinerAvalon1047(CGMinerA10X, Avalon1047):
|
class CGMinerAvalon1047(CGMinerA10X, Avalon1047):
|
||||||
def __init__(self, ip: str) -> None:
|
def __init__(self, ip: str) -> None:
|
||||||
|
|||||||
@@ -12,9 +12,10 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from .A10X import CGMinerA10X
|
|
||||||
from pyasic.miners._types import Avalon1066 # noqa - Ignore access to _module
|
from pyasic.miners._types import Avalon1066 # noqa - Ignore access to _module
|
||||||
|
|
||||||
|
from .A10X import CGMinerA10X
|
||||||
|
|
||||||
|
|
||||||
class CGMinerAvalon1066(CGMinerA10X, Avalon1066):
|
class CGMinerAvalon1066(CGMinerA10X, Avalon1066):
|
||||||
def __init__(self, ip: str) -> None:
|
def __init__(self, ip: str) -> None:
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user