Compare commits

...

63 Commits

Author SHA1 Message Date
UpstreamData
e9f54eec0a version: bump version number. 2022-11-30 10:01:27 -07:00
UpstreamData
fbbbc9f215 bug: Add VH60 to miner factory as it was missing. 2022-11-30 10:01:01 -07:00
UpstreamData
69e4f575c0 bug: fix a bug wth bosminer where it will sometimes not get data from graphql 2022-11-30 09:59:12 -07:00
UpstreamData
e95659d2e0 version: bump version number 2022-11-29 09:36:41 -07:00
UpstreamData
35f34310ec bug: fix an issue with incorrect type hinting. 2022-11-29 09:36:24 -07:00
UpstreamData
acc18e20fd Merge remote-tracking branch 'origin/master'
# Conflicts:
#	pyproject.toml
2022-11-24 11:04:19 -07:00
UpstreamData
72460eac08 version: bump version number 2022-11-24 11:03:54 -07:00
UpstreamData
3e5f9d4eca version: bump version number 2022-11-24 11:01:30 -07:00
UpstreamData
e873fa252c feature: add support for setting wattage on whatsminers with the new 2.0.5 API 2022-11-24 09:56:25 -07:00
UpstreamData
ff2c083a19 feature: add new whatsminer commands for version 2.0.5 2022-11-24 09:51:40 -07:00
UpstreamData
a30a84c34b version: bump version number 2022-11-22 18:28:02 -07:00
UpstreamData
97d2023298 feature: add support for whatsminer M31S V70 2022-11-22 18:27:35 -07:00
UpstreamData
1ce8430a14 version: bump version number 2022-11-21 11:28:29 -07:00
UpstreamData
1c0b638818 feature: add S19a Pro 2022-11-21 11:27:52 -07:00
UpstreamData
e852588eeb version: bump version number 2022-11-18 11:15:07 -07:00
UpstreamData
08b9bfd854 bug: fix error with getting miner failing to find a description key. 2022-11-18 11:14:35 -07:00
UpstreamData
7ee2f3a29a version: bump version number 2022-11-17 15:27:24 -07:00
UpstreamData
5ee6a38f39 bug: fix a bug with identifying some older version of BOSMiner. 2022-11-17 15:27:06 -07:00
UpstreamData
8f0bfd5f83 version: bump version number. 2022-11-16 14:30:52 -07:00
UpstreamData
c54f39fc77 bug: fix int and str addition in graphQL. 2022-11-16 14:30:29 -07:00
UpstreamData
eb40769ccf format: improve formatting 2022-11-15 11:28:35 -07:00
UpstreamData
418c62b40d version: bump version number 2022-11-14 13:50:28 -07:00
UpstreamData
198a480c35 bug: fix bug with read timeout not being caught when sending graphql query 2022-11-14 13:49:57 -07:00
UpstreamData
2d4bf4e847 version: bump version number 2022-11-14 11:20:54 -07:00
UpstreamData
774e3d1a62 bug: fix wattage not setting correctly for some BOS+ miners with issues. 2022-11-14 11:20:27 -07:00
UpstreamData
ade3cd6fee version: bump version number 2022-11-14 09:56:18 -07:00
UpstreamData
28dc3ccb84 version: bump version number 2022-11-14 09:51:34 -07:00
UpstreamData
6ca8582ec3 bug: improve robustness of identifying new versions of bosminer running BOSer. 2022-11-14 09:49:19 -07:00
UpstreamData
74b4aeb44a version: bump version number 2022-11-14 09:14:28 -07:00
UpstreamData
9c7ab5ac57 bug: fix support for new miners that return a BOSer string in version data. 2022-11-14 09:10:18 -07:00
Upstream Data
65ecf1fea2 version: bump version number 2022-11-13 19:36:25 -07:00
Upstream Data
44142c658b format: remove print statements 2022-11-13 19:36:07 -07:00
Upstream Data
25a205ce6c version: bump version number 2022-11-13 19:27:55 -07:00
Upstream Data
25094084cf bug: clarify uppercasing data from __get_model_from_graphql() 2022-11-13 19:27:32 -07:00
Upstream Data
4eac601153 version: bump version number 2022-11-13 19:17:43 -07:00
Upstream Data
f0d8d66b9b bug: fix not handling errors in send_graphql_query 2022-11-13 19:16:48 -07:00
Upstream Data
cfa550f8c0 version: bump version number 2022-11-13 19:07:56 -07:00
Arceris
91f6a5bf41 bug: catch TypeError on temps 2022-11-13 19:06:52 -07:00
Upstream Data
464bd6be65 version: bump version number. 2022-11-13 18:58:31 -07:00
Upstream Data
031d7e2186 bug: fix missing catching IndexError 2022-11-13 18:58:05 -07:00
Upstream Data
126b0d124c version: bump version number 2022-11-13 18:54:46 -07:00
Upstream Data
81c84a3e8f bug: fix a bug with no try except blocks on pools. 2022-11-13 18:54:26 -07:00
Upstream Data
406d5bd549 version: bump version number 2022-11-13 18:21:18 -07:00
Upstream Data
cd5fe09fd9 bug: fix wrong formatting for multiple error handling 2022-11-13 18:20:15 -07:00
Upstream Data
766fc4efed bug: fix check light not responding properly from graphQL. 2022-11-13 17:06:35 -07:00
Upstream Data
b70fed40c8 bug: add try except statements to get_data to fix bugs with getting data from graphql. 2022-11-13 17:03:41 -07:00
Upstream Data
255d98fd08 bug: fix some issues with validating data from graphql properly 2022-11-13 16:48:22 -07:00
Upstream Data
78304631f7 bug: fix errors not registering properly on braiins OS miners 2022-11-13 16:34:26 -07:00
Upstream Data
ab230844fc bug: fix an issue with chip count not receiving properly in some cases. 2022-11-13 16:31:41 -07:00
Upstream Data
8a58cb9fd3 format: remove extra print 2022-11-13 16:28:36 -07:00
Upstream Data
70b6ed73dc bug: fix manual return from __get_devdetails_and_version 2022-11-13 16:27:42 -07:00
Upstream Data
d2400bf44e bug: fix identifying stock as bosminer. 2022-11-13 16:22:57 -07:00
Upstream Data
db780fe876 version: bump version number 2022-11-13 15:14:16 -07:00
Upstream Data
cd84ae828a bug: fix a bug with some missing temperatures in graphql. 2022-11-13 15:13:56 -07:00
Upstream Data
970d5d1031 version: bump version number 2022-11-13 14:39:23 -07:00
Upstream Data
da0e327ec7 feature: add support for graphQL for BOS miners which may be having API issues, such as BBB. 2022-11-13 14:38:44 -07:00
Upstream Data
4c84a8d572 bug: ensure bosminer check_light backwards compatibility 2022-11-13 11:06:28 -07:00
Upstream Data
1cfd895deb feature: improve speed of bosminer check_light by 10x using graphql. 2022-11-13 11:01:22 -07:00
Upstream Data
d0da08eb10 version: bump version number 2022-11-12 14:51:30 -07:00
Upstream Data
ee4f2cd87d bug: fix win error check not being cross platform 2022-11-12 14:51:10 -07:00
UpstreamData
8a6577c8aa docs: Update README.md. 2022-11-10 14:20:41 -07:00
UpstreamData
ed5eae4187 format: add isort to dev requirements. 2022-11-10 14:17:31 -07:00
UpstreamData
f3b25027ad format: add isort to pre-commit and sort imports. 2022-11-10 14:15:45 -07:00
133 changed files with 798 additions and 397 deletions

View File

@@ -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

View File

@@ -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):

View File

@@ -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>

View File

@@ -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:

View File

@@ -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

View File

@@ -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):

View File

@@ -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:

View File

@@ -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.

View File

@@ -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__ = [

View File

@@ -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.

View File

@@ -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

View File

@@ -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

View File

@@ -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
) )

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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()

View File

@@ -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))

View File

@@ -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

View File

@@ -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

View File

@@ -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:

View File

@@ -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 *

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View 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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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:

View File

@@ -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:

View File

@@ -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:

View File

@@ -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:

View File

@@ -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:

View File

@@ -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:

View File

@@ -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:

View File

@@ -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):

View File

@@ -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

View File

@@ -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:

View File

@@ -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:

View File

@@ -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:

View File

@@ -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:

View 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

View File

@@ -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:

View File

@@ -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:

View File

@@ -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:

View File

@@ -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"]:

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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()

View File

@@ -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:

View File

@@ -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:

View File

@@ -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