Compare commits

...

14 Commits

Author SHA1 Message Date
Upstream Data
6bcf372be6 version: bump version number. 2023-03-04 17:55:46 -07:00
Upstream Data
092a586329 bug: fix an issue with innosilicon A10X not allowing pool config. 2023-03-04 17:46:11 -07:00
Upstream Data
e598d4b63c version: bump version number. 2023-03-04 16:14:02 -07:00
Upstream Data
848acedd52 feature: add support for E9Pro and fix some bugs and update finding chip data for Goldshell models. 2023-03-04 16:13:03 -07:00
DCreason
e3c4464556 fix internal error when not using vnish preset (#33) 2023-03-04 07:54:27 -07:00
UpstreamData
9e28f7968a version: bump version number. 2023-03-03 13:16:14 -07:00
UpstreamData
6159a72d46 feature: add support for antminer HS3. 2023-03-03 13:15:22 -07:00
UpstreamData
932c034e0e feature: improve load balancer to handle for bad boards. 2023-03-03 12:25:12 -07:00
UpstreamData
645828f35b bug: fix btminer adjust power limit and add poweroff for innosilicon miners (though it breaks the miner) 2023-03-03 10:58:16 -07:00
UpstreamData
841a546505 bug: fix some bugs. 2023-03-02 16:17:32 -07:00
UpstreamData
e65b718699 version: bump version number. 2023-03-02 13:10:27 -07:00
UpstreamData
15e4338046 feature: add support for DR5, KD5, KDMax, CK5, and A10X. 2023-03-02 13:09:46 -07:00
UpstreamData
720d4aec3d feature: add support for Goldshell HS5 2023-03-02 11:32:28 -07:00
UpstreamData
09f9028ab5 format: reformat miner files to improve readability. 2023-03-02 08:58:10 -07:00
343 changed files with 6336 additions and 552 deletions

673
pyasic/API/bfgminer.py Normal file
View File

@@ -0,0 +1,673 @@
# ------------------------------------------------------------------------------
# Copyright 2022 Upstream Data Inc -
# -
# Licensed under the Apache License, Version 2.0 (the "License"); -
# you may not use this file except in compliance with the License. -
# You may obtain a copy of the License at -
# -
# http://www.apache.org/licenses/LICENSE-2.0 -
# -
# Unless required by applicable law or agreed to in writing, software -
# distributed under the License is distributed on an "AS IS" BASIS, -
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
# See the License for the specific language governing permissions and -
# limitations under the License. -
# ------------------------------------------------------------------------------
import logging
from pyasic.API import APIError, BaseMinerAPI
class BFGMinerAPI(BaseMinerAPI):
"""An abstraction of the BFGMiner API.
Each method corresponds to an API command in BFGMiner.
[BFGMiner API documentation](https://github.com/luke-jr/bfgminer/blob/bfgminer/README.RPC)
This class abstracts use of the BFGMiner API, as well as the
methods for sending commands to it. The self.send_command()
function handles sending a command to the miner asynchronously, and
as such is the base for many of the functions in this class, which
rely on it to send the command for them.
Parameters:
ip: The IP of the miner to reference the API on.
port: The port to reference the API on. Default is 4028.
"""
def __init__(self, ip: str, api_ver: str = "0.0.0", port: int = 4028):
super().__init__(ip, port)
self.api_ver = api_ver
async def multicommand(self, *commands: str, allow_warning: bool = True) -> dict:
# make sure we can actually run each command, otherwise they will fail
commands = self._check_commands(*commands)
# standard multicommand format is "command1+command2"
# doesn't work for S19 which uses the backup _x19_multicommand
command = "+".join(commands)
try:
data = await self.send_command(command, allow_warning=allow_warning)
except APIError:
logging.debug(f"{self} - (Multicommand) - Handling X19 multicommand.")
data = await self._x19_multicommand(*command.split("+"))
return data
async def _x19_multicommand(self, *commands):
data = None
try:
data = {}
# send all commands individually
for cmd in commands:
data[cmd] = []
data[cmd].append(await self.send_command(cmd, allow_warning=True))
except APIError:
pass
except Exception as e:
logging.warning(
f"{self} - ([Hidden] X19 Multicommand) - API Command Error {e}"
)
return data
async def version(self) -> dict:
"""Get miner version info.
<details>
<summary>Expand</summary>
Returns:
Miner version information.
</details>
"""
return await self.send_command("version")
async def config(self) -> dict:
"""Get some basic configuration info.
<details>
<summary>Expand</summary>
Returns:
## Some miner configuration information:
* ASC Count <- the number of ASCs
* PGA Count <- the number of PGAs
* Pool Count <- the number of Pools
* Strategy <- the current pool strategy
* Log Interval <- the interval of logging
* Device Code <- list of compiled device drivers
* OS <- the current operating system
* Failover-Only <- failover-only setting
* Scan Time <- scan-time setting
* Queue <- queue setting
* Expiry <- expiry setting
</details>
"""
return await self.send_command("config")
async def summary(self) -> dict:
"""Get the status summary of the miner.
<details>
<summary>Expand</summary>
Returns:
The status summary of the miner.
</details>
"""
return await self.send_command("summary")
async def pools(self) -> dict:
"""Get pool information.
<details>
<summary>Expand</summary>
Returns:
Miner pool information.
</details>
"""
return await self.send_command("pools")
async def devs(self) -> dict:
"""Get data on each PGA/ASC with their details.
<details>
<summary>Expand</summary>
Returns:
Data on each PGA/ASC with their details.
</details>
"""
return await self.send_command("devs")
async def procs(self) -> dict:
"""Get data on each processor with their details.
<details>
<summary>Expand</summary>
Returns:
Data on each processor with their details.
</details>
"""
return await self.send_command("procs")
async def devscan(self, info: str = "") -> dict:
"""Get data on each processor with their details.
<details>
<summary>Expand</summary>
Parameters:
info: Info to scan for device by.
Returns:
Data on each processor with their details.
</details>
"""
return await self.send_command("devscan", parameters=info)
async def pga(self, n: int) -> dict:
"""Get data from PGA n.
<details>
<summary>Expand</summary>
Parameters:
n: The PGA number to get data from.
Returns:
Data on the PGA n.
</details>
"""
return await self.send_command("pga", parameters=n)
async def proc(self, n: int = 0) -> dict:
"""Get data processor n.
<details>
<summary>Expand</summary>
Parameters:
n: The processor to get data on.
Returns:
Data on processor n.
</details>
"""
return await self.send_command("proc", parameters=n)
async def pgacount(self) -> dict:
"""Get data fon all PGAs.
<details>
<summary>Expand</summary>
Returns:
Data on the PGAs connected.
</details>
"""
return await self.send_command("pgacount")
async def proccount(self) -> dict:
"""Get data fon all processors.
<details>
<summary>Expand</summary>
Returns:
Data on the processors connected.
</details>
"""
return await self.send_command("proccount")
async def switchpool(self, n: int) -> dict:
"""Switch pools to pool n.
<details>
<summary>Expand</summary>
Parameters:
n: The pool to switch to.
Returns:
A confirmation of switching to pool n.
</details>
"""
return await self.send_command("switchpool", parameters=n)
async def enablepool(self, n: int) -> dict:
"""Enable pool n.
<details>
<summary>Expand</summary>
Parameters:
n: The pool to enable.
Returns:
A confirmation of enabling pool n.
</details>
"""
return await self.send_command("enablepool", parameters=n)
async def addpool(self, url: str, username: str, password: str) -> dict:
"""Add a pool to the miner.
<details>
<summary>Expand</summary>
Parameters:
url: The URL of the new pool to add.
username: The users username on the new pool.
password: The worker password on the new pool.
Returns:
A confirmation of adding the pool.
</details>
"""
return await self.send_command(
"addpool", parameters=f"{url},{username},{password}"
)
async def poolpriority(self, *n: int) -> dict:
"""Set pool priority.
<details>
<summary>Expand</summary>
Parameters:
*n: Pools in order of priority.
Returns:
A confirmation of setting pool priority.
</details>
"""
pools = f"{','.join([str(item) for item in n])}"
return await self.send_command("poolpriority", parameters=pools)
async def poolquota(self, n: int, q: int) -> dict:
"""Set pool quota.
<details>
<summary>Expand</summary>
Parameters:
n: Pool number to set quota on.
q: Quota to set the pool to.
Returns:
A confirmation of setting pool quota.
</details>
"""
return await self.send_command("poolquota", parameters=f"{n},{q}")
async def disablepool(self, n: int) -> dict:
"""Disable a pool.
<details>
<summary>Expand</summary>
Parameters:
n: Pool to disable.
Returns:
A confirmation of diabling the pool.
</details>
"""
return await self.send_command("disablepool", parameters=n)
async def removepool(self, n: int) -> dict:
"""Remove a pool.
<details>
<summary>Expand</summary>
Parameters:
n: Pool to remove.
Returns:
A confirmation of removing the pool.
</details>
"""
return await self.send_command("removepool", parameters=n)
async def save(self, filename: str = None) -> dict:
"""Save the config.
<details>
<summary>Expand</summary>
Parameters:
filename: Filename to save the config as.
Returns:
A confirmation of saving the config.
</details>
"""
if filename:
return await self.send_command("save", parameters=filename)
else:
return await self.send_command("save")
async def quit(self) -> dict:
"""Quit CGMiner.
<details>
<summary>Expand</summary>
Returns:
A single "BYE" before CGMiner quits.
</details>
"""
return await self.send_command("quit")
async def notify(self) -> dict:
"""Notify the user of past errors.
<details>
<summary>Expand</summary>
Returns:
The last status and count of each devices problem(s).
</details>
"""
return await self.send_command("notify")
async def privileged(self) -> dict:
"""Check if you have privileged access.
<details>
<summary>Expand</summary>
Returns:
The STATUS section with an error if you have no privileged access, or success if you have privileged access.
</details>
"""
return await self.send_command("privileged")
async def pgaenable(self, n: int) -> dict:
"""Enable PGA n.
<details>
<summary>Expand</summary>
Parameters:
n: The PGA to enable.
Returns:
A confirmation of enabling PGA n.
</details>
"""
return await self.send_command("pgaenable", parameters=n)
async def pgadisable(self, n: int) -> dict:
"""Disable PGA n.
<details>
<summary>Expand</summary>
Parameters:
n: The PGA to disable.
Returns:
A confirmation of disabling PGA n.
</details>
"""
return await self.send_command("pgadisable", parameters=n)
async def pgarestart(self, n: int) -> dict:
"""Restart PGA n.
<details>
<summary>Expand</summary>
Parameters:
n: The PGA to restart.
Returns:
A confirmation of restarting PGA n.
</details>
"""
return await self.send_command("pgadisable", parameters=n)
async def pgaidentify(self, n: int) -> dict:
"""Identify PGA n.
<details>
<summary>Expand</summary>
Parameters:
n: The PGA to identify.
Returns:
A confirmation of identifying PGA n.
</details>
"""
return await self.send_command("pgaidentify", parameters=n)
async def procenable(self, n: int) -> dict:
"""Enable processor n.
<details>
<summary>Expand</summary>
Parameters:
n: The processor to enable.
Returns:
A confirmation of enabling processor n.
</details>
"""
return await self.send_command("procenable", parameters=n)
async def procdisable(self, n: int) -> dict:
"""Disable processor n.
<details>
<summary>Expand</summary>
Parameters:
n: The processor to disable.
Returns:
A confirmation of disabling processor n.
</details>
"""
return await self.send_command("procdisable", parameters=n)
async def procrestart(self, n: int) -> dict:
"""Restart processor n.
<details>
<summary>Expand</summary>
Parameters:
n: The processor to restart.
Returns:
A confirmation of restarting processor n.
</details>
"""
return await self.send_command("procdisable", parameters=n)
async def procidentify(self, n: int) -> dict:
"""Identify processor n.
<details>
<summary>Expand</summary>
Parameters:
n: The processor to identify.
Returns:
A confirmation of identifying processor n.
</details>
"""
return await self.send_command("procidentify", parameters=n)
async def devdetails(self) -> dict:
"""Get data on all devices with their static details.
<details>
<summary>Expand</summary>
Returns:
Data on all devices with their static details.
</details>
"""
return await self.send_command("devdetails")
async def restart(self) -> dict:
"""Restart CGMiner using the API.
<details>
<summary>Expand</summary>
Returns:
A reply informing of the restart.
</details>
"""
return await self.send_command("restart")
async def stats(self) -> dict:
"""Get stats of each device/pool with more than 1 getwork.
<details>
<summary>Expand</summary>
Returns:
Stats of each device/pool with more than 1 getwork.
</details>
"""
return await self.send_command("stats")
async def check(self, command: str) -> dict:
"""Check if the command command exists in CGMiner.
<details>
<summary>Expand</summary>
Parameters:
command: The command to check.
Returns:
## Information about a command:
* Exists (Y/N) <- the command exists in this version
* Access (Y/N) <- you have access to use the command
</details>
"""
return await self.send_command("check", parameters=command)
async def failover_only(self, failover: bool) -> dict:
"""Set failover-only.
<details>
<summary>Expand</summary>
Parameters:
failover: What to set failover-only to.
Returns:
Confirmation of setting failover-only.
</details>
"""
return await self.send_command("failover-only", parameters=failover)
async def coin(self) -> dict:
"""Get information on the current coin.
<details>
<summary>Expand</summary>
Returns:
## Information about the current coin being mined:
* Hash Method <- the hashing algorithm
* Current Block Time <- blocktime as a float, 0 means none
* Current Block Hash <- the hash of the current block, blank means none
* LP <- whether LP is in use on at least 1 pool
* Network Difficulty: the current network difficulty
</details>
"""
return await self.send_command("coin")
async def debug(self, setting: str) -> dict:
"""Set a debug setting.
<details>
<summary>Expand</summary>
Parameters:
setting: Which setting to switch to.
## Options are:
* Silent
* Quiet
* Verbose
* Debug
* RPCProto
* PerDevice
* WorkTime
* Normal
Returns:
Data on which debug setting was enabled or disabled.
</details>
"""
return await self.send_command("debug", parameters=setting)
async def setconfig(self, name: str, n: int) -> dict:
"""Set config of name to value n.
<details>
<summary>Expand</summary>
Parameters:
name: The name of the config setting to set.
## Options are:
* queue
* scantime
* expiry
n: The value to set the 'name' setting to.
Returns:
The results of setting config of name to n.
</details>
"""
return await self.send_command("setconfig", parameters=f"{name},{n}")
async def pgaset(self, n: int, opt: str, val: int = None) -> dict:
"""Set PGA option opt to val on PGA n.
<details>
<summary>Expand</summary>
Options:
```
MMQ -
opt: clock
val: 2 - 250 (multiple of 2)
XBS -
opt: clock
val: 2 - 250 (multiple of 2)
```
Parameters:
n: The PGA to set the options on.
opt: The option to set. Setting this to 'help' returns a help message.
val: The value to set the option to.
Returns:
Confirmation of setting PGA n with opt[,val].
</details>
"""
if val:
return await self.send_command("pgaset", parameters=f"{n},{opt},{val}")
else:
return await self.send_command("pgaset", parameters=f"{n},{opt}")
async def pprocset(self, n: int, opt: str, val: int = None) -> dict:
"""Set processor option opt to val on processor n.
<details>
<summary>Expand</summary>
Options:
```
MMQ -
opt: clock
val: 2 - 250 (multiple of 2)
XBS -
opt: clock
val: 2 - 250 (multiple of 2)
```
Parameters:
n: The PGA to set the options on.
opt: The option to set. Setting this to 'help' returns a help message.
val: The value to set the option to.
Returns:
Confirmation of setting PGA n with opt[,val].
</details>
"""
if val:
return await self.send_command("pgaset", parameters=f"{n},{opt},{val}")
else:
return await self.send_command("pgaset", parameters=f"{n},{opt}")
async def zero(self, which: str, summary: bool) -> dict:
"""Zero a device.
<details>
<summary>Expand</summary>
Parameters:
which: Which device to zero. Setting this to 'all' zeros all devices. Setting this to 'bestshare' zeros only the bestshare values for each pool and global.
summary: Whether or not to show a full summary.
Returns:
the STATUS section with info on the zero and optional summary.
</details>
"""
return await self.send_command("zero", parameters=f"{which},{summary}")

View File

@@ -767,7 +767,7 @@ class BTMinerAPI(BaseMinerAPI):
"""
return await self.send_privileged_command(
"adjust_power_limit", power_limit=power_limit
"adjust_power_limit", power_limit=str(power_limit)
)
@api_min_version("2.0.5")

View File

@@ -91,8 +91,21 @@ class _Pool:
pool = {"url": self.url, "user": username, "pass": self.password}
return pool
def as_x15(self, user_suffix: str = None) -> dict:
"""Convert the data in this class to a dict usable by an X19 device.
def as_x17(self, user_suffix: str = None) -> dict:
"""Convert the data in this class to a dict usable by an X5 device.
Parameters:
user_suffix: The suffix to append to username.
"""
username = self.username
if user_suffix:
username = f"{username}{user_suffix}"
pool = {"url": self.url, "user": username, "pass": self.password}
return pool
def as_goldshell(self, user_suffix: str = None) -> dict:
"""Convert the data in this class to a dict usable by a goldshell device.
Parameters:
user_suffix: The suffix to append to username.
@@ -201,8 +214,9 @@ class _PoolGroup:
pools.append(pool.as_x19(user_suffix=user_suffix))
return pools
def as_x15(self, user_suffix: str = None) -> dict:
"""Convert the data in this class to a list usable by an X15 device.
def as_x17(self, user_suffix: str = None) -> dict:
"""Convert the data in this class to a list usable by an X5 device.
Parameters:
user_suffix: The suffix to append to username.
@@ -219,23 +233,37 @@ class _PoolGroup:
"_ant_pool3pw": "",
}
for idx, pool in enumerate(self.pools[:3]):
pools[f"_ant_pool{idx+1}url"] = pool.as_x15(user_suffix=user_suffix)["url"]
pools[f"_ant_pool{idx+1}user"] = pool.as_x15(user_suffix=user_suffix)[
"user"
]
pools[f"_ant_pool{idx+1}pw"] = pool.as_x15(user_suffix=user_suffix)[
"pass"
]
pools[f"_ant_pool{idx+1}url"] = pool.as_x17(user_suffix=user_suffix)["url"]
pools[f"_ant_pool{idx+1}user"] = pool.as_x17(user_suffix=user_suffix)["user"]
pools[f"_ant_pool{idx+1}pw"] = pool.as_x17(user_suffix=user_suffix)["pass"]
return pools
def as_goldshell(self, user_suffix: str = None) -> list:
"""Convert the data in this class to a list usable by a goldshell device.
Parameters:
user_suffix: The suffix to append to username.
"""
return [pool.as_goldshell(user_suffix=user_suffix) for pool in self.pools[:3]]
def as_inno(self, user_suffix: str = None) -> dict:
"""Convert the data in this class to a list usable by an Innosilicon device.
Parameters:
user_suffix: The suffix to append to username.
"""
pools = {}
pools = {
"Pool1": None,
"UserName1": None,
"Password1": None,
"Pool2": None,
"UserName2": None,
"Password2": None,
"Pool3": None,
"UserName3": None,
"Password3": None,
}
for idx, pool in enumerate(self.pools[:3]):
pool_data = pool.as_inno(user_suffix=user_suffix)
for key in pool_data:
@@ -366,6 +394,9 @@ class MinerConfig:
"""
logging.debug(f"MinerConfig - (From Raw) - Loading raw config")
pool_groups = []
if isinstance(data, list):
# goldshell config list
data = {"pools": data}
for key in data.keys():
if key == "pools":
pool_groups.append(_PoolGroup().from_dict({"pools": data[key]}))
@@ -457,8 +488,14 @@ class MinerConfig:
for group in data["pool_groups"]:
pool_groups.append(_PoolGroup().from_dict(group))
for key in data:
if hasattr(self, key) and not key == "pool_groups":
if (
hasattr(self, key)
and not key == "pool_groups"
and not key == "miner_mode"
):
setattr(self, key, data[key])
if key == "miner_mode":
self.miner_mode = X19PowerMode(data[key])
self.pool_groups = pool_groups
return self
@@ -523,13 +560,23 @@ class MinerConfig:
return cfg
def as_x15(self, user_suffix: str = None) -> dict:
"""Convert the data in this class to a config usable by an X15 device.
def as_x17(self, user_suffix: str = None) -> dict:
"""Convert the data in this class to a config usable by an X5 device.
Parameters:
user_suffix: The suffix to append to username.
"""
cfg = self.pool_groups[0].as_x15(user_suffix=user_suffix)
cfg = self.pool_groups[0].as_x17(user_suffix=user_suffix)
return cfg
def as_goldshell(self, user_suffix: str = None) -> list:
"""Convert the data in this class to a config usable by a goldshell device.
Parameters:
user_suffix: The suffix to append to username.
"""
cfg = self.pool_groups[0].as_goldshell(user_suffix=user_suffix)
return cfg

View File

@@ -259,8 +259,9 @@ class MinerData:
@property
def left_chips(self): # noqa - Skip PyCharm inspection
if len(self.hashboards) in [2, 3]:
if len(self.hashboards) in [2, 3, 4]:
return self.hashboards[0].chips
return 0
@left_chips.setter
@@ -271,7 +272,7 @@ class MinerData:
def center_chips(self): # noqa - Skip PyCharm inspection
if len(self.hashboards) == 1:
return self.hashboards[0].chips
if len(self.hashboards) == 3:
if len(self.hashboards) in [2, 3, 4]:
return self.hashboards[1].chips
return 0
@@ -285,6 +286,8 @@ class MinerData:
return self.hashboards[1].chips
if len(self.hashboards) == 3:
return self.hashboards[2].chips
if len(self.hashboards) > 3:
return self.hashboards[-1:][0].chips
return 0
@right_chips.setter
@@ -293,7 +296,7 @@ class MinerData:
@property
def left_board_hashrate(self): # noqa - Skip PyCharm inspection
if len(self.hashboards) in [2, 3]:
if len(self.hashboards) in [2, 3, 4]:
return self.hashboards[0].hashrate
return 0
@@ -305,7 +308,7 @@ class MinerData:
def center_board_hashrate(self): # noqa - Skip PyCharm inspection
if len(self.hashboards) == 1:
return self.hashboards[0].hashrate
if len(self.hashboards) == 3:
if len(self.hashboards) in [2, 3, 4]:
return self.hashboards[1].hashrate
return 0
@@ -319,6 +322,8 @@ class MinerData:
return self.hashboards[1].hashrate
if len(self.hashboards) == 3:
return self.hashboards[2].hashrate
if len(self.hashboards) > 3:
return self.hashboards[-1:][0].hashrate
return 0
@right_board_hashrate.setter
@@ -327,7 +332,7 @@ class MinerData:
@property
def left_board_temp(self): # noqa - Skip PyCharm inspection
if len(self.hashboards) in [2, 3]:
if len(self.hashboards) in [2, 3, 4]:
return self.hashboards[0].temp
return 0
@@ -339,7 +344,7 @@ class MinerData:
def center_board_temp(self): # noqa - Skip PyCharm inspection
if len(self.hashboards) == 1:
return self.hashboards[0].temp
if len(self.hashboards) == 3:
if len(self.hashboards) in [2, 3, 4]:
return self.hashboards[1].temp
return 0
@@ -353,6 +358,8 @@ class MinerData:
return self.hashboards[1].temp
if len(self.hashboards) == 3:
return self.hashboards[2].temp
if len(self.hashboards) > 3:
return self.hashboards[-1:][0].temp
return 0
@right_board_temp.setter
@@ -361,7 +368,7 @@ class MinerData:
@property
def left_board_chip_temp(self): # noqa - Skip PyCharm inspection
if len(self.hashboards) in [2, 3]:
if len(self.hashboards) in [2, 3, 4]:
return self.hashboards[0].chip_temp
return 0
@@ -373,7 +380,7 @@ class MinerData:
def center_board_chip_temp(self): # noqa - Skip PyCharm inspection
if len(self.hashboards) == 1:
return self.hashboards[0].chip_temp
if len(self.hashboards) == 3:
if len(self.hashboards) in [2, 3, 4]:
return self.hashboards[1].chip_temp
return 0
@@ -387,6 +394,8 @@ class MinerData:
return self.hashboards[1].chip_temp
if len(self.hashboards) == 3:
return self.hashboards[2].chip_temp
if len(self.hashboards) > 3:
return self.hashboards[-1:][0].chip_temp
return 0
@right_board_chip_temp.setter

View File

@@ -19,12 +19,12 @@ from typing import List, Union
from pyasic.errors import APIError
from pyasic.miners import AnyMiner
from pyasic.miners._backends import ( # noqa - Ignore access to _module
from pyasic.miners.btc._backends import ( # noqa - Ignore access to _module
X19,
BOSMiner,
BTMiner,
)
from pyasic.miners._types import ( # noqa - Ignore access to _module
from pyasic.miners.btc._types import ( # noqa - Ignore access to _module
S9,
S17,
T17,
@@ -143,13 +143,19 @@ class _MinerPhaseBalancer:
async def get_balance_setpoints(self, wattage: int) -> dict:
# gather data needed to optimize shutdown only miners
dp = ["hashrate", "wattage", "wattage_limit"]
dp = ["hashrate", "wattage", "wattage_limit", "hashboards"]
data = await asyncio.gather(
*[
self.miners[miner]["miner"].get_data(data_to_get=dp)
for miner in self.miners
]
)
pct_ideal_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)
wattage = round(wattage * 1 / (pct_ideal / 100))
for data_point in data:
if (not self.miners[data_point.ip]["tune"]) and (

View File

@@ -0,0 +1,19 @@
# ------------------------------------------------------------------------------
# Copyright 2022 Upstream Data Inc -
# -
# Licensed under the Apache License, Version 2.0 (the "License"); -
# you may not use this file except in compliance with the License. -
# You may obtain a copy of the License at -
# -
# http://www.apache.org/licenses/LICENSE-2.0 -
# -
# Unless required by applicable law or agreed to in writing, software -
# distributed under the License is distributed on an "AS IS" BASIS, -
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
# See the License for the specific language governing permissions and -
# limitations under the License. -
# ------------------------------------------------------------------------------
from .antminer import *
from .avalonminer import *
from .innosilicon import *
from .whatsminer import *

View File

@@ -20,7 +20,7 @@ from typing import List, Optional, Union
from pyasic.API import APIError
from pyasic.config import MinerConfig, X19PowerMode
from pyasic.data.error_codes import MinerErrorData, X19Error
from pyasic.miners._backends import BMMiner # noqa - Ignore access to _module
from pyasic.miners.btc._backends import BMMiner # noqa - Ignore access to _module
from pyasic.web.X19 import X19WebAPI

View File

@@ -22,5 +22,3 @@ from .cgminer_avalon import CGMinerAvalon
from .hiveon import Hiveon
from .vnish import VNish
from .X19 import X19
from .X7 import X7
from .X15 import X15

View File

@@ -22,7 +22,7 @@ from pyasic.config import MinerConfig
from pyasic.data import Fan, HashBoard
from pyasic.data.error_codes import MinerErrorData
from pyasic.errors import APIError
from pyasic.miners._backends import CGMiner
from pyasic.miners.btc._backends import CGMiner
class CGMinerAvalon(CGMiner):

View File

@@ -16,7 +16,7 @@
import ipaddress
from pyasic.miners._backends import BMMiner
from pyasic.miners.btc._backends import BMMiner
class Hiveon(BMMiner):

View File

@@ -18,7 +18,7 @@ import logging
from typing import Optional
from pyasic.errors import APIError
from pyasic.miners._backends.bmminer import BMMiner
from pyasic.miners.btc._backends.bmminer import BMMiner
from pyasic.web.vnish import VNishWebAPI
@@ -138,6 +138,8 @@ class VNish(BMMiner):
if web_settings:
try:
wattage_limit = web_settings["miner"]["overclock"]["preset"]
if wattage_limit == "disabled":
return None
return int(wattage_limit)
except (KeyError, TypeError):
pass

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners._types.makes import AntMiner
from pyasic.miners.makes import AntMiner
class S17(AntMiner): # noqa - ignore ABC method implementation

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners._types.makes import AntMiner
from pyasic.miners.makes import AntMiner
class S17Plus(AntMiner): # noqa - ignore ABC method implementation

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners._types.makes import AntMiner
from pyasic.miners.makes import AntMiner
class S17Pro(AntMiner): # noqa - ignore ABC method implementation

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners._types.makes import AntMiner
from pyasic.miners.makes import AntMiner
class S17e(AntMiner): # noqa - ignore ABC method implementation

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners._types.makes import AntMiner
from pyasic.miners.makes import AntMiner
class T17(AntMiner): # noqa - ignore ABC method implementation

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners._types.makes import AntMiner
from pyasic.miners.makes import AntMiner
class T17Plus(AntMiner): # noqa - ignore ABC method implementation

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners._types.makes import AntMiner
from pyasic.miners.makes import AntMiner
class T17e(AntMiner): # noqa - ignore ABC method implementation

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners._types.makes import AntMiner
from pyasic.miners.makes import AntMiner
class S19(AntMiner): # noqa - ignore ABC method implementation

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners._types.makes import AntMiner
from pyasic.miners.makes import AntMiner
class S19Pro(AntMiner): # noqa - ignore ABC method implementation

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners._types.makes import AntMiner
from pyasic.miners.makes import AntMiner
class S19XP(AntMiner): # noqa - ignore ABC method implementation

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners._types.makes import AntMiner
from pyasic.miners.makes import AntMiner
class S19a(AntMiner): # noqa - ignore ABC method implementation

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners._types.makes import AntMiner
from pyasic.miners.makes import AntMiner
class S19aPro(AntMiner): # noqa - ignore ABC method implementation

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners._types.makes import AntMiner
from pyasic.miners.makes import AntMiner
class S19j(AntMiner): # noqa - ignore ABC method implementation

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners._types.makes import AntMiner
from pyasic.miners.makes import AntMiner
class S19jPro(AntMiner): # noqa - ignore ABC method implementation

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners._types.makes import AntMiner
from pyasic.miners.makes import AntMiner
class T19(AntMiner): # noqa - ignore ABC method implementation

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners._types.makes import AntMiner
from pyasic.miners.makes import AntMiner
class S9(AntMiner): # noqa - ignore ABC method implementation

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners._types.makes import AntMiner
from pyasic.miners.makes import AntMiner
class S9i(AntMiner): # noqa - ignore ABC method implementation

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners._types.makes import AntMiner
from pyasic.miners.makes import AntMiner
class T9(AntMiner): # noqa - ignore ABC method implementation

View File

@@ -13,7 +13,6 @@
# See the License for the specific language governing permissions and -
# limitations under the License. -
# ------------------------------------------------------------------------------
from .X7 import *
from .X9 import *
from .X17 import *
from .X19 import *

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners._types.makes import AvalonMiner
from pyasic.miners.makes import AvalonMiner
class Avalon1026(AvalonMiner): # noqa - ignore ABC method implementation

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners._types.makes import AvalonMiner
from pyasic.miners.makes import AvalonMiner
class Avalon1047(AvalonMiner): # noqa - ignore ABC method implementation

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners._types.makes import AvalonMiner
from pyasic.miners.makes import AvalonMiner
class Avalon1066(AvalonMiner): # noqa - ignore ABC method implementation

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners._types.makes import AvalonMiner
from pyasic.miners.makes import AvalonMiner
class Avalon721(AvalonMiner): # noqa - ignore ABC method implementation

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners._types.makes import AvalonMiner
from pyasic.miners.makes import AvalonMiner
class Avalon741(AvalonMiner): # noqa - ignore ABC method implementation

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners._types.makes import AvalonMiner
from pyasic.miners.makes import AvalonMiner
class Avalon761(AvalonMiner): # noqa - ignore ABC method implementation

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners._types.makes import AvalonMiner
from pyasic.miners.makes import AvalonMiner
class Avalon821(AvalonMiner): # noqa - ignore ABC method implementation

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners._types.makes import AvalonMiner
from pyasic.miners.makes import AvalonMiner
class Avalon841(AvalonMiner): # noqa - ignore ABC method implementation

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners._types.makes import AvalonMiner
from pyasic.miners.makes import AvalonMiner
class Avalon851(AvalonMiner): # noqa - ignore ABC method implementation

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners._types.makes import AvalonMiner
from pyasic.miners.makes import AvalonMiner
class Avalon921(AvalonMiner): # noqa - ignore ABC method implementation

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners._types.makes import InnosiliconMiner
from pyasic.miners.makes import InnosiliconMiner
class InnosiliconT3HPlus(InnosiliconMiner): # noqa - ignore ABC method implementation

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M20V10(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -16,7 +16,7 @@
import warnings
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M20SV10(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -16,7 +16,7 @@
import warnings
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M20SPlusV30(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -16,7 +16,7 @@
import warnings
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M21V10(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -16,7 +16,7 @@
import warnings
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M21SV20(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -16,7 +16,7 @@
import warnings
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M21SPlusV20(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -16,7 +16,7 @@
import warnings
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M29V10(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -16,7 +16,7 @@
import warnings
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M30V10(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -16,7 +16,7 @@
import warnings
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M30SV10(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -16,7 +16,7 @@
import warnings
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M30SPlusV10(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -16,7 +16,7 @@
import warnings
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M30SPlusPlusV10(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -16,7 +16,7 @@
import warnings
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M31V10(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -16,7 +16,7 @@
import warnings
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M31HV40(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -16,7 +16,7 @@
import warnings
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M31SV10(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -16,7 +16,7 @@
import warnings
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M31SEV10(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -16,7 +16,7 @@
import warnings
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M31SPlusV10(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -16,7 +16,7 @@
import warnings
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M32V10(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M32S(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -16,7 +16,7 @@
import warnings
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M33V10(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -16,7 +16,7 @@
import warnings
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M33SVG30(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -16,7 +16,7 @@
import warnings
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M33SPlusVH20(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -16,7 +16,7 @@
import warnings
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M33SPlusPlusVH20(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M34SPlusVE10(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -16,7 +16,7 @@
import warnings
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M36SVE10(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -16,7 +16,7 @@
import warnings
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M36SPlusVG30(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -16,7 +16,7 @@
import warnings
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M36SPlusPlusVH30(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -16,7 +16,7 @@
import warnings
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M39V20(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -16,7 +16,7 @@
import warnings
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M50VG30(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -16,7 +16,7 @@
import warnings
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M50SVJ10(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -16,7 +16,7 @@
import warnings
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M50SPlusVH30(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -16,7 +16,7 @@
import warnings
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M53VH30(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -16,7 +16,7 @@
import warnings
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M53SVH30(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -16,7 +16,7 @@
import warnings
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M53SPlusVJ30(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -16,7 +16,7 @@
import warnings
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M56VH30(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -16,7 +16,7 @@
import warnings
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M56SVH30(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -16,7 +16,7 @@
import warnings
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M56SPlusVJ30(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -16,7 +16,7 @@
import warnings
from pyasic.miners._types.makes import WhatsMiner
from pyasic.miners.makes import WhatsMiner
class M59VH30(WhatsMiner): # noqa - ignore ABC method implementation

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners._types import S17 # noqa - Ignore access to _module
from pyasic.miners.btc._types import S17 # noqa - Ignore access to _module
from .X17 import BMMinerX17

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