update documentation and add docs from config

This commit is contained in:
UpstreamData
2022-07-13 16:17:08 -06:00
parent c6c87a864d
commit ca6980b1ad
14 changed files with 178 additions and 96 deletions

24
docs/API/api.md Normal file
View File

@@ -0,0 +1,24 @@
# pyasic
## Miner APIs
Each miner has a unique API that is used to communicate with it.
Each of these API types has commands that differ between them, and some commands have data that others do not.
Each miner that is a subclass of `BaseMiner` should have an API linked to it as `Miner.api`.
All API implementations inherit from [`BaseMinerAPI`][pyasic.API.BaseMinerAPI], which implements the basic communications protocols.
BaseMinerAPI should never be used unless inheriting to create a new miner API class for a new type of miner (which should be exceedingly rare).
Use these instead -
#### [BMMiner API][pyasic.API.bmminer.BMMinerAPI]
#### [BOSMiner API][pyasic.API.bosminer.BOSMinerAPI]
#### [BTMiner API][pyasic.API.btminer.BTMinerAPI]
#### [CGMiner API][pyasic.API.cgminer.CGMinerAPI]
#### [Unknown API][pyasic.API.unknown.UnknownAPI]
<br>
## BaseMinerAPI
::: pyasic.API.BaseMinerAPI
handler: python
options:
heading_level: 4

7
docs/API/bmminer.md Normal file
View File

@@ -0,0 +1,7 @@
# pyasic
## BMMinerAPI
::: pyasic.API.bmminer.BMMinerAPI
handler: python
options:
show_root_heading: false
heading_level: 4

7
docs/API/bosminer.md Normal file
View File

@@ -0,0 +1,7 @@
# pyasic
## BOSMinerAPI
::: pyasic.API.bosminer.BOSMinerAPI
handler: python
options:
show_root_heading: false
heading_level: 4

7
docs/API/btminer.md Normal file
View File

@@ -0,0 +1,7 @@
# pyasic
## BTMinerAPI
::: pyasic.API.btminer.BTMinerAPI
handler: python
options:
show_root_heading: false
heading_level: 4

7
docs/API/cgminer.md Normal file
View File

@@ -0,0 +1,7 @@
# pyasic
## CGMinerAPI
::: pyasic.API.cgminer.CGMinerAPI
handler: python
options:
show_root_heading: false
heading_level: 4

7
docs/API/unknown.md Normal file
View File

@@ -0,0 +1,7 @@
# pyasic
## UnknownAPI
::: pyasic.API.unknown.UnknownAPI
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -1,42 +0,0 @@
# pyasic
## Miner APIs
Each miner has a unique API that is used to communicate with it.
Each of these API types has commands that differ between them, and some commands have data that others do not.
Each miner that is a subclass of `BaseMiner` should have an API linked to it as `Miner.api`.
All API implementations inherit from `BaseMinerAPI`, which implements the basic communications protocols.
## BMMinerAPI
::: pyasic.API.bmminer.BMMinerAPI
handler: python
options:
show_root_heading: false
heading_level: 4
## BOSMinerAPI
::: pyasic.API.bosminer.BOSMinerAPI
handler: python
options:
show_root_heading: false
heading_level: 4
## BTMinerAPI
::: pyasic.API.btminer.BTMinerAPI
handler: python
options:
show_root_heading: false
heading_level: 4
## CGMinerAPI
::: pyasic.API.cgminer.CGMinerAPI
handler: python
options:
show_root_heading: false
heading_level: 4
## UnknownAPI
::: pyasic.API.unknown.UnknownAPI
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -0,0 +1,24 @@
# pyasic
## Miner Config
::: pyasic.config.MinerConfig
handler: python
options:
show_root_heading: false
heading_level: 4
## Pool Groups
::: pyasic.config._PoolGroup
handler: python
options:
show_root_heading: false
heading_level: 4
## Pools
::: pyasic.config._Pool
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -2,12 +2,22 @@ site_name: pyasic
repo_url: https://github.com/UpstreamData/pyasic repo_url: https://github.com/UpstreamData/pyasic
nav: nav:
- Introduction: "index.md" - Introduction: "index.md"
- Usage: - Miners:
- Miner Factory: "miner_factory.md" - Miner Factory: "miners/miner_factory.md"
- Miner Network: "miner_network.md" - Network:
- Miner Data: "miner_data.md" - Miner Network: "network/miner_network.md"
- Data:
- Miner Data: "data/miner_data.md"
- Config:
- Miner Config: "config/miner_config.md"
- Advanced: - Advanced:
- API: "api.md" - Miner APIs:
- Base: "API/api.md"
- BMMiner: "API/bmminer.md"
- BOSMiner: "API/bosminer.md"
- BTMiner: "API/btminer.md"
- CGMiner: "API/cgminer.md"
- Unknown: "API/unknown.md"
plugins: plugins:
- mkdocstrings - mkdocstrings

View File

@@ -3,6 +3,7 @@ import json
import ipaddress import ipaddress
import warnings import warnings
import logging import logging
from typing import Union
class APIError(Exception): class APIError(Exception):
@@ -98,8 +99,8 @@ If you are sure you want to use this command please use API.send_command("{item}
async def send_command( async def send_command(
self, self,
command: str or bytes, command: Union[str, bytes],
parameters: str or int or bool = None, parameters: Union[str, int, bool] = None,
ignore_errors: bool = False, ignore_errors: bool = False,
x19_command: bool = False, x19_command: bool = False,
) -> dict: ) -> dict:

View File

@@ -1,5 +1,5 @@
from dataclasses import dataclass, asdict from dataclasses import dataclass, asdict
from typing import List, Literal from typing import Literal, List
import random import random
import string import string
@@ -13,9 +13,10 @@ import time
class _Pool: class _Pool:
"""A dataclass for pool information. """A dataclass for pool information.
:param url: URL of the pool. Attributes:
:param username: Username on the pool. url: URL of the pool.
:param password: Worker password on the pool. username: Username on the pool.
password: Worker password on the pool.
""" """
url: str = "" url: str = ""
@@ -25,7 +26,8 @@ class _Pool:
def from_dict(self, data: dict): def from_dict(self, data: dict):
"""Convert raw pool data as a dict to usable data and save it to this class. """Convert raw pool data as a dict to usable data and save it to this class.
:param data: The raw config data to convert. Parameters:
data: The raw config data to convert.
""" """
for key in data.keys(): for key in data.keys():
if key == "url": if key == "url":
@@ -36,10 +38,11 @@ class _Pool:
self.password = data[key] self.password = data[key]
return self return self
def as_x19(self, user_suffix: str = None): def as_x19(self, user_suffix: str = None) -> dict:
"""Convert the data in this class to a dict usable by an X19 device. """Convert the data in this class to a dict usable by an X19 device.
:param user_suffix: The suffix to append to username. Parameters:
user_suffix: The suffix to append to username.
""" """
username = self.username username = self.username
if user_suffix: if user_suffix:
@@ -48,7 +51,12 @@ class _Pool:
pool = {"url": self.url, "user": username, "pass": self.password} pool = {"url": self.url, "user": username, "pass": self.password}
return pool return pool
def as_avalon(self, user_suffix: str = None): def as_avalon(self, user_suffix: str = None) -> str:
"""Convert the data in this class to a string usable by an Avalonminer device.
Parameters:
user_suffix: The suffix to append to username.
"""
username = self.username username = self.username
if user_suffix: if user_suffix:
username = f"{username}{user_suffix}" username = f"{username}{user_suffix}"
@@ -56,10 +64,11 @@ class _Pool:
pool = ",".join([self.url, username, self.password]) pool = ",".join([self.url, username, self.password])
return pool return pool
def as_bos(self, user_suffix: str = None): def as_bos(self, user_suffix: str = None) -> dict:
"""Convert the data in this class to a dict usable by an BOSMiner device. """Convert the data in this class to a dict usable by an BOSMiner device.
:param user_suffix: The suffix to append to username. Parameters:
user_suffix: The suffix to append to username.
""" """
username = self.username username = self.username
if user_suffix: if user_suffix:
@@ -73,9 +82,10 @@ class _Pool:
class _PoolGroup: class _PoolGroup:
"""A dataclass for pool group information. """A dataclass for pool group information.
:param quota: The group quota. Attributes:
:param group_name: The name of the pool group. quota: The group quota.
:param pools: A list of pools in this group. group_name: The name of the pool group.
pools: A list of pools in this group.
""" """
quota: int = 1 quota: int = 1
@@ -91,7 +101,8 @@ class _PoolGroup:
def from_dict(self, data: dict): def from_dict(self, data: dict):
"""Convert raw pool group data as a dict to usable data and save it to this class. """Convert raw pool group data as a dict to usable data and save it to this class.
:param data: The raw config data to convert. Parameters:
data: The raw config data to convert.
""" """
pools = [] pools = []
for key in data.keys(): for key in data.keys():
@@ -105,24 +116,31 @@ class _PoolGroup:
self.pools = pools self.pools = pools
return self return self
def as_x19(self, user_suffix: str = None): def as_x19(self, user_suffix: str = None) -> List[dict]:
"""Convert the data in this class to a dict usable by an X19 device. """Convert the data in this class to a list usable by an X19 device.
:param user_suffix: The suffix to append to username. Parameters:
user_suffix: The suffix to append to username.
""" """
pools = [] pools = []
for pool in self.pools[:3]: for pool in self.pools[:3]:
pools.append(pool.as_x19(user_suffix=user_suffix)) pools.append(pool.as_x19(user_suffix=user_suffix))
return pools return pools
def as_avalon(self, user_suffix: str = None): def as_avalon(self, user_suffix: str = None) -> str:
"""Convert the data in this class to a dict usable by an Avalonminer device.
Parameters:
user_suffix: The suffix to append to username.
"""
pool = self.pools[0].as_avalon(user_suffix=user_suffix) pool = self.pools[0].as_avalon(user_suffix=user_suffix)
return pool return pool
def as_bos(self, user_suffix: str = None): def as_bos(self, user_suffix: str = None) -> dict:
"""Convert the data in this class to a dict usable by an BOSMiner device. """Convert the data in this class to a dict usable by an BOSMiner device.
:param user_suffix: The suffix to append to username. Parameters:
user_suffix: The suffix to append to username.
""" """
group = { group = {
"name": self.group_name, "name": self.group_name,
@@ -136,21 +154,22 @@ class _PoolGroup:
class MinerConfig: class MinerConfig:
"""A dataclass for miner configuration information. """A dataclass for miner configuration information.
:param pool_groups: A list of pool groups in this config. Attributes:
:param temp_mode: The temperature control mode. pool_groups: A list of pool groups in this config.
:param temp_target: The target temp. temp_mode: The temperature control mode.
:param temp_hot: The hot temp (100% fans). temp_target: The target temp.
:param temp_dangerous: The dangerous temp (shutdown). temp_hot: The hot temp (100% fans).
:param minimum_fans: The minimum numbers of fans to run the miner. temp_dangerous: The dangerous temp (shutdown).
:param fan_speed: Manual fan speed to run the fan at (only if temp_mode == "manual"). minimum_fans: The minimum numbers of fans to run the miner.
:param asicboost: Whether or not to enable asicboost. fan_speed: Manual fan speed to run the fan at (only if temp_mode == "manual").
:param autotuning_enabled: Whether or not to enable autotuning. asicboost: Whether or not to enable asicboost.
:param autotuning_wattage: The wattage to use when autotuning. autotuning_enabled: Whether or not to enable autotuning.
:param dps_enabled: Whether or not to enable dynamic power scaling. autotuning_wattage: The wattage to use when autotuning.
:param dps_power_step: The amount of power to reduce autotuning by when the miner reaches dangerous temp. dps_enabled: Whether or not to enable dynamic power scaling.
:param dps_min_power: The minimum power to reduce autotuning to. dps_power_step: The amount of power to reduce autotuning by when the miner reaches dangerous temp.
:param dps_shutdown_enabled: Whether or not to shutdown the miner when `dps_min_power` is reached. dps_min_power: The minimum power to reduce autotuning to.
:param dps_shutdown_duration: The amount of time to shutdown for (in hours). dps_shutdown_enabled: Whether or not to shutdown the miner when `dps_min_power` is reached.
dps_shutdown_duration: The amount of time to shutdown for (in hours).
""" """
pool_groups: List[_PoolGroup] = None pool_groups: List[_PoolGroup] = None
@@ -174,27 +193,28 @@ class MinerConfig:
dps_shutdown_enabled: bool = None dps_shutdown_enabled: bool = None
dps_shutdown_duration: float = None dps_shutdown_duration: float = None
def as_dict(self): def as_dict(self) -> dict:
"""Convert the data in this class to a dict.""" """Convert the data in this class to a dict."""
data_dict = asdict(self) data_dict = asdict(self)
for key in asdict(self).keys(): for key in asdict(self).keys():
if data_dict[key] is None: if data_dict[key] is None:
del data_dict[key] del data_dict[key]
return data_dict return data_dict
def as_toml(self): def as_toml(self) -> str:
"""Convert the data in this class to toml.""" """Convert the data in this class to toml."""
return toml.dumps(self.as_dict()) return toml.dumps(self.as_dict())
def as_yaml(self): def as_yaml(self) -> str:
"""Convert the data in this class to yaml.""" """Convert the data in this class to yaml."""
return yaml.dump(self.as_dict(), sort_keys=False) return yaml.dump(self.as_dict(), sort_keys=False)
def from_raw(self, data: dict): def from_raw(self, data: dict):
"""Convert raw config data as a dict to usable data and save it to this class. """Convert raw config data as a dict to usable data and save it to this class.
This should be able to handle any raw config file from any miner supported by pyasic.
:param data: The raw config data to convert. Parameters:
data: The raw config data to convert.
""" """
pool_groups = [] pool_groups = []
for key in data.keys(): for key in data.keys():
@@ -256,7 +276,8 @@ class MinerConfig:
def from_dict(self, data: dict): def from_dict(self, data: dict):
"""Convert an output dict of this class back into usable data and save it to this class. """Convert an output dict of this class back into usable data and save it to this class.
:param data: The raw config data to convert. Parameters:
data: The dict config data to convert.
""" """
pool_groups = [] pool_groups = []
for group in data["pool_groups"]: for group in data["pool_groups"]:
@@ -270,21 +291,24 @@ class MinerConfig:
def from_toml(self, data: str): def from_toml(self, data: str):
"""Convert output toml of this class back into usable data and save it to this class. """Convert output toml of this class back into usable data and save it to this class.
:param data: The raw config data to convert. Parameters:
data: The toml config data to convert.
""" """
return self.from_dict(toml.loads(data)) return self.from_dict(toml.loads(data))
def from_yaml(self, data: str): def from_yaml(self, data: str):
"""Convert output yaml of this class back into usable data and save it to this class. """Convert output yaml of this class back into usable data and save it to this class.
:param data: The raw config data to convert. Parameters:
data: The yaml config data to convert.
""" """
return self.from_dict(yaml.load(data, Loader=yaml.SafeLoader)) return self.from_dict(yaml.load(data, Loader=yaml.SafeLoader))
def as_x19(self, user_suffix: str = None) -> str: def as_x19(self, user_suffix: str = None) -> str:
"""Convert the data in this class to a config usable by an X19 device. """Convert the data in this class to a config usable by an X19 device.
:param user_suffix: The suffix to append to username. Parameters:
user_suffix: The suffix to append to username.
""" """
cfg = { cfg = {
"pools": self.pool_groups[0].as_x19(user_suffix=user_suffix), "pools": self.pool_groups[0].as_x19(user_suffix=user_suffix),
@@ -301,14 +325,20 @@ class MinerConfig:
return json.dumps(cfg) return json.dumps(cfg)
def as_avalon(self, user_suffix: str = None) -> str: def as_avalon(self, user_suffix: str = None) -> str:
cfg = self.pool_groups[0].as_avalon() """Convert the data in this class to a config usable by an Avalonminer device.
Parameters:
user_suffix: The suffix to append to username.
"""
cfg = self.pool_groups[0].as_avalon(user_suffix=user_suffix)
return cfg return cfg
def as_bos(self, model: str = "S9", user_suffix: str = None) -> str: def as_bos(self, model: str = "S9", user_suffix: str = None) -> str:
"""Convert the data in this class to a config usable by an BOSMiner device. """Convert the data in this class to a config usable by an BOSMiner device.
:param model: The model of the miner to be used in the format portion of the config. Parameters:
:param user_suffix: The suffix to append to username. model: The model of the miner to be used in the format portion of the config.
user_suffix: The suffix to append to username.
""" """
cfg = { cfg = {
"format": { "format": {