Compare commits

..

14 Commits

Author SHA1 Message Date
UpstreamData
d84d95fe5f version: bump version number. 2023-12-21 15:25:57 -07:00
UpstreamData
0e5b811fb9 Add config attribute to data and refactor data naming (#81)
* feature: add config to MinerData.  Remove related attributes.

* feature: rename ideal and nominal to expected to make data naming consistent across files.

* refactor: run isort on all files.

* docs: update docstrings.
2023-12-21 15:20:50 -07:00
UpstreamData
3d31179562 feature: add more BOS+ supported types. 2023-12-19 08:40:31 -07:00
UpstreamData
69f39bef0c docs: update tagline 2023-12-19 08:18:06 -07:00
UpstreamData
1076dab7f5 Update README.md 2023-12-19 08:17:39 -07:00
UpstreamData
3ae1f700c2 docs: update README.md 2023-12-18 14:48:19 -07:00
UpstreamData
dc3f061b9b docs: update shields. 2023-12-18 14:44:43 -07:00
UpstreamData
52758dd8b3 docs: update README. 2023-12-18 14:33:42 -07:00
UpstreamData
0e492f1cfd tests: add more tests for miners. 2023-12-18 14:11:16 -07:00
UpstreamData
659dc55f3c bug: add missing key to epic data locations. 2023-12-18 14:07:46 -07:00
UpstreamData
eb9b29aca1 tests: add tests for config and update tests. 2023-12-18 14:00:40 -07:00
UpstreamData
b045abe76e bug: reorder config information and fix bad key. 2023-12-18 13:59:56 -07:00
Upstream Data
7a75818a20 version: bump version number. 2023-12-17 09:09:00 -07:00
Upstream Data
d2be68d35e bug: fix MinerConfig default values for 3.11+. Add MinerConfig.as_epic default implementation. 2023-12-17 09:08:14 -07:00
119 changed files with 1061 additions and 768 deletions

289
README.md
View File

@@ -1,142 +1,249 @@
# pyasic
*A simplified and standardized interface for Bitcoin ASICs.*
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
[![pypi](https://img.shields.io/pypi/v/pyasic.svg)](https://pypi.org/project/pyasic/)
[![python](https://img.shields.io/pypi/pyversions/pyasic.svg)](https://pypi.org/project/pyasic/)
[![Read the Docs](https://img.shields.io/readthedocs/pyasic)](https://pyasic.readthedocs.io/en/latest/)
[![GitHub](https://img.shields.io/github/license/UpstreamData/pyasic)](https://github.com/UpstreamData/pyasic/blob/master/LICENSE.txt)
[![CodeFactor Grade](https://img.shields.io/codefactor/grade/github/UpstreamData/pyasic)](https://www.codefactor.io/repository/github/upstreamdata/pyasic)
## Documentation and Supported Miners
Documentation is located on Read the Docs as [pyasic](https://pyasic.readthedocs.io/en/latest/).
[![PyPI - Version](https://img.shields.io/pypi/v/pyasic.svg)](https://pypi.org/project/pyasic/)
[![PyPI - Downloads](https://img.shields.io/pypi/dm/pyasic)](https://pypi.org/project/pyasic/)
Supported miners are listed in the docs, [here](https://pyasic.readthedocs.io/en/latest/miners/supported_types/).
[![Python - Supported Versions](https://img.shields.io/pypi/pyversions/pyasic.svg)](https://pypi.org/project/pyasic/)
[![CodeFactor - Grade](https://img.shields.io/codefactor/grade/github/UpstreamData/pyasic)](https://www.codefactor.io/repository/github/upstreamdata/pyasic)
[![Commit Activity - master](https://img.shields.io/github/commit-activity/y/UpstreamData/pyasic)](https://github.com/UpstreamData/pyasic/commits/master/)
## Installation
You can install pyasic directly from pip with the command `pip install pyasic`.
[![Code Style - Black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
[![Read The Docs - Docs](https://img.shields.io/readthedocs/pyasic)](https://pyasic.readthedocs.io/en/latest/)
[![License - Apache 2.0](https://img.shields.io/github/license/UpstreamData/pyasic)](https://github.com/UpstreamData/pyasic/blob/master/LICENSE.txt)
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).
---
## Intro
## 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.
Welcome to `pyasic`! `pyasic` uses an asynchronous method of communicating with ASIC miners on your network, which makes it super fast.
<br>
[Click here to view supported miner types](miners/supported_types.md)
This repo uses poetry for dependencies, which can be installed by following the guide on their website [here](https://python-poetry.org/docs/#installation).
---
## Getting started
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.
Getting started with `pyasic` is easy. First, find your miner (or miners) on the network by scanning for them or getting the correct class automatically for them if you know the IP.
Finally, initialize pre-commit hooks with `poetry run pre-commit install`.
### Documentation Testing
Testing the documentation can be done by running `poetry run mkdocs serve`, whcih will serve the documentation locally on port 8000.
## Interfacing with miners programmatically
There are 2 main ways to get a miner (and the functions attached to it), via scanning or via the `MinerFactory()`.
#### Scanning for miners
##### Scanning for miners
To scan for miners in `pyasic`, we use the class `MinerNetwork`, which abstracts the search, communication, identification, setup, and return of a miner to 1 command.
The command `MinerNetwork.scan()` returns a list that contains any miners found.
```python
import asyncio
from pyasic.network import MinerNetwork
import asyncio # asyncio for handling the async part
from pyasic.network import MinerNetwork # miner network handles the scanning
# define asynchronous function to scan for miners
async def scan_and_get_data():
# Define network range to be used for scanning
# This can take a list of IPs, a constructor string, or an IP and subnet mask
# The standard mask is /24 (x.x.x.0-255), and you can pass any IP address in the subnet
net = MinerNetwork("192.168.1.69", mask=24)
# Scan the network for miners
# This function returns a list of miners of the correct type as a class
miners: list = await net.scan_network_for_miners()
async def scan_miners(): # define async scan function to allow awaiting
# create a miner network
# you can pass in any IP and it will use that in a subnet with a /24 mask (255 IPs).
network = MinerNetwork.from_subnet("192.168.1.50/24") # this uses the 192.168.1.0-255 network
# We can now get data from any of these miners
# To do them all we have to create a list of tasks and gather them
tasks = [miner.get_data() for miner in miners]
# Gather all tasks asynchronously and run them
data = await asyncio.gather(*tasks)
# Data is now a list of MinerData, and we can reference any part of that
# Print out all data for now
for item in data:
print(item)
# scan for miners asynchronously
# this will return the correct type of miners if they are supported with all functionality.
miners = await network.scan()
print(miners)
if __name__ == "__main__":
asyncio.run(scan_and_get_data())
asyncio.run(scan_miners()) # run the scan asynchronously with asyncio.run()
```
---
##### Creating miners based on IP
If you already know the IP address of your miner or miners, you can use the `MinerFactory` to communicate and identify the miners, or an abstraction of its functionality, `get_miner()`.
The function `get_miner()` will return any miner it found at the IP address specified, or an `UnknownMiner` if it cannot identify the miner.
```python
import asyncio # asyncio for handling the async part
from pyasic import get_miner # handles miner creation
#### Getting a miner if you know the IP
async def get_miners(): # define async scan function to allow awaiting
# get the miner with the miner factory
# the miner factory is a singleton, and will always use the same object and cache
# this means you can always call it as MinerFactory().get_miner(), or just get_miner()
miner_1 = await get_miner("192.168.1.75")
miner_2 = await get_miner("192.168.1.76")
print(miner_1, miner_2)
# can also gather these, since they are async
# gathering them will get them both at the same time
# this makes it much faster to get a lot of miners at a time
tasks = [get_miner("192.168.1.75"), get_miner("192.168.1.76")]
miners = await asyncio.gather(*tasks)
print(miners)
if __name__ == "__main__":
asyncio.run(get_miners()) # get the miners asynchronously with asyncio.run()
```
---
## Data gathering
Once you have your miner(s) identified, you will likely want to get data from the miner(s). You can do this using a built-in function in each miner called `get_data()`.
This function will return an instance of the dataclass `MinerData` with all data it can gather from the miner.
Each piece of data in a `MinerData` instance can be referenced by getting it as an attribute, such as `MinerData().hashrate`.
##### One miner
```python
import asyncio
from pyasic import get_miner
async def gather_miner_data():
miner = await get_miner("192.168.1.75")
if miner is not None:
miner_data = await miner.get_data()
print(miner_data) # all data from the dataclass
print(miner_data.hashrate) # hashrate of the miner in TH/s
if __name__ == "__main__":
asyncio.run(gather_miner_data())
```
---
##### Multiple miners
You can do something similar with multiple miners, with only needing to make a small change to get all the data at once.
```python
import asyncio # asyncio for handling the async part
from pyasic.network import MinerNetwork # miner network handles the scanning
async def gather_miner_data(): # define async scan function to allow awaiting
network = MinerNetwork.from_subnet("192.168.1.50/24")
miners = await network.scan()
# we need to asyncio.gather() all the miners get_data() functions to make them run together
all_miner_data = await asyncio.gather(*[miner.get_data() for miner in miners])
for miner_data in all_miner_data:
print(miner_data) # print out all the data one by one
if __name__ == "__main__":
asyncio.run(gather_miner_data())
```
---
## Miner control
`pyasic` exposes a standard interface for each miner using control functions.
Every miner class in `pyasic` must implement all the control functions defined in `BaseMiner`.
These functions are
`check_light`,
`fault_light_off`,
`fault_light_on`,
`get_config`,
`get_data`,
`get_errors`,
`get_hostname`,
`get_model`,
`reboot`,
`restart_backend`,
`stop_mining`,
`resume_mining`,
`is_mining`,
`send_config`, and
`set_power_limit`.
##### Usage
```python
import asyncio
from pyasic import get_miner
# define asynchronous function to get miner and data
async def get_miner_data(miner_ip: str):
# Use MinerFactory to get miner
# MinerFactory is a singleton, so we can just get the instance in place
miner = await get_miner(miner_ip)
async def set_fault_light():
miner = await get_miner("192.168.1.20")
# Get data from the miner
data = await miner.get_data()
print(data)
# call control function
await miner.fault_light_on()
if __name__ == "__main__":
asyncio.run(get_miner_data("192.168.1.69"))
asyncio.run(set_fault_light())
```
### Advanced data gathering
---
## Helper dataclasses
If needed, this library exposes a wrapper for the miner API that can be used for advanced data gathering.
##### `MinerConfig` and `MinerData`
You can see more information on basic usage of the APIs past this example in the docs [here](https://pyasic.readthedocs.io/en/latest/API/api/).
`pyasic` implements a few dataclasses as helpers to make data return types consistent across different miners and miner APIs. The different fields of these dataclasses can all be viewed with the classmethod `cls.fields()`.
Please see the appropriate API documentation page (pyasic docs -> Advanced -> Miner APIs -> your API type) for a link to that specific miner's API documentation page and more information.
---
#### List available API commands
##### MinerData
`MinerData` is a return from the [`get_data()`](#get-data) function, and is used to have a consistent dataset across all returns.
You can call `MinerData.as_dict()` to get the dataclass as a dictionary, and there are many other helper functions contained in the class to convert to different data formats.
`MinerData` instances can also be added to each other to combine their data and can be divided by a number to divide all their data, allowing you to get average data from many miners by doing -
```python
from pyasic import MinerData
# examples of miner data
d1 = MinerData("192.168.1.1")
d2 = MinerData("192.168.1.2")
list_of_miner_data = [d1, d2]
average_data = sum(list_of_miner_data, start=MinerData("0.0.0.0"))/len(list_of_miner_data)
```
---
##### MinerConfig
`MinerConfig` is `pyasic`'s way to represent a configuration file from a miner.
It is designed to unionize the configuration of all supported miner types, and is the return from [`get_config()`](#get-config).
Each miner has a unique way to convert the `MinerConfig` to their specific type, there are helper functions in the class.
In most cases these helper functions should not be used, as [`send_config()`](#send-config) takes a [`MinerConfig` and will do the conversion to the right type for you.
You can use the `MinerConfig` as follows:
```python
import asyncio
from pyasic import get_miner
async def get_api_commands(miner_ip: str):
# Get the miner
miner = await get_miner(miner_ip)
async def set_fault_light():
miner = await get_miner("192.168.1.20")
# List all available commands
# Can also be called explicitly with the function miner.api.get_commands()
print(miner.api.commands)
# get config
cfg = await miner.get_config()
# send config
await miner.send_config(cfg)
if __name__ == "__main__":
asyncio.run(get_api_commands("192.168.1.69"))
asyncio.run(set_fault_light())
```
#### Use miner API commands to gather data
---
## Settings
The miner API commands will raise an `APIError` if they fail with a bad status code, to bypass this you must send them manually by using `miner.api.send_command(command, ignore_errors=True)`
`pyasic` has settings designed to make using large groups of miners easier. You can set the default password for all types of miners using the `pyasic.settings` module, used as follows:
```python
import asyncio
from pyasic import settings
from pyasic import get_miner
async def get_api_commands(miner_ip: str):
# Get the miner
miner = await get_miner(miner_ip)
# Run the devdetails command
# This is equivalent to await miner.api.send_command("devdetails")
devdetails: dict = await miner.api.devdetails()
print(devdetails)
if __name__ == "__main__":
asyncio.run(get_api_commands("192.168.1.69"))
settings.update("default_antminer_password", "my_pwd")
```
##### Default values:
```
"network_ping_retries": 1,
"network_ping_timeout": 3,
"network_scan_threads": 300,
"factory_get_retries": 1,
"factory_get_timeout": 3,
"get_data_retries": 1,
"api_function_timeout": 5,
"default_whatsminer_password": "admin",
"default_innosilicon_password": "admin",
"default_antminer_password": "root",
"default_bosminer_password": "root",
"default_vnish_password": "admin",
"default_goldshell_password": "123456789",
# ADVANCED
# Only use this if you know what you are doing
"socket_linger_time": 1000,
```

View File

@@ -1,12 +1,15 @@
# pyasic
*A set of modules for interfacing with many common types of ASIC bitcoin miners, using both their API and SSH.*
*A simplified and standardized interface for Bitcoin ASICs.*
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
[![pypi](https://img.shields.io/pypi/v/pyasic.svg)](https://pypi.org/project/pyasic/)
[![python](https://img.shields.io/pypi/pyversions/pyasic.svg)](https://pypi.org/project/pyasic/)
[![Read the Docs](https://img.shields.io/readthedocs/pyasic)](https://pyasic.readthedocs.io/en/latest/)
[![GitHub](https://img.shields.io/github/license/UpstreamData/pyasic)](https://github.com/UpstreamData/pyasic/blob/master/LICENSE.txt)
[![CodeFactor Grade](https://img.shields.io/codefactor/grade/github/UpstreamData/pyasic)](https://www.codefactor.io/repository/github/upstreamdata/pyasic)
[![PyPI - Version](https://img.shields.io/pypi/v/pyasic.svg)](https://pypi.org/project/pyasic/)
[![PyPI - Downloads](https://img.shields.io/pypi/dm/pyasic)](https://pypi.org/project/pyasic/)
[![Python - Supported Versions](https://img.shields.io/pypi/pyversions/pyasic.svg)](https://pypi.org/project/pyasic/)
[![CodeFactor - Grade](https://img.shields.io/codefactor/grade/github/UpstreamData/pyasic)](https://www.codefactor.io/repository/github/upstreamdata/pyasic)
[![Commit Activity - master](https://img.shields.io/github/commit-activity/y/UpstreamData/pyasic)](https://github.com/UpstreamData/pyasic/commits/master/)
[![Code Style - Black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
[![Read The Docs - Docs](https://img.shields.io/readthedocs/pyasic)](https://pyasic.readthedocs.io/en/latest/)
[![License - Apache 2.0](https://img.shields.io/github/license/UpstreamData/pyasic)](https://github.com/UpstreamData/pyasic/blob/master/LICENSE.txt)
---
## Intro

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from copy import deepcopy
from dataclasses import asdict, dataclass
from dataclasses import asdict, dataclass, field
from pyasic.config.fans import FanModeConfig
from pyasic.config.mining import MiningModeConfig
@@ -25,11 +25,13 @@ from pyasic.config.temperature import TemperatureConfig
@dataclass
class MinerConfig:
pools: PoolConfig = PoolConfig.default()
fan_mode: FanModeConfig = FanModeConfig.default()
temperature: TemperatureConfig = TemperatureConfig.default()
mining_mode: MiningModeConfig = MiningModeConfig.default()
power_scaling: PowerScalingConfig = PowerScalingConfig.default()
pools: PoolConfig = field(default_factory=PoolConfig.default)
fan_mode: FanModeConfig = field(default_factory=FanModeConfig.default)
temperature: TemperatureConfig = field(default_factory=TemperatureConfig.default)
mining_mode: MiningModeConfig = field(default_factory=MiningModeConfig.default)
power_scaling: PowerScalingConfig = field(
default_factory=PowerScalingConfig.default
)
def as_dict(self) -> dict:
return asdict(self)
@@ -106,6 +108,15 @@ class MinerConfig:
**self.power_scaling.as_bos_grpc(),
}
def as_epic(self, user_suffix: str = None) -> dict:
return {
**self.fan_mode.as_epic(),
**self.temperature.as_epic(),
**self.mining_mode.as_epic(),
**self.pools.as_epic(user_suffix=user_suffix),
**self.power_scaling.as_epic(),
}
@classmethod
def from_dict(cls, dict_conf: dict) -> "MinerConfig":
return cls(

View File

@@ -47,6 +47,9 @@ class MinerConfigOption(Enum):
def as_bos_grpc(self) -> dict:
return self.value.as_bos_grpc()
def as_epic(self) -> dict:
return self.value.as_epic()
def __call__(self, *args, **kwargs):
return self.value(*args, **kwargs)
@@ -87,3 +90,6 @@ class MinerConfigValue:
def as_bos_grpc(self) -> dict:
return {}
def as_epic(self) -> dict:
return {}

View File

@@ -37,16 +37,16 @@ class FanModeNormal(MinerConfigValue):
@dataclass
class FanModeManual(MinerConfigValue):
mode: str = field(init=False, default="manual")
minimum_fans: int = 1
speed: int = 100
minimum_fans: int = 1
@classmethod
def from_dict(cls, dict_conf: Union[dict, None]) -> "FanModeManual":
cls_conf = {}
if dict_conf.get("min_fans") is not None:
cls_conf["minimum_fans"] = dict_conf["minimum_fans"]
if dict_conf.get("speed") is not None:
cls_conf["speed"] = dict_conf["speed"]
if dict_conf.get("minimum_fans") is not None:
cls_conf["minimum_fans"] = dict_conf["minimum_fans"]
return cls(**cls_conf)
@classmethod

View File

@@ -22,6 +22,9 @@ from dataclasses import asdict, dataclass, field, fields
from datetime import datetime, timezone
from typing import Any, List, Union
from pyasic.config import MinerConfig
from pyasic.config.mining import MiningModePowerTune
from .error_codes import BraiinsOSError, InnosiliconError, WhatsminerError, X19Error
@@ -35,7 +38,7 @@ class HashBoard:
temp: The temperature of the PCB as an int.
chip_temp: The temperature of the chips as an int.
chips: The chip count of the board as an int.
expected_chips: The ideal chip count of the board as an int.
expected_chips: The expected chip count of the board as an int.
missing: Whether the board is returned from the miners data as a bool.
"""
@@ -105,7 +108,7 @@ class MinerData:
hostname: The network hostname of the miner as a str.
hashrate: The hashrate of the miner in TH/s as a float. Calculated automatically.
_hashrate: Backup for hashrate found via API instead of hashboards.
nominal_hashrate: The factory nominal hashrate of the miner in TH/s as a float.
expected_hashrate: The factory nominal hashrate of the miner in TH/s as a float.
hashboards: A list of hashboards on the miner with their statistics.
temperature_avg: The average temperature across the boards. Calculated automatically.
env_temp: The environment temps as a float.
@@ -114,10 +117,10 @@ class MinerData:
fans: A list of fans on the miner with their speeds.
fan_psu: The speed of the PSU on the fan if the miner collects it.
total_chips: The total number of chips on all boards. Calculated automatically.
ideal_chips: The ideal number of chips in the miner as an int.
percent_ideal_chips: The percent of total chips out of the ideal count. Calculated automatically.
percent_ideal_hashrate: The percent of total hashrate out of the ideal hashrate. Calculated automatically.
percent_ideal_wattage: The percent of total wattage out of the ideal wattage. Calculated automatically.
expected_chips: The expected number of chips in the miner as an int.
percent_expected_chips: The percent of total chips out of the expected count. Calculated automatically.
percent_expected_hashrate: The percent of total hashrate out of the expected hashrate. Calculated automatically.
percent_expected_wattage: The percent of total wattage out of the expected wattage. Calculated automatically.
nominal: Whether the number of chips in the miner is nominal. Calculated automatically.
pool_split: The pool split as a str.
pool_1_url: The first pool url on the miner as a str.
@@ -140,27 +143,24 @@ class MinerData:
fw_ver: str = None
hostname: str = None
hashrate: float = field(init=False)
_hashrate: float = None
nominal_hashrate: float = None
_hashrate: float = field(repr=False, default=None)
expected_hashrate: float = None
hashboards: List[HashBoard] = field(default_factory=list)
ideal_hashboards: int = None
expected_hashboards: int = None
temperature_avg: int = field(init=False)
env_temp: float = None
wattage: int = None
wattage_limit: int = None
wattage_limit: int = field(init=False)
_wattage_limit: int = field(repr=False, default=None)
fans: List[Fan] = field(default_factory=list)
fan_psu: int = None
total_chips: int = field(init=False)
ideal_chips: int = None
percent_ideal_chips: float = field(init=False)
percent_ideal_hashrate: float = field(init=False)
percent_ideal_wattage: float = field(init=False)
expected_chips: int = None
percent_expected_chips: float = field(init=False)
percent_expected_hashrate: float = field(init=False)
percent_expected_wattage: float = field(init=False)
nominal: bool = field(init=False)
pool_split: str = "0"
pool_1_url: str = "Unknown"
pool_1_user: str = "Unknown"
pool_2_url: str = ""
pool_2_user: str = ""
config: MinerConfig = None
errors: List[
Union[WhatsminerError, BraiinsOSError, X19Error, InnosiliconError]
] = field(default_factory=list)
@@ -170,7 +170,11 @@ class MinerData:
@classmethod
def fields(cls):
return [f.name for f in fields(cls)]
return [f.name for f in fields(cls) if not f.name.startswith("_")]
@staticmethod
def dict_factory(x):
return {k: v for (k, v) in x if not k.startswith("_")}
def __post_init__(self):
self.datetime = datetime.now(timezone.utc).astimezone()
@@ -248,6 +252,17 @@ class MinerData:
def hashrate(self, val):
self._hashrate = val
@property
def wattage_limit(self): # noqa - Skip PyCharm inspection
if self.config is not None:
if isinstance(self.config.mining_mode, MiningModePowerTune):
return self.config.mining_mode.power
return self._wattage_limit
@wattage_limit.setter
def wattage_limit(self, val: int):
self._wattage_limit = val
@property
def total_chips(self): # noqa - Skip PyCharm inspection
if len(self.hashboards) > 0:
@@ -265,48 +280,48 @@ class MinerData:
@property
def nominal(self): # noqa - Skip PyCharm inspection
if self.total_chips is None or self.ideal_chips is None:
if self.total_chips is None or self.expected_chips is None:
return None
return self.ideal_chips == self.total_chips
return self.expected_chips == self.total_chips
@nominal.setter
def nominal(self, val):
pass
@property
def percent_ideal_chips(self): # noqa - Skip PyCharm inspection
if self.total_chips is None or self.ideal_chips is None:
def percent_expected_chips(self): # noqa - Skip PyCharm inspection
if self.total_chips is None or self.expected_chips is None:
return None
if self.total_chips == 0 or self.ideal_chips == 0:
if self.total_chips == 0 or self.expected_chips == 0:
return 0
return round((self.total_chips / self.ideal_chips) * 100)
return round((self.total_chips / self.expected_chips) * 100)
@percent_ideal_chips.setter
def percent_ideal_chips(self, val):
@percent_expected_chips.setter
def percent_expected_chips(self, val):
pass
@property
def percent_ideal_hashrate(self): # noqa - Skip PyCharm inspection
if self.hashrate is None or self.nominal_hashrate is None:
def percent_expected_hashrate(self): # noqa - Skip PyCharm inspection
if self.hashrate is None or self.expected_hashrate is None:
return None
if self.hashrate == 0 or self.nominal_hashrate == 0:
if self.hashrate == 0 or self.expected_hashrate == 0:
return 0
return round((self.hashrate / self.nominal_hashrate) * 100)
return round((self.hashrate / self.expected_hashrate) * 100)
@percent_ideal_hashrate.setter
def percent_ideal_hashrate(self, val):
@percent_expected_hashrate.setter
def percent_expected_hashrate(self, val):
pass
@property
def percent_ideal_wattage(self): # noqa - Skip PyCharm inspection
def percent_expected_wattage(self): # noqa - Skip PyCharm inspection
if self.wattage_limit is None or self.wattage is None:
return None
if self.wattage_limit == 0 or self.wattage == 0:
return 0
return round((self.wattage / self.wattage_limit) * 100)
@percent_ideal_wattage.setter
def percent_ideal_wattage(self, val):
@percent_expected_wattage.setter
def percent_expected_wattage(self, val):
pass
@property
@@ -339,7 +354,7 @@ class MinerData:
def asdict(self) -> dict:
logging.debug(f"MinerData - (To Dict) - Dumping Dict data")
return asdict(self)
return asdict(self, dict_factory=self.dict_factory)
def as_dict(self) -> dict:
"""Get this dataclass as a dictionary.

View File

@@ -137,10 +137,10 @@ class _MinerPhaseBalancer:
for miner in self.miners
]
)
pct_ideal_list = [d.percent_ideal for d in data]
pct_expected_list = [d.percent_ideal for d in data]
pct_ideal = 0
if len(pct_ideal_list) > 0:
pct_ideal = sum(pct_ideal_list) / len(pct_ideal_list)
if len(pct_expected_list) > 0:
pct_ideal = sum(pct_expected_list) / len(pct_expected_list)
wattage = round(wattage * 1 / (pct_ideal / 100))

View File

@@ -17,7 +17,7 @@
from .bmminer import *
from .bosminer import *
from .cgminer import *
from .epic import *
from .hiveon import *
from .luxos import *
from .vnish import *
from .epic import *

View File

@@ -15,17 +15,37 @@
# ------------------------------------------------------------------------------
from pyasic.miners.backends import BOSMiner
from pyasic.miners.types import S19, S19j, S19jNoPIC, S19jPro, S19kProNoPIC, S19Pro
from pyasic.miners.types import (
S19,
S19XP,
S19a,
S19aPro,
S19j,
S19jNoPIC,
S19jPro,
S19jProPlus,
S19kProNoPIC,
S19Plus,
S19Pro,
)
class BOSMinerS19(BOSMiner, S19):
pass
class BOSMinerS19Plus(BOSMiner, S19Plus):
pass
class BOSMinerS19Pro(BOSMiner, S19Pro):
pass
class BOSMinerS19a(BOSMiner, S19a):
pass
class BOSMinerS19j(BOSMiner, S19j):
pass
@@ -40,3 +60,15 @@ class BOSMinerS19jPro(BOSMiner, S19jPro):
class BOSMinerS19kProNoPIC(BOSMiner, S19kProNoPIC):
pass
class BOSMinerS19aPro(BOSMiner, S19aPro):
pass
class BOSMinerS19jProPlus(BOSMiner, S19jProPlus):
pass
class BOSMinerS19XP(BOSMiner, S19XP):
pass

View File

@@ -16,10 +16,15 @@
from .S19 import (
BOSMinerS19,
BOSMinerS19a,
BOSMinerS19aPro,
BOSMinerS19j,
BOSMinerS19jNoPIC,
BOSMinerS19jPro,
BOSMinerS19jProPlus,
BOSMinerS19kProNoPIC,
BOSMinerS19Plus,
BOSMinerS19Pro,
BOSMinerS19XP,
)
from .T19 import BOSMinerT19

View File

@@ -16,10 +16,10 @@
from .S19 import (
ePICS19,
ePICS19Pro,
ePICS19j,
ePICS19jPro,
ePICS19jProPlus,
ePICS19kPro,
ePICS19Pro,
ePICS19XP,
)

View File

@@ -54,7 +54,7 @@ class HiveonT9(Hiveon, T9):
hashboards = []
for board in board_map:
hashboard = HashBoard(slot=board, expected_chips=self.nominal_chips)
hashboard = HashBoard(slot=board, expected_chips=self.expected_chips)
hashrate = 0
chips = 0
for chipset in board_map[board]:

View File

@@ -21,8 +21,8 @@ from .bosminer import BOSMiner
from .btminer import BTMiner
from .cgminer import CGMiner
from .cgminer_avalon import CGMinerAvalon
from .epic import ePIC
from .hiveon import Hiveon
from .luxminer import LUXMiner
from .vnish import VNish
from .epic import ePIC
from .whatsminer import M2X, M3X, M5X, M6X

View File

@@ -38,8 +38,8 @@ ANTMINER_MODERN_DATA_LOC = {
"kwargs": {"web_get_system_info": {"web": "get_system_info"}},
},
"hashrate": {"cmd": "get_hashrate", "kwargs": {"api_summary": {"api": "summary"}}},
"nominal_hashrate": {
"cmd": "get_nominal_hashrate",
"expected_hashrate": {
"cmd": "get_expected_hashrate",
"kwargs": {"api_stats": {"api": "stats"}},
},
"hashboards": {"cmd": "get_hashboards", "kwargs": {"api_stats": {"api": "stats"}}},
@@ -62,6 +62,10 @@ ANTMINER_MODERN_DATA_LOC = {
"cmd": "get_uptime",
"kwargs": {"api_stats": {"api": "stats"}},
},
"config": {
"cmd": "get_config",
"kwargs": {},
},
}
@@ -198,7 +202,7 @@ class AntminerModern(BMMiner):
pass
return self.light
async def get_nominal_hashrate(self, api_stats: dict = None) -> Optional[float]:
async def get_expected_hashrate(self, api_stats: dict = None) -> Optional[float]:
if not api_stats:
try:
api_stats = await self.api.stats()
@@ -207,17 +211,17 @@ class AntminerModern(BMMiner):
if api_stats:
try:
ideal_rate = api_stats["STATS"][1]["total_rateideal"]
expected_rate = api_stats["STATS"][1]["total_rateideal"]
try:
rate_unit = api_stats["STATS"][1]["rate_unit"]
except KeyError:
rate_unit = "GH"
if rate_unit == "GH":
return round(ideal_rate / 1000, 2)
return round(expected_rate / 1000, 2)
if rate_unit == "MH":
return round(ideal_rate / 1000000, 2)
return round(expected_rate / 1000000, 2)
else:
return round(ideal_rate, 2)
return round(expected_rate, 2)
except (KeyError, IndexError):
pass
@@ -296,10 +300,7 @@ class AntminerModern(BMMiner):
ANTMINER_OLD_DATA_LOC = {
"mac": {"cmd": "get_mac", "kwargs": {}},
"model": {
"cmd": "get_model",
"kwargs": {},
},
"model": {"cmd": "get_model", "kwargs": {}},
"api_ver": {"cmd": "get_api_ver", "kwargs": {"api_version": {"api": "version"}}},
"fw_ver": {"cmd": "get_fw_ver", "kwargs": {"api_version": {"api": "version"}}},
"hostname": {
@@ -307,8 +308,8 @@ ANTMINER_OLD_DATA_LOC = {
"kwargs": {"web_get_system_info": {"web": "get_system_info"}},
},
"hashrate": {"cmd": "get_hashrate", "kwargs": {"api_summary": {"api": "summary"}}},
"nominal_hashrate": {
"cmd": "get_nominal_hashrate",
"expected_hashrate": {
"cmd": "get_expected_hashrate",
"kwargs": {"api_stats": {"api": "stats"}},
},
"hashboards": {"cmd": "get_hashboards", "kwargs": {"api_stats": {"api": "stats"}}},
@@ -327,10 +328,8 @@ ANTMINER_OLD_DATA_LOC = {
"cmd": "is_mining",
"kwargs": {"web_get_conf": {"web": "get_miner_conf"}},
},
"uptime": {
"cmd": "get_uptime",
"kwargs": {"api_stats": {"api": "stats"}},
},
"uptime": {"cmd": "get_uptime", "kwargs": {"api_stats": {"api": "stats"}}},
"config": {"cmd": "get_config", "kwargs": {}},
}
@@ -472,9 +471,11 @@ class AntminerOld(CGMiner):
if board_offset == -1:
board_offset = 1
for i in range(board_offset, board_offset + self.ideal_hashboards):
for i in range(
board_offset, board_offset + self.expected_hashboards
):
hashboard = HashBoard(
slot=i - board_offset, expected_chips=self.nominal_chips
slot=i - board_offset, expected_chips=self.expected_chips
)
chip_temp = boards[1].get(f"temp{i}")

View File

@@ -31,8 +31,8 @@ BFGMINER_DATA_LOC = {
"fw_ver": {"cmd": "get_fw_ver", "kwargs": {"api_version": {"api": "version"}}},
"hostname": {"cmd": "get_hostname", "kwargs": {}},
"hashrate": {"cmd": "get_hashrate", "kwargs": {"api_summary": {"api": "summary"}}},
"nominal_hashrate": {
"cmd": "get_nominal_hashrate",
"expected_hashrate": {
"cmd": "get_expected_hashrate",
"kwargs": {"api_stats": {"api": "stats"}},
},
"hashboards": {"cmd": "get_hashboards", "kwargs": {"api_stats": {"api": "stats"}}},
@@ -46,6 +46,7 @@ BFGMINER_DATA_LOC = {
"pools": {"cmd": "get_pools", "kwargs": {"api_pools": {"api": "pools"}}},
"is_mining": {"cmd": "is_mining", "kwargs": {}},
"uptime": {"cmd": "get_uptime", "kwargs": {}},
"config": {"cmd": "get_config", "kwargs": {}},
}
@@ -197,9 +198,11 @@ class BFGMiner(BaseMiner):
if board_offset == -1:
board_offset = 1
for i in range(board_offset, board_offset + self.ideal_hashboards):
for i in range(
board_offset, board_offset + self.expected_hashboards
):
hashboard = HashBoard(
slot=i - board_offset, expected_chips=self.nominal_chips
slot=i - board_offset, expected_chips=self.expected_chips
)
chip_temp = boards[1].get(f"temp{i}")
@@ -297,7 +300,7 @@ class BFGMiner(BaseMiner):
async def get_fault_light(self) -> bool:
return False
async def get_nominal_hashrate(self, api_stats: dict = None) -> Optional[float]:
async def get_expected_hashrate(self, api_stats: dict = None) -> Optional[float]:
# X19 method, not sure compatibility
if not api_stats:
try:
@@ -307,17 +310,17 @@ class BFGMiner(BaseMiner):
if api_stats:
try:
ideal_rate = api_stats["STATS"][1]["total_rateideal"]
expected_rate = api_stats["STATS"][1]["total_rateideal"]
try:
rate_unit = api_stats["STATS"][1]["rate_unit"]
except KeyError:
rate_unit = "GH"
if rate_unit == "GH":
return round(ideal_rate / 1000, 2)
return round(expected_rate / 1000, 2)
if rate_unit == "MH":
return round(ideal_rate / 1000000, 2)
return round(expected_rate / 1000000, 2)
else:
return round(ideal_rate, 2)
return round(expected_rate, 2)
except (KeyError, IndexError):
pass

View File

@@ -29,8 +29,8 @@ GOLDSHELL_DATA_LOC = {
"fw_ver": {"cmd": "get_fw_ver", "kwargs": {"web_status": {"web": "status"}}},
"hostname": {"cmd": "get_hostname", "kwargs": {}},
"hashrate": {"cmd": "get_hashrate", "kwargs": {"api_summary": {"api": "summary"}}},
"nominal_hashrate": {
"cmd": "get_nominal_hashrate",
"expected_hashrate": {
"cmd": "get_expected_hashrate",
"kwargs": {"api_stats": {"api": "stats"}},
},
"hashboards": {
@@ -50,6 +50,10 @@ GOLDSHELL_DATA_LOC = {
"pools": {"cmd": "get_pools", "kwargs": {"api_pools": {"api": "pools"}}},
"is_mining": {"cmd": "is_mining", "kwargs": {}},
"uptime": {"cmd": "get_uptime", "kwargs": {}},
"config": {
"cmd": "get_config",
"kwargs": {},
},
}
@@ -128,8 +132,8 @@ class BFGMinerGoldshell(BFGMiner):
pass
hashboards = [
HashBoard(slot=i, expected_chips=self.nominal_chips)
for i in range(self.ideal_hashboards)
HashBoard(slot=i, expected_chips=self.expected_chips)
for i in range(self.expected_hashboards)
]
if api_devs:

View File

@@ -32,8 +32,8 @@ BMMINER_DATA_LOC = {
"fw_ver": {"cmd": "get_fw_ver", "kwargs": {"api_version": {"api": "version"}}},
"hostname": {"cmd": "get_hostname", "kwargs": {}},
"hashrate": {"cmd": "get_hashrate", "kwargs": {"api_summary": {"api": "summary"}}},
"nominal_hashrate": {
"cmd": "get_nominal_hashrate",
"expected_hashrate": {
"cmd": "get_expected_hashrate",
"kwargs": {"api_stats": {"api": "stats"}},
},
"hashboards": {"cmd": "get_hashboards", "kwargs": {"api_stats": {"api": "stats"}}},
@@ -46,10 +46,8 @@ BMMINER_DATA_LOC = {
"fault_light": {"cmd": "get_fault_light", "kwargs": {}},
"pools": {"cmd": "get_pools", "kwargs": {"api_pools": {"api": "pools"}}},
"is_mining": {"cmd": "is_mining", "kwargs": {}},
"uptime": {
"cmd": "get_uptime",
"kwargs": {"api_stats": {"api": "stats"}},
},
"uptime": {"cmd": "get_uptime", "kwargs": {"api_stats": {"api": "stats"}}},
"config": {"cmd": "get_config", "kwargs": {}},
}
@@ -247,12 +245,12 @@ class BMMiner(BaseMiner):
if len(real_slots) < 3:
real_slots = list(
range(board_offset, board_offset + self.ideal_hashboards)
range(board_offset, board_offset + self.expected_hashboards)
)
for i in real_slots:
hashboard = HashBoard(
slot=i - board_offset, expected_chips=self.nominal_chips
slot=i - board_offset, expected_chips=self.expected_chips
)
chip_temp = boards[1].get(f"temp{i}")
@@ -349,7 +347,7 @@ class BMMiner(BaseMiner):
async def get_fault_light(self) -> bool:
return False
async def get_nominal_hashrate(self, api_stats: dict = None) -> Optional[float]:
async def get_expected_hashrate(self, api_stats: dict = None) -> Optional[float]:
# X19 method, not sure compatibility
if not api_stats:
try:
@@ -359,17 +357,17 @@ class BMMiner(BaseMiner):
if api_stats:
try:
ideal_rate = api_stats["STATS"][1]["total_rateideal"]
expected_rate = api_stats["STATS"][1]["total_rateideal"]
try:
rate_unit = api_stats["STATS"][1]["rate_unit"]
except KeyError:
rate_unit = "GH"
if rate_unit == "GH":
return round(ideal_rate / 1000, 2)
return round(expected_rate / 1000, 2)
if rate_unit == "MH":
return round(ideal_rate / 1000000, 2)
return round(expected_rate / 1000000, 2)
else:
return round(ideal_rate, 2)
return round(expected_rate, 2)
except (KeyError, IndexError):
pass

View File

@@ -38,10 +38,7 @@ BOSMINER_DATA_LOC = {
},
},
"model": {"cmd": "get_model", "kwargs": {}},
"api_ver": {
"cmd": "get_api_ver",
"kwargs": {"api_version": {"api": "version"}},
},
"api_ver": {"cmd": "get_api_ver", "kwargs": {"api_version": {"api": "version"}}},
"fw_ver": {
"cmd": "get_fw_ver",
"kwargs": {
@@ -65,8 +62,8 @@ BOSMINER_DATA_LOC = {
},
},
},
"nominal_hashrate": {
"cmd": "get_nominal_hashrate",
"expected_hashrate": {
"cmd": "get_expected_hashrate",
"kwargs": {"api_devs": {"api": "devs"}},
},
"hashboards": {
@@ -178,10 +175,8 @@ BOSMINER_DATA_LOC = {
"cmd": "is_mining",
"kwargs": {"api_devdetails": {"api": "devdetails"}},
},
"uptime": {
"cmd": "get_uptime",
"kwargs": {"api_summary": {"api": "summary"}},
},
"uptime": {"cmd": "get_uptime", "kwargs": {"api_summary": {"api": "summary"}}},
"config": {"cmd": "get_config", "kwargs": {}},
}
@@ -601,8 +596,8 @@ class BOSMiner(BaseMiner):
graphql_boards: dict = None,
):
hashboards = [
HashBoard(slot=i, expected_chips=self.nominal_chips)
for i in range(self.ideal_hashboards)
HashBoard(slot=i, expected_chips=self.expected_chips)
for i in range(self.expected_hashboards)
]
if not graphql_boards and not (api_devs or api_temps or api_devdetails):
@@ -1063,7 +1058,7 @@ class BOSMiner(BaseMiner):
except (TypeError, AttributeError):
return self.light
async def get_nominal_hashrate(self, api_devs: dict = None) -> Optional[float]:
async def get_expected_hashrate(self, api_devs: dict = None) -> Optional[float]:
if not api_devs:
try:
api_devs = await self.api.devs()
@@ -1077,14 +1072,14 @@ class BOSMiner(BaseMiner):
for board in api_devs["DEVS"]:
_id = board["ID"] - offset
nominal_hashrate = round(float(board["Nominal MHS"] / 1000000), 2)
if nominal_hashrate:
hr_list.append(nominal_hashrate)
expected_hashrate = round(float(board["Nominal MHS"] / 1000000), 2)
if expected_hashrate:
hr_list.append(expected_hashrate)
if len(hr_list) == 0:
return 0
else:
return round(
(sum(hr_list) / len(hr_list)) * self.ideal_hashboards, 2
(sum(hr_list) / len(hr_list)) * self.expected_hashboards, 2
)
except (IndexError, KeyError):
pass

View File

@@ -145,7 +145,7 @@ class BOSMinerOld(BOSMiner):
async def get_fault_light(self, *args, **kwargs) -> bool:
return False
async def get_nominal_hashrate(self, *args, **kwargs) -> Optional[float]:
async def get_expected_hashrate(self, *args, **kwargs) -> Optional[float]:
return None
async def get_data(self, allow_warning: bool = False, **kwargs) -> MinerData:

View File

@@ -50,8 +50,8 @@ BTMINER_DATA_LOC = {
"kwargs": {"api_get_miner_info": {"api": "get_miner_info"}},
},
"hashrate": {"cmd": "get_hashrate", "kwargs": {"api_summary": {"api": "summary"}}},
"nominal_hashrate": {
"cmd": "get_nominal_hashrate",
"expected_hashrate": {
"cmd": "get_expected_hashrate",
"kwargs": {"api_summary": {"api": "summary"}},
},
"hashboards": {"cmd": "get_hashboards", "kwargs": {"api_devs": {"api": "devs"}}},
@@ -88,10 +88,8 @@ BTMINER_DATA_LOC = {
},
"pools": {"cmd": "get_pools", "kwargs": {"api_pools": {"api": "pools"}}},
"is_mining": {"cmd": "is_mining", "kwargs": {"api_status": {"api": "status"}}},
"uptime": {
"cmd": "get_uptime",
"kwargs": {"api_summary": {"api": "summary"}},
},
"uptime": {"cmd": "get_uptime", "kwargs": {"api_summary": {"api": "summary"}}},
"config": {"cmd": "get_config", "kwargs": {}},
}
@@ -410,8 +408,8 @@ class BTMiner(BaseMiner):
async def get_hashboards(self, api_devs: dict = None) -> List[HashBoard]:
hashboards = [
HashBoard(slot=i, expected_chips=self.nominal_chips)
for i in range(self.ideal_hashboards)
HashBoard(slot=i, expected_chips=self.expected_chips)
for i in range(self.expected_hashboards)
]
if not api_devs:
@@ -426,10 +424,10 @@ class BTMiner(BaseMiner):
if len(hashboards) < board["ASC"] + 1:
hashboards.append(
HashBoard(
slot=board["ASC"], expected_chips=self.nominal_chips
slot=board["ASC"], expected_chips=self.expected_chips
)
)
self.ideal_hashboards += 1
self.expected_hashboards += 1
hashboards[board["ASC"]].chip_temp = round(board["Chip Temp Avg"])
hashboards[board["ASC"]].temp = round(board["Temperature"])
hashboards[board["ASC"]].hashrate = round(
@@ -592,7 +590,7 @@ class BTMiner(BaseMiner):
return errors
async def get_nominal_hashrate(self, api_summary: dict = None):
async def get_expected_hashrate(self, api_summary: dict = None):
if not api_summary:
try:
api_summary = await self.api.summary()
@@ -601,7 +599,7 @@ class BTMiner(BaseMiner):
if api_summary:
try:
nominal_hashrate = api_summary["SUMMARY"][0]["Factory GHS"]
expected_hashrate = api_summary["SUMMARY"][0]["Factory GHS"]
if nominal_hashrate:
return round(nominal_hashrate / 1000, 2)
except (KeyError, IndexError):

View File

@@ -32,8 +32,8 @@ CGMINER_DATA_LOC = {
"fw_ver": {"cmd": "get_fw_ver", "kwargs": {"api_version": {"api": "version"}}},
"hostname": {"cmd": "get_hostname", "kwargs": {}},
"hashrate": {"cmd": "get_hashrate", "kwargs": {"api_summary": {"api": "summary"}}},
"nominal_hashrate": {
"cmd": "get_nominal_hashrate",
"expected_hashrate": {
"cmd": "get_expected_hashrate",
"kwargs": {"api_stats": {"api": "stats"}},
},
"hashboards": {"cmd": "get_hashboards", "kwargs": {"api_stats": {"api": "stats"}}},
@@ -46,10 +46,8 @@ CGMINER_DATA_LOC = {
"fault_light": {"cmd": "get_fault_light", "kwargs": {}},
"pools": {"cmd": "get_pools", "kwargs": {"api_pools": {"api": "pools"}}},
"is_mining": {"cmd": "is_mining", "kwargs": {}},
"uptime": {
"cmd": "get_uptime",
"kwargs": {"api_stats": {"api": "stats"}},
},
"uptime": {"cmd": "get_uptime", "kwargs": {"api_stats": {"api": "stats"}}},
"config": {"cmd": "get_config", "kwargs": {}},
}
@@ -259,9 +257,11 @@ class CGMiner(BaseMiner):
if board_offset == -1:
board_offset = 1
for i in range(board_offset, board_offset + self.ideal_hashboards):
for i in range(
board_offset, board_offset + self.expected_hashboards
):
hashboard = HashBoard(
slot=i - board_offset, expected_chips=self.nominal_chips
slot=i - board_offset, expected_chips=self.expected_chips
)
chip_temp = boards[1].get(f"temp{i}")
@@ -360,7 +360,7 @@ class CGMiner(BaseMiner):
async def get_fault_light(self) -> bool:
return False
async def get_nominal_hashrate(self, api_stats: dict = None) -> Optional[float]:
async def get_expected_hashrate(self, api_stats: dict = None) -> Optional[float]:
# X19 method, not sure compatibility
if not api_stats:
try:
@@ -370,17 +370,17 @@ class CGMiner(BaseMiner):
if api_stats:
try:
ideal_rate = api_stats["STATS"][1]["total_rateideal"]
expected_rate = api_stats["STATS"][1]["total_rateideal"]
try:
rate_unit = api_stats["STATS"][1]["rate_unit"]
except KeyError:
rate_unit = "GH"
if rate_unit == "GH":
return round(ideal_rate / 1000, 2)
return round(expected_rate / 1000, 2)
if rate_unit == "MH":
return round(ideal_rate / 1000000, 2)
return round(expected_rate / 1000000, 2)
else:
return round(ideal_rate, 2)
return round(expected_rate, 2)
except (KeyError, IndexError):
pass

View File

@@ -31,8 +31,8 @@ AVALON_DATA_LOC = {
"fw_ver": {"cmd": "get_fw_ver", "kwargs": {"api_version": {"api": "version"}}},
"hostname": {"cmd": "get_hostname", "kwargs": {"mac": {"api": "version"}}},
"hashrate": {"cmd": "get_hashrate", "kwargs": {"api_devs": {"api": "devs"}}},
"nominal_hashrate": {
"cmd": "get_nominal_hashrate",
"expected_hashrate": {
"cmd": "get_expected_hashrate",
"kwargs": {"api_stats": {"api": "stats"}},
},
"hashboards": {"cmd": "get_hashboards", "kwargs": {"api_stats": {"api": "stats"}}},
@@ -52,6 +52,7 @@ AVALON_DATA_LOC = {
"pools": {"cmd": "get_pools", "kwargs": {"api_pools": {"api": "pools"}}},
"is_mining": {"cmd": "is_mining", "kwargs": {}},
"uptime": {"cmd": "get_uptime", "kwargs": {}},
"config": {"cmd": "get_config", "kwargs": {}},
}
@@ -201,8 +202,8 @@ class CGMinerAvalon(CGMiner):
async def get_hashboards(self, api_stats: dict = None) -> List[HashBoard]:
hashboards = [
HashBoard(slot=i, expected_chips=self.nominal_chips)
for i in range(self.ideal_hashboards)
HashBoard(slot=i, expected_chips=self.expected_chips)
for i in range(self.expected_hashboards)
]
if not api_stats:
@@ -218,7 +219,7 @@ class CGMinerAvalon(CGMiner):
except (IndexError, KeyError, ValueError, TypeError):
return hashboards
for board in range(self.ideal_hashboards):
for board in range(self.expected_hashboards):
try:
hashboards[board].chip_temp = int(parsed_stats["MTmax"][board])
except LookupError:
@@ -247,7 +248,7 @@ class CGMinerAvalon(CGMiner):
return hashboards
async def get_nominal_hashrate(self, api_stats: dict = None) -> Optional[float]:
async def get_expected_hashrate(self, api_stats: dict = None) -> Optional[float]:
if not api_stats:
try:
api_stats = await self.api.stats()

View File

@@ -30,7 +30,7 @@ EPIC_DATA_LOC = {
"fw_ver": {"cmd": "get_fw_ver", "kwargs": {"web_summary": {"web": "summary"}}},
"hostname": {"cmd": "get_hostname", "kwargs": {"web_summary": {"web": "summary"}}},
"hashrate": {"cmd": "get_hashrate", "kwargs": {"web_summary": {"web": "summary"}}},
"nominal_hashrate": {
"expected_hashrate": {
"cmd": "get_nominal_hashrate",
"kwargs": {"web_summary": {"web": "summary"}},
},
@@ -43,6 +43,7 @@ EPIC_DATA_LOC = {
},
"env_temp": {"cmd": "get_env_temp", "kwargs": {}},
"wattage": {"cmd": "get_wattage", "kwargs": {"web_summary": {"web": "summary"}}},
"wattage_limit": {"cmd": "get_wattage_limit", "kwargs": {}},
"fans": {"cmd": "get_fans", "kwargs": {"web_summary": {"web": "summary"}}},
"fan_psu": {"cmd": "get_fan_psu", "kwargs": {}},
"fault_light": {
@@ -53,6 +54,7 @@ EPIC_DATA_LOC = {
"is_mining": {"cmd": "is_mining", "kwargs": {}},
"uptime": {"cmd": "get_uptime", "kwargs": {"web_summary": {"web": "summary"}}},
"errors": {"cmd": "get_errors", "kwargs": {"web_summary": {"web": "summary"}}},
"config": {"cmd": "get_config", "kwargs": {}},
}
@@ -160,7 +162,7 @@ class ePIC(BMMiner):
logger.error(e)
pass
async def get_nominal_hashrate(self, web_summary: dict = None) -> Optional[float]:
async def get_expected_hashrate(self, web_summary: dict = None) -> Optional[float]:
# get hr from API
if not web_summary:
try:
@@ -227,8 +229,8 @@ class ePIC(BMMiner):
except APIError:
pass
hb_list = [
HashBoard(slot=i, expected_chips=self.nominal_chips)
for i in range(self.ideal_hashboards)
HashBoard(slot=i, expected_chips=self.expected_chips)
for i in range(self.expected_hashboards)
]
if web_summary["HBs"] != None:
for hb in web_summary["HBs"]:

View File

@@ -30,69 +30,25 @@ from pyasic.miners.base import BaseMiner
from pyasic.web.bosminer import BOSMinerWebAPI
LUXMINER_DATA_LOC = {
"mac": {
"cmd": "get_mac",
"kwargs": {"api_config": {"api": "config"}},
},
"mac": {"cmd": "get_mac", "kwargs": {"api_config": {"api": "config"}}},
"model": {"cmd": "get_model", "kwargs": {}},
"api_ver": {
"cmd": "get_api_ver",
"kwargs": {},
},
"fw_ver": {
"cmd": "get_fw_ver",
"kwargs": {},
},
"hostname": {
"cmd": "get_hostname",
"kwargs": {},
},
"hashrate": {
"cmd": "get_hashrate",
"kwargs": {},
},
"nominal_hashrate": {
"cmd": "get_nominal_hashrate",
"kwargs": {},
},
"hashboards": {
"cmd": "get_hashboards",
"kwargs": {},
},
"wattage": {
"cmd": "get_wattage",
"kwargs": {},
},
"wattage_limit": {
"cmd": "get_wattage_limit",
"kwargs": {},
},
"fans": {
"cmd": "get_fans",
"kwargs": {},
},
"api_ver": {"cmd": "get_api_ver", "kwargs": {}},
"fw_ver": {"cmd": "get_fw_ver", "kwargs": {}},
"hostname": {"cmd": "get_hostname", "kwargs": {}},
"hashrate": {"cmd": "get_hashrate", "kwargs": {}},
"expected_hashrate": {"cmd": "get_nominal_hashrate", "kwargs": {}},
"hashboards": {"cmd": "get_hashboards", "kwargs": {}},
"wattage": {"cmd": "get_wattage", "kwargs": {}},
"wattage_limit": {"cmd": "get_wattage_limit", "kwargs": {}},
"fans": {"cmd": "get_fans", "kwargs": {}},
"fan_psu": {"cmd": "get_fan_psu", "kwargs": {}},
"env_temp": {"cmd": "get_env_temp", "kwargs": {}},
"errors": {
"cmd": "get_errors",
"kwargs": {},
},
"fault_light": {
"cmd": "get_fault_light",
"kwargs": {},
},
"pools": {
"cmd": "get_pools",
"kwargs": {},
},
"is_mining": {
"cmd": "is_mining",
"kwargs": {},
},
"uptime": {
"cmd": "get_uptime",
"kwargs": {"api_stats": {"api": "stats"}},
},
"errors": {"cmd": "get_errors", "kwargs": {}},
"fault_light": {"cmd": "get_fault_light", "kwargs": {}},
"pools": {"cmd": "get_pools", "kwargs": {}},
"is_mining": {"cmd": "is_mining", "kwargs": {}},
"uptime": {"cmd": "get_uptime", "kwargs": {"api_stats": {"api": "stats"}}},
"config": {"cmd": "get_config", "kwargs": {}},
}
@@ -277,9 +233,11 @@ class LUXMiner(BaseMiner):
if board_offset == -1:
board_offset = 1
for i in range(board_offset, board_offset + self.ideal_hashboards):
for i in range(
board_offset, board_offset + self.expected_hashboards
):
hashboard = HashBoard(
slot=i - board_offset, expected_chips=self.nominal_chips
slot=i - board_offset, expected_chips=self.expected_chips
)
chip_temp = boards[1].get(f"temp{i}")
@@ -401,7 +359,7 @@ class LUXMiner(BaseMiner):
async def get_fault_light(self) -> bool:
pass
async def get_nominal_hashrate(self, api_stats: dict = None) -> Optional[float]:
async def get_expected_hashrate(self, api_stats: dict = None) -> Optional[float]:
if not api_stats:
try:
api_stats = await self.api.stats()
@@ -410,17 +368,17 @@ class LUXMiner(BaseMiner):
if api_stats:
try:
ideal_rate = api_stats["STATS"][1]["total_rateideal"]
expected_rate = api_stats["STATS"][1]["total_rateideal"]
try:
rate_unit = api_stats["STATS"][1]["rate_unit"]
except KeyError:
rate_unit = "GH"
if rate_unit == "GH":
return round(ideal_rate / 1000, 2)
return round(expected_rate / 1000, 2)
if rate_unit == "MH":
return round(ideal_rate / 1000000, 2)
return round(expected_rate / 1000000, 2)
else:
return round(ideal_rate, 2)
return round(expected_rate, 2)
except (KeyError, IndexError):
pass

View File

@@ -28,7 +28,7 @@ VNISH_DATA_LOC = {
"fw_ver": {"cmd": "get_fw_ver", "kwargs": {"web_summary": {"web": "summary"}}},
"hostname": {"cmd": "get_hostname", "kwargs": {"web_summary": {"web": "summary"}}},
"hashrate": {"cmd": "get_hashrate", "kwargs": {"api_summary": {"api": "summary"}}},
"nominal_hashrate": {
"expected_hashrate": {
"cmd": "get_nominal_hashrate",
"kwargs": {"api_stats": {"api": "stats"}},
},
@@ -46,6 +46,7 @@ VNISH_DATA_LOC = {
"pools": {"cmd": "get_pools", "kwargs": {"api_pools": {"api": "pools"}}},
"is_mining": {"cmd": "is_mining", "kwargs": {}},
"uptime": {"cmd": "get_uptime", "kwargs": {}},
"config": {"cmd": "get_config", "kwargs": {}},
}

View File

@@ -42,8 +42,8 @@ class BaseMiner(ABC):
self.make = None
self.model = None
# physical attributes
self.ideal_hashboards = 3
self.nominal_chips = 0
self.expected_hashboards = 3
self.expected_chips = 0
self.fan_count = 2
# data gathering locations
self.data_locations = None
@@ -173,7 +173,7 @@ class BaseMiner(ABC):
@abstractmethod
async def get_config(self) -> MinerConfig:
# Not a data gathering function, since this is used for configuration and not MinerData
# Not a data gathering function, since this is used for configuration
"""Get the mining configuration of the miner and return it as a [`MinerConfig`][pyasic.config.MinerConfig].
Returns:
@@ -387,7 +387,7 @@ class BaseMiner(ABC):
pass
@abstractmethod
async def get_nominal_hashrate(self, *args, **kwargs) -> Optional[float]:
async def get_expected_hashrate(self, *args, **kwargs) -> Optional[float]:
"""Get the nominal hashrate from factory if available.
Returns:
@@ -491,29 +491,7 @@ class BaseMiner(ABC):
continue
function = getattr(self, self.data_locations[data_name]["cmd"])
if not data_name == "pools":
miner_data[data_name] = await function(**args_to_send)
else:
pools_data = await function(**args_to_send)
if pools_data:
try:
miner_data["pool_1_url"] = pools_data[0]["pool_1_url"]
miner_data["pool_1_user"] = pools_data[0]["pool_1_user"]
except KeyError:
pass
if len(pools_data) > 1:
miner_data["pool_2_url"] = pools_data[1]["pool_1_url"]
miner_data["pool_2_user"] = pools_data[1]["pool_1_user"]
miner_data[
"pool_split"
] = f"{pools_data[0]['quota']}/{pools_data[1]['quota']}"
else:
try:
miner_data["pool_2_url"] = pools_data[0]["pool_2_url"]
miner_data["pool_2_user"] = pools_data[0]["pool_2_user"]
miner_data["quota"] = "0"
except KeyError:
pass
miner_data[data_name] = await function(**args_to_send)
return miner_data
async def get_data(
@@ -532,11 +510,11 @@ class BaseMiner(ABC):
data = MinerData(
ip=str(self.ip),
make=self.make,
ideal_chips=self.nominal_chips * self.ideal_hashboards,
ideal_hashboards=self.ideal_hashboards,
expected_chips=self.expected_chips * self.expected_hashboards,
expected_hashboards=self.expected_hashboards,
hashboards=[
HashBoard(slot=i, expected_chips=self.nominal_chips)
for i in range(self.ideal_hashboards)
HashBoard(slot=i, expected_chips=self.expected_chips)
for i in range(self.expected_hashboards)
],
)

View File

@@ -152,8 +152,8 @@ class CGMinerA10X(CGMiner, A10X):
self, api_stats: dict = None, web_get_all: dict = None
) -> List[HashBoard]:
hashboards = [
HashBoard(slot=i, expected_chips=self.nominal_chips)
for i in range(self.ideal_hashboards)
HashBoard(slot=i, expected_chips=self.expected_chips)
for i in range(self.expected_hashboards)
]
if web_get_all:
web_get_all = web_get_all["all"]

View File

@@ -133,8 +133,8 @@ class CGMinerT3HPlus(CGMiner, T3HPlus):
web_get_all = web_get_all["all"]
hashboards = [
HashBoard(slot=i, expected_chips=self.nominal_chips)
for i in range(self.ideal_hashboards)
HashBoard(slot=i, expected_chips=self.expected_chips)
for i in range(self.expected_hashboards)
]
if not api_stats:

View File

@@ -346,13 +346,18 @@ MINER_CLASSES = {
"ANTMINER T17+": BOSMinerT17Plus,
"ANTMINER T17E": BOSMinerT17e,
"ANTMINER S19": BOSMinerS19,
"ANTMINER S19+": BOSMinerS19Plus,
"ANTMINER S19 PRO": BOSMinerS19Pro,
"ANTMINER S19A": BOSMinerS19a,
"ANTMINER S19A Pro": BOSMinerS19aPro,
"ANTMINER S19J": BOSMinerS19j,
"ANTMINER S19J88NOPIC": BOSMinerS19jNoPIC,
"ANTMINER S19J PRO": BOSMinerS19jPro,
"ANTMINER S19J PRO NOPIC": BOSMinerS19jPro,
"ANTMINER T19": BOSMinerT19,
"ANTMINER S19J PRO+": BOSMinerS19jProPlus,
"ANTMINER S19K PRO NOPIC": BOSMinerS19kProNoPIC,
"ANTMINER S19XP": BOSMinerS19XP,
"ANTMINER T19": BOSMinerT19,
},
MinerTypes.VNISH: {
None: VNish,

View File

@@ -22,5 +22,5 @@ class Z15(AntMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "Z15"
self.nominal_chips = 3
self.expected_chips = 3
self.fan_count = 2

View File

@@ -22,7 +22,7 @@ class S17(AntMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "S17"
self.nominal_chips = 48
self.expected_chips = 48
self.fan_count = 4
@@ -30,7 +30,7 @@ class S17Plus(AntMiner): # noqa - ignore ABC method implementation
def __init__(self, ip: str, api_ver: str = "0.0.0"):
super().__init__(ip, api_ver)
self.model = "S17+"
self.nominal_chips = 65
self.expected_chips = 65
self.fan_count = 4
@@ -39,7 +39,7 @@ class S17Pro(AntMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "S17 Pro"
self.nominal_chips = 48
self.expected_chips = 48
self.fan_count = 4
@@ -48,5 +48,5 @@ class S17e(AntMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "S17e"
self.nominal_chips = 135
self.expected_chips = 135
self.fan_count = 4

View File

@@ -22,7 +22,7 @@ class T17(AntMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "T17"
self.nominal_chips = 30
self.expected_chips = 30
self.fan_count = 4
@@ -31,7 +31,7 @@ class T17Plus(AntMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "T17+"
self.nominal_chips = 44
self.expected_chips = 44
self.fan_count = 4
@@ -40,5 +40,5 @@ class T17e(AntMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "T17e"
self.nominal_chips = 78
self.expected_chips = 78
self.fan_count = 4

View File

@@ -22,7 +22,7 @@ class S19(AntMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "S19"
self.nominal_chips = 76
self.expected_chips = 76
self.fan_count = 4
@@ -40,7 +40,7 @@ class S19Pro(AntMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "S19 Pro"
self.nominal_chips = 114
self.expected_chips = 114
self.fan_count = 4
@@ -67,7 +67,7 @@ class S19ProPlus(AntMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "S19 Pro+"
self.nominal_chips = 120
self.expected_chips = 120
self.fan_count = 4
@@ -85,7 +85,7 @@ class S19a(AntMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "S19a"
self.nominal_chips = 72
self.expected_chips = 72
self.fan_count = 4
@@ -148,7 +148,7 @@ class S19L(AntMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "S19L"
self.nominal_chips = 76
self.expected_chips = 76
self.fan_count = 4

View File

@@ -22,5 +22,5 @@ class T19(AntMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "T19"
self.nominal_chips = 76
self.expected_chips = 76
self.fan_count = 4

View File

@@ -22,6 +22,6 @@ class D3(AntMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "D3"
self.nominal_chips = 60
self.ideal_hashboards = 3
self.expected_chips = 60
self.expected_hashboards = 3
self.fan_count = 2

View File

@@ -22,6 +22,6 @@ class HS3(AntMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "HS3"
self.nominal_chips = 92
self.ideal_hashboards = 3
self.expected_chips = 92
self.expected_hashboards = 3
self.fan_count = 2

View File

@@ -21,5 +21,5 @@ class L3Plus(AntMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "L3+"
self.nominal_chips = 72
self.expected_chips = 72
self.fan_count = 2

View File

@@ -22,6 +22,6 @@ class DR5(AntMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "DR5"
self.nominal_chips = 72
self.ideal_hashboards = 3
self.expected_chips = 72
self.expected_hashboards = 3
self.fan_count = 2

View File

@@ -21,5 +21,5 @@ class L7(AntMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "L7"
self.nominal_chips = 120
self.expected_chips = 120
self.fan_count = 4

View File

@@ -22,6 +22,6 @@ class E9Pro(AntMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "E9Pro"
self.nominal_chips = 8
self.ideal_hashboards = 2
self.expected_chips = 8
self.expected_hashboards = 2
self.fan_count = 4

View File

@@ -22,7 +22,7 @@ class S9(AntMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "S9"
self.nominal_chips = 63
self.expected_chips = 63
self.fan_count = 2
@@ -31,7 +31,7 @@ class S9i(AntMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "S9i"
self.nominal_chips = 63
self.expected_chips = 63
self.fan_count = 2

View File

@@ -22,5 +22,5 @@ class T9(AntMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "T9"
self.nominal_chips = 54
self.expected_chips = 54
self.fan_count = 2

View File

@@ -22,5 +22,5 @@ class Avalon1026(AvalonMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "Avalon 1026"
self.nominal_chips = 80
self.expected_chips = 80
self.fan_count = 2

View File

@@ -22,5 +22,5 @@ class Avalon1047(AvalonMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "Avalon 1047"
self.nominal_chips = 80
self.expected_chips = 80
self.fan_count = 2

View File

@@ -22,5 +22,5 @@ class Avalon1066(AvalonMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "Avalon 1066"
self.nominal_chips = 114
self.expected_chips = 114
self.fan_count = 4

View File

@@ -23,5 +23,5 @@ class Avalon1166Pro(AvalonMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "Avalon 1166 Pro"
self.nominal_chips = 120
self.expected_chips = 120
self.fan_count = 4

View File

@@ -23,5 +23,5 @@ class Avalon1246(AvalonMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "Avalon 1246"
self.nominal_chips = 120
self.expected_chips = 120
self.fan_count = 4

View File

@@ -22,6 +22,6 @@ class Avalon721(AvalonMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "Avalon 721"
self.ideal_hashboards = 4
self.nominal_chips = 18
self.expected_hashboards = 4
self.expected_chips = 18
self.fan_count = 1

View File

@@ -22,6 +22,6 @@ class Avalon741(AvalonMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "Avalon 741"
self.ideal_hashboards = 4
self.nominal_chips = 22
self.expected_hashboards = 4
self.expected_chips = 22
self.fan_count = 1

View File

@@ -22,6 +22,6 @@ class Avalon761(AvalonMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "Avalon 761"
self.ideal_hashboards = 4
self.nominal_chips = 18
self.expected_hashboards = 4
self.expected_chips = 18
self.fan_count = 1

View File

@@ -22,6 +22,6 @@ class Avalon821(AvalonMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "Avalon 821"
self.ideal_hashboards = 4
self.nominal_chips = 26
self.expected_hashboards = 4
self.expected_chips = 26
self.fan_count = 1

View File

@@ -22,6 +22,6 @@ class Avalon841(AvalonMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "Avalon 841"
self.ideal_hashboards = 4
self.nominal_chips = 26
self.expected_hashboards = 4
self.expected_chips = 26
self.fan_count = 1

View File

@@ -22,6 +22,6 @@ class Avalon851(AvalonMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "Avalon 851"
self.ideal_hashboards = 4
self.nominal_chips = 26
self.expected_hashboards = 4
self.expected_chips = 26
self.fan_count = 1

View File

@@ -22,6 +22,6 @@ class Avalon921(AvalonMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "Avalon 921"
self.ideal_hashboards = 4
self.nominal_chips = 26
self.expected_hashboards = 4
self.expected_chips = 26
self.fan_count = 1

View File

@@ -21,6 +21,6 @@ class CK5(GoldshellMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "CK5"
self.ideal_hashboards = 4
self.nominal_chips = 46
self.expected_hashboards = 4
self.expected_chips = 46
self.fan_count = 4

View File

@@ -21,6 +21,6 @@ class HS5(GoldshellMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "HS5"
self.ideal_hashboards = 4
self.nominal_chips = 46
self.expected_hashboards = 4
self.expected_chips = 46
self.fan_count = 4

View File

@@ -21,6 +21,6 @@ class KD5(GoldshellMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "KD5"
self.ideal_hashboards = 4
self.nominal_chips = 46
self.expected_hashboards = 4
self.expected_chips = 46
self.fan_count = 4

View File

@@ -21,6 +21,6 @@ class KDMax(GoldshellMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "KD Max"
self.ideal_hashboards = 3
self.nominal_chips = 84
self.expected_hashboards = 3
self.expected_chips = 84
self.fan_count = 4

View File

@@ -22,5 +22,5 @@ class T3HPlus(InnosiliconMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "T3H+"
self.nominal_chips = 114
self.expected_chips = 114
self.fan_count = 4

View File

@@ -22,5 +22,5 @@ class M20V10(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M20 V10"
self.nominal_chips = 70
self.expected_chips = 70
self.fan_count = 2

View File

@@ -22,7 +22,7 @@ class M20PV10(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M20P V10"
self.nominal_chips = 156
self.expected_chips = 156
self.fan_count = 2
@@ -31,5 +31,5 @@ class M20PV30(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M20P V30"
self.nominal_chips = 148
self.expected_chips = 148
self.fan_count = 2

View File

@@ -24,7 +24,7 @@ class M20SV10(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M20S V10"
self.nominal_chips = 105
self.expected_chips = 105
self.fan_count = 2
@@ -42,5 +42,5 @@ class M20SV30(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M20S V30"
self.nominal_chips = 140
self.expected_chips = 140
self.fan_count = 2

View File

@@ -24,7 +24,7 @@ class M20SPlusV30(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M20S+ V30"
self.nominal_chips = 0
self.expected_chips = 0
warnings.warn(
"Unknown chip count for miner type M20S+ V30, please open an issue on GitHub (https://github.com/UpstreamData/pyasic)."
)

View File

@@ -24,5 +24,5 @@ class M21V10(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M21 V10"
self.nominal_chips = 33
self.expected_chips = 33
self.fan_count = 2

View File

@@ -24,7 +24,7 @@ class M21SV20(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M21S V20"
self.nominal_chips = 66
self.expected_chips = 66
self.fan_count = 2
@@ -33,7 +33,7 @@ class M21SV60(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M21S V60"
self.nominal_chips = 105
self.expected_chips = 105
self.fan_count = 2
@@ -42,5 +42,5 @@ class M21SV70(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M21S V70"
self.nominal_chips = 111
self.expected_chips = 111
self.fan_count = 2

View File

@@ -24,7 +24,7 @@ class M21SPlusV20(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M21S+ V20"
self.nominal_chips = 0
self.expected_chips = 0
warnings.warn(
"Unknown chip count for miner type M21S+ V20, please open an issue on GitHub (https://github.com/UpstreamData/pyasic)."
)

View File

@@ -24,5 +24,5 @@ class M29V10(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M29 V10"
self.nominal_chips = 50
self.expected_chips = 50
self.fan_count = 2

View File

@@ -24,7 +24,7 @@ class M30V10(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M30 V10"
self.nominal_chips = 105
self.expected_chips = 105
self.fan_count = 2

View File

@@ -24,6 +24,6 @@ class M30KV10(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M30K V10"
self.ideal_hashboards = 4
self.nominal_chips = 240
self.expected_hashboards = 4
self.expected_chips = 240
self.fan_count = 2

View File

@@ -25,5 +25,5 @@ class M30LV10(WhatsMiner): # noqa - ignore ABC method implementation
self.ip = ip
self.model = "M30L V10"
self.board_num = 4
self.nominal_chips = 144
self.expected_chips = 144
self.fan_count = 2

View File

@@ -24,7 +24,7 @@ class M30SV10(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M30S V10"
self.nominal_chips = 148
self.expected_chips = 148
self.fan_count = 2
@@ -51,7 +51,7 @@ class M30SV40(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M30S V40"
self.nominal_chips = 172
self.expected_chips = 172
self.fan_count = 2
@@ -99,7 +99,7 @@ class M30SVE10(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M30S VE10"
self.nominal_chips = 105
self.expected_chips = 105
self.fan_count = 2
@@ -177,7 +177,7 @@ class M30SVF20(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M30S VF20"
self.nominal_chips = 74
self.expected_chips = 74
self.fan_count = 2
@@ -204,7 +204,7 @@ class M30SVG20(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M30S VG20"
self.nominal_chips = 70
self.expected_chips = 70
self.fan_count = 2
@@ -231,7 +231,7 @@ class M30SVH10(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M30S VH10"
self.nominal_chips = 64
self.expected_chips = 64
self.fan_count = 2
@@ -279,7 +279,7 @@ class M30SVH60(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M30S VH60"
self.nominal_chips = 0
self.expected_chips = 0
warnings.warn(
"Unknown chip count for miner type M30SVH60, please open an issue on GitHub (https://github.com/UpstreamData/pyasic)."
)

View File

@@ -24,7 +24,7 @@ class M30SPlusV10(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M30S+ V10"
self.nominal_chips = 215
self.expected_chips = 215
self.fan_count = 2
@@ -33,7 +33,7 @@ class M30SPlusV20(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M30S+ V20"
self.nominal_chips = 255
self.expected_chips = 255
self.fan_count = 2
@@ -90,7 +90,7 @@ class M30SPlusV80(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M30S+ V80"
self.nominal_chips = 245
self.expected_chips = 245
self.fan_count = 2
@@ -117,7 +117,7 @@ class M30SPlusVE30(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M30S+ VE30"
self.nominal_chips = 148
self.expected_chips = 148
self.fan_count = 2
@@ -144,7 +144,7 @@ class M30SPlusVE60(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M30S+ VE60"
self.nominal_chips = 172
self.expected_chips = 172
self.fan_count = 2
@@ -210,7 +210,7 @@ class M30SPlusVF30(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M30S+ VF30"
self.nominal_chips = 117
self.expected_chips = 117
self.fan_count = 2
@@ -237,7 +237,7 @@ class M30SPlusVG40(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M30S+ VG40"
self.nominal_chips = 105
self.expected_chips = 105
self.fan_count = 2
@@ -264,7 +264,7 @@ class M30SPlusVH10(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M30S+ VH10"
self.nominal_chips = 64
self.expected_chips = 64
self.fan_count = 2
@@ -309,5 +309,5 @@ class M30SPlusVH60(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M30S+ VH60"
self.nominal_chips = 66
self.expected_chips = 66
self.fan_count = 2

View File

@@ -24,8 +24,8 @@ class M30SPlusPlusV10(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M30S++ V10"
self.ideal_hashboards = 4
self.nominal_chips = 255
self.expected_hashboards = 4
self.expected_chips = 255
self.fan_count = 2
@@ -34,8 +34,8 @@ class M30SPlusPlusV20(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M30S++ V20"
self.ideal_hashboards = 4
self.nominal_chips = 255
self.expected_hashboards = 4
self.expected_chips = 255
self.fan_count = 2
@@ -62,7 +62,7 @@ class M30SPlusPlusVE50(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M30S++ VE50"
self.nominal_chips = 235
self.expected_chips = 235
self.fan_count = 2
@@ -119,7 +119,7 @@ class M30SPlusPlusVH20(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M30S++ VH20"
self.nominal_chips = 86
self.expected_chips = 86
self.fan_count = 2
@@ -164,7 +164,7 @@ class M30SPlusPlusVH70(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M30S++ VH70"
self.nominal_chips = 70
self.expected_chips = 70
self.fan_count = 2
@@ -191,7 +191,7 @@ class M30SPlusPlusVH100(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M30S++ VH100"
self.nominal_chips = 82
self.expected_chips = 82
self.fan_count = 2

View File

@@ -24,7 +24,7 @@ class M31V10(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M31 V10"
self.nominal_chips = 70
self.expected_chips = 70
self.fan_count = 2

View File

@@ -24,7 +24,7 @@ class M31HV10(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M31H V10"
self.nominal_chips = 114
self.expected_chips = 114
self.fan_count = 0
@@ -33,6 +33,6 @@ class M31HV40(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M31H V40"
self.ideal_hashboards = 4
self.nominal_chips = 136
self.expected_hashboards = 4
self.expected_chips = 136
self.fan_count = 0

View File

@@ -24,5 +24,5 @@ class M31LV10(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M31L V10"
self.nominal_chips = 114
self.expected_chips = 114
self.fan_count = 2

View File

@@ -24,7 +24,7 @@ class M31SV10(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M31S V10"
self.nominal_chips = 105
self.expected_chips = 105
self.fan_count = 2
@@ -33,7 +33,7 @@ class M31SV20(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M31S V20"
self.nominal_chips = 111
self.expected_chips = 111
self.fan_count = 2
@@ -42,7 +42,7 @@ class M31SV30(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M31S V30"
self.nominal_chips = 117
self.expected_chips = 117
self.fan_count = 2
@@ -51,7 +51,7 @@ class M31SV40(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M31S V40"
self.nominal_chips = 123
self.expected_chips = 123
self.fan_count = 2
@@ -60,7 +60,7 @@ class M31SV50(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M31S V50"
self.nominal_chips = 78
self.expected_chips = 78
self.fan_count = 2
@@ -69,7 +69,7 @@ class M31SV60(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M31S V60"
self.nominal_chips = 105
self.expected_chips = 105
self.fan_count = 2
@@ -78,7 +78,7 @@ class M31SV70(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M31S V70"
self.nominal_chips = 111
self.expected_chips = 111
self.fan_count = 2
@@ -87,7 +87,7 @@ class M31SV80(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M31S V80"
self.nominal_chips = 0
self.expected_chips = 0
warnings.warn(
"Unknown chip count for miner type M31SV80, please open an issue on GitHub (https://github.com/UpstreamData/pyasic)."
)
@@ -99,7 +99,7 @@ class M31SV90(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M31S V90"
self.nominal_chips = 117
self.expected_chips = 117
self.fan_count = 2
@@ -108,7 +108,7 @@ class M31SVE10(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M31S VE10"
self.nominal_chips = 70
self.expected_chips = 70
self.fan_count = 2
@@ -117,7 +117,7 @@ class M31SVE20(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M31S VE20"
self.nominal_chips = 74
self.expected_chips = 74
self.fan_count = 2
@@ -126,7 +126,7 @@ class M31SVE30(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M31S VE30"
self.nominal_chips = 0
self.expected_chips = 0
warnings.warn(
"Unknown chip count for miner type M31SVE30, please open an issue on GitHub (https://github.com/UpstreamData/pyasic)."
)

View File

@@ -24,7 +24,7 @@ class M31SEV10(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M31SE V10"
self.nominal_chips = 82
self.expected_chips = 82
self.fan_count = 2
@@ -33,7 +33,7 @@ class M31SEV20(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M31SE V20"
self.nominal_chips = 78
self.expected_chips = 78
self.fan_count = 2
@@ -42,5 +42,5 @@ class M31SEV30(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M31SE V30"
self.nominal_chips = 78
self.expected_chips = 78
self.fan_count = 2

View File

@@ -24,7 +24,7 @@ class M31SPlusV10(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M31S+ V10"
self.nominal_chips = 105
self.expected_chips = 105
self.fan_count = 2
@@ -33,7 +33,7 @@ class M31SPlusV20(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M31S+ V20"
self.nominal_chips = 111
self.expected_chips = 111
self.fan_count = 2
@@ -42,7 +42,7 @@ class M31SPlusV30(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M31S+ V30"
self.nominal_chips = 117
self.expected_chips = 117
self.fan_count = 2
@@ -123,7 +123,7 @@ class M31SPlusVE30(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M31S+ VE30"
self.nominal_chips = 105
self.expected_chips = 105
self.fan_count = 2
@@ -132,7 +132,7 @@ class M31SPlusVE40(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M31S+ VE40"
self.nominal_chips = 111
self.expected_chips = 111
self.fan_count = 2
@@ -141,7 +141,7 @@ class M31SPlusVE50(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M31S+ VE50"
self.nominal_chips = 117
self.expected_chips = 117
self.fan_count = 2
@@ -150,7 +150,7 @@ class M31SPlusVE60(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M31S+ VE60"
self.nominal_chips = 0
self.expected_chips = 0
warnings.warn(
"Unknown chip count for miner type M30S+ VE60, please open an issue on GitHub (https://github.com/UpstreamData/pyasic)."
)
@@ -162,7 +162,7 @@ class M31SPlusVE80(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M31S+ VE80"
self.nominal_chips = 0
self.expected_chips = 0
warnings.warn(
"Unknown chip count for miner type M30S+ VE80, please open an issue on GitHub (https://github.com/UpstreamData/pyasic)."
)
@@ -174,7 +174,7 @@ class M31SPlusVF20(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M31S+ VF20"
self.nominal_chips = 66
self.expected_chips = 66
self.fan_count = 2
@@ -183,7 +183,7 @@ class M31SPlusVF30(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M31S+ VF30"
self.nominal_chips = 0
self.expected_chips = 0
warnings.warn(
"Unknown chip count for miner type M30S+ VF30, please open an issue on GitHub (https://github.com/UpstreamData/pyasic)."
)
@@ -195,7 +195,7 @@ class M31SPlusVG20(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M31S+ VG20"
self.nominal_chips = 66
self.expected_chips = 66
self.fan_count = 2
@@ -204,7 +204,7 @@ class M31SPlusVG30(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M31S+ VG30"
self.nominal_chips = 70
self.expected_chips = 70
self.fan_count = 2
@@ -213,7 +213,7 @@ class M31SPlusV30(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M31S+ V30"
self.nominal_chips = 117
self.expected_chips = 117
self.fan_count = 2
@@ -222,5 +222,5 @@ class M31SPlusV40(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M31S+ V40"
self.nominal_chips = 123
self.expected_chips = 123
self.fan_count = 2

View File

@@ -24,7 +24,7 @@ class M32V10(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M32 V10"
self.nominal_chips = 78
self.expected_chips = 78
self.fan_count = 2
@@ -33,5 +33,5 @@ class M32V20(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M32 V20"
self.nominal_chips = 74
self.expected_chips = 74
self.fan_count = 2

View File

@@ -22,5 +22,5 @@ class M32S(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M32S"
self.nominal_chips = 78
self.expected_chips = 78
self.fan_count = 2

View File

@@ -24,7 +24,7 @@ class M33V10(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M33 V10"
self.nominal_chips = 33
self.expected_chips = 33
self.fan_count = 0
@@ -33,7 +33,7 @@ class M33V20(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M33 V20"
self.nominal_chips = 62
self.expected_chips = 62
self.fan_count = 0
@@ -42,5 +42,5 @@ class M33V30(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M33 V30"
self.nominal_chips = 66
self.expected_chips = 66
self.fan_count = 0

View File

@@ -24,6 +24,6 @@ class M33SVG30(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M33S VG30"
self.ideal_hashboards = 4
self.nominal_chips = 116
self.expected_hashboards = 4
self.expected_chips = 116
self.fan_count = 0

View File

@@ -24,8 +24,8 @@ class M33SPlusVG20(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M33S+ VG20"
self.ideal_hashboards = 4
self.nominal_chips = 112
self.expected_hashboards = 4
self.expected_chips = 112
self.fan_count = 0
@@ -34,8 +34,8 @@ class M33SPlusVH20(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M33S+ VH20"
self.ideal_hashboards = 4
self.nominal_chips = 100
self.expected_hashboards = 4
self.expected_chips = 100
self.fan_count = 0
@@ -44,8 +44,8 @@ class M33SPlusVH30(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M33S+ VH30"
self.ideal_hashboards = 4
self.nominal_chips = 0 # slot1 116, slot2 106, slot3 116, slot4 106
self.expected_hashboards = 4
self.expected_chips = 0 # slot1 116, slot2 106, slot3 116, slot4 106
warnings.warn(
"Unknown chip count for miner type M30S+ VH30, please open an issue on GitHub (https://github.com/UpstreamData/pyasic)."
)

View File

@@ -24,8 +24,8 @@ class M33SPlusPlusVH20(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M33S++ VH20"
self.ideal_hashboards = 4
self.nominal_chips = 112
self.expected_hashboards = 4
self.expected_chips = 112
self.fan_count = 0
@@ -34,8 +34,8 @@ class M33SPlusPlusVH30(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M33S++ VH30"
self.ideal_hashboards = 4
self.nominal_chips = 0
self.expected_hashboards = 4
self.expected_chips = 0
warnings.warn(
"Unknown chip count for miner type M30S++ VH30, please open an issue on GitHub (https://github.com/UpstreamData/pyasic)."
)
@@ -47,6 +47,6 @@ class M33SPlusPlusVG40(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M33S++ VG40"
self.ideal_hashboards = 4
self.nominal_chips = 174
self.expected_hashboards = 4
self.expected_chips = 174
self.fan_count = 0

View File

@@ -22,6 +22,6 @@ class M34SPlusVE10(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M34S+ VE10"
self.ideal_hashboards = 4
self.nominal_chips = 116
self.expected_hashboards = 4
self.expected_chips = 116
self.fan_count = 0

View File

@@ -24,6 +24,6 @@ class M36SVE10(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M36S VE10"
self.ideal_hashboards = 4
self.nominal_chips = 114
self.expected_hashboards = 4
self.expected_chips = 114
self.fan_count = 0

View File

@@ -24,6 +24,6 @@ class M36SPlusVG30(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M36S+ VG30"
self.ideal_hashboards = 4
self.nominal_chips = 108
self.expected_hashboards = 4
self.expected_chips = 108
self.fan_count = 0

View File

@@ -24,6 +24,6 @@ class M36SPlusPlusVH30(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M36S++ VH30"
self.ideal_hashboards = 4
self.nominal_chips = 80
self.expected_hashboards = 4
self.expected_chips = 80
self.fan_count = 0

View File

@@ -24,7 +24,7 @@ class M39V10(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M39 V10"
self.nominal_chips = 50
self.expected_chips = 50
self.fan_count = 0
@@ -33,7 +33,7 @@ class M39V20(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M39 V20"
self.nominal_chips = 54
self.expected_chips = 54
self.fan_count = 0
@@ -42,5 +42,5 @@ class M39V30(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M39 V30"
self.nominal_chips = 68
self.expected_chips = 68
self.fan_count = 0

View File

@@ -24,8 +24,8 @@ class M50VE30(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M50 VE30"
self.ideal_hashboards = 4
self.nominal_chips = 255
self.expected_hashboards = 4
self.expected_chips = 255
self.fan_count = 2
@@ -34,7 +34,7 @@ class M50VG30(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M50 VG30"
self.nominal_chips = 156
self.expected_chips = 156
self.fan_count = 2
@@ -43,7 +43,7 @@ class M50VH10(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M50 VH10"
self.nominal_chips = 86
self.expected_chips = 86
self.fan_count = 2
@@ -52,7 +52,7 @@ class M50VH20(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M50 VH20"
self.nominal_chips = 111
self.expected_chips = 111
self.fan_count = 2
@@ -142,7 +142,7 @@ class M50VJ30(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M50 VJ30"
self.nominal_chips = 0
self.expected_chips = 0
warnings.warn(
"Unknown chip count for miner type M50 VJ30, please open an issue on GitHub (https://github.com/UpstreamData/pyasic)."
)

View File

@@ -24,7 +24,7 @@ class M50SVJ10(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M50S VJ10"
self.nominal_chips = 0
self.expected_chips = 0
warnings.warn(
"Unknown chip count for miner type M50S VJ10, please open an issue on GitHub (https://github.com/UpstreamData/pyasic)."
)
@@ -36,7 +36,7 @@ class M50SVJ20(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M50S VJ20"
self.nominal_chips = 0
self.expected_chips = 0
warnings.warn(
"Unknown chip count for miner type M50S VJ20, please open an issue on GitHub (https://github.com/UpstreamData/pyasic)."
)
@@ -48,7 +48,7 @@ class M50SVJ30(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M50S VJ30"
self.nominal_chips = 0
self.expected_chips = 0
warnings.warn(
"Unknown chip count for miner type M50S VJ30, please open an issue on GitHub (https://github.com/UpstreamData/pyasic)."
)
@@ -60,7 +60,7 @@ class M50SVH10(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M50S VH10"
self.nominal_chips = 0
self.expected_chips = 0
warnings.warn(
"Unknown chip count for miner type M50S VH10, please open an issue on GitHub (https://github.com/UpstreamData/pyasic)."
)
@@ -72,7 +72,7 @@ class M50SVH20(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M50S VH20"
self.nominal_chips = 135
self.expected_chips = 135
self.fan_count = 2
@@ -81,7 +81,7 @@ class M50SVH30(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M50S VH30"
self.nominal_chips = 156
self.expected_chips = 156
self.fan_count = 2
@@ -90,7 +90,7 @@ class M50SVH40(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M50S VH40"
self.nominal_chips = 0
self.expected_chips = 0
warnings.warn(
"Unknown chip count for miner type M50S VH40, please open an issue on GitHub (https://github.com/UpstreamData/pyasic)."
)
@@ -102,7 +102,7 @@ class M50SVH50(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M50S VH50"
self.nominal_chips = 0
self.expected_chips = 0
warnings.warn(
"Unknown chip count for miner type M50S VH50, please open an issue on GitHub (https://github.com/UpstreamData/pyasic)."
)

View File

@@ -24,7 +24,7 @@ class M50SPlusVH30(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M50S+ VH30"
self.nominal_chips = 0
self.expected_chips = 0
warnings.warn(
"Unknown chip count for miner type M50S+ VH30, please open an issue on GitHub (https://github.com/UpstreamData/pyasic)."
)
@@ -36,7 +36,7 @@ class M50SPlusVH40(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M50S+ VH40"
self.nominal_chips = 0
self.expected_chips = 0
warnings.warn(
"Unknown chip count for miner type M50S+ VH40, please open an issue on GitHub (https://github.com/UpstreamData/pyasic)."
)
@@ -48,7 +48,7 @@ class M50SPlusVJ30(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M50S+ VJ30"
self.nominal_chips = 0
self.expected_chips = 0
warnings.warn(
"Unknown chip count for miner type M50S+ VJ30, please open an issue on GitHub (https://github.com/UpstreamData/pyasic)."
)
@@ -60,5 +60,5 @@ class M50SPlusVK20(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M50S+ VK20"
self.nominal_chips = 117
self.expected_chips = 117
self.fan_count = 2

View File

@@ -24,7 +24,7 @@ class M50SPlusPlusVK10(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M50S++ VK10"
self.nominal_chips = 0
self.expected_chips = 0
warnings.warn(
"Unknown chip count for miner type M50S+ VK10, please open an issue on GitHub (https://github.com/UpstreamData/pyasic)."
)
@@ -36,7 +36,7 @@ class M50SPlusPlusVK20(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M50S++ VK20"
self.nominal_chips = 0
self.expected_chips = 0
warnings.warn(
"Unknown chip count for miner type M50S+ VK20, please open an issue on GitHub (https://github.com/UpstreamData/pyasic)."
)
@@ -48,5 +48,5 @@ class M50SPlusPlusVK30(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M50S++ VK30"
self.nominal_chips = 76
self.expected_chips = 76
self.fan_count = 2

View File

@@ -24,6 +24,6 @@ class M53VH30(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M53 VH30"
self.ideal_hashboards = 4
self.nominal_chips = 128
self.expected_hashboards = 4
self.expected_chips = 128
self.fan_count = 0

View File

@@ -24,7 +24,7 @@ class M53SVH30(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M53S VH30"
self.nominal_chips = 0
self.expected_chips = 0
warnings.warn(
"Unknown chip count for miner type M53S VH30, please open an issue on GitHub (https://github.com/UpstreamData/pyasic)."
)

View File

@@ -24,7 +24,7 @@ class M53SPlusVJ30(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M53S+ VJ30"
self.nominal_chips = 0
self.expected_chips = 0
warnings.warn(
"Unknown chip count for miner type M53S+ VJ30, please open an issue on GitHub (https://github.com/UpstreamData/pyasic)."
)

View File

@@ -24,6 +24,6 @@ class M56VH30(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M56 VH30"
self.ideal_hashboards = 4
self.nominal_chips = 108
self.expected_hashboards = 4
self.expected_chips = 108
self.fan_count = 0

View File

@@ -24,7 +24,7 @@ class M56SVH30(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M56S VH30"
self.nominal_chips = 0
self.expected_chips = 0
warnings.warn(
"Unknown chip count for miner type M56S VH30, please open an issue on GitHub (https://github.com/UpstreamData/pyasic)."
)

View File

@@ -24,7 +24,7 @@ class M56SPlusVJ30(WhatsMiner): # noqa - ignore ABC method implementation
super().__init__(ip, api_ver)
self.ip = ip
self.model = "M56S+ VJ30"
self.nominal_chips = 0
self.expected_chips = 0
warnings.warn(
"Unknown chip count for miner type M56S+ VJ30, please open an issue on GitHub (https://github.com/UpstreamData/pyasic)."
)

Some files were not shown because too many files have changed in this diff Show More